diff --git a/UnleashedRecomp/gpu/cache/pipeline_state_cache.h b/UnleashedRecomp/gpu/cache/pipeline_state_cache.h index 42ac5f56..742acd66 100644 --- a/UnleashedRecomp/gpu/cache/pipeline_state_cache.h +++ b/UnleashedRecomp/gpu/cache/pipeline_state_cache.h @@ -125,8 +125,8 @@ { reinterpret_cast(0x86FE3502D5EC24AA),reinterpret_cast(0x94A71CC9B94E3101),reinterpret_cast(0xD452411D3FB80A0D),false,false,false,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::LESS,false,RenderBlendOperation::ADD,0,0,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0xF,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::R16G16_FLOAT,RenderFormat::UNKNOWN,1,false,0x0 }, { reinterpret_cast(0x88F67387B88F932F),reinterpret_cast(0x49101E452DF2FE98),reinterpret_cast(0x84BACD816D86543C),false,true,false,RenderBlend::SRC_ALPHA,RenderBlend::INV_SRC_ALPHA,RenderCullMode::BACK,RenderComparisonFunction::GREATER_EQUAL,true,RenderBlendOperation::ADD,0,0,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0xF,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::R16G16B16A16_FLOAT,RenderFormat::D32_FLOAT,1,false,0x10 }, { reinterpret_cast(0x88F67387B88F932F),reinterpret_cast(0xE2A5413340F573F0),reinterpret_cast(0xF10787EFFEEC0153),false,true,false,RenderBlend::SRC_ALPHA,RenderBlend::INV_SRC_ALPHA,RenderCullMode::BACK,RenderComparisonFunction::GREATER_EQUAL,true,RenderBlendOperation::ADD,0,0,RenderBlend::SRC_ALPHA,RenderBlend::INV_SRC_ALPHA,RenderBlendOperation::ADD,0xF,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::R16G16B16A16_FLOAT,RenderFormat::D32_FLOAT,1,false,0x11 }, -{ reinterpret_cast(0x8E4BB23465BD909E),reinterpret_cast(0x0),reinterpret_cast(0xFFFDDC62D86892F1),false,true,true,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::LESS_EQUAL,false,RenderBlendOperation::ADD,0,0,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0x0,RenderPrimitiveTopology::TRIANGLE_LIST,{ 32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::UNKNOWN,RenderFormat::D32_FLOAT,1,false,0x0 }, -{ reinterpret_cast(0x8E4BB23465BD909E),reinterpret_cast(0x0),reinterpret_cast(0xFFFDDC62D86892F1),false,true,true,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::LESS_EQUAL,false,RenderBlendOperation::ADD,0,0,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0x0,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::UNKNOWN,RenderFormat::D32_FLOAT,1,false,0x0 }, +{ reinterpret_cast(0x8E4BB23465BD909E),reinterpret_cast(0x0),reinterpret_cast(0xFFFDDC62D86892F1),false,true,true,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::LESS_EQUAL,false,RenderBlendOperation::ADD,1,33554,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0x0,RenderPrimitiveTopology::TRIANGLE_LIST,{ 32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::UNKNOWN,RenderFormat::D32_FLOAT,1,false,0x0 }, +{ reinterpret_cast(0x8E4BB23465BD909E),reinterpret_cast(0x0),reinterpret_cast(0xFFFDDC62D86892F1),false,true,true,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::LESS_EQUAL,false,RenderBlendOperation::ADD,1,33554,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0x0,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::UNKNOWN,RenderFormat::D32_FLOAT,1,false,0x0 }, { reinterpret_cast(0x8EA8F71BA3BE59E7),reinterpret_cast(0xA557DD8B24CD2B25),reinterpret_cast(0xEC0CD05EE1B1636),false,false,false,RenderBlend::SRC_ALPHA,RenderBlend::INV_SRC_ALPHA,RenderCullMode::NONE,RenderComparisonFunction::LESS,true,RenderBlendOperation::ADD,0,0,RenderBlend::SRC_ALPHA,RenderBlend::INV_SRC_ALPHA,RenderBlendOperation::ADD,0xF,RenderPrimitiveTopology::TRIANGLE_LIST,{ 28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::R16G16B16A16_FLOAT,RenderFormat::UNKNOWN,1,false,0x10 }, { reinterpret_cast(0x92A8B067B41E9399),reinterpret_cast(0xC135200B644173FA),reinterpret_cast(0x951A1B379F0C5D93),false,true,true,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::GREATER_EQUAL,false,RenderBlendOperation::ADD,0,0,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0xF,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 104,104,104,104,104,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::R16G16B16A16_FLOAT,RenderFormat::D32_FLOAT,1,false,0x10 }, { reinterpret_cast(0x93168E46481840FE),reinterpret_cast(0x3D818059C5EAC69D),reinterpret_cast(0x84BACD816D86543C),false,true,true,RenderBlend::ONE,RenderBlend::ZERO,RenderCullMode::NONE,RenderComparisonFunction::GREATER_EQUAL,false,RenderBlendOperation::ADD,0,0,RenderBlend::ONE,RenderBlend::ZERO,RenderBlendOperation::ADD,0xF,RenderPrimitiveTopology::TRIANGLE_STRIP,{ 104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },RenderFormat::R16G16B16A16_FLOAT,RenderFormat::D32_FLOAT,1,false,0x10 }, diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 225d014e..7a3bdbf2 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -3179,8 +3179,6 @@ static void SanitizePipelineState(PipelineState& pipelineState) pipelineState.depthStencilFormat = RenderFormat::UNKNOWN; } - assert(!g_capabilities.dynamicDepthBias || (pipelineState.depthBias == 0 && pipelineState.slopeScaledDepthBias == 0.0f)); - if (pipelineState.slopeScaledDepthBias == 0.0f) pipelineState.slopeScaledDepthBias = 0.0f; // Remove sign. @@ -3587,6 +3585,9 @@ static void ProcAddPipeline(const RenderCommand& cmd) } } +static constexpr int32_t COMMON_DEPTH_BIAS_VALUE = int32_t((1 << 24) * 0.002f); +static constexpr float COMMON_SLOPE_SCALED_DEPTH_BIAS_VALUE = 1.0f; + static void FlushRenderStateForRenderThread() { auto renderTarget = g_pipelineState.colorWriteEnable ? g_renderTarget : nullptr; @@ -3600,14 +3601,24 @@ static void FlushRenderStateForRenderThread() auto& commandList = g_commandLists[g_frame]; + // D3D12 resets depth bias values to the pipeline values, even if they are dynamic. + // We can reduce unnecessary calls by making common depth bias values part of the pipeline. + if (g_capabilities.dynamicDepthBias && !g_vulkan) + { + int32_t depthBias = g_depthBias != 0 ? COMMON_DEPTH_BIAS_VALUE : 0; + float slopeScaledDepthBias = g_slopeScaledDepthBias != 0.0f ? COMMON_SLOPE_SCALED_DEPTH_BIAS_VALUE : 0.0f; + + SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.depthBias, depthBias); + SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.slopeScaledDepthBias, slopeScaledDepthBias); + } + if (g_dirtyStates.pipelineState) { commandList->setPipeline(CreateGraphicsPipelineInRenderThread(g_pipelineState)); - // D3D12 sets the depth bias values to the values in the pipeline. - // TODO: Put the common depth bias values to shadow pipelines to reduce redundant calls. - if (!g_vulkan && g_capabilities.dynamicDepthBias) - g_dirtyStates.depthBias |= (g_depthBias != 0) || (g_slopeScaledDepthBias != 0.0f); + // D3D12 resets the depth bias values. Check if they need to be set again. + if (g_capabilities.dynamicDepthBias && !g_vulkan) + g_dirtyStates.depthBias = (g_depthBias != g_pipelineState.depthBias) || (g_slopeScaledDepthBias != g_pipelineState.slopeScaledDepthBias); } if (g_dirtyStates.depthBias && g_capabilities.dynamicDepthBias) @@ -5318,7 +5329,16 @@ static void CompileMeshPipeline(const Mesh& mesh, CompilationArgs& args) pipelineState.cullMode = mesh.material->m_DoubleSided ? RenderCullMode::NONE : RenderCullMode::BACK; pipelineState.zFunc = RenderComparisonFunction::LESS_EQUAL; - if (!g_capabilities.dynamicDepthBias) + if (g_capabilities.dynamicDepthBias) + { + // Put common depth bias values for reducing unnecessary calls. + if (!g_vulkan) + { + pipelineState.depthBias = COMMON_DEPTH_BIAS_VALUE; + pipelineState.slopeScaledDepthBias = COMMON_SLOPE_SCALED_DEPTH_BIAS_VALUE; + } + } + else { pipelineState.depthBias = (1 << 24) * (*reinterpret_cast*>(g_memory.Translate(0x83302760))); pipelineState.slopeScaledDepthBias = *reinterpret_cast*>(g_memory.Translate(0x83302764)); @@ -5977,7 +5997,8 @@ static void ModelConsumerThread() if (!g_capabilities.triangleFan && pipelineState.primitiveTopology == RenderPrimitiveTopology::TRIANGLE_FAN) pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_LIST; - if (g_capabilities.dynamicDepthBias) + // Zero out depth bias for Vulkan, we only store common values for D3D12. + if (g_capabilities.dynamicDepthBias && g_vulkan) { pipelineState.depthBias = 0; pipelineState.slopeScaledDepthBias = 0.0f;