Advances to rendering: broad guards, fix tiling (thin 64KB), ignore noperspective

This commit is contained in:
nmzik committed 2026-07-16 19:58:11 +02:00
1 parent 147188b143
commit ceb7c6765e
6 files changed
+132 -40

No files matched your search

+32 -35
View File
@@ -299,10 +299,10 @@ static bool Gen5Standard64KBLayout(uint32_t format, uint32_t* bytes_per_element,
} }
} }
static bool Gen5RenderTargetBlockSizeFromElementBytes(uint32_t bytes_per_element, static bool Gen5Thin64KBBlockSizeFromElementBytes(uint32_t bytes_per_element,
uint32_t* block_width, uint32_t* block_width,
uint32_t* block_height) { uint32_t* block_height) {
// AGC render-target // AGC thin 64 KiB block table, shared by depth and render-target tiles.
switch (bytes_per_element) { switch (bytes_per_element) {
case 1: case 1:
*block_width = 256; *block_width = 256;
@@ -1182,7 +1182,7 @@ static void ConvertRenderTargetTyped(uint32_t width, uint32_t height, uint32_t p
uint32_t block_width = 0; uint32_t block_width = 0;
uint32_t block_height = 0; uint32_t block_height = 0;
EXIT_NOT_IMPLEMENTED(!Gen5RenderTargetBlockSizeFromElementBytes( EXIT_NOT_IMPLEMENTED(!Gen5Thin64KBBlockSizeFromElementBytes(
static_cast<uint32_t>(sizeof(T)), &block_width, &block_height)); static_cast<uint32_t>(sizeof(T)), &block_width, &block_height));
const uint64_t blocks_per_row = (static_cast<uint64_t>(pitch) + block_width - 1u) / block_width; const uint64_t blocks_per_row = (static_cast<uint64_t>(pitch) + block_width - 1u) / block_width;
@@ -2448,8 +2448,8 @@ bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t
uint32_t TileGetRenderTargetPitch(uint32_t width, uint32_t bytes_per_element) { uint32_t TileGetRenderTargetPitch(uint32_t width, uint32_t bytes_per_element) {
uint32_t block_width = 0; uint32_t block_width = 0;
uint32_t block_height = 0; uint32_t block_height = 0;
if (width == 0 || !Gen5RenderTargetBlockSizeFromElementBytes(bytes_per_element, &block_width, if (width == 0 || !Gen5Thin64KBBlockSizeFromElementBytes(bytes_per_element, &block_width,
&block_height)) { &block_height)) {
return 0; return 0;
} }
const uint64_t pitch = (static_cast<uint64_t>(width) + block_width - 1u) & const uint64_t pitch = (static_cast<uint64_t>(width) + block_width - 1u) &
@@ -2463,8 +2463,8 @@ bool TileGetRenderTargetSize(uint32_t width, uint32_t height, uint32_t pitch,
uint32_t block_width = 0; uint32_t block_width = 0;
uint32_t block_height = 0; uint32_t block_height = 0;
if (height == 0 || pitch == 0 || if (height == 0 || pitch == 0 ||
!Gen5RenderTargetBlockSizeFromElementBytes(bytes_per_element, &block_width, !Gen5Thin64KBBlockSizeFromElementBytes(bytes_per_element, &block_width,
&block_height) || &block_height) ||
pitch != TileGetRenderTargetPitch(width, bytes_per_element)) { pitch != TileGetRenderTargetPitch(width, bytes_per_element)) {
return false; return false;
} }
@@ -2590,7 +2590,7 @@ void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32
bytes_per_element != 0 && tile == 27 && levels == 1) { bytes_per_element != 0 && tile == 27 && levels == 1) {
uint32_t block_width = 0; uint32_t block_width = 0;
uint32_t block_height = 0; uint32_t block_height = 0;
EXIT_NOT_IMPLEMENTED(!Gen5RenderTargetBlockSizeFromElementBytes( EXIT_NOT_IMPLEMENTED(!Gen5Thin64KBBlockSizeFromElementBytes(
bytes_per_element, &block_width, &block_height)); bytes_per_element, &block_width, &block_height));
const uint32_t padded_width = AlignUp(pitch, block_width); const uint32_t padded_width = AlignUp(pitch, block_width);
@@ -2619,7 +2619,7 @@ void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32
bytes_per_element != 0 && tile == 27 && levels > 1) { bytes_per_element != 0 && tile == 27 && levels > 1) {
uint32_t block_width = 0; uint32_t block_width = 0;
uint32_t block_height = 0; uint32_t block_height = 0;
EXIT_NOT_IMPLEMENTED(!Gen5RenderTargetBlockSizeFromElementBytes( EXIT_NOT_IMPLEMENTED(!Gen5Thin64KBBlockSizeFromElementBytes(
bytes_per_element, &block_width, &block_height)); bytes_per_element, &block_width, &block_height));
const uint32_t bytes_log2 = IntLog2(bytes_per_element); const uint32_t bytes_log2 = IntLog2(bytes_per_element);
@@ -2842,17 +2842,15 @@ void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32
if (tile == 24 && levels == 1) { if (tile == 24 && levels == 1) {
const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format); const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format);
if (bytes_per_element != 0) { if (bytes_per_element != 0) {
uint32_t block_width = 0; uint32_t block_width = 0;
switch (bytes_per_element) { uint32_t block_height = 0;
case 1: block_width = 512; break; const bool supported = bytes_per_element <= 4 &&
case 2: block_width = 256; break; Gen5Thin64KBBlockSizeFromElementBytes(
case 4: block_width = 128; break; bytes_per_element, &block_width, &block_height);
default: break;
}
if (block_width != 0) { if (supported) {
const uint32_t padded_width = (pitch + block_width - 1u) & ~(block_width - 1u); const uint32_t padded_width = (pitch + block_width - 1u) & ~(block_width - 1u);
const uint32_t padded_height = (height + 127u) & ~127u; const uint32_t padded_height = AlignUp(height, block_height);
const uint32_t size = padded_width * padded_height * bytes_per_element; const uint32_t size = padded_width * padded_height * bytes_per_element;
if (total_size != nullptr) { if (total_size != nullptr) {
@@ -2878,15 +2876,13 @@ void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32
if (tile == 24 && levels > 1) { if (tile == 24 && levels > 1) {
const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format); const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format);
if (bytes_per_element != 0) { if (bytes_per_element != 0) {
uint32_t block_width = 0; uint32_t block_width = 0;
switch (bytes_per_element) { uint32_t block_height = 0;
case 1: block_width = 512; break; const bool supported = bytes_per_element <= 4 &&
case 2: block_width = 256; break; Gen5Thin64KBBlockSizeFromElementBytes(
case 4: block_width = 128; break; bytes_per_element, &block_width, &block_height);
default: break;
}
if (block_width != 0) { if (supported) {
static bool logged = false; static bool logged = false;
if (!logged) { if (!logged) {
LOGF("\t temporary: sizing PS5 depth tiled texture with mips, format = %u, " LOGF("\t temporary: sizing PS5 depth tiled texture with mips, format = %u, "
@@ -2902,7 +2898,7 @@ void TileGetTextureSize(uint32_t format, uint32_t width, uint32_t height, uint32
offset = AlignUp(offset, 65536u); offset = AlignUp(offset, 65536u);
const uint32_t padded_width = AlignUp(mip_pitch, block_width); const uint32_t padded_width = AlignUp(mip_pitch, block_width);
const uint32_t padded_height = AlignUp(mip_height, 128u); const uint32_t padded_height = AlignUp(mip_height, block_height);
const uint32_t size = padded_width * padded_height * bytes_per_element; const uint32_t size = padded_width * padded_height * bytes_per_element;
if (level_sizes != nullptr) { if (level_sizes != nullptr) {
@@ -3130,7 +3126,7 @@ uint32_t TileGetTexturePitch(uint32_t format, uint32_t width, uint32_t levels, u
if (const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format); bytes_per_element != 0) { if (const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format); bytes_per_element != 0) {
uint32_t block_width = 0; uint32_t block_width = 0;
uint32_t block_height = 0; uint32_t block_height = 0;
EXIT_NOT_IMPLEMENTED(!Gen5RenderTargetBlockSizeFromElementBytes( EXIT_NOT_IMPLEMENTED(!Gen5Thin64KBBlockSizeFromElementBytes(
bytes_per_element, &block_width, &block_height)); bytes_per_element, &block_width, &block_height));
pitch = AlignUp(pitch, block_width); pitch = AlignUp(pitch, block_width);
} }
@@ -3152,11 +3148,12 @@ uint32_t TileGetTexturePitch(uint32_t format, uint32_t width, uint32_t levels, u
pitch = AlignUp(pitch, (1u << block_width_log2) * texels_per_element_wide); pitch = AlignUp(pitch, (1u << block_width_log2) * texels_per_element_wide);
} }
if (tile == 24) { if (tile == 24) {
switch (Prospero::NumBytesPerElement(format)) { const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format);
case 1: pitch = (pitch + 511u) & ~511u; break; uint32_t block_width = 0;
case 2: pitch = (pitch + 255u) & ~255u; break; uint32_t block_height = 0;
case 4: pitch = (pitch + 127u) & ~127u; break; if (bytes_per_element <= 4 && Gen5Thin64KBBlockSizeFromElementBytes(
default: break; bytes_per_element, &block_width, &block_height)) {
pitch = AlignUp(pitch, block_width);
} }
} }
+3 -1
View File
@@ -692,11 +692,13 @@ static void ClipPrint(const char* func, const HW::ClipControl& c) {
} }
static void ClipCheck(const HW::ClipControl& c) { static void ClipCheck(const HW::ClipControl& c) {
// dx_linear_attr_clip_enable preserves linear (noperspective) attributes at clip-generated
// vertices, which Vulkan provides as part of clipping and interpolation.
EXIT_NOT_IMPLEMENTED(c.user_clip_planes != 0 || c.user_clip_plane_mode != 0 || EXIT_NOT_IMPLEMENTED(c.user_clip_planes != 0 || c.user_clip_plane_mode != 0 ||
c.vertex_kill_any || c.min_z_clip_disable || c.max_z_clip_disable || c.vertex_kill_any || c.min_z_clip_disable || c.max_z_clip_disable ||
c.user_clip_plane_negate_y || c.clip_disable || c.user_clip_plane_negate_y || c.clip_disable ||
c.user_clip_plane_cull_only || c.cull_on_clipping_error_disable || c.user_clip_plane_cull_only || c.cull_on_clipping_error_disable ||
c.linear_attribute_clip_enable || c.force_viewport_index_from_vs_enable); c.force_viewport_index_from_vs_enable);
} }
static void RcPrint(const char* func, const HW::RenderControl& c) { static void RcPrint(const char* func, const HW::RenderControl& c) {
+10 -2
View File
@@ -310,7 +310,10 @@ static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource
static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::ImageResource& resource, static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::ImageResource& resource,
const ShaderTextureResource& descriptor) { const ShaderTextureResource& descriptor) {
const auto tile = descriptor.TileMode(); const auto tile = descriptor.TileMode();
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u;
const auto depth = static_cast<uint32_t>(descriptor.Depth()) + 1u;
const bool is_2d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D && const bool is_2d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) && descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
descriptor.Depth() == 0; descriptor.Depth() == 0;
@@ -320,8 +323,13 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
descriptor.BaseArray5() <= descriptor.Depth(); descriptor.BaseArray5() <= descriptor.Depth();
const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D && const bool is_3d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D &&
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D); descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D);
const bool supported_depth_tile =
tile == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && !resource.read &&
resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint &&
IsSupportedStorageDepthTile(descriptor.Format(), descriptor.Type(), width, height, depth);
const bool supported_tile = tile == Prospero::GpuEnumValue(Prospero::TileMode::kLinear) || const bool supported_tile = tile == Prospero::GpuEnumValue(Prospero::TileMode::kLinear) ||
tile == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget); tile == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) ||
supported_depth_tile;
const bool supported_swizzle = const bool supported_swizzle =
IsSupportedStorageSwizzle(descriptor.Format(), descriptor.DstSelXYZW()) && IsSupportedStorageSwizzle(descriptor.Format(), descriptor.DstSelXYZW()) &&
(descriptor.DstSelXYZW() == DstSel(4, 5, 6, 7) || !resource.read); (descriptor.DstSelXYZW() == DstSel(4, 5, 6, 7) || !resource.read);
@@ -21,6 +21,14 @@ namespace Libs::Graphics {
swizzle == DstSel(5, 6, 7, 4)); swizzle == DstSel(5, 6, 7, 4));
} }
[[nodiscard]] inline bool IsSupportedStorageDepthTile(uint32_t format, uint32_t type,
uint32_t width, uint32_t height,
uint32_t depth) noexcept {
return format == Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt) &&
type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) && width == 1 &&
height == 1 && depth == 1;
}
[[noreturn]] inline void UnsupportedColorView(const char* usage, VkFormat image_format, [[noreturn]] inline void UnsupportedColorView(const char* usage, VkFormat image_format,
VkFormat view_format, uint32_t swizzle) noexcept { VkFormat view_format, uint32_t swizzle) noexcept {
EXIT("unsupported %s color image view: image_format=%d view_format=%d swizzle=0x%03x\n", usage, EXIT("unsupported %s color image view: image_format=%d view_format=%d swizzle=0x%03x\n", usage,
@@ -1549,12 +1549,16 @@ StorageTextureVulkanImage* TextureCache::FindStorageTexture(CommandBuffer* com
const bool supported_type = info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) || const bool supported_type = info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) ||
info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) || info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) ||
info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D); info.type == Prospero::GpuEnumValue(Prospero::ImageType::kColor3D);
const bool supported_depth_tile =
info.tile == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) &&
IsSupportedStorageDepthTile(info.format, info.type, info.width, info.height, info.depth);
if (command == nullptr || ctx == nullptr || info.address == 0 || info.size == 0 || if (command == nullptr || ctx == nullptr || info.address == 0 || info.size == 0 ||
info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address || info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address ||
info.width == 0 || info.height == 0 || info.depth == 0 || info.levels != 1 || info.width == 0 || info.height == 0 || info.depth == 0 || info.levels != 1 ||
info.base_level != 0 || info.view_levels != 1 || info.base_array != 0 || !supported_type || info.base_level != 0 || info.view_levels != 1 || info.base_array != 0 || !supported_type ||
(info.tile != Prospero::GpuEnumValue(Prospero::TileMode::kLinear) && (info.tile != Prospero::GpuEnumValue(Prospero::TileMode::kLinear) &&
info.tile != Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget)) || info.tile != Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) &&
!supported_depth_tile) ||
!IsSupportedStorageSwizzle(info.format, info.swizzle)) { !IsSupportedStorageSwizzle(info.format, info.swizzle)) {
EXIT("TextureCache: unsupported storage-image request, command=%p ctx=%p " EXIT("TextureCache: unsupported storage-image request, command=%p ctx=%p "
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 "addr=0x%016" PRIx64 " size=0x%016" PRIx64
+74 -1
View File
@@ -9064,6 +9064,15 @@ ShaderTextureResource BasicUintArrayStorageTextureDescriptor() {
0x00000000u, 0x00700000u, 0x00000000u, 0x00000000u}}; 0x00000000u, 0x00700000u, 0x00000000u, 0x00000000u}};
} }
ShaderRecompiler::IR::ImageResource Ppsa14053DepthTileStorageTextureResource() {
return BasicUintArrayStorageTextureResource();
}
ShaderTextureResource Ppsa14053DepthTileStorageTextureDescriptor() {
return {{0x20144c00u, 0x00500000u, 0x00000000u, 0xd1800204u,
0x00000000u, 0x00700000u, 0x00000000u, 0x00000000u}};
}
ShaderRecompiler::IR::ImageResource BasicUintVolumeStorageTextureResource() { ShaderRecompiler::IR::ImageResource BasicUintVolumeStorageTextureResource() {
auto resource = BasicStorageTextureResource(); auto resource = BasicStorageTextureResource();
resource.kind = ShaderRecompiler::IR::ResourceKind::StorageImageUint; resource.kind = ShaderRecompiler::IR::ResourceKind::StorageImageUint;
@@ -9127,6 +9136,14 @@ ShaderTextureResource BasicUintVolumeStorageTextureDescriptor() {
} else if (std::strcmp(kind, "uint-resource-float-format") == 0) { } else if (std::strcmp(kind, "uint-resource-float-format") == 0) {
resource = BasicUintArrayStorageTextureResource(); resource = BasicUintArrayStorageTextureResource();
descriptor = BasicArrayStorageTextureDescriptor(); descriptor = BasicArrayStorageTextureDescriptor();
} else if (std::strcmp(kind, "depth-tile-read") == 0) {
resource = Ppsa14053DepthTileStorageTextureResource();
descriptor = Ppsa14053DepthTileStorageTextureDescriptor();
resource.read = true;
} else if (std::strcmp(kind, "depth-tile-extent") == 0) {
resource = Ppsa14053DepthTileStorageTextureResource();
descriptor = Ppsa14053DepthTileStorageTextureDescriptor();
descriptor.fields[2] |= 1u;
} else { } else {
std::_Exit(0x7e); std::_Exit(0x7e);
} }
@@ -9207,6 +9224,21 @@ void CheckBasicStorageTextureDescriptor() {
"PPSA21268 uint 3D storage descriptor fixture is malformed"); "PPSA21268 uint 3D storage descriptor fixture is malformed");
ValidateStorageTexture(BasicUintVolumeStorageTextureResource(), uint_volume, 0x10000); ValidateStorageTexture(BasicUintVolumeStorageTextureResource(), uint_volume, 0x10000);
const auto depth_tile = Ppsa14053DepthTileStorageTextureDescriptor();
Require("BasicStorageTexture", "PPSA14053 depth-tile descriptor",
depth_tile.Base40() == 0x20144c0000ull && depth_tile.Width5() + 1u == 1 &&
depth_tile.Height5() + 1u == 1 && depth_tile.Depth() + 1u == 1 &&
depth_tile.BaseArray5() == 0 &&
depth_tile.Type() ==
Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) &&
depth_tile.Format() ==
Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt) &&
depth_tile.TileMode() ==
Prospero::GpuEnumValue(Prospero::TileMode::kDepth) &&
depth_tile.DstSelXYZW() == DstSel(4, 0, 0, 1),
"PPSA14053 write-only depth-tile storage descriptor fixture is malformed");
ValidateStorageTexture(Ppsa14053DepthTileStorageTextureResource(), depth_tile, 0x10000);
char path[MAX_PATH]{}; char path[MAX_PATH]{};
Require("BasicStorageTexture", "host", Require("BasicStorageTexture", "host",
GetModuleFileNameA(nullptr, path, MAX_PATH) != 0, GetModuleFileNameA(nullptr, path, MAX_PATH) != 0,
@@ -9214,7 +9246,8 @@ void CheckBasicStorageTextureDescriptor() {
for (const char *kind : {"resource", "type", "tile", "mip", "swizzle", for (const char *kind : {"resource", "type", "tile", "mip", "swizzle",
"linear-rgb1-read", "bgra-read", "yzwx-read", "yzwx-format", "linear-rgb1-read", "bgra-read", "yzwx-read", "yzwx-format",
"array-base-view", "reserved", "metadata", "uint-format", "array-base-view", "reserved", "metadata", "uint-format",
"uint-resource-float-format"}) { "uint-resource-float-format", "depth-tile-read",
"depth-tile-extent"}) {
std::string command = std::string("\"") + path + std::string command = std::string("\"") + path +
"\" --storage-texture-descriptor-death " + kind; "\" --storage-texture-descriptor-death " + kind;
std::vector<char> mutable_command(command.begin(), command.end()); std::vector<char> mutable_command(command.begin(), command.end());
@@ -9268,6 +9301,45 @@ void CheckStorageTextureLinearUploadLayout() {
std::printf("[host] %-32s ok\n", "StorageTextureLinearUpload"); std::printf("[host] %-32s ok\n", "StorageTextureLinearUpload");
} }
void CheckStorageTextureDepthTileUploadLayout() {
constexpr uint32_t format = Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt);
constexpr uint32_t width = 1;
constexpr uint32_t height = 1;
constexpr uint32_t depth = 1;
constexpr uint32_t tile = Prospero::GpuEnumValue(Prospero::TileMode::kDepth);
const auto pitch = TileGetTexturePitch(format, width, 1, tile);
TileSizeAlign slice{};
TileSizeAlign total{};
TileSizeOffset level{};
TilePaddedSize padded{};
TileGetTextureSize(format, width, height, pitch, 1, tile, &slice, &level,
&padded);
TileGetTextureTotalSize(format, width, height, depth, pitch, 1, tile, false,
&total);
const auto layout = TextureCalcUploadLayout(
format, width, height, 1, depth, pitch, tile, total.size, true, false,
false, "StorageTextureDepthTileTest");
const auto regions = TextureBuildUploadRegions(
layout, VK_FORMAT_R8_UINT, width, height, depth, 1, true, false,
TextureUploadDestination::MipLevels,
TextureUploadSliceLayout::MipChainPerSlice);
Require("StorageTextureDepthTileUpload", "PPSA14053 layout",
pitch == 256 && padded.width == 256 && padded.height == 256 &&
slice.size == 0x10000 && slice.align == 0x10000 &&
level.size == slice.size && level.offset == 0 &&
total.size == slice.size && total.align == slice.align &&
layout.tile == tile && layout.fmt_tiled_depth &&
!layout.fmt_tiled_render_target && layout.pitch == pitch &&
layout.slice_stride == total.size && regions.size() == 1 &&
regions[0].offset == 0 && regions[0].width == width &&
regions[0].height == height && regions[0].pitch == pitch &&
TextureCalcUploadSize(layout, regions, 1, depth,
TextureUploadSliceLayout::MipChainPerSlice) ==
total.size,
"1x1 R8_UINT depth tile lost its PS5 64 KiB block footprint");
std::printf("[host] %-32s ok\n", "StorageTextureDepthTileUpload");
}
void CheckStorageTextureLinearReadbackLayout() { void CheckStorageTextureLinearReadbackLayout() {
ImageInfo info{}; ImageInfo info{};
info.address = 0x4bcc40100ull; info.address = 0x4bcc40100ull;
@@ -11049,6 +11121,7 @@ int main(int argc, char **argv) {
CheckBufferCacheRangeMerge(); CheckBufferCacheRangeMerge();
CheckBasicStorageTextureDescriptor(); CheckBasicStorageTextureDescriptor();
CheckStorageTextureLinearUploadLayout(); CheckStorageTextureLinearUploadLayout();
CheckStorageTextureDepthTileUploadLayout();
CheckStorageTextureLinearReadbackLayout(); CheckStorageTextureLinearReadbackLayout();
CheckStorageImageSwizzleSpecializationId(); CheckStorageImageSwizzleSpecializationId();
CheckRenderTargetTileRoundTrip(); CheckRenderTargetTileRoundTrip();