зеркало из 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.
|
LunarG, Inc.
|
||||||
Mark Lobodzinski
|
Mark Lobodzinski
|
||||||
|
|
||||||
|
Valve Corporation
|
||||||
|
Steven Noonan
|
||||||
|
|
|
@ -969,14 +969,17 @@ void OutputHLSL::header(TInfoSinkBase &out,
|
||||||
out << " float multiviewSelectViewportIndex : packoffset(c3.z);\n";
|
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)
|
if (mOutputType == SH_HLSL_4_1_OUTPUT)
|
||||||
{
|
{
|
||||||
mResourcesHLSL->samplerMetadataUniforms(out, 4);
|
mResourcesHLSL->samplerMetadataUniforms(out, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUsesVertexID)
|
if (mUsesVertexID)
|
||||||
{
|
{
|
||||||
out << " uint dx_VertexID : packoffset(c3.w);\n";
|
out << " uint dx_VertexID : packoffset(c4.y);\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "};\n"
|
out << "};\n"
|
||||||
|
@ -990,8 +993,12 @@ void OutputHLSL::header(TInfoSinkBase &out,
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "uniform float4 dx_ViewAdjust : register(c1);\n";
|
out << "uniform float4 dx_ViewAdjust : register(c1);\n";
|
||||||
out << "uniform float2 dx_ViewCoords : register(c2);\n"
|
out << "uniform float2 dx_ViewCoords : register(c2);\n";
|
||||||
"\n";
|
|
||||||
|
out << "static const float clipControlOrigin = -1.0f;\n";
|
||||||
|
out << "static const float clipControlZeroToOne = 0.0f;\n";
|
||||||
|
|
||||||
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUsesDepthRange)
|
if (mUsesDepthRange)
|
||||||
|
|
|
@ -553,12 +553,19 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vertexGenerateOutput << " output.dx_Position.y = - gl_Position.y;\n";
|
vertexGenerateOutput
|
||||||
|
<< " output.dx_Position.y = clipControlOrigin * gl_Position.y;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexGenerateOutput
|
vertexGenerateOutput
|
||||||
<< " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
|
<< " if (clipControlZeroToOne)\n"
|
||||||
<< " output.dx_Position.w = gl_Position.w;\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
|
else
|
||||||
{
|
{
|
||||||
|
@ -576,14 +583,20 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vertexGenerateOutput
|
vertexGenerateOutput << " output.dx_Position.y = clipControlOrigin * (gl_Position.y "
|
||||||
<< " output.dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + "
|
"* dx_ViewAdjust.w + "
|
||||||
"dx_ViewAdjust.y * gl_Position.w);\n";
|
"dx_ViewAdjust.y * gl_Position.w);\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexGenerateOutput
|
vertexGenerateOutput
|
||||||
<< " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
|
<< " if (clipControlZeroToOne)\n"
|
||||||
<< " output.dx_Position.w = gl_Position.w;\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.
|
// 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,
|
angle::Result ShaderConstants11::updateBuffer(const gl::Context *context,
|
||||||
Renderer11 *renderer,
|
Renderer11 *renderer,
|
||||||
gl::ShaderType shaderType,
|
gl::ShaderType shaderType,
|
||||||
|
@ -848,12 +855,12 @@ void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
|
||||||
|
|
||||||
void StateManager11::checkPresentPath(const gl::Context *context)
|
void StateManager11::checkPresentPath(const gl::Context *context)
|
||||||
{
|
{
|
||||||
if (!mRenderer->presentPathFastEnabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto *framebuffer = context->getState().getDrawFramebuffer();
|
const auto *framebuffer = context->getState().getDrawFramebuffer();
|
||||||
const auto *firstColorAttachment = framebuffer->getFirstColorAttachment();
|
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;
|
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:
|
case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
|
||||||
invalidateShaders();
|
invalidateShaders();
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1429,6 +1452,10 @@ void StateManager11::syncViewport(const gl::Context *context)
|
||||||
dxMinViewportBoundsY = 0;
|
dxMinViewportBoundsY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool clipSpaceOriginLowerLeft = glState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::LowerLeft;
|
||||||
|
mShaderConstants.onClipControlChange(clipSpaceOriginLowerLeft,
|
||||||
|
glState.isClipControlDepthZeroToOne());
|
||||||
|
|
||||||
const auto &viewport = glState.getViewport();
|
const auto &viewport = glState.getViewport();
|
||||||
|
|
||||||
int dxViewportTopLeftX = 0;
|
int dxViewportTopLeftX = 0;
|
||||||
|
@ -1447,7 +1474,7 @@ void StateManager11::syncViewport(const gl::Context *context)
|
||||||
|
|
||||||
D3D11_VIEWPORT dxViewport;
|
D3D11_VIEWPORT dxViewport;
|
||||||
dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
|
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
|
// When present path fast is active and we're rendering to framebuffer 0, we must invert
|
||||||
// the viewport in Y-axis.
|
// the viewport in Y-axis.
|
||||||
|
|
|
@ -53,6 +53,7 @@ class ShaderConstants11 : angle::NonCopyable
|
||||||
void onImageChange(gl::ShaderType shaderType,
|
void onImageChange(gl::ShaderType shaderType,
|
||||||
unsigned int imageIndex,
|
unsigned int imageIndex,
|
||||||
const gl::ImageUnit &imageUnit);
|
const gl::ImageUnit &imageUnit);
|
||||||
|
void onClipControlChange(bool lowerLeft, bool zeroToOne);
|
||||||
|
|
||||||
angle::Result updateBuffer(const gl::Context *context,
|
angle::Result updateBuffer(const gl::Context *context,
|
||||||
Renderer11 *renderer,
|
Renderer11 *renderer,
|
||||||
|
@ -69,7 +70,10 @@ class ShaderConstants11 : angle::NonCopyable
|
||||||
viewCoords{.0f},
|
viewCoords{.0f},
|
||||||
viewScale{.0f},
|
viewScale{.0f},
|
||||||
multiviewWriteToViewportIndex{.0f},
|
multiviewWriteToViewportIndex{.0f},
|
||||||
firstVertex{0}
|
clipControlOrigin{-1.0f},
|
||||||
|
clipControlZeroToOne{.0f},
|
||||||
|
firstVertex{0},
|
||||||
|
padding{.0f, .0f}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
float depthRange[4];
|
float depthRange[4];
|
||||||
|
@ -81,8 +85,19 @@ class ShaderConstants11 : angle::NonCopyable
|
||||||
// whenever a multi-view draw framebuffer is made active.
|
// whenever a multi-view draw framebuffer is made active.
|
||||||
float multiviewWriteToViewportIndex;
|
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;
|
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
|
struct Pixel
|
||||||
{
|
{
|
||||||
|
@ -91,8 +106,8 @@ class ShaderConstants11 : angle::NonCopyable
|
||||||
viewCoords{.0f},
|
viewCoords{.0f},
|
||||||
depthFront{.0f},
|
depthFront{.0f},
|
||||||
viewScale{.0f},
|
viewScale{.0f},
|
||||||
multiviewWriteToViewportIndex(0),
|
multiviewWriteToViewportIndex{.0f},
|
||||||
padding(0)
|
padding{.0f}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
float depthRange[4];
|
float depthRange[4];
|
||||||
|
@ -107,6 +122,7 @@ class ShaderConstants11 : angle::NonCopyable
|
||||||
// Added here to manually pad the struct.
|
// Added here to manually pad the struct.
|
||||||
float padding;
|
float padding;
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(Pixel) % 16u == 0, "D3D11 constant buffers must be multiples of 16 bytes");
|
||||||
|
|
||||||
struct Compute
|
struct Compute
|
||||||
{
|
{
|
||||||
|
|
|
@ -1666,6 +1666,9 @@ void GenerateCaps(ID3D11Device *device,
|
||||||
extensions->readStencilNV = false;
|
extensions->readStencilNV = false;
|
||||||
extensions->depthBufferFloat2NV = 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 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
|
// D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't
|
||||||
// support gl_FrontFacing.
|
// support gl_FrontFacing.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче