mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01: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
@ -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;
|
||||
|
@ -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()
|
||||
@ -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<vk::image_view*>{}, render_pass);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user