Skip to content

Commit

Permalink
vk: Rewrite partial clear shader
Browse files Browse the repository at this point in the history
- Completely removes the feedback loop and replaces with hardware channel masking
  • Loading branch information
kd-11 committed Jun 1, 2021
1 parent f85881c commit 98f534b
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 75 deletions.
27 changes: 1 addition & 26 deletions rpcs3/Emu/RSX/VK/VKGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<vk::attachment_clear_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<vk::image*> surfaces = { rtt };
std::vector<u8> 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;
Expand Down
56 changes: 13 additions & 43 deletions rpcs3/Emu/RSX/VK/VKOverlays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,9 @@ namespace vk

u64 overlay_pass::get_pipeline_key(VkRenderPass pass)
{
if (!multi_primitive)
{
// Default fast path
return reinterpret_cast<u64>(pass);
}
else
{
struct
{
u64 pass_value;
u64 config;
}
key{ reinterpret_cast<uptr>(pass), static_cast<u64>(renderpass_config.ia.topology) };
return rpcs3::hash_struct(key);
}
u64 key = rpcs3::hash_struct(renderpass_config);
key ^= reinterpret_cast<uptr>(pass);
return key;
}

void overlay_pass::check_heap()
Expand Down Expand Up @@ -500,9 +488,6 @@ namespace vk
" }\n"
"}\n";

// Allow mixed primitive rendering
multi_primitive = true;

// 2 input textures
m_num_usable_samplers = 2;

Expand Down Expand Up @@ -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";

Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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)
Expand All @@ -884,8 +859,10 @@ namespace vk
vkCmdSetScissor(cmd, 0, 1, &region);
}

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;
Expand All @@ -896,22 +873,15 @@ namespace vk
{
colormask = mask;
clear_color = color;
return true;
}

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);
// Update color mask to match request
renderpass_config.set_color_mask(0, colormask.r, colormask.g, colormask.b, colormask.a);
}

// 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<vk::image_view*>{}, render_pass);
}

Expand Down
6 changes: 1 addition & 5 deletions rpcs3/Emu/RSX/VK/VKOverlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/VK/VKRenderTargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions rpcs3/Emu/RSX/VK/vkutils/framebuffer_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ namespace vk
return m_height;
}

u8 samples()
{
ensure(!attachments.empty());
return attachments[0]->image()->samples();
}

bool matches(std::vector<vk::image*> fbo_images, u32 width, u32 height)
{
if (m_width != width || m_height != height)
Expand Down

0 comments on commit 98f534b

Please sign in to comment.