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:
parent
3288050680
commit
daaa83b9ca
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user