Upstream version 7.35.139.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / ProgramBinary.cpp
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7
8 // Program.cpp: Implements the gl::Program class. Implements GL program objects
9 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
10
11 #include "libGLESv2/BinaryStream.h"
12 #include "libGLESv2/ProgramBinary.h"
13 #include "libGLESv2/renderer/ShaderExecutable.h"
14
15 #include "common/debug.h"
16 #include "common/version.h"
17 #include "utilities.h"
18
19 #include "libGLESv2/main.h"
20 #include "libGLESv2/Shader.h"
21 #include "libGLESv2/Program.h"
22 #include "libGLESv2/renderer/Renderer.h"
23 #include "libGLESv2/renderer/VertexDataManager.h"
24
25 #undef near
26 #undef far
27
28 namespace gl
29 {
30 std::string str(int i)
31 {
32     char buffer[20];
33     snprintf(buffer, sizeof(buffer), "%d", i);
34     return buffer;
35 }
36
37 static rx::D3DWorkaroundType DiscardWorkaround(bool usesDiscard, bool nestedBreak)
38 {
39     if (usesDiscard)
40     {
41         // ANGLE issue 486:
42         // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
43         return rx::ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
44     }
45
46     if (nestedBreak)
47     {
48         // ANGLE issue 603:
49         // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop, by maximizing optimization
50         // We want to keep the use of ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes precedence
51         return rx::ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
52     }
53
54     return rx::ANGLE_D3D_WORKAROUND_NONE;
55 }
56
57 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index)
58     : name(name), element(element), index(index)
59 {
60 }
61
62 unsigned int ProgramBinary::mCurrentSerial = 1;
63
64 ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefCountObject(0), mSerial(issueSerial())
65 {
66     mPixelExecutable = NULL;
67     mVertexExecutable = NULL;
68     mGeometryExecutable = NULL;
69
70     mValidated = false;
71
72     for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
73     {
74         mSemanticIndex[index] = -1;
75     }
76
77     for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
78     {
79         mSamplersPS[index].active = false;
80     }
81
82     for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
83     {
84         mSamplersVS[index].active = false;
85     }
86
87     mUsedVertexSamplerRange = 0;
88     mUsedPixelSamplerRange = 0;
89     mUsesPointSize = false;
90 }
91
92 ProgramBinary::~ProgramBinary()
93 {
94     delete mPixelExecutable;
95     mPixelExecutable = NULL;
96
97     delete mVertexExecutable;
98     mVertexExecutable = NULL;
99
100     delete mGeometryExecutable;
101     mGeometryExecutable = NULL;
102
103     while (!mUniforms.empty())
104     {
105         delete mUniforms.back();
106         mUniforms.pop_back();
107     }
108 }
109
110 unsigned int ProgramBinary::getSerial() const
111 {
112     return mSerial;
113 }
114
115 unsigned int ProgramBinary::issueSerial()
116 {
117     return mCurrentSerial++;
118 }
119
120 rx::ShaderExecutable *ProgramBinary::getPixelExecutable()
121 {
122     return mPixelExecutable;
123 }
124
125 rx::ShaderExecutable *ProgramBinary::getVertexExecutable()
126 {
127     return mVertexExecutable;
128 }
129
130 rx::ShaderExecutable *ProgramBinary::getGeometryExecutable()
131 {
132     return mGeometryExecutable;
133 }
134
135 GLuint ProgramBinary::getAttributeLocation(const char *name)
136 {
137     if (name)
138     {
139         for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
140         {
141             if (mLinkedAttribute[index].name == std::string(name))
142             {
143                 return index;
144             }
145         }
146     }
147
148     return -1;
149 }
150
151 int ProgramBinary::getSemanticIndex(int attributeIndex)
152 {
153     ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
154     
155     return mSemanticIndex[attributeIndex];
156 }
157
158 // Returns one more than the highest sampler index used.
159 GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
160 {
161     switch (type)
162     {
163       case SAMPLER_PIXEL:
164         return mUsedPixelSamplerRange;
165       case SAMPLER_VERTEX:
166         return mUsedVertexSamplerRange;
167       default:
168         UNREACHABLE();
169         return 0;
170     }
171 }
172
173 bool ProgramBinary::usesPointSize() const
174 {
175     return mUsesPointSize;
176 }
177
178 bool ProgramBinary::usesPointSpriteEmulation() const
179 {
180     return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
181 }
182
183 bool ProgramBinary::usesGeometryShader() const
184 {
185     return usesPointSpriteEmulation();
186 }
187
188 // Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
189 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
190 GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
191 {
192     GLint logicalTextureUnit = -1;
193
194     switch (type)
195     {
196       case SAMPLER_PIXEL:
197         ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
198
199         if (mSamplersPS[samplerIndex].active)
200         {
201             logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
202         }
203         break;
204       case SAMPLER_VERTEX:
205         ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
206
207         if (mSamplersVS[samplerIndex].active)
208         {
209             logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
210         }
211         break;
212       default: UNREACHABLE();
213     }
214
215     if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
216     {
217         return logicalTextureUnit;
218     }
219
220     return -1;
221 }
222
223 // Returns the texture type for a given Direct3D 9 sampler type and
224 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
225 TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
226 {
227     switch (type)
228     {
229       case SAMPLER_PIXEL:
230         ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
231         ASSERT(mSamplersPS[samplerIndex].active);
232         return mSamplersPS[samplerIndex].textureType;
233       case SAMPLER_VERTEX:
234         ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
235         ASSERT(mSamplersVS[samplerIndex].active);
236         return mSamplersVS[samplerIndex].textureType;
237       default: UNREACHABLE();
238     }
239
240     return TEXTURE_2D;
241 }
242
243 GLint ProgramBinary::getUniformLocation(std::string name)
244 {
245     unsigned int subscript = 0;
246
247     // Strip any trailing array operator and retrieve the subscript
248     size_t open = name.find_last_of('[');
249     size_t close = name.find_last_of(']');
250     if (open != std::string::npos && close == name.length() - 1)
251     {
252         subscript = atoi(name.substr(open + 1).c_str());
253         name.erase(open);
254     }
255
256     unsigned int numUniforms = mUniformIndex.size();
257     for (unsigned int location = 0; location < numUniforms; location++)
258     {
259         if (mUniformIndex[location].name == name &&
260             mUniformIndex[location].element == subscript)
261         {
262             return location;
263         }
264     }
265
266     return -1;
267 }
268
269 bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
270 {
271     if (location < 0 || location >= (int)mUniformIndex.size())
272     {
273         return false;
274     }
275
276     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
277     targetUniform->dirty = true;
278
279     int elementCount = targetUniform->elementCount();
280
281     if (elementCount == 1 && count > 1)
282         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
283
284     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
285
286     if (targetUniform->type == GL_FLOAT)
287     {
288         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
289
290         for (int i = 0; i < count; i++)
291         {
292             target[0] = v[0];
293             target[1] = 0;
294             target[2] = 0;
295             target[3] = 0;
296             target += 4;
297             v += 1;
298         }
299     }
300     else if (targetUniform->type == GL_BOOL)
301     {
302         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
303
304         for (int i = 0; i < count; i++)
305         {
306             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
307             boolParams[1] = GL_FALSE;
308             boolParams[2] = GL_FALSE;
309             boolParams[3] = GL_FALSE;
310             boolParams += 4;
311             v += 1;
312         }
313     }
314     else
315     {
316         return false;
317     }
318
319     return true;
320 }
321
322 bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
323 {
324     if (location < 0 || location >= (int)mUniformIndex.size())
325     {
326         return false;
327     }
328
329     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
330     targetUniform->dirty = true;
331
332     int elementCount = targetUniform->elementCount();
333
334     if (elementCount == 1 && count > 1)
335         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
336
337     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
338
339     if (targetUniform->type == GL_FLOAT_VEC2)
340     {
341         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
342
343         for (int i = 0; i < count; i++)
344         {
345             target[0] = v[0];
346             target[1] = v[1];
347             target[2] = 0;
348             target[3] = 0;
349             target += 4;
350             v += 2;
351         }
352     }
353     else if (targetUniform->type == GL_BOOL_VEC2)
354     {
355         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
356
357         for (int i = 0; i < count; i++)
358         {
359             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
360             boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
361             boolParams[2] = GL_FALSE;
362             boolParams[3] = GL_FALSE;
363             boolParams += 4;
364             v += 2;
365         }
366     }
367     else 
368     {
369         return false;
370     }
371
372     return true;
373 }
374
375 bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
376 {
377     if (location < 0 || location >= (int)mUniformIndex.size())
378     {
379         return false;
380     }
381
382     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
383     targetUniform->dirty = true;
384
385     int elementCount = targetUniform->elementCount();
386
387     if (elementCount == 1 && count > 1)
388         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
389
390     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
391
392     if (targetUniform->type == GL_FLOAT_VEC3)
393     {
394         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
395
396         for (int i = 0; i < count; i++)
397         {
398             target[0] = v[0];
399             target[1] = v[1];
400             target[2] = v[2];
401             target[3] = 0;
402             target += 4;
403             v += 3;
404         }
405     }
406     else if (targetUniform->type == GL_BOOL_VEC3)
407     {
408         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
409
410         for (int i = 0; i < count; i++)
411         {
412             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
413             boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
414             boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
415             boolParams[3] = GL_FALSE;
416             boolParams += 4;
417             v += 3;
418         }
419     }
420     else 
421     {
422         return false;
423     }
424
425     return true;
426 }
427
428 bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
429 {
430     if (location < 0 || location >= (int)mUniformIndex.size())
431     {
432         return false;
433     }
434
435     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
436     targetUniform->dirty = true;
437
438     int elementCount = targetUniform->elementCount();
439
440     if (elementCount == 1 && count > 1)
441         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
442
443     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
444
445     if (targetUniform->type == GL_FLOAT_VEC4)
446     {
447         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
448
449         for (int i = 0; i < count; i++)
450         {
451             target[0] = v[0];
452             target[1] = v[1];
453             target[2] = v[2];
454             target[3] = v[3];
455             target += 4;
456             v += 4;
457         }
458     }
459     else if (targetUniform->type == GL_BOOL_VEC4)
460     {
461         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
462
463         for (int i = 0; i < count; i++)
464         {
465             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
466             boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
467             boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
468             boolParams[3] = (v[3] == 0.0f) ? GL_FALSE : GL_TRUE;
469             boolParams += 4;
470             v += 4;
471         }
472     }
473     else 
474     {
475         return false;
476     }
477
478     return true;
479 }
480
481 template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight>
482 void transposeMatrix(T *target, const GLfloat *value)
483 {
484     int copyWidth = std::min(targetWidth, srcWidth);
485     int copyHeight = std::min(targetHeight, srcHeight);
486
487     for (int x = 0; x < copyWidth; x++)
488     {
489         for (int y = 0; y < copyHeight; y++)
490         {
491             target[x * targetWidth + y] = (T)value[y * srcWidth + x];
492         }
493     }
494     // clear unfilled right side
495     for (int y = 0; y < copyHeight; y++)
496     {
497         for (int x = srcWidth; x < targetWidth; x++)
498         {
499             target[y * targetWidth + x] = (T)0;
500         }
501     }
502     // clear unfilled bottom.
503     for (int y = srcHeight; y < targetHeight; y++)
504     {
505         for (int x = 0; x < targetWidth; x++)
506         {
507             target[y * targetWidth + x] = (T)0;
508         }
509     }
510 }
511
512 bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
513 {
514     if (location < 0 || location >= (int)mUniformIndex.size())
515     {
516         return false;
517     }
518
519     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
520     targetUniform->dirty = true;
521
522     if (targetUniform->type != GL_FLOAT_MAT2)
523     {
524         return false;
525     }
526
527     int elementCount = targetUniform->elementCount();
528
529     if (elementCount == 1 && count > 1)
530         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
531
532     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
533     GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8;
534
535     for (int i = 0; i < count; i++)
536     {
537         transposeMatrix<GLfloat,4,2,2,2>(target, value);
538         target += 8;
539         value += 4;
540     }
541
542     return true;
543 }
544
545 bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
546 {
547     if (location < 0 || location >= (int)mUniformIndex.size())
548     {
549         return false;
550     }
551
552     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
553     targetUniform->dirty = true;
554
555     if (targetUniform->type != GL_FLOAT_MAT3)
556     {
557         return false;
558     }
559
560     int elementCount = targetUniform->elementCount();
561
562     if (elementCount == 1 && count > 1)
563         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
564
565     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
566     GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12;
567
568     for (int i = 0; i < count; i++)
569     {
570         transposeMatrix<GLfloat,4,3,3,3>(target, value);
571         target += 12;
572         value += 9;
573     }
574
575     return true;
576 }
577
578
579 bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
580 {
581     if (location < 0 || location >= (int)mUniformIndex.size())
582     {
583         return false;
584     }
585
586     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
587     targetUniform->dirty = true;
588
589     if (targetUniform->type != GL_FLOAT_MAT4)
590     {
591         return false;
592     }
593
594     int elementCount = targetUniform->elementCount();
595
596     if (elementCount == 1 && count > 1)
597         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
598
599     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
600     GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16);
601
602     for (int i = 0; i < count; i++)
603     {
604         transposeMatrix<GLfloat,4,4,4,4>(target, value);
605         target += 16;
606         value += 16;
607     }
608
609     return true;
610 }
611
612 bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
613 {
614     if (location < 0 || location >= (int)mUniformIndex.size())
615     {
616         return false;
617     }
618
619     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
620     targetUniform->dirty = true;
621
622     int elementCount = targetUniform->elementCount();
623
624     if (elementCount == 1 && count > 1)
625         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
626
627     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
628
629     if (targetUniform->type == GL_INT ||
630         targetUniform->type == GL_SAMPLER_2D ||
631         targetUniform->type == GL_SAMPLER_CUBE)
632     {
633         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
634
635         for (int i = 0; i < count; i++)
636         {
637             target[0] = v[0];
638             target[1] = 0;
639             target[2] = 0;
640             target[3] = 0;
641             target += 4;
642             v += 1;
643         }
644     }
645     else if (targetUniform->type == GL_BOOL)
646     {
647         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
648
649         for (int i = 0; i < count; i++)
650         {
651             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
652             boolParams[1] = GL_FALSE;
653             boolParams[2] = GL_FALSE;
654             boolParams[3] = GL_FALSE;
655             boolParams += 4;
656             v += 1;
657         }
658     }
659     else
660     {
661         return false;
662     }
663
664     return true;
665 }
666
667 bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
668 {
669     if (location < 0 || location >= (int)mUniformIndex.size())
670     {
671         return false;
672     }
673
674     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
675     targetUniform->dirty = true;
676
677     int elementCount = targetUniform->elementCount();
678
679     if (elementCount == 1 && count > 1)
680         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
681
682     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
683
684     if (targetUniform->type == GL_INT_VEC2)
685     {
686         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
687
688         for (int i = 0; i < count; i++)
689         {
690             target[0] = v[0];
691             target[1] = v[1];
692             target[2] = 0;
693             target[3] = 0;
694             target += 4;
695             v += 2;
696         }
697     }
698     else if (targetUniform->type == GL_BOOL_VEC2)
699     {
700         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
701
702         for (int i = 0; i < count; i++)
703         {
704             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
705             boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
706             boolParams[2] = GL_FALSE;
707             boolParams[3] = GL_FALSE;
708             boolParams += 4;
709             v += 2;
710         }
711     }
712     else
713     {
714         return false;
715     }
716
717     return true;
718 }
719
720 bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
721 {
722     if (location < 0 || location >= (int)mUniformIndex.size())
723     {
724         return false;
725     }
726
727     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
728     targetUniform->dirty = true;
729
730     int elementCount = targetUniform->elementCount();
731
732     if (elementCount == 1 && count > 1)
733         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
734
735     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
736
737     if (targetUniform->type == GL_INT_VEC3)
738     {
739         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
740
741         for (int i = 0; i < count; i++)
742         {
743             target[0] = v[0];
744             target[1] = v[1];
745             target[2] = v[2];
746             target[3] = 0;
747             target += 4;
748             v += 3;
749         }
750     }
751     else if (targetUniform->type == GL_BOOL_VEC3)
752     {
753         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
754
755         for (int i = 0; i < count; i++)
756         {
757             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
758             boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
759             boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
760             boolParams[3] = GL_FALSE;
761             boolParams += 4;
762             v += 3;
763         }
764     }
765     else
766     {
767         return false;
768     }
769
770     return true;
771 }
772
773 bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
774 {
775     if (location < 0 || location >= (int)mUniformIndex.size())
776     {
777         return false;
778     }
779
780     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
781     targetUniform->dirty = true;
782
783     int elementCount = targetUniform->elementCount();
784
785     if (elementCount == 1 && count > 1)
786         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
787
788     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
789
790     if (targetUniform->type == GL_INT_VEC4)
791     {
792         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
793
794         for (int i = 0; i < count; i++)
795         {
796             target[0] = v[0];
797             target[1] = v[1];
798             target[2] = v[2];
799             target[3] = v[3];
800             target += 4;
801             v += 4;
802         }
803     }
804     else if (targetUniform->type == GL_BOOL_VEC4)
805     {
806         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
807
808         for (int i = 0; i < count; i++)
809         {
810             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
811             boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
812             boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
813             boolParams[3] = (v[3] == 0) ? GL_FALSE : GL_TRUE;
814             boolParams += 4;
815             v += 4;
816         }
817     }
818     else
819     {
820         return false;
821     }
822
823     return true;
824 }
825
826 bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
827 {
828     if (location < 0 || location >= (int)mUniformIndex.size())
829     {
830         return false;
831     }
832
833     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
834
835     // sized queries -- ensure the provided buffer is large enough
836     if (bufSize)
837     {
838         int requiredBytes = UniformExternalSize(targetUniform->type);
839         if (*bufSize < requiredBytes)
840         {
841             return false;
842         }
843     }
844
845     switch (targetUniform->type)
846     {
847       case GL_FLOAT_MAT2:
848         transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
849         break;
850       case GL_FLOAT_MAT3:
851         transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
852         break;
853       case GL_FLOAT_MAT4:
854         transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
855         break;
856       default:
857         {
858             unsigned int size = UniformComponentCount(targetUniform->type);
859
860             switch (UniformComponentType(targetUniform->type))
861             {
862               case GL_BOOL:
863                 {
864                     GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
865
866                     for (unsigned int i = 0; i < size; i++)
867                     {
868                         params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
869                     }
870                 }
871                 break;
872               case GL_FLOAT:
873                 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLfloat),
874                        size * sizeof(GLfloat));
875                 break;
876               case GL_INT:
877                 {
878                     GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
879
880                     for (unsigned int i = 0; i < size; i++)
881                     {
882                         params[i] = (float)intParams[i];
883                     }
884                 }
885                 break;
886               default: UNREACHABLE();
887             }
888         }
889     }
890
891     return true;
892 }
893
894 bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
895 {
896     if (location < 0 || location >= (int)mUniformIndex.size())
897     {
898         return false;
899     }
900
901     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
902
903     // sized queries -- ensure the provided buffer is large enough
904     if (bufSize)
905     {
906         int requiredBytes = UniformExternalSize(targetUniform->type);
907         if (*bufSize < requiredBytes)
908         {
909             return false;
910         }
911     }
912
913     switch (targetUniform->type)
914     {
915       case GL_FLOAT_MAT2:
916         transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
917         break;
918       case GL_FLOAT_MAT3:
919         transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
920         break;
921       case GL_FLOAT_MAT4:
922         transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
923         break;
924       default:
925         {
926             unsigned int size = VariableColumnCount(targetUniform->type);
927
928             switch (UniformComponentType(targetUniform->type))
929             {
930               case GL_BOOL:
931                 {
932                     GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
933
934                     for (unsigned int i = 0; i < size; i++)
935                     {
936                         params[i] = boolParams[i];
937                     }
938                 }
939                 break;
940               case GL_FLOAT:
941                 {
942                     GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
943
944                     for (unsigned int i = 0; i < size; i++)
945                     {
946                         params[i] = (GLint)floatParams[i];
947                     }
948                 }
949                 break;
950               case GL_INT:
951                 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLint),
952                     size * sizeof(GLint));
953                 break;
954               default: UNREACHABLE();
955             }
956         }
957     }
958
959     return true;
960 }
961
962 void ProgramBinary::dirtyAllUniforms()
963 {
964     unsigned int numUniforms = mUniforms.size();
965     for (unsigned int index = 0; index < numUniforms; index++)
966     {
967         mUniforms[index]->dirty = true;
968     }
969 }
970
971 // Applies all the uniforms set for this program object to the renderer
972 void ProgramBinary::applyUniforms()
973 {
974     // Retrieve sampler uniform values
975     for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub)
976     {
977         Uniform *targetUniform = *ub;
978
979         if (targetUniform->dirty)
980         {
981             if (targetUniform->type == GL_SAMPLER_2D || 
982                 targetUniform->type == GL_SAMPLER_CUBE)
983             {
984                 int count = targetUniform->elementCount();
985                 GLint (*v)[4] = (GLint(*)[4])targetUniform->data;
986
987                 if (targetUniform->psRegisterIndex >= 0)
988                 {
989                     unsigned int firstIndex = targetUniform->psRegisterIndex;
990
991                     for (int i = 0; i < count; i++)
992                     {
993                         unsigned int samplerIndex = firstIndex + i;
994
995                         if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
996                         {
997                             ASSERT(mSamplersPS[samplerIndex].active);
998                             mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
999                         }
1000                     }
1001                 }
1002
1003                 if (targetUniform->vsRegisterIndex >= 0)
1004                 {
1005                     unsigned int firstIndex = targetUniform->vsRegisterIndex;
1006
1007                     for (int i = 0; i < count; i++)
1008                     {
1009                         unsigned int samplerIndex = firstIndex + i;
1010
1011                         if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
1012                         {
1013                             ASSERT(mSamplersVS[samplerIndex].active);
1014                             mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
1015                         }
1016                     }
1017                 }
1018             }
1019         }
1020     }
1021
1022     mRenderer->applyUniforms(this, &mUniforms);
1023 }
1024
1025 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
1026 // Returns the number of used varying registers, or -1 if unsuccesful
1027 int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)
1028 {
1029     const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
1030
1031     fragmentShader->resetVaryingsRegisterAssignment();
1032
1033     for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
1034     {
1035         int n = VariableRowCount(varying->type) * varying->size;
1036         int m = VariableColumnCount(varying->type);
1037         bool success = false;
1038
1039         if (m == 2 || m == 3 || m == 4)
1040         {
1041             for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
1042             {
1043                 bool available = true;
1044
1045                 for (int y = 0; y < n && available; y++)
1046                 {
1047                     for (int x = 0; x < m && available; x++)
1048                     {
1049                         if (packing[r + y][x])
1050                         {
1051                             available = false;
1052                         }
1053                     }
1054                 }
1055
1056                 if (available)
1057                 {
1058                     varying->reg = r;
1059                     varying->col = 0;
1060
1061                     for (int y = 0; y < n; y++)
1062                     {
1063                         for (int x = 0; x < m; x++)
1064                         {
1065                             packing[r + y][x] = &*varying;
1066                         }
1067                     }
1068
1069                     success = true;
1070                 }
1071             }
1072
1073             if (!success && m == 2)
1074             {
1075                 for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
1076                 {
1077                     bool available = true;
1078
1079                     for (int y = 0; y < n && available; y++)
1080                     {
1081                         for (int x = 2; x < 4 && available; x++)
1082                         {
1083                             if (packing[r + y][x])
1084                             {
1085                                 available = false;
1086                             }
1087                         }
1088                     }
1089
1090                     if (available)
1091                     {
1092                         varying->reg = r;
1093                         varying->col = 2;
1094
1095                         for (int y = 0; y < n; y++)
1096                         {
1097                             for (int x = 2; x < 4; x++)
1098                             {
1099                                 packing[r + y][x] = &*varying;
1100                             }
1101                         }
1102
1103                         success = true;
1104                     }
1105                 }
1106             }
1107         }
1108         else if (m == 1)
1109         {
1110             int space[4] = {0};
1111
1112             for (int y = 0; y < maxVaryingVectors; y++)
1113             {
1114                 for (int x = 0; x < 4; x++)
1115                 {
1116                     space[x] += packing[y][x] ? 0 : 1;
1117                 }
1118             }
1119
1120             int column = 0;
1121
1122             for (int x = 0; x < 4; x++)
1123             {
1124                 if (space[x] >= n && space[x] < space[column])
1125                 {
1126                     column = x;
1127                 }
1128             }
1129
1130             if (space[column] >= n)
1131             {
1132                 for (int r = 0; r < maxVaryingVectors; r++)
1133                 {
1134                     if (!packing[r][column])
1135                     {
1136                         varying->reg = r;
1137
1138                         for (int y = r; y < r + n; y++)
1139                         {
1140                             packing[y][column] = &*varying;
1141                         }
1142
1143                         break;
1144                     }
1145                 }
1146
1147                 varying->col = column;
1148
1149                 success = true;
1150             }
1151         }
1152         else UNREACHABLE();
1153
1154         if (!success)
1155         {
1156             infoLog.append("Could not pack varying %s", varying->name.c_str());
1157
1158             return -1;
1159         }
1160     }
1161
1162     // Return the number of used registers
1163     int registers = 0;
1164
1165     for (int r = 0; r < maxVaryingVectors; r++)
1166     {
1167         if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
1168         {
1169             registers++;
1170         }
1171     }
1172
1173     return registers;
1174 }
1175
1176 bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4],
1177                                  std::string& pixelHLSL, std::string& vertexHLSL,
1178                                  FragmentShader *fragmentShader, VertexShader *vertexShader)
1179 {
1180     if (pixelHLSL.empty() || vertexHLSL.empty())
1181     {
1182         return false;
1183     }
1184
1185     bool usesMRT = fragmentShader->mUsesMultipleRenderTargets;
1186     bool usesFragColor = fragmentShader->mUsesFragColor;
1187     bool usesFragData = fragmentShader->mUsesFragData;
1188     if (usesFragColor && usesFragData)
1189     {
1190         infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
1191         return false;
1192     }
1193
1194     // Write the HLSL input/output declarations
1195     const int shaderModel = mRenderer->getMajorShaderModel();
1196     const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
1197
1198     const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0);
1199
1200     // The output color is broadcast to all enabled draw buffers when writing to gl_FragColor 
1201     const bool broadcast = fragmentShader->mUsesFragColor;
1202     const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1);
1203
1204     if (registersNeeded > maxVaryingVectors)
1205     {
1206         infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
1207
1208         return false;
1209     }
1210
1211     vertexShader->resetVaryingsRegisterAssignment();
1212
1213     for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++)
1214     {
1215         bool matched = false;
1216
1217         for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++)
1218         {
1219             if (output->name == input->name)
1220             {
1221                 if (output->type != input->type || output->size != input->size)
1222                 {
1223                     infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
1224
1225                     return false;
1226                 }
1227
1228                 output->reg = input->reg;
1229                 output->col = input->col;
1230
1231                 matched = true;
1232                 break;
1233             }
1234         }
1235
1236         if (!matched)
1237         {
1238             infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
1239
1240             return false;
1241         }
1242     }
1243
1244     mUsesPointSize = vertexShader->mUsesPointSize;
1245     std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD";
1246     std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR";
1247     std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION";
1248     std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
1249
1250     // special varyings that use reserved registers
1251     int reservedRegisterIndex = registers;
1252     std::string fragCoordSemantic;
1253     std::string pointCoordSemantic;
1254
1255     if (fragmentShader->mUsesFragCoord)
1256     {
1257         fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
1258     }
1259
1260     if (fragmentShader->mUsesPointCoord)
1261     {
1262         // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords.
1263         // In DX11 we compute this in the GS.
1264         if (shaderModel == 3)
1265         {
1266             pointCoordSemantic = "TEXCOORD0";
1267         }
1268         else if (shaderModel >= 4)
1269         {
1270             pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); 
1271         }
1272     }
1273
1274     vertexHLSL += "struct VS_INPUT\n"
1275                   "{\n";
1276
1277     int semanticIndex = 0;
1278     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
1279     {
1280         switch (attribute->type)
1281         {
1282           case GL_FLOAT:      vertexHLSL += "    float ";    break;
1283           case GL_FLOAT_VEC2: vertexHLSL += "    float2 ";   break;
1284           case GL_FLOAT_VEC3: vertexHLSL += "    float3 ";   break;
1285           case GL_FLOAT_VEC4: vertexHLSL += "    float4 ";   break;
1286           case GL_FLOAT_MAT2: vertexHLSL += "    float2x2 "; break;
1287           case GL_FLOAT_MAT3: vertexHLSL += "    float3x3 "; break;
1288           case GL_FLOAT_MAT4: vertexHLSL += "    float4x4 "; break;
1289           default:  UNREACHABLE();
1290         }
1291
1292         vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
1293
1294         semanticIndex += VariableRowCount(attribute->type);
1295     }
1296
1297     vertexHLSL += "};\n"
1298                   "\n"
1299                   "struct VS_OUTPUT\n"
1300                   "{\n";
1301
1302     if (shaderModel < 4)
1303     {
1304         vertexHLSL += "    float4 gl_Position : " + positionSemantic + ";\n";
1305     }
1306
1307     for (int r = 0; r < registers; r++)
1308     {
1309         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
1310
1311         vertexHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
1312     }
1313
1314     if (fragmentShader->mUsesFragCoord)
1315     {
1316         vertexHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
1317     }
1318
1319     if (vertexShader->mUsesPointSize && shaderModel >= 3)
1320     {
1321         vertexHLSL += "    float gl_PointSize : PSIZE;\n";
1322     }
1323
1324     if (shaderModel >= 4)
1325     {
1326         vertexHLSL += "    float4 gl_Position : " + positionSemantic + ";\n";
1327     }
1328
1329     vertexHLSL += "};\n"
1330                   "\n"
1331                   "VS_OUTPUT main(VS_INPUT input)\n"
1332                   "{\n";
1333
1334     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
1335     {
1336         vertexHLSL += "    " + decorateAttribute(attribute->name) + " = ";
1337
1338         if (VariableRowCount(attribute->type) > 1)   // Matrix
1339         {
1340             vertexHLSL += "transpose";
1341         }
1342
1343         vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
1344     }
1345
1346     if (shaderModel >= 4)
1347     {
1348         vertexHLSL += "\n"
1349                       "    gl_main();\n"
1350                       "\n"
1351                       "    VS_OUTPUT output;\n"
1352                       "    output.gl_Position.x = gl_Position.x;\n"
1353                       "    output.gl_Position.y = -gl_Position.y;\n"
1354                       "    output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
1355                       "    output.gl_Position.w = gl_Position.w;\n";
1356     }
1357     else
1358     {
1359         vertexHLSL += "\n"
1360                       "    gl_main();\n"
1361                       "\n"
1362                       "    VS_OUTPUT output;\n"
1363                       "    output.gl_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
1364                       "    output.gl_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"
1365                       "    output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
1366                       "    output.gl_Position.w = gl_Position.w;\n";
1367     }
1368
1369     if (vertexShader->mUsesPointSize && shaderModel >= 3)
1370     {
1371         vertexHLSL += "    output.gl_PointSize = gl_PointSize;\n";
1372     }
1373
1374     if (fragmentShader->mUsesFragCoord)
1375     {
1376         vertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
1377     }
1378
1379     for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++)
1380     {
1381         if (varying->reg >= 0)
1382         {
1383             for (int i = 0; i < varying->size; i++)
1384             {
1385                 int rows = VariableRowCount(varying->type);
1386
1387                 for (int j = 0; j < rows; j++)
1388                 {
1389                     int r = varying->reg + i * rows + j;
1390                     vertexHLSL += "    output.v" + str(r);
1391
1392                     bool sharedRegister = false;   // Register used by multiple varyings
1393                     
1394                     for (int x = 0; x < 4; x++)
1395                     {
1396                         if (packing[r][x] && packing[r][x] != packing[r][0])
1397                         {
1398                             sharedRegister = true;
1399                             break;
1400                         }
1401                     }
1402
1403                     if(sharedRegister)
1404                     {
1405                         vertexHLSL += ".";
1406
1407                         for (int x = 0; x < 4; x++)
1408                         {
1409                             if (packing[r][x] == &*varying)
1410                             {
1411                                 switch(x)
1412                                 {
1413                                   case 0: vertexHLSL += "x"; break;
1414                                   case 1: vertexHLSL += "y"; break;
1415                                   case 2: vertexHLSL += "z"; break;
1416                                   case 3: vertexHLSL += "w"; break;
1417                                 }
1418                             }
1419                         }
1420                     }
1421
1422                     vertexHLSL += " = " + varying->name;
1423                     
1424                     if (varying->array)
1425                     {
1426                         vertexHLSL += "[" + str(i) + "]";
1427                     }
1428
1429                     if (rows > 1)
1430                     {
1431                         vertexHLSL += "[" + str(j) + "]";
1432                     }
1433                     
1434                     vertexHLSL += ";\n";
1435                 }
1436             }
1437         }
1438     }
1439
1440     vertexHLSL += "\n"
1441                   "    return output;\n"
1442                   "}\n";
1443
1444     pixelHLSL += "struct PS_INPUT\n"
1445                  "{\n";
1446     
1447     for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
1448     {
1449         if (varying->reg >= 0)
1450         {
1451             for (int i = 0; i < varying->size; i++)
1452             {
1453                 int rows = VariableRowCount(varying->type);
1454                 for (int j = 0; j < rows; j++)
1455                 {
1456                     std::string n = str(varying->reg + i * rows + j);
1457                     pixelHLSL += "    float" + str(VariableColumnCount(varying->type)) + " v" + n + " : " + varyingSemantic + n + ";\n";
1458                 }
1459             }
1460         }
1461         else UNREACHABLE();
1462     }
1463
1464     if (fragmentShader->mUsesFragCoord)
1465     {
1466         pixelHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
1467     }
1468         
1469     if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
1470     {
1471         pixelHLSL += "    float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
1472     }
1473
1474     // Must consume the PSIZE element if the geometry shader is not active
1475     // We won't know if we use a GS until we draw
1476     if (vertexShader->mUsesPointSize && shaderModel >= 4)
1477     {
1478         pixelHLSL += "    float gl_PointSize : PSIZE;\n";
1479     }
1480
1481     if (fragmentShader->mUsesFragCoord)
1482     {
1483         if (shaderModel >= 4)
1484         {
1485             pixelHLSL += "    float4 dx_VPos : SV_Position;\n";
1486         }
1487         else if (shaderModel >= 3)
1488         {
1489             pixelHLSL += "    float2 dx_VPos : VPOS;\n";
1490         }
1491     }
1492
1493     pixelHLSL += "};\n"
1494                  "\n"
1495                  "struct PS_OUTPUT\n"
1496                  "{\n";
1497
1498     for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
1499     {
1500         pixelHLSL += "    float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n";
1501     }
1502
1503     if (fragmentShader->mUsesFragDepth)
1504     {
1505         pixelHLSL += "    float gl_Depth : " + depthSemantic + ";\n";
1506     }
1507
1508     pixelHLSL += "};\n"
1509                  "\n";
1510
1511     if (fragmentShader->mUsesFrontFacing)
1512     {
1513         if (shaderModel >= 4)
1514         {
1515             pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n"
1516                          "{\n";
1517         }
1518         else
1519         {
1520             pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n"
1521                          "{\n";
1522         }
1523     }
1524     else
1525     {
1526         pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n"
1527                      "{\n";
1528     }
1529
1530     if (fragmentShader->mUsesFragCoord)
1531     {
1532         pixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n";
1533         
1534         if (shaderModel >= 4)
1535         {
1536             pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x;\n"
1537                          "    gl_FragCoord.y = input.dx_VPos.y;\n";
1538         }
1539         else if (shaderModel >= 3)
1540         {
1541             pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
1542                          "    gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
1543         }
1544         else
1545         {
1546             // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport()
1547             pixelHLSL += "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n"
1548                          "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n";
1549         }
1550         
1551         pixelHLSL += "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n"
1552                      "    gl_FragCoord.w = rhw;\n";
1553     }
1554
1555     if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
1556     {
1557         pixelHLSL += "    gl_PointCoord.x = input.gl_PointCoord.x;\n";
1558         pixelHLSL += "    gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
1559     }
1560
1561     if (fragmentShader->mUsesFrontFacing)
1562     {
1563         if (shaderModel <= 3)
1564         {
1565             pixelHLSL += "    gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n";
1566         }
1567         else
1568         {
1569             pixelHLSL += "    gl_FrontFacing = isFrontFace;\n";
1570         }
1571     }
1572
1573     for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
1574     {
1575         if (varying->reg >= 0)
1576         {
1577             for (int i = 0; i < varying->size; i++)
1578             {
1579                 int rows = VariableRowCount(varying->type);
1580                 for (int j = 0; j < rows; j++)
1581                 {
1582                     std::string n = str(varying->reg + i * rows + j);
1583                     pixelHLSL += "    " + varying->name;
1584
1585                     if (varying->array)
1586                     {
1587                         pixelHLSL += "[" + str(i) + "]";
1588                     }
1589
1590                     if (rows > 1)
1591                     {
1592                         pixelHLSL += "[" + str(j) + "]";
1593                     }
1594
1595                     switch (VariableColumnCount(varying->type))
1596                     {
1597                       case 1: pixelHLSL += " = input.v" + n + ".x;\n";   break;
1598                       case 2: pixelHLSL += " = input.v" + n + ".xy;\n";  break;
1599                       case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break;
1600                       case 4: pixelHLSL += " = input.v" + n + ";\n";     break;
1601                       default: UNREACHABLE();
1602                     }
1603                 }
1604             }
1605         }
1606         else UNREACHABLE();
1607     }
1608
1609     pixelHLSL += "\n"
1610                  "    gl_main();\n"
1611                  "\n"
1612                  "    PS_OUTPUT output;\n";
1613
1614     for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
1615     {
1616         unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex;
1617
1618         pixelHLSL += "    output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n";
1619     }
1620
1621     if (fragmentShader->mUsesFragDepth)
1622     {
1623         pixelHLSL += "    output.gl_Depth = gl_Depth;\n";
1624     }
1625
1626     pixelHLSL += "\n"
1627                  "    return output;\n"
1628                  "}\n";
1629
1630     return true;
1631 }
1632
1633 bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
1634 {
1635     BinaryInputStream stream(binary, length);
1636
1637     int format = 0;
1638     stream.read(&format);
1639     if (format != GL_PROGRAM_BINARY_ANGLE)
1640     {
1641         infoLog.append("Invalid program binary format.");
1642         return false;
1643     }
1644
1645     int majorVersion = 0;
1646     int minorVersion = 0;
1647     stream.read(&majorVersion);
1648     stream.read(&minorVersion);
1649     if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
1650     {
1651         infoLog.append("Invalid program binary version.");
1652         return false;
1653     }
1654
1655     unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
1656     stream.read(commitString, ANGLE_COMMIT_HASH_SIZE);
1657     if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
1658     {
1659         infoLog.append("Invalid program binary version.");
1660         return false;
1661     }
1662
1663     int compileFlags = 0;
1664     stream.read(&compileFlags);
1665     if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
1666     {
1667         infoLog.append("Mismatched compilation flags.");
1668         return false;
1669     }
1670
1671     for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
1672     {
1673         stream.read(&mLinkedAttribute[i].type);
1674         std::string name;
1675         stream.read(&name);
1676         mLinkedAttribute[i].name = name;
1677         stream.read(&mSemanticIndex[i]);
1678     }
1679
1680     initAttributesByLayout();
1681
1682     for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
1683     {
1684         stream.read(&mSamplersPS[i].active);
1685         stream.read(&mSamplersPS[i].logicalTextureUnit);
1686         
1687         int textureType;
1688         stream.read(&textureType);
1689         mSamplersPS[i].textureType = (TextureType) textureType;
1690     }
1691
1692     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
1693     {
1694         stream.read(&mSamplersVS[i].active);
1695         stream.read(&mSamplersVS[i].logicalTextureUnit);
1696         
1697         int textureType;
1698         stream.read(&textureType);
1699         mSamplersVS[i].textureType = (TextureType) textureType;
1700     }
1701
1702     stream.read(&mUsedVertexSamplerRange);
1703     stream.read(&mUsedPixelSamplerRange);
1704     stream.read(&mUsesPointSize);
1705
1706     size_t size;
1707     stream.read(&size);
1708     if (stream.error())
1709     {
1710         infoLog.append("Invalid program binary.");
1711         return false;
1712     }
1713
1714     mUniforms.resize(size);
1715     for (unsigned int i = 0; i < size; ++i)
1716     {
1717         GLenum type;
1718         GLenum precision;
1719         std::string name;
1720         unsigned int arraySize;
1721
1722         stream.read(&type);
1723         stream.read(&precision);
1724         stream.read(&name);
1725         stream.read(&arraySize);
1726
1727         mUniforms[i] = new Uniform(type, precision, name, arraySize);
1728         
1729         stream.read(&mUniforms[i]->psRegisterIndex);
1730         stream.read(&mUniforms[i]->vsRegisterIndex);
1731         stream.read(&mUniforms[i]->registerCount);
1732     }
1733
1734     stream.read(&size);
1735     if (stream.error())
1736     {
1737         infoLog.append("Invalid program binary.");
1738         return false;
1739     }
1740
1741     mUniformIndex.resize(size);
1742     for (unsigned int i = 0; i < size; ++i)
1743     {
1744         stream.read(&mUniformIndex[i].name);
1745         stream.read(&mUniformIndex[i].element);
1746         stream.read(&mUniformIndex[i].index);
1747     }
1748
1749     unsigned int pixelShaderSize;
1750     stream.read(&pixelShaderSize);
1751
1752     unsigned int vertexShaderSize;
1753     stream.read(&vertexShaderSize);
1754
1755     unsigned int geometryShaderSize;
1756     stream.read(&geometryShaderSize);
1757
1758     const char *ptr = (const char*) binary + stream.offset();
1759
1760     const GUID *binaryIdentifier = (const GUID *) ptr;
1761     ptr += sizeof(GUID);
1762
1763     GUID identifier = mRenderer->getAdapterIdentifier();
1764     if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
1765     {
1766         infoLog.append("Invalid program binary.");
1767         return false;
1768     }
1769
1770     const char *pixelShaderFunction = ptr;
1771     ptr += pixelShaderSize;
1772
1773     const char *vertexShaderFunction = ptr;
1774     ptr += vertexShaderSize;
1775
1776     const char *geometryShaderFunction = geometryShaderSize > 0 ? ptr : NULL;
1777     ptr += geometryShaderSize;
1778
1779     mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
1780                                                  pixelShaderSize, rx::SHADER_PIXEL);
1781     if (!mPixelExecutable)
1782     {
1783         infoLog.append("Could not create pixel shader.");
1784         return false;
1785     }
1786
1787     mVertexExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
1788                                                   vertexShaderSize, rx::SHADER_VERTEX);
1789     if (!mVertexExecutable)
1790     {
1791         infoLog.append("Could not create vertex shader.");
1792         delete mPixelExecutable;
1793         mPixelExecutable = NULL;
1794         return false;
1795     }
1796
1797     if (geometryShaderFunction != NULL && geometryShaderSize > 0)
1798     {
1799         mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
1800                                                         geometryShaderSize, rx::SHADER_GEOMETRY);
1801         if (!mGeometryExecutable)
1802         {
1803             infoLog.append("Could not create geometry shader.");
1804             delete mPixelExecutable;
1805             mPixelExecutable = NULL;
1806             delete mVertexExecutable;
1807             mVertexExecutable = NULL;
1808             return false;
1809         }
1810     }
1811     else
1812     {
1813         mGeometryExecutable = NULL;
1814     }
1815
1816     return true;
1817 }
1818
1819 bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
1820 {
1821     BinaryOutputStream stream;
1822
1823     stream.write(GL_PROGRAM_BINARY_ANGLE);
1824     stream.write(ANGLE_MAJOR_VERSION);
1825     stream.write(ANGLE_MINOR_VERSION);
1826     stream.write(ANGLE_COMMIT_HASH, ANGLE_COMMIT_HASH_SIZE);
1827     stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
1828
1829     for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
1830     {
1831         stream.write(mLinkedAttribute[i].type);
1832         stream.write(mLinkedAttribute[i].name);
1833         stream.write(mSemanticIndex[i]);
1834     }
1835
1836     for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
1837     {
1838         stream.write(mSamplersPS[i].active);
1839         stream.write(mSamplersPS[i].logicalTextureUnit);
1840         stream.write((int) mSamplersPS[i].textureType);
1841     }
1842
1843     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
1844     {
1845         stream.write(mSamplersVS[i].active);
1846         stream.write(mSamplersVS[i].logicalTextureUnit);
1847         stream.write((int) mSamplersVS[i].textureType);
1848     }
1849
1850     stream.write(mUsedVertexSamplerRange);
1851     stream.write(mUsedPixelSamplerRange);
1852     stream.write(mUsesPointSize);
1853
1854     stream.write(mUniforms.size());
1855     for (unsigned int i = 0; i < mUniforms.size(); ++i)
1856     {
1857         stream.write(mUniforms[i]->type);
1858         stream.write(mUniforms[i]->precision);
1859         stream.write(mUniforms[i]->name);
1860         stream.write(mUniforms[i]->arraySize);
1861
1862         stream.write(mUniforms[i]->psRegisterIndex);
1863         stream.write(mUniforms[i]->vsRegisterIndex);
1864         stream.write(mUniforms[i]->registerCount);
1865     }
1866
1867     stream.write(mUniformIndex.size());
1868     for (unsigned int i = 0; i < mUniformIndex.size(); ++i)
1869     {
1870         stream.write(mUniformIndex[i].name);
1871         stream.write(mUniformIndex[i].element);
1872         stream.write(mUniformIndex[i].index);
1873     }
1874
1875     UINT pixelShaderSize = mPixelExecutable->getLength();
1876     stream.write(pixelShaderSize);
1877
1878     UINT vertexShaderSize = mVertexExecutable->getLength();
1879     stream.write(vertexShaderSize);
1880
1881     UINT geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
1882     stream.write(geometryShaderSize);
1883
1884     GUID identifier = mRenderer->getAdapterIdentifier();
1885
1886     GLsizei streamLength = stream.length();
1887     const void *streamData = stream.data();
1888
1889     GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize + geometryShaderSize;
1890     if (totalLength > bufSize)
1891     {
1892         if (length)
1893         {
1894             *length = 0;
1895         }
1896
1897         return false;
1898     }
1899
1900     if (binary)
1901     {
1902         char *ptr = (char*) binary;
1903
1904         memcpy(ptr, streamData, streamLength);
1905         ptr += streamLength;
1906
1907         memcpy(ptr, &identifier, sizeof(GUID));
1908         ptr += sizeof(GUID);
1909
1910         memcpy(ptr, mPixelExecutable->getFunction(), pixelShaderSize);
1911         ptr += pixelShaderSize;
1912
1913         memcpy(ptr, mVertexExecutable->getFunction(), vertexShaderSize);
1914         ptr += vertexShaderSize;
1915
1916         if (mGeometryExecutable != NULL && geometryShaderSize > 0)
1917         {
1918             memcpy(ptr, mGeometryExecutable->getFunction(), geometryShaderSize);
1919             ptr += geometryShaderSize;
1920         }
1921
1922         ASSERT(ptr - totalLength == binary);
1923     }
1924
1925     if (length)
1926     {
1927         *length = totalLength;
1928     }
1929
1930     return true;
1931 }
1932
1933 GLint ProgramBinary::getLength()
1934 {
1935     GLint length;
1936     if (save(NULL, INT_MAX, &length))
1937     {
1938         return length;
1939     }
1940     else
1941     {
1942         return 0;
1943     }
1944 }
1945
1946 bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
1947 {
1948     if (!fragmentShader || !fragmentShader->isCompiled())
1949     {
1950         return false;
1951     }
1952
1953     if (!vertexShader || !vertexShader->isCompiled())
1954     {
1955         return false;
1956     }
1957
1958     std::string pixelHLSL = fragmentShader->getHLSL();
1959     std::string vertexHLSL = vertexShader->getHLSL();
1960
1961     // Map the varyings to the register file
1962     const Varying *packing[IMPLEMENTATION_MAX_VARYING_VECTORS][4] = {NULL};
1963     int registers = packVaryings(infoLog, packing, fragmentShader);
1964
1965     if (registers < 0)
1966     {
1967         return false;
1968     }
1969
1970     if (!linkVaryings(infoLog, registers, packing, pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
1971     {
1972         return false;
1973     }
1974
1975     bool success = true;
1976
1977     if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
1978     {
1979         success = false;
1980     }
1981
1982     if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms()))
1983     {
1984         success = false;
1985     }
1986
1987     // special case for gl_DepthRange, the only built-in uniform (also a struct)
1988     if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange)
1989     {
1990         mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0));
1991         mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0));
1992         mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0));
1993     }
1994
1995     if (success)
1996     {
1997         mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, DiscardWorkaround(vertexShader->mUsesDiscardRewriting, vertexShader->mUsesNestedBreak));
1998         mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, DiscardWorkaround(fragmentShader->mUsesDiscardRewriting, fragmentShader->mUsesNestedBreak));
1999
2000         if (usesGeometryShader())
2001         {
2002             std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader);
2003             mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY, rx::ANGLE_D3D_WORKAROUND_NONE);
2004         }
2005
2006         if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
2007         {
2008             infoLog.append("Failed to create D3D shaders.");
2009             success = false;
2010
2011             delete mVertexExecutable;
2012             mVertexExecutable = NULL;
2013             delete mPixelExecutable;
2014             mPixelExecutable = NULL;
2015             delete mGeometryExecutable;
2016             mGeometryExecutable = NULL;
2017         }
2018     }
2019
2020     return success;
2021 }
2022
2023 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
2024 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
2025 {
2026     unsigned int usedLocations = 0;
2027
2028     // Link attributes that have a binding location
2029     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
2030     {
2031         int location = attributeBindings.getAttributeBinding(attribute->name);
2032
2033         if (location != -1)   // Set by glBindAttribLocation
2034         {
2035             if (!mLinkedAttribute[location].name.empty())
2036             {
2037                 // Multiple active attributes bound to the same location; not an error
2038             }
2039
2040             mLinkedAttribute[location] = *attribute;
2041
2042             int rows = VariableRowCount(attribute->type);
2043
2044             if (rows + location > MAX_VERTEX_ATTRIBS)
2045             {
2046                 infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
2047
2048                 return false;
2049             }
2050
2051             for (int i = 0; i < rows; i++)
2052             {
2053                 usedLocations |= 1 << (location + i);
2054             }
2055         }
2056     }
2057
2058     // Link attributes that don't have a binding location
2059     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
2060     {
2061         int location = attributeBindings.getAttributeBinding(attribute->name);
2062
2063         if (location == -1)   // Not set by glBindAttribLocation
2064         {
2065             int rows = VariableRowCount(attribute->type);
2066             int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
2067
2068             if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
2069             {
2070                 infoLog.append("Too many active attributes (%s)", attribute->name.c_str());
2071
2072                 return false;   // Fail to link
2073             }
2074
2075             mLinkedAttribute[availableIndex] = *attribute;
2076         }
2077     }
2078
2079     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
2080     {
2081         int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
2082         int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1);
2083
2084         for (int r = 0; r < rows; r++)
2085         {
2086             mSemanticIndex[attributeIndex++] = index++;
2087         }
2088     }
2089
2090     initAttributesByLayout();
2091
2092     return true;
2093 }
2094
2095 bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms)
2096 {
2097     for (sh::ActiveUniforms::const_iterator uniform = vertexUniforms.begin(); uniform != vertexUniforms.end(); uniform++)
2098     {
2099         if (!defineUniform(GL_VERTEX_SHADER, *uniform, infoLog))
2100         {
2101             return false;
2102         }
2103     }
2104
2105     for (sh::ActiveUniforms::const_iterator uniform = fragmentUniforms.begin(); uniform != fragmentUniforms.end(); uniform++)
2106     {
2107         if (!defineUniform(GL_FRAGMENT_SHADER, *uniform, infoLog))
2108         {
2109             return false;
2110         }
2111     }
2112
2113     return true;
2114 }
2115
2116 bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog)
2117 {
2118     if (constant.type == GL_SAMPLER_2D ||
2119         constant.type == GL_SAMPLER_CUBE)
2120     {
2121         unsigned int samplerIndex = constant.registerIndex;
2122             
2123         do
2124         {
2125             if (shader == GL_VERTEX_SHADER)
2126             {
2127                 if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits())
2128                 {
2129                     mSamplersVS[samplerIndex].active = true;
2130                     mSamplersVS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
2131                     mSamplersVS[samplerIndex].logicalTextureUnit = 0;
2132                     mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
2133                 }
2134                 else
2135                 {
2136                     infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", mRenderer->getMaxVertexTextureImageUnits());
2137                     return false;
2138                 }
2139             }
2140             else if (shader == GL_FRAGMENT_SHADER)
2141             {
2142                 if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
2143                 {
2144                     mSamplersPS[samplerIndex].active = true;
2145                     mSamplersPS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
2146                     mSamplersPS[samplerIndex].logicalTextureUnit = 0;
2147                     mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
2148                 }
2149                 else
2150                 {
2151                     infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
2152                     return false;
2153                 }
2154             }
2155             else UNREACHABLE();
2156
2157             samplerIndex++;
2158         }
2159         while (samplerIndex < constant.registerIndex + constant.arraySize);
2160     }
2161
2162     Uniform *uniform = NULL;
2163     GLint location = getUniformLocation(constant.name);
2164
2165     if (location >= 0)   // Previously defined, type and precision must match
2166     {
2167         uniform = mUniforms[mUniformIndex[location].index];
2168
2169         if (uniform->type != constant.type)
2170         {
2171             infoLog.append("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
2172             return false;
2173         }
2174
2175         if (uniform->precision != constant.precision)
2176         {
2177             infoLog.append("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
2178             return false;
2179         }
2180     }
2181     else
2182     {
2183         uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize);
2184     }
2185
2186     if (!uniform)
2187     {
2188         return false;
2189     }
2190
2191     if (shader == GL_FRAGMENT_SHADER)
2192     {
2193         uniform->psRegisterIndex = constant.registerIndex;
2194     }
2195     else if (shader == GL_VERTEX_SHADER)
2196     {
2197         uniform->vsRegisterIndex = constant.registerIndex;
2198     }
2199     else UNREACHABLE();
2200
2201     if (location >= 0)
2202     {
2203         return uniform->type == constant.type;
2204     }
2205
2206     mUniforms.push_back(uniform);
2207     unsigned int uniformIndex = mUniforms.size() - 1;
2208
2209     for (unsigned int i = 0; i < uniform->elementCount(); i++)
2210     {
2211         mUniformIndex.push_back(UniformLocation(constant.name, i, uniformIndex));
2212     }
2213
2214     if (shader == GL_VERTEX_SHADER)
2215     {
2216         if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedVertexUniformVectors() + mRenderer->getMaxVertexUniformVectors())
2217         {
2218             infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", mRenderer->getMaxVertexUniformVectors());
2219             return false;
2220         }
2221     }
2222     else if (shader == GL_FRAGMENT_SHADER)
2223     {
2224         if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedFragmentUniformVectors() + mRenderer->getMaxFragmentUniformVectors())
2225         {
2226             infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", mRenderer->getMaxFragmentUniformVectors());
2227             return false;
2228         }
2229     }
2230     else UNREACHABLE();
2231
2232     return true;
2233 }
2234
2235 std::string ProgramBinary::generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const
2236 {
2237     // for now we only handle point sprite emulation
2238     ASSERT(usesPointSpriteEmulation());
2239     return generatePointSpriteHLSL(registers, packing, fragmentShader, vertexShader);
2240 }
2241
2242 std::string ProgramBinary::generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const
2243 {
2244     ASSERT(registers >= 0);
2245     ASSERT(vertexShader->mUsesPointSize);
2246     ASSERT(mRenderer->getMajorShaderModel() >= 4);
2247
2248     std::string geomHLSL;
2249
2250     std::string varyingSemantic = "TEXCOORD";
2251
2252     std::string fragCoordSemantic;
2253     std::string pointCoordSemantic;
2254
2255     int reservedRegisterIndex = registers;
2256
2257     if (fragmentShader->mUsesFragCoord)
2258     {
2259         fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
2260     }
2261
2262     if (fragmentShader->mUsesPointCoord)
2263     {
2264         pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
2265     }
2266
2267     geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n"
2268                 "\n"
2269                 "struct GS_INPUT\n"
2270                 "{\n";
2271
2272     for (int r = 0; r < registers; r++)
2273     {
2274         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
2275
2276         geomHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
2277     }
2278
2279     if (fragmentShader->mUsesFragCoord)
2280     {
2281         geomHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
2282     }
2283
2284     geomHLSL += "    float gl_PointSize : PSIZE;\n"
2285                 "    float4 gl_Position : SV_Position;\n"
2286                 "};\n"
2287                 "\n"
2288                 "struct GS_OUTPUT\n"
2289                 "{\n";
2290
2291     for (int r = 0; r < registers; r++)
2292     {
2293         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
2294
2295         geomHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
2296     }
2297
2298     if (fragmentShader->mUsesFragCoord)
2299     {
2300         geomHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
2301     }
2302
2303     if (fragmentShader->mUsesPointCoord)
2304     {
2305         geomHLSL += "    float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
2306     }
2307
2308     geomHLSL +=   "    float gl_PointSize : PSIZE;\n"
2309                   "    float4 gl_Position : SV_Position;\n"
2310                   "};\n"
2311                   "\n"
2312                   "static float2 pointSpriteCorners[] = \n"
2313                   "{\n"
2314                   "    float2( 0.5f, -0.5f),\n"
2315                   "    float2( 0.5f,  0.5f),\n"
2316                   "    float2(-0.5f, -0.5f),\n"
2317                   "    float2(-0.5f,  0.5f)\n"
2318                   "};\n"
2319                   "\n"
2320                   "static float2 pointSpriteTexcoords[] = \n"
2321                   "{\n"
2322                   "    float2(1.0f, 1.0f),\n"
2323                   "    float2(1.0f, 0.0f),\n"
2324                   "    float2(0.0f, 1.0f),\n"
2325                   "    float2(0.0f, 0.0f)\n"
2326                   "};\n"
2327                   "\n"
2328                   "static float minPointSize = " + str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n"
2329                   "static float maxPointSize = " + str(mRenderer->getMaxPointSize()) + ".0f;\n"
2330                   "\n"
2331                   "[maxvertexcount(4)]\n"
2332                   "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
2333                   "{\n"
2334                   "    GS_OUTPUT output = (GS_OUTPUT)0;\n"
2335                   "    output.gl_PointSize = input[0].gl_PointSize;\n";
2336
2337     for (int r = 0; r < registers; r++)
2338     {
2339         geomHLSL += "    output.v" + str(r) + " = input[0].v" + str(r) + ";\n";
2340     }
2341
2342     if (fragmentShader->mUsesFragCoord)
2343     {
2344         geomHLSL += "    output.gl_FragCoord = input[0].gl_FragCoord;\n";
2345     }
2346
2347     geomHLSL += "    \n"
2348                 "    float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n"
2349                 "    float4 gl_Position = input[0].gl_Position;\n"
2350                 "    float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n";
2351
2352     for (int corner = 0; corner < 4; corner++)
2353     {
2354         geomHLSL += "    \n"
2355                     "    output.gl_Position = gl_Position + float4(pointSpriteCorners[" + str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
2356
2357         if (fragmentShader->mUsesPointCoord)
2358         {
2359             geomHLSL += "    output.gl_PointCoord = pointSpriteTexcoords[" + str(corner) + "];\n";
2360         }
2361
2362         geomHLSL += "    outStream.Append(output);\n";
2363     }
2364
2365     geomHLSL += "    \n"
2366                 "    outStream.RestartStrip();\n"
2367                 "}\n";
2368
2369     return geomHLSL;
2370 }
2371
2372 // This method needs to match OutputHLSL::decorate
2373 std::string ProgramBinary::decorateAttribute(const std::string &name)
2374 {
2375     if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
2376     {
2377         return "_" + name;
2378     }
2379     
2380     return name;
2381 }
2382
2383 bool ProgramBinary::isValidated() const 
2384 {
2385     return mValidated;
2386 }
2387
2388 void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2389 {
2390     // Skip over inactive attributes
2391     unsigned int activeAttribute = 0;
2392     unsigned int attribute;
2393     for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2394     {
2395         if (mLinkedAttribute[attribute].name.empty())
2396         {
2397             continue;
2398         }
2399
2400         if (activeAttribute == index)
2401         {
2402             break;
2403         }
2404
2405         activeAttribute++;
2406     }
2407
2408     if (bufsize > 0)
2409     {
2410         const char *string = mLinkedAttribute[attribute].name.c_str();
2411
2412         strncpy(name, string, bufsize);
2413         name[bufsize - 1] = '\0';
2414
2415         if (length)
2416         {
2417             *length = strlen(name);
2418         }
2419     }
2420
2421     *size = 1;   // Always a single 'type' instance
2422
2423     *type = mLinkedAttribute[attribute].type;
2424 }
2425
2426 GLint ProgramBinary::getActiveAttributeCount() const
2427 {
2428     int count = 0;
2429
2430     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2431     {
2432         if (!mLinkedAttribute[attributeIndex].name.empty())
2433         {
2434             count++;
2435         }
2436     }
2437
2438     return count;
2439 }
2440
2441 GLint ProgramBinary::getActiveAttributeMaxLength() const
2442 {
2443     int maxLength = 0;
2444
2445     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
2446     {
2447         if (!mLinkedAttribute[attributeIndex].name.empty())
2448         {
2449             maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
2450         }
2451     }
2452
2453     return maxLength;
2454 }
2455
2456 void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
2457 {
2458     ASSERT(index < mUniforms.size());   // index must be smaller than getActiveUniformCount()
2459
2460     if (bufsize > 0)
2461     {
2462         std::string string = mUniforms[index]->name;
2463
2464         if (mUniforms[index]->isArray())
2465         {
2466             string += "[0]";
2467         }
2468
2469         strncpy(name, string.c_str(), bufsize);
2470         name[bufsize - 1] = '\0';
2471
2472         if (length)
2473         {
2474             *length = strlen(name);
2475         }
2476     }
2477
2478     *size = mUniforms[index]->elementCount();
2479
2480     *type = mUniforms[index]->type;
2481 }
2482
2483 GLint ProgramBinary::getActiveUniformCount() const
2484 {
2485     return mUniforms.size();
2486 }
2487
2488 GLint ProgramBinary::getActiveUniformMaxLength() const
2489 {
2490     int maxLength = 0;
2491
2492     unsigned int numUniforms = mUniforms.size();
2493     for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
2494     {
2495         if (!mUniforms[uniformIndex]->name.empty())
2496         {
2497             int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
2498             if (mUniforms[uniformIndex]->isArray())
2499             {
2500                 length += 3;  // Counting in "[0]".
2501             }
2502             maxLength = std::max(length, maxLength);
2503         }
2504     }
2505
2506     return maxLength;
2507 }
2508
2509 void ProgramBinary::validate(InfoLog &infoLog)
2510 {
2511     applyUniforms();
2512     if (!validateSamplers(&infoLog))
2513     {
2514         mValidated = false;
2515     }
2516     else
2517     {
2518         mValidated = true;
2519     }
2520 }
2521
2522 bool ProgramBinary::validateSamplers(InfoLog *infoLog)
2523 {
2524     // if any two active samplers in a program are of different types, but refer to the same
2525     // texture image unit, and this is the current program, then ValidateProgram will fail, and
2526     // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
2527
2528     const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
2529     TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
2530
2531     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
2532     {
2533         textureUnitType[i] = TEXTURE_UNKNOWN;
2534     }
2535
2536     for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
2537     {
2538         if (mSamplersPS[i].active)
2539         {
2540             unsigned int unit = mSamplersPS[i].logicalTextureUnit;
2541             
2542             if (unit >= maxCombinedTextureImageUnits)
2543             {
2544                 if (infoLog)
2545                 {
2546                     infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
2547                 }
2548
2549                 return false;
2550             }
2551
2552             if (textureUnitType[unit] != TEXTURE_UNKNOWN)
2553             {
2554                 if (mSamplersPS[i].textureType != textureUnitType[unit])
2555                 {
2556                     if (infoLog)
2557                     {
2558                         infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2559                     }
2560
2561                     return false;
2562                 }
2563             }
2564             else
2565             {
2566                 textureUnitType[unit] = mSamplersPS[i].textureType;
2567             }
2568         }
2569     }
2570
2571     for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
2572     {
2573         if (mSamplersVS[i].active)
2574         {
2575             unsigned int unit = mSamplersVS[i].logicalTextureUnit;
2576             
2577             if (unit >= maxCombinedTextureImageUnits)
2578             {
2579                 if (infoLog)
2580                 {
2581                     infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
2582                 }
2583
2584                 return false;
2585             }
2586
2587             if (textureUnitType[unit] != TEXTURE_UNKNOWN)
2588             {
2589                 if (mSamplersVS[i].textureType != textureUnitType[unit])
2590                 {
2591                     if (infoLog)
2592                     {
2593                         infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
2594                     }
2595
2596                     return false;
2597                 }
2598             }
2599             else
2600             {
2601                 textureUnitType[unit] = mSamplersVS[i].textureType;
2602             }
2603         }
2604     }
2605
2606     return true;
2607 }
2608
2609 ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
2610 {
2611 }
2612
2613 struct AttributeSorter
2614 {
2615     AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
2616         : originalIndices(semanticIndices)
2617     {
2618     }
2619
2620     bool operator()(int a, int b)
2621     {
2622         if (originalIndices[a] == -1) return false;
2623         if (originalIndices[b] == -1) return true;
2624         return (originalIndices[a] < originalIndices[b]);
2625     }
2626
2627     const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
2628 };
2629
2630 void ProgramBinary::initAttributesByLayout()
2631 {
2632     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2633     {
2634         mAttributesByLayout[i] = i;
2635     }
2636
2637     std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
2638 }
2639
2640 void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
2641 {
2642     rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
2643
2644     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2645     {
2646         oldTranslatedAttributes[i] = attributes[i];
2647     }
2648
2649     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2650     {
2651         int oldIndex = mAttributesByLayout[i];
2652         sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
2653         attributes[i] = oldTranslatedAttributes[oldIndex];
2654     }
2655 }
2656
2657 }