From 8a409d86d4c34ff6e07f5f107ce55ed68e12f2ba Mon Sep 17 00:00:00 2001 From: setepenre <61476054+setepenre@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:18:07 +0100 Subject: [PATCH 1/2] post-processing: rework gamma correction (#1756) --- src/video_core/host_shaders/post_process.frag | 8 +++++++- src/video_core/renderer_vulkan/vk_presenter.cpp | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/video_core/host_shaders/post_process.frag b/src/video_core/host_shaders/post_process.frag index fcced3232..d501e9813 100644 --- a/src/video_core/host_shaders/post_process.frag +++ b/src/video_core/host_shaders/post_process.frag @@ -12,8 +12,14 @@ layout(push_constant) uniform settings { float gamma; } pp; +const float cutoff = 0.0031308, a = 1.055, b = 0.055, d = 12.92; +vec3 gamma(vec3 rgb) +{ + return mix(a * pow(rgb, vec3(1.0 / (2.4 + 1.0 - pp.gamma))) - b, d * rgb / pp.gamma, lessThan(rgb, vec3(cutoff))); +} + void main() { vec4 color_linear = texture(texSampler, uv); - color = pow(color_linear, vec4(1.0/(2.2 + 1.0 - pp.gamma))); + color = vec4(gamma(color_linear.rgb), color_linear.a); } diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index b7d829316..139fd962d 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -154,7 +154,7 @@ void Presenter::CreatePostProcessPipeline() { const auto& fs_module = Vulkan::Compile(pp_shaders[1], vk::ShaderStageFlagBits::eFragment, instance.GetDevice()); ASSERT(fs_module); - Vulkan::SetObjectName(instance.GetDevice(), vs_module, "post_process.frag"); + Vulkan::SetObjectName(instance.GetDevice(), fs_module, "post_process.frag"); const std::array shaders_ci{ vk::PipelineShaderStageCreateInfo{ From 7fe4df85abb23a0f9960ed6bdb74dfaa6a71f085 Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Sun, 22 Dec 2024 20:12:43 +0300 Subject: [PATCH 2/2] Clear color attachment if FCE was invoked before any draws (#1851) * Clear RT if FCE was invoked before any draws Co-authored-by: psucien * address review comments --------- Co-authored-by: psucien --- .../renderer_vulkan/vk_rasterizer.cpp | 31 ++++++++++++++++++- .../renderer_vulkan/vk_rasterizer.h | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index a0899f7c8..ec099b9f6 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -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) { @@ -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; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 80b22c7d8..1bbb90b6c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -71,6 +71,7 @@ private: RenderState PrepareRenderState(u32 mrt_mask); void BeginRendering(const GraphicsPipeline& pipeline, RenderState& state); void Resolve(); + void EliminateFastClear(); void UpdateDynamicState(const GraphicsPipeline& pipeline); void UpdateViewportScissorState();