OSDN Git Service

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