OSDN Git Service

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