From 2e3329095b934eaa015fed3f916391c8e8ecb020 Mon Sep 17 00:00:00 2001 From: Dan Weatherford Date: Mon, 18 Sep 2017 18:18:03 -0500 Subject: [PATCH] Hack to fix render target clearing Treat a depth render to an EDRAM region that is subsequently used as a color target as a clear. --- src/xenia/gpu/vulkan/render_cache.cc | 27 +++++++++++++++++++++++++++ src/xenia/gpu/vulkan/render_cache.h | 1 + 2 files changed, 28 insertions(+) diff --git a/src/xenia/gpu/vulkan/render_cache.cc b/src/xenia/gpu/vulkan/render_cache.cc index 1991ee2b4..21b573a47 100644 --- a/src/xenia/gpu/vulkan/render_cache.cc +++ b/src/xenia/gpu/vulkan/render_cache.cc @@ -616,6 +616,7 @@ bool RenderCache::dirty() const { dirty |= cur_regs.rb_color2_info.value != regs[XE_GPU_REG_RB_COLOR2_INFO].u32; dirty |= cur_regs.rb_color3_info.value != regs[XE_GPU_REG_RB_COLOR3_INFO].u32; dirty |= cur_regs.rb_depth_info.value != regs[XE_GPU_REG_RB_DEPTH_INFO].u32; + dirty |= cur_regs.rb_color_mask != regs[XE_GPU_REG_RB_COLOR_MASK].u32; dirty |= cur_regs.pa_sc_window_scissor_tl != regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32; dirty |= cur_regs.pa_sc_window_scissor_br != @@ -634,6 +635,7 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer, current_command_buffer_ = command_buffer; // Lookup or construct a render pass compatible with our current state. + auto previous_render_pass = current_state_.render_pass; auto config = ¤t_state_.config; CachedRenderPass* render_pass = nullptr; CachedFramebuffer* framebuffer = nullptr; @@ -653,6 +655,7 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer, SetShadowRegister(®s.rb_color3_info.value, XE_GPU_REG_RB_COLOR3_INFO); dirty |= SetShadowRegister(®s.rb_depth_info.value, XE_GPU_REG_RB_DEPTH_INFO); + dirty |= SetShadowRegister(®s.rb_color_mask, XE_GPU_REG_RB_COLOR_MASK); dirty |= SetShadowRegister(®s.pa_sc_window_scissor_tl, XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL); dirty |= SetShadowRegister(®s.pa_sc_window_scissor_br, @@ -737,6 +740,28 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer, vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE); + // XXX HACK: clear the color target if the previous render pass was a + // depth-stencil pass targeting the same EDRAM tile + // (some games clear color targets with a depth pass, since it's slightly + // faster) + if (previous_render_pass && previous_render_pass->config.depth_stencil.used && + current_state_.render_pass->config.color[0].used && + previous_render_pass->config.depth_stencil.edram_base == + current_state_.render_pass->config.color[0].edram_base) { + VkClearRect clear_rect; + clear_rect.rect = render_pass_begin_info.renderArea; + clear_rect.baseArrayLayer = 0; + clear_rect.layerCount = 1; + + VkClearAttachment clear_attachments; + clear_attachments.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + clear_attachments.colorAttachment = 0; + memset(&clear_attachments.clearValue, 0, sizeof(VkClearValue)); + + vkCmdClearAttachments(command_buffer, 1, &clear_attachments, 1, + &clear_rect); + } + return ¤t_state_; } @@ -778,6 +803,7 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) { for (int i = 0; i < 4; ++i) { config->color[i].edram_base = color_info[i].color_base; config->color[i].format = color_info[i].color_format; + config->color[i].used = ((regs.rb_color_mask >> (i * 4)) & 0xf) != 0; // We don't support GAMMA formats, so switch them to what we do support. switch (config->color[i].format) { case ColorRenderTargetFormat::k_8_8_8_8_GAMMA: @@ -807,6 +833,7 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) { config->mode_control == ModeControl::kDepth) { config->depth_stencil.edram_base = regs.rb_depth_info.depth_base; config->depth_stencil.format = regs.rb_depth_info.depth_format; + config->depth_stencil.used = true; } else { config->depth_stencil.edram_base = 0; config->depth_stencil.format = DepthRenderTargetFormat::kD24S8; diff --git a/src/xenia/gpu/vulkan/render_cache.h b/src/xenia/gpu/vulkan/render_cache.h index a015dc8ca..03c500de0 100644 --- a/src/xenia/gpu/vulkan/render_cache.h +++ b/src/xenia/gpu/vulkan/render_cache.h @@ -379,6 +379,7 @@ class RenderCache { reg::RB_COLOR_INFO rb_color2_info; reg::RB_COLOR_INFO rb_color3_info; reg::RB_DEPTH_INFO rb_depth_info; + uint32_t rb_color_mask; uint32_t pa_sc_window_scissor_tl; uint32_t pa_sc_window_scissor_br;