From 98f534b1bddf6a140709da37744650d8b52fa8c0 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 31 May 2021 23:51:14 +0300 Subject: [PATCH] vk: Rewrite partial clear shader - Completely removes the feedback loop and replaces with hardware channel masking --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 27 +-------- rpcs3/Emu/RSX/VK/VKOverlays.cpp | 56 +++++-------------- rpcs3/Emu/RSX/VK/VKOverlays.h | 6 +- rpcs3/Emu/RSX/VK/VKRenderTargets.h | 2 +- .../Emu/RSX/VK/vkutils/framebuffer_object.hpp | 6 ++ 5 files changed, 22 insertions(+), 75 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index ae87008b19..d618d3c2d7 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1273,33 +1273,8 @@ void VKGSRender::clear_surface(u32 mask) color_clear_values.color.float32[3] }; - VkRenderPass renderpass = VK_NULL_HANDLE; auto attachment_clear_pass = vk::get_overlay_pass(); - attachment_clear_pass->update_config(colormask, clear_color); - - for (const auto &index : m_draw_buffers) - { - if (auto rtt = m_rtts.m_bound_render_targets[index].second) - { - if (require_mem_load) rtt->write_barrier(*m_current_command_buffer); - - // Add a barrier to ensure previous writes are visible; also transitions into GENERAL layout - rtt->push_barrier(*m_current_command_buffer, VK_IMAGE_LAYOUT_GENERAL); - - if (!renderpass) - { - std::vector surfaces = { rtt }; - std::vector input_attachments = { 0 }; - const auto key = vk::get_renderpass_key(surfaces, input_attachments); - renderpass = vk::get_renderpass(*m_device, key); - } - - attachment_clear_pass->run(*m_current_command_buffer, rtt, region.rect, renderpass); - rtt->pop_layout(*m_current_command_buffer); - } - else - fmt::throw_exception("Unreachable"); - } + attachment_clear_pass->run(*m_current_command_buffer, m_draw_fbo, region.rect, colormask, clear_color, get_render_pass()); } for (u8 index = m_rtts.m_bound_render_targets_config.first, count = 0; diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index 3c717e5fbf..29570c5f3b 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -32,21 +32,9 @@ namespace vk u64 overlay_pass::get_pipeline_key(VkRenderPass pass) { - if (!multi_primitive) - { - // Default fast path - return reinterpret_cast(pass); - } - else - { - struct - { - u64 pass_value; - u64 config; - } - key{ reinterpret_cast(pass), static_cast(renderpass_config.ia.topology) }; - return rpcs3::hash_struct(key); - } + u64 key = rpcs3::hash_struct(renderpass_config); + key ^= reinterpret_cast(pass); + return key; } void overlay_pass::check_heap() @@ -500,9 +488,6 @@ namespace vk " }\n" "}\n"; - // Allow mixed primitive rendering - multi_primitive = true; - // 2 input textures m_num_usable_samplers = 2; @@ -807,13 +792,11 @@ namespace vk "#extension GL_ARB_separate_shader_objects : enable\n" "layout(push_constant) uniform static_data{ vec4 regs[2]; };\n" "layout(location=0) out vec4 color;\n" - "layout(location=1) out vec4 mask;\n" "\n" "void main()\n" "{\n" " vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n" " color = regs[0];\n" - " mask = regs[1];\n" " gl_Position = vec4(positions[gl_VertexIndex % 4], 0., 1.);\n" "}\n"; @@ -822,21 +805,16 @@ namespace vk "#extension GL_ARB_separate_shader_objects : enable\n" "layout(input_attachment_index=0, binding=1) uniform subpassInput sp0;\n" "layout(location=0) in vec4 color;\n" - "layout(location=1) in vec4 mask;\n" "layout(location=0) out vec4 out_color;\n" "\n" "void main()\n" "{\n" - " vec4 original_color = subpassLoad(sp0);\n" - " out_color = mix(original_color, color, bvec4(mask));\n" + " out_color = color;\n" "}\n"; // Disable samplers m_num_usable_samplers = 0; - // Enable subpass attachment 0 - m_num_input_attachments = 1; - renderpass_config.set_depth_mask(false); renderpass_config.set_color_mask(0, true, true, true, true); renderpass_config.set_attachment_count(1); @@ -852,7 +830,7 @@ namespace vk return { constant }; } - void attachment_clear_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program) + void attachment_clear_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* /*program*/) { f32 data[8]; data[0] = clear_color.r; @@ -865,9 +843,6 @@ namespace vk data[7] = colormask.a; vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data); - - // Bind subpass attachment 0 - program->bind_uniform(input_attachment_info, "sp0", VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_descriptor_set); } void attachment_clear_pass::set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h) @@ -884,8 +859,10 @@ namespace vk vkCmdSetScissor(cmd, 0, 1, ®ion); } - bool attachment_clear_pass::update_config(u32 clearmask, color4f color) + void attachment_clear_pass::run(vk::command_buffer& cmd, vk::framebuffer* target, VkRect2D rect, u32 clearmask, color4f color, VkRenderPass render_pass) { + region = rect; + color4f mask = { 0.f, 0.f, 0.f, 0.f }; if (clearmask & 0x10) mask.r = 1.f; if (clearmask & 0x20) mask.g = 1.f; @@ -896,22 +873,15 @@ namespace vk { colormask = mask; clear_color = color; - return true; + + // Update color mask to match request + renderpass_config.set_color_mask(0, colormask.r, colormask.g, colormask.b, colormask.a); } - return false; - } - - void attachment_clear_pass::run(vk::command_buffer& cmd, vk::render_target* target, VkRect2D rect, VkRenderPass render_pass) - { - region = rect; - input_attachment_info = { VK_NULL_HANDLE, target->get_view(0xAAE4, rsx::default_remap_vector)->value, target->current_layout }; - - target->read_barrier(cmd); - - // Coverage sampling disabled, but actually report correct number of samples + // Update renderpass configuration with the real number of samples renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false); + // Render fullscreen quad overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target, std::vector{}, render_pass); } diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.h b/rpcs3/Emu/RSX/VK/VKOverlays.h index 7d25a71c46..b165f8af70 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.h +++ b/rpcs3/Emu/RSX/VK/VKOverlays.h @@ -62,7 +62,6 @@ namespace vk std::string fs_src; graphics_pipeline_state renderpass_config; - bool multi_primitive = false; bool initialized = false; bool compiled = false; @@ -176,7 +175,6 @@ namespace vk color4f clear_color = { 0.f, 0.f, 0.f, 0.f }; color4f colormask = { 1.f, 1.f, 1.f, 1.f }; VkRect2D region = {}; - VkDescriptorImageInfo input_attachment_info = {}; attachment_clear_pass(); @@ -186,9 +184,7 @@ namespace vk void set_up_viewport(vk::command_buffer& cmd, u32 x, u32 y, u32 w, u32 h) override; - bool update_config(u32 clearmask, color4f color); - - void run(vk::command_buffer& cmd, vk::render_target* target, VkRect2D rect, VkRenderPass render_pass); + void run(vk::command_buffer& cmd, vk::framebuffer* target, VkRect2D rect, u32 clearmask, color4f color, VkRenderPass render_pass); }; struct stencil_clear_pass : public overlay_pass diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index a0cf6f05aa..c82c5d390e 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -98,7 +98,7 @@ namespace rsx sample_layout = surface_sample_layout::null; } - VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; if (samples == 1) [[likely]] { usage_flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; diff --git a/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp b/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp index 79c8238096..3ee09e9f32 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp +++ b/rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp @@ -57,6 +57,12 @@ namespace vk return m_height; } + u8 samples() + { + ensure(!attachments.empty()); + return attachments[0]->image()->samples(); + } + bool matches(std::vector fbo_images, u32 width, u32 height) { if (m_width != width || m_height != height)