1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

rsx: Fix for framebuffer validation

This commit is contained in:
kd-11 2017-11-03 17:17:39 +03:00
parent 3288050680
commit daaa83b9ca

View File

@ -207,19 +207,30 @@ namespace rsx
private: private:
//Internal implementation methods and helpers //Internal implementation methods and helpers
utils::protection get_memory_protection(u32 address) std::pair<utils::protection, section_storage_type*> get_memory_protection(u32 address)
{ {
auto found = m_cache.find(get_block_address(address)); auto found = m_cache.find(get_block_address(address));
if (found != m_cache.end()) if (found != m_cache.end())
{ {
for (const auto &tex : found->second.data) for (auto &tex : found->second.data)
{ {
if (tex.is_locked() && tex.overlaps(address, false)) if (tex.is_locked() && tex.overlaps(address, false))
return tex.get_protection(); return{ tex.get_protection(), &tex };
} }
} }
return utils::protection::rw; //Get the preceding block and check if any hits are found
found = m_cache.find(get_block_address(address) - get_block_size());
if (found != m_cache.end())
{
for (auto &tex : found->second.data)
{
if (tex.is_locked() && tex.overlaps(address, false))
return{ tex.get_protection(), &tex };
}
}
return{ utils::protection::rw, nullptr };
} }
inline bool region_intersects_cache(u32 address, u32 range, bool is_writing) const inline bool region_intersects_cache(u32 address, u32 range, bool is_writing) const
@ -1379,12 +1390,26 @@ namespace rsx
if (!g_cfg.video.strict_rendering_mode) if (!g_cfg.video.strict_rendering_mode)
return; return;
switch (get_memory_protection(texaddr)) writer_lock lock(m_cache_mutex);
const auto protect_info = get_memory_protection(texaddr);
if (protect_info.first != utils::protection::rw)
{ {
case utils::protection::no: if (protect_info.second->overlaps(texaddr, true))
return; {
case utils::protection::ro: if (protect_info.first == utils::protection::no)
LOG_ERROR(RSX, "Framebuffer memory occupied by regular texture!"); return;
if (protect_info.second->get_context() != texture_upload_context::blit_engine_dst)
{
//TODO: Invalidate this section
LOG_TRACE(RSX, "Framebuffer memory occupied by regular texture!");
}
}
protect_info.second->unprotect();
vm::ps3::write32(texaddr, texaddr);
protect_info.second->protect(protect_info.first);
return; return;
} }
@ -1398,8 +1423,19 @@ namespace rsx
if (g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer) if (g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer)
{ {
if (get_memory_protection(texaddr) == utils::protection::no) writer_lock lock(m_cache_mutex);
return true; auto protect_info = get_memory_protection(texaddr);
if (protect_info.first == utils::protection::no)
{
if (protect_info.second->overlaps(texaddr, true))
return true;
//Address isnt actually covered by the region, it only shares a page with it
protect_info.second->unprotect();
bool result = (vm::ps3::read32(texaddr) == texaddr);
protect_info.second->protect(utils::protection::no);
return result;
}
} }
return vm::ps3::read32(texaddr) == texaddr; return vm::ps3::read32(texaddr) == texaddr;