blob: 42198d5a15ef2519babbb126b2abb6a30fcd3029 [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"
Geoff Langf9a6f082015-01-22 13:32:49 -050016
17namespace rx
18{
19
Jamie Madill5c6b7bf2015-08-17 12:53:35 -040020ProgramGL::ProgramGL(const gl::Program::Data &data,
21 const FunctionsGL *functions,
22 StateManagerGL *stateManager)
23 : ProgramImpl(data), mFunctions(functions), mStateManager(stateManager), mProgramID(0)
Geoff Langb1f435e2015-02-20 10:01:01 -050024{
25 ASSERT(mFunctions);
26 ASSERT(mStateManager);
Geoff Lang0ca53782015-05-07 13:49:39 -040027
28 mProgramID = mFunctions->createProgram();
Geoff Langb1f435e2015-02-20 10:01:01 -050029}
Geoff Langf9a6f082015-01-22 13:32:49 -050030
31ProgramGL::~ProgramGL()
Geoff Langb1f435e2015-02-20 10:01:01 -050032{
Geoff Lang0ca53782015-05-07 13:49:39 -040033 mFunctions->deleteProgram(mProgramID);
34 mProgramID = 0;
Geoff Langb1f435e2015-02-20 10:01:01 -050035}
Geoff Langf9a6f082015-01-22 13:32:49 -050036
Geoff Langf9a6f082015-01-22 13:32:49 -050037LinkResult ProgramGL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
38{
Geoff Lang6d892662015-10-02 09:57:30 -040039 preLink();
40
41 // Read the binary format, size and blob
42 GLenum binaryFormat = stream->readInt<GLenum>();
43 GLint binaryLength = stream->readInt<GLint>();
44 const uint8_t *binary = stream->data() + stream->offset();
45 stream->skip(binaryLength);
46
47 // Load the binary
48 mFunctions->programBinary(mProgramID, binaryFormat, binary, binaryLength);
49
50 // Verify that the program linked
51 if (!checkLinkStatus(infoLog))
52 {
53 return LinkResult(false, gl::Error(GL_NO_ERROR));
54 }
55
56 postLink();
57
58 return LinkResult(true, gl::Error(GL_NO_ERROR));
Geoff Langf9a6f082015-01-22 13:32:49 -050059}
60
61gl::Error ProgramGL::save(gl::BinaryOutputStream *stream)
62{
Geoff Lang6d892662015-10-02 09:57:30 -040063 GLint binaryLength = 0;
64 mFunctions->getProgramiv(mProgramID, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
65
66 std::vector<uint8_t> binary(binaryLength);
67 GLenum binaryFormat = GL_NONE;
68 mFunctions->getProgramBinary(mProgramID, binaryLength, &binaryLength, &binaryFormat,
69 &binary[0]);
70
71 stream->writeInt(binaryFormat);
72 stream->writeInt(binaryLength);
73 stream->writeBytes(&binary[0], binaryLength);
74
75 return gl::Error(GL_NO_ERROR);
Geoff Langf9a6f082015-01-22 13:32:49 -050076}
77
Jamie Madillf5f4ad22015-09-02 18:32:38 +000078LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog)
Geoff Langf9a6f082015-01-22 13:32:49 -050079{
Geoff Lang6d892662015-10-02 09:57:30 -040080 preLink();
Geoff Langb1f435e2015-02-20 10:01:01 -050081
Geoff Lang6d892662015-10-02 09:57:30 -040082 const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(mData.getAttachedVertexShader());
83 const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mData.getAttachedFragmentShader());
Geoff Langb1f435e2015-02-20 10:01:01 -050084
Geoff Langb1f435e2015-02-20 10:01:01 -050085 // Attach the shaders
86 mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
87 mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
88
Geoff Lang1528e562015-08-24 15:10:58 -040089 // Bind attribute locations to match the GL layer.
90 for (const sh::Attribute &attribute : mData.getAttributes())
91 {
92 if (!attribute.staticUse)
93 {
94 continue;
95 }
96
97 mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str());
Geoff Lang1528e562015-08-24 15:10:58 -040098 }
99
Geoff Langb1f435e2015-02-20 10:01:01 -0500100 // Link and verify
101 mFunctions->linkProgram(mProgramID);
102
Geoff Lang0ca53782015-05-07 13:49:39 -0400103 // Detach the shaders
104 mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
105 mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
106
107 // Verify the link
Geoff Lang6d892662015-10-02 09:57:30 -0400108 if (!checkLinkStatus(infoLog))
Geoff Langb1f435e2015-02-20 10:01:01 -0500109 {
Geoff Langb1f435e2015-02-20 10:01:01 -0500110 return LinkResult(false, gl::Error(GL_NO_ERROR));
111 }
112
Geoff Lang6d892662015-10-02 09:57:30 -0400113 postLink();
Geoff Langb1f435e2015-02-20 10:01:01 -0500114
Geoff Langb1f435e2015-02-20 10:01:01 -0500115 return LinkResult(true, gl::Error(GL_NO_ERROR));
Geoff Langf9a6f082015-01-22 13:32:49 -0500116}
117
Jamie Madill36cfd6a2015-08-18 10:46:20 -0400118GLboolean ProgramGL::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
119{
120 // TODO(jmadill): implement validate
121 return true;
122}
123
Geoff Langf9a6f082015-01-22 13:32:49 -0500124void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
125{
Geoff Lang63cbace2015-02-26 10:03:12 -0500126 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400127 mFunctions->uniform1fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500128}
129
130void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
131{
Geoff Lang63cbace2015-02-26 10:03:12 -0500132 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400133 mFunctions->uniform2fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500134}
135
136void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
137{
Geoff Lang63cbace2015-02-26 10:03:12 -0500138 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400139 mFunctions->uniform3fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500140}
141
142void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
143{
Geoff Lang63cbace2015-02-26 10:03:12 -0500144 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400145 mFunctions->uniform4fv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500146}
147
148void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
149{
Geoff Lang63cbace2015-02-26 10:03:12 -0500150 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400151 mFunctions->uniform1iv(uniLoc(location), count, v);
Geoff Langf51bc792015-05-04 14:57:03 -0400152
Jamie Madill62d31cb2015-09-11 13:25:51 -0400153 const gl::VariableLocation &locationEntry = mData.getUniformLocations()[location];
154
155 size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index];
156 if (samplerIndex != GL_INVALID_INDEX)
Geoff Langf51bc792015-05-04 14:57:03 -0400157 {
Jamie Madill62d31cb2015-09-11 13:25:51 -0400158 std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits;
Geoff Langf51bc792015-05-04 14:57:03 -0400159
Jamie Madill62d31cb2015-09-11 13:25:51 -0400160 size_t copyCount =
161 std::max<size_t>(count, boundTextureUnits.size() - locationEntry.element);
162 std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element);
Geoff Langf51bc792015-05-04 14:57:03 -0400163 }
Geoff Langf9a6f082015-01-22 13:32:49 -0500164}
165
166void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
167{
Geoff Lang63cbace2015-02-26 10:03:12 -0500168 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400169 mFunctions->uniform2iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500170}
171
172void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
173{
Geoff Lang63cbace2015-02-26 10:03:12 -0500174 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400175 mFunctions->uniform3iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500176}
177
178void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
179{
Geoff Lang63cbace2015-02-26 10:03:12 -0500180 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400181 mFunctions->uniform4iv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500182}
183
184void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
185{
Geoff Lang63cbace2015-02-26 10:03:12 -0500186 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500187 mFunctions->uniform1uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500188}
189
190void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
191{
Geoff Lang63cbace2015-02-26 10:03:12 -0500192 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400193 mFunctions->uniform2uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500194}
195
196void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
197{
Geoff Lang63cbace2015-02-26 10:03:12 -0500198 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400199 mFunctions->uniform3uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500200}
201
202void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
203{
Geoff Lang63cbace2015-02-26 10:03:12 -0500204 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400205 mFunctions->uniform4uiv(uniLoc(location), count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500206}
207
208void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
209{
Geoff Lang63cbace2015-02-26 10:03:12 -0500210 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400211 mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500212}
213
214void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
215{
Geoff Lang63cbace2015-02-26 10:03:12 -0500216 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400217 mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500218}
219
220void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
221{
Geoff Lang63cbace2015-02-26 10:03:12 -0500222 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400223 mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500224}
225
226void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
227{
Geoff Lang63cbace2015-02-26 10:03:12 -0500228 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400229 mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500230}
231
232void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
233{
Geoff Lang63cbace2015-02-26 10:03:12 -0500234 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400235 mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500236}
237
238void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
239{
Geoff Lang63cbace2015-02-26 10:03:12 -0500240 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400241 mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500242}
243
244void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
245{
Geoff Lang63cbace2015-02-26 10:03:12 -0500246 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400247 mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500248}
249
250void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
251{
Geoff Lang63cbace2015-02-26 10:03:12 -0500252 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400253 mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500254}
255
256void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
257{
Geoff Lang63cbace2015-02-26 10:03:12 -0500258 mStateManager->useProgram(mProgramID);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400259 mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500260}
261
Geoff Lang5d124a62015-09-15 13:03:27 -0400262void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
263{
264 mFunctions->uniformBlockBinding(mProgramID, mUniformBlockRealLocationMap[uniformBlockIndex],
265 uniformBlockBinding);
266}
267
Geoff Langb1f435e2015-02-20 10:01:01 -0500268GLuint ProgramGL::getProgramID() const
269{
270 return mProgramID;
271}
272
Geoff Langf51bc792015-05-04 14:57:03 -0400273const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() const
274{
275 return mSamplerBindings;
276}
277
Geoff Lang5d124a62015-09-15 13:03:27 -0400278void ProgramGL::gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
279 std::vector<gl::LinkedUniform> *uniforms)
Jamie Madill62d31cb2015-09-11 13:25:51 -0400280{
Geoff Lang5d124a62015-09-15 13:03:27 -0400281 mUniformBlockRealLocationMap.resize(uniformBlocks->size(), 0);
282
283 for (int i = 0; i < static_cast<int>(uniformBlocks->size()); i++)
284 {
285 auto &uniformBlock = uniformBlocks->at(i);
286
287 std::stringstream fullNameStr;
288 fullNameStr << uniformBlock.name;
289 if (uniformBlock.isArray)
290 {
291 fullNameStr << "[" << uniformBlock.arrayElement << "]";
292 }
293
294 GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, fullNameStr.str().c_str());
295 if (blockIndex != GL_INVALID_INDEX)
296 {
297 mUniformBlockRealLocationMap[i] = blockIndex;
298
299 GLint dataSize = 0;
300 mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
301 &dataSize);
302 uniformBlock.dataSize = dataSize;
303 }
304 else
305 {
306 // Remove this uniform block
307 uniformBlocks->erase(uniformBlocks->begin() + i);
308 i--;
309 }
310 }
311
312 for (int uniformIdx = 0; uniformIdx < static_cast<int>(uniforms->size()); uniformIdx++)
313 {
314 auto &uniform = uniforms->at(uniformIdx);
315 if (uniform.isInDefaultBlock())
316 {
317 continue;
318 }
319
320 const GLchar *uniformName = uniform.name.c_str();
321 GLuint uniformIndex = 0;
322 mFunctions->getUniformIndices(mProgramID, 1, &uniformName, &uniformIndex);
323
Corentin Wallez4fbec002015-10-01 11:47:47 -0700324 if (uniformIndex == GL_INVALID_INDEX)
Geoff Lang5d124a62015-09-15 13:03:27 -0400325 {
326 // Uniform member has been optimized out, remove it from the list
327 // TODO: Clean this up by using a class to wrap around the uniforms so manual removal is
328 // not needed.
329 for (size_t uniformBlockIdx = 0; uniformBlockIdx < uniformBlocks->size();
330 uniformBlockIdx++)
331 {
332 auto &uniformBlock = uniformBlocks->at(uniformBlockIdx);
333 for (int memberIndex = 0;
334 memberIndex < static_cast<int>(uniformBlock.memberUniformIndexes.size());
335 memberIndex++)
336 {
337 if (uniformBlock.memberUniformIndexes[memberIndex] ==
338 static_cast<unsigned int>(uniformIdx))
339 {
340 uniformBlock.memberUniformIndexes.erase(
341 uniformBlock.memberUniformIndexes.begin() + memberIndex);
342 memberIndex--;
343 }
344 else if (uniformBlock.memberUniformIndexes[memberIndex] >
345 static_cast<unsigned int>(uniformIdx))
346 {
347 uniformBlock.memberUniformIndexes[memberIndex]--;
348 }
349 }
350 }
351 uniforms->erase(uniforms->begin() + uniformIdx);
352 uniformIdx--;
353 }
354 else
355 {
356 GLint offset = 0;
357 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET,
358 &offset);
359 uniform.blockInfo.offset = offset;
360
361 GLint arrayStride = 0;
362 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE,
363 &arrayStride);
364 uniform.blockInfo.arrayStride = arrayStride;
365
366 GLint matrixStride = 0;
367 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
368 &matrixStride);
369 uniform.blockInfo.matrixStride = matrixStride;
370
371 // TODO: determine this at the gl::Program level.
372 GLint isRowMajorMatrix = 0;
373 mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
374 &isRowMajorMatrix);
375 uniform.blockInfo.isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
376 }
377 }
Jamie Madill62d31cb2015-09-11 13:25:51 -0400378}
Geoff Lang6d892662015-10-02 09:57:30 -0400379
380void ProgramGL::preLink()
381{
382 // Reset the program state
383 mUniformRealLocationMap.clear();
384 mSamplerBindings.clear();
385 mUniformIndexToSamplerIndex.clear();
386}
387
388bool ProgramGL::checkLinkStatus(gl::InfoLog &infoLog)
389{
390 GLint linkStatus = GL_FALSE;
391 mFunctions->getProgramiv(mProgramID, GL_LINK_STATUS, &linkStatus);
392 if (linkStatus == GL_FALSE)
393 {
394 // Linking failed, put the error into the info log
395 GLint infoLogLength = 0;
396 mFunctions->getProgramiv(mProgramID, GL_INFO_LOG_LENGTH, &infoLogLength);
397
398 std::vector<char> buf(infoLogLength);
399 mFunctions->getProgramInfoLog(mProgramID, infoLogLength, nullptr, &buf[0]);
400
401 infoLog << &buf[0];
402 TRACE("\n%s", &buf[0]);
403
404 // TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case
405 return false;
406 }
407
408 return true;
409}
410
411void ProgramGL::postLink()
412{
413 // Query the uniform information
414 ASSERT(mUniformRealLocationMap.empty());
415 const auto &uniforms = mData.getUniforms();
416 for (const gl::VariableLocation &entry : mData.getUniformLocations())
417 {
418 // From the spec:
419 // "Locations for sequential array indices are not required to be sequential."
420 const gl::LinkedUniform &uniform = uniforms[entry.index];
421 std::stringstream fullNameStr;
422 fullNameStr << uniform.name;
423 if (uniform.isArray())
424 {
425 fullNameStr << "[" << entry.element << "]";
426 }
427 const std::string &fullName = fullNameStr.str();
428
429 GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
430 mUniformRealLocationMap.push_back(realLocation);
431 }
432
433 mUniformIndexToSamplerIndex.resize(mData.getUniforms().size(), GL_INVALID_INDEX);
434
435 for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId)
436 {
437 const gl::LinkedUniform &linkedUniform = uniforms[uniformId];
438
439 if (!linkedUniform.isSampler() || !linkedUniform.staticUse)
440 {
441 continue;
442 }
443
444 mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size();
445
446 // If uniform is a sampler type, insert it into the mSamplerBindings array
447 SamplerBindingGL samplerBinding;
448 samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type);
449 samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0);
450 mSamplerBindings.push_back(samplerBinding);
451 }
452}
Geoff Langf9a6f082015-01-22 13:32:49 -0500453}