Skip to content

Commit

Permalink
Clear color attachment if FCE was invoked before any draws (shadps4-e…
Browse files Browse the repository at this point in the history
…mu#1851)

* Clear RT if FCE was invoked before any draws

Co-authored-by: psucien <[email protected]>

* address review comments

---------

Co-authored-by: psucien <[email protected]>
  • Loading branch information
roamic and psucien authored Dec 22, 2024
1 parent 8a409d8 commit 7fe4df8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/video_core/renderer_vulkan/vk_rasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ bool Rasterizer::FilterDraw() {
// There are several cases (e.g. FCE, FMask/HTile decompression) where we don't need to do an
// actual draw hence can skip pipeline creation.
if (regs.color_control.mode == Liverpool::ColorControl::OperationMode::EliminateFastClear) {
LOG_TRACE(Render_Vulkan, "FCE pass skipped");
// Clears the render target if FCE is launched before any draws
EliminateFastClear();
return false;
}
if (regs.color_control.mode == Liverpool::ColorControl::OperationMode::FmaskDecompress) {
Expand Down Expand Up @@ -201,6 +202,34 @@ RenderState Rasterizer::PrepareRenderState(u32 mrt_mask) {
return {vertex_offset, instance_offset};
}

void Rasterizer::EliminateFastClear() {
auto& col_buf = liverpool->regs.color_buffers[0];
if (!col_buf || !col_buf.info.fast_clear) {
return;
}
if (!texture_cache.IsMetaCleared(col_buf.CmaskAddress(), col_buf.view.slice_start)) {
return;
}
for (u32 slice = col_buf.view.slice_start; slice <= col_buf.view.slice_max; ++slice) {
texture_cache.TouchMeta(col_buf.CmaskAddress(), slice, false);
}
const auto& hint = liverpool->last_cb_extent[0];
VideoCore::TextureCache::RenderTargetDesc desc(col_buf, hint);
const auto& image_view = texture_cache.FindRenderTarget(desc);
const auto& image = texture_cache.GetImage(image_view.image_id);
const vk::ImageSubresourceRange range = {
.aspectMask = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = col_buf.view.slice_start,
.layerCount = col_buf.view.slice_max - col_buf.view.slice_start + 1,
};
scheduler.EndRendering();
scheduler.CommandBuffer().clearColorImage(image.image, vk::ImageLayout::eColorAttachmentOptimal,
LiverpoolToVK::ColorBufferClearValue(col_buf).color,
range);
}

void Rasterizer::Draw(bool is_indexed, u32 index_offset) {
RENDERER_TRACE;

Expand Down
1 change: 1 addition & 0 deletions src/video_core/renderer_vulkan/vk_rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class Rasterizer {
RenderState PrepareRenderState(u32 mrt_mask);
void BeginRendering(const GraphicsPipeline& pipeline, RenderState& state);
void Resolve();
void EliminateFastClear();

void UpdateDynamicState(const GraphicsPipeline& pipeline);
void UpdateViewportScissorState();
Expand Down

0 comments on commit 7fe4df8

Please sign in to comment.