mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
graphics: broaden storage image atomic compatibility
This commit is contained in:
@@ -103,11 +103,9 @@ IsSupportedSampledDepthUintResource(const ShaderRecompiler::IR::ImageResource& r
|
|||||||
|
|
||||||
inline void ValidateStorageColorView(vk::Format image_format, vk::Format view_format,
|
inline void ValidateStorageColorView(vk::Format image_format, vk::Format view_format,
|
||||||
uint32_t swizzle) noexcept {
|
uint32_t swizzle) noexcept {
|
||||||
const auto srgb_view = SrgbStorageViewFormat(image_format);
|
const auto srgb_view = SrgbStorageViewFormat(image_format);
|
||||||
const bool srgb_storage_view =
|
const bool srgb_storage_view = srgb_view != vk::Format::eUndefined && view_format == srgb_view;
|
||||||
srgb_view != vk::Format::eUndefined && view_format == srgb_view;
|
if ((image_format != view_format && !srgb_storage_view) || !IsValidImageSwizzle(swizzle)) {
|
||||||
if ((image_format != view_format && !srgb_storage_view) ||
|
|
||||||
!IsValidImageSwizzle(swizzle)) {
|
|
||||||
UnsupportedColorView("storage", image_format, view_format, swizzle);
|
UnsupportedColorView("storage", image_format, view_format, swizzle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,7 +120,10 @@ IsSupportedStorageImageResource(const ShaderRecompiler::IR::ImageResource& resou
|
|||||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D ||
|
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim3D ||
|
||||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray) &&
|
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray) &&
|
||||||
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.written &&
|
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.written &&
|
||||||
!resource.atomic && !resource.depth_compare;
|
(!resource.atomic ||
|
||||||
|
(resource.kind == ShaderRecompiler::IR::ResourceKind::StorageImageUint &&
|
||||||
|
resource.read)) &&
|
||||||
|
!resource.depth_compare;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
#include "graphics/guest_gpu/tile.h"
|
#include "graphics/guest_gpu/tile.h"
|
||||||
#include "graphics/host_gpu/graphicContext.h"
|
#include "graphics/host_gpu/graphicContext.h"
|
||||||
#include "graphics/host_gpu/hostMemory.h"
|
#include "graphics/host_gpu/hostMemory.h"
|
||||||
#include "graphics/host_gpu/renderer/image/textureCommon.h"
|
|
||||||
#include "graphics/host_gpu/renderer/debug.h"
|
#include "graphics/host_gpu/renderer/debug.h"
|
||||||
#include "graphics/host_gpu/renderer/pipeline/descriptorCache.h"
|
|
||||||
#include "graphics/host_gpu/renderer/image/imageView.h"
|
#include "graphics/host_gpu/renderer/image/imageView.h"
|
||||||
|
#include "graphics/host_gpu/renderer/image/textureCommon.h"
|
||||||
|
#include "graphics/host_gpu/renderer/pipeline/descriptorCache.h"
|
||||||
|
#include "graphics/host_gpu/renderer/pipeline/shaderResourceBarrier.h"
|
||||||
#include "graphics/host_gpu/renderer/render.h"
|
#include "graphics/host_gpu/renderer/render.h"
|
||||||
#include "graphics/host_gpu/renderer/renderContext.h"
|
#include "graphics/host_gpu/renderer/renderContext.h"
|
||||||
#include "graphics/host_gpu/renderer/pipeline/shaderResourceBarrier.h"
|
|
||||||
#include "graphics/host_gpu/vma.h"
|
#include "graphics/host_gpu/vma.h"
|
||||||
#include "graphics/host_gpu/vulkanCommon.h"
|
#include "graphics/host_gpu/vulkanCommon.h"
|
||||||
#include "graphics/shader/recompiler/ir/BindingLayout.h"
|
#include "graphics/shader/recompiler/ir/BindingLayout.h"
|
||||||
@@ -239,11 +239,11 @@ bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, co
|
|||||||
const uint32_t field3_expected =
|
const uint32_t field3_expected =
|
||||||
(descriptor.Type() << 28u) | field3_common | descriptor.DstSelXYZW();
|
(descriptor.Type() << 28u) | field3_common | descriptor.DstSelXYZW();
|
||||||
const uint32_t field4_expected = descriptor.Depth() | (descriptor.BaseArray5() << 16u);
|
const uint32_t field4_expected = descriptor.Depth() | (descriptor.BaseArray5() << 16u);
|
||||||
const bool common = (descriptor.fields[1] & field1_reserved_mask) == 0 &&
|
const bool common = (descriptor.fields[1] & field1_reserved_mask) == 0 &&
|
||||||
(descriptor.fields[2] & field2_reserved_mask) == 0 &&
|
(descriptor.fields[2] & field2_reserved_mask) == 0 &&
|
||||||
descriptor.fields[3] == field3_expected &&
|
descriptor.fields[3] == field3_expected &&
|
||||||
descriptor.fields[4] == field4_expected &&
|
descriptor.fields[4] == field4_expected &&
|
||||||
descriptor.fields[5] == field5_expected;
|
descriptor.fields[5] == field5_expected;
|
||||||
if (!common || (descriptor.fields[6] == 0 && descriptor.fields[7] != 0)) {
|
if (!common || (descriptor.fields[6] == 0 && descriptor.fields[7] != 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -318,8 +318,8 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
|||||||
const bool valid_2d_slice =
|
const bool valid_2d_slice =
|
||||||
(is_color_2d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) ||
|
(is_color_2d && descriptor.Depth() == 0 && descriptor.BaseArray5() == 0) ||
|
||||||
(is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth());
|
(is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth());
|
||||||
const bool is_2d = resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D &&
|
const bool is_2d =
|
||||||
valid_2d_slice;
|
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D && valid_2d_slice;
|
||||||
const bool is_2d_array =
|
const bool is_2d_array =
|
||||||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray &&
|
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray &&
|
||||||
is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth();
|
is_color_2d_array && descriptor.BaseArray5() <= descriptor.Depth();
|
||||||
@@ -340,13 +340,13 @@ static bool IsSupportedStorageTextureDescriptor(const ShaderRecompiler::IR::Imag
|
|||||||
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 || supported_standard_tile;
|
supported_depth_tile || supported_standard_tile;
|
||||||
|
const auto swizzle = descriptor.DstSelXYZW();
|
||||||
const bool supported_swizzle =
|
const bool supported_swizzle =
|
||||||
IsValidImageSwizzle(descriptor.DstSelXYZW()) &&
|
IsValidImageSwizzle(swizzle) &&
|
||||||
(descriptor.DstSelXYZW() == DstSel(4, 5, 6, 7) || !resource.read);
|
(swizzle == DstSel(4, 5, 6, 7) || !resource.read || resource.atomic);
|
||||||
const bool supported_mip_view = descriptor.BaseLevel() == 0 || is_1d || is_2d;
|
const bool supported_mip_view = descriptor.BaseLevel() == 0 || is_1d || is_2d;
|
||||||
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 &&
|
||||||
supported_mip_view &&
|
supported_mip_view && descriptor.BaseLevel() == descriptor.LastLevel() &&
|
||||||
descriptor.BaseLevel() == descriptor.LastLevel() &&
|
|
||||||
descriptor.LastLevel() <= descriptor.MaxMip() && descriptor.MinLod() == 0 &&
|
descriptor.LastLevel() <= descriptor.MaxMip() && descriptor.MinLod() == 0 &&
|
||||||
supported_swizzle && descriptor.BCSwizzle() == 0 && !descriptor.MsaaDepth();
|
supported_swizzle && descriptor.BCSwizzle() == 0 && !descriptor.MsaaDepth();
|
||||||
}
|
}
|
||||||
@@ -377,8 +377,10 @@ 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 format_ok = Prospero::IsSupportedTextureFormat(format) &&
|
const bool format_ok =
|
||||||
uint_resource == Prospero::IsUintTextureFormat(format);
|
Prospero::IsSupportedTextureFormat(format) &&
|
||||||
|
uint_resource == Prospero::IsUintTextureFormat(format) &&
|
||||||
|
(!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;
|
||||||
}
|
}
|
||||||
@@ -618,12 +620,12 @@ RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageResource& reso
|
|||||||
resource.written);
|
resource.written);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = SrgbStorageViewFormat(pixel_format);
|
||||||
const auto view_format =
|
const auto view_format = storage && storage_view_format != vk::Format::eUndefined
|
||||||
storage && storage_view_format != vk::Format::eUndefined ? storage_view_format
|
? storage_view_format
|
||||||
: pixel_format;
|
: pixel_format;
|
||||||
const auto block_bytes = Prospero::BlockCompressedBytesPerBlock(format);
|
const auto block_bytes = Prospero::BlockCompressedBytesPerBlock(format);
|
||||||
TextureCache::ImageDesc desc {};
|
TextureCache::ImageDesc desc {};
|
||||||
desc.info.data = {address, size.size};
|
desc.info.data = {address, size.size};
|
||||||
desc.info.pixel_format = pixel_format;
|
desc.info.pixel_format = pixel_format;
|
||||||
|
|||||||
@@ -15220,7 +15220,7 @@ void CheckRenderTargetFormatContract() {
|
|||||||
resource.kind = ShaderRecompiler::IR::ResourceKind::Image;
|
resource.kind = ShaderRecompiler::IR::ResourceKind::Image;
|
||||||
} else if (std::strcmp(kind, "storage-no-write") == 0) {
|
} else if (std::strcmp(kind, "storage-no-write") == 0) {
|
||||||
resource.written = false;
|
resource.written = false;
|
||||||
} else if (std::strcmp(kind, "storage-atomic") == 0) {
|
} else if (std::strcmp(kind, "storage-nonuint-atomic") == 0) {
|
||||||
resource.atomic = true;
|
resource.atomic = true;
|
||||||
} else if (std::strcmp(kind, "storage-compare") == 0) {
|
} else if (std::strcmp(kind, "storage-compare") == 0) {
|
||||||
resource.depth_compare = true;
|
resource.depth_compare = true;
|
||||||
@@ -15437,6 +15437,12 @@ void CheckSampledColorViews() {
|
|||||||
Require("SampledColorViews", "write-only uint 2D-array storage resource",
|
Require("SampledColorViews", "write-only uint 2D-array storage resource",
|
||||||
IsSupportedStorageImageResource(storage_resource),
|
IsSupportedStorageImageResource(storage_resource),
|
||||||
"basic write-only uint 2D-array storage resource was rejected");
|
"basic write-only uint 2D-array storage resource was rejected");
|
||||||
|
storage_resource.dimension = ShaderRecompiler::Decoder::ImageDimension::Dim2D;
|
||||||
|
storage_resource.read = true;
|
||||||
|
storage_resource.atomic = true;
|
||||||
|
Require("SampledColorViews", "atomic uint 2D storage resource",
|
||||||
|
IsSupportedStorageImageResource(storage_resource),
|
||||||
|
"atomic uint storage resource was rejected");
|
||||||
|
|
||||||
char path[MAX_PATH]{};
|
char path[MAX_PATH]{};
|
||||||
Require("SampledColorViews", "host",
|
Require("SampledColorViews", "host",
|
||||||
@@ -15446,7 +15452,7 @@ void CheckSampledColorViews() {
|
|||||||
{"sampled-invalid-selector", "sampled-incompatible-format",
|
{"sampled-invalid-selector", "sampled-incompatible-format",
|
||||||
"sampled-invalid-high", "sampled-depth-format", "sampled-depth-swizzle",
|
"sampled-invalid-high", "sampled-depth-format", "sampled-depth-swizzle",
|
||||||
"storage-incompatible-format", "storage-kind", "storage-no-write",
|
"storage-incompatible-format", "storage-kind", "storage-no-write",
|
||||||
"storage-atomic", "storage-compare", "storage-mip", "storage-dimension",
|
"storage-nonuint-atomic", "storage-compare", "storage-mip", "storage-dimension",
|
||||||
"volume-mip-count", "volume-slice-range"}) {
|
"volume-mip-count", "volume-slice-range"}) {
|
||||||
std::string command =
|
std::string command =
|
||||||
std::string("\"") + path + "\" --image-view-death " + kind;
|
std::string("\"") + path + "\" --image-view-death " + kind;
|
||||||
@@ -16155,6 +16161,19 @@ ShaderTextureResource BasicUintVolumeStorageTextureDescriptor() {
|
|||||||
0x00700000u, 0x00000000u, 0x00000000u}};
|
0x00700000u, 0x00000000u, 0x00000000u}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShaderRecompiler::IR::ImageResource AtomicStorageTextureResource() {
|
||||||
|
auto resource = BasicLinearStorageTextureResource();
|
||||||
|
resource.kind = ShaderRecompiler::IR::ResourceKind::StorageImageUint;
|
||||||
|
resource.read = true;
|
||||||
|
resource.atomic = true;
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderTextureResource AtomicStorageTextureDescriptor() {
|
||||||
|
return {{0x304bb700u, 0xc1400000u, 0x0000001fu, 0x91b00204u, 0x00000000u,
|
||||||
|
0x00700000u, 0x00000000u, 0x00000000u}};
|
||||||
|
}
|
||||||
|
|
||||||
[[noreturn]] void RunStorageTextureDescriptorDeathCase(const char *kind) {
|
[[noreturn]] void RunStorageTextureDescriptorDeathCase(const char *kind) {
|
||||||
auto resource = BasicStorageTextureResource();
|
auto resource = BasicStorageTextureResource();
|
||||||
auto descriptor = BasicStorageTextureDescriptor();
|
auto descriptor = BasicStorageTextureDescriptor();
|
||||||
@@ -16216,6 +16235,12 @@ 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, "atomic-format") == 0) {
|
||||||
|
resource = AtomicStorageTextureResource();
|
||||||
|
descriptor = AtomicStorageTextureDescriptor();
|
||||||
|
descriptor.fields[1] =
|
||||||
|
(descriptor.fields[1] & ~0x1ff00000u) |
|
||||||
|
(Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt) << 20u);
|
||||||
} else if (std::strcmp(kind, "depth-tile-read") == 0) {
|
} else if (std::strcmp(kind, "depth-tile-read") == 0) {
|
||||||
resource = Ppsa14053DepthTileStorageTextureResource();
|
resource = Ppsa14053DepthTileStorageTextureResource();
|
||||||
descriptor = Ppsa14053DepthTileStorageTextureDescriptor();
|
descriptor = Ppsa14053DepthTileStorageTextureDescriptor();
|
||||||
@@ -16590,6 +16615,18 @@ void CheckBasicStorageTextureDescriptor() {
|
|||||||
IsValidImageSwizzle(DstSel(4, 4, 4, 4)),
|
IsValidImageSwizzle(DstSel(4, 4, 4, 4)),
|
||||||
"single-channel replicated destination selection was rejected");
|
"single-channel replicated destination selection was rejected");
|
||||||
|
|
||||||
|
const auto atomic = AtomicStorageTextureDescriptor();
|
||||||
|
Require("BasicStorageTexture", "atomic R32_UINT descriptor",
|
||||||
|
atomic.Width5() + 1u == 128 && atomic.Height5() + 1u == 1 &&
|
||||||
|
atomic.Depth() + 1u == 1 &&
|
||||||
|
atomic.Type() ==
|
||||||
|
Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) &&
|
||||||
|
atomic.Format() ==
|
||||||
|
Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt) &&
|
||||||
|
atomic.DstSelXYZW() == DstSel(4, 0, 0, 1),
|
||||||
|
"PPSA22102 image-atomic descriptor fixture is malformed");
|
||||||
|
ValidateStorageTexture(AtomicStorageTextureResource(), atomic, 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,
|
||||||
@@ -16598,7 +16635,7 @@ void CheckBasicStorageTextureDescriptor() {
|
|||||||
{"resource", "type", "tile", "mip", "swizzle", "linear-rgb1-read",
|
{"resource", "type", "tile", "mip", "swizzle", "linear-rgb1-read",
|
||||||
"bgra-read", "r16-float-read", "r8-unorm-read", "yzwx-read",
|
"bgra-read", "r16-float-read", "r8-unorm-read", "yzwx-read",
|
||||||
"reserved-swizzle", "array-base-out-of-range", "array-mip-view",
|
"reserved-swizzle", "array-base-out-of-range", "array-mip-view",
|
||||||
"reserved", "uint-format", "uint-resource-float-format",
|
"reserved", "uint-format", "uint-resource-float-format", "atomic-format",
|
||||||
"depth-tile-read", "depth-tile-extent", "depth-tile-fmask"}) {
|
"depth-tile-read", "depth-tile-extent", "depth-tile-fmask"}) {
|
||||||
std::string command = std::string("\"") + path +
|
std::string command = std::string("\"") + path +
|
||||||
"\" --storage-texture-descriptor-death " + kind;
|
"\" --storage-texture-descriptor-death " + kind;
|
||||||
|
|||||||
Reference in New Issue
Block a user