1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // Program.cpp: Implements the Program class. Implements GL program objects
16 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
23 #include "TransformFeedback.h"
24 #include "utilities.h"
25 #include "common/debug.h"
26 #include "Shader/PixelShader.hpp"
27 #include "Shader/VertexShader.hpp"
34 unsigned int Program::currentSerial = 1;
36 std::string str(int i)
39 sprintf(buffer, "%d", i);
43 Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)
48 offset = uniform.blockInfo.offset;
49 arrayStride = uniform.blockInfo.arrayStride;
50 matrixStride = uniform.blockInfo.matrixStride;
51 isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
59 isRowMajorMatrix = false;
63 Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
64 const BlockInfo &blockInfo)
65 : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
67 if(blockInfo.index == -1)
69 size_t bytes = UniformTypeSize(type) * size();
70 data = new unsigned char[bytes];
71 memset(data, 0, bytes);
88 bool Uniform::isArray() const
90 return arraySize >= 1;
93 int Uniform::size() const
95 return arraySize > 0 ? arraySize : 1;
98 int Uniform::registerCount() const
100 return size() * VariableRegisterCount(type);
103 UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) :
104 name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX)
108 void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)
112 case GL_VERTEX_SHADER:
113 vsRegisterIndex = registerIndex;
115 case GL_FRAGMENT_SHADER:
116 psRegisterIndex = registerIndex;
123 bool UniformBlock::isArrayElement() const
125 return elementIndex != GL_INVALID_INDEX;
128 bool UniformBlock::isReferencedByVertexShader() const
130 return vsRegisterIndex != GL_INVALID_INDEX;
133 bool UniformBlock::isReferencedByFragmentShader() const
135 return psRegisterIndex != GL_INVALID_INDEX;
138 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
142 LinkedVarying::LinkedVarying()
146 LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col)
147 : name(name), type(type), size(size), reg(reg), col(col)
151 Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
153 device = getDevice();
160 transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;
161 totalLinkedVaryingsComponents = 0;
166 resetUniformBlockBindings();
170 retrievableBinary = false;
180 vertexShader->release();
185 fragmentShader->release();
189 bool Program::attachShader(Shader *shader)
191 if(shader->getType() == GL_VERTEX_SHADER)
198 vertexShader = (VertexShader*)shader;
199 vertexShader->addRef();
201 else if(shader->getType() == GL_FRAGMENT_SHADER)
208 fragmentShader = (FragmentShader*)shader;
209 fragmentShader->addRef();
211 else UNREACHABLE(shader->getType());
216 bool Program::detachShader(Shader *shader)
218 if(shader->getType() == GL_VERTEX_SHADER)
220 if(vertexShader != shader)
225 vertexShader->release();
228 else if(shader->getType() == GL_FRAGMENT_SHADER)
230 if(fragmentShader != shader)
235 fragmentShader->release();
238 else UNREACHABLE(shader->getType());
243 int Program::getAttachedShadersCount() const
245 return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
248 sw::PixelShader *Program::getPixelShader()
253 sw::VertexShader *Program::getVertexShader()
258 void Program::bindAttributeLocation(GLuint index, const char *name)
260 if(index < MAX_VERTEX_ATTRIBS)
262 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
264 attributeBinding[i].erase(name);
267 attributeBinding[index].insert(name);
271 GLint Program::getAttributeLocation(const char *name)
275 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
277 if(linkedAttribute[index].name == std::string(name))
287 int Program::getAttributeStream(int attributeIndex)
289 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
291 return attributeStream[attributeIndex];
294 // Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
295 GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
297 GLint logicalTextureUnit = -1;
301 case sw::SAMPLER_PIXEL:
302 ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
304 if(samplersPS[samplerIndex].active)
306 logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
309 case sw::SAMPLER_VERTEX:
310 ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
312 if(samplersVS[samplerIndex].active)
314 logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
317 default: UNREACHABLE(type);
320 if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
322 return logicalTextureUnit;
328 // Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
329 TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
333 case sw::SAMPLER_PIXEL:
334 ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
335 ASSERT(samplersPS[samplerIndex].active);
336 return samplersPS[samplerIndex].textureType;
337 case sw::SAMPLER_VERTEX:
338 ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
339 ASSERT(samplersVS[samplerIndex].active);
340 return samplersVS[samplerIndex].textureType;
341 default: UNREACHABLE(type);
347 GLint Program::getUniformLocation(const std::string &name) const
349 unsigned int subscript = GL_INVALID_INDEX;
350 std::string baseName = es2::ParseUniformName(name, &subscript);
352 size_t numUniforms = uniformIndex.size();
353 for(size_t location = 0; location < numUniforms; location++)
355 const int index = uniformIndex[location].index;
356 const bool isArray = uniforms[index]->isArray();
358 if(uniformIndex[location].name == baseName &&
359 ((isArray && uniformIndex[location].element == subscript) ||
360 (subscript == GL_INVALID_INDEX)))
362 return (GLint)location;
369 GLuint Program::getUniformIndex(const std::string &name) const
371 unsigned int subscript = GL_INVALID_INDEX;
372 std::string baseName = es2::ParseUniformName(name, &subscript);
374 // The app is not allowed to specify array indices other than 0 for arrays of basic types
375 if(subscript != 0 && subscript != GL_INVALID_INDEX)
377 return GL_INVALID_INDEX;
380 size_t numUniforms = uniforms.size();
381 for(GLuint index = 0; index < numUniforms; index++)
383 if(uniforms[index]->name == baseName)
385 if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
392 return GL_INVALID_INDEX;
395 void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
397 ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
399 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
403 case GL_UNIFORM_BLOCK_DATA_SIZE:
404 *params = static_cast<GLint>(uniformBlock.dataSize);
406 case GL_UNIFORM_BLOCK_NAME_LENGTH:
407 *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
409 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
410 *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
412 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
414 for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
416 params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
420 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
421 *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
423 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
424 *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
426 default: UNREACHABLE(pname);
430 GLuint Program::getUniformBlockIndex(const std::string &name) const
432 unsigned int subscript = GL_INVALID_INDEX;
433 std::string baseName = es2::ParseUniformName(name, &subscript);
435 size_t numUniformBlocks = getActiveUniformBlockCount();
436 for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
438 const UniformBlock &uniformBlock = *uniformBlocks[blockIndex];
439 if(uniformBlock.name == baseName)
441 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
442 if(subscript == uniformBlock.elementIndex || arrayElementZero)
449 return GL_INVALID_INDEX;
452 void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
454 uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
457 GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
459 return uniformBlockBindings[uniformBlockIndex];
462 void Program::resetUniformBlockBindings()
464 for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++)
466 uniformBlockBindings[blockId] = 0;
470 bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements)
472 ASSERT(numElements >= 1 && numElements <= 4);
474 static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 };
475 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
477 if(location < 0 || location >= (int)uniformIndex.size())
482 Uniform *targetUniform = uniforms[uniformIndex[location].index];
483 targetUniform->dirty = true;
485 int size = targetUniform->size();
487 if(size == 1 && count > 1)
489 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
492 count = std::min(size - (int)uniformIndex[location].element, count);
494 int index = numElements - 1;
495 if(targetUniform->type == floatType[index])
497 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements,
498 v, numElements * sizeof(GLfloat)* count);
500 else if(targetUniform->type == boolType[index])
502 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements;
504 for(int i = 0; i < count * numElements; i++)
506 boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE;
517 bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
519 return setUniformfv(location, count, v, 1);
522 bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
524 return setUniformfv(location, count, v, 2);
527 bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
529 return setUniformfv(location, count, v, 3);
532 bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
534 return setUniformfv(location, count, v, 4);
537 bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type)
545 case GL_FLOAT_MAT2x3:
546 case GL_FLOAT_MAT3x2:
549 case GL_FLOAT_MAT2x4:
550 case GL_FLOAT_MAT4x2:
556 case GL_FLOAT_MAT3x4:
557 case GL_FLOAT_MAT4x3:
567 if(location < 0 || location >= (int)uniformIndex.size())
572 Uniform *targetUniform = uniforms[uniformIndex[location].index];
573 targetUniform->dirty = true;
575 if(targetUniform->type != type)
580 int size = targetUniform->size();
582 if(size == 1 && count > 1)
584 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
587 count = std::min(size - (int)uniformIndex[location].element, count);
589 GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements);
591 if(transpose == GL_FALSE)
593 memcpy(dst, value, numElements * sizeof(GLfloat) * count);
597 const int rowSize = VariableRowCount(type);
598 const int colSize = VariableColumnCount(type);
599 for(int n = 0; n < count; ++n)
601 for(int i = 0; i < colSize; ++i)
603 for(int j = 0; j < rowSize; ++j)
605 dst[i * rowSize + j] = value[j * colSize + i];
609 value += numElements;
617 bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
619 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2);
622 bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
624 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3);
627 bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
629 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4);
632 bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
634 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3);
637 bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
639 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2);
642 bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
644 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4);
647 bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
649 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4);
652 bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
654 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2);
657 bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
659 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3);
662 bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
664 if(location < 0 || location >= (int)uniformIndex.size())
669 Uniform *targetUniform = uniforms[uniformIndex[location].index];
670 targetUniform->dirty = true;
672 int size = targetUniform->size();
674 if(size == 1 && count > 1)
676 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
679 count = std::min(size - (int)uniformIndex[location].element, count);
681 if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
683 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
684 v, sizeof(GLint) * count);
686 else if(targetUniform->type == GL_BOOL)
688 GLboolean *boolParams = new GLboolean[count];
690 for(int i = 0; i < count; i++)
694 boolParams[i] = GL_FALSE;
698 boolParams[i] = GL_TRUE;
702 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
703 boolParams, sizeof(GLboolean) * count);
715 bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
717 static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
718 static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
719 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
721 if(location < 0 || location >= (int)uniformIndex.size())
726 Uniform *targetUniform = uniforms[uniformIndex[location].index];
727 targetUniform->dirty = true;
729 int size = targetUniform->size();
731 if(size == 1 && count > 1)
733 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
736 count = std::min(size - (int)uniformIndex[location].element, count);
738 int index = numElements - 1;
739 if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])
741 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
742 v, numElements * sizeof(GLint)* count);
744 else if(targetUniform->type == boolType[index])
746 GLboolean *boolParams = new GLboolean[count * numElements];
748 for(int i = 0; i < count * numElements; i++)
750 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
753 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
754 boolParams, numElements * sizeof(GLboolean)* count);
766 bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
768 return setUniformiv(location, count, v, 2);
771 bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
773 return setUniformiv(location, count, v, 3);
776 bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
778 return setUniformiv(location, count, v, 4);
781 bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
783 if(location < 0 || location >= (int)uniformIndex.size())
788 Uniform *targetUniform = uniforms[uniformIndex[location].index];
789 targetUniform->dirty = true;
791 int size = targetUniform->size();
793 if(size == 1 && count > 1)
795 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
798 count = std::min(size - (int)uniformIndex[location].element, count);
800 if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
802 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
803 v, sizeof(GLuint)* count);
805 else if(targetUniform->type == GL_BOOL)
807 GLboolean *boolParams = new GLboolean[count];
809 for(int i = 0; i < count; i++)
813 boolParams[i] = GL_FALSE;
817 boolParams[i] = GL_TRUE;
821 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
822 boolParams, sizeof(GLboolean)* count);
834 bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
836 static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
837 static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
838 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
840 if(location < 0 || location >= (int)uniformIndex.size())
845 Uniform *targetUniform = uniforms[uniformIndex[location].index];
846 targetUniform->dirty = true;
848 int size = targetUniform->size();
850 if(size == 1 && count > 1)
852 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
855 count = std::min(size - (int)uniformIndex[location].element, count);
857 int index = numElements - 1;
858 if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])
860 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
861 v, numElements * sizeof(GLuint)* count);
863 else if(targetUniform->type == boolType[index])
865 GLboolean *boolParams = new GLboolean[count * numElements];
867 for(int i = 0; i < count * numElements; i++)
869 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
872 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
873 boolParams, numElements * sizeof(GLboolean)* count);
885 bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
887 return setUniformuiv(location, count, v, 2);
890 bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
892 return setUniformuiv(location, count, v, 3);
895 bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
897 return setUniformuiv(location, count, v, 4);
900 bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
902 if(location < 0 || location >= (int)uniformIndex.size())
907 Uniform *targetUniform = uniforms[uniformIndex[location].index];
908 unsigned int count = UniformComponentCount(targetUniform->type);
910 // Sized query - ensure the provided buffer is large enough
911 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
916 switch(UniformComponentType(targetUniform->type))
920 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
922 for(unsigned int i = 0; i < count; i++)
924 params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
929 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
930 count * sizeof(GLfloat));
934 GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
936 for(unsigned int i = 0; i < count; i++)
938 params[i] = (float)intParams[i];
942 case GL_UNSIGNED_INT:
944 GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count;
946 for(unsigned int i = 0; i < count; i++)
948 params[i] = (float)uintParams[i];
952 default: UNREACHABLE(targetUniform->type);
958 bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
960 if(location < 0 || location >= (int)uniformIndex.size())
965 Uniform *targetUniform = uniforms[uniformIndex[location].index];
966 unsigned int count = UniformComponentCount(targetUniform->type);
968 // Sized query - ensure the provided buffer is large enough
969 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint))
974 switch(UniformComponentType(targetUniform->type))
978 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
980 for(unsigned int i = 0; i < count; i++)
982 params[i] = (GLint)boolParams[i];
988 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
990 for(unsigned int i = 0; i < count; i++)
992 params[i] = (GLint)floatParams[i];
997 case GL_UNSIGNED_INT:
998 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
999 count * sizeof(GLint));
1001 default: UNREACHABLE(targetUniform->type);
1007 bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
1009 if(location < 0 || location >= (int)uniformIndex.size())
1014 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1015 unsigned int count = UniformComponentCount(targetUniform->type);
1017 // Sized query - ensure the provided buffer is large enough
1018 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint))
1023 switch(UniformComponentType(targetUniform->type))
1027 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
1029 for(unsigned int i = 0; i < count; i++)
1031 params[i] = (GLuint)boolParams[i];
1037 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
1039 for(unsigned int i = 0; i < count; i++)
1041 params[i] = (GLuint)floatParams[i];
1046 case GL_UNSIGNED_INT:
1047 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint),
1048 count * sizeof(GLuint));
1050 default: UNREACHABLE(targetUniform->type);
1056 void Program::dirtyAllUniforms()
1058 size_t numUniforms = uniforms.size();
1059 for(size_t index = 0; index < numUniforms; index++)
1061 uniforms[index]->dirty = true;
1065 // Applies all the uniforms set for this program object to the device
1066 void Program::applyUniforms()
1068 GLint numUniforms = static_cast<GLint>(uniformIndex.size());
1069 for(GLint location = 0; location < numUniforms; location++)
1071 if(uniformIndex[location].element != 0)
1076 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1078 if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
1080 GLsizei size = targetUniform->size();
1081 GLfloat *f = (GLfloat*)targetUniform->data;
1082 GLint *i = (GLint*)targetUniform->data;
1083 GLuint *ui = (GLuint*)targetUniform->data;
1084 GLboolean *b = (GLboolean*)targetUniform->data;
1086 switch(targetUniform->type)
1088 case GL_BOOL: applyUniform1bv(location, size, b); break;
1089 case GL_BOOL_VEC2: applyUniform2bv(location, size, b); break;
1090 case GL_BOOL_VEC3: applyUniform3bv(location, size, b); break;
1091 case GL_BOOL_VEC4: applyUniform4bv(location, size, b); break;
1092 case GL_FLOAT: applyUniform1fv(location, size, f); break;
1093 case GL_FLOAT_VEC2: applyUniform2fv(location, size, f); break;
1094 case GL_FLOAT_VEC3: applyUniform3fv(location, size, f); break;
1095 case GL_FLOAT_VEC4: applyUniform4fv(location, size, f); break;
1096 case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, size, f); break;
1097 case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(location, size, f); break;
1098 case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(location, size, f); break;
1099 case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(location, size, f); break;
1100 case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, size, f); break;
1101 case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(location, size, f); break;
1102 case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(location, size, f); break;
1103 case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(location, size, f); break;
1104 case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, size, f); break;
1106 case GL_SAMPLER_CUBE:
1107 case GL_SAMPLER_EXTERNAL_OES:
1108 case GL_SAMPLER_3D_OES:
1109 case GL_SAMPLER_2D_ARRAY:
1110 case GL_SAMPLER_2D_SHADOW:
1111 case GL_SAMPLER_CUBE_SHADOW:
1112 case GL_SAMPLER_2D_ARRAY_SHADOW:
1113 case GL_INT_SAMPLER_2D:
1114 case GL_UNSIGNED_INT_SAMPLER_2D:
1115 case GL_INT_SAMPLER_CUBE:
1116 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1117 case GL_INT_SAMPLER_3D:
1118 case GL_UNSIGNED_INT_SAMPLER_3D:
1119 case GL_INT_SAMPLER_2D_ARRAY:
1120 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1121 case GL_INT: applyUniform1iv(location, size, i); break;
1122 case GL_INT_VEC2: applyUniform2iv(location, size, i); break;
1123 case GL_INT_VEC3: applyUniform3iv(location, size, i); break;
1124 case GL_INT_VEC4: applyUniform4iv(location, size, i); break;
1125 case GL_UNSIGNED_INT: applyUniform1uiv(location, size, ui); break;
1126 case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(location, size, ui); break;
1127 case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(location, size, ui); break;
1128 case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(location, size, ui); break;
1130 UNREACHABLE(targetUniform->type);
1133 targetUniform->dirty = false;
1138 void Program::applyUniformBuffers(BufferBinding* uniformBuffers)
1140 GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
1141 GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
1143 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1145 vertexUniformBuffers[bufferBindingIndex] = -1;
1148 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1150 fragmentUniformBuffers[bufferBindingIndex] = -1;
1153 int vertexUniformBufferIndex = 0;
1154 int fragmentUniformBufferIndex = 0;
1155 for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
1157 UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
1159 // Unnecessary to apply an unreferenced standard or shared UBO
1160 if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
1165 GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
1167 if(uniformBlock.isReferencedByVertexShader())
1169 vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
1172 if(uniformBlock.isReferencedByFragmentShader())
1174 fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
1178 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1180 int index = vertexUniformBuffers[bufferBindingIndex];
1181 const gl::BindingPointer<Buffer> &buffer = uniformBuffers[index].get();
1185 device->VertexProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? buffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
1186 index = fragmentUniformBuffers[bufferBindingIndex];
1187 device->PixelProcessor::setUniformBuffer(bufferBindingIndex, (index != -1) ? buffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
1192 void Program::applyTransformFeedback(TransformFeedback* transformFeedback)
1194 // Make sure the flags will fit in a 64 bit unsigned int variable
1195 ASSERT(sw::max<int>(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) <= 64);
1197 BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr;
1199 uint64_t enableTransformFeedback = 0;
1200 if(!transformFeedbackBuffers)
1202 for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
1204 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
1206 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
1210 unsigned int maxVaryings = static_cast<unsigned int>(transformFeedbackLinkedVaryings.size());
1211 switch(transformFeedbackBufferMode)
1213 case GL_SEPARATE_ATTRIBS:
1215 maxVaryings = sw::min(maxVaryings, (unsigned int)MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
1216 // Attribs go to separate buffers
1217 for(unsigned int index = 0; index < maxVaryings; ++index)
1219 int size = transformFeedbackLinkedVaryings[index].size;
1220 int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
1221 int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
1222 int nbRegs = rowCount > 1 ? colCount * size : size;
1223 int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
1224 int componentStride = rowCount * colCount * size;
1225 int baseOffset = transformFeedback->vertexOffset() * componentStride * sizeof(float);
1226 device->VertexProcessor::setTransformFeedbackBuffer(index,
1227 transformFeedbackBuffers[index].get()->getResource(),
1228 transformFeedbackBuffers[index].getOffset() + baseOffset,
1229 transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
1230 nbRegs, nbComponentsPerReg, componentStride);
1231 enableTransformFeedback |= 1ULL << index;
1235 case GL_INTERLEAVED_ATTRIBS:
1237 // OpenGL ES 3.0.4 spec, section 2.15.2:
1238 // In INTERLEAVED_ATTRIBS mode, the values of one or more output variables
1239 // written by a vertex shader are written, interleaved, into the buffer object
1240 // bound to the first transform feedback binding point (index = 0).
1241 sw::Resource* resource = transformFeedbackBuffers[0].get()->getResource();
1242 int componentStride = static_cast<int>(totalLinkedVaryingsComponents);
1243 int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));
1244 maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1245 int totalComponents = 0;
1246 for(unsigned int index = 0; index < maxVaryings; ++index)
1248 int size = transformFeedbackLinkedVaryings[index].size;
1249 int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
1250 int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
1251 int nbRegs = rowCount > 1 ? colCount * size : size;
1252 int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
1253 device->VertexProcessor::setTransformFeedbackBuffer(index, resource,
1254 baseOffset + (totalComponents * sizeof(float)),
1255 transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
1256 nbRegs, nbComponentsPerReg, componentStride);
1257 totalComponents += rowCount * colCount * size;
1258 enableTransformFeedback |= 1ULL << index;
1263 UNREACHABLE(transformFeedbackBufferMode);
1267 // Unset all other transform feedback buffers
1268 for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
1270 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
1273 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
1276 bool Program::linkVaryings()
1278 for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
1280 bool matched = false;
1282 for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); ++output)
1284 if(output->name == input->name)
1286 if(output->type != input->type || output->size() != input->size())
1288 appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
1300 appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
1306 glsl::VaryingList &psVaryings = fragmentShader->varyings;
1307 glsl::VaryingList &vsVaryings = vertexShader->varyings;
1309 for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); ++output)
1311 for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); ++input)
1313 if(output->name == input->name)
1315 int in = input->reg;
1316 int out = output->reg;
1317 int components = VariableRegisterSize(output->type);
1318 int registers = VariableRegisterCount(output->type) * output->size();
1322 if(in + registers > MAX_VARYING_VECTORS)
1324 appendToInfoLog("Too many varyings");
1330 if(out + registers > MAX_VARYING_VECTORS)
1332 appendToInfoLog("Too many varyings");
1336 for(int i = 0; i < registers; i++)
1338 vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, pixelBinary->getInput(in + i, 0).flat));
1341 else // Vertex varying is declared but not written to
1343 for(int i = 0; i < registers; i++)
1345 pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
1357 bool Program::linkTransformFeedback()
1359 size_t totalComponents = 0;
1360 totalLinkedVaryingsComponents = 0;
1362 std::set<std::string> uniqueNames;
1364 for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
1366 unsigned int subscript = GL_INVALID_INDEX;
1367 std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript);
1368 bool hasSubscript = (subscript != GL_INVALID_INDEX);
1370 if(tfVaryingName.find('[') != std::string::npos)
1372 appendToInfoLog("Capture of array sub-elements is undefined and not supported.");
1377 for(const glsl::Varying varying : vertexShader->varyings)
1379 if(tfVaryingName == varying.name)
1381 if(uniqueNames.count(indexedTfVaryingName) > 0)
1383 appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str());
1386 uniqueNames.insert(indexedTfVaryingName);
1388 if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size()))
1390 appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str());
1394 int size = hasSubscript ? 1 : varying.size();
1396 int rowCount = VariableRowCount(varying.type);
1397 int colCount = VariableColumnCount(varying.type);
1398 int componentCount = rowCount * colCount * size;
1399 if(transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
1400 componentCount > sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)
1402 appendToInfoLog("Transform feedback varying's %s components (%d) exceed the maximum separate components (%d).",
1403 varying.name.c_str(), componentCount, sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
1407 totalComponents += componentCount;
1409 int reg = varying.reg;
1412 reg += rowCount > 1 ? colCount * subscript : subscript;
1414 int col = varying.col;
1415 if(tfVaryingName == "gl_PointSize")
1417 // Point size is stored in the y element of the vector, not the x element
1418 col = 1; // FIXME: varying.col could already contain this information
1420 transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col));
1429 appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str());
1434 if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
1435 totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
1437 appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).",
1438 totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1442 totalLinkedVaryingsComponents = totalComponents;
1447 // Links the code of the vertex and pixel shader by matching up their varyings,
1448 // compiling them into binaries, determining the attribute mappings, and collecting
1449 // a list of uniforms
1450 void Program::link()
1454 resetUniformBlockBindings();
1456 if(!fragmentShader || !fragmentShader->isCompiled())
1461 if(!vertexShader || !vertexShader->isCompiled())
1466 vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
1467 pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
1474 if(!linkAttributes())
1479 // Link uniform blocks before uniforms to make it easy to assign block indices to fields
1480 if(!linkUniformBlocks(vertexShader, fragmentShader))
1485 if(!linkUniforms(fragmentShader))
1490 if(!linkUniforms(vertexShader))
1495 if(!linkTransformFeedback())
1500 linked = true; // Success
1503 // Determines the mapping between GL attributes and vertex stream usage indices
1504 bool Program::linkAttributes()
1506 unsigned int usedLocations = 0;
1508 // Link attributes that have a binding location
1509 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
1511 int location = getAttributeBinding(*attribute);
1513 if(location != -1) // Set by glBindAttribLocation
1515 int rows = VariableRegisterCount(attribute->type);
1517 if(rows + location > MAX_VERTEX_ATTRIBS)
1519 appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
1523 // In GLSL 3.00, attribute aliasing produces a link error
1524 // In GLSL 1.00, attribute aliasing is allowed
1525 if(egl::getClientVersion() >= 3)
1527 for(int i = 0; i < rows; i++)
1529 if(!linkedAttribute[location + i].name.empty())
1531 appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute->name.c_str(), linkedAttribute[location].name.c_str(), location);
1537 for(int i = 0; i < rows; i++)
1539 linkedAttribute[location + i] = *attribute;
1540 usedLocations |= 1 << (location + i);
1545 // Link attributes that don't have a binding location
1546 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
1548 int location = getAttributeBinding(*attribute);
1550 if(location == -1) // Not set by glBindAttribLocation
1552 int rows = VariableRegisterCount(attribute->type);
1553 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
1555 if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
1557 appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
1558 return false; // Fail to link
1561 for(int i = 0; i < rows; i++)
1563 linkedAttribute[availableIndex + i] = *attribute;
1568 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
1570 int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
1571 int rows = std::max(VariableRegisterCount(linkedAttribute[attributeIndex].type), 1);
1573 for(int r = 0; r < rows; r++)
1575 attributeStream[attributeIndex++] = index++;
1582 int Program::getAttributeBinding(const glsl::Attribute &attribute)
1584 if(attribute.location != -1)
1586 return attribute.location;
1589 for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
1591 if(attributeBinding[location].find(attribute.name.c_str()) != attributeBinding[location].end())
1600 bool Program::linkUniforms(const Shader *shader)
1602 const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
1604 for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
1606 const glsl::Uniform &uniform = activeUniforms[uniformIndex];
1608 unsigned int blockIndex = GL_INVALID_INDEX;
1609 if(uniform.blockId >= 0)
1611 const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
1612 ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
1613 blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
1614 ASSERT(blockIndex != GL_INVALID_INDEX);
1616 if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))
1625 bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)
1627 if(IsSamplerUniform(type))
1629 int index = registerIndex;
1633 if(shader == GL_VERTEX_SHADER)
1635 if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
1637 samplersVS[index].active = true;
1641 default: UNREACHABLE(type);
1642 case GL_INT_SAMPLER_2D:
1643 case GL_UNSIGNED_INT_SAMPLER_2D:
1644 case GL_SAMPLER_2D_SHADOW:
1645 case GL_SAMPLER_2D: samplersVS[index].textureType = TEXTURE_2D; break;
1646 case GL_INT_SAMPLER_CUBE:
1647 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1648 case GL_SAMPLER_CUBE_SHADOW:
1649 case GL_SAMPLER_CUBE: samplersVS[index].textureType = TEXTURE_CUBE; break;
1650 case GL_INT_SAMPLER_3D:
1651 case GL_UNSIGNED_INT_SAMPLER_3D:
1652 case GL_SAMPLER_3D_OES: samplersVS[index].textureType = TEXTURE_3D; break;
1653 case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;
1654 case GL_INT_SAMPLER_2D_ARRAY:
1655 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1656 case GL_SAMPLER_2D_ARRAY_SHADOW:
1657 case GL_SAMPLER_2D_ARRAY: samplersVS[index].textureType = TEXTURE_2D_ARRAY; break;
1660 samplersVS[index].logicalTextureUnit = 0;
1664 appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
1668 else if(shader == GL_FRAGMENT_SHADER)
1670 if(index < MAX_TEXTURE_IMAGE_UNITS)
1672 samplersPS[index].active = true;
1676 default: UNREACHABLE(type);
1677 case GL_INT_SAMPLER_2D:
1678 case GL_UNSIGNED_INT_SAMPLER_2D:
1679 case GL_SAMPLER_2D_SHADOW:
1680 case GL_SAMPLER_2D: samplersPS[index].textureType = TEXTURE_2D; break;
1681 case GL_INT_SAMPLER_CUBE:
1682 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1683 case GL_SAMPLER_CUBE_SHADOW:
1684 case GL_SAMPLER_CUBE: samplersPS[index].textureType = TEXTURE_CUBE; break;
1685 case GL_INT_SAMPLER_3D:
1686 case GL_UNSIGNED_INT_SAMPLER_3D:
1687 case GL_SAMPLER_3D_OES: samplersPS[index].textureType = TEXTURE_3D; break;
1688 case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;
1689 case GL_INT_SAMPLER_2D_ARRAY:
1690 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1691 case GL_SAMPLER_2D_ARRAY_SHADOW:
1692 case GL_SAMPLER_2D_ARRAY: samplersPS[index].textureType = TEXTURE_2D_ARRAY; break;
1695 samplersPS[index].logicalTextureUnit = 0;
1699 appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
1703 else UNREACHABLE(shader);
1707 while(index < registerIndex + static_cast<int>(arraySize));
1710 Uniform *uniform = 0;
1711 GLint location = getUniformLocation(name);
1713 if(location >= 0) // Previously defined, types must match
1715 uniform = uniforms[uniformIndex[location].index];
1717 if(uniform->type != type)
1719 appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
1723 if(uniform->precision != precision)
1725 appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
1731 uniform = new Uniform(type, precision, name, arraySize, blockInfo);
1739 if(shader == GL_VERTEX_SHADER)
1741 uniform->vsRegisterIndex = registerIndex;
1743 else if(shader == GL_FRAGMENT_SHADER)
1745 uniform->psRegisterIndex = registerIndex;
1747 else UNREACHABLE(shader);
1749 if(location == -1) // Not previously defined
1751 uniforms.push_back(uniform);
1752 unsigned int index = static_cast<unsigned int>(uniforms.size() - 1);
1754 for(int i = 0; i < uniform->size(); i++)
1756 uniformIndex.push_back(UniformLocation(name, i, index));
1760 if(shader == GL_VERTEX_SHADER)
1762 if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
1764 appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
1768 else if(shader == GL_FRAGMENT_SHADER)
1770 if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
1772 appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
1776 else UNREACHABLE(shader);
1781 bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
1783 // validate blocks for the same member types
1784 if(block1.fields.size() != block2.fields.size())
1788 if(block1.arraySize != block2.arraySize)
1792 if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
1796 const size_t numBlockMembers = block1.fields.size();
1797 for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
1799 const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];
1800 const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];
1801 if(member1.name != member2.name ||
1802 member1.arraySize != member2.arraySize ||
1803 member1.precision != member2.precision ||
1804 member1.type != member2.type)
1812 bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)
1814 const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks;
1815 const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks;
1816 // Check that interface blocks defined in the vertex and fragment shaders are identical
1817 typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap;
1818 UniformBlockMap linkedUniformBlocks;
1819 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
1821 const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];
1822 linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;
1824 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
1826 const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];
1827 UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);
1828 if(entry != linkedUniformBlocks.end())
1830 const glsl::UniformBlock &vertexUniformBlock = *entry->second;
1831 if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))
1837 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
1839 const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];
1840 if(!defineUniformBlock(vertexShader, uniformBlock))
1845 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
1847 const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];
1848 if(!defineUniformBlock(fragmentShader, uniformBlock))
1856 bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
1858 GLuint blockIndex = getUniformBlockIndex(block.name);
1860 if(blockIndex == GL_INVALID_INDEX)
1862 const std::vector<int>& fields = block.fields;
1863 std::vector<unsigned int> memberUniformIndexes;
1864 for(size_t i = 0; i < fields.size(); ++i)
1866 memberUniformIndexes.push_back(fields[i]);
1869 if(block.arraySize > 0)
1871 int regIndex = block.registerIndex;
1872 int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
1873 for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc)
1875 uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));
1876 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);
1881 uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
1882 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
1887 int regIndex = block.registerIndex;
1888 int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
1889 int nbBlocks = (block.arraySize > 0) ? block.arraySize : 1;
1890 for(int i = 0; i < nbBlocks; ++i, regIndex += regInc)
1892 uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex);
1899 bool Program::applyUniform(GLint location, float* data)
1901 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1903 if(targetUniform->psRegisterIndex != -1)
1905 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount());
1908 if(targetUniform->vsRegisterIndex != -1)
1910 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount());
1916 bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
1918 int vector[MAX_UNIFORM_VECTORS][4];
1920 for(int i = 0; i < count; i++)
1922 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1930 return applyUniform(location, (float*)vector);
1933 bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
1935 int vector[MAX_UNIFORM_VECTORS][4];
1937 for(int i = 0; i < count; i++)
1939 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1940 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1947 return applyUniform(location, (float*)vector);
1950 bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
1952 int vector[MAX_UNIFORM_VECTORS][4];
1954 for(int i = 0; i < count; i++)
1956 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1957 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1958 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1964 return applyUniform(location, (float*)vector);
1967 bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
1969 int vector[MAX_UNIFORM_VECTORS][4];
1971 for(int i = 0; i < count; i++)
1973 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1974 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1975 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1976 vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1981 return applyUniform(location, (float*)vector);
1984 bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
1986 float vector[MAX_UNIFORM_VECTORS][4];
1988 for(int i = 0; i < count; i++)
1990 vector[i][0] = v[0];
1998 return applyUniform(location, (float*)vector);
2001 bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)
2003 float vector[MAX_UNIFORM_VECTORS][4];
2005 for(int i = 0; i < count; i++)
2007 vector[i][0] = v[0];
2008 vector[i][1] = v[1];
2015 return applyUniform(location, (float*)vector);
2018 bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)
2020 float vector[MAX_UNIFORM_VECTORS][4];
2022 for(int i = 0; i < count; i++)
2024 vector[i][0] = v[0];
2025 vector[i][1] = v[1];
2026 vector[i][2] = v[2];
2032 return applyUniform(location, (float*)vector);
2035 bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)
2037 return applyUniform(location, (float*)v);
2040 bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
2042 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2044 for(int i = 0; i < count; i++)
2046 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0;
2047 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0;
2052 return applyUniform(location, (float*)matrix);
2055 bool Program::applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value)
2057 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2059 for(int i = 0; i < count; i++)
2061 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
2062 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
2067 return applyUniform(location, (float*)matrix);
2070 bool Program::applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value)
2072 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2074 for(int i = 0; i < count; i++)
2076 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];
2077 matrix[i][1][0] = value[4]; matrix[i][1][1] = value[5]; matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];
2082 return applyUniform(location, (float*)matrix);
2085 bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
2087 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2089 for(int i = 0; i < count; i++)
2091 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
2092 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
2093 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0;
2098 return applyUniform(location, (float*)matrix);
2101 bool Program::applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value)
2103 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2105 for(int i = 0; i < count; i++)
2107 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0;
2108 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0;
2109 matrix[i][2][0] = value[4]; matrix[i][2][1] = value[5]; matrix[i][2][2] = 0; matrix[i][2][3] = 0;
2114 return applyUniform(location, (float*)matrix);
2117 bool Program::applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value)
2119 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2121 for(int i = 0; i < count; i++)
2123 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];
2124 matrix[i][1][0] = value[4]; matrix[i][1][1] = value[5]; matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];
2125 matrix[i][2][0] = value[8]; matrix[i][2][1] = value[9]; matrix[i][2][2] = value[10]; matrix[i][2][3] = value[11];
2130 return applyUniform(location, (float*)matrix);
2133 bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
2135 return applyUniform(location, (float*)value);
2138 bool Program::applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value)
2140 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
2142 for(int i = 0; i < count; i++)
2144 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0;
2145 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0;
2146 matrix[i][2][0] = value[4]; matrix[i][2][1] = value[5]; matrix[i][2][2] = 0; matrix[i][2][3] = 0;
2147 matrix[i][3][0] = value[6]; matrix[i][3][1] = value[7]; matrix[i][3][2] = 0; matrix[i][3][3] = 0;
2152 return applyUniform(location, (float*)matrix);
2155 bool Program::applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value)
2157 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
2159 for(int i = 0; i < count; i++)
2161 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
2162 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
2163 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0;
2164 matrix[i][3][0] = value[9]; matrix[i][3][1] = value[10]; matrix[i][3][2] = value[11]; matrix[i][3][3] = 0;
2169 return applyUniform(location, (float*)matrix);
2172 bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
2174 GLint vector[MAX_UNIFORM_VECTORS][4];
2176 for(int i = 0; i < count; i++)
2178 vector[i][0] = v[i];
2184 Uniform *targetUniform = uniforms[uniformIndex[location].index];
2185 if(IsSamplerUniform(targetUniform->type))
2187 if(targetUniform->psRegisterIndex != -1)
2189 for(int i = 0; i < count; i++)
2191 unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
2193 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2195 ASSERT(samplersPS[samplerIndex].active);
2196 samplersPS[samplerIndex].logicalTextureUnit = v[i];
2201 if(targetUniform->vsRegisterIndex != -1)
2203 for(int i = 0; i < count; i++)
2205 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
2207 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
2209 ASSERT(samplersVS[samplerIndex].active);
2210 samplersVS[samplerIndex].logicalTextureUnit = v[i];
2217 return applyUniform(location, (float*)vector);
2223 bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
2225 GLint vector[MAX_UNIFORM_VECTORS][4];
2227 for(int i = 0; i < count; i++)
2229 vector[i][0] = v[0];
2230 vector[i][1] = v[1];
2237 return applyUniform(location, (float*)vector);
2240 bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
2242 GLint vector[MAX_UNIFORM_VECTORS][4];
2244 for(int i = 0; i < count; i++)
2246 vector[i][0] = v[0];
2247 vector[i][1] = v[1];
2248 vector[i][2] = v[2];
2254 return applyUniform(location, (float*)vector);
2257 bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
2259 GLint vector[MAX_UNIFORM_VECTORS][4];
2261 for(int i = 0; i < count; i++)
2263 vector[i][0] = v[0];
2264 vector[i][1] = v[1];
2265 vector[i][2] = v[2];
2266 vector[i][3] = v[3];
2271 return applyUniform(location, (float*)vector);
2274 bool Program::applyUniform1uiv(GLint location, GLsizei count, const GLuint *v)
2276 GLuint vector[MAX_UNIFORM_VECTORS][4];
2278 for(int i = 0; i < count; i++)
2280 vector[i][0] = v[i];
2286 Uniform *targetUniform = uniforms[uniformIndex[location].index];
2287 if(IsSamplerUniform(targetUniform->type))
2289 if(targetUniform->psRegisterIndex != -1)
2291 for(int i = 0; i < count; i++)
2293 unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
2295 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2297 ASSERT(samplersPS[samplerIndex].active);
2298 samplersPS[samplerIndex].logicalTextureUnit = v[i];
2303 if(targetUniform->vsRegisterIndex != -1)
2305 for(int i = 0; i < count; i++)
2307 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
2309 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
2311 ASSERT(samplersVS[samplerIndex].active);
2312 samplersVS[samplerIndex].logicalTextureUnit = v[i];
2319 return applyUniform(location, (float*)vector);
2325 bool Program::applyUniform2uiv(GLint location, GLsizei count, const GLuint *v)
2327 GLuint vector[MAX_UNIFORM_VECTORS][4];
2329 for(int i = 0; i < count; i++)
2331 vector[i][0] = v[0];
2332 vector[i][1] = v[1];
2339 return applyUniform(location, (float*)vector);
2342 bool Program::applyUniform3uiv(GLint location, GLsizei count, const GLuint *v)
2344 GLuint vector[MAX_UNIFORM_VECTORS][4];
2346 for(int i = 0; i < count; i++)
2348 vector[i][0] = v[0];
2349 vector[i][1] = v[1];
2350 vector[i][2] = v[2];
2356 return applyUniform(location, (float*)vector);
2359 bool Program::applyUniform4uiv(GLint location, GLsizei count, const GLuint *v)
2361 GLuint vector[MAX_UNIFORM_VECTORS][4];
2363 for(int i = 0; i < count; i++)
2365 vector[i][0] = v[0];
2366 vector[i][1] = v[1];
2367 vector[i][2] = v[2];
2368 vector[i][3] = v[3];
2373 return applyUniform(location, (float*)vector);
2376 void Program::appendToInfoLog(const char *format, ...)
2386 va_start(vararg, format);
2387 vsnprintf(info, sizeof(info), format, vararg);
2390 size_t infoLength = strlen(info);
2394 infoLog = new char[infoLength + 2];
2395 strcpy(infoLog, info);
2396 strcpy(infoLog + infoLength, "\n");
2400 size_t logLength = strlen(infoLog);
2401 char *newLog = new char[logLength + infoLength + 2];
2402 strcpy(newLog, infoLog);
2403 strcpy(newLog + logLength, info);
2404 strcpy(newLog + logLength + infoLength, "\n");
2411 void Program::resetInfoLog()
2420 // Returns the program object to an unlinked state, before re-linking, or at destruction
2421 void Program::unlink()
2423 delete vertexBinary;
2428 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
2430 linkedAttribute[index].name.clear();
2431 attributeStream[index] = -1;
2434 for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
2436 samplersPS[index].active = false;
2439 for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
2441 samplersVS[index].active = false;
2444 while(!uniforms.empty())
2446 delete uniforms.back();
2447 uniforms.pop_back();
2450 while(!uniformBlocks.empty())
2452 delete uniformBlocks.back();
2453 uniformBlocks.pop_back();
2456 uniformIndex.clear();
2457 transformFeedbackLinkedVaryings.clear();
2465 bool Program::isLinked() const
2470 bool Program::isValidated() const
2475 GLint Program::getBinaryLength() const
2481 void Program::release()
2485 if(referenceCount == 0 && orphaned)
2487 resourceManager->deleteProgram(handle);
2491 void Program::addRef()
2496 unsigned int Program::getRefCount() const
2498 return referenceCount;
2501 unsigned int Program::getSerial() const
2506 unsigned int Program::issueSerial()
2508 return currentSerial++;
2511 size_t Program::getInfoLogLength() const
2519 return strlen(infoLog) + 1;
2523 void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
2531 index = std::min(bufSize - 1, (int)strlen(infoLog));
2532 memcpy(buffer, infoLog, index);
2535 buffer[index] = '\0';
2544 void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
2548 if(vertexShader && (total < maxCount))
2550 shaders[total++] = vertexShader->getName();
2553 if(fragmentShader && (total < maxCount))
2555 shaders[total++] = fragmentShader->getName();
2564 void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2566 // Skip over inactive attributes
2567 unsigned int activeAttribute = 0;
2568 unsigned int attribute;
2569 for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2571 if(linkedAttribute[attribute].name.empty())
2576 if(activeAttribute == index)
2586 const char *string = linkedAttribute[attribute].name.c_str();
2588 strncpy(name, string, bufsize);
2589 name[bufsize - 1] = '\0';
2593 *length = static_cast<GLsizei>(strlen(name));
2597 *size = 1; // Always a single 'type' instance
2599 *type = linkedAttribute[attribute].type;
2602 size_t Program::getActiveAttributeCount() const
2606 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2608 if(!linkedAttribute[attributeIndex].name.empty())
2617 GLint Program::getActiveAttributeMaxLength() const
2621 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2623 if(!linkedAttribute[attributeIndex].name.empty())
2625 maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
2632 void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2636 std::string string = uniforms[index]->name;
2638 if(uniforms[index]->isArray())
2643 strncpy(name, string.c_str(), bufsize);
2644 name[bufsize - 1] = '\0';
2648 *length = static_cast<GLsizei>(strlen(name));
2652 *size = uniforms[index]->size();
2654 *type = uniforms[index]->type;
2657 size_t Program::getActiveUniformCount() const
2659 return uniforms.size();
2662 GLint Program::getActiveUniformMaxLength() const
2666 size_t numUniforms = uniforms.size();
2667 for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
2669 if(!uniforms[uniformIndex]->name.empty())
2671 int length = (int)(uniforms[uniformIndex]->name.length() + 1);
2672 if(uniforms[uniformIndex]->isArray())
2674 length += 3; // Counting in "[0]".
2676 maxLength = std::max(length, maxLength);
2683 GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
2685 const Uniform& uniform = *uniforms[index];
2688 case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
2689 case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.size());
2690 case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
2691 case GL_UNIFORM_BLOCK_INDEX: return uniform.blockInfo.index;
2692 case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
2693 case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
2694 case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
2695 case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
2703 void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
2705 ASSERT(index < getActiveUniformBlockCount());
2707 const UniformBlock &uniformBlock = *uniformBlocks[index];
2711 std::string string = uniformBlock.name;
2713 if(uniformBlock.isArrayElement())
2715 std::ostringstream elementIndex;
2716 elementIndex << uniformBlock.elementIndex;
2717 string += "[" + elementIndex.str() + "]";
2720 strncpy(name, string.c_str(), bufSize);
2721 name[bufSize - 1] = '\0';
2725 *length = static_cast<GLsizei>(strlen(name));
2730 size_t Program::getActiveUniformBlockCount() const
2732 return uniformBlocks.size();
2735 GLint Program::getActiveUniformBlockMaxLength() const
2737 GLint maxLength = 0;
2741 size_t numUniformBlocks = getActiveUniformBlockCount();
2742 for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
2744 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
2745 if(!uniformBlock.name.empty())
2747 GLint length = static_cast<GLint>(uniformBlock.name.length() + 1);
2749 // Counting in "[0]".
2750 const GLint arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
2752 maxLength = std::max(length + arrayLength, maxLength);
2760 void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
2762 transformFeedbackVaryings.resize(count);
2763 for(GLsizei i = 0; i < count; i++)
2765 transformFeedbackVaryings[i] = varyings[i];
2768 transformFeedbackBufferMode = bufferMode;
2771 void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
2775 ASSERT(index < transformFeedbackLinkedVaryings.size());
2776 const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];
2777 GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
2780 *length = lastNameIdx;
2784 *size = varying.size;
2788 *type = varying.type;
2792 memcpy(name, varying.name.c_str(), lastNameIdx);
2793 name[lastNameIdx] = '\0';
2798 GLsizei Program::getTransformFeedbackVaryingCount() const
2802 return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());
2810 GLsizei Program::getTransformFeedbackVaryingMaxLength() const
2814 GLsizei maxSize = 0;
2815 for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)
2817 const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];
2818 maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
2829 GLenum Program::getTransformFeedbackBufferMode() const
2831 return transformFeedbackBufferMode;
2834 void Program::flagForDeletion()
2839 bool Program::isFlaggedForDeletion() const
2844 void Program::validate()
2850 appendToInfoLog("Program has not been successfully linked.");
2856 if(!validateSamplers(true))
2867 bool Program::validateSamplers(bool logErrors)
2869 // if any two active samplers in a program are of different types, but refer to the same
2870 // texture image unit, and this is the current program, then ValidateProgram will fail, and
2871 // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
2873 TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
2875 for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
2877 textureUnitType[i] = TEXTURE_UNKNOWN;
2880 for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
2882 if(samplersPS[i].active)
2884 unsigned int unit = samplersPS[i].logicalTextureUnit;
2886 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
2890 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2896 if(textureUnitType[unit] != TEXTURE_UNKNOWN)
2898 if(samplersPS[i].textureType != textureUnitType[unit])
2902 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2910 textureUnitType[unit] = samplersPS[i].textureType;
2915 for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
2917 if(samplersVS[i].active)
2919 unsigned int unit = samplersVS[i].logicalTextureUnit;
2921 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
2925 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2931 if(textureUnitType[unit] != TEXTURE_UNKNOWN)
2933 if(samplersVS[i].textureType != textureUnitType[unit])
2937 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2945 textureUnitType[unit] = samplersVS[i].textureType;