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.
This commit is contained in:
Dan Weatherford 2017-09-18 18:18:03 -05:00 committed by DrChat
parent 6b8a34c9ba
commit 2e3329095b
2 changed files with 28 additions and 0 deletions

View File

@ -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 = &current_state_.config;
CachedRenderPass* render_pass = nullptr;
CachedFramebuffer* framebuffer = nullptr;
@ -653,6 +655,7 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer,
SetShadowRegister(&regs.rb_color3_info.value, XE_GPU_REG_RB_COLOR3_INFO);
dirty |=
SetShadowRegister(&regs.rb_depth_info.value, XE_GPU_REG_RB_DEPTH_INFO);
dirty |= SetShadowRegister(&regs.rb_color_mask, XE_GPU_REG_RB_COLOR_MASK);
dirty |= SetShadowRegister(&regs.pa_sc_window_scissor_tl,
XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL);
dirty |= SetShadowRegister(&regs.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 &current_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;

View File

@ -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;