rsx: Reorganize write barrier implementation (either clear or memory barrier)

This commit is contained in:
kd-11 2018-12-22 15:01:30 +03:00 committed by kd-11
parent 9c45ce6d37
commit 1ffadbe086
2 changed files with 95 additions and 103 deletions

View File

@ -210,58 +210,9 @@ void GLGSRender::end()
}
};
//Check if we have any 'recycled' surfaces in memory and if so, clear them
std::vector<int> buffers_to_clear;
bool clear_all_color = true;
bool clear_depth = false;
for (int index = 0; index < 4; index++)
{
if (std::get<0>(m_rtts.m_bound_render_targets[index]) != 0)
{
if (std::get<1>(m_rtts.m_bound_render_targets[index])->cleared())
clear_all_color = false;
else
buffers_to_clear.push_back(index);
}
}
gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil);
if (ds && !ds->cleared())
{
clear_depth = true;
}
if (clear_depth || buffers_to_clear.size() > 0)
{
gl_state.enable(GL_FALSE, GL_SCISSOR_TEST);
GLenum mask = 0;
if (clear_depth)
{
gl_state.depth_mask(GL_TRUE);
gl_state.clear_depth(1.f);
gl_state.clear_stencil(255);
mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
}
if (clear_all_color)
mask |= GL_COLOR_BUFFER_BIT;
glClear(mask);
if (buffers_to_clear.size() > 0 && !clear_all_color)
{
GLfloat colors[] = { 0.f, 0.f, 0.f, 0.f };
//It is impossible for the render target to be type A or B here (clear all would have been flagged)
for (auto &i : buffers_to_clear)
glClearBufferfv(m_draw_fbo->id(), i, colors);
}
if (clear_depth)
gl_state.depth_mask(rsx::method_registers.depth_write_enabled());
}
// Handle special memory barrier for ARGB8->D24S8 in an active DSV
if (ds && ds->old_contents != nullptr && ds->get_rsx_pitch() == static_cast<gl::render_target*>(ds->old_contents)->get_rsx_pitch() &&
ds->old_contents->get_internal_format() == gl::texture::internal_format::rgba8)
{
@ -453,6 +404,56 @@ void GLGSRender::end()
}
}
rsx::simple_array<int> buffers_to_clear;
bool clear_all_color = true;
bool clear_depth = false;
for (int index = 0; index < 4; index++)
{
if (std::get<0>(m_rtts.m_bound_render_targets[index]) != 0)
{
if (std::get<1>(m_rtts.m_bound_render_targets[index])->cleared())
clear_all_color = false;
else
buffers_to_clear.push_back(index);
}
}
if (ds && !ds->cleared())
{
clear_depth = true;
}
if (clear_depth || buffers_to_clear.size() > 0)
{
gl_state.enable(GL_FALSE, GL_SCISSOR_TEST);
GLenum mask = 0;
if (clear_depth)
{
gl_state.depth_mask(GL_TRUE);
gl_state.clear_depth(1.f);
gl_state.clear_stencil(255);
mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
}
if (clear_all_color)
mask |= GL_COLOR_BUFFER_BIT;
glClear(mask);
if (buffers_to_clear.size() > 0 && !clear_all_color)
{
GLfloat colors[] = { 0.f, 0.f, 0.f, 0.f };
//It is impossible for the render target to be type A or B here (clear all would have been flagged)
for (auto &i : buffers_to_clear)
glClearBufferfv(m_draw_fbo->id(), i, colors);
}
if (clear_depth)
gl_state.depth_mask(rsx::method_registers.depth_write_enabled());
}
// Unconditionally enable stencil test if it was disabled before
gl_state.enable(GL_TRUE, GL_SCISSOR_TEST);

View File

@ -1332,42 +1332,8 @@ void VKGSRender::end()
std::chrono::time_point<steady_clock> textures_start = steady_clock::now();
// Clear any 'dirty' surfaces - possible is a recycled cache surface is used
rsx::simple_array<VkClearAttachment> buffers_to_clear;
// Check for data casts
auto ds = std::get<1>(m_rtts.m_bound_depth_stencil);
//Check for memory clears
if (ds && ds->dirty)
{
//Clear this surface before drawing on it
VkClearValue clear_value = {};
clear_value.depthStencil = { 1.f, 255 };
buffers_to_clear.push_back({ vk::get_aspect_flags(ds->info.format), 0, clear_value });
}
for (u32 index = 0; index < m_draw_buffers.size(); ++index)
{
if (auto rtt = std::get<1>(m_rtts.m_bound_render_targets[index]))
{
if (rtt->dirty)
{
buffers_to_clear.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, index, {} });
}
}
}
if (UNLIKELY(!buffers_to_clear.empty()))
{
begin_render_pass();
VkClearRect rect = { {{0, 0}, {m_draw_fbo->width(), m_draw_fbo->height()}}, 0, 1 };
vkCmdClearAttachments(*m_current_command_buffer, (u32)buffers_to_clear.size(),
buffers_to_clear.data(), 1, &rect);
close_render_pass();
}
//Check for data casts
if (ds && ds->old_contents)
{
if (UNLIKELY(ds->old_contents->info.format == VK_FORMAT_B8G8R8A8_UNORM))
@ -1385,24 +1351,6 @@ void VKGSRender::end()
}
}
if (g_cfg.video.strict_rendering_mode)
{
//Prepare surfaces if needed
for (auto &rtt : m_rtts.m_bound_render_targets)
{
if (auto surface = std::get<1>(rtt))
{
if (surface->old_contents != nullptr)
surface->memory_barrier(*m_current_command_buffer);
}
}
if (ds && ds->old_contents)
{
ds->memory_barrier(*m_current_command_buffer);
}
}
//Load textures
{
std::lock_guard lock(m_sampler_mutex);
@ -1699,6 +1647,20 @@ void VKGSRender::end()
m_current_command_buffer->flags |= cb_has_occlusion_task;
}
// Apply write memory barriers
if (g_cfg.video.strict_rendering_mode)
{
if (ds) ds->memory_barrier(*m_current_command_buffer);
for (auto &rtt : m_rtts.m_bound_render_targets)
{
if (auto surface = std::get<1>(rtt))
{
surface->memory_barrier(*m_current_command_buffer);
}
}
}
// While vertex upload is an interruptible process, if we made it this far, there's no need to sync anything that occurs past this point
// Only textures are synchronized tightly with the GPU and they have been read back above
vk::enter_uninterruptible();
@ -1707,6 +1669,35 @@ void VKGSRender::end()
update_draw_state();
begin_render_pass();
// Clear any 'dirty' surfaces - possible is a recycled cache surface is used
rsx::simple_array<VkClearAttachment> buffers_to_clear;
if (ds && ds->dirty)
{
// Clear this surface before drawing on it
VkClearValue clear_value = {};
clear_value.depthStencil = { 1.f, 255 };
buffers_to_clear.push_back({ vk::get_aspect_flags(ds->info.format), 0, clear_value });
}
for (u32 index = 0; index < m_draw_buffers.size(); ++index)
{
if (auto rtt = std::get<1>(m_rtts.m_bound_render_targets[index]))
{
if (rtt->dirty)
{
buffers_to_clear.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, index, {} });
}
}
}
if (UNLIKELY(!buffers_to_clear.empty()))
{
VkClearRect rect = { {{0, 0}, {m_draw_fbo->width(), m_draw_fbo->height()}}, 0, 1 };
vkCmdClearAttachments(*m_current_command_buffer, (u32)buffers_to_clear.size(),
buffers_to_clear.data(), 1, &rect);
}
u32 sub_index = 0;
rsx::method_registers.current_draw_clause.begin();
do