graphics: support signed 32-bit image atomic descriptors

This commit is contained in:
nmzik committed 2026-10-13 21:27:07 +00:00
1 parent 68d7bc94e2
commit aec8c88755
3 files changed
+22 -8

No files matched your search

@@ -309,7 +309,8 @@ void ValidateStorageTexture(const ShaderRecompiler::IR::ImageResource& resource,
const bool encoding_ok = IsSupportedStorageTextureEncoding(resource, descriptor); const bool encoding_ok = IsSupportedStorageTextureEncoding(resource, descriptor);
const bool uint_resource = resource.numeric_class == Prospero::TextureNumericClass::Uint; const bool uint_resource = resource.numeric_class == Prospero::TextureNumericClass::Uint;
const bool raw_sint_storage = format == Prospero::BufferFormat::k32SInt && uint_resource && const bool raw_sint_storage = format == Prospero::BufferFormat::k32SInt && uint_resource &&
resource.written && !resource.read && !resource.atomic; resource.written &&
(resource.atomic ? !resource.atomic64 : !resource.read);
const auto numeric_class = Prospero::SampledTextureNumericClass(format); const auto numeric_class = Prospero::SampledTextureNumericClass(format);
const bool raw_float_atomic = format == Prospero::BufferFormat::k32Float && uint_resource && const bool raw_float_atomic = format == Prospero::BufferFormat::k32Float && uint_resource &&
resource.atomic && !resource.atomic64; resource.atomic && !resource.atomic64;
@@ -630,6 +630,7 @@ static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSna
if (base.atomic && if (base.atomic &&
(base.atomic64 ? format != Prospero::BufferFormat::k32_32UInt (base.atomic64 ? format != Prospero::BufferFormat::k32_32UInt
: format != Prospero::BufferFormat::k32UInt && : format != Prospero::BufferFormat::k32UInt &&
format != Prospero::BufferFormat::k32SInt &&
format != Prospero::BufferFormat::k32Float)) { format != Prospero::BufferFormat::k32Float)) {
return SpecializationFail( return SpecializationFail(
fmt::format("atomic image descriptor {} uses unsupported format {}", i, fmt::format("atomic image descriptor {} uses unsupported format {}", i,
@@ -650,7 +651,7 @@ static bool BuildResourceSpecialization(const ResourcePlan& program, ResourceSna
image.shader_swizzle = DescriptorImageSwizzle(descriptor); image.shader_swizzle = DescriptorImageSwizzle(descriptor);
} }
const bool raw_sint_storage = storage && format == Prospero::BufferFormat::k32SInt && const bool raw_sint_storage = storage && format == Prospero::BufferFormat::k32SInt &&
base.written && !base.read && !base.atomic; base.written && (base.atomic ? !base.atomic64 : !base.read);
image.numeric_class = Prospero::SampledTextureNumericClass(format); image.numeric_class = Prospero::SampledTextureNumericClass(format);
if (storage) { if (storage) {
if ((!raw_sint_storage && image.numeric_class == Prospero::TextureNumericClass::Sint) || if ((!raw_sint_storage && image.numeric_class == Prospero::TextureNumericClass::Sint) ||
+18 -6
View File
@@ -37202,7 +37202,7 @@ TestCase ImageStoreAndAtomicUseSeparateBindings() {
return test; return test;
} }
TestCase ImageAtomicVariants() { template <bool signed_format = false> TestCase ImageAtomicVariants() {
using O = ShaderOpcode; using O = ShaderOpcode;
const u32 initial[] = {10, 10, 0xf0f0u, 0xf000u, 0xf00fu}; const u32 initial[] = {10, 10, 0xf0f0u, 0xf000u, 0xf00fu};
@@ -37222,7 +37222,10 @@ TestCase ImageAtomicVariants() {
AppendEnd(&code); AppendEnd(&code);
TestCase test; TestCase test;
test.name = "ImageAtomicVariants"; test.name = signed_format ? "ImageAtomicSintVariants" : "ImageAtomicVariants";
test.user_data = MakeStorageTextureData(signed_format ? Prospero::BufferFormat::k32SInt
: Prospero::BufferFormat::k32UInt);
test.has_user_data = true;
test.code = code; test.code = code;
test.expected = {10, 10, 0xf0f0u, 0xf000u, 0xf00fu}; test.expected = {10, 10, 0xf0f0u, 0xf000u, 0xf00fu};
test.opcodes = {O::V_MOV_B32, O::IMAGE_ATOMIC_ADD, test.opcodes = {O::V_MOV_B32, O::IMAGE_ATOMIC_ADD,
@@ -37370,7 +37373,7 @@ TestCase ImageAtomicIntegerGlcAndExec(const ImageAtomicIntegerCase &atomic, bool
return test; return test;
} }
template <bool max_value> TestCase ImageAtomicSignedMinMax() { template <bool max_value, bool signed_format = false> TestCase ImageAtomicSignedMinMax() {
using O = ShaderOpcode; using O = ShaderOpcode;
// Input, old value, signed minimum, signed maximum. // Input, old value, signed minimum, signed maximum.
constexpr u32 values[][4] = { constexpr u32 values[][4] = {
@@ -37383,8 +37386,11 @@ template <bool max_value> TestCase ImageAtomicSignedMinMax() {
{2, 8, 2, 8}, {8, 2, 2, 8}, {2, 8, 2, 8}, {8, 2, 2, 8},
}; };
TestCase test; TestCase test;
test.name = max_value ? "ImageAtomicSMaxGlcAndExec" : "ImageAtomicSMinGlcAndExec"; test.name = signed_format
test.user_data = MakeStorageTextureData(Prospero::BufferFormat::k32UInt); ? (max_value ? "ImageAtomicSMaxSintGlcAndExec" : "ImageAtomicSMinSintGlcAndExec")
: (max_value ? "ImageAtomicSMaxGlcAndExec" : "ImageAtomicSMinGlcAndExec");
test.user_data = MakeStorageTextureData(signed_format ? Prospero::BufferFormat::k32SInt
: Prospero::BufferFormat::k32UInt);
test.has_user_data = true; test.has_user_data = true;
test.storage_image_r32ui.assign(16, 0); test.storage_image_r32ui.assign(16, 0);
test.expected_storage_image_r32ui = test.storage_image_r32ui; test.expected_storage_image_r32ui = test.storage_image_r32ui;
@@ -38479,6 +38485,8 @@ std::vector<TestCase> MakeCases() {
AddCase(BufferAtomicAndX2GlcAndExec); AddCase(BufferAtomicAndX2GlcAndExec);
AddCase(ImageAtomicSignedMinMax<false>); AddCase(ImageAtomicSignedMinMax<false>);
AddCase(ImageAtomicSignedMinMax<true>); AddCase(ImageAtomicSignedMinMax<true>);
AddCase(ImageAtomicSignedMinMax<false, true>);
AddCase(ImageAtomicSignedMinMax<true, true>);
for (bool decrement : {false, true}) { for (bool decrement : {false, true}) {
for (bool gds : {false, true}) { for (bool gds : {false, true}) {
cases.push_back(DsBoundedAtomicBoundaries(decrement, gds)); cases.push_back(DsBoundedAtomicBoundaries(decrement, gds));
@@ -38569,7 +38577,8 @@ std::vector<TestCase> MakeCases() {
AddCase(ImageAtomicCompareSwapGlcAndExec); AddCase(ImageAtomicCompareSwapGlcAndExec);
AddCase(ImageAtomicSwapReturnsPreviousTexel); AddCase(ImageAtomicSwapReturnsPreviousTexel);
AddCase(ImageStoreAndAtomicUseSeparateBindings); AddCase(ImageStoreAndAtomicUseSeparateBindings);
AddCase(ImageAtomicVariants); AddCase(ImageAtomicVariants<>);
AddCase(ImageAtomicVariants<true>);
for (const auto &atomic : ImageAtomicIntegerCases) { for (const auto &atomic : ImageAtomicIntegerCases) {
cases.push_back(ImageAtomicIntegerGlcAndExec(atomic, false)); cases.push_back(ImageAtomicIntegerGlcAndExec(atomic, false));
cases.push_back(ImageAtomicIntegerGlcAndExec(atomic, true)); cases.push_back(ImageAtomicIntegerGlcAndExec(atomic, true));
@@ -44385,6 +44394,9 @@ int main(int argc, char **argv) {
RunCase(&vulkan, ImageAtomicCompareSwapGlcAndExec()); RunCase(&vulkan, ImageAtomicCompareSwapGlcAndExec());
RunCase(&vulkan, ImageAtomicSwapReturnsPreviousTexel()); RunCase(&vulkan, ImageAtomicSwapReturnsPreviousTexel());
RunCase(&vulkan, ImageAtomicVariants()); RunCase(&vulkan, ImageAtomicVariants());
RunCase(&vulkan, ImageAtomicVariants<true>());
RunCase(&vulkan, ImageAtomicSignedMinMax<false, true>());
RunCase(&vulkan, ImageAtomicSignedMinMax<true, true>());
return 0; return 0;
} }
if (argc == 2 && std::strcmp(argv[1], "--image-atomic64-only") == 0) { if (argc == 2 && std::strcmp(argv[1], "--image-atomic64-only") == 0) {