ES31: support stencil texture via DEPTH_STENCIL_TEXTURE_MODE.

BUG=angleproject:2373

Change-Id: I5edd9db6ef6101b0ad75f71fdcdfbb1261100583
Reviewed-on: https://chromium-review.googlesource.com/936421
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp
index 24e8c22..aaf19db 100644
--- a/src/libANGLE/Texture.cpp
+++ b/src/libANGLE/Texture.cpp
@@ -342,6 +342,26 @@
         }
     }
 
+    // OpenGLES 3.1 spec section 8.16 states that a texture is not mipmap complete if:
+    // The internalformat specified for the texture is DEPTH_STENCIL format, the value of
+    // DEPTH_STENCIL_TEXTURE_MODE is STENCIL_INDEX, and either the magnification filter is
+    // not NEAREST or the minification filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
+    // However, the ES 3.1 spec differs from the statement above, because it is incorrect.
+    // See the issue at https://github.com/KhronosGroup/OpenGL-API/issues/33.
+    // For multismaple texture, filter state of multisample texture is ignored(11.1.3.3).
+    // So it shouldn't be judged as incomplete texture. So, we ignore filtering for multisample
+    // texture completeness here.
+    if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && baseImageDesc.format.info->depthBits > 0 &&
+        mDepthStencilTextureMode == GL_STENCIL_INDEX)
+    {
+        if ((samplerState.minFilter != GL_NEAREST &&
+             samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
+            samplerState.magFilter != GL_NEAREST)
+        {
+            return false;
+        }
+    }
+
     return true;
 }
 
@@ -792,14 +812,12 @@
 
 void Texture::setDepthStencilTextureMode(GLenum mode)
 {
-    if (mode != mState.mDepthStencilTextureMode)
+    if (mState.mDepthStencilTextureMode != mode)
     {
-        // Changing the mode from the default state (GL_DEPTH_COMPONENT) is not implemented yet
-        UNIMPLEMENTED();
+        mState.mDepthStencilTextureMode = mode;
+        mDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE);
+        invalidateCompletenessCache();
     }
-
-    // TODO(geofflang): add dirty bits
-    mState.mDepthStencilTextureMode = mode;
 }
 
 GLenum Texture::getDepthStencilTextureMode() const
diff --git a/src/libANGLE/Texture.h b/src/libANGLE/Texture.h
index 7525da2..7a849d4 100644
--- a/src/libANGLE/Texture.h
+++ b/src/libANGLE/Texture.h
@@ -113,6 +113,7 @@
     const SwizzleState &getSwizzleState() const { return mSwizzleState; }
     const SamplerState &getSamplerState() const { return mSamplerState; }
     GLenum getUsage() const { return mUsage; }
+    GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
 
   private:
     // Texture needs access to the ImageDesc functions.
@@ -391,6 +392,7 @@
         DIRTY_BIT_SWIZZLE_ALPHA,
         DIRTY_BIT_BASE_LEVEL,
         DIRTY_BIT_MAX_LEVEL,
+        DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE,
 
         // Misc
         DIRTY_BIT_LABEL,
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index c9d75ce..9370f4f 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -183,6 +183,10 @@
         case GL_TEXTURE_SRGB_DECODE_EXT:
             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
             break;
+        case GL_DEPTH_STENCIL_TEXTURE_MODE:
+            *params =
+                CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
+            break;
         default:
             UNREACHABLE();
             break;
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp
index cbe3f18..5598c96 100644
--- a/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -1154,6 +1154,13 @@
                 mAppliedMaxLevel = mState.getEffectiveMaxLevel();
                 mFunctions->texParameteri(getTarget(), GL_TEXTURE_MAX_LEVEL, mAppliedMaxLevel);
                 break;
+            case gl::Texture::DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE:
+            {
+                GLenum mDepthStencilTextureMode = mState.getDepthStencilTextureMode();
+                mFunctions->texParameteri(getTarget(), GL_DEPTH_STENCIL_TEXTURE_MODE,
+                                          mDepthStencilTextureMode);
+                break;
+            }
             case gl::Texture::DIRTY_BIT_USAGE:
                 break;
             case gl::Texture::DIRTY_BIT_LABEL:
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index d8919dd..fd00b7b 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -4994,6 +4994,14 @@
             }
             break;
 
+        case GL_DEPTH_STENCIL_TEXTURE_MODE:
+            if (context->getClientVersion() < Version(3, 1))
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
+                return false;
+            }
+            break;
+
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
diff --git a/src/tests/deqp_support/deqp_gles31_test_expectations.txt b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
index e311ec5..e231851 100644
--- a/src/tests/deqp_support/deqp_gles31_test_expectations.txt
+++ b/src/tests/deqp_support/deqp_gles31_test_expectations.txt
@@ -1174,24 +1174,7 @@
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_count = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_size = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.helper_invocation.* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d_array = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_2d = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_2d_array = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth24_stencil8_cube = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth32f_stencil8_clear = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth32f_stencil8_draw = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_clear = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.render.depth24_stencil8_draw = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.compare_mode_effect = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.misc.base_level = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.integer.program_pipeline_binding_* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d.depth_stencil_mode_* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_cube_map.depth_stencil_mode_* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d_array.depth_stencil_mode_* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_3d.depth_stencil_mode_* = FAIL
-1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.texture.texture_2d_multisample.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program.program_separable_get_programiv = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program_pipeline.* = FAIL
 1442 OPENGL D3D11 : dEQP-GLES31.functional.synchronization.inter_call.without_memory_barrier.atomic_counter_dispatch_100_calls_1k_invocations = FAIL