OSDN Git Service

1da918a60ab3a784160182606fbc09f0c4b5ebc3
[android-x86/external-swiftshader.git] / src / OpenGL / libGLESv2 / Program.cpp
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
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
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
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.
17
18 #include "Program.h"
19
20 #include "main.h"
21 #include "Buffer.h"
22 #include "Shader.h"
23 #include "TransformFeedback.h"
24 #include "utilities.h"
25 #include "common/debug.h"
26 #include "Shader/PixelShader.hpp"
27 #include "Shader/VertexShader.hpp"
28
29 #include <string>
30 #include <stdlib.h>
31
32 namespace es2
33 {
34         unsigned int Program::currentSerial = 1;
35
36         std::string str(int i)
37         {
38                 char buffer[20];
39                 sprintf(buffer, "%d", i);
40                 return buffer;
41         }
42
43         Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)
44         {
45                 if(blockIndex >= 0)
46                 {
47                         index = blockIndex;
48                         offset = uniform.blockInfo.offset;
49                         arrayStride = uniform.blockInfo.arrayStride;
50                         matrixStride = uniform.blockInfo.matrixStride;
51                         isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
52                 }
53                 else
54                 {
55                         index = -1;
56                         offset = -1;
57                         arrayStride = -1;
58                         matrixStride = -1;
59                         isRowMajorMatrix = false;
60                 }
61         }
62
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)
66         {
67                 if(blockInfo.index == -1)
68                 {
69                         size_t bytes = UniformTypeSize(type) * size();
70                         data = new unsigned char[bytes];
71                         memset(data, 0, bytes);
72                 }
73                 else
74                 {
75                         data = nullptr;
76                 }
77                 dirty = true;
78
79                 psRegisterIndex = -1;
80                 vsRegisterIndex = -1;
81         }
82
83         Uniform::~Uniform()
84         {
85                 delete[] data;
86         }
87
88         bool Uniform::isArray() const
89         {
90                 return arraySize >= 1;
91         }
92
93         int Uniform::size() const
94         {
95                 return arraySize > 0 ? arraySize : 1;
96         }
97
98         int Uniform::registerCount() const
99         {
100                 return size() * VariableRegisterCount(type);
101         }
102
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)
105         {
106         }
107
108         void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)
109         {
110                 switch(shader)
111                 {
112                 case GL_VERTEX_SHADER:
113                         vsRegisterIndex = registerIndex;
114                         break;
115                 case GL_FRAGMENT_SHADER:
116                         psRegisterIndex = registerIndex;
117                         break;
118                 default:
119                         UNREACHABLE(shader);
120                 }
121         }
122
123         bool UniformBlock::isArrayElement() const
124         {
125                 return elementIndex != GL_INVALID_INDEX;
126         }
127
128         bool UniformBlock::isReferencedByVertexShader() const
129         {
130                 return vsRegisterIndex != GL_INVALID_INDEX;
131         }
132
133         bool UniformBlock::isReferencedByFragmentShader() const
134         {
135                 return psRegisterIndex != GL_INVALID_INDEX;
136         }
137
138         UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
139         {
140         }
141
142         LinkedVarying::LinkedVarying()
143         {
144         }
145
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)
148         {
149         }
150
151         Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
152         {
153                 device = getDevice();
154
155                 fragmentShader = 0;
156                 vertexShader = 0;
157                 pixelBinary = 0;
158                 vertexBinary = 0;
159
160                 transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;
161                 totalLinkedVaryingsComponents = 0;
162
163                 infoLog = 0;
164                 validated = false;
165
166                 resetUniformBlockBindings();
167                 unlink();
168
169                 orphaned = false;
170                 retrievableBinary = false;
171                 referenceCount = 0;
172         }
173
174         Program::~Program()
175         {
176                 unlink();
177
178                 if(vertexShader)
179                 {
180                         vertexShader->release();
181                 }
182
183                 if(fragmentShader)
184                 {
185                         fragmentShader->release();
186                 }
187         }
188
189         bool Program::attachShader(Shader *shader)
190         {
191                 if(shader->getType() == GL_VERTEX_SHADER)
192                 {
193                         if(vertexShader)
194                         {
195                                 return false;
196                         }
197
198                         vertexShader = (VertexShader*)shader;
199                         vertexShader->addRef();
200                 }
201                 else if(shader->getType() == GL_FRAGMENT_SHADER)
202                 {
203                         if(fragmentShader)
204                         {
205                                 return false;
206                         }
207
208                         fragmentShader = (FragmentShader*)shader;
209                         fragmentShader->addRef();
210                 }
211                 else UNREACHABLE(shader->getType());
212
213                 return true;
214         }
215
216         bool Program::detachShader(Shader *shader)
217         {
218                 if(shader->getType() == GL_VERTEX_SHADER)
219                 {
220                         if(vertexShader != shader)
221                         {
222                                 return false;
223                         }
224
225                         vertexShader->release();
226                         vertexShader = 0;
227                 }
228                 else if(shader->getType() == GL_FRAGMENT_SHADER)
229                 {
230                         if(fragmentShader != shader)
231                         {
232                                 return false;
233                         }
234
235                         fragmentShader->release();
236                         fragmentShader = 0;
237                 }
238                 else UNREACHABLE(shader->getType());
239
240                 return true;
241         }
242
243         int Program::getAttachedShadersCount() const
244         {
245                 return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
246         }
247
248         sw::PixelShader *Program::getPixelShader()
249         {
250                 return pixelBinary;
251         }
252
253         sw::VertexShader *Program::getVertexShader()
254         {
255                 return vertexBinary;
256         }
257
258         void Program::bindAttributeLocation(GLuint index, const char *name)
259         {
260                 if(index < MAX_VERTEX_ATTRIBS)
261                 {
262                         for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
263                         {
264                                 attributeBinding[i].erase(name);
265                         }
266
267                         attributeBinding[index].insert(name);
268                 }
269         }
270
271         GLint Program::getAttributeLocation(const char *name)
272         {
273                 if(name)
274                 {
275                         for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
276                         {
277                                 if(linkedAttribute[index].name == std::string(name))
278                                 {
279                                         return index;
280                                 }
281                         }
282                 }
283
284                 return -1;
285         }
286
287         int Program::getAttributeStream(int attributeIndex)
288         {
289                 ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
290
291                 return attributeStream[attributeIndex];
292         }
293
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)
296         {
297                 GLint logicalTextureUnit = -1;
298
299                 switch(type)
300                 {
301                 case sw::SAMPLER_PIXEL:
302                         ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
303
304                         if(samplersPS[samplerIndex].active)
305                         {
306                                 logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
307                         }
308                         break;
309                 case sw::SAMPLER_VERTEX:
310                         ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
311
312                         if(samplersVS[samplerIndex].active)
313                         {
314                                 logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
315                         }
316                         break;
317                 default: UNREACHABLE(type);
318                 }
319
320                 if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
321                 {
322                         return logicalTextureUnit;
323                 }
324
325                 return -1;
326         }
327
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)
330         {
331                 switch(type)
332                 {
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);
342                 }
343
344                 return TEXTURE_2D;
345         }
346
347         GLint Program::getUniformLocation(const std::string &name) const
348         {
349                 unsigned int subscript = GL_INVALID_INDEX;
350                 std::string baseName = es2::ParseUniformName(name, &subscript);
351
352                 size_t numUniforms = uniformIndex.size();
353                 for(size_t location = 0; location < numUniforms; location++)
354                 {
355                         const int index = uniformIndex[location].index;
356                         const bool isArray = uniforms[index]->isArray();
357
358                         if(uniformIndex[location].name == baseName &&
359                            ((isArray && uniformIndex[location].element == subscript) ||
360                             (subscript == GL_INVALID_INDEX)))
361                         {
362                                 return (GLint)location;
363                         }
364                 }
365
366                 return -1;
367         }
368
369         GLuint Program::getUniformIndex(const std::string &name) const
370         {
371                 unsigned int subscript = GL_INVALID_INDEX;
372                 std::string baseName = es2::ParseUniformName(name, &subscript);
373
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)
376                 {
377                         return GL_INVALID_INDEX;
378                 }
379
380                 size_t numUniforms = uniforms.size();
381                 for(GLuint index = 0; index < numUniforms; index++)
382                 {
383                         if(uniforms[index]->name == baseName)
384                         {
385                                 if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
386                                 {
387                                         return index;
388                                 }
389                         }
390                 }
391
392                 return GL_INVALID_INDEX;
393         }
394
395         void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
396         {
397                 ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
398
399                 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
400
401                 switch(pname)
402                 {
403                 case GL_UNIFORM_BLOCK_DATA_SIZE:
404                         *params = static_cast<GLint>(uniformBlock.dataSize);
405                         break;
406                 case GL_UNIFORM_BLOCK_NAME_LENGTH:
407                         *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
408                         break;
409                 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
410                         *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
411                         break;
412                 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
413                         {
414                                 for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
415                                 {
416                                         params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
417                                 }
418                         }
419                         break;
420                 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
421                         *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
422                         break;
423                 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
424                         *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
425                         break;
426                 default: UNREACHABLE(pname);
427                 }
428         }
429
430         GLuint Program::getUniformBlockIndex(const std::string &name) const
431         {
432                 unsigned int subscript = GL_INVALID_INDEX;
433                 std::string baseName = es2::ParseUniformName(name, &subscript);
434
435                 size_t numUniformBlocks = getActiveUniformBlockCount();
436                 for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
437                 {
438                         const UniformBlock &uniformBlock = *uniformBlocks[blockIndex];
439                         if(uniformBlock.name == baseName)
440                         {
441                                 const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
442                                 if(subscript == uniformBlock.elementIndex || arrayElementZero)
443                                 {
444                                         return blockIndex;
445                                 }
446                         }
447                 }
448
449                 return GL_INVALID_INDEX;
450         }
451
452         void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
453         {
454                 uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
455         }
456
457         GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
458         {
459                 return uniformBlockBindings[uniformBlockIndex];
460         }
461
462         void Program::resetUniformBlockBindings()
463         {
464                 for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++)
465                 {
466                         uniformBlockBindings[blockId] = 0;
467                 }
468         }
469
470         bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements)
471         {
472                 ASSERT(numElements >= 1 && numElements <= 4);
473
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 };
476
477                 if(location < 0 || location >= (int)uniformIndex.size())
478                 {
479                         return false;
480                 }
481
482                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
483                 targetUniform->dirty = true;
484
485                 int size = targetUniform->size();
486
487                 if(size == 1 && count > 1)
488                 {
489                         return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
490                 }
491
492                 count = std::min(size - (int)uniformIndex[location].element, count);
493
494                 int index = numElements - 1;
495                 if(targetUniform->type == floatType[index])
496                 {
497                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements,
498                                    v, numElements * sizeof(GLfloat)* count);
499                 }
500                 else if(targetUniform->type == boolType[index])
501                 {
502                         GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements;
503
504                         for(int i = 0; i < count * numElements; i++)
505                         {
506                                 boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE;
507                         }
508                 }
509                 else
510                 {
511                         return false;
512                 }
513
514                 return true;
515         }
516
517         bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
518         {
519                 return setUniformfv(location, count, v, 1);
520         }
521
522         bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
523         {
524                 return setUniformfv(location, count, v, 2);
525         }
526
527         bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
528         {
529                 return setUniformfv(location, count, v, 3);
530         }
531
532         bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
533         {
534                 return setUniformfv(location, count, v, 4);
535         }
536
537         bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type)
538         {
539                 int numElements;
540                 switch(type)
541                 {
542                 case GL_FLOAT_MAT2:
543                         numElements = 4;
544                         break;
545                 case GL_FLOAT_MAT2x3:
546                 case GL_FLOAT_MAT3x2:
547                         numElements = 6;
548                         break;
549                 case GL_FLOAT_MAT2x4:
550                 case GL_FLOAT_MAT4x2:
551                         numElements = 8;
552                         break;
553                 case GL_FLOAT_MAT3:
554                         numElements = 9;
555                         break;
556                 case GL_FLOAT_MAT3x4:
557                 case GL_FLOAT_MAT4x3:
558                         numElements = 12;
559                         break;
560                 case GL_FLOAT_MAT4:
561                         numElements = 16;
562                         break;
563                 default:
564                         return false;
565                 }
566
567                 if(location < 0 || location >= (int)uniformIndex.size())
568                 {
569                         return false;
570                 }
571
572                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
573                 targetUniform->dirty = true;
574
575                 if(targetUniform->type != type)
576                 {
577                         return false;
578                 }
579
580                 int size = targetUniform->size();
581
582                 if(size == 1 && count > 1)
583                 {
584                         return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
585                 }
586
587                 count = std::min(size - (int)uniformIndex[location].element, count);
588
589                 GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements);
590
591                 if(transpose == GL_FALSE)
592                 {
593                         memcpy(dst, value, numElements * sizeof(GLfloat) * count);
594                 }
595                 else
596                 {
597                         const int rowSize = VariableRowCount(type);
598                         const int colSize = VariableColumnCount(type);
599                         for(int n = 0; n < count; ++n)
600                         {
601                                 for(int i = 0; i < colSize; ++i)
602                                 {
603                                         for(int j = 0; j < rowSize; ++j)
604                                         {
605                                                 dst[i * rowSize + j] = value[j * colSize + i];
606                                         }
607                                 }
608                                 dst += numElements;
609                                 value += numElements;
610                         }
611                 }
612
613
614                 return true;
615         }
616
617         bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
618         {
619                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2);
620         }
621
622         bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
623         {
624                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3);
625         }
626
627         bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
628         {
629                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4);
630         }
631
632         bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
633         {
634                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3);
635         }
636
637         bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
638         {
639                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2);
640         }
641
642         bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
643         {
644                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4);
645         }
646
647         bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
648         {
649                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4);
650         }
651
652         bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
653         {
654                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2);
655         }
656
657         bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
658         {
659                 return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3);
660         }
661
662         bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
663         {
664                 if(location < 0 || location >= (int)uniformIndex.size())
665                 {
666                         return false;
667                 }
668
669                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
670                 targetUniform->dirty = true;
671
672                 int size = targetUniform->size();
673
674                 if(size == 1 && count > 1)
675                 {
676                         return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
677                 }
678
679                 count = std::min(size - (int)uniformIndex[location].element, count);
680
681                 if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
682                 {
683                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
684                                    v, sizeof(GLint) * count);
685                 }
686                 else if(targetUniform->type == GL_BOOL)
687                 {
688                         GLboolean *boolParams = new GLboolean[count];
689
690                         for(int i = 0; i < count; i++)
691                         {
692                                 if(v[i] == 0)
693                                 {
694                                         boolParams[i] = GL_FALSE;
695                                 }
696                                 else
697                                 {
698                                         boolParams[i] = GL_TRUE;
699                                 }
700                         }
701
702                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
703                                    boolParams, sizeof(GLboolean) * count);
704
705                         delete[] boolParams;
706                 }
707                 else
708                 {
709                         return false;
710                 }
711
712                 return true;
713         }
714
715         bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
716         {
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 };
720
721                 if(location < 0 || location >= (int)uniformIndex.size())
722                 {
723                         return false;
724                 }
725
726                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
727                 targetUniform->dirty = true;
728
729                 int size = targetUniform->size();
730
731                 if(size == 1 && count > 1)
732                 {
733                         return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
734                 }
735
736                 count = std::min(size - (int)uniformIndex[location].element, count);
737
738                 int index = numElements - 1;
739                 if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])
740                 {
741                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
742                                    v, numElements * sizeof(GLint)* count);
743                 }
744                 else if(targetUniform->type == boolType[index])
745                 {
746                         GLboolean *boolParams = new GLboolean[count * numElements];
747
748                         for(int i = 0; i < count * numElements; i++)
749                         {
750                                 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
751                         }
752
753                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
754                                    boolParams, numElements * sizeof(GLboolean)* count);
755
756                         delete[] boolParams;
757                 }
758                 else
759                 {
760                         return false;
761                 }
762
763                 return true;
764         }
765
766         bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
767         {
768                 return setUniformiv(location, count, v, 2);
769         }
770
771         bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
772         {
773                 return setUniformiv(location, count, v, 3);
774         }
775
776         bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
777         {
778                 return setUniformiv(location, count, v, 4);
779         }
780
781         bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
782         {
783                 if(location < 0 || location >= (int)uniformIndex.size())
784                 {
785                         return false;
786                 }
787
788                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
789                 targetUniform->dirty = true;
790
791                 int size = targetUniform->size();
792
793                 if(size == 1 && count > 1)
794                 {
795                         return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
796                 }
797
798                 count = std::min(size - (int)uniformIndex[location].element, count);
799
800                 if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
801                 {
802                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
803                                    v, sizeof(GLuint)* count);
804                 }
805                 else if(targetUniform->type == GL_BOOL)
806                 {
807                         GLboolean *boolParams = new GLboolean[count];
808
809                         for(int i = 0; i < count; i++)
810                         {
811                                 if(v[i] == 0)
812                                 {
813                                         boolParams[i] = GL_FALSE;
814                                 }
815                                 else
816                                 {
817                                         boolParams[i] = GL_TRUE;
818                                 }
819                         }
820
821                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
822                                    boolParams, sizeof(GLboolean)* count);
823
824                         delete[] boolParams;
825                 }
826                 else
827                 {
828                         return false;
829                 }
830
831                 return true;
832         }
833
834         bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
835         {
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 };
839
840                 if(location < 0 || location >= (int)uniformIndex.size())
841                 {
842                         return false;
843                 }
844
845                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
846                 targetUniform->dirty = true;
847
848                 int size = targetUniform->size();
849
850                 if(size == 1 && count > 1)
851                 {
852                         return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
853                 }
854
855                 count = std::min(size - (int)uniformIndex[location].element, count);
856
857                 int index = numElements - 1;
858                 if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])
859                 {
860                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
861                                    v, numElements * sizeof(GLuint)* count);
862                 }
863                 else if(targetUniform->type == boolType[index])
864                 {
865                         GLboolean *boolParams = new GLboolean[count * numElements];
866
867                         for(int i = 0; i < count * numElements; i++)
868                         {
869                                 boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
870                         }
871
872                         memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
873                                    boolParams, numElements * sizeof(GLboolean)* count);
874
875                         delete[] boolParams;
876                 }
877                 else
878                 {
879                         return false;
880                 }
881
882                 return true;
883         }
884
885         bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
886         {
887                 return setUniformuiv(location, count, v, 2);
888         }
889
890         bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
891         {
892                 return setUniformuiv(location, count, v, 3);
893         }
894
895         bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
896         {
897                 return setUniformuiv(location, count, v, 4);
898         }
899
900         bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
901         {
902                 if(location < 0 || location >= (int)uniformIndex.size())
903                 {
904                         return false;
905                 }
906
907                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
908                 unsigned int count = UniformComponentCount(targetUniform->type);
909
910                 // Sized query - ensure the provided buffer is large enough
911                 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
912                 {
913                         return false;
914                 }
915
916                 switch(UniformComponentType(targetUniform->type))
917                 {
918                 case GL_BOOL:
919                         {
920                                 GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
921
922                                 for(unsigned int i = 0; i < count; i++)
923                                 {
924                                         params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
925                                 }
926                         }
927                         break;
928                 case GL_FLOAT:
929                         memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
930                                    count * sizeof(GLfloat));
931                         break;
932                 case GL_INT:
933                         {
934                                 GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
935
936                                 for(unsigned int i = 0; i < count; i++)
937                                 {
938                                         params[i] = (float)intParams[i];
939                                 }
940                         }
941                         break;
942                 case GL_UNSIGNED_INT:
943                         {
944                                 GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count;
945
946                                 for(unsigned int i = 0; i < count; i++)
947                                 {
948                                         params[i] = (float)uintParams[i];
949                                 }
950                         }
951                         break;
952                 default: UNREACHABLE(targetUniform->type);
953                 }
954
955                 return true;
956         }
957
958         bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
959         {
960                 if(location < 0 || location >= (int)uniformIndex.size())
961                 {
962                         return false;
963                 }
964
965                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
966                 unsigned int count = UniformComponentCount(targetUniform->type);
967
968                 // Sized query - ensure the provided buffer is large enough
969                 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint))
970                 {
971                         return false;
972                 }
973
974                 switch(UniformComponentType(targetUniform->type))
975                 {
976                 case GL_BOOL:
977                         {
978                                 GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
979
980                                 for(unsigned int i = 0; i < count; i++)
981                                 {
982                                         params[i] = (GLint)boolParams[i];
983                                 }
984                         }
985                         break;
986                 case GL_FLOAT:
987                         {
988                                 GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
989
990                                 for(unsigned int i = 0; i < count; i++)
991                                 {
992                                         params[i] = (GLint)floatParams[i];
993                                 }
994                         }
995                         break;
996                 case GL_INT:
997                 case GL_UNSIGNED_INT:
998                         memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
999                                    count * sizeof(GLint));
1000                         break;
1001                 default: UNREACHABLE(targetUniform->type);
1002                 }
1003
1004                 return true;
1005         }
1006
1007         bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
1008         {
1009                 if(location < 0 || location >= (int)uniformIndex.size())
1010                 {
1011                         return false;
1012                 }
1013
1014                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1015                 unsigned int count = UniformComponentCount(targetUniform->type);
1016
1017                 // Sized query - ensure the provided buffer is large enough
1018                 if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint))
1019                 {
1020                         return false;
1021                 }
1022
1023                 switch(UniformComponentType(targetUniform->type))
1024                 {
1025                 case GL_BOOL:
1026                 {
1027                         GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
1028
1029                         for(unsigned int i = 0; i < count; i++)
1030                         {
1031                                 params[i] = (GLuint)boolParams[i];
1032                         }
1033                 }
1034                         break;
1035                 case GL_FLOAT:
1036                 {
1037                         GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
1038
1039                         for(unsigned int i = 0; i < count; i++)
1040                         {
1041                                 params[i] = (GLuint)floatParams[i];
1042                         }
1043                 }
1044                         break;
1045                 case GL_INT:
1046                 case GL_UNSIGNED_INT:
1047                         memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint),
1048                                    count * sizeof(GLuint));
1049                         break;
1050                 default: UNREACHABLE(targetUniform->type);
1051                 }
1052
1053                 return true;
1054         }
1055
1056         void Program::dirtyAllUniforms()
1057         {
1058                 size_t numUniforms = uniforms.size();
1059                 for(size_t index = 0; index < numUniforms; index++)
1060                 {
1061                         uniforms[index]->dirty = true;
1062                 }
1063         }
1064
1065         // Applies all the uniforms set for this program object to the device
1066         void Program::applyUniforms()
1067         {
1068                 GLint numUniforms = static_cast<GLint>(uniformIndex.size());
1069                 for(GLint location = 0; location < numUniforms; location++)
1070                 {
1071                         if(uniformIndex[location].element != 0)
1072                         {
1073                                 continue;
1074                         }
1075
1076                         Uniform *targetUniform = uniforms[uniformIndex[location].index];
1077
1078                         if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
1079                         {
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;
1085
1086                                 switch(targetUniform->type)
1087                                 {
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;
1105                                 case GL_SAMPLER_2D:
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;
1129                                 default:
1130                                         UNREACHABLE(targetUniform->type);
1131                                 }
1132
1133                                 targetUniform->dirty = false;
1134                         }
1135                 }
1136         }
1137
1138         void Program::applyUniformBuffers(BufferBinding* uniformBuffers)
1139         {
1140                 GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
1141                 GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
1142
1143                 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1144                 {
1145                         vertexUniformBuffers[bufferBindingIndex] = -1;
1146                 }
1147
1148                 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1149                 {
1150                         fragmentUniformBuffers[bufferBindingIndex] = -1;
1151                 }
1152
1153                 int vertexUniformBufferIndex = 0;
1154                 int fragmentUniformBufferIndex = 0;
1155                 for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
1156                 {
1157                         UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
1158
1159                         // Unnecessary to apply an unreferenced standard or shared UBO
1160                         if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
1161                         {
1162                                 continue;
1163                         }
1164
1165                         GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
1166
1167                         if(uniformBlock.isReferencedByVertexShader())
1168                         {
1169                                 vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
1170                         }
1171
1172                         if(uniformBlock.isReferencedByFragmentShader())
1173                         {
1174                                 fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
1175                         }
1176                 }
1177
1178                 for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
1179                 {
1180                         int index = vertexUniformBuffers[bufferBindingIndex];
1181                         const gl::BindingPointer<Buffer> &buffer = uniformBuffers[index].get();
1182
1183                         if(buffer)
1184                         {
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);
1188                         }
1189                 }
1190         }
1191
1192         void Program::applyTransformFeedback(TransformFeedback* transformFeedback)
1193         {
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);
1196
1197                 BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr;
1198
1199                 uint64_t enableTransformFeedback = 0;
1200                 if(!transformFeedbackBuffers)
1201                 {
1202                         for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
1203                         {
1204                                 device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
1205                         }
1206                         device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
1207                         return;
1208                 }
1209
1210                 unsigned int maxVaryings = static_cast<unsigned int>(transformFeedbackLinkedVaryings.size());
1211                 switch(transformFeedbackBufferMode)
1212                 {
1213                 case GL_SEPARATE_ATTRIBS:
1214                 {
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)
1218                         {
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;
1232                         }
1233                 }
1234                         break;
1235                 case GL_INTERLEAVED_ATTRIBS:
1236                 {
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)
1247                         {
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;
1259                         }
1260                 }
1261                         break;
1262                 default:
1263                         UNREACHABLE(transformFeedbackBufferMode);
1264                         break;
1265                 }
1266
1267                 // Unset all other transform feedback buffers
1268                 for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
1269                 {
1270                         device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
1271                 }
1272
1273                 device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
1274         }
1275
1276         bool Program::linkVaryings()
1277         {
1278                 for(glsl::VaryingList::iterator input = fragmentShader->varyings.begin(); input != fragmentShader->varyings.end(); ++input)
1279                 {
1280                         bool matched = false;
1281
1282                         for(glsl::VaryingList::iterator output = vertexShader->varyings.begin(); output != vertexShader->varyings.end(); ++output)
1283                         {
1284                                 if(output->name == input->name)
1285                                 {
1286                                         if(output->type != input->type || output->size() != input->size())
1287                                         {
1288                                                 appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
1289
1290                                                 return false;
1291                                         }
1292
1293                                         matched = true;
1294                                         break;
1295                                 }
1296                         }
1297
1298                         if(!matched)
1299                         {
1300                                 appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str());
1301
1302                                 return false;
1303                         }
1304                 }
1305
1306                 glsl::VaryingList &psVaryings = fragmentShader->varyings;
1307                 glsl::VaryingList &vsVaryings = vertexShader->varyings;
1308
1309                 for(glsl::VaryingList::iterator output = vsVaryings.begin(); output != vsVaryings.end(); ++output)
1310                 {
1311                         for(glsl::VaryingList::iterator input = psVaryings.begin(); input != psVaryings.end(); ++input)
1312                         {
1313                                 if(output->name == input->name)
1314                                 {
1315                                         int in = input->reg;
1316                                         int out = output->reg;
1317                                         int components = VariableRegisterSize(output->type);
1318                                         int registers = VariableRegisterCount(output->type) * output->size();
1319
1320                                         ASSERT(in >= 0);
1321
1322                                         if(in + registers > MAX_VARYING_VECTORS)
1323                                         {
1324                                                 appendToInfoLog("Too many varyings");
1325                                                 return false;
1326                                         }
1327
1328                                         if(out >= 0)
1329                                         {
1330                                                 if(out + registers > MAX_VARYING_VECTORS)
1331                                                 {
1332                                                         appendToInfoLog("Too many varyings");
1333                                                         return false;
1334                                                 }
1335
1336                                                 for(int i = 0; i < registers; i++)
1337                                                 {
1338                                                         vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, pixelBinary->getInput(in + i, 0).flat));
1339                                                 }
1340                                         }
1341                                         else   // Vertex varying is declared but not written to
1342                                         {
1343                                                 for(int i = 0; i < registers; i++)
1344                                                 {
1345                                                         pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
1346                                                 }
1347                                         }
1348
1349                                         break;
1350                                 }
1351                         }
1352                 }
1353
1354                 return true;
1355         }
1356
1357         bool Program::linkTransformFeedback()
1358         {
1359                 size_t totalComponents = 0;
1360                 totalLinkedVaryingsComponents = 0;
1361
1362                 std::set<std::string> uniqueNames;
1363
1364                 for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
1365                 {
1366                         unsigned int subscript = GL_INVALID_INDEX;
1367                         std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript);
1368                         bool hasSubscript = (subscript != GL_INVALID_INDEX);
1369
1370                         if(tfVaryingName.find('[') != std::string::npos)
1371                         {
1372                                 appendToInfoLog("Capture of array sub-elements is undefined and not supported.");
1373                                 return false;
1374                         }
1375
1376                         bool found = false;
1377                         for(const glsl::Varying varying : vertexShader->varyings)
1378                         {
1379                                 if(tfVaryingName == varying.name)
1380                                 {
1381                                         if(uniqueNames.count(indexedTfVaryingName) > 0)
1382                                         {
1383                                                 appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str());
1384                                                 return false;
1385                                         }
1386                                         uniqueNames.insert(indexedTfVaryingName);
1387
1388                                         if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size()))
1389                                         {
1390                                                 appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str());
1391                                                 return false;
1392                                         }
1393
1394                                         int size = hasSubscript ? 1 : varying.size();
1395
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)
1401                                         {
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);
1404                                                 return false;
1405                                         }
1406
1407                                         totalComponents += componentCount;
1408
1409                                         int reg = varying.reg;
1410                                         if(hasSubscript)
1411                                         {
1412                                                 reg += rowCount > 1 ? colCount * subscript : subscript;
1413                                         }
1414                                         int col = varying.col;
1415                                         if(tfVaryingName == "gl_PointSize")
1416                                         {
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
1419                                         }
1420                                         transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col));
1421
1422                                         found = true;
1423                                         break;
1424                                 }
1425                         }
1426
1427                         if(!found)
1428                         {
1429                                 appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str());
1430                                 return false;
1431                         }
1432                 }
1433
1434                 if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
1435                    totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
1436                 {
1437                         appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).",
1438                                         totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1439                         return false;
1440                 }
1441
1442                 totalLinkedVaryingsComponents = totalComponents;
1443
1444                 return true;
1445         }
1446
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()
1451         {
1452                 unlink();
1453
1454                 resetUniformBlockBindings();
1455
1456                 if(!fragmentShader || !fragmentShader->isCompiled())
1457                 {
1458                         return;
1459                 }
1460
1461                 if(!vertexShader || !vertexShader->isCompiled())
1462                 {
1463                         return;
1464                 }
1465
1466                 vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
1467                 pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
1468
1469                 if(!linkVaryings())
1470                 {
1471                         return;
1472                 }
1473
1474                 if(!linkAttributes())
1475                 {
1476                         return;
1477                 }
1478
1479                 // Link uniform blocks before uniforms to make it easy to assign block indices to fields
1480                 if(!linkUniformBlocks(vertexShader, fragmentShader))
1481                 {
1482                         return;
1483                 }
1484
1485                 if(!linkUniforms(fragmentShader))
1486                 {
1487                         return;
1488                 }
1489
1490                 if(!linkUniforms(vertexShader))
1491                 {
1492                         return;
1493                 }
1494
1495                 if(!linkTransformFeedback())
1496                 {
1497                         return;
1498                 }
1499
1500                 linked = true;   // Success
1501         }
1502
1503         // Determines the mapping between GL attributes and vertex stream usage indices
1504         bool Program::linkAttributes()
1505         {
1506                 unsigned int usedLocations = 0;
1507
1508                 // Link attributes that have a binding location
1509                 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
1510                 {
1511                         int location = getAttributeBinding(*attribute);
1512
1513                         if(location != -1)   // Set by glBindAttribLocation
1514                         {
1515                                 int rows = VariableRegisterCount(attribute->type);
1516
1517                                 if(rows + location > MAX_VERTEX_ATTRIBS)
1518                                 {
1519                                         appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
1520                                         return false;
1521                                 }
1522
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)
1526                                 {
1527                                         for(int i = 0; i < rows; i++)
1528                                         {
1529                                                 if(!linkedAttribute[location + i].name.empty())
1530                                                 {
1531                                                         appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute->name.c_str(), linkedAttribute[location].name.c_str(), location);
1532                                                         return false;
1533                                                 }
1534                                         }
1535                                 }
1536
1537                                 for(int i = 0; i < rows; i++)
1538                                 {
1539                                         linkedAttribute[location + i] = *attribute;
1540                                         usedLocations |= 1 << (location + i);
1541                                 }
1542                         }
1543                 }
1544
1545                 // Link attributes that don't have a binding location
1546                 for(glsl::ActiveAttributes::iterator attribute = vertexShader->activeAttributes.begin(); attribute != vertexShader->activeAttributes.end(); ++attribute)
1547                 {
1548                         int location = getAttributeBinding(*attribute);
1549
1550                         if(location == -1)   // Not set by glBindAttribLocation
1551                         {
1552                                 int rows = VariableRegisterCount(attribute->type);
1553                                 int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
1554
1555                                 if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
1556                                 {
1557                                         appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str());
1558                                         return false;   // Fail to link
1559                                 }
1560
1561                                 for(int i = 0; i < rows; i++)
1562                                 {
1563                                         linkedAttribute[availableIndex + i] = *attribute;
1564                                 }
1565                         }
1566                 }
1567
1568                 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
1569                 {
1570                         int index = vertexShader->getSemanticIndex(linkedAttribute[attributeIndex].name);
1571                         int rows = std::max(VariableRegisterCount(linkedAttribute[attributeIndex].type), 1);
1572
1573                         for(int r = 0; r < rows; r++)
1574                         {
1575                                 attributeStream[attributeIndex++] = index++;
1576                         }
1577                 }
1578
1579                 return true;
1580         }
1581
1582         int Program::getAttributeBinding(const glsl::Attribute &attribute)
1583         {
1584                 if(attribute.location != -1)
1585                 {
1586                         return attribute.location;
1587                 }
1588
1589                 for(int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
1590                 {
1591                         if(attributeBinding[location].find(attribute.name.c_str()) != attributeBinding[location].end())
1592                         {
1593                                 return location;
1594                         }
1595                 }
1596
1597                 return -1;
1598         }
1599
1600         bool Program::linkUniforms(const Shader *shader)
1601         {
1602                 const glsl::ActiveUniforms &activeUniforms = shader->activeUniforms;
1603
1604                 for(unsigned int uniformIndex = 0; uniformIndex < activeUniforms.size(); uniformIndex++)
1605                 {
1606                         const glsl::Uniform &uniform = activeUniforms[uniformIndex];
1607
1608                         unsigned int blockIndex = GL_INVALID_INDEX;
1609                         if(uniform.blockId >= 0)
1610                         {
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);
1615                         }
1616                         if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))
1617                         {
1618                                 return false;
1619                         }
1620                 }
1621
1622                 return true;
1623         }
1624
1625         bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex, const Uniform::BlockInfo& blockInfo)
1626         {
1627                 if(IsSamplerUniform(type))
1628             {
1629                         int index = registerIndex;
1630
1631                         do
1632                         {
1633                                 if(shader == GL_VERTEX_SHADER)
1634                                 {
1635                                         if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
1636                                         {
1637                                                 samplersVS[index].active = true;
1638
1639                                                 switch(type)
1640                                                 {
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;
1658                                                 }
1659
1660                                                 samplersVS[index].logicalTextureUnit = 0;
1661                                         }
1662                                         else
1663                                         {
1664                                            appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
1665                                            return false;
1666                                         }
1667                                 }
1668                                 else if(shader == GL_FRAGMENT_SHADER)
1669                                 {
1670                                         if(index < MAX_TEXTURE_IMAGE_UNITS)
1671                                         {
1672                                                 samplersPS[index].active = true;
1673
1674                                                 switch(type)
1675                                                 {
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;
1693                                                 }
1694
1695                                                 samplersPS[index].logicalTextureUnit = 0;
1696                                         }
1697                                         else
1698                                         {
1699                                                 appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
1700                                                 return false;
1701                                         }
1702                                 }
1703                                 else UNREACHABLE(shader);
1704
1705                                 index++;
1706                         }
1707                         while(index < registerIndex + static_cast<int>(arraySize));
1708             }
1709
1710                 Uniform *uniform = 0;
1711                 GLint location = getUniformLocation(name);
1712
1713                 if(location >= 0)   // Previously defined, types must match
1714                 {
1715                         uniform = uniforms[uniformIndex[location].index];
1716
1717                         if(uniform->type != type)
1718                         {
1719                                 appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
1720                                 return false;
1721                         }
1722
1723                         if(uniform->precision != precision)
1724                         {
1725                                 appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
1726                                 return false;
1727                         }
1728                 }
1729                 else
1730                 {
1731                         uniform = new Uniform(type, precision, name, arraySize, blockInfo);
1732                 }
1733
1734                 if(!uniform)
1735                 {
1736                         return false;
1737                 }
1738
1739                 if(shader == GL_VERTEX_SHADER)
1740                 {
1741                         uniform->vsRegisterIndex = registerIndex;
1742                 }
1743                 else if(shader == GL_FRAGMENT_SHADER)
1744                 {
1745                         uniform->psRegisterIndex = registerIndex;
1746                 }
1747                 else UNREACHABLE(shader);
1748
1749                 if(location == -1)   // Not previously defined
1750                 {
1751                         uniforms.push_back(uniform);
1752                         unsigned int index = static_cast<unsigned int>(uniforms.size() - 1);
1753
1754                         for(int i = 0; i < uniform->size(); i++)
1755                         {
1756                                 uniformIndex.push_back(UniformLocation(name, i, index));
1757                         }
1758                 }
1759
1760                 if(shader == GL_VERTEX_SHADER)
1761                 {
1762                         if(registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
1763                         {
1764                                 appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
1765                                 return false;
1766                         }
1767                 }
1768                 else if(shader == GL_FRAGMENT_SHADER)
1769                 {
1770                         if(registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
1771                         {
1772                                 appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
1773                                 return false;
1774                         }
1775                 }
1776                 else UNREACHABLE(shader);
1777
1778                 return true;
1779         }
1780
1781         bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
1782         {
1783                 // validate blocks for the same member types
1784                 if(block1.fields.size() != block2.fields.size())
1785                 {
1786                         return false;
1787                 }
1788                 if(block1.arraySize != block2.arraySize)
1789                 {
1790                         return false;
1791                 }
1792                 if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
1793                 {
1794                         return false;
1795                 }
1796                 const size_t numBlockMembers = block1.fields.size();
1797                 for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
1798                 {
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)
1805                         {
1806                                 return false;
1807                         }
1808                 }
1809                 return true;
1810         }
1811
1812         bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)
1813         {
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++)
1820                 {
1821                         const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];
1822                         linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;
1823                 }
1824                 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
1825                 {
1826                         const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];
1827                         UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);
1828                         if(entry != linkedUniformBlocks.end())
1829                         {
1830                                 const glsl::UniformBlock &vertexUniformBlock = *entry->second;
1831                                 if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))
1832                                 {
1833                                         return false;
1834                                 }
1835                         }
1836                 }
1837                 for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
1838                 {
1839                         const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];
1840                         if(!defineUniformBlock(vertexShader, uniformBlock))
1841                         {
1842                                 return false;
1843                         }
1844                 }
1845                 for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
1846                 {
1847                         const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];
1848                         if(!defineUniformBlock(fragmentShader, uniformBlock))
1849                         {
1850                                 return false;
1851                         }
1852                 }
1853                 return true;
1854         }
1855
1856         bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
1857         {
1858                 GLuint blockIndex = getUniformBlockIndex(block.name);
1859
1860                 if(blockIndex == GL_INVALID_INDEX)
1861                 {
1862                         const std::vector<int>& fields = block.fields;
1863                         std::vector<unsigned int> memberUniformIndexes;
1864                         for(size_t i = 0; i < fields.size(); ++i)
1865                         {
1866                                 memberUniformIndexes.push_back(fields[i]);
1867                         }
1868
1869                         if(block.arraySize > 0)
1870                         {
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)
1874                                 {
1875                                         uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));
1876                                         uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);
1877                                 }
1878                         }
1879                         else
1880                         {
1881                                 uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
1882                                 uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
1883                         }
1884                 }
1885                 else
1886                 {
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)
1891                         {
1892                                 uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex);
1893                         }
1894                 }
1895
1896                 return true;
1897         }
1898
1899         bool Program::applyUniform(GLint location, float* data)
1900         {
1901                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
1902
1903                 if(targetUniform->psRegisterIndex != -1)
1904                 {
1905                         device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount());
1906                 }
1907
1908                 if(targetUniform->vsRegisterIndex != -1)
1909                 {
1910                         device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount());
1911                 }
1912
1913                 return true;
1914         }
1915
1916         bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
1917         {
1918                 int vector[MAX_UNIFORM_VECTORS][4];
1919
1920                 for(int i = 0; i < count; i++)
1921                 {
1922                         vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1923                         vector[i][1] = 0;
1924                         vector[i][2] = 0;
1925                         vector[i][3] = 0;
1926
1927                         v += 1;
1928                 }
1929
1930                 return applyUniform(location, (float*)vector);
1931         }
1932
1933         bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
1934         {
1935                 int vector[MAX_UNIFORM_VECTORS][4];
1936
1937                 for(int i = 0; i < count; i++)
1938                 {
1939                         vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1940                         vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
1941                         vector[i][2] = 0;
1942                         vector[i][3] = 0;
1943
1944                         v += 2;
1945                 }
1946
1947                 return applyUniform(location, (float*)vector);
1948         }
1949
1950         bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
1951         {
1952                 int vector[MAX_UNIFORM_VECTORS][4];
1953
1954                 for(int i = 0; i < count; i++)
1955                 {
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);
1959                         vector[i][3] = 0;
1960
1961                         v += 3;
1962                 }
1963
1964                 return applyUniform(location, (float*)vector);
1965         }
1966
1967         bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
1968         {
1969                 int vector[MAX_UNIFORM_VECTORS][4];
1970
1971                 for(int i = 0; i < count; i++)
1972                 {
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);
1977
1978                         v += 4;
1979                 }
1980
1981                 return applyUniform(location, (float*)vector);
1982         }
1983
1984         bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
1985         {
1986                 float vector[MAX_UNIFORM_VECTORS][4];
1987
1988                 for(int i = 0; i < count; i++)
1989                 {
1990                         vector[i][0] = v[0];
1991                         vector[i][1] = 0;
1992                         vector[i][2] = 0;
1993                         vector[i][3] = 0;
1994
1995                         v += 1;
1996                 }
1997
1998                 return applyUniform(location, (float*)vector);
1999         }
2000
2001         bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v)
2002         {
2003                 float vector[MAX_UNIFORM_VECTORS][4];
2004
2005                 for(int i = 0; i < count; i++)
2006                 {
2007                         vector[i][0] = v[0];
2008                         vector[i][1] = v[1];
2009                         vector[i][2] = 0;
2010                         vector[i][3] = 0;
2011
2012                         v += 2;
2013                 }
2014
2015                 return applyUniform(location, (float*)vector);
2016         }
2017
2018         bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v)
2019         {
2020                 float vector[MAX_UNIFORM_VECTORS][4];
2021
2022                 for(int i = 0; i < count; i++)
2023                 {
2024                         vector[i][0] = v[0];
2025                         vector[i][1] = v[1];
2026                         vector[i][2] = v[2];
2027                         vector[i][3] = 0;
2028
2029                         v += 3;
2030                 }
2031
2032                 return applyUniform(location, (float*)vector);
2033         }
2034
2035         bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v)
2036         {
2037                 return applyUniform(location, (float*)v);
2038         }
2039
2040         bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
2041         {
2042                 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2043
2044                 for(int i = 0; i < count; i++)
2045                 {
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;
2048
2049                         value += 4;
2050                 }
2051
2052                 return applyUniform(location, (float*)matrix);
2053         }
2054
2055         bool Program::applyUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value)
2056         {
2057                 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2058
2059                 for(int i = 0; i < count; i++)
2060                 {
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;
2063
2064                         value += 6;
2065                 }
2066
2067                 return applyUniform(location, (float*)matrix);
2068         }
2069
2070         bool Program::applyUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value)
2071         {
2072                 float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
2073
2074                 for(int i = 0; i < count; i++)
2075                 {
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];
2078
2079                         value += 8;
2080                 }
2081
2082                 return applyUniform(location, (float*)matrix);
2083         }
2084
2085         bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
2086         {
2087                 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2088
2089                 for(int i = 0; i < count; i++)
2090                 {
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;
2094
2095                         value += 9;
2096                 }
2097
2098                 return applyUniform(location, (float*)matrix);
2099         }
2100
2101         bool Program::applyUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value)
2102         {
2103                 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2104
2105                 for(int i = 0; i < count; i++)
2106                 {
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;
2110
2111                         value += 6;
2112                 }
2113
2114                 return applyUniform(location, (float*)matrix);
2115         }
2116
2117         bool Program::applyUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value)
2118         {
2119                 float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
2120
2121                 for(int i = 0; i < count; i++)
2122                 {
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];
2126
2127                         value += 12;
2128                 }
2129
2130                 return applyUniform(location, (float*)matrix);
2131         }
2132
2133         bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
2134         {
2135                 return applyUniform(location, (float*)value);
2136         }
2137
2138         bool Program::applyUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value)
2139         {
2140                 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
2141
2142                 for(int i = 0; i < count; i++)
2143                 {
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;
2148
2149                         value += 8;
2150                 }
2151
2152                 return applyUniform(location, (float*)matrix);
2153         }
2154
2155         bool Program::applyUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value)
2156         {
2157                 float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
2158
2159                 for(int i = 0; i < count; i++)
2160                 {
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;
2165
2166                         value += 12;
2167                 }
2168
2169                 return applyUniform(location, (float*)matrix);
2170         }
2171
2172         bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
2173         {
2174                 GLint vector[MAX_UNIFORM_VECTORS][4];
2175
2176                 for(int i = 0; i < count; i++)
2177                 {
2178                         vector[i][0] = v[i];
2179                         vector[i][1] = 0;
2180                         vector[i][2] = 0;
2181                         vector[i][3] = 0;
2182                 }
2183
2184                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
2185                 if(IsSamplerUniform(targetUniform->type))
2186                 {
2187                         if(targetUniform->psRegisterIndex != -1)
2188                         {
2189                                 for(int i = 0; i < count; i++)
2190                                 {
2191                                         unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
2192
2193                                         if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2194                                         {
2195                                                 ASSERT(samplersPS[samplerIndex].active);
2196                                                 samplersPS[samplerIndex].logicalTextureUnit = v[i];
2197                                         }
2198                                 }
2199                         }
2200
2201                         if(targetUniform->vsRegisterIndex != -1)
2202                         {
2203                                 for(int i = 0; i < count; i++)
2204                                 {
2205                                         unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
2206
2207                                         if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
2208                                         {
2209                                                 ASSERT(samplersVS[samplerIndex].active);
2210                                                 samplersVS[samplerIndex].logicalTextureUnit = v[i];
2211                                         }
2212                                 }
2213                         }
2214                 }
2215                 else
2216                 {
2217                         return applyUniform(location, (float*)vector);
2218                 }
2219
2220                 return true;
2221         }
2222
2223         bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
2224         {
2225                 GLint vector[MAX_UNIFORM_VECTORS][4];
2226
2227                 for(int i = 0; i < count; i++)
2228                 {
2229                         vector[i][0] = v[0];
2230                         vector[i][1] = v[1];
2231                         vector[i][2] = 0;
2232                         vector[i][3] = 0;
2233
2234                         v += 2;
2235                 }
2236
2237                 return applyUniform(location, (float*)vector);
2238         }
2239
2240         bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
2241         {
2242                 GLint vector[MAX_UNIFORM_VECTORS][4];
2243
2244                 for(int i = 0; i < count; i++)
2245                 {
2246                         vector[i][0] = v[0];
2247                         vector[i][1] = v[1];
2248                         vector[i][2] = v[2];
2249                         vector[i][3] = 0;
2250
2251                         v += 3;
2252                 }
2253
2254                 return applyUniform(location, (float*)vector);
2255         }
2256
2257         bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
2258         {
2259                 GLint vector[MAX_UNIFORM_VECTORS][4];
2260
2261                 for(int i = 0; i < count; i++)
2262                 {
2263                         vector[i][0] = v[0];
2264                         vector[i][1] = v[1];
2265                         vector[i][2] = v[2];
2266                         vector[i][3] = v[3];
2267
2268                         v += 4;
2269                 }
2270
2271                 return applyUniform(location, (float*)vector);
2272         }
2273
2274         bool Program::applyUniform1uiv(GLint location, GLsizei count, const GLuint *v)
2275         {
2276                 GLuint vector[MAX_UNIFORM_VECTORS][4];
2277
2278                 for(int i = 0; i < count; i++)
2279                 {
2280                         vector[i][0] = v[i];
2281                         vector[i][1] = 0;
2282                         vector[i][2] = 0;
2283                         vector[i][3] = 0;
2284                 }
2285
2286                 Uniform *targetUniform = uniforms[uniformIndex[location].index];
2287                 if(IsSamplerUniform(targetUniform->type))
2288                 {
2289                         if(targetUniform->psRegisterIndex != -1)
2290                         {
2291                                 for(int i = 0; i < count; i++)
2292                                 {
2293                                         unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
2294
2295                                         if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2296                                         {
2297                                                 ASSERT(samplersPS[samplerIndex].active);
2298                                                 samplersPS[samplerIndex].logicalTextureUnit = v[i];
2299                                         }
2300                                 }
2301                         }
2302
2303                         if(targetUniform->vsRegisterIndex != -1)
2304                         {
2305                                 for(int i = 0; i < count; i++)
2306                                 {
2307                                         unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
2308
2309                                         if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
2310                                         {
2311                                                 ASSERT(samplersVS[samplerIndex].active);
2312                                                 samplersVS[samplerIndex].logicalTextureUnit = v[i];
2313                                         }
2314                                 }
2315                         }
2316                 }
2317                 else
2318                 {
2319                         return applyUniform(location, (float*)vector);
2320                 }
2321
2322                 return true;
2323         }
2324
2325         bool Program::applyUniform2uiv(GLint location, GLsizei count, const GLuint *v)
2326         {
2327                 GLuint vector[MAX_UNIFORM_VECTORS][4];
2328
2329                 for(int i = 0; i < count; i++)
2330                 {
2331                         vector[i][0] = v[0];
2332                         vector[i][1] = v[1];
2333                         vector[i][2] = 0;
2334                         vector[i][3] = 0;
2335
2336                         v += 2;
2337                 }
2338
2339                 return applyUniform(location, (float*)vector);
2340         }
2341
2342         bool Program::applyUniform3uiv(GLint location, GLsizei count, const GLuint *v)
2343         {
2344                 GLuint vector[MAX_UNIFORM_VECTORS][4];
2345
2346                 for(int i = 0; i < count; i++)
2347                 {
2348                         vector[i][0] = v[0];
2349                         vector[i][1] = v[1];
2350                         vector[i][2] = v[2];
2351                         vector[i][3] = 0;
2352
2353                         v += 3;
2354                 }
2355
2356                 return applyUniform(location, (float*)vector);
2357         }
2358
2359         bool Program::applyUniform4uiv(GLint location, GLsizei count, const GLuint *v)
2360         {
2361                 GLuint vector[MAX_UNIFORM_VECTORS][4];
2362
2363                 for(int i = 0; i < count; i++)
2364                 {
2365                         vector[i][0] = v[0];
2366                         vector[i][1] = v[1];
2367                         vector[i][2] = v[2];
2368                         vector[i][3] = v[3];
2369
2370                         v += 4;
2371                 }
2372
2373                 return applyUniform(location, (float*)vector);
2374         }
2375
2376         void Program::appendToInfoLog(const char *format, ...)
2377         {
2378                 if(!format)
2379                 {
2380                         return;
2381                 }
2382
2383                 char info[1024];
2384
2385                 va_list vararg;
2386                 va_start(vararg, format);
2387                 vsnprintf(info, sizeof(info), format, vararg);
2388                 va_end(vararg);
2389
2390                 size_t infoLength = strlen(info);
2391
2392                 if(!infoLog)
2393                 {
2394                         infoLog = new char[infoLength + 2];
2395                         strcpy(infoLog, info);
2396                         strcpy(infoLog + infoLength, "\n");
2397                 }
2398                 else
2399                 {
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");
2405
2406                         delete[] infoLog;
2407                         infoLog = newLog;
2408                 }
2409         }
2410
2411         void Program::resetInfoLog()
2412         {
2413                 if(infoLog)
2414                 {
2415                         delete[] infoLog;
2416                         infoLog = 0;
2417                 }
2418         }
2419
2420         // Returns the program object to an unlinked state, before re-linking, or at destruction
2421         void Program::unlink()
2422         {
2423                 delete vertexBinary;
2424                 vertexBinary = 0;
2425                 delete pixelBinary;
2426                 pixelBinary = 0;
2427
2428                 for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
2429                 {
2430                         linkedAttribute[index].name.clear();
2431                         attributeStream[index] = -1;
2432                 }
2433
2434                 for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
2435                 {
2436                         samplersPS[index].active = false;
2437                 }
2438
2439                 for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
2440                 {
2441                         samplersVS[index].active = false;
2442                 }
2443
2444                 while(!uniforms.empty())
2445                 {
2446                         delete uniforms.back();
2447                         uniforms.pop_back();
2448                 }
2449
2450                 while(!uniformBlocks.empty())
2451                 {
2452                         delete uniformBlocks.back();
2453                         uniformBlocks.pop_back();
2454                 }
2455
2456                 uniformIndex.clear();
2457                 transformFeedbackLinkedVaryings.clear();
2458
2459                 delete[] infoLog;
2460                 infoLog = 0;
2461
2462                 linked = false;
2463         }
2464
2465         bool Program::isLinked() const
2466         {
2467                 return linked;
2468         }
2469
2470         bool Program::isValidated() const
2471         {
2472                 return validated;
2473         }
2474
2475         GLint Program::getBinaryLength() const
2476         {
2477                 UNIMPLEMENTED();
2478                 return 0;
2479         }
2480
2481         void Program::release()
2482         {
2483                 referenceCount--;
2484
2485                 if(referenceCount == 0 && orphaned)
2486                 {
2487                         resourceManager->deleteProgram(handle);
2488                 }
2489         }
2490
2491         void Program::addRef()
2492         {
2493                 referenceCount++;
2494         }
2495
2496         unsigned int Program::getRefCount() const
2497         {
2498                 return referenceCount;
2499         }
2500
2501         unsigned int Program::getSerial() const
2502         {
2503                 return serial;
2504         }
2505
2506         unsigned int Program::issueSerial()
2507         {
2508                 return currentSerial++;
2509         }
2510
2511         size_t Program::getInfoLogLength() const
2512         {
2513                 if(!infoLog)
2514                 {
2515                         return 0;
2516                 }
2517                 else
2518                 {
2519                    return strlen(infoLog) + 1;
2520                 }
2521         }
2522
2523         void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
2524         {
2525                 int index = 0;
2526
2527                 if(bufSize > 0)
2528                 {
2529                         if(infoLog)
2530                         {
2531                                 index = std::min(bufSize - 1, (int)strlen(infoLog));
2532                                 memcpy(buffer, infoLog, index);
2533                         }
2534
2535                         buffer[index] = '\0';
2536                 }
2537
2538                 if(length)
2539                 {
2540                         *length = index;
2541                 }
2542         }
2543
2544         void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
2545         {
2546                 int total = 0;
2547
2548                 if(vertexShader && (total < maxCount))
2549                 {
2550                         shaders[total++] = vertexShader->getName();
2551                 }
2552
2553                 if(fragmentShader && (total < maxCount))
2554                 {
2555                         shaders[total++] = fragmentShader->getName();
2556                 }
2557
2558                 if(count)
2559                 {
2560                         *count = total;
2561                 }
2562         }
2563
2564         void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2565         {
2566                 // Skip over inactive attributes
2567                 unsigned int activeAttribute = 0;
2568                 unsigned int attribute;
2569                 for(attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2570                 {
2571                         if(linkedAttribute[attribute].name.empty())
2572                         {
2573                                 continue;
2574                         }
2575
2576                         if(activeAttribute == index)
2577                         {
2578                                 break;
2579                         }
2580
2581                         activeAttribute++;
2582                 }
2583
2584                 if(bufsize > 0)
2585                 {
2586                         const char *string = linkedAttribute[attribute].name.c_str();
2587
2588                         strncpy(name, string, bufsize);
2589                         name[bufsize - 1] = '\0';
2590
2591                         if(length)
2592                         {
2593                                 *length = static_cast<GLsizei>(strlen(name));
2594                         }
2595                 }
2596
2597                 *size = 1;   // Always a single 'type' instance
2598
2599                 *type = linkedAttribute[attribute].type;
2600         }
2601
2602         size_t Program::getActiveAttributeCount() const
2603         {
2604                 int count = 0;
2605
2606                 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2607                 {
2608                         if(!linkedAttribute[attributeIndex].name.empty())
2609                         {
2610                                 count++;
2611                         }
2612                 }
2613
2614                 return count;
2615         }
2616
2617         GLint Program::getActiveAttributeMaxLength() const
2618         {
2619                 int maxLength = 0;
2620
2621                 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2622                 {
2623                         if(!linkedAttribute[attributeIndex].name.empty())
2624                         {
2625                                 maxLength = std::max((int)(linkedAttribute[attributeIndex].name.length() + 1), maxLength);
2626                         }
2627                 }
2628
2629                 return maxLength;
2630         }
2631
2632         void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2633         {
2634                 if(bufsize > 0)
2635                 {
2636                         std::string string = uniforms[index]->name;
2637
2638                         if(uniforms[index]->isArray())
2639                         {
2640                                 string += "[0]";
2641                         }
2642
2643                         strncpy(name, string.c_str(), bufsize);
2644                         name[bufsize - 1] = '\0';
2645
2646                         if(length)
2647                         {
2648                                 *length = static_cast<GLsizei>(strlen(name));
2649                         }
2650                 }
2651
2652                 *size = uniforms[index]->size();
2653
2654                 *type = uniforms[index]->type;
2655         }
2656
2657         size_t Program::getActiveUniformCount() const
2658         {
2659                 return uniforms.size();
2660         }
2661
2662         GLint Program::getActiveUniformMaxLength() const
2663         {
2664                 int maxLength = 0;
2665
2666                 size_t numUniforms = uniforms.size();
2667                 for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
2668                 {
2669                         if(!uniforms[uniformIndex]->name.empty())
2670                         {
2671                                 int length = (int)(uniforms[uniformIndex]->name.length() + 1);
2672                                 if(uniforms[uniformIndex]->isArray())
2673                                 {
2674                                         length += 3;  // Counting in "[0]".
2675                                 }
2676                                 maxLength = std::max(length, maxLength);
2677                         }
2678                 }
2679
2680                 return maxLength;
2681         }
2682
2683         GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
2684         {
2685                 const Uniform& uniform = *uniforms[index];
2686                 switch(pname)
2687                 {
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);
2696                 default:
2697                         UNREACHABLE(pname);
2698                         break;
2699                 }
2700                 return 0;
2701         }
2702
2703         void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
2704         {
2705                 ASSERT(index < getActiveUniformBlockCount());
2706
2707                 const UniformBlock &uniformBlock = *uniformBlocks[index];
2708
2709                 if(bufSize > 0)
2710                 {
2711                         std::string string = uniformBlock.name;
2712
2713                         if(uniformBlock.isArrayElement())
2714                         {
2715                                 std::ostringstream elementIndex;
2716                                 elementIndex << uniformBlock.elementIndex;
2717                                 string += "[" + elementIndex.str()  + "]";
2718                         }
2719
2720                         strncpy(name, string.c_str(), bufSize);
2721                         name[bufSize - 1] = '\0';
2722
2723                         if(length)
2724                         {
2725                                 *length = static_cast<GLsizei>(strlen(name));
2726                         }
2727                 }
2728         }
2729
2730         size_t Program::getActiveUniformBlockCount() const
2731         {
2732                 return uniformBlocks.size();
2733         }
2734
2735         GLint Program::getActiveUniformBlockMaxLength() const
2736         {
2737                 GLint maxLength = 0;
2738
2739                 if(isLinked())
2740                 {
2741                         size_t numUniformBlocks = getActiveUniformBlockCount();
2742                         for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
2743                         {
2744                                 const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
2745                                 if(!uniformBlock.name.empty())
2746                                 {
2747                                         GLint length = static_cast<GLint>(uniformBlock.name.length() + 1);
2748
2749                                         // Counting in "[0]".
2750                                         const GLint arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
2751
2752                                         maxLength = std::max(length + arrayLength, maxLength);
2753                                 }
2754                         }
2755                 }
2756
2757                 return maxLength;
2758         }
2759
2760         void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
2761         {
2762                 transformFeedbackVaryings.resize(count);
2763                 for(GLsizei i = 0; i < count; i++)
2764                 {
2765                         transformFeedbackVaryings[i] = varyings[i];
2766                 }
2767
2768                 transformFeedbackBufferMode = bufferMode;
2769         }
2770
2771         void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
2772         {
2773                 if(linked)
2774                 {
2775                         ASSERT(index < transformFeedbackLinkedVaryings.size());
2776                         const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];
2777                         GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
2778                         if(length)
2779                         {
2780                                 *length = lastNameIdx;
2781                         }
2782                         if(size)
2783                         {
2784                                 *size = varying.size;
2785                         }
2786                         if(type)
2787                         {
2788                                 *type = varying.type;
2789                         }
2790                         if(name)
2791                         {
2792                                 memcpy(name, varying.name.c_str(), lastNameIdx);
2793                                 name[lastNameIdx] = '\0';
2794                         }
2795                 }
2796         }
2797
2798         GLsizei Program::getTransformFeedbackVaryingCount() const
2799         {
2800                 if(linked)
2801                 {
2802                         return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());
2803                 }
2804                 else
2805                 {
2806                         return 0;
2807                 }
2808         }
2809
2810         GLsizei Program::getTransformFeedbackVaryingMaxLength() const
2811         {
2812                 if(linked)
2813                 {
2814                         GLsizei maxSize = 0;
2815                         for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)
2816                         {
2817                                 const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];
2818                                 maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
2819                         }
2820
2821                         return maxSize;
2822                 }
2823                 else
2824                 {
2825                         return 0;
2826                 }
2827         }
2828
2829         GLenum Program::getTransformFeedbackBufferMode() const
2830         {
2831                 return transformFeedbackBufferMode;
2832         }
2833
2834         void Program::flagForDeletion()
2835         {
2836                 orphaned = true;
2837         }
2838
2839         bool Program::isFlaggedForDeletion() const
2840         {
2841                 return orphaned;
2842         }
2843
2844         void Program::validate()
2845         {
2846                 resetInfoLog();
2847
2848                 if(!isLinked())
2849                 {
2850                         appendToInfoLog("Program has not been successfully linked.");
2851                         validated = false;
2852                 }
2853                 else
2854                 {
2855                         applyUniforms();
2856                         if(!validateSamplers(true))
2857                         {
2858                                 validated = false;
2859                         }
2860                         else
2861                         {
2862                                 validated = true;
2863                         }
2864                 }
2865         }
2866
2867         bool Program::validateSamplers(bool logErrors)
2868         {
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.
2872
2873                 TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
2874
2875                 for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
2876                 {
2877                         textureUnitType[i] = TEXTURE_UNKNOWN;
2878                 }
2879
2880                 for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
2881                 {
2882                         if(samplersPS[i].active)
2883                         {
2884                                 unsigned int unit = samplersPS[i].logicalTextureUnit;
2885
2886                                 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
2887                                 {
2888                                         if(logErrors)
2889                                         {
2890                                                 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2891                                         }
2892
2893                                         return false;
2894                                 }
2895
2896                                 if(textureUnitType[unit] != TEXTURE_UNKNOWN)
2897                                 {
2898                                         if(samplersPS[i].textureType != textureUnitType[unit])
2899                                         {
2900                                                 if(logErrors)
2901                                                 {
2902                                                         appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2903                                                 }
2904
2905                                                 return false;
2906                                         }
2907                                 }
2908                                 else
2909                                 {
2910                                         textureUnitType[unit] = samplersPS[i].textureType;
2911                                 }
2912                         }
2913                 }
2914
2915                 for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
2916                 {
2917                         if(samplersVS[i].active)
2918                         {
2919                                 unsigned int unit = samplersVS[i].logicalTextureUnit;
2920
2921                                 if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
2922                                 {
2923                                         if(logErrors)
2924                                         {
2925                                                 appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
2926                                         }
2927
2928                                         return false;
2929                                 }
2930
2931                                 if(textureUnitType[unit] != TEXTURE_UNKNOWN)
2932                                 {
2933                                         if(samplersVS[i].textureType != textureUnitType[unit])
2934                                         {
2935                                                 if(logErrors)
2936                                                 {
2937                                                         appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2938                                                 }
2939
2940                                                 return false;
2941                                         }
2942                                 }
2943                                 else
2944                                 {
2945                                         textureUnitType[unit] = samplersVS[i].textureType;
2946                                 }
2947                         }
2948                 }
2949
2950                 return true;
2951         }
2952 }