Prevent D3D11 Feature Level 9_3 from sampling from SV_Position in Pixel Shaders
D3D11 FL9_3, like Shader Model 2.0 in D3D9, doesn't support reading from SV_Position in the pixel shader. We have to reconstruct gl_FragCoord using dx_ViewCoords instead.
Change-Id: I7e898038d210d73a9d224dcc18b033e5cd4a56f5
Reviewed-on: https://chromium-review.googlesource.com/234277
Tested-by: Austin Kinross <aukinros@microsoft.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index 8e0c2bd..1225f58 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -871,12 +871,14 @@
{
pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
- if (shaderModel >= 4)
+ // Certain Shader Models (4_0+ and 3_0) allow reading from dx_Position in the pixel shader.
+ // Other Shader Models (4_0_level_9_3 and 2_x) don't support this, so we emulate it using dx_ViewCoords.
+ if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
{
pixelHLSL += " gl_FragCoord.x = input.dx_Position.x;\n"
" gl_FragCoord.y = input.dx_Position.y;\n";
}
- else if (shaderModel >= 3)
+ else if (shaderModel == 3)
{
pixelHLSL += " gl_FragCoord.x = input.dx_Position.x + 0.5;\n"
" gl_FragCoord.y = input.dx_Position.y + 0.5;\n";
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index 34f18f5..ccc0d01 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -76,6 +76,9 @@
bool isDeviceLost() const override;
std::string getVendorString() const override;
+ virtual int getMinorShaderModel() const = 0;
+ virtual std::string getShaderModelSuffix() const = 0;
+
DisplayImpl *createDisplay() override;
// Direct3D Specific methods
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index 7acf58a..b4c8324 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -114,6 +114,8 @@
virtual bool getPostSubBufferSupport() const;
virtual int getMajorShaderModel() const;
+ int getMinorShaderModel() const override;
+ std::string getShaderModelSuffix() const override;
virtual int getMinSwapInterval() const;
virtual int getMaxSwapInterval() const;
@@ -247,8 +249,6 @@
void initializeDevice();
void releaseDeviceResources();
- int getMinorShaderModel() const;
- std::string getShaderModelSuffix() const;
void release();
RenderStateCache mStateCache;
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 999ebde..b5f7a0c 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -2383,6 +2383,16 @@
return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
}
+int Renderer9::getMinorShaderModel() const
+{
+ return D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion);
+}
+
+std::string Renderer9::getShaderModelSuffix() const
+{
+ return "";
+}
+
DWORD Renderer9::getCapsDeclTypes() const
{
return mDeviceCaps.DeclTypes;
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
index 2127bf5..76527e8 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -117,6 +117,9 @@
virtual bool getPostSubBufferSupport() const;
virtual int getMajorShaderModel() const;
+ int getMinorShaderModel() const override;
+ std::string getShaderModelSuffix() const override;
+
DWORD getCapsDeclTypes() const;
virtual int getMinSwapInterval() const;
virtual int getMaxSwapInterval() const;