diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index b197d58f4..ca9838696 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -1199,7 +1199,8 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, uint32_t color_mask = GetCurrentColorMask(pixel_shader); uint32_t rb_depthcontrol = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32; uint32_t rb_stencilrefmask = regs[XE_GPU_REG_RB_STENCILREFMASK].u32; - if (!memexport_used && !color_mask && !(rb_depthcontrol & 0x4) && + if (!memexport_used && !color_mask && + ((rb_depthcontrol & (0x2 | 0x4)) != (0x2 | 0x4)) && (!(rb_depthcontrol & 0x1) || !(rb_stencilrefmask & (0xFF << 16)))) { // Not writing to color, depth or stencil, so doesn't draw. return true; @@ -2017,12 +2018,12 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( // Disable depth and stencil if it aliases a color render target (for // instance, during the XBLA logo in Banjo-Kazooie, though depth writing is // already disabled there). - if (IsROVUsedForEDRAM() && (rb_depthcontrol & (0x1 | 0x2 | 0x4))) { + if (IsROVUsedForEDRAM() && (rb_depthcontrol & (0x1 | 0x2))) { uint32_t edram_base_depth = rb_depth_info & 0xFFF; for (uint32_t i = 0; i < 4; ++i) { if ((color_mask & (0xF << (i * 4))) && edram_base_depth == (color_infos[i] & 0xFFF)) { - rb_depthcontrol &= ~(uint32_t(0x1 | 0x2 | 0x4)); + rb_depthcontrol &= ~(uint32_t(0x1 | 0x2)); break; } } @@ -2099,30 +2100,30 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( uint32_t(ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) { flags |= DxbcShaderTranslator::kSysFlag_Color3Gamma; } - if (IsROVUsedForEDRAM()) { - uint32_t depth_comparison; - if (rb_depthcontrol & 0x2) { - depth_comparison = (rb_depthcontrol >> 4) & 0x7; - } else { - depth_comparison = 0b111; + if (IsROVUsedForEDRAM() && (rb_depthcontrol & (0x1 | 0x2))) { + flags |= DxbcShaderTranslator::kSysFlag_DepthStencil; + if (DepthRenderTargetFormat((rb_depth_info >> 16) & 0x1) == + DepthRenderTargetFormat::kD24FS8) { + flags |= DxbcShaderTranslator::kSysFlag_DepthFloat24; } - if (depth_comparison != 0b111 || (rb_depthcontrol & (0x1 | 0x4))) { - flags |= DxbcShaderTranslator::kSysFlag_DepthStencil; - flags |= depth_comparison + if (rb_depthcontrol & 0x2) { + flags |= ((rb_depthcontrol >> 4) & 0x7) << DxbcShaderTranslator::kSysFlag_DepthPassIfLess_Shift; - if (DepthRenderTargetFormat((rb_depth_info >> 16) & 0x1) == - DepthRenderTargetFormat::kD24FS8) { - flags |= DxbcShaderTranslator::kSysFlag_DepthFloat24; - } if (rb_depthcontrol & 0x4) { flags |= DxbcShaderTranslator::kSysFlag_DepthWriteMask | DxbcShaderTranslator::kSysFlag_DepthStencilWrite; } - if (rb_depthcontrol & 0x1) { - flags |= DxbcShaderTranslator::kSysFlag_StencilTest; - if (rb_stencilrefmask & (0xFF << 16)) { - flags |= DxbcShaderTranslator::kSysFlag_DepthStencilWrite; - } + } else { + // In case stencil is used without depth testing - always pass, and + // don't modify the stored depth. + flags |= DxbcShaderTranslator::kSysFlag_DepthPassIfLess | + DxbcShaderTranslator::kSysFlag_DepthPassIfEqual | + DxbcShaderTranslator::kSysFlag_DepthPassIfGreater; + } + if (rb_depthcontrol & 0x1) { + flags |= DxbcShaderTranslator::kSysFlag_StencilTest; + if (rb_stencilrefmask & (0xFF << 16)) { + flags |= DxbcShaderTranslator::kSysFlag_DepthStencilWrite; } } } diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc index 6b2641d43..4eb0df2a0 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.cc +++ b/src/xenia/gpu/d3d12/pipeline_cache.cc @@ -584,10 +584,10 @@ bool PipelineCache::GetCurrentStateDescription( uint32_t rb_depthcontrol = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32; if (rb_depthcontrol & 0x2) { description_out.depth_func = (rb_depthcontrol >> 4) & 0x7; + description_out.depth_write = (rb_depthcontrol & 0x4) != 0; } else { description_out.depth_func = 0b111; } - description_out.depth_write = (rb_depthcontrol & 0x4) != 0; if (rb_depthcontrol & 0x1) { description_out.stencil_enable = 1; uint32_t rb_stencilrefmask = regs[XE_GPU_REG_RB_STENCILREFMASK].u32; diff --git a/src/xenia/gpu/d3d12/render_target_cache.cc b/src/xenia/gpu/d3d12/render_target_cache.cc index ef013093d..c150facd6 100644 --- a/src/xenia/gpu/d3d12/render_target_cache.cc +++ b/src/xenia/gpu/d3d12/render_target_cache.cc @@ -570,8 +570,8 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { } uint32_t rb_depthcontrol = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32; uint32_t rb_depth_info = regs[XE_GPU_REG_RB_DEPTH_INFO].u32; - // 0x1 = stencil test, 0x2 = depth test, 0x4 = depth writing. - enabled[4] = (rb_depthcontrol & (0x1 | 0x2 | 0x4)) != 0; + // 0x1 = stencil test, 0x2 = depth test. + enabled[4] = (rb_depthcontrol & (0x1 | 0x2)) != 0; edram_bases[4] = std::min(rb_depth_info & 0xFFF, 2048u); formats[4] = (rb_depth_info >> 16) & 0x1; formats_are_64bpp[4] = false; @@ -672,7 +672,6 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { const RenderTargetBinding& binding = current_bindings_[i]; if (binding.is_bound) { if (binding.edram_base != edram_bases[i]) { - full_update = true; break; } if (rov_used) {