gfx/angle/src/libGLESv2/ProgramBinary.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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 //
     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.
    11 #include "libGLESv2/BinaryStream.h"
    12 #include "libGLESv2/ProgramBinary.h"
    13 #include "libGLESv2/renderer/ShaderExecutable.h"
    15 #include "common/debug.h"
    16 #include "common/version.h"
    17 #include "utilities.h"
    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"
    25 #include <algorithm>
    27 #undef near
    28 #undef far
    30 namespace gl
    31 {
    32 std::string str(int i)
    33 {
    34     char buffer[20];
    35     snprintf(buffer, sizeof(buffer), "%d", i);
    36     return buffer;
    37 }
    39 UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) 
    40     : name(name), element(element), index(index)
    41 {
    42 }
    44 unsigned int ProgramBinary::mCurrentSerial = 1;
    46 ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefCountObject(0), mSerial(issueSerial())
    47 {
    48     mPixelExecutable = NULL;
    49     mVertexExecutable = NULL;
    50     mGeometryExecutable = NULL;
    52     mValidated = false;
    54     for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
    55     {
    56         mSemanticIndex[index] = -1;
    57     }
    59     for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
    60     {
    61         mSamplersPS[index].active = false;
    62     }
    64     for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
    65     {
    66         mSamplersVS[index].active = false;
    67     }
    69     mUsedVertexSamplerRange = 0;
    70     mUsedPixelSamplerRange = 0;
    71     mUsesPointSize = false;
    72 }
    74 ProgramBinary::~ProgramBinary()
    75 {
    76     delete mPixelExecutable;
    77     mPixelExecutable = NULL;
    79     delete mVertexExecutable;
    80     mVertexExecutable = NULL;
    82     delete mGeometryExecutable;
    83     mGeometryExecutable = NULL;
    85     while (!mUniforms.empty())
    86     {
    87         delete mUniforms.back();
    88         mUniforms.pop_back();
    89     }
    90 }
    92 unsigned int ProgramBinary::getSerial() const
    93 {
    94     return mSerial;
    95 }
    97 unsigned int ProgramBinary::issueSerial()
    98 {
    99     return mCurrentSerial++;
   100 }
   102 rx::ShaderExecutable *ProgramBinary::getPixelExecutable()
   103 {
   104     return mPixelExecutable;
   105 }
   107 rx::ShaderExecutable *ProgramBinary::getVertexExecutable()
   108 {
   109     return mVertexExecutable;
   110 }
   112 rx::ShaderExecutable *ProgramBinary::getGeometryExecutable()
   113 {
   114     return mGeometryExecutable;
   115 }
   117 GLuint ProgramBinary::getAttributeLocation(const char *name)
   118 {
   119     if (name)
   120     {
   121         for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
   122         {
   123             if (mLinkedAttribute[index].name == std::string(name))
   124             {
   125                 return index;
   126             }
   127         }
   128     }
   130     return -1;
   131 }
   133 int ProgramBinary::getSemanticIndex(int attributeIndex)
   134 {
   135     ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
   137     return mSemanticIndex[attributeIndex];
   138 }
   140 // Returns one more than the highest sampler index used.
   141 GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
   142 {
   143     switch (type)
   144     {
   145       case SAMPLER_PIXEL:
   146         return mUsedPixelSamplerRange;
   147       case SAMPLER_VERTEX:
   148         return mUsedVertexSamplerRange;
   149       default:
   150         UNREACHABLE();
   151         return 0;
   152     }
   153 }
   155 bool ProgramBinary::usesPointSize() const
   156 {
   157     return mUsesPointSize;
   158 }
   160 bool ProgramBinary::usesPointSpriteEmulation() const
   161 {
   162     return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
   163 }
   165 bool ProgramBinary::usesGeometryShader() const
   166 {
   167     return usesPointSpriteEmulation();
   168 }
   170 // Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
   171 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
   172 GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
   173 {
   174     GLint logicalTextureUnit = -1;
   176     switch (type)
   177     {
   178       case SAMPLER_PIXEL:
   179         ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
   181         if (mSamplersPS[samplerIndex].active)
   182         {
   183             logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
   184         }
   185         break;
   186       case SAMPLER_VERTEX:
   187         ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
   189         if (mSamplersVS[samplerIndex].active)
   190         {
   191             logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
   192         }
   193         break;
   194       default: UNREACHABLE();
   195     }
   197     if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
   198     {
   199         return logicalTextureUnit;
   200     }
   202     return -1;
   203 }
   205 // Returns the texture type for a given Direct3D 9 sampler type and
   206 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
   207 TextureType ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
   208 {
   209     switch (type)
   210     {
   211       case SAMPLER_PIXEL:
   212         ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0]));
   213         ASSERT(mSamplersPS[samplerIndex].active);
   214         return mSamplersPS[samplerIndex].textureType;
   215       case SAMPLER_VERTEX:
   216         ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0]));
   217         ASSERT(mSamplersVS[samplerIndex].active);
   218         return mSamplersVS[samplerIndex].textureType;
   219       default: UNREACHABLE();
   220     }
   222     return TEXTURE_2D;
   223 }
   225 GLint ProgramBinary::getUniformLocation(std::string name)
   226 {
   227     unsigned int subscript = 0;
   229     // Strip any trailing array operator and retrieve the subscript
   230     size_t open = name.find_last_of('[');
   231     size_t close = name.find_last_of(']');
   232     if (open != std::string::npos && close == name.length() - 1)
   233     {
   234         subscript = atoi(name.substr(open + 1).c_str());
   235         name.erase(open);
   236     }
   238     unsigned int numUniforms = mUniformIndex.size();
   239     for (unsigned int location = 0; location < numUniforms; location++)
   240     {
   241         if (mUniformIndex[location].name == name &&
   242             mUniformIndex[location].element == subscript)
   243         {
   244             return location;
   245         }
   246     }
   248     return -1;
   249 }
   251 bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
   252 {
   253     if (location < 0 || location >= (int)mUniformIndex.size())
   254     {
   255         return false;
   256     }
   258     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   259     targetUniform->dirty = true;
   261     int elementCount = targetUniform->elementCount();
   263     if (elementCount == 1 && count > 1)
   264         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   266     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   268     if (targetUniform->type == GL_FLOAT)
   269     {
   270         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
   272         for (int i = 0; i < count; i++)
   273         {
   274             target[0] = v[0];
   275             target[1] = 0;
   276             target[2] = 0;
   277             target[3] = 0;
   278             target += 4;
   279             v += 1;
   280         }
   281     }
   282     else if (targetUniform->type == GL_BOOL)
   283     {
   284         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   286         for (int i = 0; i < count; i++)
   287         {
   288             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
   289             boolParams[1] = GL_FALSE;
   290             boolParams[2] = GL_FALSE;
   291             boolParams[3] = GL_FALSE;
   292             boolParams += 4;
   293             v += 1;
   294         }
   295     }
   296     else
   297     {
   298         return false;
   299     }
   301     return true;
   302 }
   304 bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
   305 {
   306     if (location < 0 || location >= (int)mUniformIndex.size())
   307     {
   308         return false;
   309     }
   311     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   312     targetUniform->dirty = true;
   314     int elementCount = targetUniform->elementCount();
   316     if (elementCount == 1 && count > 1)
   317         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   319     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   321     if (targetUniform->type == GL_FLOAT_VEC2)
   322     {
   323         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
   325         for (int i = 0; i < count; i++)
   326         {
   327             target[0] = v[0];
   328             target[1] = v[1];
   329             target[2] = 0;
   330             target[3] = 0;
   331             target += 4;
   332             v += 2;
   333         }
   334     }
   335     else if (targetUniform->type == GL_BOOL_VEC2)
   336     {
   337         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   339         for (int i = 0; i < count; i++)
   340         {
   341             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
   342             boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
   343             boolParams[2] = GL_FALSE;
   344             boolParams[3] = GL_FALSE;
   345             boolParams += 4;
   346             v += 2;
   347         }
   348     }
   349     else 
   350     {
   351         return false;
   352     }
   354     return true;
   355 }
   357 bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
   358 {
   359     if (location < 0 || location >= (int)mUniformIndex.size())
   360     {
   361         return false;
   362     }
   364     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   365     targetUniform->dirty = true;
   367     int elementCount = targetUniform->elementCount();
   369     if (elementCount == 1 && count > 1)
   370         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   372     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   374     if (targetUniform->type == GL_FLOAT_VEC3)
   375     {
   376         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
   378         for (int i = 0; i < count; i++)
   379         {
   380             target[0] = v[0];
   381             target[1] = v[1];
   382             target[2] = v[2];
   383             target[3] = 0;
   384             target += 4;
   385             v += 3;
   386         }
   387     }
   388     else if (targetUniform->type == GL_BOOL_VEC3)
   389     {
   390         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   392         for (int i = 0; i < count; i++)
   393         {
   394             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
   395             boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
   396             boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
   397             boolParams[3] = GL_FALSE;
   398             boolParams += 4;
   399             v += 3;
   400         }
   401     }
   402     else 
   403     {
   404         return false;
   405     }
   407     return true;
   408 }
   410 bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
   411 {
   412     if (location < 0 || location >= (int)mUniformIndex.size())
   413     {
   414         return false;
   415     }
   417     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   418     targetUniform->dirty = true;
   420     int elementCount = targetUniform->elementCount();
   422     if (elementCount == 1 && count > 1)
   423         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   425     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   427     if (targetUniform->type == GL_FLOAT_VEC4)
   428     {
   429         GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
   431         for (int i = 0; i < count; i++)
   432         {
   433             target[0] = v[0];
   434             target[1] = v[1];
   435             target[2] = v[2];
   436             target[3] = v[3];
   437             target += 4;
   438             v += 4;
   439         }
   440     }
   441     else if (targetUniform->type == GL_BOOL_VEC4)
   442     {
   443         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   445         for (int i = 0; i < count; i++)
   446         {
   447             boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
   448             boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
   449             boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
   450             boolParams[3] = (v[3] == 0.0f) ? GL_FALSE : GL_TRUE;
   451             boolParams += 4;
   452             v += 4;
   453         }
   454     }
   455     else 
   456     {
   457         return false;
   458     }
   460     return true;
   461 }
   463 template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight>
   464 void transposeMatrix(T *target, const GLfloat *value)
   465 {
   466     int copyWidth = std::min(targetWidth, srcWidth);
   467     int copyHeight = std::min(targetHeight, srcHeight);
   469     for (int x = 0; x < copyWidth; x++)
   470     {
   471         for (int y = 0; y < copyHeight; y++)
   472         {
   473             target[x * targetWidth + y] = (T)value[y * srcWidth + x];
   474         }
   475     }
   476     // clear unfilled right side
   477     for (int y = 0; y < copyHeight; y++)
   478     {
   479         for (int x = srcWidth; x < targetWidth; x++)
   480         {
   481             target[y * targetWidth + x] = (T)0;
   482         }
   483     }
   484     // clear unfilled bottom.
   485     for (int y = srcHeight; y < targetHeight; y++)
   486     {
   487         for (int x = 0; x < targetWidth; x++)
   488         {
   489             target[y * targetWidth + x] = (T)0;
   490         }
   491     }
   492 }
   494 bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value)
   495 {
   496     if (location < 0 || location >= (int)mUniformIndex.size())
   497     {
   498         return false;
   499     }
   501     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   502     targetUniform->dirty = true;
   504     if (targetUniform->type != GL_FLOAT_MAT2)
   505     {
   506         return false;
   507     }
   509     int elementCount = targetUniform->elementCount();
   511     if (elementCount == 1 && count > 1)
   512         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   514     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   515     GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8;
   517     for (int i = 0; i < count; i++)
   518     {
   519         transposeMatrix<GLfloat,4,2,2,2>(target, value);
   520         target += 8;
   521         value += 4;
   522     }
   524     return true;
   525 }
   527 bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value)
   528 {
   529     if (location < 0 || location >= (int)mUniformIndex.size())
   530     {
   531         return false;
   532     }
   534     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   535     targetUniform->dirty = true;
   537     if (targetUniform->type != GL_FLOAT_MAT3)
   538     {
   539         return false;
   540     }
   542     int elementCount = targetUniform->elementCount();
   544     if (elementCount == 1 && count > 1)
   545         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   547     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   548     GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12;
   550     for (int i = 0; i < count; i++)
   551     {
   552         transposeMatrix<GLfloat,4,3,3,3>(target, value);
   553         target += 12;
   554         value += 9;
   555     }
   557     return true;
   558 }
   561 bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value)
   562 {
   563     if (location < 0 || location >= (int)mUniformIndex.size())
   564     {
   565         return false;
   566     }
   568     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   569     targetUniform->dirty = true;
   571     if (targetUniform->type != GL_FLOAT_MAT4)
   572     {
   573         return false;
   574     }
   576     int elementCount = targetUniform->elementCount();
   578     if (elementCount == 1 && count > 1)
   579         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   581     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   582     GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16);
   584     for (int i = 0; i < count; i++)
   585     {
   586         transposeMatrix<GLfloat,4,4,4,4>(target, value);
   587         target += 16;
   588         value += 16;
   589     }
   591     return true;
   592 }
   594 bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
   595 {
   596     if (location < 0 || location >= (int)mUniformIndex.size())
   597     {
   598         return false;
   599     }
   601     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   602     targetUniform->dirty = true;
   604     int elementCount = targetUniform->elementCount();
   606     if (elementCount == 1 && count > 1)
   607         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   609     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   611     if (targetUniform->type == GL_INT ||
   612         targetUniform->type == GL_SAMPLER_2D ||
   613         targetUniform->type == GL_SAMPLER_CUBE)
   614     {
   615         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   617         for (int i = 0; i < count; i++)
   618         {
   619             target[0] = v[0];
   620             target[1] = 0;
   621             target[2] = 0;
   622             target[3] = 0;
   623             target += 4;
   624             v += 1;
   625         }
   626     }
   627     else if (targetUniform->type == GL_BOOL)
   628     {
   629         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   631         for (int i = 0; i < count; i++)
   632         {
   633             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
   634             boolParams[1] = GL_FALSE;
   635             boolParams[2] = GL_FALSE;
   636             boolParams[3] = GL_FALSE;
   637             boolParams += 4;
   638             v += 1;
   639         }
   640     }
   641     else
   642     {
   643         return false;
   644     }
   646     return true;
   647 }
   649 bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
   650 {
   651     if (location < 0 || location >= (int)mUniformIndex.size())
   652     {
   653         return false;
   654     }
   656     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   657     targetUniform->dirty = true;
   659     int elementCount = targetUniform->elementCount();
   661     if (elementCount == 1 && count > 1)
   662         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   664     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   666     if (targetUniform->type == GL_INT_VEC2)
   667     {
   668         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   670         for (int i = 0; i < count; i++)
   671         {
   672             target[0] = v[0];
   673             target[1] = v[1];
   674             target[2] = 0;
   675             target[3] = 0;
   676             target += 4;
   677             v += 2;
   678         }
   679     }
   680     else if (targetUniform->type == GL_BOOL_VEC2)
   681     {
   682         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   684         for (int i = 0; i < count; i++)
   685         {
   686             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
   687             boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
   688             boolParams[2] = GL_FALSE;
   689             boolParams[3] = GL_FALSE;
   690             boolParams += 4;
   691             v += 2;
   692         }
   693     }
   694     else
   695     {
   696         return false;
   697     }
   699     return true;
   700 }
   702 bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
   703 {
   704     if (location < 0 || location >= (int)mUniformIndex.size())
   705     {
   706         return false;
   707     }
   709     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   710     targetUniform->dirty = true;
   712     int elementCount = targetUniform->elementCount();
   714     if (elementCount == 1 && count > 1)
   715         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   717     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   719     if (targetUniform->type == GL_INT_VEC3)
   720     {
   721         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   723         for (int i = 0; i < count; i++)
   724         {
   725             target[0] = v[0];
   726             target[1] = v[1];
   727             target[2] = v[2];
   728             target[3] = 0;
   729             target += 4;
   730             v += 3;
   731         }
   732     }
   733     else if (targetUniform->type == GL_BOOL_VEC3)
   734     {
   735         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   737         for (int i = 0; i < count; i++)
   738         {
   739             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
   740             boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
   741             boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
   742             boolParams[3] = GL_FALSE;
   743             boolParams += 4;
   744             v += 3;
   745         }
   746     }
   747     else
   748     {
   749         return false;
   750     }
   752     return true;
   753 }
   755 bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
   756 {
   757     if (location < 0 || location >= (int)mUniformIndex.size())
   758     {
   759         return false;
   760     }
   762     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   763     targetUniform->dirty = true;
   765     int elementCount = targetUniform->elementCount();
   767     if (elementCount == 1 && count > 1)
   768         return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
   770     count = std::min(elementCount - (int)mUniformIndex[location].element, count);
   772     if (targetUniform->type == GL_INT_VEC4)
   773     {
   774         GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   776         for (int i = 0; i < count; i++)
   777         {
   778             target[0] = v[0];
   779             target[1] = v[1];
   780             target[2] = v[2];
   781             target[3] = v[3];
   782             target += 4;
   783             v += 4;
   784         }
   785     }
   786     else if (targetUniform->type == GL_BOOL_VEC4)
   787     {
   788         GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   790         for (int i = 0; i < count; i++)
   791         {
   792             boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
   793             boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
   794             boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
   795             boolParams[3] = (v[3] == 0) ? GL_FALSE : GL_TRUE;
   796             boolParams += 4;
   797             v += 4;
   798         }
   799     }
   800     else
   801     {
   802         return false;
   803     }
   805     return true;
   806 }
   808 bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
   809 {
   810     if (location < 0 || location >= (int)mUniformIndex.size())
   811     {
   812         return false;
   813     }
   815     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   817     // sized queries -- ensure the provided buffer is large enough
   818     if (bufSize)
   819     {
   820         int requiredBytes = UniformExternalSize(targetUniform->type);
   821         if (*bufSize < requiredBytes)
   822         {
   823             return false;
   824         }
   825     }
   827     switch (targetUniform->type)
   828     {
   829       case GL_FLOAT_MAT2:
   830         transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
   831         break;
   832       case GL_FLOAT_MAT3:
   833         transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
   834         break;
   835       case GL_FLOAT_MAT4:
   836         transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
   837         break;
   838       default:
   839         {
   840             unsigned int size = UniformComponentCount(targetUniform->type);
   842             switch (UniformComponentType(targetUniform->type))
   843             {
   844               case GL_BOOL:
   845                 {
   846                     GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   848                     for (unsigned int i = 0; i < size; i++)
   849                     {
   850                         params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
   851                     }
   852                 }
   853                 break;
   854               case GL_FLOAT:
   855                 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLfloat),
   856                        size * sizeof(GLfloat));
   857                 break;
   858               case GL_INT:
   859                 {
   860                     GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   862                     for (unsigned int i = 0; i < size; i++)
   863                     {
   864                         params[i] = (float)intParams[i];
   865                     }
   866                 }
   867                 break;
   868               default: UNREACHABLE();
   869             }
   870         }
   871     }
   873     return true;
   874 }
   876 bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
   877 {
   878     if (location < 0 || location >= (int)mUniformIndex.size())
   879     {
   880         return false;
   881     }
   883     Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
   885     // sized queries -- ensure the provided buffer is large enough
   886     if (bufSize)
   887     {
   888         int requiredBytes = UniformExternalSize(targetUniform->type);
   889         if (*bufSize < requiredBytes)
   890         {
   891             return false;
   892         }
   893     }
   895     switch (targetUniform->type)
   896     {
   897       case GL_FLOAT_MAT2:
   898         transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
   899         break;
   900       case GL_FLOAT_MAT3:
   901         transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
   902         break;
   903       case GL_FLOAT_MAT4:
   904         transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
   905         break;
   906       default:
   907         {
   908             unsigned int size = VariableColumnCount(targetUniform->type);
   910             switch (UniformComponentType(targetUniform->type))
   911             {
   912               case GL_BOOL:
   913                 {
   914                     GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
   916                     for (unsigned int i = 0; i < size; i++)
   917                     {
   918                         params[i] = boolParams[i];
   919                     }
   920                 }
   921                 break;
   922               case GL_FLOAT:
   923                 {
   924                     GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
   926                     for (unsigned int i = 0; i < size; i++)
   927                     {
   928                         params[i] = (GLint)floatParams[i];
   929                     }
   930                 }
   931                 break;
   932               case GL_INT:
   933                 memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLint),
   934                     size * sizeof(GLint));
   935                 break;
   936               default: UNREACHABLE();
   937             }
   938         }
   939     }
   941     return true;
   942 }
   944 void ProgramBinary::dirtyAllUniforms()
   945 {
   946     unsigned int numUniforms = mUniforms.size();
   947     for (unsigned int index = 0; index < numUniforms; index++)
   948     {
   949         mUniforms[index]->dirty = true;
   950     }
   951 }
   953 // Applies all the uniforms set for this program object to the renderer
   954 void ProgramBinary::applyUniforms()
   955 {
   956     // Retrieve sampler uniform values
   957     for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub)
   958     {
   959         Uniform *targetUniform = *ub;
   961         if (targetUniform->dirty)
   962         {
   963             if (targetUniform->type == GL_SAMPLER_2D || 
   964                 targetUniform->type == GL_SAMPLER_CUBE)
   965             {
   966                 int count = targetUniform->elementCount();
   967                 GLint (*v)[4] = (GLint(*)[4])targetUniform->data;
   969                 if (targetUniform->psRegisterIndex >= 0)
   970                 {
   971                     unsigned int firstIndex = targetUniform->psRegisterIndex;
   973                     for (int i = 0; i < count; i++)
   974                     {
   975                         unsigned int samplerIndex = firstIndex + i;
   977                         if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
   978                         {
   979                             ASSERT(mSamplersPS[samplerIndex].active);
   980                             mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
   981                         }
   982                     }
   983                 }
   985                 if (targetUniform->vsRegisterIndex >= 0)
   986                 {
   987                     unsigned int firstIndex = targetUniform->vsRegisterIndex;
   989                     for (int i = 0; i < count; i++)
   990                     {
   991                         unsigned int samplerIndex = firstIndex + i;
   993                         if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
   994                         {
   995                             ASSERT(mSamplersVS[samplerIndex].active);
   996                             mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
   997                         }
   998                     }
   999                 }
  1004     mRenderer->applyUniforms(this, &mUniforms);
  1007 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
  1008 // Returns the number of used varying registers, or -1 if unsuccesful
  1009 int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)
  1011     const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
  1013     fragmentShader->resetVaryingsRegisterAssignment();
  1015     for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
  1017         int n = VariableRowCount(varying->type) * varying->size;
  1018         int m = VariableColumnCount(varying->type);
  1019         bool success = false;
  1021         if (m == 2 || m == 3 || m == 4)
  1023             for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
  1025                 bool available = true;
  1027                 for (int y = 0; y < n && available; y++)
  1029                     for (int x = 0; x < m && available; x++)
  1031                         if (packing[r + y][x])
  1033                             available = false;
  1038                 if (available)
  1040                     varying->reg = r;
  1041                     varying->col = 0;
  1043                     for (int y = 0; y < n; y++)
  1045                         for (int x = 0; x < m; x++)
  1047                             packing[r + y][x] = &*varying;
  1051                     success = true;
  1055             if (!success && m == 2)
  1057                 for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
  1059                     bool available = true;
  1061                     for (int y = 0; y < n && available; y++)
  1063                         for (int x = 2; x < 4 && available; x++)
  1065                             if (packing[r + y][x])
  1067                                 available = false;
  1072                     if (available)
  1074                         varying->reg = r;
  1075                         varying->col = 2;
  1077                         for (int y = 0; y < n; y++)
  1079                             for (int x = 2; x < 4; x++)
  1081                                 packing[r + y][x] = &*varying;
  1085                         success = true;
  1090         else if (m == 1)
  1092             int space[4] = {0};
  1094             for (int y = 0; y < maxVaryingVectors; y++)
  1096                 for (int x = 0; x < 4; x++)
  1098                     space[x] += packing[y][x] ? 0 : 1;
  1102             int column = 0;
  1104             for (int x = 0; x < 4; x++)
  1106                 if (space[x] >= n && space[x] < space[column])
  1108                     column = x;
  1112             if (space[column] >= n)
  1114                 for (int r = 0; r < maxVaryingVectors; r++)
  1116                     if (!packing[r][column])
  1118                         varying->reg = r;
  1120                         for (int y = r; y < r + n; y++)
  1122                             packing[y][column] = &*varying;
  1125                         break;
  1129                 varying->col = column;
  1131                 success = true;
  1134         else UNREACHABLE();
  1136         if (!success)
  1138             infoLog.append("Could not pack varying %s", varying->name.c_str());
  1140             return -1;
  1144     // Return the number of used registers
  1145     int registers = 0;
  1147     for (int r = 0; r < maxVaryingVectors; r++)
  1149         if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
  1151             registers++;
  1155     return registers;
  1158 bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4],
  1159                                  std::string& pixelHLSL, std::string& vertexHLSL,
  1160                                  FragmentShader *fragmentShader, VertexShader *vertexShader)
  1162     if (pixelHLSL.empty() || vertexHLSL.empty())
  1164         return false;
  1167     bool usesMRT = fragmentShader->mUsesMultipleRenderTargets;
  1168     bool usesFragColor = fragmentShader->mUsesFragColor;
  1169     bool usesFragData = fragmentShader->mUsesFragData;
  1170     if (usesFragColor && usesFragData)
  1172         infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
  1173         return false;
  1176     // Write the HLSL input/output declarations
  1177     const int shaderModel = mRenderer->getMajorShaderModel();
  1178     const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
  1180     const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0);
  1182     // The output color is broadcast to all enabled draw buffers when writing to gl_FragColor 
  1183     const bool broadcast = fragmentShader->mUsesFragColor;
  1184     const unsigned int numRenderTargets = (broadcast || usesMRT ? mRenderer->getMaxRenderTargets() : 1);
  1186     if (registersNeeded > maxVaryingVectors)
  1188         infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
  1190         return false;
  1193     vertexShader->resetVaryingsRegisterAssignment();
  1195     for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++)
  1197         bool matched = false;
  1199         for (VaryingList::iterator output = vertexShader->mVaryings.begin(); output != vertexShader->mVaryings.end(); output++)
  1201             if (output->name == input->name)
  1203                 if (output->type != input->type || output->size != input->size)
  1205                     infoLog.append("Type of vertex varying %s does not match that of the fragment varying", output->name.c_str());
  1207                     return false;
  1210                 output->reg = input->reg;
  1211                 output->col = input->col;
  1213                 matched = true;
  1214                 break;
  1218         if (!matched)
  1220             infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
  1222             return false;
  1226     mUsesPointSize = vertexShader->mUsesPointSize;
  1227     std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD";
  1228     std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR";
  1229     std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION";
  1230     std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
  1232     // special varyings that use reserved registers
  1233     int reservedRegisterIndex = registers;
  1234     std::string fragCoordSemantic;
  1235     std::string pointCoordSemantic;
  1237     if (fragmentShader->mUsesFragCoord)
  1239         fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
  1242     if (fragmentShader->mUsesPointCoord)
  1244         // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords.
  1245         // In DX11 we compute this in the GS.
  1246         if (shaderModel == 3)
  1248             pointCoordSemantic = "TEXCOORD0";
  1250         else if (shaderModel >= 4)
  1252             pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++); 
  1256     vertexHLSL += "struct VS_INPUT\n"
  1257                   "{\n";
  1259     int semanticIndex = 0;
  1260     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
  1262         switch (attribute->type)
  1264           case GL_FLOAT:      vertexHLSL += "    float ";    break;
  1265           case GL_FLOAT_VEC2: vertexHLSL += "    float2 ";   break;
  1266           case GL_FLOAT_VEC3: vertexHLSL += "    float3 ";   break;
  1267           case GL_FLOAT_VEC4: vertexHLSL += "    float4 ";   break;
  1268           case GL_FLOAT_MAT2: vertexHLSL += "    float2x2 "; break;
  1269           case GL_FLOAT_MAT3: vertexHLSL += "    float3x3 "; break;
  1270           case GL_FLOAT_MAT4: vertexHLSL += "    float4x4 "; break;
  1271           default:  UNREACHABLE();
  1274         vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
  1276         semanticIndex += VariableRowCount(attribute->type);
  1279     vertexHLSL += "};\n"
  1280                   "\n"
  1281                   "struct VS_OUTPUT\n"
  1282                   "{\n";
  1284     if (shaderModel < 4)
  1286         vertexHLSL += "    float4 gl_Position : " + positionSemantic + ";\n";
  1289     for (int r = 0; r < registers; r++)
  1291         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
  1293         vertexHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
  1296     if (fragmentShader->mUsesFragCoord)
  1298         vertexHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
  1301     if (vertexShader->mUsesPointSize && shaderModel >= 3)
  1303         vertexHLSL += "    float gl_PointSize : PSIZE;\n";
  1306     if (shaderModel >= 4)
  1308         vertexHLSL += "    float4 gl_Position : " + positionSemantic + ";\n";
  1311     vertexHLSL += "};\n"
  1312                   "\n"
  1313                   "VS_OUTPUT main(VS_INPUT input)\n"
  1314                   "{\n";
  1316     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
  1318         vertexHLSL += "    " + decorateAttribute(attribute->name) + " = ";
  1320         if (VariableRowCount(attribute->type) > 1)   // Matrix
  1322             vertexHLSL += "transpose";
  1325         vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
  1328     if (shaderModel >= 4)
  1330         vertexHLSL += "\n"
  1331                       "    gl_main();\n"
  1332                       "\n"
  1333                       "    VS_OUTPUT output;\n"
  1334                       "    output.gl_Position.x = gl_Position.x;\n"
  1335                       "    output.gl_Position.y = -gl_Position.y;\n"
  1336                       "    output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
  1337                       "    output.gl_Position.w = gl_Position.w;\n";
  1339     else
  1341         vertexHLSL += "\n"
  1342                       "    gl_main();\n"
  1343                       "\n"
  1344                       "    VS_OUTPUT output;\n"
  1345                       "    output.gl_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
  1346                       "    output.gl_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"
  1347                       "    output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
  1348                       "    output.gl_Position.w = gl_Position.w;\n";
  1351     if (vertexShader->mUsesPointSize && shaderModel >= 3)
  1353         vertexHLSL += "    output.gl_PointSize = gl_PointSize;\n";
  1356     if (fragmentShader->mUsesFragCoord)
  1358         vertexHLSL += "    output.gl_FragCoord = gl_Position;\n";
  1361     for (VaryingList::iterator varying = vertexShader->mVaryings.begin(); varying != vertexShader->mVaryings.end(); varying++)
  1363         if (varying->reg >= 0)
  1365             for (int i = 0; i < varying->size; i++)
  1367                 int rows = VariableRowCount(varying->type);
  1369                 for (int j = 0; j < rows; j++)
  1371                     int r = varying->reg + i * rows + j;
  1372                     vertexHLSL += "    output.v" + str(r);
  1374                     bool sharedRegister = false;   // Register used by multiple varyings
  1376                     for (int x = 0; x < 4; x++)
  1378                         if (packing[r][x] && packing[r][x] != packing[r][0])
  1380                             sharedRegister = true;
  1381                             break;
  1385                     if(sharedRegister)
  1387                         vertexHLSL += ".";
  1389                         for (int x = 0; x < 4; x++)
  1391                             if (packing[r][x] == &*varying)
  1393                                 switch(x)
  1395                                   case 0: vertexHLSL += "x"; break;
  1396                                   case 1: vertexHLSL += "y"; break;
  1397                                   case 2: vertexHLSL += "z"; break;
  1398                                   case 3: vertexHLSL += "w"; break;
  1404                     vertexHLSL += " = " + varying->name;
  1406                     if (varying->array)
  1408                         vertexHLSL += "[" + str(i) + "]";
  1411                     if (rows > 1)
  1413                         vertexHLSL += "[" + str(j) + "]";
  1416                     vertexHLSL += ";\n";
  1422     vertexHLSL += "\n"
  1423                   "    return output;\n"
  1424                   "}\n";
  1426     pixelHLSL += "struct PS_INPUT\n"
  1427                  "{\n";
  1429     for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
  1431         if (varying->reg >= 0)
  1433             for (int i = 0; i < varying->size; i++)
  1435                 int rows = VariableRowCount(varying->type);
  1436                 for (int j = 0; j < rows; j++)
  1438                     std::string n = str(varying->reg + i * rows + j);
  1439                     pixelHLSL += "    float" + str(VariableColumnCount(varying->type)) + " v" + n + " : " + varyingSemantic + n + ";\n";
  1443         else UNREACHABLE();
  1446     if (fragmentShader->mUsesFragCoord)
  1448         pixelHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
  1451     if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
  1453         pixelHLSL += "    float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
  1456     // Must consume the PSIZE element if the geometry shader is not active
  1457     // We won't know if we use a GS until we draw
  1458     if (vertexShader->mUsesPointSize && shaderModel >= 4)
  1460         pixelHLSL += "    float gl_PointSize : PSIZE;\n";
  1463     if (fragmentShader->mUsesFragCoord)
  1465         if (shaderModel >= 4)
  1467             pixelHLSL += "    float4 dx_VPos : SV_Position;\n";
  1469         else if (shaderModel >= 3)
  1471             pixelHLSL += "    float2 dx_VPos : VPOS;\n";
  1475     pixelHLSL += "};\n"
  1476                  "\n"
  1477                  "struct PS_OUTPUT\n"
  1478                  "{\n";
  1480     for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
  1482         pixelHLSL += "    float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n";
  1485     if (fragmentShader->mUsesFragDepth)
  1487         pixelHLSL += "    float gl_Depth : " + depthSemantic + ";\n";
  1490     pixelHLSL += "};\n"
  1491                  "\n";
  1493     if (fragmentShader->mUsesFrontFacing)
  1495         if (shaderModel >= 4)
  1497             pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n"
  1498                          "{\n";
  1500         else
  1502             pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n"
  1503                          "{\n";
  1506     else
  1508         pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n"
  1509                      "{\n";
  1512     if (fragmentShader->mUsesFragCoord)
  1514         pixelHLSL += "    float rhw = 1.0 / input.gl_FragCoord.w;\n";
  1516         if (shaderModel >= 4)
  1518             pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x;\n"
  1519                          "    gl_FragCoord.y = input.dx_VPos.y;\n";
  1521         else if (shaderModel >= 3)
  1523             pixelHLSL += "    gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
  1524                          "    gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
  1526         else
  1528             // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport()
  1529             pixelHLSL += "    gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n"
  1530                          "    gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n";
  1533         pixelHLSL += "    gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n"
  1534                      "    gl_FragCoord.w = rhw;\n";
  1537     if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
  1539         pixelHLSL += "    gl_PointCoord.x = input.gl_PointCoord.x;\n";
  1540         pixelHLSL += "    gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
  1543     if (fragmentShader->mUsesFrontFacing)
  1545         if (shaderModel <= 3)
  1547             pixelHLSL += "    gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n";
  1549         else
  1551             pixelHLSL += "    gl_FrontFacing = isFrontFace;\n";
  1555     for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
  1557         if (varying->reg >= 0)
  1559             for (int i = 0; i < varying->size; i++)
  1561                 int rows = VariableRowCount(varying->type);
  1562                 for (int j = 0; j < rows; j++)
  1564                     std::string n = str(varying->reg + i * rows + j);
  1565                     pixelHLSL += "    " + varying->name;
  1567                     if (varying->array)
  1569                         pixelHLSL += "[" + str(i) + "]";
  1572                     if (rows > 1)
  1574                         pixelHLSL += "[" + str(j) + "]";
  1577                     switch (VariableColumnCount(varying->type))
  1579                       case 1: pixelHLSL += " = input.v" + n + ".x;\n";   break;
  1580                       case 2: pixelHLSL += " = input.v" + n + ".xy;\n";  break;
  1581                       case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break;
  1582                       case 4: pixelHLSL += " = input.v" + n + ";\n";     break;
  1583                       default: UNREACHABLE();
  1588         else UNREACHABLE();
  1591     pixelHLSL += "\n"
  1592                  "    gl_main();\n"
  1593                  "\n"
  1594                  "    PS_OUTPUT output;\n";
  1596     for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++)
  1598         unsigned int sourceColorIndex = broadcast ? 0 : renderTargetIndex;
  1600         pixelHLSL += "    output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n";
  1603     if (fragmentShader->mUsesFragDepth)
  1605         pixelHLSL += "    output.gl_Depth = gl_Depth;\n";
  1608     pixelHLSL += "\n"
  1609                  "    return output;\n"
  1610                  "}\n";
  1612     return true;
  1615 bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
  1617     BinaryInputStream stream(binary, length);
  1619     int format = 0;
  1620     stream.read(&format);
  1621     if (format != GL_PROGRAM_BINARY_ANGLE)
  1623         infoLog.append("Invalid program binary format.");
  1624         return false;
  1627     int version = 0;
  1628     stream.read(&version);
  1629     if (version != VERSION_DWORD)
  1631         infoLog.append("Invalid program binary version.");
  1632         return false;
  1635     int compileFlags = 0;
  1636     stream.read(&compileFlags);
  1637     if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
  1639         infoLog.append("Mismatched compilation flags.");
  1640         return false;
  1643     for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
  1645         stream.read(&mLinkedAttribute[i].type);
  1646         std::string name;
  1647         stream.read(&name);
  1648         mLinkedAttribute[i].name = name;
  1649         stream.read(&mSemanticIndex[i]);
  1652     for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
  1654         stream.read(&mSamplersPS[i].active);
  1655         stream.read(&mSamplersPS[i].logicalTextureUnit);
  1657         int textureType;
  1658         stream.read(&textureType);
  1659         mSamplersPS[i].textureType = (TextureType) textureType;
  1662     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
  1664         stream.read(&mSamplersVS[i].active);
  1665         stream.read(&mSamplersVS[i].logicalTextureUnit);
  1667         int textureType;
  1668         stream.read(&textureType);
  1669         mSamplersVS[i].textureType = (TextureType) textureType;
  1672     stream.read(&mUsedVertexSamplerRange);
  1673     stream.read(&mUsedPixelSamplerRange);
  1674     stream.read(&mUsesPointSize);
  1676     size_t size;
  1677     stream.read(&size);
  1678     if (stream.error())
  1680         infoLog.append("Invalid program binary.");
  1681         return false;
  1684     mUniforms.resize(size);
  1685     for (unsigned int i = 0; i < size; ++i)
  1687         GLenum type;
  1688         GLenum precision;
  1689         std::string name;
  1690         unsigned int arraySize;
  1692         stream.read(&type);
  1693         stream.read(&precision);
  1694         stream.read(&name);
  1695         stream.read(&arraySize);
  1697         mUniforms[i] = new Uniform(type, precision, name, arraySize);
  1699         stream.read(&mUniforms[i]->psRegisterIndex);
  1700         stream.read(&mUniforms[i]->vsRegisterIndex);
  1701         stream.read(&mUniforms[i]->registerCount);
  1704     stream.read(&size);
  1705     if (stream.error())
  1707         infoLog.append("Invalid program binary.");
  1708         return false;
  1711     mUniformIndex.resize(size);
  1712     for (unsigned int i = 0; i < size; ++i)
  1714         stream.read(&mUniformIndex[i].name);
  1715         stream.read(&mUniformIndex[i].element);
  1716         stream.read(&mUniformIndex[i].index);
  1719     unsigned int pixelShaderSize;
  1720     stream.read(&pixelShaderSize);
  1722     unsigned int vertexShaderSize;
  1723     stream.read(&vertexShaderSize);
  1725     unsigned int geometryShaderSize;
  1726     stream.read(&geometryShaderSize);
  1728     const char *ptr = (const char*) binary + stream.offset();
  1730     const GUID *binaryIdentifier = (const GUID *) ptr;
  1731     ptr += sizeof(GUID);
  1733     GUID identifier = mRenderer->getAdapterIdentifier();
  1734     if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
  1736         infoLog.append("Invalid program binary.");
  1737         return false;
  1740     const char *pixelShaderFunction = ptr;
  1741     ptr += pixelShaderSize;
  1743     const char *vertexShaderFunction = ptr;
  1744     ptr += vertexShaderSize;
  1746     const char *geometryShaderFunction = geometryShaderSize > 0 ? ptr : NULL;
  1747     ptr += geometryShaderSize;
  1749     mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
  1750                                                  pixelShaderSize, rx::SHADER_PIXEL);
  1751     if (!mPixelExecutable)
  1753         infoLog.append("Could not create pixel shader.");
  1754         return false;
  1757     mVertexExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
  1758                                                   vertexShaderSize, rx::SHADER_VERTEX);
  1759     if (!mVertexExecutable)
  1761         infoLog.append("Could not create vertex shader.");
  1762         delete mPixelExecutable;
  1763         mPixelExecutable = NULL;
  1764         return false;
  1767     if (geometryShaderFunction != NULL && geometryShaderSize > 0)
  1769         mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
  1770                                                         geometryShaderSize, rx::SHADER_GEOMETRY);
  1771         if (!mGeometryExecutable)
  1773             infoLog.append("Could not create geometry shader.");
  1774             delete mPixelExecutable;
  1775             mPixelExecutable = NULL;
  1776             delete mVertexExecutable;
  1777             mVertexExecutable = NULL;
  1778             return false;
  1781     else
  1783         mGeometryExecutable = NULL;
  1786     return true;
  1789 bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
  1791     BinaryOutputStream stream;
  1793     stream.write(GL_PROGRAM_BINARY_ANGLE);
  1794     stream.write(VERSION_DWORD);
  1795     stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
  1797     for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
  1799         stream.write(mLinkedAttribute[i].type);
  1800         stream.write(mLinkedAttribute[i].name);
  1801         stream.write(mSemanticIndex[i]);
  1804     for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i)
  1806         stream.write(mSamplersPS[i].active);
  1807         stream.write(mSamplersPS[i].logicalTextureUnit);
  1808         stream.write((int) mSamplersPS[i].textureType);
  1811     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
  1813         stream.write(mSamplersVS[i].active);
  1814         stream.write(mSamplersVS[i].logicalTextureUnit);
  1815         stream.write((int) mSamplersVS[i].textureType);
  1818     stream.write(mUsedVertexSamplerRange);
  1819     stream.write(mUsedPixelSamplerRange);
  1820     stream.write(mUsesPointSize);
  1822     stream.write(mUniforms.size());
  1823     for (unsigned int i = 0; i < mUniforms.size(); ++i)
  1825         stream.write(mUniforms[i]->type);
  1826         stream.write(mUniforms[i]->precision);
  1827         stream.write(mUniforms[i]->name);
  1828         stream.write(mUniforms[i]->arraySize);
  1830         stream.write(mUniforms[i]->psRegisterIndex);
  1831         stream.write(mUniforms[i]->vsRegisterIndex);
  1832         stream.write(mUniforms[i]->registerCount);
  1835     stream.write(mUniformIndex.size());
  1836     for (unsigned int i = 0; i < mUniformIndex.size(); ++i)
  1838         stream.write(mUniformIndex[i].name);
  1839         stream.write(mUniformIndex[i].element);
  1840         stream.write(mUniformIndex[i].index);
  1843     UINT pixelShaderSize = mPixelExecutable->getLength();
  1844     stream.write(pixelShaderSize);
  1846     UINT vertexShaderSize = mVertexExecutable->getLength();
  1847     stream.write(vertexShaderSize);
  1849     UINT geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
  1850     stream.write(geometryShaderSize);
  1852     GUID identifier = mRenderer->getAdapterIdentifier();
  1854     GLsizei streamLength = stream.length();
  1855     const void *streamData = stream.data();
  1857     GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize + geometryShaderSize;
  1858     if (totalLength > bufSize)
  1860         if (length)
  1862             *length = 0;
  1865         return false;
  1868     if (binary)
  1870         char *ptr = (char*) binary;
  1872         memcpy(ptr, streamData, streamLength);
  1873         ptr += streamLength;
  1875         memcpy(ptr, &identifier, sizeof(GUID));
  1876         ptr += sizeof(GUID);
  1878         memcpy(ptr, mPixelExecutable->getFunction(), pixelShaderSize);
  1879         ptr += pixelShaderSize;
  1881         memcpy(ptr, mVertexExecutable->getFunction(), vertexShaderSize);
  1882         ptr += vertexShaderSize;
  1884         if (mGeometryExecutable != NULL && geometryShaderSize > 0)
  1886             memcpy(ptr, mGeometryExecutable->getFunction(), geometryShaderSize);
  1887             ptr += geometryShaderSize;
  1890         ASSERT(ptr - totalLength == binary);
  1893     if (length)
  1895         *length = totalLength;
  1898     return true;
  1901 GLint ProgramBinary::getLength()
  1903     GLint length;
  1904     if (save(NULL, INT_MAX, &length))
  1906         return length;
  1908     else
  1910         return 0;
  1914 bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
  1916     if (!fragmentShader || !fragmentShader->isCompiled())
  1918         return false;
  1921     if (!vertexShader || !vertexShader->isCompiled())
  1923         return false;
  1926     std::string pixelHLSL = fragmentShader->getHLSL();
  1927     std::string vertexHLSL = vertexShader->getHLSL();
  1929     // Map the varyings to the register file
  1930     const Varying *packing[IMPLEMENTATION_MAX_VARYING_VECTORS][4] = {NULL};
  1931     int registers = packVaryings(infoLog, packing, fragmentShader);
  1933     if (registers < 0)
  1935         return false;
  1938     if (!linkVaryings(infoLog, registers, packing, pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
  1940         return false;
  1943     bool success = true;
  1945     if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
  1947         success = false;
  1950     if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms()))
  1952         success = false;
  1955     // special case for gl_DepthRange, the only built-in uniform (also a struct)
  1956     if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange)
  1958         mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0));
  1959         mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0));
  1960         mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0));
  1963     if (success)
  1965         mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX);
  1966         mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL);
  1968         if (usesGeometryShader())
  1970             std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader);
  1971             mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY);
  1974         if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
  1976             infoLog.append("Failed to create D3D shaders.");
  1977             success = false;
  1979             delete mVertexExecutable;
  1980             mVertexExecutable = NULL;
  1981             delete mPixelExecutable;
  1982             mPixelExecutable = NULL;
  1983             delete mGeometryExecutable;
  1984             mGeometryExecutable = NULL;
  1988     return success;
  1991 // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
  1992 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
  1994     unsigned int usedLocations = 0;
  1996     // Link attributes that have a binding location
  1997     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
  1999         int location = attributeBindings.getAttributeBinding(attribute->name);
  2001         if (location != -1)   // Set by glBindAttribLocation
  2003             if (!mLinkedAttribute[location].name.empty())
  2005                 // Multiple active attributes bound to the same location; not an error
  2008             mLinkedAttribute[location] = *attribute;
  2010             int rows = VariableRowCount(attribute->type);
  2012             if (rows + location > MAX_VERTEX_ATTRIBS)
  2014                 infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
  2016                 return false;
  2019             for (int i = 0; i < rows; i++)
  2021                 usedLocations |= 1 << (location + i);
  2026     // Link attributes that don't have a binding location
  2027     for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
  2029         int location = attributeBindings.getAttributeBinding(attribute->name);
  2031         if (location == -1)   // Not set by glBindAttribLocation
  2033             int rows = VariableRowCount(attribute->type);
  2034             int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
  2036             if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
  2038                 infoLog.append("Too many active attributes (%s)", attribute->name.c_str());
  2040                 return false;   // Fail to link
  2043             mLinkedAttribute[availableIndex] = *attribute;
  2047     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
  2049         int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
  2050         int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1);
  2052         for (int r = 0; r < rows; r++)
  2054             mSemanticIndex[attributeIndex++] = index++;
  2058     return true;
  2061 bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms)
  2063     for (sh::ActiveUniforms::const_iterator uniform = vertexUniforms.begin(); uniform != vertexUniforms.end(); uniform++)
  2065         if (!defineUniform(GL_VERTEX_SHADER, *uniform, infoLog))
  2067             return false;
  2071     for (sh::ActiveUniforms::const_iterator uniform = fragmentUniforms.begin(); uniform != fragmentUniforms.end(); uniform++)
  2073         if (!defineUniform(GL_FRAGMENT_SHADER, *uniform, infoLog))
  2075             return false;
  2079     return true;
  2082 bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog)
  2084     if (constant.type == GL_SAMPLER_2D ||
  2085         constant.type == GL_SAMPLER_CUBE)
  2087         unsigned int samplerIndex = constant.registerIndex;
  2089         do
  2091             if (shader == GL_VERTEX_SHADER)
  2093                 if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits())
  2095                     mSamplersVS[samplerIndex].active = true;
  2096                     mSamplersVS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
  2097                     mSamplersVS[samplerIndex].logicalTextureUnit = 0;
  2098                     mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
  2100                 else
  2102                     infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", mRenderer->getMaxVertexTextureImageUnits());
  2103                     return false;
  2106             else if (shader == GL_FRAGMENT_SHADER)
  2108                 if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
  2110                     mSamplersPS[samplerIndex].active = true;
  2111                     mSamplersPS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
  2112                     mSamplersPS[samplerIndex].logicalTextureUnit = 0;
  2113                     mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
  2115                 else
  2117                     infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
  2118                     return false;
  2121             else UNREACHABLE();
  2123             samplerIndex++;
  2125         while (samplerIndex < constant.registerIndex + constant.arraySize);
  2128     Uniform *uniform = NULL;
  2129     GLint location = getUniformLocation(constant.name);
  2131     if (location >= 0)   // Previously defined, type and precision must match
  2133         uniform = mUniforms[mUniformIndex[location].index];
  2135         if (uniform->type != constant.type)
  2137             infoLog.append("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
  2138             return false;
  2141         if (uniform->precision != constant.precision)
  2143             infoLog.append("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
  2144             return false;
  2147     else
  2149         uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize);
  2152     if (!uniform)
  2154         return false;
  2157     if (shader == GL_FRAGMENT_SHADER)
  2159         uniform->psRegisterIndex = constant.registerIndex;
  2161     else if (shader == GL_VERTEX_SHADER)
  2163         uniform->vsRegisterIndex = constant.registerIndex;
  2165     else UNREACHABLE();
  2167     if (location >= 0)
  2169         return uniform->type == constant.type;
  2172     mUniforms.push_back(uniform);
  2173     unsigned int uniformIndex = mUniforms.size() - 1;
  2175     for (unsigned int i = 0; i < uniform->elementCount(); i++)
  2177         mUniformIndex.push_back(UniformLocation(constant.name, i, uniformIndex));
  2180     if (shader == GL_VERTEX_SHADER)
  2182         if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedVertexUniformVectors() + mRenderer->getMaxVertexUniformVectors())
  2184             infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", mRenderer->getMaxVertexUniformVectors());
  2185             return false;
  2188     else if (shader == GL_FRAGMENT_SHADER)
  2190         if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedFragmentUniformVectors() + mRenderer->getMaxFragmentUniformVectors())
  2192             infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", mRenderer->getMaxFragmentUniformVectors());
  2193             return false;
  2196     else UNREACHABLE();
  2198     return true;
  2201 std::string ProgramBinary::generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const
  2203     // for now we only handle point sprite emulation
  2204     ASSERT(usesPointSpriteEmulation());
  2205     return generatePointSpriteHLSL(registers, packing, fragmentShader, vertexShader);
  2208 std::string ProgramBinary::generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const
  2210     ASSERT(registers >= 0);
  2211     ASSERT(vertexShader->mUsesPointSize);
  2212     ASSERT(mRenderer->getMajorShaderModel() >= 4);
  2214     std::string geomHLSL;
  2216     std::string varyingSemantic = "TEXCOORD";
  2218     std::string fragCoordSemantic;
  2219     std::string pointCoordSemantic;
  2221     int reservedRegisterIndex = registers;
  2223     if (fragmentShader->mUsesFragCoord)
  2225         fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
  2228     if (fragmentShader->mUsesPointCoord)
  2230         pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
  2233     geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n"
  2234                 "\n"
  2235                 "struct GS_INPUT\n"
  2236                 "{\n";
  2238     for (int r = 0; r < registers; r++)
  2240         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
  2242         geomHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
  2245     if (fragmentShader->mUsesFragCoord)
  2247         geomHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
  2250     geomHLSL += "    float gl_PointSize : PSIZE;\n"
  2251                 "    float4 gl_Position : SV_Position;\n"
  2252                 "};\n"
  2253                 "\n"
  2254                 "struct GS_OUTPUT\n"
  2255                 "{\n";
  2257     for (int r = 0; r < registers; r++)
  2259         int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
  2261         geomHLSL += "    float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
  2264     if (fragmentShader->mUsesFragCoord)
  2266         geomHLSL += "    float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
  2269     if (fragmentShader->mUsesPointCoord)
  2271         geomHLSL += "    float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
  2274     geomHLSL +=   "    float gl_PointSize : PSIZE;\n"
  2275                   "    float4 gl_Position : SV_Position;\n"
  2276                   "};\n"
  2277                   "\n"
  2278                   "static float2 pointSpriteCorners[] = \n"
  2279                   "{\n"
  2280                   "    float2( 0.5f, -0.5f),\n"
  2281                   "    float2( 0.5f,  0.5f),\n"
  2282                   "    float2(-0.5f, -0.5f),\n"
  2283                   "    float2(-0.5f,  0.5f)\n"
  2284                   "};\n"
  2285                   "\n"
  2286                   "static float2 pointSpriteTexcoords[] = \n"
  2287                   "{\n"
  2288                   "    float2(1.0f, 1.0f),\n"
  2289                   "    float2(1.0f, 0.0f),\n"
  2290                   "    float2(0.0f, 1.0f),\n"
  2291                   "    float2(0.0f, 0.0f)\n"
  2292                   "};\n"
  2293                   "\n"
  2294                   "static float minPointSize = " + str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n"
  2295                   "static float maxPointSize = " + str(mRenderer->getMaxPointSize()) + ".0f;\n"
  2296                   "\n"
  2297                   "[maxvertexcount(4)]\n"
  2298                   "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
  2299                   "{\n"
  2300                   "    GS_OUTPUT output = (GS_OUTPUT)0;\n"
  2301                   "    output.gl_PointSize = input[0].gl_PointSize;\n";
  2303     for (int r = 0; r < registers; r++)
  2305         geomHLSL += "    output.v" + str(r) + " = input[0].v" + str(r) + ";\n";
  2308     if (fragmentShader->mUsesFragCoord)
  2310         geomHLSL += "    output.gl_FragCoord = input[0].gl_FragCoord;\n";
  2313     geomHLSL += "    \n"
  2314                 "    float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n"
  2315                 "    float4 gl_Position = input[0].gl_Position;\n"
  2316                 "    float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n";
  2318     for (int corner = 0; corner < 4; corner++)
  2320         geomHLSL += "    \n"
  2321                     "    output.gl_Position = gl_Position + float4(pointSpriteCorners[" + str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
  2323         if (fragmentShader->mUsesPointCoord)
  2325             geomHLSL += "    output.gl_PointCoord = pointSpriteTexcoords[" + str(corner) + "];\n";
  2328         geomHLSL += "    outStream.Append(output);\n";
  2331     geomHLSL += "    \n"
  2332                 "    outStream.RestartStrip();\n"
  2333                 "}\n";
  2335     return geomHLSL;
  2338 // This method needs to match OutputHLSL::decorate
  2339 std::string ProgramBinary::decorateAttribute(const std::string &name)
  2341     if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
  2343         return "_" + name;
  2346     return name;
  2349 bool ProgramBinary::isValidated() const 
  2351     return mValidated;
  2354 void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
  2356     // Skip over inactive attributes
  2357     unsigned int activeAttribute = 0;
  2358     unsigned int attribute;
  2359     for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
  2361         if (mLinkedAttribute[attribute].name.empty())
  2363             continue;
  2366         if (activeAttribute == index)
  2368             break;
  2371         activeAttribute++;
  2374     if (bufsize > 0)
  2376         const char *string = mLinkedAttribute[attribute].name.c_str();
  2378         strncpy(name, string, bufsize);
  2379         name[bufsize - 1] = '\0';
  2381         if (length)
  2383             *length = strlen(name);
  2387     *size = 1;   // Always a single 'type' instance
  2389     *type = mLinkedAttribute[attribute].type;
  2392 GLint ProgramBinary::getActiveAttributeCount() const
  2394     int count = 0;
  2396     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
  2398         if (!mLinkedAttribute[attributeIndex].name.empty())
  2400             count++;
  2404     return count;
  2407 GLint ProgramBinary::getActiveAttributeMaxLength() const
  2409     int maxLength = 0;
  2411     for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
  2413         if (!mLinkedAttribute[attributeIndex].name.empty())
  2415             maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
  2419     return maxLength;
  2422 void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
  2424     ASSERT(index < mUniforms.size());   // index must be smaller than getActiveUniformCount()
  2426     if (bufsize > 0)
  2428         std::string string = mUniforms[index]->name;
  2430         if (mUniforms[index]->isArray())
  2432             string += "[0]";
  2435         strncpy(name, string.c_str(), bufsize);
  2436         name[bufsize - 1] = '\0';
  2438         if (length)
  2440             *length = strlen(name);
  2444     *size = mUniforms[index]->elementCount();
  2446     *type = mUniforms[index]->type;
  2449 GLint ProgramBinary::getActiveUniformCount() const
  2451     return mUniforms.size();
  2454 GLint ProgramBinary::getActiveUniformMaxLength() const
  2456     int maxLength = 0;
  2458     unsigned int numUniforms = mUniforms.size();
  2459     for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
  2461         if (!mUniforms[uniformIndex]->name.empty())
  2463             int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
  2464             if (mUniforms[uniformIndex]->isArray())
  2466                 length += 3;  // Counting in "[0]".
  2468             maxLength = std::max(length, maxLength);
  2472     return maxLength;
  2475 void ProgramBinary::validate(InfoLog &infoLog)
  2477     applyUniforms();
  2478     if (!validateSamplers(&infoLog))
  2480         mValidated = false;
  2482     else
  2484         mValidated = true;
  2488 bool ProgramBinary::validateSamplers(InfoLog *infoLog)
  2490     // if any two active samplers in a program are of different types, but refer to the same
  2491     // texture image unit, and this is the current program, then ValidateProgram will fail, and
  2492     // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
  2494     const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
  2495     TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
  2497     for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
  2499         textureUnitType[i] = TEXTURE_UNKNOWN;
  2502     for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
  2504         if (mSamplersPS[i].active)
  2506             unsigned int unit = mSamplersPS[i].logicalTextureUnit;
  2508             if (unit >= maxCombinedTextureImageUnits)
  2510                 if (infoLog)
  2512                     infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
  2515                 return false;
  2518             if (textureUnitType[unit] != TEXTURE_UNKNOWN)
  2520                 if (mSamplersPS[i].textureType != textureUnitType[unit])
  2522                     if (infoLog)
  2524                         infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
  2527                     return false;
  2530             else
  2532                 textureUnitType[unit] = mSamplersPS[i].textureType;
  2537     for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
  2539         if (mSamplersVS[i].active)
  2541             unsigned int unit = mSamplersVS[i].logicalTextureUnit;
  2543             if (unit >= maxCombinedTextureImageUnits)
  2545                 if (infoLog)
  2547                     infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
  2550                 return false;
  2553             if (textureUnitType[unit] != TEXTURE_UNKNOWN)
  2555                 if (mSamplersVS[i].textureType != textureUnitType[unit])
  2557                     if (infoLog)
  2559                         infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
  2562                     return false;
  2565             else
  2567                 textureUnitType[unit] = mSamplersVS[i].textureType;
  2572     return true;
  2575 ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
  2579 struct AttributeSorter
  2581     AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
  2582         : originalIndices(semanticIndices)
  2584         for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
  2586             indices[i] = i;
  2589         std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this);
  2592     bool operator()(int a, int b)
  2594         return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b];
  2597     int indices[MAX_VERTEX_ATTRIBS];
  2598     const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
  2599 };
  2601 void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
  2603     AttributeSorter sorter(mSemanticIndex);
  2605     int oldIndices[MAX_VERTEX_ATTRIBS];
  2606     rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
  2608     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
  2610         oldIndices[i] = mSemanticIndex[i];
  2611         oldTranslatedAttributes[i] = attributes[i];
  2614     for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
  2616         int oldIndex = sorter.indices[i];
  2617         sortedSemanticIndices[i] = oldIndices[oldIndex];
  2618         attributes[i] = oldTranslatedAttributes[oldIndex];

mercurial