mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-09-18 07:22:25 +00:00
rsx: Tweak blit engine heurestics a bit
- Reject writes to RTT if the source data is of unknown origin. non-RTT data and only 1 line in length is suspicious and often GPU data like programs or other rendering inputs.
This commit is contained in:
parent
c1d7b46235
commit
1206a5d4b7
1 changed files with 52 additions and 40 deletions
|
@ -2056,53 +2056,16 @@ namespace rsx
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Surface exists in local memory.
|
// Surface exists in local memory.
|
||||||
// 1. Invalidate surfaces in range
|
|
||||||
// 2. Proceed as normal, blit into a 'normal' surface and any upload routines should catch it
|
|
||||||
m_rtts.invalidate_range(utils::address_range::start_length(dst_address, dst.pitch * dst_h));
|
|
||||||
use_null_region = (is_copy_op && !is_format_convert);
|
use_null_region = (is_copy_op && !is_format_convert);
|
||||||
|
|
||||||
|
// Invalidate surfaces in range. Sample tests should catch overlaps in theory.
|
||||||
|
m_rtts.invalidate_range(utils::address_range::start_length(dst_address, dst.pitch* dst_h));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle cases where src or dst can be a depth texture while the other is a color texture - requires a render pass to emulate
|
// TODO: Handle cases where src or dst can be a depth texture while the other is a color texture - requires a render pass to emulate
|
||||||
auto src_subres = rtt_lookup(src_address, src_w, src_h, src.pitch, src_bpp, false);
|
auto src_subres = rtt_lookup(src_address, src_w, src_h, src.pitch, src_bpp, false);
|
||||||
src_is_render_target = src_subres.surface != nullptr;
|
src_is_render_target = src_subres.surface != nullptr;
|
||||||
|
|
||||||
// Always use GPU blit if src or dst is in the surface store
|
|
||||||
if (!src_is_render_target && !dst_is_render_target)
|
|
||||||
{
|
|
||||||
const bool is_trivial_copy = is_copy_op && !is_format_convert && !dst.swizzled;
|
|
||||||
if (is_trivial_copy)
|
|
||||||
{
|
|
||||||
// Check if trivial memcpy can perform the same task
|
|
||||||
// Used to copy programs and arbitrary data to the GPU in some cases
|
|
||||||
// NOTE: This case overrides the GPU texture scaling option
|
|
||||||
if ((src_h == 1 && dst_h == 1) || (dst_w == src_w && dst_h == src_h && src.pitch == dst.pitch))
|
|
||||||
{
|
|
||||||
if (dst.scale_x > 0.f && dst.scale_y > 0.f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a matching section exists with a different use-case, fall back to CPU memcpy
|
|
||||||
skip_if_collision_exists = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_cfg.video.use_gpu_texture_scaling)
|
|
||||||
{
|
|
||||||
if (dst.swizzled)
|
|
||||||
{
|
|
||||||
// Swizzle operation requested. Use fallback
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_trivial_copy && get_location(dst_address) != CELL_GCM_LOCATION_LOCAL)
|
|
||||||
{
|
|
||||||
// Trivial copy and the destination is in XDR memory
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src_is_render_target)
|
if (src_is_render_target)
|
||||||
{
|
{
|
||||||
const auto surf = src_subres.surface;
|
const auto surf = src_subres.surface;
|
||||||
|
@ -2130,6 +2093,55 @@ namespace rsx
|
||||||
use_null_region = false;
|
use_null_region = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Determine whether to perform this transfer on CPU or GPU (src data may not be graphical)
|
||||||
|
const bool is_trivial_copy = is_copy_op && !is_format_convert && !dst.swizzled;
|
||||||
|
const bool is_block_transfer = (dst_w == src_w && dst_h == src_h && (src.pitch == dst.pitch || src_h == 1));
|
||||||
|
const bool is_mirror_op = (dst.scale_x < 0.f || dst.scale_y < 0.f);
|
||||||
|
|
||||||
|
if (dst_is_render_target)
|
||||||
|
{
|
||||||
|
if (is_trivial_copy && src_h == 1)
|
||||||
|
{
|
||||||
|
dst_is_render_target = false;
|
||||||
|
dst_subres = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always use GPU blit if src or dst is in the surface store
|
||||||
|
if (!dst_is_render_target)
|
||||||
|
{
|
||||||
|
if (is_trivial_copy)
|
||||||
|
{
|
||||||
|
// Check if trivial memcpy can perform the same task
|
||||||
|
// Used to copy programs and arbitrary data to the GPU in some cases
|
||||||
|
// NOTE: This case overrides the GPU texture scaling option
|
||||||
|
if (is_block_transfer && !is_mirror_op)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a matching section exists with a different use-case, fall back to CPU memcpy
|
||||||
|
skip_if_collision_exists = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_cfg.video.use_gpu_texture_scaling)
|
||||||
|
{
|
||||||
|
if (dst.swizzled)
|
||||||
|
{
|
||||||
|
// Swizzle operation requested. Use fallback
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_trivial_copy && get_location(dst_address) != CELL_GCM_LOCATION_LOCAL)
|
||||||
|
{
|
||||||
|
// Trivial copy and the destination is in XDR memory
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dst_is_render_target)
|
if (dst_is_render_target)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue