mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-24 09:39:55 +00:00
rsx: Blit engine fixes
- If a transfer writes to a RTT and depth mismatch happens, create a local target and the upload function will likely resolve between the two - If a surface is rejected, reset the target region!
This commit is contained in:
parent
86ad204636
commit
41b87cf577
@ -2290,6 +2290,7 @@ namespace rsx
|
|||||||
if (!g_cfg.video.use_gpu_texture_scaling && !(src_is_render_target || dst_is_render_target))
|
if (!g_cfg.video.use_gpu_texture_scaling && !(src_is_render_target || dst_is_render_target))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
// Check if trivial memcpy can perform the same task
|
// Check if trivial memcpy can perform the same task
|
||||||
// Used to copy programs and arbitrary data to the GPU in some cases
|
// Used to copy programs and arbitrary data to the GPU in some cases
|
||||||
if (!src_is_render_target && !dst_is_render_target && dst_is_argb8 == src_is_argb8 && !dst.swizzled)
|
if (!src_is_render_target && !dst_is_render_target && dst_is_argb8 == src_is_argb8 && !dst.swizzled)
|
||||||
@ -2315,6 +2316,17 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity and format compatibility checks
|
||||||
|
if (dst_is_render_target)
|
||||||
|
{
|
||||||
|
if (src_subres.is_depth != dst_subres.is_depth)
|
||||||
|
{
|
||||||
|
// Create a cache-local resource to resolve later
|
||||||
|
// TODO: Support depth->RGBA typeless transfer for vulkan
|
||||||
|
dst_is_render_target = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (src_is_render_target)
|
if (src_is_render_target)
|
||||||
{
|
{
|
||||||
src_subres.surface->read_barrier(cmd);
|
src_subres.surface->read_barrier(cmd);
|
||||||
@ -2377,12 +2389,11 @@ namespace rsx
|
|||||||
|
|
||||||
reader_lock lock(m_cache_mutex);
|
reader_lock lock(m_cache_mutex);
|
||||||
|
|
||||||
|
const auto old_dst_area = dst_area;
|
||||||
if (!dst_is_render_target)
|
if (!dst_is_render_target)
|
||||||
{
|
{
|
||||||
// Check for any available region that will fit this one
|
// Check for any available region that will fit this one
|
||||||
auto overlapping_surfaces = find_texture_from_range(address_range::start_length(dst_address, dst.pitch * dst.clip_height), dst.pitch, rsx::texture_upload_context::blit_engine_dst);
|
auto overlapping_surfaces = find_texture_from_range(address_range::start_length(dst_address, dst.pitch * dst.clip_height), dst.pitch, rsx::texture_upload_context::blit_engine_dst);
|
||||||
const auto old_dst_area = dst_area;
|
|
||||||
|
|
||||||
for (const auto &surface : overlapping_surfaces)
|
for (const auto &surface : overlapping_surfaces)
|
||||||
{
|
{
|
||||||
if (!surface->is_locked())
|
if (!surface->is_locked())
|
||||||
@ -2444,24 +2455,19 @@ namespace rsx
|
|||||||
max_dst_height = dst_subres.surface->get_surface_height();
|
max_dst_height = dst_subres.surface->get_surface_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool src_is_depth = src_subres.is_depth;
|
// Check if available target is acceptable
|
||||||
const bool dst_is_depth = dst_is_render_target? dst_subres.is_depth :
|
// TODO: Check for other types of format mismatch
|
||||||
dest_texture ? cached_dest->is_depth_texture() : src_is_depth;
|
bool format_mismatch = false;
|
||||||
|
if (cached_dest)
|
||||||
// Type of blit decided by the source, destination use should adapt on the fly
|
|
||||||
const bool is_depth_blit = src_is_depth;
|
|
||||||
|
|
||||||
bool format_mismatch = (src_is_depth != dst_is_depth);
|
|
||||||
if (format_mismatch)
|
|
||||||
{
|
{
|
||||||
if (dst_is_render_target)
|
if (cached_dest->is_depth_texture() != src_subres.is_depth)
|
||||||
{
|
{
|
||||||
LOG_ERROR(RSX, "Depth<->RGBA blit on a framebuffer requested but not supported");
|
// Dest surface has the wrong 'aspect'
|
||||||
return false;
|
format_mismatch = true;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else if (src_is_render_target && cached_dest)
|
|
||||||
{
|
{
|
||||||
|
// Check if it matches the transfer declaration
|
||||||
switch (cached_dest->get_gcm_format())
|
switch (cached_dest->get_gcm_format())
|
||||||
{
|
{
|
||||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||||
@ -2477,15 +2483,14 @@ namespace rsx
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Check for other types of format mismatch
|
|
||||||
const address_range dst_range = address_range::start_length(dst_address, dst.pitch * dst.height);
|
|
||||||
AUDIT(cached_dest == nullptr || cached_dest->overlaps(dst_range, section_bounds::full_range));
|
|
||||||
if (format_mismatch)
|
if (format_mismatch)
|
||||||
{
|
{
|
||||||
// The invalidate call before creating a new target will remove this section
|
// The invalidate call before creating a new target will remove this section
|
||||||
cached_dest = nullptr;
|
cached_dest = nullptr;
|
||||||
dest_texture = 0;
|
dest_texture = 0;
|
||||||
|
dst_area = old_dst_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create source texture if does not exist
|
// Create source texture if does not exist
|
||||||
@ -2564,7 +2569,10 @@ namespace rsx
|
|||||||
typeless_info.src_context = texture_upload_context::framebuffer_storage;
|
typeless_info.src_context = texture_upload_context::framebuffer_storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type of blit decided by the source, destination use should adapt on the fly
|
||||||
|
const bool is_depth_blit = src_subres.is_depth;
|
||||||
u32 gcm_format;
|
u32 gcm_format;
|
||||||
|
|
||||||
if (is_depth_blit)
|
if (is_depth_blit)
|
||||||
gcm_format = (dst_is_argb8) ? CELL_GCM_TEXTURE_DEPTH24_D8 : CELL_GCM_TEXTURE_DEPTH16;
|
gcm_format = (dst_is_argb8) ? CELL_GCM_TEXTURE_DEPTH24_D8 : CELL_GCM_TEXTURE_DEPTH16;
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user