D3D11: Allow no-op pixel shader output.

On HLSL 4+, the debug runtime issues a warning when we try to render
to a color output in the pixel shader that doesn't have a matching
render target bound. This happens when doing a depth or stencil-only
render pass. We only need to bind a dummy output in HLSL 3, so tighten
the workaround we had in place and fix the warning for D3D11.

BUG=angleproject:2025

Change-Id: I16ba9e907f3a6e59afff93fe4583d084cbdf42c5
Reviewed-on: https://chromium-review.googlesource.com/617268
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index ebd0653..9fc081a 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -2853,7 +2853,7 @@
     InfoLog infoLog;
     Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
                                                                      mMemoryProgramCache, drawMode);
-    if (err.isError())
+    if (err.isError() || infoLog.getLength() > 0)
     {
         WARN() << "Dynamic recompilation error log: " << infoLog.str();
     }
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index ea0eaee..ba3ab6b 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -294,8 +294,13 @@
     declarationStream << "struct PS_OUTPUT\n"
                          "{\n";
 
+    size_t numOutputs = outputLayout.size();
+
     // Workaround for HLSL 3.x: We can't do a depth/stencil only render, the runtime will complain.
-    size_t numOutputs = outputLayout.empty() ? 1u : outputLayout.size();
+    if (numOutputs == 0 && (shaderModel == 3 || !mRenderer->getShaderModelSuffix().empty()))
+    {
+        numOutputs = 1u;
+    }
     const PixelShaderOutputVariable defaultOutput(GL_FLOAT_VEC4, "dummy", "float4(0, 0, 0, 1)", 0);
 
     for (size_t layoutIndex = 0; layoutIndex < numOutputs; ++layoutIndex)
diff --git a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
index 46fee8d..8d502ff 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -326,6 +326,10 @@
     {
         ShaderExecutableD3D *vertexExe = nullptr;
         ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, infoLog));
+        if (!programD3D->hasVertexExecutableForCachedInputLayout())
+        {
+            return gl::InternalError() << "Error compiling dynamic vertex executable.";
+        }
     }
 
     if (recompileGS)
@@ -333,12 +337,20 @@
         ShaderExecutableD3D *geometryExe = nullptr;
         ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(
             context->getContextState(), drawMode, &geometryExe, infoLog));
+        if (!programD3D->hasGeometryExecutableForPrimitiveType(drawMode))
+        {
+            return gl::InternalError() << "Error compiling dynamic geometry executable.";
+        }
     }
 
     if (recompilePS)
     {
         ShaderExecutableD3D *pixelExe = nullptr;
         ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, infoLog));
+        if (!programD3D->hasPixelExecutableForCachedOutputLayout())
+        {
+            return gl::InternalError() << "Error compiling dynamic pixel executable.";
+        }
     }
 
     // Refresh the program cache entry.
diff --git a/src/tests/gl_tests/WebGLFramebufferTest.cpp b/src/tests/gl_tests/WebGLFramebufferTest.cpp
index 81e178f..89365e7 100644
--- a/src/tests/gl_tests/WebGLFramebufferTest.cpp
+++ b/src/tests/gl_tests/WebGLFramebufferTest.cpp
@@ -808,6 +808,12 @@
 // Determine if we can attach both color and depth or color and depth_stencil
 TEST_P(WebGLFramebufferTest, CheckValidColorDepthCombination)
 {
+    // In FL9_3, we don't have a good way to handle non-color framebuffer rendering.
+    if (IsD3D11_FL93())
+    {
+        ignoreD3D11SDKLayersWarnings();
+    }
+
     GLenum depthFormat     = GL_NONE;
     GLenum depthAttachment = GL_NONE;