mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 18:28:35 +12: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
4 changed files with 38 additions and 2 deletions
|
@ -165,8 +165,11 @@ namespace rsx
|
||||||
new_surface_storage = std::move(rtt);
|
new_surface_storage = std::move(rtt);
|
||||||
|
|
||||||
if (old_surface)
|
if (old_surface)
|
||||||
|
{
|
||||||
//Exchange this surface with the invalidated one
|
//Exchange this surface with the invalidated one
|
||||||
|
Traits::notify_surface_invalidated(old_surface_storage);
|
||||||
rtt = std::move(old_surface_storage);
|
rtt = std::move(old_surface_storage);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
//rtt is now empty - erase it
|
//rtt is now empty - erase it
|
||||||
invalidated_resources.erase(It);
|
invalidated_resources.erase(It);
|
||||||
|
@ -179,8 +182,11 @@ namespace rsx
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_surface != nullptr && new_surface == nullptr)
|
if (old_surface != nullptr && new_surface == nullptr)
|
||||||
|
{
|
||||||
//This was already determined to be invalid and is excluded from testing above
|
//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));
|
invalidated_resources.push_back(std::move(old_surface_storage));
|
||||||
|
}
|
||||||
|
|
||||||
if (new_surface != nullptr)
|
if (new_surface != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -229,8 +235,11 @@ namespace rsx
|
||||||
new_surface_storage = std::move(ds);
|
new_surface_storage = std::move(ds);
|
||||||
|
|
||||||
if (old_surface)
|
if (old_surface)
|
||||||
|
{
|
||||||
//Exchange this surface with the invalidated one
|
//Exchange this surface with the invalidated one
|
||||||
|
Traits::notify_surface_invalidated(old_surface_storage);
|
||||||
ds = std::move(old_surface_storage);
|
ds = std::move(old_surface_storage);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
invalidated_resources.erase(It);
|
invalidated_resources.erase(It);
|
||||||
|
|
||||||
|
@ -242,8 +251,11 @@ namespace rsx
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_surface != nullptr && new_surface == nullptr)
|
if (old_surface != nullptr && new_surface == nullptr)
|
||||||
|
{
|
||||||
//This was already determined to be invalid and is excluded from testing above
|
//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));
|
invalidated_resources.push_back(std::move(old_surface_storage));
|
||||||
|
}
|
||||||
|
|
||||||
if (new_surface != nullptr)
|
if (new_surface != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -498,6 +510,7 @@ namespace rsx
|
||||||
|
|
||||||
if (surface == ref)
|
if (surface == ref)
|
||||||
{
|
{
|
||||||
|
Traits::notify_surface_invalidated(It->second);
|
||||||
invalidated_resources.push_back(std::move(It->second));
|
invalidated_resources.push_back(std::move(It->second));
|
||||||
m_render_targets_storage.erase(It);
|
m_render_targets_storage.erase(It);
|
||||||
|
|
||||||
|
@ -515,6 +528,7 @@ namespace rsx
|
||||||
|
|
||||||
if (surface == ref)
|
if (surface == ref)
|
||||||
{
|
{
|
||||||
|
Traits::notify_surface_invalidated(It->second);
|
||||||
invalidated_resources.push_back(std::move(It->second));
|
invalidated_resources.push_back(std::move(It->second));
|
||||||
m_depth_stencil_storage.erase(It);
|
m_depth_stencil_storage.erase(It);
|
||||||
|
|
||||||
|
@ -541,6 +555,7 @@ namespace rsx
|
||||||
auto It = m_render_targets_storage.find(addr);
|
auto It = m_render_targets_storage.find(addr);
|
||||||
if (It != m_render_targets_storage.end())
|
if (It != m_render_targets_storage.end())
|
||||||
{
|
{
|
||||||
|
Traits::notify_surface_invalidated(It->second);
|
||||||
invalidated_resources.push_back(std::move(It->second));
|
invalidated_resources.push_back(std::move(It->second));
|
||||||
m_render_targets_storage.erase(It);
|
m_render_targets_storage.erase(It);
|
||||||
|
|
||||||
|
@ -553,6 +568,7 @@ namespace rsx
|
||||||
auto It = m_depth_stencil_storage.find(addr);
|
auto It = m_depth_stencil_storage.find(addr);
|
||||||
if (It != m_depth_stencil_storage.end())
|
if (It != m_depth_stencil_storage.end())
|
||||||
{
|
{
|
||||||
|
Traits::notify_surface_invalidated(It->second);
|
||||||
invalidated_resources.push_back(std::move(It->second));
|
invalidated_resources.push_back(std::move(It->second));
|
||||||
m_depth_stencil_storage.erase(It);
|
m_depth_stencil_storage.erase(It);
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,9 @@ struct render_target_traits
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void notify_surface_invalidated(const ComPtr<ID3D12Resource>&)
|
||||||
|
{}
|
||||||
|
|
||||||
static
|
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)
|
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_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 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
|
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)
|
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;
|
std::unique_ptr<vk::image_view> view;
|
||||||
|
|
||||||
render_target *old_contents = nullptr; //Data occupying the memory location that this surface is replacing
|
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,
|
render_target(vk::render_device &dev,
|
||||||
uint32_t memory_type_index,
|
uint32_t memory_type_index,
|
||||||
|
@ -223,6 +224,7 @@ namespace rsx
|
||||||
|
|
||||||
//Reset deref count
|
//Reset deref count
|
||||||
surface->deref_count = 0;
|
surface->deref_count = 0;
|
||||||
|
surface->frame_tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_rtt_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
static void prepare_rtt_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
||||||
|
@ -238,6 +240,7 @@ namespace rsx
|
||||||
|
|
||||||
//Reset deref count
|
//Reset deref count
|
||||||
surface->deref_count = 0;
|
surface->deref_count = 0;
|
||||||
|
surface->frame_tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_ds_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
|
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;
|
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)
|
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'
|
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()
|
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++;
|
rtt->deref_count++;
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue