mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
Preserve PS5 mip-tail views and GPU data during image expansion
Related work: https://github.com/KytyPS5/KytyPS5/pull/558 Co-authored-by: Çağatay Güçlü <33038942+defektu@users.noreply.github.com>
This commit is contained in:
@@ -86,6 +86,7 @@ struct TileMipLayout {
|
|||||||
uint32_t padded_height = 0;
|
uint32_t padded_height = 0;
|
||||||
uint32_t tail_x = 0;
|
uint32_t tail_x = 0;
|
||||||
uint32_t tail_y = 0;
|
uint32_t tail_y = 0;
|
||||||
|
bool operator==(const TileMipLayout&) const = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TileSurfaceLayout {
|
struct TileSurfaceLayout {
|
||||||
|
|||||||
+14
-3
@@ -208,6 +208,10 @@ bool TextureCache::SameBacking(const ImageInfo& cached, const ImageInfo& request
|
|||||||
if (cached.extent != requested.extent) {
|
if (cached.extent != requested.extent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (cached.resources.levels < requested.resources.levels ||
|
||||||
|
cached.resources.layers < requested.resources.layers) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (cached.samples != requested.samples) {
|
if (cached.samples != requested.samples) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -843,6 +847,16 @@ TextureCache::OverlapResult TextureCache::ResolveOverlap(const ImageInfo& reques
|
|||||||
ImageViewOps::FormatsCompatible(cached.info.pixel_format, requested.pixel_format)) {
|
ImageViewOps::FormatsCompatible(cached.info.pixel_format, requested.pixel_format)) {
|
||||||
return {ExpandImage(requested, cached_id)};
|
return {ExpandImage(requested, cached_id)};
|
||||||
}
|
}
|
||||||
|
// PS5 mip tails can expose more levels without increasing the guest allocation.
|
||||||
|
if (requested.pixel_format == cached.info.pixel_format &&
|
||||||
|
requested.type == cached.info.type && requested.resources > cached.info.resources &&
|
||||||
|
(requested.data.size > cached.info.data.size ||
|
||||||
|
(requested.data.size == cached.info.data.size &&
|
||||||
|
requested.extent == cached.info.extent &&
|
||||||
|
cached.info.resources.levels > 1 &&
|
||||||
|
requested.resources.layers == cached.info.resources.layers))) {
|
||||||
|
return {ExpandImage(requested, cached_id)};
|
||||||
|
}
|
||||||
if (requested.pixel_format != cached.info.pixel_format ||
|
if (requested.pixel_format != cached.info.pixel_format ||
|
||||||
requested.data.size <= cached.info.data.size) {
|
requested.data.size <= cached.info.data.size) {
|
||||||
const auto result_id = merged_id ? merged_id : cached_id;
|
const auto result_id = merged_id ? merged_id : cached_id;
|
||||||
@@ -852,9 +866,6 @@ TextureCache::OverlapResult TextureCache::ResolveOverlap(const ImageInfo& reques
|
|||||||
? result_id
|
? result_id
|
||||||
: ImageId {}};
|
: ImageId {}};
|
||||||
}
|
}
|
||||||
if (requested.type == cached.info.type && requested.resources > cached.info.resources) {
|
|
||||||
return {ExpandImage(requested, cached_id)};
|
|
||||||
}
|
|
||||||
EXIT("TextureCache: unresolvable equal-address image overlap, address=0x%016" PRIx64
|
EXIT("TextureCache: unresolvable equal-address image overlap, address=0x%016" PRIx64
|
||||||
" requested=%ux%u "
|
" requested=%ux%u "
|
||||||
"cached=%ux%u requested_size=0x%016" PRIx64 " cached_size=0x%016" PRIx64
|
"cached=%ux%u requested_size=0x%016" PRIx64 " cached_size=0x%016" PRIx64
|
||||||
|
|||||||
@@ -293,13 +293,8 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
|||||||
const bool supported_swizzle =
|
const bool supported_swizzle =
|
||||||
IsValidImageSwizzle(swizzle) &&
|
IsValidImageSwizzle(swizzle) &&
|
||||||
(swizzle == DstSel(4, 5, 6, 7) || !resource.read || resource.atomic);
|
(swizzle == DstSel(4, 5, 6, 7) || !resource.read || resource.atomic);
|
||||||
const auto max_mip = resource.r128 ? descriptor.LastLevel() : descriptor.MaxMip();
|
|
||||||
const auto view_last_level =
|
|
||||||
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::DynamicStorage
|
|
||||||
? descriptor.LastLevel()
|
|
||||||
: std::min(descriptor.LastLevel(), max_mip);
|
|
||||||
return (is_1d || is_1d_array || is_2d || is_2d_array || is_3d) && supported_tile &&
|
return (is_1d || is_1d_array || is_2d || is_2d_array || is_3d) && supported_tile &&
|
||||||
descriptor.BaseLevel() <= view_last_level && view_last_level <= max_mip &&
|
descriptor.BaseLevel() <= descriptor.LastLevel() &&
|
||||||
descriptor.MinLod() == 0 && supported_swizzle && descriptor.BCSwizzle() == 0 &&
|
descriptor.MinLod() == 0 && supported_swizzle && descriptor.BCSwizzle() == 0 &&
|
||||||
!descriptor.MsaaDepth();
|
!descriptor.MsaaDepth();
|
||||||
}
|
}
|
||||||
@@ -507,6 +502,21 @@ static ImageViewInfo TextureViewInfo(const ShaderRecompiler::IR::ImageResource&
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool TextureViewPreservesMipLayout(const TileSurfaceDescription& description,
|
||||||
|
uint32_t view_levels) {
|
||||||
|
TileSurfaceLayout physical {};
|
||||||
|
TileSurfaceLayout view {};
|
||||||
|
auto view_description = description;
|
||||||
|
view_description.levels = view_levels;
|
||||||
|
return TileGetTiledTextureLayout(description, physical) &&
|
||||||
|
TileGetTiledTextureLayout(view_description, view) &&
|
||||||
|
physical.first_tail_level == view.first_tail_level &&
|
||||||
|
physical.block_slice_size == view.block_slice_size &&
|
||||||
|
physical.total_size == view.total_size &&
|
||||||
|
std::equal(std::begin(physical.mips), std::begin(physical.mips) + description.levels,
|
||||||
|
std::begin(view.mips));
|
||||||
|
}
|
||||||
|
|
||||||
TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
||||||
const ShaderRecompiler::IR::DescriptorValue& value) {
|
const ShaderRecompiler::IR::DescriptorValue& value) {
|
||||||
auto descriptor = DecodeNativeDescriptor<ShaderTextureResource>(value);
|
auto descriptor = DecodeNativeDescriptor<ShaderTextureResource>(value);
|
||||||
@@ -523,24 +533,22 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
|||||||
return {id, nullptr, std::move(desc)};
|
return {id, nullptr, std::move(desc)};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto address = descriptor.Base40();
|
const auto address = descriptor.Base40();
|
||||||
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
|
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
|
||||||
const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u;
|
const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u;
|
||||||
const auto base_level = descriptor.BaseLevel();
|
const auto base_level = descriptor.BaseLevel();
|
||||||
const auto last_level = descriptor.LastLevel();
|
const auto last_level = descriptor.LastLevel();
|
||||||
const auto type = TextureType(descriptor);
|
const auto type = TextureType(descriptor);
|
||||||
const bool multisampled = IsMultisampledTexture(type);
|
const bool multisampled = IsMultisampledTexture(type);
|
||||||
const auto max_mip = resource.r128 ? last_level : descriptor.MaxMip();
|
const auto max_mip = resource.r128 ? last_level : descriptor.MaxMip();
|
||||||
const auto levels = multisampled ? 1u : static_cast<uint32_t>(max_mip) + 1u;
|
const auto physical_levels = multisampled ? 1u : static_cast<uint32_t>(max_mip) + 1u;
|
||||||
const bool dynamic_storage =
|
const auto levels =
|
||||||
storage && resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::DynamicStorage;
|
multisampled ? 1u : std::max(physical_levels, static_cast<uint32_t>(last_level) + 1u);
|
||||||
const auto view_last_level =
|
|
||||||
!multisampled && !dynamic_storage ? std::min(last_level, max_mip) : last_level;
|
|
||||||
const auto tile = descriptor.TileMode();
|
const auto tile = descriptor.TileMode();
|
||||||
const bool depth_tile = tile == Prospero::TileMode::kDepth;
|
const bool depth_tile = tile == Prospero::TileMode::kDepth;
|
||||||
const bool msaa_tile = depth_tile || tile == Prospero::TileMode::kRenderTarget;
|
const bool msaa_tile = depth_tile || tile == Prospero::TileMode::kRenderTarget;
|
||||||
const bool msaa_array = type == Prospero::ImageType::kColor2DMsaaArray;
|
const bool msaa_array = type == Prospero::ImageType::kColor2DMsaaArray;
|
||||||
if ((!multisampled && (base_level > view_last_level || view_last_level >= levels)) ||
|
if ((!multisampled && base_level > last_level) ||
|
||||||
(multisampled &&
|
(multisampled &&
|
||||||
(base_level != 0 || last_level == 0 || last_level > 3 || max_mip != last_level ||
|
(base_level != 0 || last_level == 0 || last_level > 3 || max_mip != last_level ||
|
||||||
!msaa_tile || (descriptor.MsaaDepth() && !depth_tile) ||
|
!msaa_tile || (descriptor.MsaaDepth() && !depth_tile) ||
|
||||||
@@ -559,7 +567,7 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
|||||||
}
|
}
|
||||||
const auto samples = multisampled ? 1u << last_level : 1u;
|
const auto samples = multisampled ? 1u << last_level : 1u;
|
||||||
const auto view_levels =
|
const auto view_levels =
|
||||||
multisampled ? 1u : static_cast<uint32_t>(view_last_level - base_level) + 1u;
|
multisampled ? 1u : static_cast<uint32_t>(last_level - base_level) + 1u;
|
||||||
const auto depth = static_cast<uint32_t>(descriptor.Depth()) + 1u;
|
const auto depth = static_cast<uint32_t>(descriptor.Depth()) + 1u;
|
||||||
const auto format = descriptor.Format();
|
const auto format = descriptor.Format();
|
||||||
const auto surface_format = TextureGetSurfaceFormatInfo(format);
|
const auto surface_format = TextureGetSurfaceFormatInfo(format);
|
||||||
@@ -578,7 +586,19 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
|||||||
type == Prospero::ImageType::kColor2DArray ||
|
type == Prospero::ImageType::kColor2DArray ||
|
||||||
type == Prospero::ImageType::kColor2DMsaaArray;
|
type == Prospero::ImageType::kColor2DMsaaArray;
|
||||||
const auto image_layers = layered ? depth : 1u;
|
const auto image_layers = layered ? depth : 1u;
|
||||||
uint32_t pitch = 0;
|
if (levels > physical_levels) {
|
||||||
|
const TileSurfaceDescription physical {
|
||||||
|
format, tile, volume ? TileSurfaceDimension::Dim3D : TileSurfaceDimension::Dim2D,
|
||||||
|
width, height, volume ? depth : 1u, physical_levels, image_layers};
|
||||||
|
// Texture mip views take precedence over the resource count, but must keep its storage layout.
|
||||||
|
if (!TextureViewPreservesMipLayout(physical, levels)) {
|
||||||
|
EXIT("unsupported texture mip view changes physical layout: base=%u last=%u max=%u "
|
||||||
|
"extent=%ux%ux%u tile=%u\n",
|
||||||
|
base_level, last_level, max_mip, width, height, depth,
|
||||||
|
static_cast<uint32_t>(tile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t pitch = 0;
|
||||||
TileSizeAlign size {};
|
TileSizeAlign size {};
|
||||||
if (multisampled) {
|
if (multisampled) {
|
||||||
const auto bytes = Prospero::NumBytesPerElement(format);
|
const auto bytes = Prospero::NumBytesPerElement(format);
|
||||||
@@ -591,8 +611,8 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
|||||||
size.size *= image_layers;
|
size.size *= image_layers;
|
||||||
} else {
|
} else {
|
||||||
pitch = TileGetTexturePitch(format, width, tile);
|
pitch = TileGetTexturePitch(format, width, tile);
|
||||||
TileGetTextureTotalSize(format, width, height, volume ? depth : image_layers, levels, tile,
|
TileGetTextureTotalSize(format, width, height, volume ? depth : image_layers,
|
||||||
volume, size);
|
physical_levels, tile, volume, size);
|
||||||
}
|
}
|
||||||
EXIT_NOT_IMPLEMENTED(size.size == 0 || size.align == 0 ||
|
EXIT_NOT_IMPLEMENTED(size.size == 0 || size.align == 0 ||
|
||||||
(address & (static_cast<uint64_t>(size.align) - 1u)) != 0);
|
(address & (static_cast<uint64_t>(size.align) - 1u)) != 0);
|
||||||
@@ -629,7 +649,7 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
|||||||
!desc.info.IsDepth()) {
|
!desc.info.IsDepth()) {
|
||||||
TileSizeAlign metadata_size {};
|
TileSizeAlign metadata_size {};
|
||||||
(void)TileGetDccSize(width, height, volume ? depth : image_layers,
|
(void)TileGetDccSize(width, height, volume ? depth : image_layers,
|
||||||
desc.info.bytes_per_block, levels, tile, metadata_size,
|
desc.info.bytes_per_block, physical_levels, tile, metadata_size,
|
||||||
std::countr_zero(samples));
|
std::countr_zero(samples));
|
||||||
desc.info.metadata.kind = ImageMetadataKind::Dcc;
|
desc.info.metadata.kind = ImageMetadataKind::Dcc;
|
||||||
desc.info.metadata.range = {descriptor.MetaAddr() << 8u, metadata_size.size};
|
desc.info.metadata.range = {descriptor.MetaAddr() << 8u, metadata_size.size};
|
||||||
|
|||||||
@@ -8594,7 +8594,8 @@ public:
|
|||||||
|
|
||||||
std::vector<u32> ReadCachedTexel(const char *name, RenderContext &context,
|
std::vector<u32> ReadCachedTexel(const char *name, RenderContext &context,
|
||||||
ImageId id, vk::Offset3D offset = {},
|
ImageId id, vk::Offset3D offset = {},
|
||||||
vk::Extent3D extent = {1, 1, 1}, uint32_t layer = 0) {
|
vk::Extent3D extent = {1, 1, 1}, uint32_t layer = 0,
|
||||||
|
uint32_t mip = 0) {
|
||||||
auto &scheduler = context.GetCommandScheduler();
|
auto &scheduler = context.GetCommandScheduler();
|
||||||
auto &image = context.GetTextureCache().GetImage(id);
|
auto &image = context.GetTextureCache().GetImage(id);
|
||||||
const auto bytes = image.info.bytes_per_block * extent.width *
|
const auto bytes = image.info.bytes_per_block * extent.width *
|
||||||
@@ -8607,7 +8608,7 @@ public:
|
|||||||
scheduler.Current().Handle());
|
scheduler.Current().Handle());
|
||||||
vk::BufferImageCopy copy{};
|
vk::BufferImageCopy copy{};
|
||||||
copy.imageSubresource = {image.info.IsDepth() ? vk::ImageAspectFlagBits::eDepth
|
copy.imageSubresource = {image.info.IsDepth() ? vk::ImageAspectFlagBits::eDepth
|
||||||
: vk::ImageAspectFlagBits::eColor, 0, layer, 1};
|
: vk::ImageAspectFlagBits::eColor, mip, layer, 1};
|
||||||
copy.imageOffset = offset;
|
copy.imageOffset = offset;
|
||||||
copy.imageExtent = extent;
|
copy.imageExtent = extent;
|
||||||
scheduler.Current().Handle().copyImageToBuffer(
|
scheduler.Current().Handle().copyImageToBuffer(
|
||||||
@@ -9602,6 +9603,9 @@ public:
|
|||||||
constexpr uint64_t allocation_alignment = 0x10000;
|
constexpr uint64_t allocation_alignment = 0x10000;
|
||||||
constexpr uint64_t depth_address = base + 0x40000;
|
constexpr uint64_t depth_address = base + 0x40000;
|
||||||
constexpr uint64_t stencil_address = base + 0x70000;
|
constexpr uint64_t stencil_address = base + 0x70000;
|
||||||
|
constexpr uint64_t mipped_storage_address = base + 0x100000;
|
||||||
|
constexpr uint32_t tail_backing_value = 0x2468ace0u;
|
||||||
|
constexpr uint32_t tail_gpu_value = 0x13579bdfu;
|
||||||
EnsureRuntimeContext();
|
EnsureRuntimeContext();
|
||||||
|
|
||||||
int64_t direct_offset = -1;
|
int64_t direct_offset = -1;
|
||||||
@@ -9618,6 +9622,8 @@ public:
|
|||||||
mapped == reinterpret_cast<void *>(base),
|
mapped == reinterpret_cast<void *>(base),
|
||||||
"descriptor discovery fixed mapping failed");
|
"descriptor discovery fixed mapping failed");
|
||||||
std::memset(mapped, 0, allocation_size);
|
std::memset(mapped, 0, allocation_size);
|
||||||
|
std::fill_n(reinterpret_cast<uint32_t *>(mipped_storage_address),
|
||||||
|
0x10000 / 4, tail_backing_value);
|
||||||
|
|
||||||
{
|
{
|
||||||
RenderContext context(m_runtime_context);
|
RenderContext context(m_runtime_context);
|
||||||
@@ -9884,17 +9890,17 @@ public:
|
|||||||
storage_descriptor.dwords.begin());
|
storage_descriptor.dwords.begin());
|
||||||
storage_descriptor.dword_count = 8;
|
storage_descriptor.dword_count = 8;
|
||||||
auto mipped_storage = storage;
|
auto mipped_storage = storage;
|
||||||
constexpr uint64_t mipped_storage_address = base + 0x100000;
|
|
||||||
const auto encoded_mipped_storage_address = mipped_storage_address >> 8u;
|
const auto encoded_mipped_storage_address = mipped_storage_address >> 8u;
|
||||||
mipped_storage.fields[0] =
|
mipped_storage.fields[0] =
|
||||||
static_cast<uint32_t>(encoded_mipped_storage_address);
|
static_cast<uint32_t>(encoded_mipped_storage_address);
|
||||||
mipped_storage.fields[1] =
|
mipped_storage.fields[1] =
|
||||||
static_cast<uint32_t>(encoded_mipped_storage_address >> 32u) |
|
static_cast<uint32_t>(encoded_mipped_storage_address >> 32u) |
|
||||||
(static_cast<uint32_t>(stencil_format) << 20u) | (3u << 30u);
|
(static_cast<uint32_t>(Prospero::BufferFormat::k32UInt) << 20u) |
|
||||||
mipped_storage.fields[2] = 1u | (7u << 14u);
|
(3u << 30u);
|
||||||
|
mipped_storage.fields[2] = 15u | (63u << 14u);
|
||||||
mipped_storage.fields[3] =
|
mipped_storage.fields[3] =
|
||||||
DstSel(4, 5, 6, 7) | (1u << 12u) | (3u << 16u) |
|
DstSel(4, 5, 6, 7) | (1u << 12u) | (3u << 16u) |
|
||||||
(static_cast<uint32_t>(linear) << 20u) |
|
(static_cast<uint32_t>(Prospero::TileMode::kStandard64KB) << 20u) |
|
||||||
(static_cast<uint32_t>(Prospero::ImageType::kColor2D) << 28u);
|
(static_cast<uint32_t>(Prospero::ImageType::kColor2D) << 28u);
|
||||||
mipped_storage.fields[5] = 0x00700000u | (3u << 4u);
|
mipped_storage.fields[5] = 0x00700000u | (3u << 4u);
|
||||||
ShaderRecompiler::IR::DescriptorValue mipped_storage_descriptor{};
|
ShaderRecompiler::IR::DescriptorValue mipped_storage_descriptor{};
|
||||||
@@ -9911,6 +9917,14 @@ public:
|
|||||||
std::end(overwide_mipped_storage.fields),
|
std::end(overwide_mipped_storage.fields),
|
||||||
overwide_mipped_storage_descriptor.dwords.begin());
|
overwide_mipped_storage_descriptor.dwords.begin());
|
||||||
overwide_mipped_storage_descriptor.dword_count = 8;
|
overwide_mipped_storage_descriptor.dword_count = 8;
|
||||||
|
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||||
|
ExpectFatal("MipViewPhysicalLayoutChange", [&] {
|
||||||
|
auto linear_view = overwide_mipped_storage_descriptor;
|
||||||
|
linear_view.dwords[3] &= ~(0x1fu << 20u);
|
||||||
|
(void)RenderExecutorTestAccess::ResolveTexture(executor, storage_resource,
|
||||||
|
linear_view);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
auto mipped_storage_resource = storage_resource;
|
auto mipped_storage_resource = storage_resource;
|
||||||
mipped_storage_resource.mip_mode =
|
mipped_storage_resource.mip_mode =
|
||||||
ShaderRecompiler::IR::ImageMipMode::DynamicStorage;
|
ShaderRecompiler::IR::ImageMipMode::DynamicStorage;
|
||||||
@@ -9925,6 +9939,11 @@ public:
|
|||||||
auto plain_mipped_storage_binding =
|
auto plain_mipped_storage_binding =
|
||||||
RenderExecutorTestAccess::ResolveTexture(executor, storage_resource,
|
RenderExecutorTestAccess::ResolveTexture(executor, storage_resource,
|
||||||
mipped_storage_descriptor);
|
mipped_storage_descriptor);
|
||||||
|
vk::ClearValue tail_clear{};
|
||||||
|
tail_clear.color.uint32[0] = tail_gpu_value;
|
||||||
|
TextureCacheTestAccess::ClearImage(
|
||||||
|
texture_cache, scheduler.Current(), plain_mipped_storage_binding.image_id,
|
||||||
|
{vk::ImageAspectFlagBits::eColor, 0, 4, 0, 1}, tail_clear);
|
||||||
auto mipped_storage_binding = RenderExecutorTestAccess::ResolveTexture(
|
auto mipped_storage_binding = RenderExecutorTestAccess::ResolveTexture(
|
||||||
executor, mipped_storage_resource, mipped_storage_descriptor);
|
executor, mipped_storage_resource, mipped_storage_descriptor);
|
||||||
auto overwide_mipped_storage_binding =
|
auto overwide_mipped_storage_binding =
|
||||||
@@ -9933,6 +9952,16 @@ public:
|
|||||||
auto sampled_overwide_resolved = RenderExecutorTestAccess::ResolveTexture(
|
auto sampled_overwide_resolved = RenderExecutorTestAccess::ResolveTexture(
|
||||||
executor, sampled_overwide_resource,
|
executor, sampled_overwide_resource,
|
||||||
overwide_mipped_storage_descriptor);
|
overwide_mipped_storage_descriptor);
|
||||||
|
const auto tail0 = ReadCachedTexel(name, context, overwide_mipped_storage_binding.image_id);
|
||||||
|
const auto tail3 = ReadCachedTexel(name, context, overwide_mipped_storage_binding.image_id,
|
||||||
|
{}, {1, 1, 1}, 0, 3);
|
||||||
|
const auto tail4 = ReadCachedTexel(name, context, overwide_mipped_storage_binding.image_id,
|
||||||
|
{}, {1, 1, 1}, 0, 4);
|
||||||
|
Require(name, "expanded tail preserves GPU and backing data",
|
||||||
|
tail0 == std::vector<u32>{tail_gpu_value} &&
|
||||||
|
tail3 == std::vector<u32>{tail_gpu_value} &&
|
||||||
|
tail4 == std::vector<u32>{tail_backing_value},
|
||||||
|
"expanding a shared mip tail lost GPU writes or the added mip's backing bytes");
|
||||||
PreparedBindings mipped_prepared{};
|
PreparedBindings mipped_prepared{};
|
||||||
ShaderRecompiler::IR::CompiledShaderInfo mipped_program{};
|
ShaderRecompiler::IR::CompiledShaderInfo mipped_program{};
|
||||||
mipped_program.info.images.push_back(storage_resource);
|
mipped_program.info.images.push_back(storage_resource);
|
||||||
@@ -9994,23 +10023,22 @@ public:
|
|||||||
overwide_mipped_storage.MaxMip() == 3 &&
|
overwide_mipped_storage.MaxMip() == 3 &&
|
||||||
overwide_mipped_binding.image_id ==
|
overwide_mipped_binding.image_id ==
|
||||||
plain_mipped_binding.image_id &&
|
plain_mipped_binding.image_id &&
|
||||||
overwide_mipped_binding.desc.info.resources.levels == 4 &&
|
overwide_mipped_binding.desc.info.resources.levels == 5 &&
|
||||||
overwide_mipped_binding.desc.view_info.base_level == 1 &&
|
overwide_mipped_binding.desc.view_info.base_level == 1 &&
|
||||||
overwide_mipped_binding.desc.view_info.level_count == 3 &&
|
overwide_mipped_binding.desc.view_info.level_count == 4 &&
|
||||||
overwide_mipped_binding.mip_views.empty() &&
|
overwide_mipped_binding.mip_views.empty() &&
|
||||||
overwide_mipped_binding.image_view ==
|
overwide_mipped_binding.image_view ==
|
||||||
plain_mipped_binding.image_view,
|
plain_mipped_binding.image_view,
|
||||||
"fixed storage view was not intersected with its physical mip "
|
"fixed storage view lost addressable mips in the allocated tail");
|
||||||
"range before Vulkan acquisition");
|
|
||||||
Require(name, "over-wide sampled mip view",
|
Require(name, "over-wide sampled mip view",
|
||||||
sampled_overwide_binding.image_id ==
|
sampled_overwide_binding.image_id ==
|
||||||
plain_mipped_binding.image_id &&
|
plain_mipped_binding.image_id &&
|
||||||
sampled_overwide_binding.desc.info.resources.levels == 4 &&
|
sampled_overwide_binding.desc.info.resources.levels == 5 &&
|
||||||
sampled_overwide_binding.desc.view_info.base_level == 1 &&
|
sampled_overwide_binding.desc.view_info.base_level == 1 &&
|
||||||
sampled_overwide_binding.desc.view_info.level_count == 3 &&
|
sampled_overwide_binding.desc.view_info.level_count == 4 &&
|
||||||
sampled_overwide_binding.mip_views.empty() &&
|
sampled_overwide_binding.mip_views.empty() &&
|
||||||
sampled_overwide_binding.image_view != nullptr,
|
sampled_overwide_binding.image_view != nullptr,
|
||||||
"sampled view was not intersected with its physical mip range");
|
"sampled view lost addressable mips in the allocated tail");
|
||||||
auto srgb_storage = storage;
|
auto srgb_storage = storage;
|
||||||
constexpr auto srgb_format =
|
constexpr auto srgb_format =
|
||||||
static_cast<uint32_t>(Prospero::BufferFormat::k8_8_8_8Srgb);
|
static_cast<uint32_t>(Prospero::BufferFormat::k8_8_8_8Srgb);
|
||||||
@@ -27983,12 +28011,6 @@ ShaderTextureResource AtomicStorageTextureDescriptor() {
|
|||||||
descriptor.fields[3] =
|
descriptor.fields[3] =
|
||||||
(descriptor.fields[3] & ~(0x1fu << 20u)) |
|
(descriptor.fields[3] & ~(0x1fu << 20u)) |
|
||||||
(static_cast<uint32_t>(Prospero::TileMode::kStandard256B) << 20u);
|
(static_cast<uint32_t>(Prospero::TileMode::kStandard256B) << 20u);
|
||||||
} else if (std::strcmp(kind, "base-mip-out-of-resource") == 0) {
|
|
||||||
descriptor.fields[3] |= (1u << 12u) | (1u << 16u);
|
|
||||||
} else if (std::strcmp(kind, "dynamic-mip-out-of-resource") == 0) {
|
|
||||||
resource.mip_mode = ShaderRecompiler::IR::ImageMipMode::DynamicStorage;
|
|
||||||
resource.mip_count = 2;
|
|
||||||
descriptor.fields[3] |= 1u << 16u;
|
|
||||||
} else if (std::strcmp(kind, "inverted-mip-range") == 0) {
|
} else if (std::strcmp(kind, "inverted-mip-range") == 0) {
|
||||||
descriptor.fields[3] |= 1u << 12u;
|
descriptor.fields[3] |= 1u << 12u;
|
||||||
descriptor.fields[5] |= 1u << 4u;
|
descriptor.fields[5] |= 1u << 4u;
|
||||||
@@ -28460,8 +28482,6 @@ void CheckBasicStorageTextureDescriptor() {
|
|||||||
for (const char *kind : {"resource",
|
for (const char *kind : {"resource",
|
||||||
"type",
|
"type",
|
||||||
"standard256b-volume",
|
"standard256b-volume",
|
||||||
"base-mip-out-of-resource",
|
|
||||||
"dynamic-mip-out-of-resource",
|
|
||||||
"inverted-mip-range",
|
"inverted-mip-range",
|
||||||
"swizzle",
|
"swizzle",
|
||||||
"linear-rgb1-read",
|
"linear-rgb1-read",
|
||||||
|
|||||||
Reference in New Issue
Block a user