mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-07 03:40:07 +00:00
rsx: Improve surface store resource management
- vk: Use frame testing to determine invalidated resources that can be safely deleted
This commit is contained in:
parent
ec3e5c547f
commit
af1d3c2aa6
@ -165,8 +165,11 @@ namespace rsx
|
||||
new_surface_storage = std::move(rtt);
|
||||
|
||||
if (old_surface)
|
||||
{
|
||||
//Exchange this surface with the invalidated one
|
||||
Traits::notify_surface_invalidated(old_surface_storage);
|
||||
rtt = std::move(old_surface_storage);
|
||||
}
|
||||
else
|
||||
//rtt is now empty - erase it
|
||||
invalidated_resources.erase(It);
|
||||
@ -179,8 +182,11 @@ namespace rsx
|
||||
}
|
||||
|
||||
if (old_surface != nullptr && new_surface == nullptr)
|
||||
{
|
||||
//This was already determined to be invalid and is excluded from testing above
|
||||
Traits::notify_surface_invalidated(old_surface_storage);
|
||||
invalidated_resources.push_back(std::move(old_surface_storage));
|
||||
}
|
||||
|
||||
if (new_surface != nullptr)
|
||||
{
|
||||
@ -229,8 +235,11 @@ namespace rsx
|
||||
new_surface_storage = std::move(ds);
|
||||
|
||||
if (old_surface)
|
||||
{
|
||||
//Exchange this surface with the invalidated one
|
||||
Traits::notify_surface_invalidated(old_surface_storage);
|
||||
ds = std::move(old_surface_storage);
|
||||
}
|
||||
else
|
||||
invalidated_resources.erase(It);
|
||||
|
||||
@ -242,8 +251,11 @@ namespace rsx
|
||||
}
|
||||
|
||||
if (old_surface != nullptr && new_surface == nullptr)
|
||||
{
|
||||
//This was already determined to be invalid and is excluded from testing above
|
||||
Traits::notify_surface_invalidated(old_surface_storage);
|
||||
invalidated_resources.push_back(std::move(old_surface_storage));
|
||||
}
|
||||
|
||||
if (new_surface != nullptr)
|
||||
{
|
||||
@ -498,6 +510,7 @@ namespace rsx
|
||||
|
||||
if (surface == ref)
|
||||
{
|
||||
Traits::notify_surface_invalidated(It->second);
|
||||
invalidated_resources.push_back(std::move(It->second));
|
||||
m_render_targets_storage.erase(It);
|
||||
|
||||
@ -515,6 +528,7 @@ namespace rsx
|
||||
|
||||
if (surface == ref)
|
||||
{
|
||||
Traits::notify_surface_invalidated(It->second);
|
||||
invalidated_resources.push_back(std::move(It->second));
|
||||
m_depth_stencil_storage.erase(It);
|
||||
|
||||
@ -541,6 +555,7 @@ namespace rsx
|
||||
auto It = m_render_targets_storage.find(addr);
|
||||
if (It != m_render_targets_storage.end())
|
||||
{
|
||||
Traits::notify_surface_invalidated(It->second);
|
||||
invalidated_resources.push_back(std::move(It->second));
|
||||
m_render_targets_storage.erase(It);
|
||||
|
||||
@ -553,6 +568,7 @@ namespace rsx
|
||||
auto It = m_depth_stencil_storage.find(addr);
|
||||
if (It != m_depth_stencil_storage.end())
|
||||
{
|
||||
Traits::notify_surface_invalidated(It->second);
|
||||
invalidated_resources.push_back(std::move(It->second));
|
||||
m_depth_stencil_storage.erase(It);
|
||||
|
||||
|
@ -142,6 +142,9 @@ struct render_target_traits
|
||||
//TODO
|
||||
}
|
||||
|
||||
static
|
||||
void notify_surface_invalidated(const ComPtr<ID3D12Resource>&)
|
||||
{}
|
||||
|
||||
static
|
||||
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height, bool=false)
|
||||
|
@ -253,6 +253,10 @@ struct gl_render_target_traits
|
||||
static void invalidate_rtt_surface_contents(void *, gl::render_target *rtt, gl::render_target* /*old*/, bool forced) { if (forced) rtt->set_cleared(false); }
|
||||
static void invalidate_depth_surface_contents(void *, gl::render_target *ds, gl::render_target* /*old*/, bool) { ds->set_cleared(false); }
|
||||
|
||||
static
|
||||
void notify_surface_invalidated(const std::unique_ptr<gl::render_target>&)
|
||||
{}
|
||||
|
||||
static
|
||||
bool rtt_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_color_format format, size_t width, size_t height, bool check_refs=false)
|
||||
{
|
||||
|
@ -26,6 +26,7 @@ namespace vk
|
||||
std::unique_ptr<vk::image_view> view;
|
||||
|
||||
render_target *old_contents = nullptr; //Data occupying the memory location that this surface is replacing
|
||||
u64 frame_tag = 0; //frame id when invalidated, 0 if not invalid
|
||||
|
||||
render_target(vk::render_device &dev,
|
||||
uint32_t memory_type_index,
|
||||
@ -223,6 +224,7 @@ namespace rsx
|
||||
|
||||
//Reset deref count
|
||||
surface->deref_count = 0;
|
||||
surface->frame_tag = 0;
|
||||
}
|
||||
|
||||
static void prepare_rtt_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
||||
@ -238,6 +240,7 @@ namespace rsx
|
||||
|
||||
//Reset deref count
|
||||
surface->deref_count = 0;
|
||||
surface->frame_tag = 0;
|
||||
}
|
||||
|
||||
static void prepare_ds_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
||||
@ -261,6 +264,12 @@ namespace rsx
|
||||
ds->old_contents = old_surface;
|
||||
}
|
||||
|
||||
static
|
||||
void notify_surface_invalidated(const std::unique_ptr<vk::render_target> &surface)
|
||||
{
|
||||
surface->frame_tag = vk::get_current_frame_id();
|
||||
}
|
||||
|
||||
static bool rtt_has_format_width_height(const std::unique_ptr<vk::render_target> &rtt, surface_color_format format, size_t width, size_t height, bool check_refs=false)
|
||||
{
|
||||
if (check_refs && rtt->deref_count == 0) //Surface may still have read refs from data 'copy'
|
||||
@ -337,9 +346,13 @@ namespace rsx
|
||||
|
||||
void free_invalidated()
|
||||
{
|
||||
invalidated_resources.remove_if([](std::unique_ptr<vk::render_target> &rtt)
|
||||
const u64 last_finished_frame = vk::get_last_completed_frame_id();
|
||||
invalidated_resources.remove_if([&](std::unique_ptr<vk::render_target> &rtt)
|
||||
{
|
||||
if (rtt->deref_count >= 2) return true;
|
||||
verify(HERE), rtt->frame_tag != 0;
|
||||
|
||||
if (rtt->deref_count >= 2 && rtt->frame_tag < last_finished_frame)
|
||||
return true;
|
||||
|
||||
rtt->deref_count++;
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user