зеркало из https://github.com/AvaloniaUI/angle.git
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>
This commit is contained in:
Родитель
4b056a17b5
Коммит
01341f9483
|
@ -210,3 +210,6 @@ Collabora, Ltd.
|
|||
|
||||
LunarG, Inc.
|
||||
Mark Lobodzinski
|
||||
|
||||
Valve Corporation
|
||||
Steven Noonan
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче