Create a single-level SRV when not mipmapping.

BUG=angle:596

Change-Id: Iec5a9e43a23c0743ff8b01985a86a72c5f18a7f7
Reviewed-on: https://chromium-review.googlesource.com/192052
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 4348c8a..143f7ac 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -57,6 +57,8 @@
     IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15   // 1+log2 of MAX_TEXTURE_SIZE
 };
 
+bool IsMipmapFiltered(const SamplerState &samplerState);
+
 class Texture : public RefCountObject
 {
   public:
diff --git a/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp b/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp
index dcd498d..4848189 100644
--- a/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp
+++ b/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp
@@ -402,15 +402,15 @@
         samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS);
         samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT);
         samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.wrapR);
-        samplerDesc.MipLODBias = static_cast<float>(samplerState.lodOffset);
+        samplerDesc.MipLODBias = 0;
         samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy;
         samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.compareFunc);
         samplerDesc.BorderColor[0] = 0.0f;
         samplerDesc.BorderColor[1] = 0.0f;
         samplerDesc.BorderColor[2] = 0.0f;
         samplerDesc.BorderColor[3] = 0.0f;
-        samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
-        samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
+        samplerDesc.MinLOD = -FLT_MAX;
+        samplerDesc.MaxLOD = +FLT_MAX;
 
         ID3D11SamplerState *dx11SamplerState = NULL;
         HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
diff --git a/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
index 2fcf6c4..ea10aa8 100644
--- a/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
@@ -288,11 +288,9 @@
 {
     mTexture = swapchain->getOffscreenTexture();
     mTexture->AddRef();
-    mSRV = swapchain->getRenderTargetShaderResource();
-    mSRV->AddRef();
-
     mSwizzleTexture = NULL;
-    mSwizzleSRV = NULL;
+
+    memset(mSRV, NULL, sizeof(mSRV));
 
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
@@ -309,8 +307,9 @@
     mTextureHeight = texDesc.Height;
     mTextureDepth = 1;
 
+    ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
     D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
-    mSRV->GetDesc(&srvDesc);
+    srv->GetDesc(&srvDesc);
     mShaderResourceFormat = srvDesc.Format;
 
     ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
@@ -330,9 +329,10 @@
     : TextureStorage11(renderer, baseLevel, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget))
 {
     mTexture = NULL;
-    mSRV = NULL;
     mSwizzleTexture = NULL;
-    mSwizzleSRV = NULL;
+
+    memset(mSRV, NULL, sizeof(mSRV));
+
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
         mLevelSRVs[i] = NULL;
@@ -400,9 +400,11 @@
 TextureStorage11_2D::~TextureStorage11_2D()
 {
     SafeRelease(mTexture);
-    SafeRelease(mSRV);
     SafeRelease(mSwizzleTexture);
-    SafeRelease(mSwizzleSRV);
+
+    for (int i = 0; i < 2; i++)
+        for (int j = 0; j < 2; j++)
+            SafeRelease(mSRV[i][j]);
 
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
@@ -501,7 +503,8 @@
 {
     bool swizzleRequired = samplerState.swizzleRed != GL_RED || samplerState.swizzleGreen != GL_GREEN ||
                            samplerState.swizzleBlue != GL_BLUE || samplerState.swizzleAlpha != GL_ALPHA;
-    ID3D11ShaderResourceView **resultSRV = swizzleRequired ? &mSwizzleSRV : &mSRV;
+    bool mipmapping = gl::IsMipmapFiltered(samplerState);
+    ID3D11ShaderResourceView **resultSRV = &mSRV[swizzleRequired][mipmapping];
 
     if (swizzleRequired)
     {
@@ -515,8 +518,8 @@
         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
         srvDesc.Format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
-        srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
-        srvDesc.Texture2D.MostDetailedMip = 0;
+        srvDesc.Texture2D.MipLevels = mipmapping ? (mMipLevels == 0 ? -1 : mMipLevels) : 1;
+        srvDesc.Texture2D.MostDetailedMip = mLodOffset;
 
         ID3D11Texture2D *sourceTexture = swizzleRequired ? getSwizzleTexture() : mTexture;
         HRESULT result = device->CreateShaderResourceView(sourceTexture, &srvDesc, resultSRV);
@@ -643,9 +646,10 @@
     : TextureStorage11(renderer, baseLevel, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget))
 {
     mTexture = NULL;
-    mSRV = NULL;
     mSwizzleTexture = NULL;
-    mSwizzleSRV = NULL;
+
+    memset(mSRV, NULL, sizeof(mSRV));
+
     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
         mLevelSRVs[level] = NULL;
@@ -711,9 +715,11 @@
 TextureStorage11_Cube::~TextureStorage11_Cube()
 {
     SafeRelease(mTexture);
-    SafeRelease(mSRV);
     SafeRelease(mSwizzleTexture);
-    SafeRelease(mSwizzleSRV);
+
+    for (int i = 0; i < 2; i++)
+        for (int j = 0; j < 2; j++)
+            SafeRelease(mSRV[i][j]);
 
     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
@@ -833,7 +839,8 @@
 {
     bool swizzleRequired = samplerState.swizzleRed != GL_RED || samplerState.swizzleGreen != GL_GREEN ||
                            samplerState.swizzleBlue != GL_BLUE || samplerState.swizzleAlpha != GL_ALPHA;
-    ID3D11ShaderResourceView **resultSRV = swizzleRequired ? &mSwizzleSRV : &mSRV;
+    bool mipmapping = gl::IsMipmapFiltered(samplerState);
+    ID3D11ShaderResourceView **resultSRV = &mSRV[swizzleRequired][mipmapping];
 
     if (swizzleRequired)
     {
@@ -852,7 +859,7 @@
             d3d11::GetComponentType(mTextureFormat) == GL_UNSIGNED_INT)
         {
             srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
-            srvDesc.Texture2DArray.MostDetailedMip = 0;
+            srvDesc.Texture2DArray.MostDetailedMip = mLodOffset;
             srvDesc.Texture2DArray.MipLevels = 1;
             srvDesc.Texture2DArray.FirstArraySlice = 0;
             srvDesc.Texture2DArray.ArraySize = 6;
@@ -860,8 +867,8 @@
         else
         {
             srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
-            srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
-            srvDesc.TextureCube.MostDetailedMip = 0;
+            srvDesc.TextureCube.MipLevels = mipmapping ? (mMipLevels == 0 ? -1 : mMipLevels) : 1;
+            srvDesc.TextureCube.MostDetailedMip = mLodOffset;
         }
 
         ID3D11Texture2D *sourceTexture = swizzleRequired ? getSwizzleTexture() : mTexture;
@@ -994,9 +1001,9 @@
     : TextureStorage11(renderer, baseLevel, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget))
 {
     mTexture = NULL;
-    mSRV = NULL;
     mSwizzleTexture = NULL;
-    mSwizzleSRV = NULL;
+
+    memset(mSRV, NULL, sizeof(mSRV));
 
     for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
     {
@@ -1063,9 +1070,11 @@
 TextureStorage11_3D::~TextureStorage11_3D()
 {
     SafeRelease(mTexture);
-    SafeRelease(mSRV);
     SafeRelease(mSwizzleTexture);
-    SafeRelease(mSwizzleSRV);
+
+    for (int i = 0; i < 2; i++)
+        for (int j = 0; j < 2; j++)
+            SafeRelease(mSRV[i][j]);
 
     for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++)
     {
@@ -1096,7 +1105,8 @@
 {
     bool swizzleRequired = samplerState.swizzleRed != GL_RED || samplerState.swizzleGreen != GL_GREEN ||
                            samplerState.swizzleBlue != GL_BLUE || samplerState.swizzleAlpha != GL_ALPHA;
-    ID3D11ShaderResourceView **resultSRV = swizzleRequired ? &mSwizzleSRV : &mSRV;
+    bool mipmapping = gl::IsMipmapFiltered(samplerState);
+    ID3D11ShaderResourceView **resultSRV = &mSRV[swizzleRequired][mipmapping];
 
     if (swizzleRequired)
     {
@@ -1110,8 +1120,8 @@
         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
         srvDesc.Format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
-        srvDesc.Texture3D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
-        srvDesc.Texture3D.MostDetailedMip = 0;
+        srvDesc.Texture3D.MipLevels = mipmapping ? (mMipLevels == 0 ? -1 : mMipLevels) : 1;
+        srvDesc.Texture3D.MostDetailedMip = mLodOffset;
 
         ID3D11Texture3D *sourceTexture = swizzleRequired ? getSwizzleTexture() : mTexture;
         HRESULT result = device->CreateShaderResourceView(sourceTexture, &srvDesc, resultSRV);
@@ -1344,9 +1354,9 @@
     : TextureStorage11(renderer, baseLevel, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget))
 {
     mTexture = NULL;
-    mSRV = NULL;
     mSwizzleTexture = NULL;
-    mSwizzleSRV = NULL;
+
+    memset(mSRV, NULL, sizeof(mSRV));
 
     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
@@ -1414,9 +1424,11 @@
 TextureStorage11_2DArray::~TextureStorage11_2DArray()
 {
     SafeRelease(mTexture);
-    SafeRelease(mSRV);
     SafeRelease(mSwizzleTexture);
-    SafeRelease(mSwizzleSRV);
+
+    for (int i = 0; i < 2; i++)
+        for (int j = 0; j < 2; j++)
+            SafeRelease(mSRV[i][j]);
 
     for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
@@ -1446,7 +1458,8 @@
 {
     bool swizzleRequired = samplerState.swizzleRed != GL_RED || samplerState.swizzleGreen != GL_GREEN ||
                            samplerState.swizzleBlue != GL_BLUE || samplerState.swizzleAlpha != GL_ALPHA;
-    ID3D11ShaderResourceView **resultSRV = swizzleRequired ? &mSwizzleSRV : &mSRV;
+    bool mipmapping = gl::IsMipmapFiltered(samplerState);
+    ID3D11ShaderResourceView **resultSRV = &mSRV[swizzleRequired][mipmapping];
 
     if (swizzleRequired)
     {
@@ -1460,8 +1473,8 @@
         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
         srvDesc.Format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
         srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
-        srvDesc.Texture2DArray.MostDetailedMip = 0;
-        srvDesc.Texture2DArray.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
+        srvDesc.Texture2DArray.MostDetailedMip = mLodOffset;
+        srvDesc.Texture2DArray.MipLevels = mipmapping ? (mMipLevels == 0 ? -1 : mMipLevels) : 1;
         srvDesc.Texture2DArray.FirstArraySlice = 0;
         srvDesc.Texture2DArray.ArraySize = mTextureDepth;
 
diff --git a/src/libGLESv2/renderer/d3d11/TextureStorage11.h b/src/libGLESv2/renderer/d3d11/TextureStorage11.h
index 0e5ef0b..74e02da 100644
--- a/src/libGLESv2/renderer/d3d11/TextureStorage11.h
+++ b/src/libGLESv2/renderer/d3d11/TextureStorage11.h
@@ -134,13 +134,13 @@
     DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
 
     ID3D11Texture2D *mTexture;
-    ID3D11ShaderResourceView *mSRV;
-    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
     RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
     ID3D11Texture2D *mSwizzleTexture;
-    ID3D11ShaderResourceView *mSwizzleSRV;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    ID3D11ShaderResourceView *mSRV[2][2];   // [swizzle][mipmapping]
+    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 class TextureStorage11_Cube : public TextureStorage11
@@ -169,13 +169,13 @@
     DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
 
     ID3D11Texture2D *mTexture;
-    ID3D11ShaderResourceView *mSRV;
-    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
     RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
     ID3D11Texture2D *mSwizzleTexture;
-    ID3D11ShaderResourceView *mSwizzleSRV;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    ID3D11ShaderResourceView *mSRV[2][2];   // [swizzle][mipmapping]
+    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 class TextureStorage11_3D : public TextureStorage11
@@ -212,12 +212,11 @@
     RenderTarget11 *mLevelRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
     ID3D11Texture3D *mTexture;
-    ID3D11ShaderResourceView *mSRV;
-    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
-
     ID3D11Texture3D *mSwizzleTexture;
-    ID3D11ShaderResourceView *mSwizzleSRV;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    ID3D11ShaderResourceView *mSRV[2][2];   // [swizzle][mipmapping]
+    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 class TextureStorage11_2DArray : public TextureStorage11
@@ -251,12 +250,12 @@
     RenderTargetMap mRenderTargets;
 
     ID3D11Texture2D *mTexture;
-    ID3D11ShaderResourceView *mSRV;
-    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
     ID3D11Texture2D *mSwizzleTexture;
-    ID3D11ShaderResourceView *mSwizzleSRV;
     ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+
+    ID3D11ShaderResourceView *mSRV[2][2];   // [swizzle][mipmapping]
+    ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 };
 
 }
diff --git a/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp b/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp
index 40f5ce0..dc5e9df 100644
--- a/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp
+++ b/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp
@@ -203,16 +203,6 @@
     return D3D11_TEXTURE_ADDRESS_WRAP;
 }
 
-FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset)
-{
-    return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : -FLT_MAX;
-}
-
-FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset)
-{
-    return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : FLT_MAX;
-}
-
 D3D11_QUERY ConvertQueryType(GLenum queryType)
 {
     switch (queryType)
diff --git a/src/libGLESv2/renderer/d3d11/renderer11_utils.h b/src/libGLESv2/renderer/d3d11/renderer11_utils.h
index ba3ace7..e577d48 100644
--- a/src/libGLESv2/renderer/d3d11/renderer11_utils.h
+++ b/src/libGLESv2/renderer/d3d11/renderer11_utils.h
@@ -31,8 +31,6 @@
 
 D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode);
 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
-FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset);
-FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
 
 D3D11_QUERY ConvertQueryType(GLenum queryType);