mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 05:17:44 -07:00
VideoCommon: Always utilize unrestricted depth range to get rid of normalization.
This commit is contained in:
parent
9f9b1752cb
commit
e0fe72bfc0
@ -117,6 +117,7 @@ void VideoBackend::FillBackendInfo()
|
||||
g_Config.backend_info.bSupportsDynamicVertexLoader = false;
|
||||
g_Config.backend_info.bSupportsHDROutput = true;
|
||||
g_Config.backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||
g_Config.backend_info.bSupportsDepthClampControl = false;
|
||||
|
||||
g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames();
|
||||
g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);
|
||||
|
@ -92,6 +92,7 @@ void VideoBackend::FillBackendInfo()
|
||||
g_Config.backend_info.bSupportsVSLinePointExpand = true;
|
||||
g_Config.backend_info.bSupportsHDROutput = true;
|
||||
g_Config.backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||
g_Config.backend_info.bSupportsDepthClampControl = false;
|
||||
|
||||
// We can only check texture support once we have a device.
|
||||
if (g_dx_context)
|
||||
|
@ -80,6 +80,7 @@ void Metal::Util::PopulateBackendInfo(VideoConfig* config)
|
||||
config->backend_info.bSupportsHDROutput =
|
||||
1.0 < [[NSScreen deepestScreen] maximumPotentialExtendedDynamicRangeColorComponentValue];
|
||||
config->backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||
config->backend_info.bSupportsDepthClampControl = false;
|
||||
}
|
||||
|
||||
void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config,
|
||||
|
@ -64,6 +64,7 @@ void VideoBackend::InitBackendInfo(const WindowSystemInfo& wsi)
|
||||
g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
|
||||
g_Config.backend_info.bSupportsDynamicVertexLoader = false;
|
||||
g_Config.backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||
g_Config.backend_info.bSupportsDepthClampControl = false;
|
||||
|
||||
// aamodes: We only support 1 sample, so no MSAA
|
||||
g_Config.backend_info.Adapters.clear();
|
||||
|
@ -136,6 +136,7 @@ bool VideoBackend::FillBackendInfo(GLContext* context)
|
||||
// Unneccessary since OGL doesn't use pipelines
|
||||
g_Config.backend_info.bSupportsDynamicVertexLoader = false;
|
||||
g_Config.backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||
g_Config.backend_info.bSupportsDepthClampControl = false;
|
||||
|
||||
// TODO: There is a bug here, if texel buffers or SSBOs/atomics are not supported the graphics
|
||||
// options will show the option when it is not supported. The only way around this would be
|
||||
|
@ -472,6 +472,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
|
||||
config->backend_info.bSupportsVSLinePointExpand = true; // Assumed support.
|
||||
config->backend_info.bSupportsHDROutput = true; // Assumed support.
|
||||
config->backend_info.bSupportsUnrestrictedDepthRange = false; // Dependent on features.
|
||||
config->backend_info.bSupportsDepthClampControl = false; // Dependent on features.
|
||||
}
|
||||
|
||||
void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list)
|
||||
@ -677,12 +678,9 @@ bool VulkanContext::SelectDeviceExtensions(bool enable_surface)
|
||||
AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
|
||||
AddExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, false);
|
||||
|
||||
// Enabling the depth clamp control extension is harmless, but we need to ensure
|
||||
// we don't enable the unrestricted depth range extension unless we can actually
|
||||
// make use of it.
|
||||
g_Config.backend_info.bSupportsUnrestrictedDepthRange =
|
||||
AddExtension(VK_EXT_DEPTH_CLAMP_CONTROL_EXTENSION_NAME, false) &&
|
||||
AddExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, false);
|
||||
g_Config.backend_info.bSupportsUnrestrictedDepthRange = AddExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, false);
|
||||
if (g_Config.backend_info.bSupportsUnrestrictedDepthRange)
|
||||
g_Config.backend_info.bSupportsDepthClampControl = AddExtension(VK_EXT_DEPTH_CLAMP_CONTROL_EXTENSION_NAME, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -215,17 +215,12 @@ void SetScissorAndViewport()
|
||||
y += height;
|
||||
height *= -1;
|
||||
}
|
||||
if (!g_ActiveConfig.backend_info.bSupportsUnrestrictedDepthRange)
|
||||
{
|
||||
min_depth = min_depth / 16777216.0f;
|
||||
max_depth = max_depth / 16777216.0f;
|
||||
}
|
||||
|
||||
// The maximum depth that is written to the depth buffer should never exceed this value.
|
||||
// This is necessary because we use a 2^24 divisor for all our depth values to prevent
|
||||
// floating-point round-trip errors. However the console GPU doesn't ever write a value
|
||||
// to the depth buffer that exceeds 2^24 - 1.
|
||||
constexpr float GX_MAX_DEPTH = 16777215.0f / 16777216.0f;
|
||||
constexpr float GX_MAX_DEPTH = 16777215.0f;
|
||||
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
{
|
||||
// There's no way to support oversized depth ranges in this situation. Let's just clamp the
|
||||
@ -250,6 +245,12 @@ void SetScissorAndViewport()
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_ActiveConfig.backend_info.bSupportsUnrestrictedDepthRange)
|
||||
{
|
||||
min_depth /= 16777216.0f;
|
||||
max_depth /= 16777216.0f;
|
||||
}
|
||||
|
||||
float near_depth, far_depth;
|
||||
if (g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
||||
{
|
||||
|
@ -432,27 +432,27 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
|
||||
// if not then early z culling will improve speed.
|
||||
//
|
||||
// The depth range can also be oversized beyond the range supported by the depth buffer. The final
|
||||
// depth value will still be clamped to the 0..1 range, so these games effectively add a depth
|
||||
// bias to the values written to the depth buffer.
|
||||
// depth value will still be clamped to the 0..2^24-1 range, so these games effectively add a
|
||||
// depth bias to the values written to the depth buffer.
|
||||
//
|
||||
// If an unrestricted depth range is supported then we can let host driver handle the oversized
|
||||
// depth range. This can only work if the host driver also supports a feature to allow us to
|
||||
// clamp any depth values that are beyond the supported 0..2^24-1 of the depth buffer.
|
||||
//
|
||||
// If only a depth range of 0..1 is supported then we process the depth equation in the vertex
|
||||
// shader and handle the depth clamp by setting the depth range to 0..(2^24-1)/(2^24).
|
||||
//
|
||||
// If the depth range is not oversized or when we let the host driver handle the oversized depth
|
||||
// range then the constants in this equation will be set so that z = -z.
|
||||
out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - "
|
||||
"o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n");
|
||||
|
||||
if (host_config.backend_unrestricted_depth_range)
|
||||
{
|
||||
// If an unrestricted depth range is supported then we let host driver handle the oversized
|
||||
// depth range. This can only work if the host driver also supports a feature to allow us to
|
||||
// clamp any depth values that are beyond the supported 0..2^24-1 of the depth buffer.
|
||||
// On top of that we also get rid of any normalization to further avoid rounding errors.
|
||||
//
|
||||
// Getting rid of the normalization additionally allows us to add a small depth bias to
|
||||
// influence rounding behaviour since the console expects the depth value to be truncated
|
||||
// before being added to the far value of the depth range.
|
||||
out.Write("o.pos.z = -o.pos.z + (0.5 / 16777216.0);\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// If only a depth range of 0..1 is supported then we process the depth equation in the vertex
|
||||
// shader and handle the depth clamp by setting the depth range to 0..(2^24-1)/(2^24).
|
||||
// If the depth range is not oversized then this equation will be set to so that z = -z.
|
||||
out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - "
|
||||
"o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n");
|
||||
// If we don't use normalization then we can add a small depth bias to influence rounding
|
||||
// behaviour since the console expects the depth value to be truncated before being added
|
||||
// to the far value of the depth range.
|
||||
out.Write("o.pos.z += (0.5 / 16777216.0);\n");
|
||||
}
|
||||
|
||||
if (!host_config.backend_clip_control)
|
||||
|
@ -618,27 +618,27 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
||||
// if not then early z culling will improve speed.
|
||||
//
|
||||
// The depth range can also be oversized beyond the range supported by the depth buffer. The final
|
||||
// depth value will still be clamped to the 0..1 range, so these games effectively add a depth
|
||||
// bias to the values written to the depth buffer.
|
||||
// depth value will still be clamped to the 0..2^24-1 range, so these games effectively add a
|
||||
// depth bias to the values written to the depth buffer.
|
||||
//
|
||||
// If an unrestricted depth range is supported then we can let host driver handle the oversized
|
||||
// depth range. This can only work if the host driver also supports a feature to allow us to
|
||||
// clamp any depth values that are beyond the supported 0..2^24-1 of the depth buffer.
|
||||
//
|
||||
// If only a depth range of 0..1 is supported then we process the depth equation in the vertex
|
||||
// shader and handle the depth clamp by setting the depth range to 0..(2^24-1)/(2^24).
|
||||
//
|
||||
// If the depth range is not oversized or when we let the host driver handle the oversized depth
|
||||
// range then the constants in this equation will be set so that z = -z.
|
||||
out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - "
|
||||
"o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n");
|
||||
|
||||
if (host_config.backend_unrestricted_depth_range)
|
||||
{
|
||||
// If an unrestricted depth range is supported then we let host driver handle the oversized
|
||||
// depth range. This can only work if the host driver also supports a feature to allow us to
|
||||
// clamp any depth values that are beyond the supported 0..2^24-1 of the depth buffer.
|
||||
// On top of that we also get rid of any normalization to further avoid rounding errors.
|
||||
//
|
||||
// Getting rid of the normalization additionally allows us to add a small depth bias to
|
||||
// influence rounding behaviour since the console expects the depth value to be truncated
|
||||
// before being added to the far value of the depth range.
|
||||
out.Write("o.pos.z = -o.pos.z + (0.5 / 16777216.0);\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// If only a depth range of 0..1 is supported then we process the depth equation in the vertex
|
||||
// shader and handle the depth clamp by setting the depth range to 0..(2^24-1)/(2^24).
|
||||
// If the depth range is not oversized then this equation will be set to so that z = -z.
|
||||
out.Write("o.pos.z = o.pos.w * " I_PIXELCENTERCORRECTION ".w - "
|
||||
"o.pos.z * " I_PIXELCENTERCORRECTION ".z;\n");
|
||||
// If we don't use normalization then we can add a small depth bias to influence rounding
|
||||
// behaviour since the console expects the depth value to be truncated before being added
|
||||
// to the far value of the depth range.
|
||||
out.Write("o.pos.z += (0.5 / 16777216.0);\n");
|
||||
}
|
||||
|
||||
if (!host_config.backend_clip_control)
|
||||
|
@ -140,7 +140,7 @@ void VertexShaderManager::SetProjectionMatrix(XFStateManager& xf_state_manager)
|
||||
bool VertexShaderManager::UseVertexDepthRange()
|
||||
{
|
||||
// Backend has full native support for the depth range including clamping the depth.
|
||||
if (g_ActiveConfig.backend_info.bSupportsUnrestrictedDepthRange)
|
||||
if (g_ActiveConfig.backend_info.bSupportsDepthClampControl)
|
||||
return false;
|
||||
|
||||
// We can't compute the depth range in the vertex shader if we don't support depth clamp.
|
||||
|
@ -339,6 +339,7 @@ struct VideoConfig final
|
||||
bool bSupportsGLLayerInFS = true;
|
||||
bool bSupportsHDROutput = false;
|
||||
bool bSupportsUnrestrictedDepthRange = false;
|
||||
bool bSupportsDepthClampControl = false;
|
||||
} backend_info;
|
||||
|
||||
// Utility
|
||||
|
Loading…
Reference in New Issue
Block a user