mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 03:16:54 +02:00
Graphics: preserve rendered contents across 1D and 2D texture aliases
This commit is contained in:
+15
-9
@@ -193,7 +193,7 @@ bool TextureCache::SameBacking(const ImageInfo& cached, const ImageInfo& request
|
||||
return false;
|
||||
}
|
||||
if (!ImageViewOps::FormatsCompatible(cached.pixel_format, requested.pixel_format) ||
|
||||
(cached.type != requested.type && requested.extent != vk::Extent3D {1, 1, 1})) {
|
||||
cached.type != requested.type) {
|
||||
return false;
|
||||
}
|
||||
if (exact_format && cached.pixel_format != requested.pixel_format) {
|
||||
@@ -639,9 +639,12 @@ void TextureCache::CopyImage(ImageId destination_id, ImageId source_id) {
|
||||
const bool source_depth = source.info.IsDepth();
|
||||
const bool dest_depth = destination.info.IsDepth();
|
||||
const bool direct_copy =
|
||||
source.backing.format == destination.backing.format ||
|
||||
(!source_depth && !dest_depth &&
|
||||
vk::blockSize(source.backing.format) == vk::blockSize(destination.backing.format));
|
||||
(source.backing.image_type == destination.backing.image_type ||
|
||||
(source.backing.image_type != vk::ImageType::e1D &&
|
||||
destination.backing.image_type != vk::ImageType::e1D)) &&
|
||||
(source.backing.format == destination.backing.format ||
|
||||
(!source_depth && !dest_depth &&
|
||||
vk::blockSize(source.backing.format) == vk::blockSize(destination.backing.format)));
|
||||
if (direct_copy) {
|
||||
destination.CopyImage(source);
|
||||
} else if (!CopyD16(destination, source)) {
|
||||
@@ -810,12 +813,15 @@ TextureCache::OverlapResult TextureCache::ResolveOverlap(const ImageInfo& reques
|
||||
return {merged_id};
|
||||
}
|
||||
// PPSA08394
|
||||
// A view cannot change the native image type or grow its extent.
|
||||
if (requested.data.size == cached.info.data.size &&
|
||||
requested.resources == cached.info.resources && requested.type == cached.info.type &&
|
||||
requested.extent.width > cached.info.extent.width &&
|
||||
requested.extent.height >= cached.info.extent.height &&
|
||||
requested.extent.depth >= cached.info.extent.depth &&
|
||||
ImageViewOps::FormatsCompatible(cached.info.pixel_format, requested.pixel_format)) {
|
||||
requested.resources == cached.info.resources &&
|
||||
ImageViewOps::FormatsCompatible(cached.info.pixel_format, requested.pixel_format) &&
|
||||
(requested.type != cached.info.type
|
||||
? requested.extent == cached.info.extent
|
||||
: requested.extent.width > cached.info.extent.width &&
|
||||
requested.extent.height >= cached.info.extent.height &&
|
||||
requested.extent.depth >= cached.info.extent.depth)) {
|
||||
return {ExpandImage(requested, cached_id)};
|
||||
}
|
||||
// PS5 mip tails can expose more levels without increasing the guest allocation.
|
||||
|
||||
@@ -8478,6 +8478,50 @@ public:
|
||||
{1, 1, 1}, 0, mip) == expected,
|
||||
"the sampled target lost its GPU-written final texel");
|
||||
}
|
||||
if (width == 1 && height == 1) {
|
||||
for (const bool uint_view : {true, false}) {
|
||||
descriptor.fields[1] = static_cast<uint32_t>(
|
||||
uint_view ? Prospero::BufferFormat::k16_16_16_16UInt
|
||||
: Prospero::BufferFormat::k16_16_16_16Float) << 20u;
|
||||
descriptor.fields[3] = 0x81b00facu; // Captured 1D view, tile27, RGBA swizzle.
|
||||
std::copy_n(descriptor.fields, 8, value.dwords.begin());
|
||||
resource.numeric_class = uint_view ? Prospero::TextureNumericClass::Uint
|
||||
: Prospero::TextureNumericClass::Float;
|
||||
resource.dimension = ShaderRecompiler::Decoder::ImageDimension::Dim1D;
|
||||
const auto one_d =
|
||||
RenderExecutorTestAccess::ResolveTexture(executor, resource, value);
|
||||
const auto one_d_view = texture_cache.FindTexture(one_d.image_id, one_d.desc);
|
||||
const auto repeated =
|
||||
RenderExecutorTestAccess::ResolveTexture(executor, resource, value);
|
||||
Require(name, "1D sampled backing and reuse",
|
||||
one_d.image_id != color.image_id && one_d_view != nullptr &&
|
||||
one_d.desc.view_info.type == vk::ImageViewType::e1D &&
|
||||
texture_cache.GetImage(one_d.image_id).backing.image_type ==
|
||||
vk::ImageType::e1D &&
|
||||
repeated.image_id == one_d.image_id &&
|
||||
texture_cache.FindTexture(repeated.image_id, repeated.desc) == one_d_view &&
|
||||
ReadCachedTexel(name, context, one_d.image_id) == expected,
|
||||
"the 1D alias reused an incompatible backing or lost the rendered texel");
|
||||
|
||||
RenderExecutorTestAccess::ResetBindings(executor);
|
||||
RenderExecutorTestAccess::ResolveRenderColorTarget(
|
||||
executor, scheduler.Current(), color, 0);
|
||||
const auto restored = RenderExecutorTestAccess::AcquireRenderTargets(
|
||||
executor, scheduler.Current(), &color, 1, no_depth);
|
||||
scheduler.Current().BeginRendering(restored);
|
||||
scheduler.Current().EndRendering();
|
||||
Require(name, "2D target restoration",
|
||||
color.image_id != one_d.image_id &&
|
||||
restored.color_attachments[0].image_view != nullptr &&
|
||||
texture_cache.GetImage(color.image_id).backing.image_type ==
|
||||
vk::ImageType::e2D &&
|
||||
texture_cache.GetImage(color.image_id).info.pixel_format ==
|
||||
vk::Format::eR16G16B16A16Sfloat &&
|
||||
ReadCachedTexel(name, context, color.image_id) == expected,
|
||||
"restoring the 2D target lost its view type or GPU-written texel");
|
||||
RenderExecutorTestAccess::ResetBindings(executor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderExecutorTestAccess::ResetBindings(executor);
|
||||
|
||||
Reference in New Issue
Block a user