rsx: Improve surface store resource management

- vk: Use frame testing to determine invalidated resources that can be safely deleted
This commit is contained in:
kd-11 2017-10-31 21:01:24 +03:00
parent ec3e5c547f
commit af1d3c2aa6
4 changed files with 38 additions and 2 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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;