OSDN Git Service

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