blob: 6a2bc446a630aa54547c570a39c8d7fffdc5e68a [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// ProgramGL.cpp: Implements the class methods for ProgramGL.
8
9#include "libANGLE/renderer/gl/ProgramGL.h"
10
11#include "common/debug.h"
Geoff Lang5ed74cf2015-04-14 13:57:07 -040012#include "common/utilities.h"
Geoff Langb1f435e2015-02-20 10:01:01 -050013#include "libANGLE/renderer/gl/FunctionsGL.h"
14#include "libANGLE/renderer/gl/ShaderGL.h"
15#include "libANGLE/renderer/gl/StateManagerGL.h"
Philippe Hamel40911192016-04-07 16:45:50 -040016#include "libANGLE/renderer/gl/WorkaroundsGL.h"
unknownb4a3af22015-11-25 15:02:51 -050017#include "platform/Platform.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050018
19namespace rx
20{
21
Jamie Madill5c6b7bf2015-08-17 12:53:35 -040022ProgramGL::ProgramGL(const gl::Program::Data &data,
23 const FunctionsGL *functions,
Philippe Hamel40911192016-04-07 16:45:50 -040024 const WorkaroundsGL &workarounds,
Jamie Madill5c6b7bf2015-08-17 12:53:35 -040025 StateManagerGL *stateManager)
Philippe Hamel40911192016-04-07 16:45:50 -040026 : ProgramImpl(data),
27 mFunctions(functions),
28 mWorkarounds(workarounds),
29 mStateManager(stateManager),
30 mProgramID(0)
Geoff Langb1f435e2015-02-20 10:01:01 -050031{
32 ASSERT(mFunctions);
33 ASSERT(mStateManager);
Geoff Lang0ca53782015-05-07 13:49:39 -040034
35 mProgramID = mFunctions->createProgram();
Geoff Langb1f435e2015-02-20 10:01:01 -050036}
Geoff Langf9a6f082015-01-22 13:32:49 -050037
38ProgramGL::~ProgramGL()
Geoff Langb1f435e2015-02-20 10:01:01 -050039{
Geoff Lang0ca53782015-05-07 13:49:39 -040040 mFunctions->deleteProgram(mProgramID);
41 mProgramID = 0;
Geoff Langb1f435e2015-02-20 10:01:01 -050042}
Geoff Langf9a6f082015-01-22 13:32:49 -050043
Geoff Langf9a6f082015-01-22 13:32:49 -050044LinkResult ProgramGL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
45{
Geoff Lang01306fc2015-10-05 16:53:10 +000046 UNIMPLEMENTED();
47 return LinkResult(false, gl::Error(GL_INVALID_OPERATION));
Geoff Langf9a6f082015-01-22 13:32:49 -050048}
49
50gl::Error ProgramGL::save(gl::BinaryOutputStream *stream)
51{
Geoff Lang01306fc2015-10-05 16:53:10 +000052 UNIMPLEMENTED();
53 return gl::Error(GL_INVALID_OPERATION);
Geoff Langf9a6f082015-01-22 13:32:49 -050054}
55
Geoff Langc5629752015-12-07 16:29:04 -050056void ProgramGL::setBinaryRetrievableHint(bool retrievable)
57{
58 UNIMPLEMENTED();
59}
60
Jamie Madillf5f4ad22015-09-02 18:32:38 +000061LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog)
Geoff Langf9a6f082015-01-22 13:32:49 -050062{
Geoff Lang01306fc2015-10-05 16:53:10 +000063 // Reset the program state, delete the current program if one exists
64 reset();
Geoff Langb1f435e2015-02-20 10:01:01 -050065
Geoff Lang1a683462015-09-29 15:09:59 -040066 // Set the transform feedback state
67 std::vector<const GLchar *> transformFeedbackVaryings;
68 for (const auto &tfVarying : mData.getTransformFeedbackVaryingNames())
69 {
70 transformFeedbackVaryings.push_back(tfVarying.c_str());
71 }
72
73 if (transformFeedbackVaryings.empty())
74 {
75 if (mFunctions->transformFeedbackVaryings)
76 {
77 mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr,
78 mData.getTransformFeedbackBufferMode());
79 }
80 }
81 else
82 {
83 ASSERT(mFunctions->transformFeedbackVaryings);
84 mFunctions->transformFeedbackVaryings(
85 mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()),
86 &transformFeedbackVaryings[0], mData.getTransformFeedbackBufferMode());
87 }
88
Geoff Lang01306fc2015-10-05 16:53:10 +000089 const gl::Shader *vertexShader = mData.getAttachedVertexShader();
90 const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
91
92 const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(vertexShader);
93 const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(fragmentShader);
Geoff Langb1f435e2015-02-20 10:01:01 -050094
Geoff Langb1f435e2015-02-20 10:01:01 -050095 // Attach the shaders
96 mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
97 mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
98
Geoff Lang1528e562015-08-24 15:10:58 -040099 // Bind attribute locations to match the GL layer.
100 for (const sh::Attribute &attribute : mData.getAttributes())
101 {
102 if (!attribute.staticUse)
103 {
104 continue;
105 }
106
107 mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str());
Geoff Lang1528e562015-08-24 15:10:58 -0400108 }
109
Geoff Langb1f435e2015-02-20 10:01:01 -0500110 // Link and verify
111 mFunctions->linkProgram(mProgramID);
112
Geoff Lang0ca53782015-05-07 13:49:39 -0400113 // Detach the shaders
114 mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
115 mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
116
117 // Verify the link
Geoff Lang01306fc2015-10-05 16:53:10 +0000118 GLint linkStatus = GL_FALSE;
119 mFunctions->getProgramiv(mProgramID, GL_LINK_STATUS, &linkStatus);
Geoff Lang01306fc2015-10-05 16:53:10 +0000120 if (linkStatus == GL_FALSE)
Geoff Langb1f435e2015-02-20 10:01:01 -0500121 {
Geoff Lang01306fc2015-10-05 16:53:10 +0000122 // Linking failed, put the error into the info log
123 GLint infoLogLength = 0;
124 mFunctions->getProgramiv(mProgramID, GL_INFO_LOG_LENGTH, &infoLogLength);
125
Corentin Wallez01ad6442016-03-03 13:53:45 -0500126 std::string warning;
Olli Etuaho67946762016-03-08 15:43:55 +0200127
128 // Info log length includes the null terminator, so 1 means that the info log is an empty
129 // string.
130 if (infoLogLength > 1)
Corentin Wallez01ad6442016-03-03 13:53:45 -0500131 {
132 std::vector<char> buf(infoLogLength);
133 mFunctions->getProgramInfoLog(mProgramID, infoLogLength, nullptr, &buf[0]);
Geoff Lang01306fc2015-10-05 16:53:10 +0000134
Corentin Wallez01ad6442016-03-03 13:53:45 -0500135 mFunctions->deleteProgram(mProgramID);
136 mProgramID = 0;
Geoff Lang01306fc2015-10-05 16:53:10 +0000137
Corentin Wallez01ad6442016-03-03 13:53:45 -0500138 infoLog << buf.data();
unknownb4a3af22015-11-25 15:02:51 -0500139
Corentin Wallez01ad6442016-03-03 13:53:45 -0500140 warning = FormatString("Program link failed unexpectedly: %s", buf.data());
141 }
142 else
143 {
144 warning = "Program link failed unexpectedly with no info log.";
145 }
unknownb4a3af22015-11-25 15:02:51 -0500146 ANGLEPlatformCurrent()->logWarning(warning.c_str());
147 TRACE("\n%s", warning.c_str());
Geoff Lang01306fc2015-10-05 16:53:10 +0000148
149 // TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case
Geoff Langb1f435e2015-02-20 10:01:01 -0500150 return LinkResult(false, gl::Error(GL_NO_ERROR));
151 }
152
Philippe Hamel40911192016-04-07 16:45:50 -0400153 if (mWorkarounds.alwaysCallUseProgramAfterLink)
154 {
155 mStateManager->forceUseProgram(mProgramID);
156 }
157
Geoff Lang01306fc2015-10-05 16:53:10 +0000158 // Query the uniform information
159 ASSERT(mUniformRealLocationMap.empty());
Geoff Langd8605522016-04-13 10:19:12 -0400160 const auto &uniformLocations = mData.getUniformLocations();
Geoff Lang01306fc2015-10-05 16:53:10 +0000161 const auto &uniforms = mData.getUniforms();
Geoff Langd8605522016-04-13 10:19:12 -0400162 mUniformRealLocationMap.resize(uniformLocations.size(), GL_INVALID_INDEX);
163 for (size_t uniformLocation = 0; uniformLocation < uniformLocations.size(); uniformLocation++)
Geoff Lang01306fc2015-10-05 16:53:10 +0000164 {
Geoff Langd8605522016-04-13 10:19:12 -0400165 const auto &entry = uniformLocations[uniformLocation];
166 if (!entry.used)
167 {
168 continue;
169 }
170
Geoff Lang01306fc2015-10-05 16:53:10 +0000171 // From the spec:
172 // "Locations for sequential array indices are not required to be sequential."
173 const gl::LinkedUniform &uniform = uniforms[entry.index];
174 std::stringstream fullNameStr;
175 fullNameStr << uniform.name;
176 if (uniform.isArray())
177 {
178 fullNameStr << "[" << entry.element << "]";
179 }
180 const std::string &fullName = fullNameStr.str();
181
182 GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
Geoff Langd8605522016-04-13 10:19:12 -0400183 mUniformRealLocationMap[uniformLocation] = realLocation;
Geoff Lang01306fc2015-10-05 16:53:10 +0000184 }
185
186 mUniformIndexToSamplerIndex.resize(mData.getUniforms().size(), GL_INVALID_INDEX);
187
188 for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId)
189 {
190 const gl::LinkedUniform &linkedUniform = uniforms[uniformId];
191
192 if (!linkedUniform.isSampler() || !linkedUniform.staticUse)
193 continue;
194
195 mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size();
196
197 // If uniform is a sampler type, insert it into the mSamplerBindings array
198 SamplerBindingGL samplerBinding;
199 samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type);
200 samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0);
201 mSamplerBindings.push_back(samplerBinding);
202 }
Geoff Langb1f435e2015-02-20 10:01:01 -0500203
Geoff Langb1f435e2015-02-20 10:01:01 -0500204 return LinkResult(true, gl::Error(GL_NO_ERROR));
Geoff Langf9a6f082015-01-22 13:32:49 -0500205}
206
Jamie Madill36cfd6a2015-08-18 10:46:20 -0400207GLboolean ProgramGL::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
208{
209 // TODO(jmadill): implement validate
210 return true;
211}
212
Geoff Langf9a6f082015-01-22 13:32:49 -0500213void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
214{
Geoff Lang63cbace2015-02-26 10:03:12 -0500215 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400216 mFunctions->uniform1fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500217}
218
219void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
220{
Geoff Lang63cbace2015-02-26 10:03:12 -0500221 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400222 mFunctions->uniform2fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500223}
224
225void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
226{
Geoff Lang63cbace2015-02-26 10:03:12 -0500227 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400228 mFunctions->uniform3fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500229}
230
231void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
232{
Geoff Lang63cbace2015-02-26 10:03:12 -0500233 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400234 mFunctions->uniform4fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500235}
236
237void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
238{
Geoff Lang63cbace2015-02-26 10:03:12 -0500239 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400240 mFunctions->uniform1iv(uniLoc(location), count, v);
Geoff Langf51bc792015-05-04 14:57:03 -0400241
Jamie Madill62d31cb2015-09-11 13:25:51 -0400242 const gl::VariableLocation &locationEntry = mData.getUniformLocations()[location];
243
244 size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index];
245 if (samplerIndex != GL_INVALID_INDEX)
Geoff Langf51bc792015-05-04 14:57:03 -0400246 {
Jamie Madill62d31cb2015-09-11 13:25:51 -0400247 std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits;
Geoff Langf51bc792015-05-04 14:57:03 -0400248
Jamie Madill62d31cb2015-09-11 13:25:51 -0400249 size_t copyCount =
250 std::max<size_t>(count, boundTextureUnits.size() - locationEntry.element);
251 std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element);
Geoff Langf51bc792015-05-04 14:57:03 -0400252 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500253}
254
255void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
256{
Geoff Lang63cbace2015-02-26 10:03:12 -0500257 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400258 mFunctions->uniform2iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500259}
260
261void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
262{
Geoff Lang63cbace2015-02-26 10:03:12 -0500263 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400264 mFunctions->uniform3iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500265}
266
267void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
268{
Geoff Lang63cbace2015-02-26 10:03:12 -0500269 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400270 mFunctions->uniform4iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500271}
272
273void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
274{
Geoff Lang63cbace2015-02-26 10:03:12 -0500275 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500276 mFunctions->uniform1uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500277}
278
279void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
280{
Geoff Lang63cbace2015-02-26 10:03:12 -0500281 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400282 mFunctions->uniform2uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500283}
284
285void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
286{
Geoff Lang63cbace2015-02-26 10:03:12 -0500287 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400288 mFunctions->uniform3uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500289}
290
291void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
292{
Geoff Lang63cbace2015-02-26 10:03:12 -0500293 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400294 mFunctions->uniform4uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500295}
296
297void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
298{
Geoff Lang63cbace2015-02-26 10:03:12 -0500299 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400300 mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500301}
302
303void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
304{
Geoff Lang63cbace2015-02-26 10:03:12 -0500305 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400306 mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500307}
308
309void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
310{
Geoff Lang63cbace2015-02-26 10:03:12 -0500311 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400312 mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500313}
314
315void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
316{
Geoff Lang63cbace2015-02-26 10:03:12 -0500317 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400318 mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500319}
320
321void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
322{
Geoff Lang63cbace2015-02-26 10:03:12 -0500323 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400324 mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500325}
326
327void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
328{
Geoff Lang63cbace2015-02-26 10:03:12 -0500329 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400330 mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500331}
332
333void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
334{
Geoff Lang63cbace2015-02-26 10:03:12 -0500335 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400336 mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500337}
338
339void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
340{
Geoff Lang63cbace2015-02-26 10:03:12 -0500341 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400342 mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500343}
344
345void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
346{
Geoff Lang63cbace2015-02-26 10:03:12 -0500347 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400348 mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500349}
350
Geoff Lang5d124a62015-09-15 13:03:27 -0400351void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
352{
Jamie Madill4a3c2342015-10-08 12:58:45 -0400353 // Lazy init
354 if (mUniformBlockRealLocationMap.empty())
355 {
356 mUniformBlockRealLocationMap.reserve(mData.getUniformBlocks().size());
357 for (const gl::UniformBlock &uniformBlock : mData.getUniformBlocks())
358 {
359 const std::string &nameWithIndex = uniformBlock.nameWithArrayIndex();
360 GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, nameWithIndex.c_str());
361 mUniformBlockRealLocationMap.push_back(blockIndex);
362 }
363 }
364
365 GLuint realBlockIndex = mUniformBlockRealLocationMap[uniformBlockIndex];
366 if (realBlockIndex != GL_INVALID_INDEX)
367 {
368 mFunctions->uniformBlockBinding(mProgramID, realBlockIndex, uniformBlockBinding);
369 }
Geoff Lang5d124a62015-09-15 13:03:27 -0400370}
371
Geoff Lang01306fc2015-10-05 16:53:10 +0000372void ProgramGL::reset()
373{
374 mUniformRealLocationMap.clear();
Jamie Madill4a3c2342015-10-08 12:58:45 -0400375 mUniformBlockRealLocationMap.clear();
Geoff Lang01306fc2015-10-05 16:53:10 +0000376 mSamplerBindings.clear();
377 mUniformIndexToSamplerIndex.clear();
378}
379
Geoff Langb1f435e2015-02-20 10:01:01 -0500380GLuint ProgramGL::getProgramID() const
381{
382 return mProgramID;
383}
384
Geoff Langf51bc792015-05-04 14:57:03 -0400385const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() const
386{
387 return mSamplerBindings;
388}
389
Jamie Madill4a3c2342015-10-08 12:58:45 -0400390bool ProgramGL::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const
Jamie Madill62d31cb2015-09-11 13:25:51 -0400391{
Jamie Madill4a3c2342015-10-08 12:58:45 -0400392 ASSERT(mProgramID != 0u);
Geoff Lang5d124a62015-09-15 13:03:27 -0400393
Jamie Madill4a3c2342015-10-08 12:58:45 -0400394 GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, blockName.c_str());
395 if (blockIndex == GL_INVALID_INDEX)
Geoff Lang5d124a62015-09-15 13:03:27 -0400396 {
Jamie Madill4a3c2342015-10-08 12:58:45 -0400397 *sizeOut = 0;
398 return false;
Geoff Lang5d124a62015-09-15 13:03:27 -0400399 }
400
Jamie Madill4a3c2342015-10-08 12:58:45 -0400401 GLint dataSize = 0;
402 mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
403 &dataSize);
404 *sizeOut = static_cast<size_t>(dataSize);
405 return true;
406}
407
408bool ProgramGL::getUniformBlockMemberInfo(const std::string &memberUniformName,
409 sh::BlockMemberInfo *memberInfoOut) const
410{
411 GLuint uniformIndex;
412 const GLchar *memberNameGLStr = memberUniformName.c_str();
413 mFunctions->getUniformIndices(mProgramID, 1, &memberNameGLStr, &uniformIndex);
414
415 if (uniformIndex == GL_INVALID_INDEX)
Geoff Lang5d124a62015-09-15 13:03:27 -0400416 {
Jamie Madill4a3c2342015-10-08 12:58:45 -0400417 *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
418 return false;
Geoff Lang5d124a62015-09-15 13:03:27 -0400419 }
Jamie Madill4a3c2342015-10-08 12:58:45 -0400420
421 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET,
422 &memberInfoOut->offset);
423 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE,
424 &memberInfoOut->arrayStride);
425 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
426 &memberInfoOut->matrixStride);
427
428 // TODO(jmadill): possibly determine this at the gl::Program level.
429 GLint isRowMajorMatrix = 0;
430 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
431 &isRowMajorMatrix);
432 memberInfoOut->isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
433 return true;
Jamie Madill62d31cb2015-09-11 13:25:51 -0400434}
Jamie Madill4a3c2342015-10-08 12:58:45 -0400435
436} // namespace rx