rsx: Clean up surface cache routines around RTT invalidate

This commit is contained in:
kd-11 2022-03-10 00:06:03 +03:00 committed by kd-11
parent 1670769119
commit 1943d9819f
4 changed files with 42 additions and 40 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "surface_utils.h" #include "surface_utils.h"
#include "simple_array.hpp"
#include "../gcm_enums.h" #include "../gcm_enums.h"
#include "../rsx_utils.h" #include "../rsx_utils.h"
#include <list> #include <list>
@ -56,10 +57,9 @@ namespace rsx
rsx::surface_raster_type m_active_raster_type = rsx::surface_raster_type::linear; rsx::surface_raster_type m_active_raster_type = rsx::surface_raster_type::linear;
public: public:
std::pair<u8, u8> m_bound_render_targets_config = {}; rsx::simple_array<u8> m_bound_render_target_ids = {};
std::array<std::pair<u32, surface_type>, 4> m_bound_render_targets = {}; std::array<std::pair<u32, surface_type>, 4> m_bound_render_targets = {};
std::pair<u32, surface_type> m_bound_depth_stencil = {}; std::pair<u32, surface_type> m_bound_depth_stencil = {};
u8 m_bound_buffers_count = 0;
// List of sections derived from a section that has been split and invalidated // List of sections derived from a section that has been split and invalidated
std::vector<surface_type> orphaned_surfaces; std::vector<surface_type> orphaned_surfaces;
@ -840,23 +840,19 @@ namespace rsx
cache_tag = rsx::get_shared_tag(); cache_tag = rsx::get_shared_tag();
m_invalidate_on_write = (antialias != rsx::surface_antialiasing::center_1_sample); m_invalidate_on_write = (antialias != rsx::surface_antialiasing::center_1_sample);
m_active_raster_type = raster_type; m_active_raster_type = raster_type;
m_bound_buffers_count = 0;
// Make previous RTTs sampleable // Make previous RTTs sampleable
for (int i = m_bound_render_targets_config.first, count = 0; for (const auto& i : m_bound_render_target_ids)
count < m_bound_render_targets_config.second;
++i, ++count)
{ {
auto &rtt = m_bound_render_targets[i]; auto &rtt = m_bound_render_targets[i];
Traits::prepare_surface_for_sampling(command_list, std::get<1>(rtt)); Traits::prepare_surface_for_sampling(command_list, std::get<1>(rtt));
rtt = std::make_pair(0, nullptr); rtt = std::make_pair(0, nullptr);
} }
const auto rtt_indices = utility::get_rtt_indexes(set_surface_target); m_bound_render_target_ids.clear();
if (!rtt_indices.empty()) [[likely]] if (const auto rtt_indices = utility::get_rtt_indexes(set_surface_target);
!rtt_indices.empty()) [[likely]]
{ {
m_bound_render_targets_config = { rtt_indices.front(), 0 };
// Create/Reuse requested rtts // Create/Reuse requested rtts
for (u8 surface_index : rtt_indices) for (u8 surface_index : rtt_indices)
{ {
@ -867,14 +863,9 @@ namespace rsx
bind_address_as_render_targets(command_list, surface_addresses[surface_index], color_format, antialias, bind_address_as_render_targets(command_list, surface_addresses[surface_index], color_format, antialias,
clip_width, clip_height, surface_pitch[surface_index], std::forward<Args>(extra_params)...)); clip_width, clip_height, surface_pitch[surface_index], std::forward<Args>(extra_params)...));
++m_bound_render_targets_config.second; m_bound_render_target_ids.push_back(surface_index);
++m_bound_buffers_count;
} }
} }
else
{
m_bound_render_targets_config = { 0, 0 };
}
// Same for depth buffer // Same for depth buffer
if (std::get<1>(m_bound_depth_stencil) != nullptr) if (std::get<1>(m_bound_depth_stencil) != nullptr)
@ -887,8 +878,6 @@ namespace rsx
m_bound_depth_stencil = std::make_pair(address_z, m_bound_depth_stencil = std::make_pair(address_z,
bind_address_as_depth_stencil(command_list, address_z, depth_format, antialias, bind_address_as_depth_stencil(command_list, address_z, depth_format, antialias,
clip_width, clip_height, zeta_pitch, std::forward<Args>(extra_params)...)); clip_width, clip_height, zeta_pitch, std::forward<Args>(extra_params)...));
++m_bound_buffers_count;
} }
else else
{ {
@ -898,7 +887,7 @@ namespace rsx
u8 get_color_surface_count() const u8 get_color_surface_count() const
{ {
return m_bound_render_targets_config.second; return static_cast<u8>(m_bound_render_target_ids.size());
} }
surface_type get_surface_at(u32 address) surface_type get_surface_at(u32 address)
@ -947,14 +936,15 @@ namespace rsx
} }
} }
bool address_is_bound(u32 address) const inline bool address_is_bound(u32 address) const
{ {
for (int i = m_bound_render_targets_config.first, count = 0; ensure(address);
count < m_bound_render_targets_config.second; for (int i = 0; i < 4; ++i)
++i, ++count)
{ {
if (m_bound_render_targets[i].first == address) if (m_bound_render_targets[i].first == address)
{
return true; return true;
}
} }
return (m_bound_depth_stencil.first == address); return (m_bound_depth_stencil.first == address);
@ -1127,21 +1117,33 @@ namespace rsx
// TODO: Take WCB/WDB into account. Should speed this up a bit by skipping sync_tag calls // TODO: Take WCB/WDB into account. Should speed this up a bit by skipping sync_tag calls
write_tag = rsx::get_shared_tag(); write_tag = rsx::get_shared_tag();
for (u8 i = m_bound_render_targets_config.first, count = 0; for (const auto& i : m_bound_render_target_ids)
count < m_bound_render_targets_config.second;
++count, ++i)
{ {
if (auto surface = m_bound_render_targets[i].second; if (color_mrt_writes_enabled[i])
surface && color_mrt_writes_enabled[i])
{ {
surface->on_write(write_tag); auto surface = m_bound_render_targets[i].second;
if (surface->last_use_tag > cache_tag) [[ likely ]]
{
surface->on_write_fast(write_tag);
}
else
{
surface->on_write(write_tag, rsx::surface_state_flags::require_resolve, m_active_raster_type);
}
} }
} }
if (auto zsurface = m_bound_depth_stencil.second; if (auto zsurface = m_bound_depth_stencil.second;
zsurface && depth_stencil_writes_enabled) zsurface && depth_stencil_writes_enabled)
{ {
zsurface->on_write(write_tag); if (zsurface->last_use_tag > cache_tag) [[ likely ]]
{
zsurface->on_write_fast(write_tag);
}
else
{
zsurface->on_write(write_tag, rsx::surface_state_flags::require_resolve, m_active_raster_type);
}
} }
} }
@ -1164,7 +1166,7 @@ namespace rsx
ensure(m_active_memory_used == 0); ensure(m_active_memory_used == 0);
m_bound_depth_stencil = std::make_pair(0, nullptr); m_bound_depth_stencil = std::make_pair(0, nullptr);
m_bound_render_targets_config = { 0, 0 }; m_bound_render_target_ids.clear();
for (auto &rtt : m_bound_render_targets) for (auto &rtt : m_bound_render_targets)
{ {
rtt = std::make_pair(0, nullptr); rtt = std::make_pair(0, nullptr);

View File

@ -623,11 +623,14 @@ namespace rsx
} }
} }
void on_invalidate_children() inline void on_write_fast(u64 write_tag)
{ {
ensure(write_tag);
last_use_tag = write_tag;
if (resolve_surface) if (resolve_surface)
{ {
msaa_flags = rsx::surface_state_flags::require_resolve; msaa_flags |= rsx::surface_state_flags::require_resolve;
} }
} }

View File

@ -644,16 +644,15 @@ void GLGSRender::clear_surface(u32 arg)
gl_state.clear_color(clear_r, clear_g, clear_b, clear_a); gl_state.clear_color(clear_r, clear_g, clear_b, clear_a);
mask |= GLenum(gl::buffers::color); mask |= GLenum(gl::buffers::color);
for (u8 index = m_rtts.m_bound_render_targets_config.first, count = 0; int hw_index = 0;
count < m_rtts.m_bound_render_targets_config.second; for (const auto& index : m_rtts.m_bound_render_target_ids)
++count, ++index)
{ {
if (!full_frame) if (!full_frame)
{ {
m_rtts.m_bound_render_targets[index].second->write_barrier(cmd); m_rtts.m_bound_render_targets[index].second->write_barrier(cmd);
} }
gl_state.color_maski(count, colormask); gl_state.color_maski(hw_index++, colormask);
} }
update_color = true; update_color = true;

View File

@ -1382,9 +1382,7 @@ void VKGSRender::clear_surface(u32 mask)
if (!use_fast_clear || !full_frame) if (!use_fast_clear || !full_frame)
{ {
// If we're not clobber all the memory, a barrier is required // If we're not clobber all the memory, a barrier is required
for (u8 index = m_rtts.m_bound_render_targets_config.first, count = 0; for (const auto& index : m_rtts.m_bound_render_target_ids)
count < m_rtts.m_bound_render_targets_config.second;
++count, ++index)
{ {
m_rtts.m_bound_render_targets[index].second->write_barrier(*m_current_command_buffer); m_rtts.m_bound_render_targets[index].second->write_barrier(*m_current_command_buffer);
} }