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"
35 unsigned int Program::currentSerial = 1;
37 std::string str(int i)
40 sprintf(buffer, "%d", i);
44 Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)
49 offset = uniform.blockInfo.offset;
50 arrayStride = uniform.blockInfo.arrayStride;
51 matrixStride = uniform.blockInfo.matrixStride;
52 isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
60 isRowMajorMatrix = false;
64 Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize,
65 const BlockInfo &blockInfo)
66 : type(type), precision(precision), name(name), arraySize(arraySize), blockInfo(blockInfo)
68 if(blockInfo.index == -1)
70 size_t bytes = UniformTypeSize(type) * size();
71 data = new unsigned char[bytes];
72 memset(data, 0, bytes);
89 bool Uniform::isArray() const
91 return arraySize >= 1;
94 int Uniform::size() const
96 return arraySize > 0 ? arraySize : 1;
99 int Uniform::registerCount() const
101 return size() * VariableRegisterCount(type);
104 UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) :
105 name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX)
109 void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)
113 case GL_VERTEX_SHADER:
114 vsRegisterIndex = registerIndex;
116 case GL_FRAGMENT_SHADER:
117 psRegisterIndex = registerIndex;
124 bool UniformBlock::isArrayElement() const
126 return elementIndex != GL_INVALID_INDEX;
129 bool UniformBlock::isReferencedByVertexShader() const
131 return vsRegisterIndex != GL_INVALID_INDEX;
134 bool UniformBlock::isReferencedByFragmentShader() const
136 return psRegisterIndex != GL_INVALID_INDEX;
139 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
143 LinkedVarying::LinkedVarying()
147 LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col)
148 : name(name), type(type), size(size), reg(reg), col(col)
152 Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
159 transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;
160 totalLinkedVaryingsComponents = 0;
165 resetUniformBlockBindings();
169 retrievableBinary = false;
179 vertexShader->release();
184 fragmentShader->release();
188 bool Program::attachShader(Shader *shader)
190 if(shader->getType() == GL_VERTEX_SHADER)
197 vertexShader = (VertexShader*)shader;
198 vertexShader->addRef();
200 else if(shader->getType() == GL_FRAGMENT_SHADER)
207 fragmentShader = (FragmentShader*)shader;
208 fragmentShader->addRef();
210 else UNREACHABLE(shader->getType());
215 bool Program::detachShader(Shader *shader)
217 if(shader->getType() == GL_VERTEX_SHADER)
219 if(vertexShader != shader)
224 vertexShader->release();
227 else if(shader->getType() == GL_FRAGMENT_SHADER)
229 if(fragmentShader != shader)
234 fragmentShader->release();
237 else UNREACHABLE(shader->getType());
242 int Program::getAttachedShadersCount() const
244 return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
247 sw::PixelShader *Program::getPixelShader()
252 sw::VertexShader *Program::getVertexShader()
257 void Program::bindAttributeLocation(GLuint index, const char *name)
259 if(index < MAX_VERTEX_ATTRIBS)
261 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
263 attributeBinding[i].erase(name);
266 attributeBinding[index].insert(name);
270 GLint Program::getAttributeLocation(const char *name)
274 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
276 if(linkedAttribute[index].name == std::string(name))
286 int Program::getAttributeStream(int attributeIndex)
288 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
290 return attributeStream[attributeIndex];
293 // 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)
294 GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
296 GLint logicalTextureUnit = -1;
300 case sw::SAMPLER_PIXEL:
301 ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
303 if(samplersPS[samplerIndex].active)
305 logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
308 case sw::SAMPLER_VERTEX:
309 ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
311 if(samplersVS[samplerIndex].active)
313 logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
316 default: UNREACHABLE(type);
319 if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
321 return logicalTextureUnit;
327 // Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
328 TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
332 case sw::SAMPLER_PIXEL:
333 ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
334 ASSERT(samplersPS[samplerIndex].active);
335 return samplersPS[samplerIndex].textureType;
336 case sw::SAMPLER_VERTEX:
337 ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
338 ASSERT(samplersVS[samplerIndex].active);
339 return samplersVS[samplerIndex].textureType;
340 default: UNREACHABLE(type);
346 GLint Program::getUniformLocation(const std::string &name) const
348 unsigned int subscript = GL_INVALID_INDEX;
349 std::string baseName = es2::ParseUniformName(name, &subscript);
351 size_t numUniforms = uniformIndex.size();
352 for(size_t location = 0; location < numUniforms; location++)
354 const int index = uniformIndex[location].index;
355 const bool isArray = uniforms[index]->isArray();
357 if(uniformIndex[location].name == baseName &&
358 ((isArray && uniformIndex[location].element == subscript) ||
359 (subscript == GL_INVALID_INDEX)))
361 return (GLint)location;
368 GLuint Program::getUniformIndex(const std::string &name) const
370 unsigned int subscript = GL_INVALID_INDEX;
371 std::string baseName = es2::ParseUniformName(name, &subscript);
373 // The app is not allowed to specify array indices other than 0 for arrays of basic types
374 if(subscript != 0 && subscript != GL_INVALID_INDEX)
376 return GL_INVALID_INDEX;
379 size_t numUniforms = uniforms.size();
380 for(GLuint index = 0; index < numUniforms; index++)
382 if(uniforms[index]->name == baseName)
384 if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
391 return GL_INVALID_INDEX;
394 void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
396 ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
398 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
402 case GL_UNIFORM_BLOCK_DATA_SIZE:
403 *params = static_cast<GLint>(uniformBlock.dataSize);
405 case GL_UNIFORM_BLOCK_NAME_LENGTH:
406 *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
408 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
409 *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
411 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
413 for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
415 params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
419 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
420 *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
422 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
423 *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
425 default: UNREACHABLE(pname);
429 GLuint Program::getUniformBlockIndex(const std::string &name) const
431 unsigned int subscript = GL_INVALID_INDEX;
432 std::string baseName = es2::ParseUniformName(name, &subscript);
434 size_t numUniformBlocks = getActiveUniformBlockCount();
435 for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
437 const UniformBlock &uniformBlock = *uniformBlocks[blockIndex];
438 if(uniformBlock.name == baseName)
440 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
441 if(subscript == uniformBlock.elementIndex || arrayElementZero)
448 return GL_INVALID_INDEX;
451 void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
453 uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
456 GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
458 return uniformBlockBindings[uniformBlockIndex];
461 void Program::resetUniformBlockBindings()
463 for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++)
465 uniformBlockBindings[blockId] = 0;
469 bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements)
471 ASSERT(numElements >= 1 && numElements <= 4);
473 static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 };
474 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
476 if(location < 0 || location >= (int)uniformIndex.size())
481 Uniform *targetUniform = uniforms[uniformIndex[location].index];
482 targetUniform->dirty = true;
484 int size = targetUniform->size();
486 if(size == 1 && count > 1)
488 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
491 count = std::min(size - (int)uniformIndex[location].element, count);
493 int index = numElements - 1;
494 if(targetUniform->type == floatType[index])
496 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements,
497 v, numElements * sizeof(GLfloat) * count);
499 else if(targetUniform->type == boolType[index])
501 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements;
503 for(int i = 0; i < count * numElements; i++)
505 boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE;
516 bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
518 return setUniformfv(location, count, v, 1);
521 bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
523 return setUniformfv(location, count, v, 2);
526 bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
528 return setUniformfv(location, count, v, 3);
531 bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
533 return setUniformfv(location, count, v, 4);
536 bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type)
544 case GL_FLOAT_MAT2x3:
545 case GL_FLOAT_MAT3x2:
548 case GL_FLOAT_MAT2x4:
549 case GL_FLOAT_MAT4x2:
555 case GL_FLOAT_MAT3x4:
556 case GL_FLOAT_MAT4x3:
566 if(location < 0 || location >= (int)uniformIndex.size())
571 Uniform *targetUniform = uniforms[uniformIndex[location].index];
572 targetUniform->dirty = true;
574 if(targetUniform->type != type)
579 int size = targetUniform->size();
581 if(size == 1 && count > 1)
583 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
586 count = std::min(size - (int)uniformIndex[location].element, count);
588 GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements);
590 if(transpose == GL_FALSE)
592 memcpy(dst, value, numElements * sizeof(GLfloat) * count);
596 const int rowSize = VariableRowCount(type);
597 const int colSize = VariableColumnCount(type);
598 for(int n = 0; n < count; ++n)
600 for(int i = 0; i < colSize; ++i)
602 for(int j = 0; j < rowSize; ++j)
604 dst[i * rowSize + j] = value[j * colSize + i];
608 value += numElements;
616 bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
618 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2);
621 bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
623 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3);
626 bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
628 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4);
631 bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
633 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3);
636 bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
638 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2);
641 bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
643 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4);
646 bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
648 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4);
651 bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
653 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2);
656 bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
658 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3);
661 bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
663 if(location < 0 || location >= (int)uniformIndex.size())
668 Uniform *targetUniform = uniforms[uniformIndex[location].index];
669 targetUniform->dirty = true;
671 int size = targetUniform->size();
673 if(size == 1 && count > 1)
675 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
678 count = std::min(size - (int)uniformIndex[location].element, count);
680 if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
682 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
683 v, sizeof(GLint) * count);
685 else if(targetUniform->type == GL_BOOL)
687 GLboolean *boolParams = new GLboolean[count];
689 for(int i = 0; i < count; i++)
693 boolParams[i] = GL_FALSE;
697 boolParams[i] = GL_TRUE;
701 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
702 boolParams, sizeof(GLboolean) * count);
714 bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
716 static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
717 static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
718 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
720 if(location < 0 || location >= (int)uniformIndex.size())
725 Uniform *targetUniform = uniforms[uniformIndex[location].index];
726 targetUniform->dirty = true;
728 int size = targetUniform->size();
730 if(size == 1 && count > 1)
732 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
735 count = std::min(size - (int)uniformIndex[location].element, count);
737 int index = numElements - 1;
738 if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])
740 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
741 v, numElements * sizeof(GLint)* count);
743 else if(targetUniform->type == boolType[index])
745 GLboolean *boolParams = new GLboolean[count * numElements];
747 for(int i = 0; i < count * numElements; i++)
749 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
752 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
753 boolParams, numElements * sizeof(GLboolean)* count);
765 bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
767 return setUniformiv(location, count, v, 2);
770 bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
772 return setUniformiv(location, count, v, 3);
775 bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
777 return setUniformiv(location, count, v, 4);
780 bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
782 if(location < 0 || location >= (int)uniformIndex.size())
787 Uniform *targetUniform = uniforms[uniformIndex[location].index];
788 targetUniform->dirty = true;
790 int size = targetUniform->size();
792 if(size == 1 && count > 1)
794 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
797 count = std::min(size - (int)uniformIndex[location].element, count);
799 if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
801 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
802 v, sizeof(GLuint)* count);
804 else if(targetUniform->type == GL_BOOL)
806 GLboolean *boolParams = new GLboolean[count];
808 for(int i = 0; i < count; i++)
812 boolParams[i] = GL_FALSE;
816 boolParams[i] = GL_TRUE;
820 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
821 boolParams, sizeof(GLboolean)* count);
833 bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
835 static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
836 static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
837 static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
839 if(location < 0 || location >= (int)uniformIndex.size())
844 Uniform *targetUniform = uniforms[uniformIndex[location].index];
845 targetUniform->dirty = true;
847 int size = targetUniform->size();
849 if(size == 1 && count > 1)
851 return false; // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
854 count = std::min(size - (int)uniformIndex[location].element, count);
856 int index = numElements - 1;
857 if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])
859 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
860 v, numElements * sizeof(GLuint)* count);
862 else if(targetUniform->type == boolType[index])
864 GLboolean *boolParams = new GLboolean[count * numElements];
866 for(int i = 0; i < count * numElements; i++)
868 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
871 memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
872 boolParams, numElements * sizeof(GLboolean)* count);
884 bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
886 return setUniformuiv(location, count, v, 2);
889 bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
891 return setUniformuiv(location, count, v, 3);
894 bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
896 return setUniformuiv(location, count, v, 4);
899 bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
901 if(location < 0 || location >= (int)uniformIndex.size())
906 Uniform *targetUniform = uniforms[uniformIndex[location].index];
907 unsigned int count = UniformComponentCount(targetUniform->type);
909 // Sized query - ensure the provided buffer is large enough
910 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
915 switch(UniformComponentType(targetUniform->type))
919 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
921 for(unsigned int i = 0; i < count; i++)
923 params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
928 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
929 count * sizeof(GLfloat));
933 GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
935 for(unsigned int i = 0; i < count; i++)
937 params[i] = (float)intParams[i];
941 case GL_UNSIGNED_INT:
943 GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count;
945 for(unsigned int i = 0; i < count; i++)
947 params[i] = (float)uintParams[i];
951 default: UNREACHABLE(targetUniform->type);
957 bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
959 if(location < 0 || location >= (int)uniformIndex.size())
964 Uniform *targetUniform = uniforms[uniformIndex[location].index];
965 unsigned int count = UniformComponentCount(targetUniform->type);
967 // Sized query - ensure the provided buffer is large enough
968 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint))
973 switch(UniformComponentType(targetUniform->type))
977 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
979 for(unsigned int i = 0; i < count; i++)
981 params[i] = (GLint)boolParams[i];
987 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
989 for(unsigned int i = 0; i < count; i++)
991 params[i] = (GLint)floatParams[i];
996 case GL_UNSIGNED_INT:
997 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
998 count * sizeof(GLint));
1000 default: UNREACHABLE(targetUniform->type);
1006 bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
1008 if(location < 0 || location >= (int)uniformIndex.size())
1013 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1014 unsigned int count = UniformComponentCount(targetUniform->type);
1016 // Sized query - ensure the provided buffer is large enough
1017 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint))
1022 switch(UniformComponentType(targetUniform->type))
1026 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
1028 for(unsigned int i = 0; i < count; i++)
1030 params[i] = (GLuint)boolParams[i];
1036 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
1038 for(unsigned int i = 0; i < count; i++)
1040 params[i] = (GLuint)floatParams[i];
1045 case GL_UNSIGNED_INT:
1046 memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint),
1047 count * sizeof(GLuint));
1049 default: UNREACHABLE(targetUniform->type);
1055 void Program::dirtyAllUniforms()
1057 size_t numUniforms = uniforms.size();
1058 for(size_t index = 0; index < numUniforms; index++)
1060 uniforms[index]->dirty = true;
1064 // Applies all the uniforms set for this program object to the device
1065 void Program::applyUniforms(Device *device)
1067 GLint numUniforms = static_cast<GLint>(uniformIndex.size());
1068 for(GLint location = 0; location < numUniforms; location++)
1070 if(uniformIndex[location].element != 0)
1075 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1077 if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
1079 GLsizei size = targetUniform->size();
1080 GLfloat *f = (GLfloat*)targetUniform->data;
1081 GLint *i = (GLint*)targetUniform->data;
1082 GLuint *ui = (GLuint*)targetUniform->data;
1083 GLboolean *b = (GLboolean*)targetUniform->data;
1085 switch(targetUniform->type)
1087 case GL_BOOL: applyUniform1bv(device, location, size, b); break;
1088 case GL_BOOL_VEC2: applyUniform2bv(device, location, size, b); break;
1089 case GL_BOOL_VEC3: applyUniform3bv(device, location, size, b); break;
1090 case GL_BOOL_VEC4: applyUniform4bv(device, location, size, b); break;
1091 case GL_FLOAT: applyUniform1fv(device, location, size, f); break;
1092 case GL_FLOAT_VEC2: applyUniform2fv(device, location, size, f); break;
1093 case GL_FLOAT_VEC3: applyUniform3fv(device, location, size, f); break;
1094 case GL_FLOAT_VEC4: applyUniform4fv(device, location, size, f); break;
1095 case GL_FLOAT_MAT2: applyUniformMatrix2fv(device, location, size, f); break;
1096 case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(device, location, size, f); break;
1097 case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(device, location, size, f); break;
1098 case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(device, location, size, f); break;
1099 case GL_FLOAT_MAT3: applyUniformMatrix3fv(device, location, size, f); break;
1100 case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(device, location, size, f); break;
1101 case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(device, location, size, f); break;
1102 case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(device, location, size, f); break;
1103 case GL_FLOAT_MAT4: applyUniformMatrix4fv(device, location, size, f); break;
1105 case GL_SAMPLER_CUBE:
1106 case GL_SAMPLER_EXTERNAL_OES:
1107 case GL_SAMPLER_3D_OES:
1108 case GL_SAMPLER_2D_ARRAY:
1109 case GL_SAMPLER_2D_SHADOW:
1110 case GL_SAMPLER_CUBE_SHADOW:
1111 case GL_SAMPLER_2D_ARRAY_SHADOW:
1112 case GL_INT_SAMPLER_2D:
1113 case GL_UNSIGNED_INT_SAMPLER_2D:
1114 case GL_INT_SAMPLER_CUBE:
1115 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1116 case GL_INT_SAMPLER_3D:
1117 case GL_UNSIGNED_INT_SAMPLER_3D:
1118 case GL_INT_SAMPLER_2D_ARRAY:
1119 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1120 case GL_INT: applyUniform1iv(device, location, size, i); break;
1121 case GL_INT_VEC2: applyUniform2iv(device, location, size, i); break;
1122 case GL_INT_VEC3: applyUniform3iv(device, location, size, i); break;
1123 case GL_INT_VEC4: applyUniform4iv(device, location, size, i); break;
1124 case GL_UNSIGNED_INT: applyUniform1uiv(device, location, size, ui); break;
1125 case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(device, location, size, ui); break;
1126 case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(device, location, size, ui); break;
1127 case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(device, location, size, ui); break;
1129 UNREACHABLE(targetUniform->type);
1132 targetUniform->dirty = false;
1137 void Program::applyUniformBuffers(Device *device, BufferBinding* uniformBuffers)
1139 GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
1140 GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
1142 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1144 vertexUniformBuffers[bufferBindingIndex] = -1;
1147 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1149 fragmentUniformBuffers[bufferBindingIndex] = -1;
1152 int vertexUniformBufferIndex = 0;
1153 int fragmentUniformBufferIndex = 0;
1154 for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
1156 UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
1158 // Unnecessary to apply an unreferenced standard or shared UBO
1159 if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
1164 GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
1166 if(uniformBlock.isReferencedByVertexShader())
1168 vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
1171 if(uniformBlock.isReferencedByFragmentShader())
1173 fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
1177 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1179 int index = vertexUniformBuffers[bufferBindingIndex];
1180 Buffer* vsBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr;
1181 device->VertexProcessor::setUniformBuffer(bufferBindingIndex,
1182 vsBuffer ? vsBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
1183 index = fragmentUniformBuffers[bufferBindingIndex];
1184 Buffer* psBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr;
1185 device->PixelProcessor::setUniformBuffer(bufferBindingIndex,
1186 psBuffer ? psBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
1190 void Program::applyTransformFeedback(Device *device, TransformFeedback* transformFeedback)
1192 // Make sure the flags will fit in a 64 bit unsigned int variable
1193 ASSERT(sw::max<int>(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) <= 64);
1195 BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr;
1197 uint64_t enableTransformFeedback = 0;
1198 if(!transformFeedbackBuffers)
1200 for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
1202 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
1204 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
1208 unsigned int maxVaryings = static_cast<unsigned int>(transformFeedbackLinkedVaryings.size());
1209 switch(transformFeedbackBufferMode)
1211 case GL_SEPARATE_ATTRIBS:
1213 maxVaryings = sw::min(maxVaryings, (unsigned int)MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
1214 // Attribs go to separate buffers
1215 for(unsigned int index = 0; index < maxVaryings; ++index)
1217 int size = transformFeedbackLinkedVaryings[index].size;
1218 int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
1219 int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
1220 int nbRegs = rowCount > 1 ? colCount * size : size;
1221 int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
1222 int componentStride = rowCount * colCount * size;
1223 int baseOffset = transformFeedback->vertexOffset() * componentStride * sizeof(float);
1224 device->VertexProcessor::setTransformFeedbackBuffer(index,
1225 transformFeedbackBuffers[index].get()->getResource(),
1226 transformFeedbackBuffers[index].getOffset() + baseOffset,
1227 transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
1228 nbRegs, nbComponentsPerReg, componentStride);
1229 enableTransformFeedback |= 1ULL << index;
1233 case GL_INTERLEAVED_ATTRIBS:
1235 // OpenGL ES 3.0.4 spec, section 2.15.2:
1236 // In INTERLEAVED_ATTRIBS mode, the values of one or more output variables
1237 // written by a vertex shader are written, interleaved, into the buffer object
1238 // bound to the first transform feedback binding point (index = 0).
1239 sw::Resource* resource = transformFeedbackBuffers[0].get()->getResource();
1240 int componentStride = static_cast<int>(totalLinkedVaryingsComponents);
1241 int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));
1242 maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1243 int totalComponents = 0;
1244 for(unsigned int index = 0; index < maxVaryings; ++index)
1246 int size = transformFeedbackLinkedVaryings[index].size;
1247 int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
1248 int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
1249 int nbRegs = rowCount > 1 ? colCount * size : size;
1250 int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
1251 device->VertexProcessor::setTransformFeedbackBuffer(index, resource,
1252 baseOffset + (totalComponents * sizeof(float)),
1253 transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
1254 nbRegs, nbComponentsPerReg, componentStride);
1255 totalComponents += rowCount * colCount * size;
1256 enableTransformFeedback |= 1ULL << index;
1261 UNREACHABLE(transformFeedbackBufferMode);
1265 // Unset all other transform feedback buffers
1266 for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
1268 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
1271 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
1274 bool Program::linkVaryings()
1276 for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
1278 bool matched = false;
1280 for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); ++output)
1282 if(output->name == input->name)
1284 if(output->type != input->type || output->size() != input->size())
1286 appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
1298 appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
1304 glsl::VaryingList &psVaryings = fragmentShader->varyings;
1305 glsl::VaryingList &vsVaryings = vertexShader->varyings;
1307 for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); ++output)
1309 bool matched = false;
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());
1356 // For openGL ES 3.0, we need to still add the vertex shader outputs for unmatched varyings, for transform feedback.
1357 for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
1359 std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, nullptr);
1361 if(tfVaryingName == output->name)
1363 int out = output->reg;
1364 int components = VariableRegisterSize(output->type);
1365 int registers = VariableRegisterCount(output->type) * output->size();
1369 if(out + registers > MAX_VARYING_VECTORS)
1371 appendToInfoLog("Too many varyings");
1375 for(int i = 0; i < registers; i++)
1377 vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR));
1389 bool Program::linkTransformFeedback()
1391 size_t totalComponents = 0;
1392 totalLinkedVaryingsComponents = 0;
1394 std::set<std::string> uniqueNames;
1396 for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
1398 unsigned int subscript = GL_INVALID_INDEX;
1399 std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript);
1400 bool hasSubscript = (subscript != GL_INVALID_INDEX);
1402 if(tfVaryingName.find('[') != std::string::npos)
1404 appendToInfoLog("Capture of array sub-elements is undefined and not supported.");
1409 for(const glsl::Varying varying : vertexShader->varyings)
1411 if(tfVaryingName == varying.name)
1413 if(uniqueNames.count(indexedTfVaryingName) > 0)
1415 appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str());
1418 uniqueNames.insert(indexedTfVaryingName);
1420 if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size()))
1422 appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str());
1426 int size = hasSubscript ? 1 : varying.size();
1428 int rowCount = VariableRowCount(varying.type);
1429 int colCount = VariableColumnCount(varying.type);
1430 int componentCount = rowCount * colCount * size;
1431 if(transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
1432 componentCount > sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)
1434 appendToInfoLog("Transform feedback varying's %s components (%d) exceed the maximum separate components (%d).",
1435 varying.name.c_str(), componentCount, sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
1439 totalComponents += componentCount;
1441 int reg = varying.reg;
1444 reg += rowCount > 1 ? colCount * subscript : subscript;
1446 int col = varying.col;
1447 if(tfVaryingName == "gl_PointSize")
1449 // Point size is stored in the y element of the vector, not the x element
1450 col = 1; // FIXME: varying.col could already contain this information
1452 transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col));
1461 appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str());
1466 if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
1467 totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
1469 appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).",
1470 totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1474 totalLinkedVaryingsComponents = totalComponents;
1479 // Links the code of the vertex and pixel shader by matching up their varyings,
1480 // compiling them into binaries, determining the attribute mappings, and collecting
1481 // a list of uniforms
1482 void Program::link()
1486 resetUniformBlockBindings();
1488 if(!fragmentShader || !fragmentShader->isCompiled())
1493 if(!vertexShader || !vertexShader->isCompiled())
1498 vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
1499 pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
1506 if(!linkAttributes())
1511 // Link uniform blocks before uniforms to make it easy to assign block indices to fields
1512 if(!linkUniformBlocks(vertexShader, fragmentShader))
1517 if(!linkUniforms(fragmentShader))
1522 if(!linkUniforms(vertexShader))
1527 if(!linkTransformFeedback())
1532 linked = true; // Success
1535 // Determines the mapping between GL attributes and vertex stream usage indices
1536 bool Program::linkAttributes()
1538 unsigned int usedLocations = 0;
1540 // Link attributes that have a binding location
1541 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
1543 int location = getAttributeBinding(*attribute);
1545 if(location != -1) // Set by glBindAttribLocation
1547 int rows = VariableRegisterCount(attribute->type);
1549 if(rows + location > MAX_VERTEX_ATTRIBS)
1551 appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
1555 // In GLSL 3.00, attribute aliasing produces a link error
1556 // In GLSL 1.00, attribute aliasing is allowed
1557 if(egl::getClientVersion() >= 3)
1559 for(int i = 0; i < rows; i++)
1561 if(!linkedAttribute[location + i].name.empty())
1563 appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute->name.c_str(), linkedAttribute[location].name.c_str(), location);
1569 for(int i = 0; i < rows; i++)
1571 linkedAttribute[location + i] = *attribute;
1572 usedLocations |= 1 << (location + i);
1577 // Link attributes that don't have a binding location
1578 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
1580 int location = getAttributeBinding(*attribute);
1582 if(location == -1) // Not set by glBindAttribLocation
1584 int rows = VariableRegisterCount(attribute->type);
1585 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
1587 if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
1589 appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
1590 return false; // Fail to link
1593 for(int i = 0; i < rows; i++)
1595 linkedAttribute[availableIndex + i] = *attribute;
1600 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
1602 int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
1603 int rows = std::max(VariableRegisterCount(linkedAttribute[attributeIndex].type), 1);
1605 for(int r = 0; r < rows; r++)
1607 attributeStream[attributeIndex++] = index++;
1614 int Program::getAttributeBinding(const glsl::Attribute &attribute)
1616 if(attribute.location != -1)
1618 return attribute.location;
1621 for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
1623 if(attributeBinding[location].find(attribute.name.c_str()) != attributeBinding[location].end())
1632 bool Program::linkUniforms(const Shader *shader)
1634 const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
1636 for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
1638 const glsl::Uniform &uniform = activeUniforms[uniformIndex];
1640 unsigned int blockIndex = GL_INVALID_INDEX;
1641 if(uniform.blockId >= 0)
1643 const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
1644 ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
1645 blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
1646 ASSERT(blockIndex != GL_INVALID_INDEX);
1648 if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))
1657 bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)
1659 if(IsSamplerUniform(type))
1661 int index = registerIndex;
1665 if(shader == GL_VERTEX_SHADER)
1667 if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
1669 samplersVS[index].active = true;
1673 default: UNREACHABLE(type);
1674 case GL_INT_SAMPLER_2D:
1675 case GL_UNSIGNED_INT_SAMPLER_2D:
1676 case GL_SAMPLER_2D_SHADOW:
1677 case GL_SAMPLER_2D: samplersVS[index].textureType = TEXTURE_2D; break;
1678 case GL_INT_SAMPLER_CUBE:
1679 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1680 case GL_SAMPLER_CUBE_SHADOW:
1681 case GL_SAMPLER_CUBE: samplersVS[index].textureType = TEXTURE_CUBE; break;
1682 case GL_INT_SAMPLER_3D:
1683 case GL_UNSIGNED_INT_SAMPLER_3D:
1684 case GL_SAMPLER_3D_OES: samplersVS[index].textureType = TEXTURE_3D; break;
1685 case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;
1686 case GL_INT_SAMPLER_2D_ARRAY:
1687 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1688 case GL_SAMPLER_2D_ARRAY_SHADOW:
1689 case GL_SAMPLER_2D_ARRAY: samplersVS[index].textureType = TEXTURE_2D_ARRAY; break;
1692 samplersVS[index].logicalTextureUnit = 0;
1696 appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
1700 else if(shader == GL_FRAGMENT_SHADER)
1702 if(index < MAX_TEXTURE_IMAGE_UNITS)
1704 samplersPS[index].active = true;
1708 default: UNREACHABLE(type);
1709 case GL_INT_SAMPLER_2D:
1710 case GL_UNSIGNED_INT_SAMPLER_2D:
1711 case GL_SAMPLER_2D_SHADOW:
1712 case GL_SAMPLER_2D: samplersPS[index].textureType = TEXTURE_2D; break;
1713 case GL_INT_SAMPLER_CUBE:
1714 case GL_UNSIGNED_INT_SAMPLER_CUBE:
1715 case GL_SAMPLER_CUBE_SHADOW:
1716 case GL_SAMPLER_CUBE: samplersPS[index].textureType = TEXTURE_CUBE; break;
1717 case GL_INT_SAMPLER_3D:
1718 case GL_UNSIGNED_INT_SAMPLER_3D:
1719 case GL_SAMPLER_3D_OES: samplersPS[index].textureType = TEXTURE_3D; break;
1720 case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;
1721 case GL_INT_SAMPLER_2D_ARRAY:
1722 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1723 case GL_SAMPLER_2D_ARRAY_SHADOW:
1724 case GL_SAMPLER_2D_ARRAY: samplersPS[index].textureType = TEXTURE_2D_ARRAY; break;
1727 samplersPS[index].logicalTextureUnit = 0;
1731 appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
1735 else UNREACHABLE(shader);
1739 while(index < registerIndex + static_cast<int>(arraySize));
1742 Uniform *uniform = 0;
1743 GLint location = getUniformLocation(name);
1745 if(location >= 0) // Previously defined, types must match
1747 uniform = uniforms[uniformIndex[location].index];
1749 if(uniform->type != type)
1751 appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
1755 if(uniform->precision != precision)
1757 appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
1763 uniform = new Uniform(type, precision, name, arraySize, blockInfo);
1771 if(shader == GL_VERTEX_SHADER)
1773 uniform->vsRegisterIndex = registerIndex;
1775 else if(shader == GL_FRAGMENT_SHADER)
1777 uniform->psRegisterIndex = registerIndex;
1779 else UNREACHABLE(shader);
1781 if(location == -1) // Not previously defined
1783 uniforms.push_back(uniform);
1784 unsigned int index = static_cast<unsigned int>(uniforms.size() - 1);
1786 for(int i = 0; i < uniform->size(); i++)
1788 uniformIndex.push_back(UniformLocation(name, i, index));
1792 if(shader == GL_VERTEX_SHADER)
1794 if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
1796 appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
1800 else if(shader == GL_FRAGMENT_SHADER)
1802 if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
1804 appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
1808 else UNREACHABLE(shader);
1813 bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
1815 // validate blocks for the same member types
1816 if(block1.fields.size() != block2.fields.size())
1820 if(block1.arraySize != block2.arraySize)
1824 if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
1828 const size_t numBlockMembers = block1.fields.size();
1829 for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
1831 const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];
1832 const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];
1833 if(member1.name != member2.name ||
1834 member1.arraySize != member2.arraySize ||
1835 member1.precision != member2.precision ||
1836 member1.type != member2.type)
1844 bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)
1846 const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks;
1847 const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks;
1848 // Check that interface blocks defined in the vertex and fragment shaders are identical
1849 typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap;
1850 UniformBlockMap linkedUniformBlocks;
1851 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
1853 const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];
1854 linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;
1856 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
1858 const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];
1859 UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);
1860 if(entry != linkedUniformBlocks.end())
1862 const glsl::UniformBlock &vertexUniformBlock = *entry->second;
1863 if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))
1869 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
1871 const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];
1872 if(!defineUniformBlock(vertexShader, uniformBlock))
1877 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
1879 const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];
1880 if(!defineUniformBlock(fragmentShader, uniformBlock))
1888 bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
1890 GLuint blockIndex = getUniformBlockIndex(block.name);
1892 if(blockIndex == GL_INVALID_INDEX)
1894 const std::vector<int>& fields = block.fields;
1895 std::vector<unsigned int> memberUniformIndexes;
1896 for(size_t i = 0; i < fields.size(); ++i)
1898 memberUniformIndexes.push_back(fields[i]);
1901 if(block.arraySize > 0)
1903 int regIndex = block.registerIndex;
1904 int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
1905 for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc)
1907 uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));
1908 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);
1913 uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
1914 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
1919 int regIndex = block.registerIndex;
1920 int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
1921 int nbBlocks = (block.arraySize > 0) ? block.arraySize : 1;
1922 for(int i = 0; i < nbBlocks; ++i, regIndex += regInc)
1924 uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex);
1931 bool Program::applyUniform(Device *device, GLint location, float* data)
1933 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1935 if(targetUniform->psRegisterIndex != -1)
1937 device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount());
1940 if(targetUniform->vsRegisterIndex != -1)
1942 device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount());
1948 bool Program::applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
1950 int vector[MAX_UNIFORM_VECTORS][4];
1952 for(int i = 0; i < count; i++)
1954 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1962 return applyUniform(device, location, (float*)vector);
1965 bool Program::applyUniform2bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
1967 int vector[MAX_UNIFORM_VECTORS][4];
1969 for(int i = 0; i < count; i++)
1971 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1972 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1979 return applyUniform(device, location, (float*)vector);
1982 bool Program::applyUniform3bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
1984 int vector[MAX_UNIFORM_VECTORS][4];
1986 for(int i = 0; i < count; i++)
1988 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1989 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1990 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1996 return applyUniform(device, location, (float*)vector);
1999 bool Program::applyUniform4bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
2001 int vector[MAX_UNIFORM_VECTORS][4];
2003 for(int i = 0; i < count; i++)
2005 vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
2006 vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
2007 vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
2008 vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
2013 return applyUniform(device, location, (float*)vector);
2016 bool Program::applyUniform1fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
2018 float vector[MAX_UNIFORM_VECTORS][4];
2020 for(int i = 0; i < count; i++)
2022 vector[i][0] = v[0];
2030 return applyUniform(device, location, (float*)vector);
2033 bool Program::applyUniform2fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
2035 float vector[MAX_UNIFORM_VECTORS][4];
2037 for(int i = 0; i < count; i++)
2039 vector[i][0] = v[0];
2040 vector[i][1] = v[1];
2047 return applyUniform(device, location, (float*)vector);
2050 bool Program::applyUniform3fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
2052 float vector[MAX_UNIFORM_VECTORS][4];
2054 for(int i = 0; i < count; i++)
2056 vector[i][0] = v[0];
2057 vector[i][1] = v[1];
2058 vector[i][2] = v[2];
2064 return applyUniform(device, location, (float*)vector);
2067 bool Program::applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
2069 return applyUniform(device, location, (float*)v);
2072 bool Program::applyUniformMatrix2fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2074 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2076 for(int i = 0; i < count; i++)
2078 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0;
2079 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0;
2084 return applyUniform(device, location, (float*)matrix);
2087 bool Program::applyUniformMatrix2x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2089 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2091 for(int i = 0; i < count; i++)
2093 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
2094 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
2099 return applyUniform(device, location, (float*)matrix);
2102 bool Program::applyUniformMatrix2x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2104 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2106 for(int i = 0; i < count; i++)
2108 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];
2109 matrix[i][1][0] = value[4]; matrix[i][1][1] = value[5]; matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];
2114 return applyUniform(device, location, (float*)matrix);
2117 bool Program::applyUniformMatrix3fv(Device *device, 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] = 0;
2124 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
2125 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0;
2130 return applyUniform(device, location, (float*)matrix);
2133 bool Program::applyUniformMatrix3x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2135 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2137 for(int i = 0; i < count; i++)
2139 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0;
2140 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0;
2141 matrix[i][2][0] = value[4]; matrix[i][2][1] = value[5]; matrix[i][2][2] = 0; matrix[i][2][3] = 0;
2146 return applyUniform(device, location, (float*)matrix);
2149 bool Program::applyUniformMatrix3x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2151 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2153 for(int i = 0; i < count; i++)
2155 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];
2156 matrix[i][1][0] = value[4]; matrix[i][1][1] = value[5]; matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];
2157 matrix[i][2][0] = value[8]; matrix[i][2][1] = value[9]; matrix[i][2][2] = value[10]; matrix[i][2][3] = value[11];
2162 return applyUniform(device, location, (float*)matrix);
2165 bool Program::applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2167 return applyUniform(device, location, (float*)value);
2170 bool Program::applyUniformMatrix4x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2172 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
2174 for(int i = 0; i < count; i++)
2176 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = 0; matrix[i][0][3] = 0;
2177 matrix[i][1][0] = value[2]; matrix[i][1][1] = value[3]; matrix[i][1][2] = 0; matrix[i][1][3] = 0;
2178 matrix[i][2][0] = value[4]; matrix[i][2][1] = value[5]; matrix[i][2][2] = 0; matrix[i][2][3] = 0;
2179 matrix[i][3][0] = value[6]; matrix[i][3][1] = value[7]; matrix[i][3][2] = 0; matrix[i][3][3] = 0;
2184 return applyUniform(device, location, (float*)matrix);
2187 bool Program::applyUniformMatrix4x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
2189 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
2191 for(int i = 0; i < count; i++)
2193 matrix[i][0][0] = value[0]; matrix[i][0][1] = value[1]; matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
2194 matrix[i][1][0] = value[3]; matrix[i][1][1] = value[4]; matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
2195 matrix[i][2][0] = value[6]; matrix[i][2][1] = value[7]; matrix[i][2][2] = value[8]; matrix[i][2][3] = 0;
2196 matrix[i][3][0] = value[9]; matrix[i][3][1] = value[10]; matrix[i][3][2] = value[11]; matrix[i][3][3] = 0;
2201 return applyUniform(device, location, (float*)matrix);
2204 bool Program::applyUniform1iv(Device *device, GLint location, GLsizei count, const GLint *v)
2206 GLint vector[MAX_UNIFORM_VECTORS][4];
2208 for(int i = 0; i < count; i++)
2210 vector[i][0] = v[i];
2216 Uniform *targetUniform = uniforms[uniformIndex[location].index];
2217 if(IsSamplerUniform(targetUniform->type))
2219 if(targetUniform->psRegisterIndex != -1)
2221 for(int i = 0; i < count; i++)
2223 unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
2225 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2227 ASSERT(samplersPS[samplerIndex].active);
2228 samplersPS[samplerIndex].logicalTextureUnit = v[i];
2233 if(targetUniform->vsRegisterIndex != -1)
2235 for(int i = 0; i < count; i++)
2237 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
2239 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
2241 ASSERT(samplersVS[samplerIndex].active);
2242 samplersVS[samplerIndex].logicalTextureUnit = v[i];
2249 return applyUniform(device, location, (float*)vector);
2255 bool Program::applyUniform2iv(Device *device, GLint location, GLsizei count, const GLint *v)
2257 GLint vector[MAX_UNIFORM_VECTORS][4];
2259 for(int i = 0; i < count; i++)
2261 vector[i][0] = v[0];
2262 vector[i][1] = v[1];
2269 return applyUniform(device, location, (float*)vector);
2272 bool Program::applyUniform3iv(Device *device, GLint location, GLsizei count, const GLint *v)
2274 GLint vector[MAX_UNIFORM_VECTORS][4];
2276 for(int i = 0; i < count; i++)
2278 vector[i][0] = v[0];
2279 vector[i][1] = v[1];
2280 vector[i][2] = v[2];
2286 return applyUniform(device, location, (float*)vector);
2289 bool Program::applyUniform4iv(Device *device, GLint location, GLsizei count, const GLint *v)
2291 GLint vector[MAX_UNIFORM_VECTORS][4];
2293 for(int i = 0; i < count; i++)
2295 vector[i][0] = v[0];
2296 vector[i][1] = v[1];
2297 vector[i][2] = v[2];
2298 vector[i][3] = v[3];
2303 return applyUniform(device, location, (float*)vector);
2306 bool Program::applyUniform1uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
2308 GLuint vector[MAX_UNIFORM_VECTORS][4];
2310 for(int i = 0; i < count; i++)
2312 vector[i][0] = v[i];
2318 Uniform *targetUniform = uniforms[uniformIndex[location].index];
2319 if(IsSamplerUniform(targetUniform->type))
2321 if(targetUniform->psRegisterIndex != -1)
2323 for(int i = 0; i < count; i++)
2325 unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
2327 if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2329 ASSERT(samplersPS[samplerIndex].active);
2330 samplersPS[samplerIndex].logicalTextureUnit = v[i];
2335 if(targetUniform->vsRegisterIndex != -1)
2337 for(int i = 0; i < count; i++)
2339 unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
2341 if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
2343 ASSERT(samplersVS[samplerIndex].active);
2344 samplersVS[samplerIndex].logicalTextureUnit = v[i];
2351 return applyUniform(device, location, (float*)vector);
2357 bool Program::applyUniform2uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
2359 GLuint vector[MAX_UNIFORM_VECTORS][4];
2361 for(int i = 0; i < count; i++)
2363 vector[i][0] = v[0];
2364 vector[i][1] = v[1];
2371 return applyUniform(device, location, (float*)vector);
2374 bool Program::applyUniform3uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
2376 GLuint vector[MAX_UNIFORM_VECTORS][4];
2378 for(int i = 0; i < count; i++)
2380 vector[i][0] = v[0];
2381 vector[i][1] = v[1];
2382 vector[i][2] = v[2];
2388 return applyUniform(device, location, (float*)vector);
2391 bool Program::applyUniform4uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
2393 GLuint vector[MAX_UNIFORM_VECTORS][4];
2395 for(int i = 0; i < count; i++)
2397 vector[i][0] = v[0];
2398 vector[i][1] = v[1];
2399 vector[i][2] = v[2];
2400 vector[i][3] = v[3];
2405 return applyUniform(device, location, (float*)vector);
2408 void Program::appendToInfoLog(const char *format, ...)
2418 va_start(vararg, format);
2419 vsnprintf(info, sizeof(info), format, vararg);
2422 size_t infoLength = strlen(info);
2426 infoLog = new char[infoLength + 2];
2427 strcpy(infoLog, info);
2428 strcpy(infoLog + infoLength, "\n");
2432 size_t logLength = strlen(infoLog);
2433 char *newLog = new char[logLength + infoLength + 2];
2434 strcpy(newLog, infoLog);
2435 strcpy(newLog + logLength, info);
2436 strcpy(newLog + logLength + infoLength, "\n");
2443 void Program::resetInfoLog()
2452 // Returns the program object to an unlinked state, before re-linking, or at destruction
2453 void Program::unlink()
2455 delete vertexBinary;
2460 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
2462 linkedAttribute[index].name.clear();
2463 attributeStream[index] = -1;
2466 for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
2468 samplersPS[index].active = false;
2471 for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
2473 samplersVS[index].active = false;
2476 while(!uniforms.empty())
2478 delete uniforms.back();
2479 uniforms.pop_back();
2482 while(!uniformBlocks.empty())
2484 delete uniformBlocks.back();
2485 uniformBlocks.pop_back();
2488 uniformIndex.clear();
2489 transformFeedbackLinkedVaryings.clear();
2497 bool Program::isLinked() const
2502 bool Program::isValidated() const
2507 GLint Program::getBinaryLength() const
2513 void Program::release()
2517 if(referenceCount == 0 && orphaned)
2519 resourceManager->deleteProgram(handle);
2523 void Program::addRef()
2528 unsigned int Program::getRefCount() const
2530 return referenceCount;
2533 unsigned int Program::getSerial() const
2538 unsigned int Program::issueSerial()
2540 return currentSerial++;
2543 size_t Program::getInfoLogLength() const
2551 return strlen(infoLog) + 1;
2555 void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
2563 index = std::min(bufSize - 1, (int)strlen(infoLog));
2564 memcpy(buffer, infoLog, index);
2567 buffer[index] = '\0';
2576 void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
2580 if(vertexShader && (total < maxCount))
2582 shaders[total++] = vertexShader->getName();
2585 if(fragmentShader && (total < maxCount))
2587 shaders[total++] = fragmentShader->getName();
2596 void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2598 // Skip over inactive attributes
2599 unsigned int activeAttribute = 0;
2600 unsigned int attribute;
2601 for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2603 if(linkedAttribute[attribute].name.empty())
2608 if(activeAttribute == index)
2618 const char *string = linkedAttribute[attribute].name.c_str();
2620 strncpy(name, string, bufsize);
2621 name[bufsize - 1] = '\0';
2625 *length = static_cast<GLsizei>(strlen(name));
2629 *size = 1; // Always a single 'type' instance
2631 *type = linkedAttribute[attribute].type;
2634 size_t Program::getActiveAttributeCount() const
2638 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2640 if(!linkedAttribute[attributeIndex].name.empty())
2649 GLint Program::getActiveAttributeMaxLength() const
2653 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2655 if(!linkedAttribute[attributeIndex].name.empty())
2657 maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
2664 void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2668 std::string string = uniforms[index]->name;
2670 if(uniforms[index]->isArray())
2675 strncpy(name, string.c_str(), bufsize);
2676 name[bufsize - 1] = '\0';
2680 *length = static_cast<GLsizei>(strlen(name));
2684 *size = uniforms[index]->size();
2686 *type = uniforms[index]->type;
2689 size_t Program::getActiveUniformCount() const
2691 return uniforms.size();
2694 GLint Program::getActiveUniformMaxLength() const
2698 size_t numUniforms = uniforms.size();
2699 for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
2701 if(!uniforms[uniformIndex]->name.empty())
2703 int length = (int)(uniforms[uniformIndex]->name.length() + 1);
2704 if(uniforms[uniformIndex]->isArray())
2706 length += 3; // Counting in "[0]".
2708 maxLength = std::max(length, maxLength);
2715 GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
2717 const Uniform& uniform = *uniforms[index];
2720 case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
2721 case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.size());
2722 case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
2723 case GL_UNIFORM_BLOCK_INDEX: return uniform.blockInfo.index;
2724 case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
2725 case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
2726 case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
2727 case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
2735 void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
2737 ASSERT(index < getActiveUniformBlockCount());
2739 const UniformBlock &uniformBlock = *uniformBlocks[index];
2743 std::string string = uniformBlock.name;
2745 if(uniformBlock.isArrayElement())
2747 std::ostringstream elementIndex;
2748 elementIndex << uniformBlock.elementIndex;
2749 string += "[" + elementIndex.str() + "]";
2752 strncpy(name, string.c_str(), bufSize);
2753 name[bufSize - 1] = '\0';
2757 *length = static_cast<GLsizei>(strlen(name));
2762 size_t Program::getActiveUniformBlockCount() const
2764 return uniformBlocks.size();
2767 GLint Program::getActiveUniformBlockMaxLength() const
2769 GLint maxLength = 0;
2773 size_t numUniformBlocks = getActiveUniformBlockCount();
2774 for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
2776 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
2777 if(!uniformBlock.name.empty())
2779 GLint length = static_cast<GLint>(uniformBlock.name.length() + 1);
2781 // Counting in "[0]".
2782 const GLint arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
2784 maxLength = std::max(length + arrayLength, maxLength);
2792 void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
2794 transformFeedbackVaryings.resize(count);
2795 for(GLsizei i = 0; i < count; i++)
2797 transformFeedbackVaryings[i] = varyings[i];
2800 transformFeedbackBufferMode = bufferMode;
2803 void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
2807 ASSERT(index < transformFeedbackLinkedVaryings.size());
2808 const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];
2809 GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
2812 *length = lastNameIdx;
2816 *size = varying.size;
2820 *type = varying.type;
2824 memcpy(name, varying.name.c_str(), lastNameIdx);
2825 name[lastNameIdx] = '\0';
2830 GLsizei Program::getTransformFeedbackVaryingCount() const
2834 return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());
2842 GLsizei Program::getTransformFeedbackVaryingMaxLength() const
2846 GLsizei maxSize = 0;
2847 for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)
2849 const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];
2850 maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
2861 GLenum Program::getTransformFeedbackBufferMode() const
2863 return transformFeedbackBufferMode;
2866 void Program::flagForDeletion()
2871 bool Program::isFlaggedForDeletion() const
2876 void Program::validate(Device* device)
2882 appendToInfoLog("Program has not been successfully linked.");
2887 applyUniforms(device);
2888 if(!validateSamplers(true))
2899 bool Program::validateSamplers(bool logErrors)
2901 // if any two active samplers in a program are of different types, but refer to the same
2902 // texture image unit, and this is the current program, then ValidateProgram will fail, and
2903 // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
2905 TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
2907 for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
2909 textureUnitType[i] = TEXTURE_UNKNOWN;
2912 for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
2914 if(samplersPS[i].active)
2916 unsigned int unit = samplersPS[i].logicalTextureUnit;
2918 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
2922 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2928 if(textureUnitType[unit] != TEXTURE_UNKNOWN)
2930 if(samplersPS[i].textureType != textureUnitType[unit])
2934 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2942 textureUnitType[unit] = samplersPS[i].textureType;
2947 for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
2949 if(samplersVS[i].active)
2951 unsigned int unit = samplersVS[i].logicalTextureUnit;
2953 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
2957 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2963 if(textureUnitType[unit] != TEXTURE_UNKNOWN)
2965 if(samplersVS[i].textureType != textureUnitType[unit])
2969 appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2977 textureUnitType[unit] = samplersVS[i].textureType;