Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / ProgramBinary.cpp
1 //
2 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Program.cpp: Implements the gl::Program class. Implements GL program objects
8 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
9
10 #include "libGLESv2/BinaryStream.h"
11 #include "libGLESv2/ProgramBinary.h"
12 #include "libGLESv2/Framebuffer.h"
13 #include "libGLESv2/FramebufferAttachment.h"
14 #include "libGLESv2/Renderbuffer.h"
15 #include "libGLESv2/renderer/ShaderExecutable.h"
16
17 #include "common/debug.h"
18 #include "common/version.h"
19 #include "common/utilities.h"
20 #include "common/platform.h"
21
22 #include "libGLESv2/main.h"
23 #include "libGLESv2/Shader.h"
24 #include "libGLESv2/Program.h"
25 #include "libGLESv2/renderer/ProgramImpl.h"
26 #include "libGLESv2/renderer/Renderer.h"
27 #include "libGLESv2/renderer/d3d/DynamicHLSL.h"
28 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
29 #include "libGLESv2/renderer/d3d/VertexDataManager.h"
30 #include "libGLESv2/Context.h"
31 #include "libGLESv2/Buffer.h"
32 #include "common/blocklayout.h"
33
34 namespace gl
35 {
36
37 namespace
38 {
39
40 GLenum GetTextureType(GLenum samplerType)
41 {
42     switch (samplerType)
43     {
44       case GL_SAMPLER_2D:
45       case GL_INT_SAMPLER_2D:
46       case GL_UNSIGNED_INT_SAMPLER_2D:
47       case GL_SAMPLER_2D_SHADOW:
48         return GL_TEXTURE_2D;
49       case GL_SAMPLER_3D:
50       case GL_INT_SAMPLER_3D:
51       case GL_UNSIGNED_INT_SAMPLER_3D:
52         return GL_TEXTURE_3D;
53       case GL_SAMPLER_CUBE:
54       case GL_SAMPLER_CUBE_SHADOW:
55         return GL_TEXTURE_CUBE_MAP;
56       case GL_INT_SAMPLER_CUBE:
57       case GL_UNSIGNED_INT_SAMPLER_CUBE:
58         return GL_TEXTURE_CUBE_MAP;
59       case GL_SAMPLER_2D_ARRAY:
60       case GL_INT_SAMPLER_2D_ARRAY:
61       case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
62       case GL_SAMPLER_2D_ARRAY_SHADOW:
63         return GL_TEXTURE_2D_ARRAY;
64       default: UNREACHABLE();
65     }
66
67     return GL_TEXTURE_2D;
68 }
69
70 unsigned int ParseAndStripArrayIndex(std::string* name)
71 {
72     unsigned int subscript = GL_INVALID_INDEX;
73
74     // Strip any trailing array operator and retrieve the subscript
75     size_t open = name->find_last_of('[');
76     size_t close = name->find_last_of(']');
77     if (open != std::string::npos && close == name->length() - 1)
78     {
79         subscript = atoi(name->substr(open + 1).c_str());
80         name->erase(open);
81     }
82
83     return subscript;
84 }
85
86 void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
87 {
88     size_t layoutIndex = 0;
89     for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
90     {
91         ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS);
92
93         const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
94
95         if (shaderAttr.type != GL_NONE)
96         {
97             GLenum transposedType = TransposeMatrixType(shaderAttr.type);
98
99             for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++)
100             {
101                 VertexFormat *defaultFormat = &inputLayout[layoutIndex];
102
103                 defaultFormat->mType = VariableComponentType(transposedType);
104                 defaultFormat->mNormalized = false;
105                 defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
106                 defaultFormat->mComponents = VariableColumnCount(transposedType);
107             }
108         }
109     }
110 }
111
112 std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
113 {
114     std::vector<GLenum> defaultPixelOutput(1);
115
116     ASSERT(!shaderOutputVars.empty());
117     defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
118
119     return defaultPixelOutput;
120 }
121
122 bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
123 {
124     return var.isRowMajorLayout;
125 }
126
127 bool IsRowMajorLayout(const sh::ShaderVariable &var)
128 {
129     return false;
130 }
131
132 }
133
134 VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
135     : name(name), element(element), index(index)
136 {
137 }
138
139 ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[],
140                                                   const GLenum signature[],
141                                                   rx::ShaderExecutable *shaderExecutable)
142     : mShaderExecutable(shaderExecutable)
143 {
144     for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
145     {
146         mInputs[attributeIndex] = inputLayout[attributeIndex];
147         mSignature[attributeIndex] = signature[attributeIndex];
148     }
149 }
150
151 ProgramBinary::VertexExecutable::~VertexExecutable()
152 {
153     SafeDelete(mShaderExecutable);
154 }
155
156 bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const
157 {
158     for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
159     {
160         if (mSignature[attributeIndex] != signature[attributeIndex])
161         {
162             return false;
163         }
164     }
165
166     return true;
167 }
168
169 ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable)
170     : mOutputSignature(outputSignature),
171       mShaderExecutable(shaderExecutable)
172 {
173 }
174
175 ProgramBinary::PixelExecutable::~PixelExecutable()
176 {
177     SafeDelete(mShaderExecutable);
178 }
179
180 LinkedVarying::LinkedVarying()
181 {
182 }
183
184 LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
185                              unsigned int semanticIndex, unsigned int semanticIndexCount)
186     : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount)
187 {
188 }
189
190 unsigned int ProgramBinary::mCurrentSerial = 1;
191
192 ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
193     : RefCountObject(0),
194       mProgram(impl),
195       mGeometryExecutable(NULL),
196       mUsedVertexSamplerRange(0),
197       mUsedPixelSamplerRange(0),
198       mUsesPointSize(false),
199       mShaderVersion(100),
200       mDirtySamplerMapping(true),
201       mValidated(false),
202       mSerial(issueSerial())
203 {
204     ASSERT(impl);
205
206     for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
207     {
208         mSemanticIndex[index] = -1;
209     }
210 }
211
212 ProgramBinary::~ProgramBinary()
213 {
214     reset();
215     SafeDelete(mProgram);
216 }
217
218 unsigned int ProgramBinary::getSerial() const
219 {
220     return mSerial;
221 }
222
223 int ProgramBinary::getShaderVersion() const
224 {
225     return mShaderVersion;
226 }
227
228 unsigned int ProgramBinary::issueSerial()
229 {
230     return mCurrentSerial++;
231 }
232
233 rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
234 {
235     std::vector<GLenum> outputs;
236
237     const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
238
239     for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
240     {
241         const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
242
243         if (colorbuffer)
244         {
245             outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
246         }
247         else
248         {
249             outputs.push_back(GL_NONE);
250         }
251     }
252
253     return getPixelExecutableForOutputLayout(outputs);
254 }
255
256 rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
257 {
258     for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
259     {
260         if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
261         {
262             return mPixelExecutables[executableIndex]->shaderExecutable();
263         }
264     }
265
266     InfoLog tempInfoLog;
267     rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
268             mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
269
270     if (!pixelExecutable)
271     {
272         std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
273         tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
274         ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
275     }
276     else
277     {
278         mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
279     }
280
281     return pixelExecutable;
282 }
283
284 rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
285 {
286     GLenum signature[MAX_VERTEX_ATTRIBS];
287     mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
288
289     for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
290     {
291         if (mVertexExecutables[executableIndex]->matchesSignature(signature))
292         {
293             return mVertexExecutables[executableIndex]->shaderExecutable();
294         }
295     }
296
297     InfoLog tempInfoLog;
298     rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
299             mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
300
301     if (!vertexExecutable)
302     {
303         std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
304         tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
305         ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
306     }
307     else
308     {
309         mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
310     }
311
312     return vertexExecutable;
313 }
314
315 rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const
316 {
317     return mGeometryExecutable;
318 }
319
320 GLuint ProgramBinary::getAttributeLocation(const char *name)
321 {
322     if (name)
323     {
324         for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
325         {
326             if (mLinkedAttribute[index].name == std::string(name))
327             {
328                 return index;
329             }
330         }
331     }
332
333     return -1;
334 }
335
336 int ProgramBinary::getSemanticIndex(int attributeIndex)
337 {
338     ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
339
340     return mSemanticIndex[attributeIndex];
341 }
342
343 // Returns one more than the highest sampler index used.
344 GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
345 {
346     switch (type)
347     {
348       case SAMPLER_PIXEL:
349         return mUsedPixelSamplerRange;
350       case SAMPLER_VERTEX:
351         return mUsedVertexSamplerRange;
352       default:
353         UNREACHABLE();
354         return 0;
355     }
356 }
357
358 bool ProgramBinary::usesPointSize() const
359 {
360     return mUsesPointSize;
361 }
362
363 bool ProgramBinary::usesPointSpriteEmulation() const
364 {
365     return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
366 }
367
368 bool ProgramBinary::usesGeometryShader() const
369 {
370     return usesPointSpriteEmulation();
371 }
372
373 GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
374 {
375     GLint logicalTextureUnit = -1;
376
377     switch (type)
378     {
379       case SAMPLER_PIXEL:
380         ASSERT(samplerIndex < caps.maxTextureImageUnits);
381         if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
382         {
383             logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
384         }
385         break;
386       case SAMPLER_VERTEX:
387         ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
388         if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
389         {
390             logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
391         }
392         break;
393       default: UNREACHABLE();
394     }
395
396     if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
397     {
398         return logicalTextureUnit;
399     }
400
401     return -1;
402 }
403
404 // Returns the texture type for a given Direct3D 9 sampler type and
405 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
406 GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
407 {
408     switch (type)
409     {
410       case SAMPLER_PIXEL:
411         ASSERT(samplerIndex < mSamplersPS.size());
412         ASSERT(mSamplersPS[samplerIndex].active);
413         return mSamplersPS[samplerIndex].textureType;
414       case SAMPLER_VERTEX:
415         ASSERT(samplerIndex < mSamplersVS.size());
416         ASSERT(mSamplersVS[samplerIndex].active);
417         return mSamplersVS[samplerIndex].textureType;
418       default: UNREACHABLE();
419     }
420
421     return GL_TEXTURE_2D;
422 }
423
424 GLint ProgramBinary::getUniformLocation(std::string name)
425 {
426     unsigned int subscript = ParseAndStripArrayIndex(&name);
427
428     unsigned int numUniforms = mUniformIndex.size();
429     for (unsigned int location = 0; location < numUniforms; location++)
430     {
431         if (mUniformIndex[location].name == name)
432         {
433             const int index = mUniformIndex[location].index;
434             const bool isArray = mUniforms[index]->isArray();
435
436             if ((isArray && mUniformIndex[location].element == subscript) ||
437                 (subscript == GL_INVALID_INDEX))
438             {
439                 return location;
440             }
441         }
442     }
443
444     return -1;
445 }
446
447 GLuint ProgramBinary::getUniformIndex(std::string name)
448 {
449     unsigned int subscript = ParseAndStripArrayIndex(&name);
450
451     // The app is not allowed to specify array indices other than 0 for arrays of basic types
452     if (subscript != 0 && subscript != GL_INVALID_INDEX)
453     {
454         return GL_INVALID_INDEX;
455     }
456
457     unsigned int numUniforms = mUniforms.size();
458     for (unsigned int index = 0; index < numUniforms; index++)
459     {
460         if (mUniforms[index]->name == name)
461         {
462             if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
463             {
464                 return index;
465             }
466         }
467     }
468
469     return GL_INVALID_INDEX;
470 }
471
472 GLuint ProgramBinary::getUniformBlockIndex(std::string name)
473 {
474     unsigned int subscript = ParseAndStripArrayIndex(&name);
475
476     unsigned int numUniformBlocks = mUniformBlocks.size();
477     for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
478     {
479         const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
480         if (uniformBlock.name == name)
481         {
482             const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
483             if (subscript == uniformBlock.elementIndex || arrayElementZero)
484             {
485                 return blockIndex;
486             }
487         }
488     }
489
490     return GL_INVALID_INDEX;
491 }
492
493 UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
494 {
495     ASSERT(blockIndex < mUniformBlocks.size());
496     return mUniformBlocks[blockIndex];
497 }
498
499 GLint ProgramBinary::getFragDataLocation(const char *name) const
500 {
501     std::string baseName(name);
502     unsigned int arrayIndex;
503     arrayIndex = ParseAndStripArrayIndex(&baseName);
504
505     for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
506     {
507         const VariableLocation &outputVariable = locationIt->second;
508
509         if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element))
510         {
511             return static_cast<GLint>(locationIt->first);
512         }
513     }
514
515     return -1;
516 }
517
518 size_t ProgramBinary::getTransformFeedbackVaryingCount() const
519 {
520     return mTransformFeedbackLinkedVaryings.size();
521 }
522
523 const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
524 {
525     return mTransformFeedbackLinkedVaryings[idx];
526 }
527
528 GLenum ProgramBinary::getTransformFeedbackBufferMode() const
529 {
530     return mTransformFeedbackBufferMode;
531 }
532
533 template <typename T>
534 static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
535 {
536     ASSERT(dest != NULL);
537     ASSERT(dirtyFlag != NULL);
538
539     *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0);
540     *dest = source;
541 }
542
543 template <typename T>
544 void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
545 {
546     const int components = VariableComponentCount(targetUniformType);
547     const GLenum targetBoolType = VariableBoolVectorType(targetUniformType);
548
549     LinkedUniform *targetUniform = getUniformByLocation(location);
550
551     int elementCount = targetUniform->elementCount();
552
553     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
554
555     if (targetUniform->type == targetUniformType)
556     {
557         T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
558
559         for (int i = 0; i < count; i++)
560         {
561             T *dest = target + (i * 4);
562             const T *source = v + (i * components);
563
564             for (int c = 0; c < components; c++)
565             {
566                 SetIfDirty(dest + c, source[c], &targetUniform->dirty);
567             }
568             for (int c = components; c < 4; c++)
569             {
570                 SetIfDirty(dest + c, T(0), &targetUniform->dirty);
571             }
572         }
573     }
574     else if (targetUniform->type == targetBoolType)
575     {
576         GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
577
578         for (int i = 0; i < count; i++)
579         {
580             GLint *dest = boolParams + (i * 4);
581             const T *source = v + (i * components);
582
583             for (int c = 0; c < components; c++)
584             {
585                 SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
586             }
587             for (int c = components; c < 4; c++)
588             {
589                 SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
590             }
591         }
592     }
593     else if (IsSampler(targetUniform->type))
594     {
595         ASSERT(targetUniformType == GL_INT);
596
597         GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
598
599         bool wasDirty = targetUniform->dirty;
600
601         for (int i = 0; i < count; i++)
602         {
603             GLint *dest = target + (i * 4);
604             const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
605
606             SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
607             SetIfDirty(dest + 1, 0, &targetUniform->dirty);
608             SetIfDirty(dest + 2, 0, &targetUniform->dirty);
609             SetIfDirty(dest + 3, 0, &targetUniform->dirty);
610         }
611
612         if (!wasDirty && targetUniform->dirty)
613         {
614             mDirtySamplerMapping = true;
615         }
616     }
617     else UNREACHABLE();
618 }
619
620 void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
621 {
622     setUniform(location, count, v, GL_FLOAT);
623 }
624
625 void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
626 {
627     setUniform(location, count, v, GL_FLOAT_VEC2);
628 }
629
630 void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
631 {
632     setUniform(location, count, v, GL_FLOAT_VEC3);
633 }
634
635 void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
636 {
637     setUniform(location, count, v, GL_FLOAT_VEC4);
638 }
639
640 template<typename T>
641 bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
642 {
643     bool dirty = false;
644     int copyWidth = std::min(targetHeight, srcWidth);
645     int copyHeight = std::min(targetWidth, srcHeight);
646
647     for (int x = 0; x < copyWidth; x++)
648     {
649         for (int y = 0; y < copyHeight; y++)
650         {
651             SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty);
652         }
653     }
654     // clear unfilled right side
655     for (int y = 0; y < copyWidth; y++)
656     {
657         for (int x = copyHeight; x < targetWidth; x++)
658         {
659             SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
660         }
661     }
662     // clear unfilled bottom.
663     for (int y = copyWidth; y < targetHeight; y++)
664     {
665         for (int x = 0; x < targetWidth; x++)
666         {
667             SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
668         }
669     }
670
671     return dirty;
672 }
673
674 template<typename T>
675 bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
676 {
677     bool dirty = false;
678     int copyWidth = std::min(targetWidth, srcWidth);
679     int copyHeight = std::min(targetHeight, srcHeight);
680
681     for (int y = 0; y < copyHeight; y++)
682     {
683         for (int x = 0; x < copyWidth; x++)
684         {
685             SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty);
686         }
687     }
688     // clear unfilled right side
689     for (int y = 0; y < copyHeight; y++)
690     {
691         for (int x = copyWidth; x < targetWidth; x++)
692         {
693             SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
694         }
695     }
696     // clear unfilled bottom.
697     for (int y = copyHeight; y < targetHeight; y++)
698     {
699         for (int x = 0; x < targetWidth; x++)
700         {
701             SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
702         }
703     }
704
705     return dirty;
706 }
707
708 template <int cols, int rows>
709 void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
710 {
711     LinkedUniform *targetUniform = getUniformByLocation(location);
712
713     int elementCount = targetUniform->elementCount();
714
715     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
716     const unsigned int targetMatrixStride = (4 * rows);
717     GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
718
719     for (int i = 0; i < count; i++)
720     {
721         // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
722         if (transpose == GL_FALSE)
723         {
724             targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty;
725         }
726         else
727         {
728             targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty;
729         }
730         target += targetMatrixStride;
731         value += cols * rows;
732     }
733 }
734
735 void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
736 {
737     setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
738 }
739
740 void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
741 {
742     setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
743 }
744
745 void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
746 {
747     setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
748 }
749
750 void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
751 {
752     setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
753 }
754
755 void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
756 {
757     setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
758 }
759
760 void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
761 {
762     setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
763 }
764
765 void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
766 {
767     setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
768 }
769
770 void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
771 {
772     setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
773 }
774
775 void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
776 {
777     setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
778 }
779
780 void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
781 {
782     setUniform(location, count, v, GL_INT);
783 }
784
785 void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
786 {
787     setUniform(location, count, v, GL_INT_VEC2);
788 }
789
790 void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
791 {
792     setUniform(location, count, v, GL_INT_VEC3);
793 }
794
795 void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
796 {
797     setUniform(location, count, v, GL_INT_VEC4);
798 }
799
800 void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
801 {
802     setUniform(location, count, v, GL_UNSIGNED_INT);
803 }
804
805 void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
806 {
807     setUniform(location, count, v, GL_UNSIGNED_INT_VEC2);
808 }
809
810 void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
811 {
812     setUniform(location, count, v, GL_UNSIGNED_INT_VEC3);
813 }
814
815 void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
816 {
817     setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
818 }
819
820 template <typename T>
821 void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
822 {
823     LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
824
825     if (IsMatrixType(targetUniform->type))
826     {
827         const int rows = VariableRowCount(targetUniform->type);
828         const int cols = VariableColumnCount(targetUniform->type);
829         transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
830     }
831     else if (uniformType == VariableComponentType(targetUniform->type))
832     {
833         unsigned int size = VariableComponentCount(targetUniform->type);
834         memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
835                 size * sizeof(T));
836     }
837     else
838     {
839         unsigned int size = VariableComponentCount(targetUniform->type);
840         switch (VariableComponentType(targetUniform->type))
841         {
842           case GL_BOOL:
843             {
844                 GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
845
846                 for (unsigned int i = 0; i < size; i++)
847                 {
848                     params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
849                 }
850             }
851             break;
852
853           case GL_FLOAT:
854             {
855                 GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
856
857                 for (unsigned int i = 0; i < size; i++)
858                 {
859                     params[i] = static_cast<T>(floatParams[i]);
860                 }
861             }
862             break;
863
864           case GL_INT:
865             {
866                 GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
867
868                 for (unsigned int i = 0; i < size; i++)
869                 {
870                     params[i] = static_cast<T>(intParams[i]);
871                 }
872             }
873             break;
874
875           case GL_UNSIGNED_INT:
876             {
877                 GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
878
879                 for (unsigned int i = 0; i < size; i++)
880                 {
881                     params[i] = static_cast<T>(uintParams[i]);
882                 }
883             }
884             break;
885
886           default: UNREACHABLE();
887         }
888     }
889 }
890
891 void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
892 {
893     getUniformv(location, params, GL_FLOAT);
894 }
895
896 void ProgramBinary::getUniformiv(GLint location, GLint *params)
897 {
898     getUniformv(location, params, GL_INT);
899 }
900
901 void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
902 {
903     getUniformv(location, params, GL_UNSIGNED_INT);
904 }
905
906 void ProgramBinary::dirtyAllUniforms()
907 {
908     unsigned int numUniforms = mUniforms.size();
909     for (unsigned int index = 0; index < numUniforms; index++)
910     {
911         mUniforms[index]->dirty = true;
912     }
913 }
914
915 void ProgramBinary::updateSamplerMapping()
916 {
917     if (!mDirtySamplerMapping)
918     {
919         return;
920     }
921
922     mDirtySamplerMapping = false;
923
924     // Retrieve sampler uniform values
925     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
926     {
927         LinkedUniform *targetUniform = mUniforms[uniformIndex];
928
929         if (targetUniform->dirty)
930         {
931             if (IsSampler(targetUniform->type))
932             {
933                 int count = targetUniform->elementCount();
934                 GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
935
936                 if (targetUniform->isReferencedByFragmentShader())
937                 {
938                     unsigned int firstIndex = targetUniform->psRegisterIndex;
939
940                     for (int i = 0; i < count; i++)
941                     {
942                         unsigned int samplerIndex = firstIndex + i;
943
944                         if (samplerIndex < mSamplersPS.size())
945                         {
946                             ASSERT(mSamplersPS[samplerIndex].active);
947                             mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
948                         }
949                     }
950                 }
951
952                 if (targetUniform->isReferencedByVertexShader())
953                 {
954                     unsigned int firstIndex = targetUniform->vsRegisterIndex;
955
956                     for (int i = 0; i < count; i++)
957                     {
958                         unsigned int samplerIndex = firstIndex + i;
959
960                         if (samplerIndex < mSamplersVS.size())
961                         {
962                             ASSERT(mSamplersVS[samplerIndex].active);
963                             mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
964                         }
965                     }
966                 }
967             }
968         }
969     }
970 }
971
972 // Applies all the uniforms set for this program object to the renderer
973 void ProgramBinary::applyUniforms()
974 {
975     updateSamplerMapping();
976
977     mProgram->getRenderer()->applyUniforms(*this);
978
979     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
980     {
981         mUniforms[uniformIndex]->dirty = false;
982     }
983 }
984
985 bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
986 {
987     const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
988     const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
989
990     const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers();
991     const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers();
992
993     ASSERT(boundBuffers.size() == mUniformBlocks.size());
994
995     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
996     {
997         UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
998         gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
999
1000         ASSERT(uniformBlock && uniformBuffer);
1001
1002         if (uniformBuffer->getSize() < uniformBlock->dataSize)
1003         {
1004             // undefined behaviour
1005             return false;
1006         }
1007
1008         // Unnecessary to apply an unreferenced standard or shared UBO
1009         if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
1010         {
1011             continue;
1012         }
1013
1014         if (uniformBlock->isReferencedByVertexShader())
1015         {
1016             unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
1017             ASSERT(vertexUniformBuffers[registerIndex] == NULL);
1018             ASSERT(registerIndex < caps.maxVertexUniformBlocks);
1019             vertexUniformBuffers[registerIndex] = uniformBuffer;
1020         }
1021
1022         if (uniformBlock->isReferencedByFragmentShader())
1023         {
1024             unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
1025             ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
1026             ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
1027             fragmentUniformBuffers[registerIndex] = uniformBuffer;
1028         }
1029     }
1030
1031     return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
1032 }
1033
1034 bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
1035 {
1036     std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
1037     std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
1038
1039     for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
1040     {
1041         PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
1042         bool matched = false;
1043
1044         // Built-in varyings obey special rules
1045         if (input->isBuiltIn())
1046         {
1047             continue;
1048         }
1049
1050         for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
1051         {
1052             PackedVarying *output = &vertexVaryings[vertVaryingIndex];
1053             if (output->name == input->name)
1054             {
1055                 if (!linkValidateVaryings(infoLog, output->name, *input, *output))
1056                 {
1057                     return false;
1058                 }
1059
1060                 output->registerIndex = input->registerIndex;
1061                 output->columnIndex = input->columnIndex;
1062
1063                 matched = true;
1064                 break;
1065             }
1066         }
1067
1068         // We permit unmatched, unreferenced varyings
1069         if (!matched && input->staticUse)
1070         {
1071             infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
1072             return false;
1073         }
1074     }
1075
1076     return true;
1077 }
1078
1079 bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
1080 {
1081 #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
1082     return false;
1083 #else
1084     ASSERT(binaryFormat == mProgram->getBinaryFormat());
1085
1086     reset();
1087
1088     BinaryInputStream stream(binary, length);
1089
1090     GLenum format = stream.readInt<GLenum>();
1091     if (format != mProgram->getBinaryFormat())
1092     {
1093         infoLog.append("Invalid program binary format.");
1094         return false;
1095     }
1096
1097     int majorVersion = stream.readInt<int>();
1098     int minorVersion = stream.readInt<int>();
1099     if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
1100     {
1101         infoLog.append("Invalid program binary version.");
1102         return false;
1103     }
1104
1105     unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
1106     stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE);
1107     if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
1108     {
1109         infoLog.append("Invalid program binary version.");
1110         return false;
1111     }
1112
1113     int compileFlags = stream.readInt<int>();
1114     if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
1115     {
1116         infoLog.append("Mismatched compilation flags.");
1117         return false;
1118     }
1119
1120     for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
1121     {
1122         stream.readInt(&mLinkedAttribute[i].type);
1123         stream.readString(&mLinkedAttribute[i].name);
1124         stream.readInt(&mShaderAttributes[i].type);
1125         stream.readString(&mShaderAttributes[i].name);
1126         stream.readInt(&mSemanticIndex[i]);
1127     }
1128
1129     initAttributesByLayout();
1130
1131     const unsigned int psSamplerCount = stream.readInt<unsigned int>();
1132     for (unsigned int i = 0; i < psSamplerCount; ++i)
1133     {
1134         Sampler sampler;
1135         stream.readBool(&sampler.active);
1136         stream.readInt(&sampler.logicalTextureUnit);
1137         stream.readInt(&sampler.textureType);
1138         mSamplersPS.push_back(sampler);
1139     }
1140     const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
1141     for (unsigned int i = 0; i < vsSamplerCount; ++i)
1142     {
1143         Sampler sampler;
1144         stream.readBool(&sampler.active);
1145         stream.readInt(&sampler.logicalTextureUnit);
1146         stream.readInt(&sampler.textureType);
1147         mSamplersVS.push_back(sampler);
1148     }
1149
1150     stream.readInt(&mUsedVertexSamplerRange);
1151     stream.readInt(&mUsedPixelSamplerRange);
1152     stream.readBool(&mUsesPointSize);
1153     stream.readInt(&mShaderVersion);
1154
1155     const unsigned int uniformCount = stream.readInt<unsigned int>();
1156     if (stream.error())
1157     {
1158         infoLog.append("Invalid program binary.");
1159         return false;
1160     }
1161
1162     mUniforms.resize(uniformCount);
1163     for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
1164     {
1165         GLenum type = stream.readInt<GLenum>();
1166         GLenum precision = stream.readInt<GLenum>();
1167         std::string name = stream.readString();
1168         unsigned int arraySize = stream.readInt<unsigned int>();
1169         int blockIndex = stream.readInt<int>();
1170
1171         int offset = stream.readInt<int>();
1172         int arrayStride = stream.readInt<int>();
1173         int matrixStride = stream.readInt<int>();
1174         bool isRowMajorMatrix = stream.readBool();
1175
1176         const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
1177
1178         LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
1179
1180         stream.readInt(&uniform->psRegisterIndex);
1181         stream.readInt(&uniform->vsRegisterIndex);
1182         stream.readInt(&uniform->registerCount);
1183         stream.readInt(&uniform->registerElement);
1184
1185         mUniforms[uniformIndex] = uniform;
1186     }
1187
1188     unsigned int uniformBlockCount = stream.readInt<unsigned int>();
1189     if (stream.error())
1190     {
1191         infoLog.append("Invalid program binary.");
1192         return false;
1193     }
1194
1195     mUniformBlocks.resize(uniformBlockCount);
1196     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
1197     {
1198         std::string name = stream.readString();
1199         unsigned int elementIndex = stream.readInt<unsigned int>();
1200         unsigned int dataSize = stream.readInt<unsigned int>();
1201
1202         UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize);
1203
1204         stream.readInt(&uniformBlock->psRegisterIndex);
1205         stream.readInt(&uniformBlock->vsRegisterIndex);
1206
1207         unsigned int numMembers = stream.readInt<unsigned int>();
1208         uniformBlock->memberUniformIndexes.resize(numMembers);
1209         for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
1210         {
1211             stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
1212         }
1213
1214         mUniformBlocks[uniformBlockIndex] = uniformBlock;
1215     }
1216
1217     const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
1218     if (stream.error())
1219     {
1220         infoLog.append("Invalid program binary.");
1221         return false;
1222     }
1223
1224     mUniformIndex.resize(uniformIndexCount);
1225     for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
1226     {
1227         stream.readString(&mUniformIndex[uniformIndexIndex].name);
1228         stream.readInt(&mUniformIndex[uniformIndexIndex].element);
1229         stream.readInt(&mUniformIndex[uniformIndexIndex].index);
1230     }
1231
1232     stream.readInt(&mTransformFeedbackBufferMode);
1233     const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>();
1234     mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
1235     for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
1236     {
1237         LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
1238
1239         stream.readString(&varying.name);
1240         stream.readInt(&varying.type);
1241         stream.readInt(&varying.size);
1242         stream.readString(&varying.semanticName);
1243         stream.readInt(&varying.semanticIndex);
1244         stream.readInt(&varying.semanticIndexCount);
1245     }
1246
1247     const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
1248     for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
1249     {
1250         VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
1251
1252         for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
1253         {
1254             VertexFormat *vertexInput = &inputLayout[inputIndex];
1255             stream.readInt(&vertexInput->mType);
1256             stream.readInt(&vertexInput->mNormalized);
1257             stream.readInt(&vertexInput->mComponents);
1258             stream.readBool(&vertexInput->mPureInteger);
1259         }
1260
1261         unsigned int vertexShaderSize = stream.readInt<unsigned int>();
1262         const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
1263         rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
1264                                                                            vertexShaderSize, rx::SHADER_VERTEX,
1265                                                                            mTransformFeedbackLinkedVaryings,
1266                                                                            (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
1267         if (!shaderExecutable)
1268         {
1269             infoLog.append("Could not create vertex shader.");
1270             return false;
1271         }
1272
1273         // generated converted input layout
1274         GLenum signature[MAX_VERTEX_ATTRIBS];
1275         mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
1276
1277         // add new binary
1278         mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
1279
1280         stream.skip(vertexShaderSize);
1281     }
1282
1283     const size_t pixelShaderCount = stream.readInt<unsigned int>();
1284     for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
1285     {
1286         const size_t outputCount = stream.readInt<unsigned int>();
1287         std::vector<GLenum> outputs(outputCount);
1288         for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
1289         {
1290             stream.readInt(&outputs[outputIndex]);
1291         }
1292
1293         const size_t pixelShaderSize = stream.readInt<unsigned int>();
1294         const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
1295         rx::Renderer *renderer = mProgram->getRenderer();
1296         rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
1297                                                                           rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
1298                                                                           (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
1299
1300         if (!shaderExecutable)
1301         {
1302             infoLog.append("Could not create pixel shader.");
1303             return false;
1304         }
1305
1306         // add new binary
1307         mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
1308
1309         stream.skip(pixelShaderSize);
1310     }
1311
1312     unsigned int geometryShaderSize = stream.readInt<unsigned int>();
1313
1314     if (geometryShaderSize > 0)
1315     {
1316         const char *geometryShaderFunction = (const char*) binary + stream.offset();
1317         rx::Renderer *renderer = mProgram->getRenderer();
1318         mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
1319                                                        geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
1320                                                        (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
1321
1322         if (!mGeometryExecutable)
1323         {
1324             infoLog.append("Could not create geometry shader.");
1325             return false;
1326         }
1327         stream.skip(geometryShaderSize);
1328     }
1329
1330     if (!mProgram->load(infoLog, &stream))
1331     {
1332         return false;
1333     }
1334
1335     const char *ptr = (const char*) binary + stream.offset();
1336
1337     const GUID *binaryIdentifier = (const GUID *) ptr;
1338     ptr += sizeof(GUID);
1339
1340     GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
1341     if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
1342     {
1343         infoLog.append("Invalid program binary.");
1344         return false;
1345     }
1346
1347     mProgram->initializeUniformStorage(mUniforms);
1348
1349     return true;
1350 #endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
1351 }
1352
1353 bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
1354 {
1355     if (binaryFormat)
1356     {
1357         *binaryFormat = mProgram->getBinaryFormat();
1358     }
1359
1360     BinaryOutputStream stream;
1361
1362     stream.writeInt(mProgram->getBinaryFormat());
1363     stream.writeInt(ANGLE_MAJOR_VERSION);
1364     stream.writeInt(ANGLE_MINOR_VERSION);
1365     stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
1366     stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
1367
1368     for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
1369     {
1370         stream.writeInt(mLinkedAttribute[i].type);
1371         stream.writeString(mLinkedAttribute[i].name);
1372         stream.writeInt(mShaderAttributes[i].type);
1373         stream.writeString(mShaderAttributes[i].name);
1374         stream.writeInt(mSemanticIndex[i]);
1375     }
1376
1377     stream.writeInt(mSamplersPS.size());
1378     for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
1379     {
1380         stream.writeInt(mSamplersPS[i].active);
1381         stream.writeInt(mSamplersPS[i].logicalTextureUnit);
1382         stream.writeInt(mSamplersPS[i].textureType);
1383     }
1384
1385     stream.writeInt(mSamplersVS.size());
1386     for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
1387     {
1388         stream.writeInt(mSamplersVS[i].active);
1389         stream.writeInt(mSamplersVS[i].logicalTextureUnit);
1390         stream.writeInt(mSamplersVS[i].textureType);
1391     }
1392
1393     stream.writeInt(mUsedVertexSamplerRange);
1394     stream.writeInt(mUsedPixelSamplerRange);
1395     stream.writeInt(mUsesPointSize);
1396     stream.writeInt(mShaderVersion);
1397
1398     stream.writeInt(mUniforms.size());
1399     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
1400     {
1401         const LinkedUniform &uniform = *mUniforms[uniformIndex];
1402
1403         stream.writeInt(uniform.type);
1404         stream.writeInt(uniform.precision);
1405         stream.writeString(uniform.name);
1406         stream.writeInt(uniform.arraySize);
1407         stream.writeInt(uniform.blockIndex);
1408
1409         stream.writeInt(uniform.blockInfo.offset);
1410         stream.writeInt(uniform.blockInfo.arrayStride);
1411         stream.writeInt(uniform.blockInfo.matrixStride);
1412         stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
1413
1414         stream.writeInt(uniform.psRegisterIndex);
1415         stream.writeInt(uniform.vsRegisterIndex);
1416         stream.writeInt(uniform.registerCount);
1417         stream.writeInt(uniform.registerElement);
1418     }
1419
1420     stream.writeInt(mUniformBlocks.size());
1421     for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
1422     {
1423         const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
1424
1425         stream.writeString(uniformBlock.name);
1426         stream.writeInt(uniformBlock.elementIndex);
1427         stream.writeInt(uniformBlock.dataSize);
1428
1429         stream.writeInt(uniformBlock.memberUniformIndexes.size());
1430         for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
1431         {
1432             stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
1433         }
1434
1435         stream.writeInt(uniformBlock.psRegisterIndex);
1436         stream.writeInt(uniformBlock.vsRegisterIndex);
1437     }
1438
1439     stream.writeInt(mUniformIndex.size());
1440     for (size_t i = 0; i < mUniformIndex.size(); ++i)
1441     {
1442         stream.writeString(mUniformIndex[i].name);
1443         stream.writeInt(mUniformIndex[i].element);
1444         stream.writeInt(mUniformIndex[i].index);
1445     }
1446
1447     stream.writeInt(mTransformFeedbackBufferMode);
1448     stream.writeInt(mTransformFeedbackLinkedVaryings.size());
1449     for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
1450     {
1451         const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
1452
1453         stream.writeString(varying.name);
1454         stream.writeInt(varying.type);
1455         stream.writeInt(varying.size);
1456         stream.writeString(varying.semanticName);
1457         stream.writeInt(varying.semanticIndex);
1458         stream.writeInt(varying.semanticIndexCount);
1459     }
1460
1461     stream.writeInt(mVertexExecutables.size());
1462     for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
1463     {
1464         VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
1465
1466         for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
1467         {
1468             const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
1469             stream.writeInt(vertexInput.mType);
1470             stream.writeInt(vertexInput.mNormalized);
1471             stream.writeInt(vertexInput.mComponents);
1472             stream.writeInt(vertexInput.mPureInteger);
1473         }
1474
1475         size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
1476         stream.writeInt(vertexShaderSize);
1477
1478         const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
1479         stream.writeBytes(vertexBlob, vertexShaderSize);
1480     }
1481
1482     stream.writeInt(mPixelExecutables.size());
1483     for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
1484     {
1485         PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
1486
1487         const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
1488         stream.writeInt(outputs.size());
1489         for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
1490         {
1491             stream.writeInt(outputs[outputIndex]);
1492         }
1493
1494         size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
1495         stream.writeInt(pixelShaderSize);
1496
1497         const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
1498         stream.writeBytes(pixelBlob, pixelShaderSize);
1499     }
1500
1501     size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
1502     stream.writeInt(geometryShaderSize);
1503
1504     if (mGeometryExecutable != NULL && geometryShaderSize > 0)
1505     {
1506         const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
1507         stream.writeBytes(geometryBlob, geometryShaderSize);
1508     }
1509
1510     if (!mProgram->save(&stream))
1511     {
1512         if (length)
1513         {
1514             *length = 0;
1515         }
1516
1517         return false;
1518     }
1519
1520     GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
1521
1522     GLsizei streamLength = stream.length();
1523     const void *streamData = stream.data();
1524
1525     GLsizei totalLength = streamLength + sizeof(GUID);
1526     if (totalLength > bufSize)
1527     {
1528         if (length)
1529         {
1530             *length = 0;
1531         }
1532
1533         return false;
1534     }
1535
1536     if (binary)
1537     {
1538         char *ptr = (char*) binary;
1539
1540         memcpy(ptr, streamData, streamLength);
1541         ptr += streamLength;
1542
1543         memcpy(ptr, &identifier, sizeof(GUID));
1544         ptr += sizeof(GUID);
1545
1546         ASSERT(ptr - totalLength == binary);
1547     }
1548
1549     if (length)
1550     {
1551         *length = totalLength;
1552     }
1553
1554     return true;
1555 }
1556
1557 GLint ProgramBinary::getLength()
1558 {
1559     GLint length;
1560     if (save(NULL, NULL, INT_MAX, &length))
1561     {
1562         return length;
1563     }
1564     else
1565     {
1566         return 0;
1567     }
1568 }
1569
1570 bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
1571                          const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
1572 {
1573     if (!fragmentShader || !fragmentShader->isCompiled())
1574     {
1575         return false;
1576     }
1577     ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
1578
1579     if (!vertexShader || !vertexShader->isCompiled())
1580     {
1581         return false;
1582     }
1583     ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
1584
1585     reset();
1586
1587     mSamplersPS.resize(caps.maxTextureImageUnits);
1588     mSamplersVS.resize(caps.maxVertexTextureImageUnits);
1589
1590     mTransformFeedbackBufferMode = transformFeedbackBufferMode;
1591
1592     rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
1593     rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
1594
1595     mShaderVersion = vertexShaderD3D->getShaderVersion();
1596
1597     int registers;
1598     std::vector<LinkedVarying> linkedVaryings;
1599     if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables))
1600     {
1601         return false;
1602     }
1603
1604     mUsesPointSize = vertexShaderD3D->usesPointSize();
1605
1606     bool success = true;
1607
1608     if (!linkAttributes(infoLog, attributeBindings, vertexShader))
1609     {
1610         success = false;
1611     }
1612
1613     if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
1614     {
1615         success = false;
1616     }
1617
1618     // special case for gl_DepthRange, the only built-in uniform (also a struct)
1619     if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
1620     {
1621         const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
1622
1623         mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
1624         mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
1625         mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
1626     }
1627
1628     if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
1629     {
1630         success = false;
1631     }
1632
1633     if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
1634                                                transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
1635     {
1636         success = false;
1637     }
1638
1639     if (success)
1640     {
1641         VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
1642         GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
1643         rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
1644
1645         std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
1646         rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
1647
1648         if (usesGeometryShader())
1649         {
1650             std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
1651             mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(),
1652                                                                                rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
1653                                                                                (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
1654                                                                                rx::ANGLE_D3D_WORKAROUND_NONE);
1655         }
1656
1657         if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
1658         {
1659             infoLog.append("Failed to create D3D shaders.");
1660             success = false;
1661             reset();
1662         }
1663     }
1664
1665     return success;
1666 }
1667
1668 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
1669 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
1670 {
1671     const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
1672
1673     unsigned int usedLocations = 0;
1674     const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
1675
1676     // Link attributes that have a binding location
1677     for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
1678     {
1679         const sh::Attribute &attribute = shaderAttributes[attributeIndex];
1680
1681         ASSERT(attribute.staticUse);
1682
1683         const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
1684
1685         mShaderAttributes[attributeIndex] = attribute;
1686
1687         if (location != -1)   // Set by glBindAttribLocation or by location layout qualifier
1688         {
1689             const int rows = VariableRegisterCount(attribute.type);
1690
1691             if (rows + location > MAX_VERTEX_ATTRIBS)
1692             {
1693                 infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
1694
1695                 return false;
1696             }
1697
1698             for (int row = 0; row < rows; row++)
1699             {
1700                 const int rowLocation = location + row;
1701                 sh::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation];
1702
1703                 // In GLSL 3.00, attribute aliasing produces a link error
1704                 // In GLSL 1.00, attribute aliasing is allowed
1705                 if (mShaderVersion >= 300)
1706                 {
1707                     if (!linkedAttribute.name.empty())
1708                     {
1709                         infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation);
1710                         return false;
1711                     }
1712                 }
1713
1714                 linkedAttribute = attribute;
1715                 usedLocations |= 1 << rowLocation;
1716             }
1717         }
1718     }
1719
1720     // Link attributes that don't have a binding location
1721     for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
1722     {
1723         const sh::Attribute &attribute = shaderAttributes[attributeIndex];
1724
1725         ASSERT(attribute.staticUse);
1726
1727         const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
1728
1729         if (location == -1)   // Not set by glBindAttribLocation or by location layout qualifier
1730         {
1731             int rows = VariableRegisterCount(attribute.type);
1732             int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
1733
1734             if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
1735             {
1736                 infoLog.append("Too many active attributes (%s)", attribute.name.c_str());
1737
1738                 return false;   // Fail to link
1739             }
1740
1741             mLinkedAttribute[availableIndex] = attribute;
1742         }
1743     }
1744
1745     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
1746     {
1747         int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
1748         int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
1749
1750         for (int r = 0; r < rows; r++)
1751         {
1752             mSemanticIndex[attributeIndex++] = index++;
1753         }
1754     }
1755
1756     initAttributesByLayout();
1757
1758     return true;
1759 }
1760
1761 bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
1762                                               const sh::ShaderVariable &fragmentVariable, bool validatePrecision)
1763 {
1764     if (vertexVariable.type != fragmentVariable.type)
1765     {
1766         infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str());
1767         return false;
1768     }
1769     if (vertexVariable.arraySize != fragmentVariable.arraySize)
1770     {
1771         infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str());
1772         return false;
1773     }
1774     if (validatePrecision && vertexVariable.precision != fragmentVariable.precision)
1775     {
1776         infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str());
1777         return false;
1778     }
1779
1780     if (vertexVariable.fields.size() != fragmentVariable.fields.size())
1781     {
1782         infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str());
1783         return false;
1784     }
1785     const unsigned int numMembers = vertexVariable.fields.size();
1786     for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
1787     {
1788         const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex];
1789         const sh::ShaderVariable &fragmentMember = fragmentVariable.fields[memberIndex];
1790
1791         if (vertexMember.name != fragmentMember.name)
1792         {
1793             infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')",
1794                            memberIndex, variableName.c_str(),
1795                            vertexMember.name.c_str(), fragmentMember.name.c_str());
1796             return false;
1797         }
1798
1799         const std::string memberName = variableName.substr(0, variableName.length() - 1) + "." +
1800                                        vertexMember.name + "'";
1801
1802         if (!linkValidateVariablesBase(infoLog, vertexMember.name, vertexMember, fragmentMember, validatePrecision))
1803         {
1804             return false;
1805         }
1806     }
1807
1808     return true;
1809 }
1810
1811 bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
1812 {
1813     if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
1814     {
1815         return false;
1816     }
1817
1818     return true;
1819 }
1820
1821 bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
1822 {
1823     if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
1824     {
1825         return false;
1826     }
1827
1828     if (vertexVarying.interpolation != fragmentVarying.interpolation)
1829     {
1830         infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str());
1831         return false;
1832     }
1833
1834     return true;
1835 }
1836
1837 bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
1838 {
1839     if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
1840     {
1841         return false;
1842     }
1843
1844     if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
1845     {
1846         infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
1847         return false;
1848     }
1849
1850     return true;
1851 }
1852
1853 bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
1854 {
1855     const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
1856     const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
1857
1858     const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
1859     const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
1860
1861     // Check that uniforms defined in the vertex and fragment shaders are identical
1862     typedef std::map<std::string, const sh::Uniform*> UniformMap;
1863     UniformMap linkedUniforms;
1864
1865     for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
1866     {
1867         const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
1868         linkedUniforms[vertexUniform.name] = &vertexUniform;
1869     }
1870
1871     for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
1872     {
1873         const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
1874         UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
1875         if (entry != linkedUniforms.end())
1876         {
1877             const sh::Uniform &vertexUniform = *entry->second;
1878             const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
1879             if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
1880             {
1881                 return false;
1882             }
1883         }
1884     }
1885
1886     for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
1887     {
1888         const sh::Uniform &uniform = vertexUniforms[uniformIndex];
1889
1890         if (uniform.staticUse)
1891         {
1892             defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
1893         }
1894     }
1895
1896     for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
1897     {
1898         const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
1899
1900         if (uniform.staticUse)
1901         {
1902             defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
1903         }
1904     }
1905
1906     if (!indexUniforms(infoLog, caps))
1907     {
1908         return false;
1909     }
1910
1911     mProgram->initializeUniformStorage(mUniforms);
1912
1913     return true;
1914 }
1915
1916 void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
1917 {
1918     ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
1919     sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
1920     encoder.skipRegisters(uniformRegister);
1921
1922     defineUniform(shader, uniform, uniform.name, &encoder);
1923 }
1924
1925 void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
1926                                   const std::string &fullName, sh::HLSLBlockEncoder *encoder)
1927 {
1928     if (uniform.isStruct())
1929     {
1930         for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
1931         {
1932             const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
1933
1934             encoder->enterAggregateType();
1935
1936             for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
1937             {
1938                 const sh::ShaderVariable &field = uniform.fields[fieldIndex];
1939                 const std::string &fieldFullName = (fullName + elementString + "." + field.name);
1940
1941                 defineUniform(shader, field, fieldFullName, encoder);
1942             }
1943
1944             encoder->exitAggregateType();
1945         }
1946     }
1947     else // Not a struct
1948     {
1949         // Arrays are treated as aggregate types
1950         if (uniform.isArray())
1951         {
1952             encoder->enterAggregateType();
1953         }
1954
1955         LinkedUniform *linkedUniform = getUniformByName(fullName);
1956
1957         if (!linkedUniform)
1958         {
1959             linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
1960                                               -1, sh::BlockMemberInfo::getDefaultBlockInfo());
1961             ASSERT(linkedUniform);
1962             linkedUniform->registerElement = encoder->getCurrentElement();
1963             mUniforms.push_back(linkedUniform);
1964         }
1965
1966         ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
1967
1968         if (shader == GL_FRAGMENT_SHADER)
1969         {
1970             linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
1971         }
1972         else if (shader == GL_VERTEX_SHADER)
1973         {
1974             linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
1975         }
1976         else UNREACHABLE();
1977
1978         // Advance the uniform offset, to track registers allocation for structs
1979         encoder->encodeType(uniform.type, uniform.arraySize, false);
1980
1981         // Arrays are treated as aggregate types
1982         if (uniform.isArray())
1983         {
1984             encoder->exitAggregateType();
1985         }
1986     }
1987 }
1988
1989 bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
1990 {
1991     ASSERT(IsSampler(uniform.type));
1992     ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
1993
1994     if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
1995     {
1996         if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
1997                             &mUsedVertexSamplerRange))
1998         {
1999             infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
2000                            mSamplersVS.size());
2001             return false;
2002         }
2003
2004         unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
2005         if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
2006         {
2007             infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
2008                            caps.maxVertexUniformVectors);
2009             return false;
2010         }
2011     }
2012
2013     if (uniform.psRegisterIndex != GL_INVALID_INDEX)
2014     {
2015         if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
2016                             &mUsedPixelSamplerRange))
2017         {
2018             infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
2019                            mSamplersPS.size());
2020             return false;
2021         }
2022
2023         unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
2024         if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
2025         {
2026             infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
2027                            caps.maxFragmentUniformVectors);
2028             return false;
2029         }
2030     }
2031
2032     return true;
2033 }
2034
2035 bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
2036 {
2037     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
2038     {
2039         const LinkedUniform &uniform = *mUniforms[uniformIndex];
2040
2041         if (IsSampler(uniform.type))
2042         {
2043             if (!indexSamplerUniform(uniform, infoLog, caps))
2044             {
2045                 return false;
2046             }
2047         }
2048
2049         for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
2050         {
2051             mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
2052         }
2053     }
2054
2055     return true;
2056 }
2057
2058 bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
2059                                    GLenum samplerType,
2060                                    unsigned int samplerCount,
2061                                    std::vector<Sampler> &outSamplers,
2062                                    GLuint *outUsedRange)
2063 {
2064     unsigned int samplerIndex = startSamplerIndex;
2065
2066     do
2067     {
2068         if (samplerIndex < outSamplers.size())
2069         {
2070             Sampler& sampler = outSamplers[samplerIndex];
2071             sampler.active = true;
2072             sampler.textureType = GetTextureType(samplerType);
2073             sampler.logicalTextureUnit = 0;
2074             *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
2075         }
2076         else
2077         {
2078             return false;
2079         }
2080
2081         samplerIndex++;
2082     } while (samplerIndex < startSamplerIndex + samplerCount);
2083
2084     return true;
2085 }
2086
2087 bool ProgramBinary::areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock)
2088 {
2089     const char* blockName = vertexInterfaceBlock.name.c_str();
2090
2091     // validate blocks for the same member types
2092     if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
2093     {
2094         infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
2095         return false;
2096     }
2097
2098     if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
2099     {
2100         infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
2101         return false;
2102     }
2103
2104     if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
2105     {
2106         infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
2107         return false;
2108     }
2109
2110     const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
2111     for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
2112     {
2113         const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
2114         const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
2115
2116         if (vertexMember.name != fragmentMember.name)
2117         {
2118             infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
2119                            blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
2120             return false;
2121         }
2122
2123         std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
2124         if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
2125         {
2126             return false;
2127         }
2128     }
2129
2130     return true;
2131 }
2132
2133 bool ProgramBinary::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
2134 {
2135     const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
2136     const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
2137
2138     // Check that interface blocks defined in the vertex and fragment shaders are identical
2139     typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
2140     UniformBlockMap linkedUniformBlocks;
2141
2142     for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
2143     {
2144         const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
2145         linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
2146     }
2147
2148     for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
2149     {
2150         const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
2151         UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
2152         if (entry != linkedUniformBlocks.end())
2153         {
2154             const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
2155             if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
2156             {
2157                 return false;
2158             }
2159         }
2160     }
2161
2162     for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
2163     {
2164         const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
2165
2166         // Note: shared and std140 layouts are always considered active
2167         if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
2168         {
2169             if (!defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
2170             {
2171                 return false;
2172             }
2173         }
2174     }
2175
2176     for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
2177     {
2178         const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
2179
2180         // Note: shared and std140 layouts are always considered active
2181         if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
2182         {
2183             if (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
2184             {
2185                 return false;
2186             }
2187         }
2188     }
2189
2190     return true;
2191 }
2192
2193 bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
2194                                                           const std::vector<std::string> &transformFeedbackVaryingNames,
2195                                                           GLenum transformFeedbackBufferMode,
2196                                                           std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
2197                                                           const Caps &caps) const
2198 {
2199     size_t totalComponents = 0;
2200
2201     // Gather the linked varyings that are used for transform feedback, they should all exist.
2202     outTransformFeedbackLinkedVaryings->clear();
2203     for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++)
2204     {
2205         bool found = false;
2206         for (size_t j = 0; j < linkedVaryings.size(); j++)
2207         {
2208             if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name)
2209             {
2210                 for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++)
2211                 {
2212                     if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name)
2213                     {
2214                         infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str());
2215                         return false;
2216                     }
2217                 }
2218
2219                 size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
2220                 if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
2221                     componentCount > caps.maxTransformFeedbackSeparateComponents)
2222                 {
2223                     infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).",
2224                                    linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents);
2225                     return false;
2226                 }
2227
2228                 totalComponents += componentCount;
2229
2230                 outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]);
2231                 found = true;
2232                 break;
2233             }
2234         }
2235
2236         // All transform feedback varyings are expected to exist since packVaryings checks for them.
2237         ASSERT(found);
2238     }
2239
2240     if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents)
2241     {
2242         infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).",
2243                        totalComponents, caps.maxTransformFeedbackInterleavedComponents);
2244         return false;
2245     }
2246
2247     return true;
2248 }
2249
2250 template <typename VarT>
2251 void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
2252                                               sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
2253                                               bool inRowMajorLayout)
2254 {
2255     for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
2256     {
2257         const VarT &field = fields[uniformIndex];
2258         const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
2259
2260         if (field.isStruct())
2261         {
2262             bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
2263
2264             for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
2265             {
2266                 encoder->enterAggregateType();
2267
2268                 const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
2269                 defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
2270
2271                 encoder->exitAggregateType();
2272             }
2273         }
2274         else
2275         {
2276             bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout);
2277
2278             sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
2279
2280             LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
2281                                                           blockIndex, memberInfo);
2282
2283             // add to uniform list, but not index, since uniform block uniforms have no location
2284             blockUniformIndexes->push_back(mUniforms.size());
2285             mUniforms.push_back(newUniform);
2286         }
2287     }
2288 }
2289
2290 bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps)
2291 {
2292     const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation());
2293
2294     // create uniform block entries if they do not exist
2295     if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
2296     {
2297         std::vector<unsigned int> blockUniformIndexes;
2298         const unsigned int blockIndex = mUniformBlocks.size();
2299
2300         // define member uniforms
2301         sh::BlockLayoutEncoder *encoder = NULL;
2302
2303         if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
2304         {
2305             encoder = new sh::Std140BlockEncoder;
2306         }
2307         else
2308         {
2309             encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
2310         }
2311         ASSERT(encoder);
2312
2313         defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
2314
2315         size_t dataSize = encoder->getBlockSize();
2316
2317         // create all the uniform blocks
2318         if (interfaceBlock.arraySize > 0)
2319         {
2320             for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
2321             {
2322                 UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
2323                 newUniformBlock->memberUniformIndexes = blockUniformIndexes;
2324                 mUniformBlocks.push_back(newUniformBlock);
2325             }
2326         }
2327         else
2328         {
2329             UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
2330             newUniformBlock->memberUniformIndexes = blockUniformIndexes;
2331             mUniformBlocks.push_back(newUniformBlock);
2332         }
2333     }
2334
2335     if (interfaceBlock.staticUse)
2336     {
2337         // Assign registers to the uniform blocks
2338         const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
2339         const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
2340         ASSERT(blockIndex != GL_INVALID_INDEX);
2341         ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
2342
2343         unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
2344
2345         for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
2346         {
2347             UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
2348             ASSERT(uniformBlock->name == interfaceBlock.name);
2349
2350             if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
2351                                             interfaceBlockRegister + uniformBlockElement, caps))
2352             {
2353                 return false;
2354             }
2355         }
2356     }
2357
2358     return true;
2359 }
2360
2361 bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps)
2362 {
2363     if (shader == GL_VERTEX_SHADER)
2364     {
2365         uniformBlock->vsRegisterIndex = registerIndex;
2366         if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
2367         {
2368             infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
2369             return false;
2370         }
2371     }
2372     else if (shader == GL_FRAGMENT_SHADER)
2373     {
2374         uniformBlock->psRegisterIndex = registerIndex;
2375         if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
2376         {
2377             infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
2378             return false;
2379         }
2380     }
2381     else UNREACHABLE();
2382
2383     return true;
2384 }
2385
2386 bool ProgramBinary::isValidated() const
2387 {
2388     return mValidated;
2389 }
2390
2391 void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2392 {
2393     // Skip over inactive attributes
2394     unsigned int activeAttribute = 0;
2395     unsigned int attribute;
2396     for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2397     {
2398         if (mLinkedAttribute[attribute].name.empty())
2399         {
2400             continue;
2401         }
2402
2403         if (activeAttribute == index)
2404         {
2405             break;
2406         }
2407
2408         activeAttribute++;
2409     }
2410
2411     if (bufsize > 0)
2412     {
2413         const char *string = mLinkedAttribute[attribute].name.c_str();
2414
2415         strncpy(name, string, bufsize);
2416         name[bufsize - 1] = '\0';
2417
2418         if (length)
2419         {
2420             *length = strlen(name);
2421         }
2422     }
2423
2424     *size = 1;   // Always a single 'type' instance
2425
2426     *type = mLinkedAttribute[attribute].type;
2427 }
2428
2429 GLint ProgramBinary::getActiveAttributeCount() const
2430 {
2431     int count = 0;
2432
2433     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2434     {
2435         if (!mLinkedAttribute[attributeIndex].name.empty())
2436         {
2437             count++;
2438         }
2439     }
2440
2441     return count;
2442 }
2443
2444 GLint ProgramBinary::getActiveAttributeMaxLength() const
2445 {
2446     int maxLength = 0;
2447
2448     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2449     {
2450         if (!mLinkedAttribute[attributeIndex].name.empty())
2451         {
2452             maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
2453         }
2454     }
2455
2456     return maxLength;
2457 }
2458
2459 void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2460 {
2461     ASSERT(index < mUniforms.size());   // index must be smaller than getActiveUniformCount()
2462
2463     if (bufsize > 0)
2464     {
2465         std::string string = mUniforms[index]->name;
2466
2467         if (mUniforms[index]->isArray())
2468         {
2469             string += "[0]";
2470         }
2471
2472         strncpy(name, string.c_str(), bufsize);
2473         name[bufsize - 1] = '\0';
2474
2475         if (length)
2476         {
2477             *length = strlen(name);
2478         }
2479     }
2480
2481     *size = mUniforms[index]->elementCount();
2482
2483     *type = mUniforms[index]->type;
2484 }
2485
2486 GLint ProgramBinary::getActiveUniformCount() const
2487 {
2488     return mUniforms.size();
2489 }
2490
2491 GLint ProgramBinary::getActiveUniformMaxLength() const
2492 {
2493     int maxLength = 0;
2494
2495     unsigned int numUniforms = mUniforms.size();
2496     for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
2497     {
2498         if (!mUniforms[uniformIndex]->name.empty())
2499         {
2500             int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
2501             if (mUniforms[uniformIndex]->isArray())
2502             {
2503                 length += 3;  // Counting in "[0]".
2504             }
2505             maxLength = std::max(length, maxLength);
2506         }
2507     }
2508
2509     return maxLength;
2510 }
2511
2512 GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
2513 {
2514     const gl::LinkedUniform& uniform = *mUniforms[index];
2515
2516     switch (pname)
2517     {
2518       case GL_UNIFORM_TYPE:         return static_cast<GLint>(uniform.type);
2519       case GL_UNIFORM_SIZE:         return static_cast<GLint>(uniform.elementCount());
2520       case GL_UNIFORM_NAME_LENGTH:  return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
2521       case GL_UNIFORM_BLOCK_INDEX:  return uniform.blockIndex;
2522
2523       case GL_UNIFORM_OFFSET:       return uniform.blockInfo.offset;
2524       case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
2525       case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
2526       case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
2527
2528       default:
2529         UNREACHABLE();
2530         break;
2531     }
2532     return 0;
2533 }
2534
2535 bool ProgramBinary::isValidUniformLocation(GLint location) const
2536 {
2537     ASSERT(rx::IsIntegerCastSafe<GLint>(mUniformIndex.size()));
2538     return (location >= 0 && location < static_cast<GLint>(mUniformIndex.size()));
2539 }
2540
2541 LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const
2542 {
2543     ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
2544     return mUniforms[mUniformIndex[location].index];
2545 }
2546
2547 LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const
2548 {
2549     for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
2550     {
2551         if (mUniforms[uniformIndex]->name == name)
2552         {
2553             return mUniforms[uniformIndex];
2554         }
2555     }
2556
2557     return NULL;
2558 }
2559
2560 void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
2561 {
2562     ASSERT(uniformBlockIndex < mUniformBlocks.size());   // index must be smaller than getActiveUniformBlockCount()
2563
2564     const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
2565
2566     if (bufSize > 0)
2567     {
2568         std::string string = uniformBlock.name;
2569
2570         if (uniformBlock.isArrayElement())
2571         {
2572             string += ArrayString(uniformBlock.elementIndex);
2573         }
2574
2575         strncpy(uniformBlockName, string.c_str(), bufSize);
2576         uniformBlockName[bufSize - 1] = '\0';
2577
2578         if (length)
2579         {
2580             *length = strlen(uniformBlockName);
2581         }
2582     }
2583 }
2584
2585 void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
2586 {
2587     ASSERT(uniformBlockIndex < mUniformBlocks.size());   // index must be smaller than getActiveUniformBlockCount()
2588
2589     const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
2590
2591     switch (pname)
2592     {
2593       case GL_UNIFORM_BLOCK_DATA_SIZE:
2594         *params = static_cast<GLint>(uniformBlock.dataSize);
2595         break;
2596       case GL_UNIFORM_BLOCK_NAME_LENGTH:
2597         *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
2598         break;
2599       case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
2600         *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
2601         break;
2602       case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
2603         {
2604             for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
2605             {
2606                 params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
2607             }
2608         }
2609         break;
2610       case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
2611         *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
2612         break;
2613       case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
2614         *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
2615         break;
2616       default: UNREACHABLE();
2617     }
2618 }
2619
2620 GLuint ProgramBinary::getActiveUniformBlockCount() const
2621 {
2622     return mUniformBlocks.size();
2623 }
2624
2625 GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
2626 {
2627     unsigned int maxLength = 0;
2628
2629     unsigned int numUniformBlocks = mUniformBlocks.size();
2630     for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
2631     {
2632         const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
2633         if (!uniformBlock.name.empty())
2634         {
2635             const unsigned int length = uniformBlock.name.length() + 1;
2636
2637             // Counting in "[0]".
2638             const unsigned int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
2639
2640             maxLength = std::max(length + arrayLength, maxLength);
2641         }
2642     }
2643
2644     return maxLength;
2645 }
2646
2647 void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
2648 {
2649     applyUniforms();
2650     if (!validateSamplers(&infoLog, caps))
2651     {
2652         mValidated = false;
2653     }
2654     else
2655     {
2656         mValidated = true;
2657     }
2658 }
2659
2660 bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
2661 {
2662     // if any two active samplers in a program are of different types, but refer to the same
2663     // texture image unit, and this is the current program, then ValidateProgram will fail, and
2664     // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
2665     updateSamplerMapping();
2666
2667     std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
2668
2669     for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
2670     {
2671         if (mSamplersPS[i].active)
2672         {
2673             unsigned int unit = mSamplersPS[i].logicalTextureUnit;
2674
2675             if (unit >= textureUnitTypes.size())
2676             {
2677                 if (infoLog)
2678                 {
2679                     infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
2680                 }
2681
2682                 return false;
2683             }
2684
2685             if (textureUnitTypes[unit] != GL_NONE)
2686             {
2687                 if (mSamplersPS[i].textureType != textureUnitTypes[unit])
2688                 {
2689                     if (infoLog)
2690                     {
2691                         infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2692                     }
2693
2694                     return false;
2695                 }
2696             }
2697             else
2698             {
2699                 textureUnitTypes[unit] = mSamplersPS[i].textureType;
2700             }
2701         }
2702     }
2703
2704     for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
2705     {
2706         if (mSamplersVS[i].active)
2707         {
2708             unsigned int unit = mSamplersVS[i].logicalTextureUnit;
2709
2710             if (unit >= textureUnitTypes.size())
2711             {
2712                 if (infoLog)
2713                 {
2714                     infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
2715                 }
2716
2717                 return false;
2718             }
2719
2720             if (textureUnitTypes[unit] != GL_NONE)
2721             {
2722                 if (mSamplersVS[i].textureType != textureUnitTypes[unit])
2723                 {
2724                     if (infoLog)
2725                     {
2726                         infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2727                     }
2728
2729                     return false;
2730                 }
2731             }
2732             else
2733             {
2734                 textureUnitTypes[unit] = mSamplersVS[i].textureType;
2735             }
2736         }
2737     }
2738
2739     return true;
2740 }
2741
2742 ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
2743 {
2744 }
2745
2746 struct AttributeSorter
2747 {
2748     AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
2749         : originalIndices(semanticIndices)
2750     {
2751     }
2752
2753     bool operator()(int a, int b)
2754     {
2755         if (originalIndices[a] == -1) return false;
2756         if (originalIndices[b] == -1) return true;
2757         return (originalIndices[a] < originalIndices[b]);
2758     }
2759
2760     const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
2761 };
2762
2763 void ProgramBinary::initAttributesByLayout()
2764 {
2765     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2766     {
2767         mAttributesByLayout[i] = i;
2768     }
2769
2770     std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
2771 }
2772
2773 void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
2774 {
2775     rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
2776
2777     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2778     {
2779         oldTranslatedAttributes[i] = attributes[i];
2780     }
2781
2782     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2783     {
2784         int oldIndex = mAttributesByLayout[i];
2785         sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
2786         attributes[i] = oldTranslatedAttributes[oldIndex];
2787     }
2788 }
2789
2790 void ProgramBinary::reset()
2791 {
2792     SafeDeleteContainer(mVertexExecutables);
2793     SafeDeleteContainer(mPixelExecutables);
2794
2795     SafeDelete(mGeometryExecutable);
2796
2797     mTransformFeedbackBufferMode = GL_NONE;
2798     mTransformFeedbackLinkedVaryings.clear();
2799
2800     mSamplersPS.clear();
2801     mSamplersVS.clear();
2802
2803     mUsedVertexSamplerRange = 0;
2804     mUsedPixelSamplerRange = 0;
2805     mUsesPointSize = false;
2806     mShaderVersion = 0;
2807     mDirtySamplerMapping = true;
2808
2809     SafeDeleteContainer(mUniforms);
2810     SafeDeleteContainer(mUniformBlocks);
2811     mUniformIndex.clear();
2812     mOutputVariables.clear();
2813
2814     mProgram->reset();
2815
2816     mValidated = false;
2817 }
2818
2819 }