mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
renderer: broaden compatibility
This commit is contained in:
@@ -270,7 +270,7 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, c
|
|||||||
supported_msaa_array) &&
|
supported_msaa_array) &&
|
||||||
levels_ok && descriptor.MinLod() == 0 &&
|
levels_ok && descriptor.MinLod() == 0 &&
|
||||||
descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) &&
|
descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) &&
|
||||||
descriptor.BCSwizzle() == 0 && descriptor.MsaaDepth() == multisampled &&
|
descriptor.BCSwizzle() == 0 && (!descriptor.MsaaDepth() || multisampled) &&
|
||||||
pitch >= width && pitch == image.info.pitch;
|
pitch >= width && pitch == image.info.pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,10 +424,14 @@ void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
|
|||||||
const bool encoding_ok = IsSupportedStorageTextureEncoding(descriptor);
|
const bool encoding_ok = IsSupportedStorageTextureEncoding(descriptor);
|
||||||
const bool uint_resource =
|
const bool uint_resource =
|
||||||
resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint;
|
resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint;
|
||||||
|
const bool raw_sint_storage =
|
||||||
|
format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) && uint_resource &&
|
||||||
|
resource.written && !resource.read && !resource.atomic;
|
||||||
const bool format_ok =
|
const bool format_ok =
|
||||||
Prospero::IsSupportedTextureFormat(format) &&
|
raw_sint_storage ||
|
||||||
|
(Prospero::IsSupportedTextureFormat(format) &&
|
||||||
uint_resource == Prospero::IsUintTextureFormat(format) &&
|
uint_resource == Prospero::IsUintTextureFormat(format) &&
|
||||||
(!resource.atomic || format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt));
|
(!resource.atomic || format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt)));
|
||||||
if (resource_ok && descriptor_ok && encoding_ok && format_ok && size != 0) {
|
if (resource_ok && descriptor_ok && encoding_ok && format_ok && size != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -614,14 +618,14 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
|||||||
const bool multisampled = IsMultisampledTexture(type);
|
const bool multisampled = IsMultisampledTexture(type);
|
||||||
const auto levels = multisampled ? 1u : static_cast<uint32_t>(descriptor.MaxMip()) + 1u;
|
const auto levels = multisampled ? 1u : static_cast<uint32_t>(descriptor.MaxMip()) + 1u;
|
||||||
const auto tile = descriptor.TileMode();
|
const auto tile = descriptor.TileMode();
|
||||||
|
const bool depth_tile = tile == Prospero::GpuEnumValue(Prospero::TileMode::kDepth);
|
||||||
const bool msaa_tile =
|
const bool msaa_tile =
|
||||||
tile == Prospero::GpuEnumValue(descriptor.MsaaDepth() ? Prospero::TileMode::kDepth
|
depth_tile || tile == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
|
||||||
: Prospero::TileMode::kRenderTarget);
|
|
||||||
const bool msaa_array = type == Prospero::ImageType::kColor2DMsaaArray;
|
const bool msaa_array = type == Prospero::ImageType::kColor2DMsaaArray;
|
||||||
if ((!multisampled && (base_level > last_level || last_level >= levels)) ||
|
if ((!multisampled && (base_level > last_level || last_level >= levels)) ||
|
||||||
(multisampled &&
|
(multisampled &&
|
||||||
(base_level != 0 || last_level == 0 || last_level > 3 ||
|
(base_level != 0 || last_level == 0 || last_level > 3 ||
|
||||||
descriptor.MaxMip() != last_level || !msaa_tile ||
|
descriptor.MaxMip() != last_level || !msaa_tile || (descriptor.MsaaDepth() && !depth_tile) ||
|
||||||
(!msaa_array && (descriptor.Depth() != 0 || descriptor.BaseArray5() != 0))))) {
|
(!msaa_array && (descriptor.Depth() != 0 || descriptor.BaseArray5() != 0))))) {
|
||||||
EXIT("unsupported texture mip view: base=%u last=%u levels=%u max=%u type=%u tile=%u "
|
EXIT("unsupported texture mip view: base=%u last=%u levels=%u max=%u type=%u tile=%u "
|
||||||
"kind=%u dimension=%u mip_mode=%u read=%d written=%d "
|
"kind=%u dimension=%u mip_mode=%u read=%d written=%d "
|
||||||
@@ -657,7 +661,8 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
|||||||
TileSizeAlign size {};
|
TileSizeAlign size {};
|
||||||
if (multisampled) {
|
if (multisampled) {
|
||||||
const auto bytes = Prospero::NumBytesPerElement(format);
|
const auto bytes = Prospero::NumBytesPerElement(format);
|
||||||
pitch = TileGetRenderTargetPitch(width, bytes, last_level);
|
pitch = depth_tile ? TileGetDepthPitch(width, bytes, last_level)
|
||||||
|
: TileGetRenderTargetPitch(width, bytes, last_level);
|
||||||
if (pitch == 0 || !TileGetRenderTargetSize(width, height, pitch, bytes, size, last_level) ||
|
if (pitch == 0 || !TileGetRenderTargetSize(width, height, pitch, bytes, size, last_level) ||
|
||||||
size.size > UINT32_MAX / image_layers) {
|
size.size > UINT32_MAX / image_layers) {
|
||||||
EXIT("unsupported multisample texture layout\n");
|
EXIT("unsupported multisample texture layout\n");
|
||||||
@@ -675,7 +680,10 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto pixel_format = TextureGetFormat(format);
|
const auto pixel_format = TextureGetFormat(format);
|
||||||
const auto storage_view_format = SrgbStorageViewFormat(pixel_format);
|
const auto storage_view_format =
|
||||||
|
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt)
|
||||||
|
? vk::Format::eR32Uint
|
||||||
|
: SrgbStorageViewFormat(pixel_format);
|
||||||
const auto view_format = storage && storage_view_format != vk::Format::eUndefined
|
const auto view_format = storage && storage_view_format != vk::Format::eUndefined
|
||||||
? storage_view_format
|
? storage_view_format
|
||||||
: pixel_format;
|
: pixel_format;
|
||||||
|
|||||||
@@ -220,8 +220,12 @@ bool ValidateResourceSpecialization(const Program& program, const ResourceSnapsh
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto uint_descriptor =
|
const auto format = (descriptor.dwords[1] >> 20u) & 0x1ffu;
|
||||||
Prospero::IsUintTextureFormat((descriptor.dwords[1] >> 20u) & 0x1ffu);
|
const bool raw_sint_storage =
|
||||||
|
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) &&
|
||||||
|
!image.read && !image.atomic;
|
||||||
|
const bool uint_descriptor =
|
||||||
|
Prospero::IsUintTextureFormat(format) || raw_sint_storage;
|
||||||
const auto uint_program = image.kind == ResourceKind::ImageUint ||
|
const auto uint_program = image.kind == ResourceKind::ImageUint ||
|
||||||
image.kind == ResourceKind::StorageImageUint;
|
image.kind == ResourceKind::StorageImageUint;
|
||||||
if (uint_descriptor != uint_program && !(image.atomic && uint_program)) {
|
if (uint_descriptor != uint_program && !(image.atomic && uint_program)) {
|
||||||
@@ -408,7 +412,14 @@ bool SpecializeResources(Program& program, const ResourceSnapshot& snapshot, std
|
|||||||
image.kind == ResourceKind::StorageImageUint) {
|
image.kind == ResourceKind::StorageImageUint) {
|
||||||
image.storage_swizzle = DescriptorImageSwizzle(descriptor);
|
image.storage_swizzle = DescriptorImageSwizzle(descriptor);
|
||||||
}
|
}
|
||||||
if (Prospero::IsUintTextureFormat((descriptor.dwords[1] >> 20u) & 0x1ffu)) {
|
const auto format = (descriptor.dwords[1] >> 20u) & 0x1ffu;
|
||||||
|
const bool storage = image.kind == ResourceKind::StorageImage ||
|
||||||
|
image.kind == ResourceKind::StorageImageUint;
|
||||||
|
const bool raw_sint_storage =
|
||||||
|
storage && format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) &&
|
||||||
|
!image.read && !image.atomic;
|
||||||
|
const bool uint_image = Prospero::IsUintTextureFormat(format) || raw_sint_storage;
|
||||||
|
if (uint_image) {
|
||||||
switch (image.kind) {
|
switch (image.kind) {
|
||||||
case ResourceKind::Image: image.kind = ResourceKind::ImageUint; break;
|
case ResourceKind::Image: image.kind = ResourceKind::ImageUint; break;
|
||||||
case ResourceKind::StorageImage: image.kind = ResourceKind::StorageImageUint; break;
|
case ResourceKind::StorageImage: image.kind = ResourceKind::StorageImageUint; break;
|
||||||
|
|||||||
@@ -4733,6 +4733,45 @@ public:
|
|||||||
"storage descriptor did not preserve its sRGB backing and "
|
"storage descriptor did not preserve its sRGB backing and "
|
||||||
"select an UNORM Vulkan view");
|
"select an UNORM Vulkan view");
|
||||||
|
|
||||||
|
ShaderTextureResource sint_storage {{0x01514b00u, 0xc1500000u, 0x000bc00bu,
|
||||||
|
0x91b00204u, 0x00000000u, 0x00700000u,
|
||||||
|
0x102b0000u, 0x0001514au}};
|
||||||
|
Require(name, "PPSA06888 R32 SINT descriptor",
|
||||||
|
sint_storage.Base40() == 0x1514b0000ull && sint_storage.Width5() + 1u == 48 &&
|
||||||
|
sint_storage.Height5() + 1u == 48 && sint_storage.Depth() + 1u == 1 &&
|
||||||
|
sint_storage.Format() ==
|
||||||
|
Prospero::GpuEnumValue(Prospero::BufferFormat::k32SInt) &&
|
||||||
|
sint_storage.Type() ==
|
||||||
|
Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
|
||||||
|
sint_storage.TileMode() ==
|
||||||
|
Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) &&
|
||||||
|
sint_storage.DstSelXYZW() == DstSel(4, 0, 0, 1),
|
||||||
|
"captured write-only signed storage descriptor was decoded incorrectly");
|
||||||
|
const uint64_t mapped_sint_address = base + 0xe0000;
|
||||||
|
const auto encoded_sint_address = mapped_sint_address >> 8u;
|
||||||
|
sint_storage.fields[0] = static_cast<uint32_t>(encoded_sint_address);
|
||||||
|
sint_storage.fields[1] =
|
||||||
|
(sint_storage.fields[1] & ~0xffu) |
|
||||||
|
static_cast<uint32_t>(encoded_sint_address >> 32u);
|
||||||
|
ShaderRecompiler::IR::DescriptorValue sint_storage_descriptor {};
|
||||||
|
std::copy(std::begin(sint_storage.fields), std::end(sint_storage.fields),
|
||||||
|
sint_storage_descriptor.dwords.begin());
|
||||||
|
sint_storage_descriptor.dword_count = 8;
|
||||||
|
auto sint_storage_resource = srgb_storage_resource;
|
||||||
|
sint_storage_resource.kind = ShaderRecompiler::IR::ResourceKind::StorageImageUint;
|
||||||
|
const auto sint_storage_binding = RenderExecutorTestAccess::ResolveTexture(
|
||||||
|
executor, sint_storage_resource, sint_storage_descriptor);
|
||||||
|
const auto sint_storage_view =
|
||||||
|
texture_cache.FindTexture(sint_storage_binding.image_id, sint_storage_binding.desc);
|
||||||
|
Require(name, "PPSA06888 raw R32 SINT storage view",
|
||||||
|
sint_storage_view != nullptr &&
|
||||||
|
sint_storage_binding.desc.info.data.size == 0x10000 &&
|
||||||
|
sint_storage_binding.desc.info.pixel_format == vk::Format::eR32Sint &&
|
||||||
|
sint_storage_binding.desc.view_info.format == vk::Format::eR32Uint &&
|
||||||
|
texture_cache.GetImage(sint_storage_binding.image_id).backing.format ==
|
||||||
|
vk::Format::eR32Sint,
|
||||||
|
"write-only R32 SINT storage did not select a bit-compatible uint view");
|
||||||
|
|
||||||
auto narrowed_storage = storage;
|
auto narrowed_storage = storage;
|
||||||
constexpr uint64_t narrowed_storage_address = base + 0xd0000;
|
constexpr uint64_t narrowed_storage_address = base + 0xd0000;
|
||||||
const auto encoded_narrowed_address = narrowed_storage_address >> 8u;
|
const auto encoded_narrowed_address = narrowed_storage_address >> 8u;
|
||||||
@@ -13604,6 +13643,33 @@ TestCase ImageStoreR32FloatUsesFormatlessStorageImage() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase ImageStoreR32SintUsesRawUintView() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
|
std::vector<u32> code;
|
||||||
|
AppendVMovU32(&code, 20, 2);
|
||||||
|
AppendVMovU32(&code, 21, 1);
|
||||||
|
AppendVMovU32(&code, 22, 0);
|
||||||
|
AppendVMovLiteral(&code, 0, 0x80000001u);
|
||||||
|
code.push_back(EncodeMimg0(0x08, 0x1));
|
||||||
|
code.push_back(EncodeMimg1(0, 20));
|
||||||
|
AppendEnd(&code);
|
||||||
|
|
||||||
|
std::vector<u32> expected_image(16, 0);
|
||||||
|
expected_image[1 * 4 + 2] = 0x80000001u;
|
||||||
|
|
||||||
|
TestCase test;
|
||||||
|
test.name = "ImageStoreR32SintUsesRawUintView";
|
||||||
|
test.code = code;
|
||||||
|
test.opcodes = {O::VMovB32, O::ImageStore, O::SEndpgm};
|
||||||
|
test.user_data = MakeStorageTextureData(Prospero::BufferFormat::k32SInt);
|
||||||
|
test.has_user_data = true;
|
||||||
|
test.storage_image_r32ui = std::vector<u32>(16, 0);
|
||||||
|
test.expected_storage_image_r32ui = expected_image;
|
||||||
|
test.required_spirv = {"storage_uint_2d"};
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase ImageStoreR32UintUsesUintStorageImage() {
|
TestCase ImageStoreR32UintUsesUintStorageImage() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -14181,6 +14247,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(ImageStoreBgraUsesInverseSwizzle);
|
AddCase(ImageStoreBgraUsesInverseSwizzle);
|
||||||
AddCase(ImageStoreYzwxUsesInverseSwizzle);
|
AddCase(ImageStoreYzwxUsesInverseSwizzle);
|
||||||
AddCase(ImageStoreR32FloatUsesFormatlessStorageImage);
|
AddCase(ImageStoreR32FloatUsesFormatlessStorageImage);
|
||||||
|
AddCase(ImageStoreR32SintUsesRawUintView);
|
||||||
AddCase(ImageStoreR32UintUsesUintStorageImage);
|
AddCase(ImageStoreR32UintUsesUintStorageImage);
|
||||||
AddCase(ComputeTgSizeSgprUsesWaveMetadata);
|
AddCase(ComputeTgSizeSgprUsesWaveMetadata);
|
||||||
AddCase(ImageAtomicVariants);
|
AddCase(ImageAtomicVariants);
|
||||||
@@ -15114,7 +15181,7 @@ void CheckSampledDepthDescriptor(RenderContext& renderer) {
|
|||||||
auto& context = renderer.GetGraphics();
|
auto& context = renderer.GetGraphics();
|
||||||
CommandScheduler scheduler(renderer, context);
|
CommandScheduler scheduler(renderer, context);
|
||||||
const auto make_info = [](uint32_t width, uint32_t height, uint32_t pitch, uint32_t layers,
|
const auto make_info = [](uint32_t width, uint32_t height, uint32_t pitch, uint32_t layers,
|
||||||
vk::Format format, Prospero::ImageType type) {
|
vk::Format format, Prospero::ImageType type, uint32_t samples = 1) {
|
||||||
ImageInfo info {};
|
ImageInfo info {};
|
||||||
info.pixel_format = format;
|
info.pixel_format = format;
|
||||||
info.guest_format = Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float);
|
info.guest_format = Prospero::GpuEnumValue(Prospero::BufferFormat::k32Float);
|
||||||
@@ -15123,7 +15190,7 @@ void CheckSampledDepthDescriptor(RenderContext& renderer) {
|
|||||||
info.resources = {1, layers};
|
info.resources = {1, layers};
|
||||||
info.pitch = pitch;
|
info.pitch = pitch;
|
||||||
info.bytes_per_block = 4;
|
info.bytes_per_block = 4;
|
||||||
info.samples = 1;
|
info.samples = samples;
|
||||||
info.tile_mode = Prospero::GpuEnumValue(Prospero::TileMode::kDepth);
|
info.tile_mode = Prospero::GpuEnumValue(Prospero::TileMode::kDepth);
|
||||||
info.mip_layout[0] = {0, static_cast<uint64_t>(pitch) * height * layers * 4, pitch, height};
|
info.mip_layout[0] = {0, static_cast<uint64_t>(pitch) * height * layers * 4, pitch, height};
|
||||||
return info;
|
return info;
|
||||||
@@ -15141,6 +15208,20 @@ void CheckSampledDepthDescriptor(RenderContext& renderer) {
|
|||||||
IsSupportedDepthTargetDescriptor(descriptor, image),
|
IsSupportedDepthTargetDescriptor(descriptor, image),
|
||||||
"normalized depth image rejected a valid padded descriptor");
|
"normalized depth image rejected a valid padded descriptor");
|
||||||
|
|
||||||
|
const ShaderTextureResource uncompressed_msaa {{
|
||||||
|
0x00705d00u, 0xc1600000u, 0x010dc1dfu, 0xe1810924u,
|
||||||
|
0x00000000u, 0x00700010u, 0x00000000u, 0x00000000u,
|
||||||
|
}};
|
||||||
|
auto msaa_info =
|
||||||
|
make_info(1920, 1080, 1920, 1, vk::Format::eD32Sfloat, Prospero::ImageType::kColor2D, 2);
|
||||||
|
msaa_info.mip_layout[0] = {0, 0x010e0000, 1920, 1152};
|
||||||
|
Image msaa_image(context, scheduler, msaa_info);
|
||||||
|
msaa_image.usage.depth_target = true;
|
||||||
|
Require("SampledDepthDescriptor", "uncompressed 2x MSAA depth",
|
||||||
|
IsSupportedDepthTargetDescriptor(uncompressed_msaa, msaa_image) &&
|
||||||
|
IsSupportedDepthTextureEncoding(uncompressed_msaa, msaa_image),
|
||||||
|
"valid uncompressed MSAA depth descriptor required an HTILE compatibility flag");
|
||||||
|
|
||||||
descriptor.fields[3] = (descriptor.fields[3] & ~(0xfu << 28u)) |
|
descriptor.fields[3] = (descriptor.fields[3] & ~(0xfu << 28u)) |
|
||||||
(Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) << 28u);
|
(Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) << 28u);
|
||||||
Require("SampledDepthDescriptor", "singleton array descriptor",
|
Require("SampledDepthDescriptor", "singleton array descriptor",
|
||||||
|
|||||||
Reference in New Issue
Block a user