Pass texture base level to shaders on D3D11

The base level is passed to shaders in a uniform block created
specifically for passing sampler metadata. This is done on feature levels
above 9_3, which treat samplers as indices to sampler arrays in shaders.

BUG=angleproject:596
TEST=angle_end2end_tests

Change-Id: I846f2fc195ab1fd884052824ffd3c1d65083c0fb
Reviewed-on: https://chromium-review.googlesource.com/322122
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 170875e..602c839 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -183,8 +183,8 @@
         mUniformHLSL->reserveUniformRegisters(3);
     }
 
-    // Reserve registers for the default uniform block and driver constants
-    mUniformHLSL->reserveInterfaceBlockRegisters(2);
+    // Reserve registers for the default uniform block, driver constants and sampler metadata
+    mUniformHLSL->reserveInterfaceBlockRegisters(3);
 }
 
 OutputHLSL::~OutputHLSL()
@@ -506,6 +506,11 @@
             }
 
             out << "};\n";
+
+            if (mOutputType == SH_HLSL_4_1_OUTPUT)
+            {
+                mUniformHLSL->samplerMetadataUniforms(out);
+            }
         }
         else
         {
@@ -607,6 +612,11 @@
 
             out << "};\n"
                    "\n";
+
+            if (mOutputType == SH_HLSL_4_1_OUTPUT)
+            {
+                mUniformHLSL->samplerMetadataUniforms(out);
+            }
         }
         else
         {
diff --git a/src/compiler/translator/UniformHLSL.cpp b/src/compiler/translator/UniformHLSL.cpp
index 20961c4..b1df8b4 100644
--- a/src/compiler/translator/UniformHLSL.cpp
+++ b/src/compiler/translator/UniformHLSL.cpp
@@ -246,6 +246,17 @@
     }
 }
 
+void UniformHLSL::samplerMetadataUniforms(TInfoSinkBase &out)
+{
+    if (mSamplerRegister > 0)
+    {
+        out << "cbuffer SamplerMetadata : register(b2)\n"
+            << "{\n"
+            << "    int samplerMetadata[" << mSamplerRegister << "] : packoffset(c0);\n"
+            << "};\n";
+    }
+}
+
 TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks)
 {
     TString interfaceBlocks;
diff --git a/src/compiler/translator/UniformHLSL.h b/src/compiler/translator/UniformHLSL.h
index 0f51f34..e377480 100644
--- a/src/compiler/translator/UniformHLSL.h
+++ b/src/compiler/translator/UniformHLSL.h
@@ -31,6 +31,10 @@
     void uniformsHeader(TInfoSinkBase &out,
                         ShShaderOutput outputType,
                         const ReferencedSymbols &referencedUniforms);
+
+    // Must be called after uniformsHeader
+    void samplerMetadataUniforms(TInfoSinkBase &out);
+
     TString interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks);
 
     // Used for direct index references