mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-11 01:08:39 +12:00
vk: Rewrite partial clear shader
- Completely removes the feedback loop and replaces with hardware channel masking
This commit is contained in:
parent
f85881c18c
commit
98f534b1bd
5 changed files with 22 additions and 75 deletions
|
@ -1273,33 +1273,8 @@ void VKGSRender::clear_surface(u32 mask)
|
||||||
color_clear_values.color.float32[3]
|
color_clear_values.color.float32[3]
|
||||||
};
|
};
|
||||||
|
|
||||||
VkRenderPass renderpass = VK_NULL_HANDLE;
|
|
||||||
auto attachment_clear_pass = vk::get_overlay_pass<vk::attachment_clear_pass>();
|
auto attachment_clear_pass = vk::get_overlay_pass<vk::attachment_clear_pass>();
|
||||||
attachment_clear_pass->update_config(colormask, clear_color);
|
attachment_clear_pass->run(*m_current_command_buffer, m_draw_fbo, region.rect, colormask, clear_color, get_render_pass());
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 index = m_rtts.m_bound_render_targets_config.first, count = 0;
|
for (u8 index = m_rtts.m_bound_render_targets_config.first, count = 0;
|
||||||
|
|
|
@ -32,21 +32,9 @@ namespace vk
|
||||||
|
|
||||||
u64 overlay_pass::get_pipeline_key(VkRenderPass pass)
|
u64 overlay_pass::get_pipeline_key(VkRenderPass pass)
|
||||||
{
|
{
|
||||||
if (!multi_primitive)
|
u64 key = rpcs3::hash_struct(renderpass_config);
|
||||||
{
|
key ^= reinterpret_cast<uptr>(pass);
|
||||||
// Default fast path
|
return key;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_pass::check_heap()
|
void overlay_pass::check_heap()
|
||||||
|
@ -500,9 +488,6 @@ namespace vk
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
// Allow mixed primitive rendering
|
|
||||||
multi_primitive = true;
|
|
||||||
|
|
||||||
// 2 input textures
|
// 2 input textures
|
||||||
m_num_usable_samplers = 2;
|
m_num_usable_samplers = 2;
|
||||||
|
|
||||||
|
@ -807,13 +792,11 @@ namespace vk
|
||||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||||
"layout(push_constant) uniform static_data{ vec4 regs[2]; };\n"
|
"layout(push_constant) uniform static_data{ vec4 regs[2]; };\n"
|
||||||
"layout(location=0) out vec4 color;\n"
|
"layout(location=0) out vec4 color;\n"
|
||||||
"layout(location=1) out vec4 mask;\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n"
|
" vec2 positions[] = {vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)};\n"
|
||||||
" color = regs[0];\n"
|
" color = regs[0];\n"
|
||||||
" mask = regs[1];\n"
|
|
||||||
" gl_Position = vec4(positions[gl_VertexIndex % 4], 0., 1.);\n"
|
" gl_Position = vec4(positions[gl_VertexIndex % 4], 0., 1.);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
@ -822,21 +805,16 @@ namespace vk
|
||||||
"#extension GL_ARB_separate_shader_objects : enable\n"
|
"#extension GL_ARB_separate_shader_objects : enable\n"
|
||||||
"layout(input_attachment_index=0, binding=1) uniform subpassInput sp0;\n"
|
"layout(input_attachment_index=0, binding=1) uniform subpassInput sp0;\n"
|
||||||
"layout(location=0) in vec4 color;\n"
|
"layout(location=0) in vec4 color;\n"
|
||||||
"layout(location=1) in vec4 mask;\n"
|
|
||||||
"layout(location=0) out vec4 out_color;\n"
|
"layout(location=0) out vec4 out_color;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" vec4 original_color = subpassLoad(sp0);\n"
|
" out_color = color;\n"
|
||||||
" out_color = mix(original_color, color, bvec4(mask));\n"
|
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
// Disable samplers
|
// Disable samplers
|
||||||
m_num_usable_samplers = 0;
|
m_num_usable_samplers = 0;
|
||||||
|
|
||||||
// Enable subpass attachment 0
|
|
||||||
m_num_input_attachments = 1;
|
|
||||||
|
|
||||||
renderpass_config.set_depth_mask(false);
|
renderpass_config.set_depth_mask(false);
|
||||||
renderpass_config.set_color_mask(0, true, true, true, true);
|
renderpass_config.set_color_mask(0, true, true, true, true);
|
||||||
renderpass_config.set_attachment_count(1);
|
renderpass_config.set_attachment_count(1);
|
||||||
|
@ -852,7 +830,7 @@ namespace vk
|
||||||
return { constant };
|
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];
|
f32 data[8];
|
||||||
data[0] = clear_color.r;
|
data[0] = clear_color.r;
|
||||||
|
@ -865,9 +843,6 @@ namespace vk
|
||||||
data[7] = colormask.a;
|
data[7] = colormask.a;
|
||||||
|
|
||||||
vkCmdPushConstants(cmd, m_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 32, data);
|
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)
|
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);
|
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 };
|
color4f mask = { 0.f, 0.f, 0.f, 0.f };
|
||||||
if (clearmask & 0x10) mask.r = 1.f;
|
if (clearmask & 0x10) mask.r = 1.f;
|
||||||
if (clearmask & 0x20) mask.g = 1.f;
|
if (clearmask & 0x20) mask.g = 1.f;
|
||||||
|
@ -896,22 +873,15 @@ namespace vk
|
||||||
{
|
{
|
||||||
colormask = mask;
|
colormask = mask;
|
||||||
clear_color = color;
|
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;
|
// Update renderpass configuration with the real number of samples
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
renderpass_config.set_multisample_state(target->samples(), 0xFFFF, false, false, false);
|
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);
|
overlay_pass::run(cmd, { 0, 0, target->width(), target->height() }, target, std::vector<vk::image_view*>{}, render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,6 @@ namespace vk
|
||||||
std::string fs_src;
|
std::string fs_src;
|
||||||
|
|
||||||
graphics_pipeline_state renderpass_config;
|
graphics_pipeline_state renderpass_config;
|
||||||
bool multi_primitive = false;
|
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
bool compiled = false;
|
bool compiled = false;
|
||||||
|
@ -176,7 +175,6 @@ namespace vk
|
||||||
color4f clear_color = { 0.f, 0.f, 0.f, 0.f };
|
color4f clear_color = { 0.f, 0.f, 0.f, 0.f };
|
||||||
color4f colormask = { 1.f, 1.f, 1.f, 1.f };
|
color4f colormask = { 1.f, 1.f, 1.f, 1.f };
|
||||||
VkRect2D region = {};
|
VkRect2D region = {};
|
||||||
VkDescriptorImageInfo input_attachment_info = {};
|
|
||||||
|
|
||||||
attachment_clear_pass();
|
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;
|
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::framebuffer* target, VkRect2D rect, u32 clearmask, color4f color, VkRenderPass render_pass);
|
||||||
|
|
||||||
void run(vk::command_buffer& cmd, vk::render_target* target, VkRect2D rect, VkRenderPass render_pass);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stencil_clear_pass : public overlay_pass
|
struct stencil_clear_pass : public overlay_pass
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace rsx
|
||||||
sample_layout = surface_sample_layout::null;
|
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]]
|
if (samples == 1) [[likely]]
|
||||||
{
|
{
|
||||||
usage_flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
usage_flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
|
|
|
@ -57,6 +57,12 @@ namespace vk
|
||||||
return m_height;
|
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)
|
bool matches(std::vector<vk::image*> fbo_images, u32 width, u32 height)
|
||||||
{
|
{
|
||||||
if (m_width != width || m_height != height)
|
if (m_width != width || m_height != height)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue