OSDN Git Service

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