[D3D12] Truncate depth to float24 in EDRAM range ownership transfers and resolves by default
Doesn't ruin the "greater or equal" depth test in subsequent rendering passes if precision is lost, unlike rounding to the nearest
This commit is contained in:
@@ -2239,18 +2239,13 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
// Get dynamic rasterizer state.
|
||||
uint32_t draw_resolution_scale_x = texture_cache_->draw_resolution_scale_x();
|
||||
uint32_t draw_resolution_scale_y = texture_cache_->draw_resolution_scale_y();
|
||||
RenderTargetCache::DepthFloat24Conversion depth_float24_conversion =
|
||||
render_target_cache_->depth_float24_conversion();
|
||||
draw_util::ViewportInfo viewport_info;
|
||||
draw_util::GetHostViewportInfo(
|
||||
regs, draw_resolution_scale_x, draw_resolution_scale_y, true,
|
||||
D3D12_VIEWPORT_BOUNDS_MAX, D3D12_VIEWPORT_BOUNDS_MAX, false,
|
||||
normalized_depth_control,
|
||||
host_render_targets_used &&
|
||||
(depth_float24_conversion ==
|
||||
RenderTargetCache::DepthFloat24Conversion::kOnOutputTruncating ||
|
||||
depth_float24_conversion ==
|
||||
RenderTargetCache::DepthFloat24Conversion::kOnOutputRounding),
|
||||
render_target_cache_->depth_float24_convert_in_pixel_shader(),
|
||||
host_render_targets_used, pixel_shader && pixel_shader->writes_depth(),
|
||||
viewport_info);
|
||||
draw_util::Scissor scissor;
|
||||
|
||||
@@ -457,7 +457,9 @@ bool D3D12RenderTargetCache::Initialize() {
|
||||
|
||||
gamma_render_target_as_srgb_ = cvars::gamma_render_target_as_srgb;
|
||||
|
||||
depth_float24_conversion_ = GetConfigDepthFloat24Conversion();
|
||||
depth_float24_round_ = cvars::depth_float24_round;
|
||||
depth_float24_convert_in_pixel_shader_ =
|
||||
cvars::depth_float24_convert_in_pixel_shader;
|
||||
|
||||
// Check if 2x MSAA is supported or needs to be emulated with 4x MSAA
|
||||
// instead.
|
||||
@@ -1013,8 +1015,9 @@ bool D3D12RenderTargetCache::Initialize() {
|
||||
// Blending is done in linear space directly in shaders.
|
||||
gamma_render_target_as_srgb_ = false;
|
||||
|
||||
// Always true float24 depth.
|
||||
depth_float24_conversion_ = DepthFloat24Conversion::kOnOutputRounding;
|
||||
// Always true float24 depth rounded to the nearest even.
|
||||
depth_float24_round_ = true;
|
||||
depth_float24_convert_in_pixel_shader_ = true;
|
||||
|
||||
// Only ForcedSampleCount, which doesn't support 2x.
|
||||
msaa_2x_supported_ = false;
|
||||
@@ -2091,7 +2094,7 @@ RenderTargetCache::RenderTarget* D3D12RenderTargetCache::CreateRenderTarget(
|
||||
bool D3D12RenderTargetCache::IsHostDepthEncodingDifferent(
|
||||
xenos::DepthRenderTargetFormat format) const {
|
||||
if (format == xenos::DepthRenderTargetFormat::kD24FS8) {
|
||||
return depth_float24_conversion_ == DepthFloat24Conversion::kOnCopy;
|
||||
return !depth_float24_convert_in_pixel_shader_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -3542,8 +3545,8 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
} break;
|
||||
case xenos::DepthRenderTargetFormat::kD24FS8: {
|
||||
// Convert using r1.y as temporary.
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(a, i, 3, i, 3, 1, 1,
|
||||
true);
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(
|
||||
a, i, 3, i, 3, 1, 1, depth_float24_round(), true);
|
||||
} break;
|
||||
}
|
||||
// Merge depth and stencil into r0/r1.x.
|
||||
@@ -3729,8 +3732,8 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
} break;
|
||||
case xenos::DepthRenderTargetFormat::kD24FS8: {
|
||||
// Convert using r1.y as temporary.
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(a, 1, 3, 1, 3, 1, 1,
|
||||
true);
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(
|
||||
a, 1, 3, 1, 3, 1, 1, depth_float24_round(), true);
|
||||
} break;
|
||||
}
|
||||
if (dest_is_color) {
|
||||
@@ -4105,8 +4108,8 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
|
||||
dxbc::Src::R(0, dxbc::Src::kYYYY));
|
||||
} break;
|
||||
case xenos::DepthRenderTargetFormat::kD24FS8: {
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(a, 0, 1, 0, 0, 0, 2,
|
||||
true);
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(
|
||||
a, 0, 1, 0, 0, 0, 2, depth_float24_round(), true);
|
||||
} break;
|
||||
}
|
||||
a.OpIEq(dxbc::Dest::R(0, 0b0010), dxbc::Src::R(0, dxbc::Src::kYYYY),
|
||||
@@ -6167,7 +6170,8 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
|
||||
case xenos::DepthRenderTargetFormat::kD24FS8:
|
||||
// Convert to [0, 2) float24 from [0, 1) float32, using r0.x as
|
||||
// temporary.
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(a, 1, 0, 1, 0, 0, 0, true);
|
||||
DxbcShaderTranslator::PreClampedDepthTo20e4(
|
||||
a, 1, 0, 1, 0, 0, 0, depth_float24_round(), true);
|
||||
break;
|
||||
}
|
||||
// Combine 24-bit depth and stencil into r1.x.
|
||||
|
||||
@@ -107,8 +107,9 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
|
||||
!cvars::snorm16_render_target_full_range;
|
||||
}
|
||||
|
||||
DepthFloat24Conversion depth_float24_conversion() const {
|
||||
return depth_float24_conversion_;
|
||||
bool depth_float24_round() const { return depth_float24_round_; }
|
||||
bool depth_float24_convert_in_pixel_shader() const {
|
||||
return depth_float24_convert_in_pixel_shader_;
|
||||
}
|
||||
|
||||
DXGI_FORMAT GetColorResourceDXGIFormat(
|
||||
@@ -720,8 +721,8 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
|
||||
|
||||
bool gamma_render_target_as_srgb_ = false;
|
||||
|
||||
DepthFloat24Conversion depth_float24_conversion_ =
|
||||
DepthFloat24Conversion::kOnCopy;
|
||||
bool depth_float24_round_ = false;
|
||||
bool depth_float24_convert_in_pixel_shader_ = false;
|
||||
|
||||
bool msaa_2x_supported_ = false;
|
||||
|
||||
|
||||
@@ -882,20 +882,14 @@ PipelineCache::GetCurrentPixelShaderModification(
|
||||
RenderTargetCache::Path::kHostRenderTargets) {
|
||||
using DepthStencilMode =
|
||||
DxbcShaderTranslator::Modification::DepthStencilMode;
|
||||
RenderTargetCache::DepthFloat24Conversion depth_float24_conversion =
|
||||
render_target_cache_.depth_float24_conversion();
|
||||
if ((depth_float24_conversion ==
|
||||
RenderTargetCache::DepthFloat24Conversion::kOnOutputTruncating ||
|
||||
depth_float24_conversion ==
|
||||
RenderTargetCache::DepthFloat24Conversion::kOnOutputRounding) &&
|
||||
if (render_target_cache_.depth_float24_convert_in_pixel_shader() &&
|
||||
normalized_depth_control.z_enable &&
|
||||
regs.Get<reg::RB_DEPTH_INFO>().depth_format ==
|
||||
xenos::DepthRenderTargetFormat::kD24FS8) {
|
||||
modification.pixel.depth_stencil_mode =
|
||||
depth_float24_conversion ==
|
||||
RenderTargetCache::DepthFloat24Conversion::kOnOutputTruncating
|
||||
? DepthStencilMode::kFloat24Truncating
|
||||
: DepthStencilMode::kFloat24Rounding;
|
||||
render_target_cache_.depth_float24_round()
|
||||
? DepthStencilMode::kFloat24Rounding
|
||||
: DepthStencilMode::kFloat24Truncating;
|
||||
} else {
|
||||
if (shader.implicit_early_z_write_allowed() &&
|
||||
(!shader.writes_color_target(0) ||
|
||||
@@ -2917,20 +2911,16 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
|
||||
state_desc.PS.pShaderBytecode = depth_only_pixel_shader_.data();
|
||||
state_desc.PS.BytecodeLength = depth_only_pixel_shader_.size();
|
||||
} else {
|
||||
if ((description.depth_func != xenos::CompareFunction::kAlways ||
|
||||
if (render_target_cache_.depth_float24_convert_in_pixel_shader() &&
|
||||
(description.depth_func != xenos::CompareFunction::kAlways ||
|
||||
description.depth_write) &&
|
||||
description.depth_format == xenos::DepthRenderTargetFormat::kD24FS8) {
|
||||
switch (render_target_cache_.depth_float24_conversion()) {
|
||||
case RenderTargetCache::DepthFloat24Conversion::kOnOutputTruncating:
|
||||
state_desc.PS.pShaderBytecode = shaders::float24_truncate_ps;
|
||||
state_desc.PS.BytecodeLength = sizeof(shaders::float24_truncate_ps);
|
||||
break;
|
||||
case RenderTargetCache::DepthFloat24Conversion::kOnOutputRounding:
|
||||
state_desc.PS.pShaderBytecode = shaders::float24_round_ps;
|
||||
state_desc.PS.BytecodeLength = sizeof(shaders::float24_round_ps);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (render_target_cache_.depth_float24_round()) {
|
||||
state_desc.PS.pShaderBytecode = shaders::float24_round_ps;
|
||||
state_desc.PS.BytecodeLength = sizeof(shaders::float24_round_ps);
|
||||
} else {
|
||||
state_desc.PS.pShaderBytecode = shaders::float24_truncate_ps;
|
||||
state_desc.PS.BytecodeLength = sizeof(shaders::float24_truncate_ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user