Draft: Use a fixed-point depth buffer with an unrestricted depth range.
This commit is contained in:
parent
7db13d23c9
commit
a1a43d7da4
|
@ -116,6 +116,7 @@ void VideoBackend::FillBackendInfo()
|
||||||
g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
|
g_Config.backend_info.bSupportsPartialMultisampleResolve = true;
|
||||||
g_Config.backend_info.bSupportsDynamicVertexLoader = false;
|
g_Config.backend_info.bSupportsDynamicVertexLoader = false;
|
||||||
g_Config.backend_info.bSupportsHDROutput = true;
|
g_Config.backend_info.bSupportsHDROutput = true;
|
||||||
|
g_Config.backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||||
|
|
||||||
g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames();
|
g_Config.backend_info.Adapters = D3DCommon::GetAdapterNames();
|
||||||
g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);
|
g_Config.backend_info.AAModes = D3D::GetAAModes(g_Config.iAdapter);
|
||||||
|
|
|
@ -133,7 +133,7 @@ void Gfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_enab
|
||||||
->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
|
||||||
|
|
||||||
// D3D does not support reversed depth ranges.
|
// D3D does not support reversed depth ranges.
|
||||||
const float clear_depth = 1.0f - static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
|
const float clear_depth = 1.0f - static_cast<float>(z & 0xFFFFFF) / 16777215.0f;
|
||||||
d3d_frame_buffer->ClearDepth(clear_depth, &d3d_clear_rc);
|
d3d_frame_buffer->ClearDepth(clear_depth, &d3d_clear_rc);
|
||||||
z_enable = false;
|
z_enable = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ void VideoBackend::FillBackendInfo()
|
||||||
g_Config.backend_info.bSupportsDynamicVertexLoader = true;
|
g_Config.backend_info.bSupportsDynamicVertexLoader = true;
|
||||||
g_Config.backend_info.bSupportsVSLinePointExpand = true;
|
g_Config.backend_info.bSupportsVSLinePointExpand = true;
|
||||||
g_Config.backend_info.bSupportsHDROutput = true;
|
g_Config.backend_info.bSupportsHDROutput = true;
|
||||||
|
g_Config.backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||||
|
|
||||||
// We can only check texture support once we have a device.
|
// We can only check texture support once we have a device.
|
||||||
if (g_dx_context)
|
if (g_dx_context)
|
||||||
|
|
|
@ -79,6 +79,7 @@ void Metal::Util::PopulateBackendInfo(VideoConfig* config)
|
||||||
config->backend_info.bSupportsVSLinePointExpand = true;
|
config->backend_info.bSupportsVSLinePointExpand = true;
|
||||||
config->backend_info.bSupportsHDROutput =
|
config->backend_info.bSupportsHDROutput =
|
||||||
1.0 < [[NSScreen deepestScreen] maximumPotentialExtendedDynamicRangeColorComponentValue];
|
1.0 < [[NSScreen deepestScreen] maximumPotentialExtendedDynamicRangeColorComponentValue];
|
||||||
|
config->backend_info.bSupportsUnrestrictedDepthRange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config,
|
void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config,
|
||||||
|
|
|
@ -349,6 +349,8 @@ bool PopulateConfig(GLContext* m_main_gl_context)
|
||||||
GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450;
|
GLExtensions::Supports("GL_ARB_derivative_control") || GLExtensions::Version() >= 450;
|
||||||
g_Config.backend_info.bSupportsTextureQueryLevels =
|
g_Config.backend_info.bSupportsTextureQueryLevels =
|
||||||
GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430;
|
GLExtensions::Supports("GL_ARB_texture_query_levels") || GLExtensions::Version() >= 430;
|
||||||
|
g_Config.backend_info.bSupportsUnrestrictedDepthRange =
|
||||||
|
GLExtensions::Supports("GL_NV_depth_buffer_float");
|
||||||
|
|
||||||
if (GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"))
|
if (GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,6 +118,16 @@ static void APIENTRY ClearDepthf(GLfloat depthval)
|
||||||
glClearDepth(depthval);
|
glClearDepth(depthval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Two small overrides to support unrestricted depth range
|
||||||
|
static void APIENTRY DepthRangefNV(GLfloat neardepth, GLfloat fardepth)
|
||||||
|
{
|
||||||
|
glDepthRangedNV(neardepth, fardepth);
|
||||||
|
}
|
||||||
|
static void APIENTRY ClearDepthfNV(GLfloat depthval)
|
||||||
|
{
|
||||||
|
glClearDepthdNV(depthval);
|
||||||
|
}
|
||||||
|
|
||||||
OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scale)
|
OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scale)
|
||||||
: m_main_gl_context(std::move(main_gl_context)),
|
: m_main_gl_context(std::move(main_gl_context)),
|
||||||
m_current_rasterization_state(RenderState::GetInvalidRasterizationState()),
|
m_current_rasterization_state(RenderState::GetInvalidRasterizationState()),
|
||||||
|
@ -136,12 +146,17 @@ OGLGfx::OGLGfx(std::unique_ptr<GLContext> main_gl_context, float backbuffer_scal
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_main_gl_context->IsGLES())
|
if (!m_main_gl_context->IsGLES())
|
||||||
|
{
|
||||||
|
if (g_ActiveConfig.backend_info.bSupportsUnrestrictedDepthRange)
|
||||||
|
{
|
||||||
|
glDepthRangef = DepthRangefNV;
|
||||||
|
glClearDepthf = ClearDepthfNV;
|
||||||
|
}
|
||||||
|
else if (!GLExtensions::Supports("GL_ARB_ES2_compatibility"))
|
||||||
{
|
{
|
||||||
// OpenGL 3 doesn't provide GLES like float functions for depth.
|
// OpenGL 3 doesn't provide GLES like float functions for depth.
|
||||||
// They are in core in OpenGL 4.1, so almost every driver should support them.
|
// They are in core in OpenGL 4.1, so almost every driver should support them.
|
||||||
// But for the oldest ones, we provide fallbacks to the old double functions.
|
// But for the oldest ones, we provide fallbacks to the old double functions.
|
||||||
if (!GLExtensions::Supports("GL_ARB_ES2_compatibility"))
|
|
||||||
{
|
|
||||||
glDepthRangef = DepthRangef;
|
glDepthRangef = DepthRangef;
|
||||||
glClearDepthf = ClearDepthf;
|
glClearDepthf = ClearDepthf;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +402,7 @@ void OGLGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool colorEn
|
||||||
if (zEnable)
|
if (zEnable)
|
||||||
{
|
{
|
||||||
glDepthMask(zEnable ? GL_TRUE : GL_FALSE);
|
glDepthMask(zEnable ? GL_TRUE : GL_FALSE);
|
||||||
glClearDepthf(float(z & 0xFFFFFF) / 16777216.0f);
|
glClearDepthf(float(z & 0xFFFFFF) / 16777215.0f);
|
||||||
clear_mask |= GL_DEPTH_BUFFER_BIT;
|
clear_mask |= GL_DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,14 @@ GLenum OGLTexture::GetGLInternalFormatForTextureFormat(AbstractTextureFormat for
|
||||||
case AbstractTextureFormat::D24_S8:
|
case AbstractTextureFormat::D24_S8:
|
||||||
return GL_DEPTH24_STENCIL8;
|
return GL_DEPTH24_STENCIL8;
|
||||||
case AbstractTextureFormat::D32F:
|
case AbstractTextureFormat::D32F:
|
||||||
|
if (g_ActiveConfig.backend_info.bSupportsUnrestrictedDepthRange)
|
||||||
|
return GL_DEPTH_COMPONENT32F_NV;
|
||||||
|
else
|
||||||
return GL_DEPTH_COMPONENT32F;
|
return GL_DEPTH_COMPONENT32F;
|
||||||
case AbstractTextureFormat::D32F_S8:
|
case AbstractTextureFormat::D32F_S8:
|
||||||
|
if (g_ActiveConfig.backend_info.bSupportsUnrestrictedDepthRange)
|
||||||
|
return GL_DEPTH32F_STENCIL8_NV;
|
||||||
|
else
|
||||||
return GL_DEPTH32F_STENCIL8;
|
return GL_DEPTH32F_STENCIL8;
|
||||||
default:
|
default:
|
||||||
PanicAlertFmt("Unhandled texture format.");
|
PanicAlertFmt("Unhandled texture format.");
|
||||||
|
|
|
@ -117,7 +117,7 @@ void VKGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool color_en
|
||||||
clear_color_value.color.float32[1] = static_cast<float>((color >> 8) & 0xFF) / 255.0f;
|
clear_color_value.color.float32[1] = static_cast<float>((color >> 8) & 0xFF) / 255.0f;
|
||||||
clear_color_value.color.float32[2] = static_cast<float>((color >> 0) & 0xFF) / 255.0f;
|
clear_color_value.color.float32[2] = static_cast<float>((color >> 0) & 0xFF) / 255.0f;
|
||||||
clear_color_value.color.float32[3] = static_cast<float>((color >> 24) & 0xFF) / 255.0f;
|
clear_color_value.color.float32[3] = static_cast<float>((color >> 24) & 0xFF) / 255.0f;
|
||||||
clear_depth_value.depthStencil.depth = static_cast<float>(z & 0xFFFFFF) / 16777216.0f;
|
clear_depth_value.depthStencil.depth = static_cast<float>(z & 0xFFFFFF) / 16777215.0f;
|
||||||
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
||||||
clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth;
|
clear_depth_value.depthStencil.depth = 1.0f - clear_depth_value.depthStencil.depth;
|
||||||
|
|
||||||
|
|
|
@ -471,6 +471,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
|
||||||
config->backend_info.bSupportsDynamicVertexLoader = true; // Assumed support.
|
config->backend_info.bSupportsDynamicVertexLoader = true; // Assumed support.
|
||||||
config->backend_info.bSupportsVSLinePointExpand = true; // Assumed support.
|
config->backend_info.bSupportsVSLinePointExpand = true; // Assumed support.
|
||||||
config->backend_info.bSupportsHDROutput = true; // Assumed support.
|
config->backend_info.bSupportsHDROutput = true; // Assumed support.
|
||||||
|
config->backend_info.bSupportsUnrestrictedDepthRange = false; // Dependent on features.
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list)
|
void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list)
|
||||||
|
@ -676,6 +677,9 @@ bool VulkanContext::SelectDeviceExtensions(bool enable_surface)
|
||||||
AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
|
AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
|
||||||
AddExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, false);
|
AddExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, false);
|
||||||
|
|
||||||
|
g_Config.backend_info.bSupportsUnrestrictedDepthRange =
|
||||||
|
AddExtension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ void AbstractGfx::ClearRegion(const MathUtil::Rectangle<int>& target_rc, bool co
|
||||||
static_cast<float>((color >> 8) & 0xFF) / 255.0f,
|
static_cast<float>((color >> 8) & 0xFF) / 255.0f,
|
||||||
static_cast<float>((color >> 0) & 0xFF) / 255.0f,
|
static_cast<float>((color >> 0) & 0xFF) / 255.0f,
|
||||||
static_cast<float>((color >> 24) & 0xFF) / 255.0f},
|
static_cast<float>((color >> 24) & 0xFF) / 255.0f},
|
||||||
static_cast<float>(z & 0xFFFFFF) / 16777216.0f};
|
static_cast<float>(z & 0xFFFFFF) / 16777215.0f};
|
||||||
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
||||||
uniforms.clear_depth = 1.0f - uniforms.clear_depth;
|
uniforms.clear_depth = 1.0f - uniforms.clear_depth;
|
||||||
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
|
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
|
||||||
|
|
|
@ -203,8 +203,8 @@ void SetScissorAndViewport()
|
||||||
float y = g_framebuffer_manager->EFBToScaledYf(raw_y);
|
float y = g_framebuffer_manager->EFBToScaledYf(raw_y);
|
||||||
float width = g_framebuffer_manager->EFBToScaledXf(raw_width);
|
float width = g_framebuffer_manager->EFBToScaledXf(raw_width);
|
||||||
float height = g_framebuffer_manager->EFBToScaledYf(raw_height);
|
float height = g_framebuffer_manager->EFBToScaledYf(raw_height);
|
||||||
float min_depth = (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f;
|
float min_depth = (xfmem.viewport.farZ / 16777215.0f - xfmem.viewport.zRange / 16777215.0f);
|
||||||
float max_depth = xfmem.viewport.farZ / 16777216.0f;
|
float max_depth = xfmem.viewport.farZ / 16777215.0f;
|
||||||
if (width < 0.f)
|
if (width < 0.f)
|
||||||
{
|
{
|
||||||
x += width;
|
x += width;
|
||||||
|
@ -216,17 +216,12 @@ void SetScissorAndViewport()
|
||||||
height *= -1;
|
height *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
|
||||||
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||||
{
|
{
|
||||||
// There's no way to support oversized depth ranges in this situation. Let's just clamp the
|
// There's no way to support oversized depth ranges in this situation. Let's just clamp the
|
||||||
// range to the maximum value supported by the console GPU and hope for the best.
|
// range to the maximum value supported by the console GPU and hope for the best.
|
||||||
min_depth = std::clamp(min_depth, 0.0f, GX_MAX_DEPTH);
|
min_depth = std::clamp(min_depth, 0.0f, 1.0f);
|
||||||
max_depth = std::clamp(max_depth, 0.0f, GX_MAX_DEPTH);
|
max_depth = std::clamp(max_depth, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VertexShaderManager::UseVertexDepthRange())
|
if (VertexShaderManager::UseVertexDepthRange())
|
||||||
|
@ -235,13 +230,13 @@ void SetScissorAndViewport()
|
||||||
// Taking into account whether the depth range is inverted or not.
|
// Taking into account whether the depth range is inverted or not.
|
||||||
if (xfmem.viewport.zRange < 0.0f && g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
if (xfmem.viewport.zRange < 0.0f && g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
||||||
{
|
{
|
||||||
min_depth = GX_MAX_DEPTH;
|
min_depth = 1.0f;
|
||||||
max_depth = 0.0f;
|
max_depth = 0.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
min_depth = 0.0f;
|
min_depth = 0.0f;
|
||||||
max_depth = GX_MAX_DEPTH;
|
max_depth = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,13 +131,7 @@ AbstractTextureFormat FramebufferManager::GetEFBColorFormat()
|
||||||
|
|
||||||
AbstractTextureFormat FramebufferManager::GetEFBDepthFormat()
|
AbstractTextureFormat FramebufferManager::GetEFBDepthFormat()
|
||||||
{
|
{
|
||||||
// 32-bit depth clears are broken in the Adreno Vulkan driver, and have no effect.
|
|
||||||
// To work around this, we use a D24_S8 buffer instead, which results in a loss of accuracy.
|
|
||||||
// We still resolve this to a R32F texture, as there is no 24-bit format.
|
|
||||||
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_D32F_CLEAR))
|
|
||||||
return AbstractTextureFormat::D24_S8;
|
return AbstractTextureFormat::D24_S8;
|
||||||
else
|
|
||||||
return AbstractTextureFormat::D32F;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractTextureFormat FramebufferManager::GetEFBDepthCopyFormat()
|
AbstractTextureFormat FramebufferManager::GetEFBDepthCopyFormat()
|
||||||
|
|
|
@ -1261,9 +1261,9 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!host_config.backend_reversed_depth_range)
|
if (!host_config.backend_reversed_depth_range)
|
||||||
out.Write("\tint zCoord = int((1.0 - rawpos.z) * 16777216.0);\n");
|
out.Write("\tint zCoord = int((1.0 - rawpos.z) * 16777215.0);\n");
|
||||||
else
|
else
|
||||||
out.Write("\tint zCoord = int(rawpos.z * 16777216.0);\n");
|
out.Write("\tint zCoord = int(rawpos.z * 16777215.0);\n");
|
||||||
}
|
}
|
||||||
out.Write("\tzCoord = clamp(zCoord, 0, 0xFFFFFF);\n");
|
out.Write("\tzCoord = clamp(zCoord, 0, 0xFFFFFF);\n");
|
||||||
|
|
||||||
|
@ -1278,9 +1278,9 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
|
||||||
if (uid_data->per_pixel_depth && early_ztest)
|
if (uid_data->per_pixel_depth && early_ztest)
|
||||||
{
|
{
|
||||||
if (!host_config.backend_reversed_depth_range)
|
if (!host_config.backend_reversed_depth_range)
|
||||||
out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n");
|
out.Write("\tdepth = 1.0 - float(zCoord) / 16777215.0;\n");
|
||||||
else
|
else
|
||||||
out.Write("\tdepth = float(zCoord) / 16777216.0;\n");
|
out.Write("\tdepth = float(zCoord) / 16777215.0;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: depth texture output is only written to depth buffer if late depth test is used
|
// Note: depth texture output is only written to depth buffer if late depth test is used
|
||||||
|
@ -1299,9 +1299,9 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
|
||||||
if (uid_data->per_pixel_depth && uid_data->ztest == EmulatedZ::Late)
|
if (uid_data->per_pixel_depth && uid_data->ztest == EmulatedZ::Late)
|
||||||
{
|
{
|
||||||
if (!host_config.backend_reversed_depth_range)
|
if (!host_config.backend_reversed_depth_range)
|
||||||
out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n");
|
out.Write("\tdepth = 1.0 - float(zCoord) / 16777215.0;\n");
|
||||||
else
|
else
|
||||||
out.Write("\tdepth = float(zCoord) / 16777216.0;\n");
|
out.Write("\tdepth = float(zCoord) / 16777215.0;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// No dithering for RGB8 mode
|
// No dithering for RGB8 mode
|
||||||
|
@ -1977,14 +1977,14 @@ static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data)
|
||||||
// renderer)
|
// renderer)
|
||||||
// Maybe we want to use "ze = (A << B_SHF)/((B << B_SHF) - Zs)" instead?
|
// Maybe we want to use "ze = (A << B_SHF)/((B << B_SHF) - Zs)" instead?
|
||||||
// That's equivalent, but keeps the lower bits of Zs.
|
// That's equivalent, but keeps the lower bits of Zs.
|
||||||
out.Write("\tfloat ze = (" I_FOGF ".x * 16777216.0) / float(" I_FOGI ".y - (zCoord >> " I_FOGI
|
out.Write("\tfloat ze = (" I_FOGF ".x * 16777215.0) / float(" I_FOGI ".y - (zCoord >> " I_FOGI
|
||||||
".w));\n");
|
".w));\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// orthographic
|
// orthographic
|
||||||
// ze = a*Zs (here, no B_SHF)
|
// ze = a*Zs (here, no B_SHF)
|
||||||
out.Write("\tfloat ze = " I_FOGF ".x * float(zCoord) / 16777216.0;\n");
|
out.Write("\tfloat ze = " I_FOGF ".x * float(zCoord) / 16777215.0;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// x_adjust = sqrt((x-center)^2 + k^2)/k
|
// x_adjust = sqrt((x-center)^2 + k^2)/k
|
||||||
|
|
|
@ -127,7 +127,7 @@ static void WriteSampleFunction(ShaderCode& code, const EFBCopyParams& params, A
|
||||||
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
||||||
code.Write(" tex_sample.x = 1.0 - tex_sample.x;\n");
|
code.Write(" tex_sample.x = 1.0 - tex_sample.x;\n");
|
||||||
|
|
||||||
code.Write(" uint depth = uint(tex_sample.x * 16777216.0);\n"
|
code.Write(" uint depth = uint(tex_sample.x * 16777215.0);\n"
|
||||||
" return uint4((depth >> 16) & 255u, (depth >> 8) & 255u, depth & 255u, 255u);\n"
|
" return uint4((depth >> 16) & 255u, (depth >> 8) & 255u, depth & 255u, 255u);\n"
|
||||||
"}}\n");
|
"}}\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ ShaderCode GeneratePixelShader(APIType api_type, const UidData* uid_data)
|
||||||
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
|
||||||
out.Write(" tex_sample.x = 1.0 - tex_sample.x;\n");
|
out.Write(" tex_sample.x = 1.0 - tex_sample.x;\n");
|
||||||
|
|
||||||
out.Write(" uint depth = uint(tex_sample.x * 16777216.0);\n"
|
out.Write(" uint depth = uint(tex_sample.x * 16777215.0);\n"
|
||||||
" return uint4((depth >> 16) & 255u, (depth >> 8) & 255u, depth & 255u, 255u);\n"
|
" return uint4((depth >> 16) & 255u, (depth >> 8) & 255u, depth & 255u, 255u);\n"
|
||||||
"}}\n");
|
"}}\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1327,9 +1327,9 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
|
||||||
if (host_config.fast_depth_calc)
|
if (host_config.fast_depth_calc)
|
||||||
{
|
{
|
||||||
if (!host_config.backend_reversed_depth_range)
|
if (!host_config.backend_reversed_depth_range)
|
||||||
out.Write(" int zCoord = int((1.0 - rawpos.z) * 16777216.0);\n");
|
out.Write(" int zCoord = int((1.0 - rawpos.z) * 16777215.0);\n");
|
||||||
else
|
else
|
||||||
out.Write(" int zCoord = int(rawpos.z * 16777216.0);\n");
|
out.Write(" int zCoord = int(rawpos.z * 16777215.0);\n");
|
||||||
out.Write(" zCoord = clamp(zCoord, 0, 0xFFFFFF);\n"
|
out.Write(" zCoord = clamp(zCoord, 0, 0xFFFFFF);\n"
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
@ -1383,9 +1383,9 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
|
||||||
" // If early depth isn't enabled, we write to the zbuffer here\n"
|
" // If early depth isn't enabled, we write to the zbuffer here\n"
|
||||||
" int zbuffer_zCoord = bpmem_late_ztest ? zCoord : early_zCoord;\n");
|
" int zbuffer_zCoord = bpmem_late_ztest ? zCoord : early_zCoord;\n");
|
||||||
if (!host_config.backend_reversed_depth_range)
|
if (!host_config.backend_reversed_depth_range)
|
||||||
out.Write(" depth = 1.0 - float(zbuffer_zCoord) / 16777216.0;\n");
|
out.Write(" depth = 1.0 - float(zbuffer_zCoord) / 16777215.0;\n");
|
||||||
else
|
else
|
||||||
out.Write(" depth = float(zbuffer_zCoord) / 16777216.0;\n");
|
out.Write(" depth = float(zbuffer_zCoord) / 16777215.0;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
out.Write(" // Alpha Test\n");
|
out.Write(" // Alpha Test\n");
|
||||||
|
@ -1454,12 +1454,12 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
|
||||||
BitfieldExtract<&FogParam3::proj>("bpmem_fogParam3"));
|
BitfieldExtract<&FogParam3::proj>("bpmem_fogParam3"));
|
||||||
out.Write(" // perspective\n"
|
out.Write(" // perspective\n"
|
||||||
" // ze = A/(B - (Zs >> B_SHF)\n"
|
" // ze = A/(B - (Zs >> B_SHF)\n"
|
||||||
" ze = (" I_FOGF ".x * 16777216.0) / float(" I_FOGI ".y - (zCoord >> " I_FOGI
|
" ze = (" I_FOGF ".x * 16777215.0) / float(" I_FOGI ".y - (zCoord >> " I_FOGI
|
||||||
".w));\n"
|
".w));\n"
|
||||||
" }} else {{\n"
|
" }} else {{\n"
|
||||||
" // orthographic\n"
|
" // orthographic\n"
|
||||||
" // ze = a*Zs (here, no B_SHF)\n"
|
" // ze = a*Zs (here, no B_SHF)\n"
|
||||||
" ze = " I_FOGF ".x * float(zCoord) / 16777216.0;\n"
|
" ze = " I_FOGF ".x * float(zCoord) / 16777215.0;\n"
|
||||||
" }}\n"
|
" }}\n"
|
||||||
"\n"
|
"\n"
|
||||||
" if (bool({})) {{\n",
|
" if (bool({})) {{\n",
|
||||||
|
|
|
@ -139,6 +139,9 @@ void VertexShaderManager::SetProjectionMatrix(XFStateManager& xf_state_manager)
|
||||||
|
|
||||||
bool VertexShaderManager::UseVertexDepthRange()
|
bool VertexShaderManager::UseVertexDepthRange()
|
||||||
{
|
{
|
||||||
|
if (g_Config.backend_info.bSupportsUnrestrictedDepthRange)
|
||||||
|
return false;
|
||||||
|
|
||||||
// We can't compute the depth range in the vertex shader if we don't support depth clamp.
|
// We can't compute the depth range in the vertex shader if we don't support depth clamp.
|
||||||
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -338,6 +338,7 @@ struct VideoConfig final
|
||||||
bool bSupportsVSLinePointExpand = false;
|
bool bSupportsVSLinePointExpand = false;
|
||||||
bool bSupportsGLLayerInFS = true;
|
bool bSupportsGLLayerInFS = true;
|
||||||
bool bSupportsHDROutput = false;
|
bool bSupportsHDROutput = false;
|
||||||
|
bool bSupportsUnrestrictedDepthRange = false;
|
||||||
} backend_info;
|
} backend_info;
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
|
|
Loading…
Reference in New Issue