rsx: Critical fixes

- texture cache: Avoid leaking memory sections
  - Avoid double ref increment on flush-always reprotection
  - Detect invalidated_resources entries in surface cache when protecting fbo memory
- vk: Copypasta bugfix, properly initialize aspect mask
This commit is contained in:
kd-11 2018-04-16 01:59:45 +03:00 committed by kd-11
parent a42b00488d
commit da99f3cb9a
3 changed files with 34 additions and 6 deletions

View File

@ -849,7 +849,7 @@ namespace rsx
for (auto &tex_info : data)
{
auto this_address = std::get<0>(tex_info);
if (this_address > limit)
if (this_address >= limit)
continue;
auto surface = std::get<1>(tex_info).get();

View File

@ -910,6 +910,7 @@ namespace rsx
}
section_storage_type tmp;
update_cache_tag();
m_cache[block_address].add(tmp, rsx_address, rsx_size);
return m_cache[block_address].data.back();
}
@ -961,10 +962,35 @@ namespace rsx
region.set_context(texture_upload_context::framebuffer_storage);
region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized);
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
update_cache_tag();
region.set_memory_read_flags(memory_read_flags::flush_always);
m_flush_always_cache[memory_address] = memory_size;
//Test for invalidated sections from surface cache occupying same address range
auto &overlapped = find_texture_from_range(memory_address, memory_size);
if (overlapped.size() > 1)
{
for (auto surface : overlapped)
{
if (surface == &region)
continue;
//Memory is shared with another surface
//Discard it - the backend should ensure memory contents are preserved if needed
surface->set_dirty(true);
if (surface->get_context() != rsx::texture_upload_context::framebuffer_storage)
m_unreleased_texture_objects++;
if (surface->is_locked())
{
surface->unprotect();
m_cache[get_block_address(surface->get_section_base())].remove_one();
}
}
}
update_cache_tag();
}
void set_memory_read_flags(u32 memory_address, u32 memory_size, memory_read_flags flags)
@ -2303,18 +2329,20 @@ namespace rsx
if (m_cache_update_tag.load(std::memory_order_consume) != m_flush_always_update_timestamp)
{
writer_lock lock(m_cache_mutex);
bool update_tag = false;
for (const auto &It : m_flush_always_cache)
{
auto& section = find_cached_texture(It.first, It.second);
if (section.get_protection() != utils::protection::no)
{
auto &range = m_cache[get_block_address(It.first)];
//NOTE: find_cached_texture will increment block ctr
section.reprotect(utils::protection::no);
range.notify();
update_tag = true;
}
}
if (update_tag) update_cache_tag();
m_flush_always_update_timestamp = m_cache_update_tag.load(std::memory_order_consume);
}
}

View File

@ -736,7 +736,7 @@ namespace vk
VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, remap_vector, false);
VkImage dst = result->info.image;
VkImageAspectFlags dst_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format);
VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 1 };
vk::change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);