aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Noonan <steven@valvesoftware.com>2021-10-11 19:26:07 -0700
committerAngle LUCI CQ <angle-scoped@luci-project-accounts.iam.gserviceaccount.com>2021-10-12 18:57:15 +0000
commit01341f94838325016519b159b854cd09acd05f82 (patch)
tree6fc85b070ae8e1189c0072216411faa317ad722e
parent4b056a17b5a1ba63d19875009e729c032c41c343 (diff)
downloadangle-01341f94838325016519b159b854cd09acd05f82.tar.gz
D3D11: implement EXT_clip_control
This implements EXT_clip_control for the D3D11 renderer, so that I can use a reversed-Z depth buffer with ANGLE. Tested with angle_deqp_gles2_tests.exe --deqp-egl-display-type=angle-d3d11 --deqp-case=dEQP-GLES2.functional.clip_control.* and angle_end2end_tests.exe --gtest_filter=*D3D11* Bug: angleproject:6554 Change-Id: I1d11cd04a6654c28530b11104470f0cad0009abe Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3218659 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
-rw-r--r--CONTRIBUTORS3
-rw-r--r--src/compiler/translator/OutputHLSL.cpp15
-rw-r--r--src/libANGLE/renderer/d3d/DynamicHLSL.cpp29
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp37
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/StateManager11.h22
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp3
6 files changed, 89 insertions, 20 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index c1c2e4d1c9..770d7e4284 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -210,3 +210,6 @@ Collabora, Ltd.
LunarG, Inc.
Mark Lobodzinski
+
+Valve Corporation
+ Steven Noonan
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 001d9031d7..04ba480399 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -969,14 +969,17 @@ void OutputHLSL::header(TInfoSinkBase &out,
out << " float multiviewSelectViewportIndex : packoffset(c3.z);\n";
}
+ out << " float clipControlOrigin : packoffset(c3.w);\n";
+ out << " float clipControlZeroToOne : packoffset(c4);\n";
+
if (mOutputType == SH_HLSL_4_1_OUTPUT)
{
- mResourcesHLSL->samplerMetadataUniforms(out, 4);
+ mResourcesHLSL->samplerMetadataUniforms(out, 5);
}
if (mUsesVertexID)
{
- out << " uint dx_VertexID : packoffset(c3.w);\n";
+ out << " uint dx_VertexID : packoffset(c4.y);\n";
}
out << "};\n"
@@ -990,8 +993,12 @@ void OutputHLSL::header(TInfoSinkBase &out,
}
out << "uniform float4 dx_ViewAdjust : register(c1);\n";
- out << "uniform float2 dx_ViewCoords : register(c2);\n"
- "\n";
+ out << "uniform float2 dx_ViewCoords : register(c2);\n";
+
+ out << "static const float clipControlOrigin = -1.0f;\n";
+ out << "static const float clipControlZeroToOne = 0.0f;\n";
+
+ out << "\n";
}
if (mUsesDepthRange)
diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index 6c167f7a9f..950a6ef269 100644
--- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -553,12 +553,19 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
}
else
{
- vertexGenerateOutput << " output.dx_Position.y = - gl_Position.y;\n";
+ vertexGenerateOutput
+ << " output.dx_Position.y = clipControlOrigin * gl_Position.y;\n";
}
vertexGenerateOutput
- << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
- << " output.dx_Position.w = gl_Position.w;\n";
+ << " if (clipControlZeroToOne)\n"
+ << " {\n"
+ << " output.dx_Position.z = gl_Position.z;\n"
+ << " } else {\n"
+ << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+ << " }\n";
+
+ vertexGenerateOutput << " output.dx_Position.w = gl_Position.w;\n";
}
else
{
@@ -576,14 +583,20 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
}
else
{
- vertexGenerateOutput
- << " output.dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + "
- "dx_ViewAdjust.y * gl_Position.w);\n";
+ vertexGenerateOutput << " output.dx_Position.y = clipControlOrigin * (gl_Position.y "
+ "* dx_ViewAdjust.w + "
+ "dx_ViewAdjust.y * gl_Position.w);\n";
}
vertexGenerateOutput
- << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
- << " output.dx_Position.w = gl_Position.w;\n";
+ << " if (clipControlZeroToOne)\n"
+ << " {\n"
+ << " output.dx_Position.z = gl_Position.z;\n"
+ << " } else {\n"
+ << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+ << " }\n";
+
+ vertexGenerateOutput << " output.dx_Position.w = gl_Position.w;\n";
}
// We don't need to output gl_PointSize if we use are emulating point sprites via instancing.
diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
index fd94e2bdee..6b14031c88 100644
--- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -589,6 +589,13 @@ void ShaderConstants11::onImageChange(gl::ShaderType shaderType,
}
}
+void ShaderConstants11::onClipControlChange(bool lowerLeft, bool zeroToOne)
+{
+ mVertex.clipControlOrigin = lowerLeft ? -1.0f : 1.0f;
+ mVertex.clipControlZeroToOne = zeroToOne ? 1.0f : 0.0f;
+ mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+}
+
angle::Result ShaderConstants11::updateBuffer(const gl::Context *context,
Renderer11 *renderer,
gl::ShaderType shaderType,
@@ -848,12 +855,12 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
void StateManager11::checkPresentPath(const gl::Context *context)
{
- if (!mRenderer->presentPathFastEnabled())
- return;
-
const auto *framebuffer = context->getState().getDrawFramebuffer();
const auto *firstColorAttachment = framebuffer->getFirstColorAttachment();
- const bool presentPathFastActive = UsePresentPathFast(mRenderer, firstColorAttachment);
+ const bool clipSpaceOriginUpperLeft =
+ context->getState().getClipSpaceOrigin() == gl::ClipSpaceOrigin::UpperLeft;
+ const bool presentPathFastActive =
+ UsePresentPathFast(mRenderer, firstColorAttachment) || clipSpaceOriginUpperLeft;
const int colorBufferHeight = firstColorAttachment ? firstColorAttachment->getSize().height : 0;
@@ -1205,6 +1212,22 @@ void StateManager11::syncState(const gl::Context *context, const gl::State::Dirt
case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
invalidateShaders();
break;
+ case gl::State::DIRTY_BIT_EXTENDED:
+ {
+ gl::State::ExtendedDirtyBits extendedDirtyBits =
+ state.getAndResetExtendedDirtyBits();
+
+ for (size_t extendedDirtyBit : extendedDirtyBits)
+ {
+ switch (extendedDirtyBit)
+ {
+ case gl::State::EXTENDED_DIRTY_BIT_CLIP_CONTROL:
+ checkPresentPath(context);
+ break;
+ }
+ }
+ break;
+ }
default:
break;
}
@@ -1429,6 +1452,10 @@ void StateManager11::syncViewport(const gl::Context *context)
dxMinViewportBoundsY = 0;
}
+ bool clipSpaceOriginLowerLeft = glState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::LowerLeft;
+ mShaderConstants.onClipControlChange(clipSpaceOriginLowerLeft,
+ glState.isClipControlDepthZeroToOne());
+
const auto &viewport = glState.getViewport();
int dxViewportTopLeftX = 0;
@@ -1447,7 +1474,7 @@ void StateManager11::syncViewport(const gl::Context *context)
D3D11_VIEWPORT dxViewport;
dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
- if (mCurPresentPathFastEnabled)
+ if (mCurPresentPathFastEnabled && clipSpaceOriginLowerLeft)
{
// When present path fast is active and we're rendering to framebuffer 0, we must invert
// the viewport in Y-axis.
diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
index 3155b2bf47..ee2fe887a0 100644
--- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
@@ -53,6 +53,7 @@ class ShaderConstants11 : angle::NonCopyable
void onImageChange(gl::ShaderType shaderType,
unsigned int imageIndex,
const gl::ImageUnit &imageUnit);
+ void onClipControlChange(bool lowerLeft, bool zeroToOne);
angle::Result updateBuffer(const gl::Context *context,
Renderer11 *renderer,
@@ -69,7 +70,10 @@ class ShaderConstants11 : angle::NonCopyable
viewCoords{.0f},
viewScale{.0f},
multiviewWriteToViewportIndex{.0f},
- firstVertex{0}
+ clipControlOrigin{-1.0f},
+ clipControlZeroToOne{.0f},
+ firstVertex{0},
+ padding{.0f, .0f}
{}
float depthRange[4];
@@ -81,8 +85,19 @@ class ShaderConstants11 : angle::NonCopyable
// whenever a multi-view draw framebuffer is made active.
float multiviewWriteToViewportIndex;
+ // EXT_clip_control
+ // Multiplied with Y coordinate: -1.0 for GL_LOWER_LEFT_EXT, 1.0f for GL_UPPER_LEFT_EXT
+ float clipControlOrigin;
+ // 0.0 for GL_NEGATIVE_ONE_TO_ONE_EXT, 1.0 for GL_ZERO_TO_ONE_EXT
+ float clipControlZeroToOne;
+
uint32_t firstVertex;
+
+ // Added here to manually pad the struct to 16 byte boundary
+ float padding[2];
};
+ static_assert(sizeof(Vertex) % 16u == 0,
+ "D3D11 constant buffers must be multiples of 16 bytes");
struct Pixel
{
@@ -91,8 +106,8 @@ class ShaderConstants11 : angle::NonCopyable
viewCoords{.0f},
depthFront{.0f},
viewScale{.0f},
- multiviewWriteToViewportIndex(0),
- padding(0)
+ multiviewWriteToViewportIndex{.0f},
+ padding{.0f}
{}
float depthRange[4];
@@ -107,6 +122,7 @@ class ShaderConstants11 : angle::NonCopyable
// Added here to manually pad the struct.
float padding;
};
+ static_assert(sizeof(Pixel) % 16u == 0, "D3D11 constant buffers must be multiples of 16 bytes");
struct Compute
{
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index f9f6c18e7a..00b40848ea 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -1666,6 +1666,9 @@ void GenerateCaps(ID3D11Device *device,
extensions->readStencilNV = false;
extensions->depthBufferFloat2NV = false;
+ // GL_EXT_clip_control
+ extensions->clipControlEXT = (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_9_3);
+
// D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't
// support gl_FrontFacing.