Implemented support for DX11 driver uniforms by assigning fixed register slots.

TRAC #22369
Signed-off-by: Daniel Koch
Signed-off-by: Geoff Lang
Author: Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1682 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/common/version.h b/src/common/version.h
index dd6867c..bbcc4f0 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
 #define MAJOR_VERSION 1
 #define MINOR_VERSION 1
 #define BUILD_VERSION 0
-#define BUILD_REVISION 1565
+#define BUILD_REVISION 1643
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 33bda05..0a54952 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -90,7 +90,15 @@
 
     mExcessiveLoopIndex = NULL;
 
-    mUniformRegister = 0;
+    if (mContext.shaderType == SH_FRAGMENT_SHADER)
+    {
+        mUniformRegister = 3;   // Reserve registers for dx_DepthRange, dx_Coord and dx_DepthFront
+    }
+    else
+    {
+        mUniformRegister = 2;   // Reserve registers for dx_DepthRange and dx_HalfPixelSize
+    }
+
     mSamplerRegister = 0;
 }
 
@@ -199,12 +207,12 @@
 
         if (mUsesFragCoord)
         {
-            out << "uniform float4 dx_Coord : register(" + dx_RegisterString(GL_FLOAT_VEC4, "dx_Coord") + ");\n";
+            out << "uniform float4 dx_Coord : register(c1);\n";
         }
 
         if (mUsesFragCoord || mUsesFrontFacing)
         {
-            out << "uniform float3 dx_DepthFront : register(" + dx_RegisterString(GL_FLOAT_VEC3, "dx_DepthFront") + ");\n";
+            out << "uniform float3 dx_DepthFront : register(c2);\n";
         }
         
         out << "\n";
@@ -357,7 +365,7 @@
                "// Varyings\n";
         out <<  varyings;
         out << "\n"
-               "uniform float2 dx_HalfPixelSize : register(" + dx_RegisterString(GL_FLOAT_VEC2, "dx_HalfPixelSize") + ");\n"
+               "uniform float2 dx_HalfPixelSize : register(c1);\n"
                "\n";
         out <<  uniforms;
         out << "\n";
@@ -456,7 +464,7 @@
                "    float diff;\n"
                "};\n"
                "\n"
-               "uniform float3 dx_DepthRange : register(" + dx_RegisterString(GL_FLOAT_VEC3, "dx_DepthRange") + ");"
+               "uniform float3 dx_DepthRange : register(c0);"
                "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
                "\n";
     }
@@ -2609,17 +2617,6 @@
     return "c" + str(uniformRegister(operand));
 }
 
-TString OutputHLSL::dx_RegisterString(GLenum type, const char *name)
-{
-    ASSERT(type >= GL_FLOAT_VEC2 && type <= GL_FLOAT_VEC4);   // Only single (uniform) registers handled
-    int index = mUniformRegister;
-    mUniformRegister += 1;
-
-    mActiveUniforms.push_back(Uniform(type, name, 0, index));
-
-    return "c" + str(index);
-}
-
 int OutputHLSL::samplerRegister(TIntermSymbol *sampler)
 {
     const TType &type = sampler->getType();
diff --git a/src/compiler/OutputHLSL.h b/src/compiler/OutputHLSL.h
index b87fec3..704fc16 100644
--- a/src/compiler/OutputHLSL.h
+++ b/src/compiler/OutputHLSL.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -158,7 +158,6 @@
     int mSamplerRegister;
 
     TString registerString(TIntermSymbol *operand);
-    TString dx_RegisterString(GLenum type, const char *name);
     int samplerRegister(TIntermSymbol *sampler);
     int uniformRegister(TIntermSymbol *uniform);
     void declareUniform(const TType &type, const TString &name, int index);
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index f7e3785..e29b449 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -61,12 +61,6 @@
 
     mUsedVertexSamplerRange = 0;
     mUsedPixelSamplerRange = 0;
-
-    mDxDepthRangeRegisterVS = -1;
-    mDxDepthRangeRegisterPS = -1;
-    mDxDepthFrontRegister = -1;
-    mDxCoordRegister = -1;
-    mDxHalfPixelSizeRegister = -1;
 }
 
 ProgramBinary::~ProgramBinary()
@@ -1008,7 +1002,7 @@
         }
     }
 
-    mRenderer->applyUniforms(&mUniforms);
+    mRenderer->applyUniforms(&mUniforms, mVertexConstants, mPixelConstants);
 }
 
 // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
@@ -1609,12 +1603,6 @@
         stream.read(&mUniformIndex[i].index);
     }
 
-    stream.read(&mDxDepthRangeRegisterVS);
-    stream.read(&mDxDepthRangeRegisterPS);
-    stream.read(&mDxDepthFrontRegister);
-    stream.read(&mDxCoordRegister);
-    stream.read(&mDxHalfPixelSizeRegister);
-
     unsigned int pixelShaderSize;
     stream.read(&pixelShaderSize);
 
@@ -1714,12 +1702,6 @@
         stream.write(mUniformIndex[i].index);
     }
 
-    stream.write(mDxDepthRangeRegisterVS);
-    stream.write(mDxDepthRangeRegisterPS);
-    stream.write(mDxDepthFrontRegister);
-    stream.write(mDxCoordRegister);
-    stream.write(mDxHalfPixelSizeRegister);
-
     UINT pixelShaderSize = mPixelExecutable->getLength();
     stream.write(pixelShaderSize);
 
@@ -1926,31 +1908,6 @@
 
 bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog)
 {
-    if (constant.name == "dx_DepthRange")
-    {
-        if (shader == GL_VERTEX_SHADER)   mDxDepthRangeRegisterVS = constant.registerIndex;
-        if (shader == GL_FRAGMENT_SHADER) mDxDepthRangeRegisterPS = constant.registerIndex;
-        return true;
-    }
-
-    if (constant.name == "dx_DepthFront")
-    {
-        mDxDepthFrontRegister = constant.registerIndex;
-        return true;
-    }
-
-    if (constant.name == "dx_Coord")
-    {
-        mDxCoordRegister = constant.registerIndex;
-        return true;
-    }
-
-    if (constant.name == "dx_HalfPixelSize")
-    {
-        mDxHalfPixelSizeRegister = constant.registerIndex;
-        return true;
-    }
-
     if (constant.type == GL_SAMPLER_2D ||
         constant.type == GL_SAMPLER_CUBE)
     {
@@ -2284,56 +2241,34 @@
 
 void ProgramBinary::applyDxDepthRange(float near, float far, float diff)
 {
-    if (dynamic_cast<rx::Renderer9*>(mRenderer) == NULL) return;   // UNIMPLEMENTED
-    IDirect3DDevice9 *device = rx::Renderer9::makeRenderer9(mRenderer)->getDevice();   // D3D9_REPLACE
+    mVertexConstants.depthRange[0] = near;
+    mVertexConstants.depthRange[1] = far;
+    mVertexConstants.depthRange[2] = diff;
 
-    if (mDxDepthRangeRegisterVS >= 0)
-    {
-        float nearFarDiff[4] = {near, far, diff};
-        device->SetVertexShaderConstantF(mDxDepthRangeRegisterVS, nearFarDiff, 1);
-    }
-
-    if (mDxDepthRangeRegisterPS >= 0)
-    {
-        float nearFarDiff[4] = {near, far, diff};
-        device->SetPixelShaderConstantF(mDxDepthRangeRegisterPS, nearFarDiff, 1);
-    }
+    mPixelConstants.depthRange[0] = near;
+    mPixelConstants.depthRange[1] = far;
+    mPixelConstants.depthRange[2] = diff;
 }
 
 void ProgramBinary::applyDxDepthFront(float range, float start, float frontCCW)
 {
-    if (mDxDepthFrontRegister >= 0)
-    {
-        if (dynamic_cast<rx::Renderer9*>(mRenderer) == NULL) return;   // UNIMPLEMENTED
-        IDirect3DDevice9 *device = rx::Renderer9::makeRenderer9(mRenderer)->getDevice();   // D3D9_REPLACE
-    
-        GLfloat dz[4] = {range, start, frontCCW};
-        device->SetPixelShaderConstantF(mDxDepthFrontRegister, dz, 1);
-    }
+    mPixelConstants.depthFront[0] = range;
+    mPixelConstants.depthFront[1] = start;
+    mPixelConstants.depthFront[2] = frontCCW;
 }
 
 void ProgramBinary::applyDxCoord(float halfWidth, float halfHeight, float x0, float y0)
 {
-    if (mDxCoordRegister >= 0)
-    {
-        if (dynamic_cast<rx::Renderer9*>(mRenderer) == NULL) return;   // UNIMPLEMENTED
-        IDirect3DDevice9 *device = rx::Renderer9::makeRenderer9(mRenderer)->getDevice();   // D3D9_REPLACE
-    
-        GLfloat whxy[4] = {halfWidth,halfHeight, x0, y0};
-        device->SetPixelShaderConstantF(mDxCoordRegister, whxy, 1);
-    }
+    mPixelConstants.coord[0] = halfWidth;
+    mPixelConstants.coord[1] = halfHeight;
+    mPixelConstants.coord[2] = x0;
+    mPixelConstants.coord[3] = y0;
 }
 
 void ProgramBinary::applyDxHalfPixelSize(float width, float height)
 {
-    if (mDxHalfPixelSizeRegister >= 0)
-    {
-        if (dynamic_cast<rx::Renderer9*>(mRenderer) == NULL) return;   // UNIMPLEMENTED
-        IDirect3DDevice9 *device = rx::Renderer9::makeRenderer9(mRenderer)->getDevice();   // D3D9_REPLACE
-    
-        GLfloat xy[4] = {width, height};
-        device->SetVertexShaderConstantF(mDxHalfPixelSizeRegister, xy, 1);
-    }
+    mVertexConstants.halfPixelSize[0] = width;
+    mVertexConstants.halfPixelSize[1] = height;
 }
 
 ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index 9fae582..2f910fd 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -147,11 +147,8 @@
     typedef std::vector<UniformLocation> UniformIndex;
     UniformIndex mUniformIndex;
 
-    int mDxDepthRangeRegisterVS;
-    int mDxDepthRangeRegisterPS;
-    int mDxDepthFrontRegister;
-    int mDxCoordRegister;
-    int mDxHalfPixelSizeRegister;
+    rx::dx_VertexConstants mVertexConstants;
+    rx::dx_PixelConstants mPixelConstants;
 
     bool mValidated;
 
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 7e6fc19..dab8d3b 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -67,6 +67,19 @@
     bool    fastConfig;
 };
 
+struct dx_VertexConstants
+{
+    float depthRange[4];
+    float halfPixelSize[4];
+};
+
+struct dx_PixelConstants
+{
+    float depthRange[4];
+    float coord[4];
+    float depthFront[4];
+};
+
 class Renderer
 {
   public:
@@ -98,7 +111,7 @@
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
     virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
-    virtual void applyUniforms(const gl::UniformArray *uniformArray) = 0;
+    virtual void applyUniforms(const gl::UniformArray *uniformArray, const dx_VertexConstants &vertexConstants, const dx_PixelConstants &pixelConstants) = 0;
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0;
     virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 18a5c1e..5857c60 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -867,7 +867,7 @@
     }
 }
 
-void Renderer11::applyUniforms(const gl::UniformArray *uniformArray)
+void Renderer11::applyUniforms(const gl::UniformArray *uniformArray, const dx_VertexConstants &vertexConstants, const dx_PixelConstants &pixelConstants)
 {
     D3D11_BUFFER_DESC constantBufferDescription = {0};
     constantBufferDescription.ByteWidth = D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * sizeof(float[4]);
@@ -940,6 +940,10 @@
         }
     }
 
+    // Driver uniforms
+    memcpy(cVS, &vertexConstants, sizeof(dx_VertexConstants));
+    memcpy(cPS, &pixelConstants, sizeof(dx_PixelConstants));
+
     mDeviceContext->Unmap(constantBufferVS, 0);
     mDeviceContext->VSSetConstantBuffers(0, 1, &constantBufferVS);
     constantBufferVS->Release();
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index d7ab8f5..8957ca4 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -67,7 +67,7 @@
     virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
     virtual void applyShaders(gl::ProgramBinary *programBinary);
-    virtual void applyUniforms(const gl::UniformArray *uniformArray);
+    virtual void applyUniforms(const gl::UniformArray *uniformArray, const dx_VertexConstants &vertexConstants, const dx_PixelConstants &pixelConstants);
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
     virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
 
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 1405e2f..4df6dae 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1561,7 +1561,7 @@
     }
 }
 
-void Renderer9::applyUniforms(const gl::UniformArray *uniformArray)
+void Renderer9::applyUniforms(const gl::UniformArray *uniformArray, const dx_VertexConstants &vertexConstants, const dx_PixelConstants &pixelConstants)
 {
     for (std::vector<gl::Uniform*>::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub)
     {
@@ -1601,6 +1601,10 @@
             targetUniform->dirty = false;
         }
     }
+
+    // Driver uniforms
+    mDevice->SetVertexShaderConstantF(0, (float*)&vertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4]));
+    mDevice->SetPixelShaderConstantF(0, (float*)&pixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4]));
 }
 
 void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index a14ba12..2e535aa 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -90,7 +90,7 @@
 
     virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
     virtual void applyShaders(gl::ProgramBinary *programBinary);
-    virtual void applyUniforms(const gl::UniformArray *uniformArray);
+    virtual void applyUniforms(const gl::UniformArray *uniformArray, const dx_VertexConstants &vertexConstants, const dx_PixelConstants &pixelConstants);
     virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
     virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
     virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);