Use D3D11 GetDimensions driver workaround for 2D integer textures

Some NVIDIA D3D11 drivers are buggy and interprets the level passed to
GetDimensions as being relative to 0, rather than the SRV's MostDetailedMip.
A test is added which reads from non-zero base level integer texture. When the
workaround is not being used, reads outside the first quadrant return black.

Bug: chromium:679639
Change-Id: I5282a1ba207b2d553d1836f9460ec09cb5590ea6
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1591594
Commit-Queue: Kimmo Kinnunen FI <kkinnunen@nvidia.com>
Reviewed-by: Kimmo Kinnunen FI <kkinnunen@nvidia.com>
diff --git a/src/compiler/translator/TextureFunctionHLSL.cpp b/src/compiler/translator/TextureFunctionHLSL.cpp
index 28208bc..f4c6fc5 100644
--- a/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -602,7 +602,8 @@
     const ImmutableString &textureReference,
     ImmutableString *texCoordX,
     ImmutableString *texCoordY,
-    ImmutableString *texCoordZ)
+    ImmutableString *texCoordZ,
+    bool getDimensionsIgnoresBaseLevel)
 {
     if (!IsIntegerSampler(textureFunction.sampler))
     {
@@ -752,6 +753,15 @@
         }
         else if (IsSampler2D(textureFunction.sampler))
         {
+            if (getDimensionsIgnoresBaseLevel)
+            {
+                out << "    int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
+            }
+            else
+            {
+                out << "    int baseLevel = 0;\n";
+            }
+
             out << "    float width; float height; float levels;\n";
 
             if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
@@ -764,7 +774,8 @@
             }
             else
             {
-                out << "    " << textureReference << ".GetDimensions(0, width, height, levels);\n";
+                out << "    " << textureReference
+                    << ".GetDimensions(baseLevel, width, height, levels);\n";
 
                 if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
                     textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
@@ -791,7 +802,8 @@
                 out << "    uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
             }
 
-            out << "    " << textureReference << ".GetDimensions(mip, width, height, levels);\n";
+            out << "    " << textureReference
+                << ".GetDimensions(baseLevel + mip, width, height, levels);\n";
         }
         else if (IsSampler3D(textureFunction.sampler))
         {
@@ -1458,9 +1470,9 @@
             else
             {
                 ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
-                OutputIntegerTextureSampleFunctionComputations(out, textureFunction, outputType,
-                                                               textureReference, &texCoordX,
-                                                               &texCoordY, &texCoordZ);
+                OutputIntegerTextureSampleFunctionComputations(
+                    out, textureFunction, outputType, textureReference, &texCoordX, &texCoordY,
+                    &texCoordZ, getDimensionsIgnoresBaseLevel);
                 OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
                                                            textureReference, samplerReference,
                                                            texCoordX, texCoordY, texCoordZ);