blob: 71d73fd446e032256e7dbc860adbf785d9cc5842 [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());
160 const auto &uniforms = mData.getUniforms();
161 for (const gl::VariableLocation &entry : mData.getUniformLocations())
162 {
163 // From the spec:
164 // "Locations for sequential array indices are not required to be sequential."
165 const gl::LinkedUniform &uniform = uniforms[entry.index];
166 std::stringstream fullNameStr;
167 fullNameStr << uniform.name;
168 if (uniform.isArray())
169 {
170 fullNameStr << "[" << entry.element << "]";
171 }
172 const std::string &fullName = fullNameStr.str();
173
174 GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
175 mUniformRealLocationMap.push_back(realLocation);
176 }
177
178 mUniformIndexToSamplerIndex.resize(mData.getUniforms().size(), GL_INVALID_INDEX);
179
180 for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId)
181 {
182 const gl::LinkedUniform &linkedUniform = uniforms[uniformId];
183
184 if (!linkedUniform.isSampler() || !linkedUniform.staticUse)
185 continue;
186
187 mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size();
188
189 // If uniform is a sampler type, insert it into the mSamplerBindings array
190 SamplerBindingGL samplerBinding;
191 samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type);
192 samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0);
193 mSamplerBindings.push_back(samplerBinding);
194 }
Geoff Langb1f435e2015-02-20 10:01:01 -0500195
Geoff Langb1f435e2015-02-20 10:01:01 -0500196 return LinkResult(true, gl::Error(GL_NO_ERROR));
Geoff Langf9a6f082015-01-22 13:32:49 -0500197}
198
Jamie Madill36cfd6a2015-08-18 10:46:20 -0400199GLboolean ProgramGL::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
200{
201 // TODO(jmadill): implement validate
202 return true;
203}
204
Geoff Langf9a6f082015-01-22 13:32:49 -0500205void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
206{
Geoff Lang63cbace2015-02-26 10:03:12 -0500207 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400208 mFunctions->uniform1fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500209}
210
211void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
212{
Geoff Lang63cbace2015-02-26 10:03:12 -0500213 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400214 mFunctions->uniform2fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500215}
216
217void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
218{
Geoff Lang63cbace2015-02-26 10:03:12 -0500219 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400220 mFunctions->uniform3fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500221}
222
223void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
224{
Geoff Lang63cbace2015-02-26 10:03:12 -0500225 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400226 mFunctions->uniform4fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500227}
228
229void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
230{
Geoff Lang63cbace2015-02-26 10:03:12 -0500231 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400232 mFunctions->uniform1iv(uniLoc(location), count, v);
Geoff Langf51bc792015-05-04 14:57:03 -0400233
Jamie Madill62d31cb2015-09-11 13:25:51 -0400234 const gl::VariableLocation &locationEntry = mData.getUniformLocations()[location];
235
236 size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index];
237 if (samplerIndex != GL_INVALID_INDEX)
Geoff Langf51bc792015-05-04 14:57:03 -0400238 {
Jamie Madill62d31cb2015-09-11 13:25:51 -0400239 std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits;
Geoff Langf51bc792015-05-04 14:57:03 -0400240
Jamie Madill62d31cb2015-09-11 13:25:51 -0400241 size_t copyCount =
242 std::max<size_t>(count, boundTextureUnits.size() - locationEntry.element);
243 std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element);
Geoff Langf51bc792015-05-04 14:57:03 -0400244 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500245}
246
247void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
248{
Geoff Lang63cbace2015-02-26 10:03:12 -0500249 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400250 mFunctions->uniform2iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500251}
252
253void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
254{
Geoff Lang63cbace2015-02-26 10:03:12 -0500255 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400256 mFunctions->uniform3iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500257}
258
259void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
260{
Geoff Lang63cbace2015-02-26 10:03:12 -0500261 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400262 mFunctions->uniform4iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500263}
264
265void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
266{
Geoff Lang63cbace2015-02-26 10:03:12 -0500267 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500268 mFunctions->uniform1uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500269}
270
271void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
272{
Geoff Lang63cbace2015-02-26 10:03:12 -0500273 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400274 mFunctions->uniform2uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500275}
276
277void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
278{
Geoff Lang63cbace2015-02-26 10:03:12 -0500279 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400280 mFunctions->uniform3uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500281}
282
283void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
284{
Geoff Lang63cbace2015-02-26 10:03:12 -0500285 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400286 mFunctions->uniform4uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500287}
288
289void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
290{
Geoff Lang63cbace2015-02-26 10:03:12 -0500291 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400292 mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500293}
294
295void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
296{
Geoff Lang63cbace2015-02-26 10:03:12 -0500297 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400298 mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500299}
300
301void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
302{
Geoff Lang63cbace2015-02-26 10:03:12 -0500303 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400304 mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500305}
306
307void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
308{
Geoff Lang63cbace2015-02-26 10:03:12 -0500309 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400310 mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500311}
312
313void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
314{
Geoff Lang63cbace2015-02-26 10:03:12 -0500315 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400316 mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500317}
318
319void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
320{
Geoff Lang63cbace2015-02-26 10:03:12 -0500321 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400322 mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500323}
324
325void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
326{
Geoff Lang63cbace2015-02-26 10:03:12 -0500327 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400328 mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500329}
330
331void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
332{
Geoff Lang63cbace2015-02-26 10:03:12 -0500333 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400334 mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500335}
336
337void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
338{
Geoff Lang63cbace2015-02-26 10:03:12 -0500339 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400340 mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500341}
342
Geoff Lang5d124a62015-09-15 13:03:27 -0400343void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
344{
Jamie Madill4a3c2342015-10-08 12:58:45 -0400345 // Lazy init
346 if (mUniformBlockRealLocationMap.empty())
347 {
348 mUniformBlockRealLocationMap.reserve(mData.getUniformBlocks().size());
349 for (const gl::UniformBlock &uniformBlock : mData.getUniformBlocks())
350 {
351 const std::string &nameWithIndex = uniformBlock.nameWithArrayIndex();
352 GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, nameWithIndex.c_str());
353 mUniformBlockRealLocationMap.push_back(blockIndex);
354 }
355 }
356
357 GLuint realBlockIndex = mUniformBlockRealLocationMap[uniformBlockIndex];
358 if (realBlockIndex != GL_INVALID_INDEX)
359 {
360 mFunctions->uniformBlockBinding(mProgramID, realBlockIndex, uniformBlockBinding);
361 }
Geoff Lang5d124a62015-09-15 13:03:27 -0400362}
363
Geoff Lang01306fc2015-10-05 16:53:10 +0000364void ProgramGL::reset()
365{
366 mUniformRealLocationMap.clear();
Jamie Madill4a3c2342015-10-08 12:58:45 -0400367 mUniformBlockRealLocationMap.clear();
Geoff Lang01306fc2015-10-05 16:53:10 +0000368 mSamplerBindings.clear();
369 mUniformIndexToSamplerIndex.clear();
370}
371
Geoff Langb1f435e2015-02-20 10:01:01 -0500372GLuint ProgramGL::getProgramID() const
373{
374 return mProgramID;
375}
376
Geoff Langf51bc792015-05-04 14:57:03 -0400377const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() const
378{
379 return mSamplerBindings;
380}
381
Jamie Madill4a3c2342015-10-08 12:58:45 -0400382bool ProgramGL::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const
Jamie Madill62d31cb2015-09-11 13:25:51 -0400383{
Jamie Madill4a3c2342015-10-08 12:58:45 -0400384 ASSERT(mProgramID != 0u);
Geoff Lang5d124a62015-09-15 13:03:27 -0400385
Jamie Madill4a3c2342015-10-08 12:58:45 -0400386 GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, blockName.c_str());
387 if (blockIndex == GL_INVALID_INDEX)
Geoff Lang5d124a62015-09-15 13:03:27 -0400388 {
Jamie Madill4a3c2342015-10-08 12:58:45 -0400389 *sizeOut = 0;
390 return false;
Geoff Lang5d124a62015-09-15 13:03:27 -0400391 }
392
Jamie Madill4a3c2342015-10-08 12:58:45 -0400393 GLint dataSize = 0;
394 mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
395 &dataSize);
396 *sizeOut = static_cast<size_t>(dataSize);
397 return true;
398}
399
400bool ProgramGL::getUniformBlockMemberInfo(const std::string &memberUniformName,
401 sh::BlockMemberInfo *memberInfoOut) const
402{
403 GLuint uniformIndex;
404 const GLchar *memberNameGLStr = memberUniformName.c_str();
405 mFunctions->getUniformIndices(mProgramID, 1, &memberNameGLStr, &uniformIndex);
406
407 if (uniformIndex == GL_INVALID_INDEX)
Geoff Lang5d124a62015-09-15 13:03:27 -0400408 {
Jamie Madill4a3c2342015-10-08 12:58:45 -0400409 *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
410 return false;
Geoff Lang5d124a62015-09-15 13:03:27 -0400411 }
Jamie Madill4a3c2342015-10-08 12:58:45 -0400412
413 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET,
414 &memberInfoOut->offset);
415 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE,
416 &memberInfoOut->arrayStride);
417 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
418 &memberInfoOut->matrixStride);
419
420 // TODO(jmadill): possibly determine this at the gl::Program level.
421 GLint isRowMajorMatrix = 0;
422 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
423 &isRowMajorMatrix);
424 memberInfoOut->isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
425 return true;
Jamie Madill62d31cb2015-09-11 13:25:51 -0400426}
Jamie Madill4a3c2342015-10-08 12:58:45 -0400427
428} // namespace rx