Added support for vertex texure fetch in DX11 mode.

Trac #22354

Signed-off-by: Geoff Lang
Signed-off-by: Shannon Woods
Author: Jamie Madill

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1757 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 19dae91..0ed3064 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -207,7 +207,7 @@
 
     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
     {
-        for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++)
+        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
         {
             mState.samplerTexture[type][sampler].set(NULL);
         }
@@ -1269,7 +1269,7 @@
       case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = gl::MAX_VERTEX_UNIFORM_VECTORS;       break;
       case GL_MAX_VARYING_VECTORS:              *params = getMaximumVaryingVectors();           break;
       case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = getMaximumCombinedTextureImageUnits(); break;
-      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = getMaximumVertexTextureImageUnits();  break;
+      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = mRenderer->getMaxVertexTextureImageUnits(); break;
       case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = gl::MAX_TEXTURE_IMAGE_UNITS;          break;
       case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = getMaximumFragmentUniformVectors();   break;
       case GL_MAX_RENDERBUFFER_SIZE:            *params = getMaximumRenderbufferDimension();    break;
@@ -1776,7 +1776,8 @@
 {
     ProgramBinary *programBinary = getCurrentProgramBinary();
 
-    int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF;   // Range of Direct3D 9 samplers of given sampler type
+    // Range of Direct3D samplers of given sampler type
+    int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
     int samplerRange = programBinary->getUsedSamplerRange(type);
 
     for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
@@ -2128,14 +2129,9 @@
     return mMajorShaderModel >= 3 ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
 }
 
-unsigned int Context::getMaximumVertexTextureImageUnits() const
-{
-    return mSupportsVertexTexture ? MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF : 0;
-}
-
 unsigned int Context::getMaximumCombinedTextureImageUnits() const
 {
-    return MAX_TEXTURE_IMAGE_UNITS + getMaximumVertexTextureImageUnits();
+    return MAX_TEXTURE_IMAGE_UNITS + mRenderer->getMaxVertexTextureImageUnits();
 }
 
 int Context::getMaximumFragmentUniformVectors() const
@@ -2321,7 +2317,7 @@
 
     for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
     {
-        for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++)
+        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
         {
             if (mState.samplerTexture[type][sampler].id() == texture)
             {
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index d9727dc..f8b4c25 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -65,8 +65,12 @@
     MAX_VARYING_VECTORS_SM2 = 8,
     MAX_VARYING_VECTORS_SM3 = 10,
     MAX_TEXTURE_IMAGE_UNITS = 16,
-    MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF = 4,   // For devices supporting vertex texture fetch
-    MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF,    
+
+    // Implementation upper limit, for devices supporting vertex texture fetch. 
+    // Real limit depends on the shader model
+    IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16,
+    IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS,    
+
     MAX_FRAGMENT_UNIFORM_VECTORS_SM2 = 32 - 3,    // Reserve space for dx_Coord, dx_DepthFront and dx_DepthRange.
     MAX_FRAGMENT_UNIFORM_VECTORS_SM3 = 224 - 3,
     MAX_DRAW_BUFFERS = 1
@@ -173,7 +177,7 @@
     GLuint currentProgram;
 
     VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
-    BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];
+    BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
     BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
 
     GLint unpackAlignment;
@@ -377,7 +381,6 @@
     int getMajorShaderModel() const;
     float getMaximumPointSize() const;
     int getMaximumVaryingVectors() const;
-    unsigned int getMaximumVertexTextureImageUnits() const;
     unsigned int getMaximumCombinedTextureImageUnits() const;
     int getMaximumFragmentUniformVectors() const;
     int getMaximumRenderbufferDimension() const;
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 9e4b04a..bc7c38c 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -54,7 +54,7 @@
         mSamplersPS[index].active = false;
     }
 
-    for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++)
+    for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
     {
         mSamplersVS[index].active = false;
     }
@@ -989,7 +989,7 @@
                     {
                         unsigned int samplerIndex = firstIndex + i;
 
-                        if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF)
+                        if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
                         {
                             ASSERT(mSamplersVS[samplerIndex].active);
                             mSamplersVS[samplerIndex].logicalTextureUnit = v[i];
@@ -1573,7 +1573,7 @@
         mSamplersPS[i].textureType = (TextureType) textureType;
     }
 
-    for (unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; ++i)
+    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
     {
         stream.read(&mSamplersVS[i].active);
         stream.read(&mSamplersVS[i].logicalTextureUnit);
@@ -1694,7 +1694,7 @@
         stream.write((int) mSamplersPS[i].textureType);
     }
 
-    for (unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; ++i)
+    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
     {
         stream.write(mSamplersVS[i].active);
         stream.write(mSamplersVS[i].logicalTextureUnit);
@@ -1937,7 +1937,7 @@
         {
             if (shader == GL_VERTEX_SHADER)
             {
-                if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits())
+                if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits())
                 {
                     mSamplersVS[samplerIndex].active = true;
                     mSamplersVS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
@@ -1946,7 +1946,7 @@
                 }
                 else
                 {
-                    infoLog.append("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits());
+                    infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", mRenderer->getMaxVertexTextureImageUnits());
                     return false;
                 }
             }
@@ -2177,9 +2177,9 @@
     // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
 
     const unsigned int maxCombinedTextureImageUnits = getContext()->getMaximumCombinedTextureImageUnits();
-    TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];
+    TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
 
-    for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i)
+    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
     {
         textureUnitType[i] = TEXTURE_UNKNOWN;
     }
@@ -2194,7 +2194,7 @@
             {
                 if (infoLog)
                 {
-                    infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+                    infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
                 }
 
                 return false;
@@ -2229,7 +2229,7 @@
             {
                 if (infoLog)
                 {
-                    infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+                    infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
                 }
 
                 return false;
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index 782d3f9..ab91522 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -133,7 +133,7 @@
     };
 
     Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS];
-    Sampler mSamplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
+    Sampler mSamplersVS[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
     GLuint mUsedVertexSamplerRange;
     GLuint mUsedPixelSamplerRange;
     bool mUsesPointSize;
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index 861f82c..cd8aebf 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -238,7 +238,7 @@
             resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
             resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
             resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
-            resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
+            resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
             resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
             resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
             resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 187adff..b26eff6 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -142,7 +142,8 @@
     virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable) = 0;
     virtual bool getLuminanceTextureSupport() = 0;
     virtual bool getLuminanceAlphaTextureSupport() = 0;
-    virtual bool getVertexTextureSupport() const = 0;
+    bool getVertexTextureSupport() const { return getMaxVertexTextureImageUnits() > 0; }
+    virtual unsigned int getMaxVertexTextureImageUnits() const = 0;
     virtual bool getNonPower2TextureSupport() const = 0;
     virtual bool getDepthTextureSupport() const = 0;
     virtual bool getOcclusionQuerySupport() const = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index e478ff3..dc36c67 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -46,6 +46,11 @@
         DXGI_FORMAT_D24_UNORM_S8_UINT
     };
 
+enum
+{
+    MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
+};
+
 Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
 {
     mVertexDataManager = NULL;
@@ -312,7 +317,7 @@
     }
     else if (type == gl::SAMPLER_VERTEX)
     {
-        if (index < 0 || index >= gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF)
+        if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
         {
             ERR("Vertex shader sampler index %i is not valid.", index);
             return;
@@ -378,7 +383,7 @@
     }
     else if (type == gl::SAMPLER_VERTEX)
     {
-        if (index < 0 || index >= gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF)
+        if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
         {
             ERR("Vertex shader sampler index %i is not valid.", index);
             return;
@@ -1317,7 +1322,7 @@
     mDepthStencilInitialized = false;
     mRenderTargetDescInitialized = false;
 
-    for (int i = 0; i < gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; i++)
+    for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
     {
         mForceSetVertexSamplerStates[i] = true;
         mCurVertexTextureSerials[i] = 0;
@@ -1584,11 +1589,18 @@
     return false;
 }
 
-bool Renderer11::getVertexTextureSupport() const
+unsigned int Renderer11::getMaxVertexTextureImageUnits() const
 {
-    // TODO
-    // UNIMPLEMENTED();
-    return false;
+    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
+      default: UNREACHABLE();
+        return 0;
+    }
 }
 
 bool Renderer11::getNonPower2TextureSupport() const
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index cfa09f8..2356b05 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -97,7 +97,7 @@
     virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
     virtual bool getLuminanceTextureSupport();
     virtual bool getLuminanceAlphaTextureSupport();
-    virtual bool getVertexTextureSupport() const;
+    virtual unsigned int getMaxVertexTextureImageUnits() const;
     virtual bool getNonPower2TextureSupport() const;
     virtual bool getDepthTextureSupport() const;
     virtual bool getOcclusionQuerySupport() const;
@@ -191,14 +191,14 @@
     unsigned int mCurStencilSize;
 
     // Currently applied sampler states
-    bool mForceSetVertexSamplerStates[gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
-    gl::SamplerState mCurVertexSamplerStates[gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
+    bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
 
     bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
     gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
 
     // Currently applied textures
-    unsigned int mCurVertexTextureSerials[gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
+    unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
     unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
 
     // Currently applied blend state
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index e9e6f3e..6a60762 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -66,6 +66,11 @@
     //  D3DFMT_D24FS8
     };
 
+enum
+{
+    MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
+};
+
 Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Renderer(display), mDc(hDc), mSoftwareDevice(softwareDevice)
 {
     mD3d9Module = NULL;
@@ -1946,7 +1951,7 @@
     mForceSetViewport = true;
     mForceSetBlendState = true;
 
-    for (unsigned int i = 0; i < gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; i++)
+    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
     {
         mForceSetVertexSamplerStates[i] = true;
         mCurVertexTextureSerials[i] = 0;
@@ -2223,9 +2228,10 @@
     return mEventQuerySupport;
 }
 
-bool Renderer9::getVertexTextureSupport() const
+unsigned int Renderer9::getMaxVertexTextureImageUnits() const
 {
-    return mVertexTextureSupport;
+    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+    return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0;
 }
 
 bool Renderer9::getNonPower2TextureSupport() const
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index 1ef3b13..17320f8 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -122,7 +122,7 @@
     virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
     virtual bool getLuminanceTextureSupport();
     virtual bool getLuminanceAlphaTextureSupport();
-    virtual bool getVertexTextureSupport() const;
+    virtual unsigned int getMaxVertexTextureImageUnits() const;
     virtual bool getNonPower2TextureSupport() const;
     virtual bool getDepthTextureSupport() const;
     virtual bool getOcclusionQuerySupport() const;
@@ -296,14 +296,14 @@
     GLuint mCurSampleMask;
 
     // Currently applied sampler states
-    bool mForceSetVertexSamplerStates[gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
-    gl::SamplerState mCurVertexSamplerStates[gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
+    bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
 
     bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
     gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
 
     // Currently applied textures
-    unsigned int mCurVertexTextureSerials[gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
+    unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
     unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
 
     unsigned int mAppliedIBSerial;