From 05dfd32fd2ea832c19fee006bd4eb0a8b4416bd6 Mon Sep 17 00:00:00 2001 From: Mike Schuchardt Date: Thu, 4 Jun 2026 11:54:43 -0700 Subject: [PATCH] Treat uvec2 as a potential BDA type vkd3d can pass 64-bit buffer device addresses as a 2-component vectors of unsigned 32-bit integers (uvec2). This is apparently a common lowering and explicitly allowed by the GL_EXT_buffer_reference_uvec2 GLSL extension. Therefore, treat uvec2 values (and arrays) as potential BDAs in the forward SPIRV-reflect pass of SpirVParsingUtil::ParseBufferReferences. Add a test case to the SpirVParsingUtil for both uvec2 and uvec2[] paths. --- framework/util/spirv_parsing_util.cpp | 10 +- .../util/test/test_spirv_parsing_util.cpp | 124 +++++++++++++++++- 2 files changed, 132 insertions(+), 2 deletions(-) diff --git a/framework/util/spirv_parsing_util.cpp b/framework/util/spirv_parsing_util.cpp index fd178404df..915ed2511a 100644 --- a/framework/util/spirv_parsing_util.cpp +++ b/framework/util/spirv_parsing_util.cpp @@ -127,7 +127,15 @@ LayoutInfo compute_type_layout(const SpvReflectTypeDescription* type_description static bool check_type_potential_ref(const SpvReflectTypeDescription* td) { return td->storage_class == spv::StorageClassPhysicalStorageBuffer || - (td->op == SpvOpTypeInt && td->traits.numeric.scalar.width == 64 && !td->traits.numeric.scalar.signedness); + // uint64_t + (td->op == SpvOpTypeInt && td->traits.numeric.scalar.width == 64 && !td->traits.numeric.scalar.signedness) || + // uvec2 + (td->op == SpvOpTypeVector && td->traits.numeric.vector.component_count == 2 && + td->traits.numeric.scalar.width == 32 && !td->traits.numeric.scalar.signedness) || + // uvec2 array + ((td->op == SpvOpTypeRuntimeArray || td->op == SpvOpTypeArray) && + td->traits.numeric.vector.component_count == 2 && td->traits.numeric.scalar.width == 32 && + !td->traits.numeric.scalar.signedness); } // Instruction represents a single Spv::Op instruction. diff --git a/framework/util/test/test_spirv_parsing_util.cpp b/framework/util/test/test_spirv_parsing_util.cpp index 5f2a7e6451..fc49988b7e 100644 --- a/framework/util/test/test_spirv_parsing_util.cpp +++ b/framework/util/test/test_spirv_parsing_util.cpp @@ -475,6 +475,102 @@ const uint32_t spirv_bda_pointer_chaining[] = { 0x000200f9, 0x00000058, 0x000200f8, 0x00000058, 0x000100fd, 0x00010038 }; +#if 0 // original glsl - bda_uvec2.comp +#version 460 + +#extension GL_EXT_buffer_reference : require +#extension GL_EXT_buffer_reference_uvec2 : require + +layout(local_size_x = 64) in; + +layout(buffer_reference, std430, buffer_reference_align = 4) readonly buffer ValueRef { + uint value; +}; + +layout(buffer_reference, std430, buffer_reference_align = 4) writeonly buffer OutputRef { + uint values[]; +}; + +/* Addresses stored as uvec2 to stay 4-byte aligned without shaderInt64. */ +layout(set = 0, binding = 0, std430) readonly buffer InputAddresses { + uvec2 addresses[]; +}; + +layout(push_constant) uniform PushConstants { + uvec2 output_address; + uint count; +} pc; + +void main() { + uint index = gl_GlobalInvocationID.x; + if (index >= pc.count) + return; + + uvec2 src_address = addresses[index]; + if (all(equal(src_address, uvec2(0)))) + return; + + OutputRef(pc.output_address).values[index] = ValueRef(src_address).value; +} +#endif +const uint32_t spirv_bda_uvec2[] = { + 0x07230203, 0x00010500, 0x0008000b, 0x00000045, 0x00000000, 0x00020011, 0x00000001, 0x00020011, 0x000014e3, + 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x000014e4, 0x00000001, + 0x0008000f, 0x00000005, 0x00000004, 0x6e69616d, 0x00000000, 0x0000000b, 0x00000014, 0x00000024, 0x00060010, + 0x00000004, 0x00000011, 0x00000040, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001cc, 0x00070004, + 0x455f4c47, 0x625f5458, 0x65666675, 0x65725f72, 0x65726566, 0x0065636e, 0x00090004, 0x455f4c47, 0x625f5458, + 0x65666675, 0x65725f72, 0x65726566, 0x5f65636e, 0x63657675, 0x00000032, 0x00040005, 0x00000004, 0x6e69616d, + 0x00000000, 0x00040005, 0x00000008, 0x65646e69, 0x00000078, 0x00080005, 0x0000000b, 0x475f6c67, 0x61626f6c, + 0x766e496c, 0x7461636f, 0x496e6f69, 0x00000044, 0x00060005, 0x00000012, 0x68737550, 0x736e6f43, 0x746e6174, + 0x00000073, 0x00070006, 0x00000012, 0x00000000, 0x7074756f, 0x615f7475, 0x65726464, 0x00007373, 0x00050006, + 0x00000012, 0x00000001, 0x6e756f63, 0x00000074, 0x00030005, 0x00000014, 0x00006370, 0x00050005, 0x00000020, + 0x5f637273, 0x72646461, 0x00737365, 0x00060005, 0x00000022, 0x75706e49, 0x64644174, 0x73736572, 0x00007365, + 0x00060006, 0x00000022, 0x00000000, 0x72646461, 0x65737365, 0x00000073, 0x00030005, 0x00000024, 0x00000000, + 0x00050005, 0x00000037, 0x7074754f, 0x65527475, 0x00000066, 0x00050006, 0x00000037, 0x00000000, 0x756c6176, + 0x00007365, 0x00050005, 0x0000003c, 0x756c6156, 0x66655265, 0x00000000, 0x00050006, 0x0000003c, 0x00000000, + 0x756c6176, 0x00000065, 0x00040047, 0x0000000b, 0x0000000b, 0x0000001c, 0x00030047, 0x00000012, 0x00000002, + 0x00050048, 0x00000012, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000012, 0x00000001, 0x00000023, + 0x00000008, 0x00040047, 0x00000021, 0x00000006, 0x00000008, 0x00030047, 0x00000022, 0x00000002, 0x00040048, + 0x00000022, 0x00000000, 0x00000018, 0x00050048, 0x00000022, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x00000024, 0x00000018, 0x00040047, 0x00000024, 0x00000021, 0x00000000, 0x00040047, 0x00000024, 0x00000022, + 0x00000000, 0x00040047, 0x00000036, 0x00000006, 0x00000004, 0x00030047, 0x00000037, 0x00000002, 0x00040048, + 0x00000037, 0x00000000, 0x00000019, 0x00050048, 0x00000037, 0x00000000, 0x00000023, 0x00000000, 0x00030047, + 0x0000003c, 0x00000002, 0x00040048, 0x0000003c, 0x00000000, 0x00000018, 0x00050048, 0x0000003c, 0x00000000, + 0x00000023, 0x00000000, 0x00040047, 0x00000044, 0x0000000b, 0x00000019, 0x00020013, 0x00000002, 0x00030021, + 0x00000003, 0x00000002, 0x00040015, 0x00000006, 0x00000020, 0x00000000, 0x00040020, 0x00000007, 0x00000007, + 0x00000006, 0x00040017, 0x00000009, 0x00000006, 0x00000003, 0x00040020, 0x0000000a, 0x00000001, 0x00000009, + 0x0004003b, 0x0000000a, 0x0000000b, 0x00000001, 0x0004002b, 0x00000006, 0x0000000c, 0x00000000, 0x00040020, + 0x0000000d, 0x00000001, 0x00000006, 0x00040017, 0x00000011, 0x00000006, 0x00000002, 0x0004001e, 0x00000012, + 0x00000011, 0x00000006, 0x00040020, 0x00000013, 0x00000009, 0x00000012, 0x0004003b, 0x00000013, 0x00000014, + 0x00000009, 0x00040015, 0x00000015, 0x00000020, 0x00000001, 0x0004002b, 0x00000015, 0x00000016, 0x00000001, + 0x00040020, 0x00000017, 0x00000009, 0x00000006, 0x00020014, 0x0000001a, 0x00040020, 0x0000001f, 0x00000007, + 0x00000011, 0x0003001d, 0x00000021, 0x00000011, 0x0003001e, 0x00000022, 0x00000021, 0x00040020, 0x00000023, + 0x0000000c, 0x00000022, 0x0004003b, 0x00000023, 0x00000024, 0x0000000c, 0x0004002b, 0x00000015, 0x00000025, + 0x00000000, 0x00040020, 0x00000027, 0x0000000c, 0x00000011, 0x0005002c, 0x00000011, 0x0000002b, 0x0000000c, + 0x0000000c, 0x00040017, 0x0000002c, 0x0000001a, 0x00000002, 0x00040020, 0x00000032, 0x00000009, 0x00000011, + 0x00030027, 0x00000035, 0x000014e5, 0x0003001d, 0x00000036, 0x00000006, 0x0003001e, 0x00000037, 0x00000036, + 0x00040020, 0x00000035, 0x000014e5, 0x00000037, 0x00030027, 0x0000003b, 0x000014e5, 0x0003001e, 0x0000003c, + 0x00000006, 0x00040020, 0x0000003b, 0x000014e5, 0x0000003c, 0x00040020, 0x0000003e, 0x000014e5, 0x00000006, + 0x0004002b, 0x00000006, 0x00000042, 0x00000040, 0x0004002b, 0x00000006, 0x00000043, 0x00000001, 0x0006002c, + 0x00000009, 0x00000044, 0x00000042, 0x00000043, 0x00000043, 0x00050036, 0x00000002, 0x00000004, 0x00000000, + 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x00000007, 0x00000008, 0x00000007, 0x0004003b, 0x0000001f, + 0x00000020, 0x00000007, 0x00050041, 0x0000000d, 0x0000000e, 0x0000000b, 0x0000000c, 0x0004003d, 0x00000006, + 0x0000000f, 0x0000000e, 0x0003003e, 0x00000008, 0x0000000f, 0x0004003d, 0x00000006, 0x00000010, 0x00000008, + 0x00050041, 0x00000017, 0x00000018, 0x00000014, 0x00000016, 0x0004003d, 0x00000006, 0x00000019, 0x00000018, + 0x000500ae, 0x0000001a, 0x0000001b, 0x00000010, 0x00000019, 0x000300f7, 0x0000001d, 0x00000000, 0x000400fa, + 0x0000001b, 0x0000001c, 0x0000001d, 0x000200f8, 0x0000001c, 0x000100fd, 0x000200f8, 0x0000001d, 0x0004003d, + 0x00000006, 0x00000026, 0x00000008, 0x00060041, 0x00000027, 0x00000028, 0x00000024, 0x00000025, 0x00000026, + 0x0004003d, 0x00000011, 0x00000029, 0x00000028, 0x0003003e, 0x00000020, 0x00000029, 0x0004003d, 0x00000011, + 0x0000002a, 0x00000020, 0x000500aa, 0x0000002c, 0x0000002d, 0x0000002a, 0x0000002b, 0x0004009b, 0x0000001a, + 0x0000002e, 0x0000002d, 0x000300f7, 0x00000030, 0x00000000, 0x000400fa, 0x0000002e, 0x0000002f, 0x00000030, + 0x000200f8, 0x0000002f, 0x000100fd, 0x000200f8, 0x00000030, 0x00050041, 0x00000032, 0x00000033, 0x00000014, + 0x00000025, 0x0004003d, 0x00000011, 0x00000034, 0x00000033, 0x0004007c, 0x00000035, 0x00000038, 0x00000034, + 0x0004003d, 0x00000006, 0x00000039, 0x00000008, 0x0004003d, 0x00000011, 0x0000003a, 0x00000020, 0x0004007c, + 0x0000003b, 0x0000003d, 0x0000003a, 0x00050041, 0x0000003e, 0x0000003f, 0x0000003d, 0x00000025, 0x0006003d, + 0x00000006, 0x00000040, 0x0000003f, 0x00000002, 0x00000004, 0x00060041, 0x0000003e, 0x00000041, 0x00000038, + 0x00000025, 0x00000039, 0x0005003e, 0x00000041, 0x00000040, 0x00000002, 0x00000004, 0x000100fd, 0x00010038, +}; + TEST_CASE("SpirVParsingUtil", "[buffer_references]") { gfxrecon::util::Log::Init(gfxrecon::util::LoggingSeverity::kError); @@ -567,4 +663,30 @@ TEST_CASE("SpirVParsingUtil_pointer_chaining", "[buffer_references_pointer_chain REQUIRE(buffer_references[3].array_stride == 0); gfxrecon::util::Log::Release(); -} \ No newline at end of file +} + +TEST_CASE("SpirVParsingUtil_uvec2") +{ + gfxrecon::util::Log::Init(gfxrecon::util::LoggingSeverity::kError); + gfxrecon::util::SpirVParsingUtil spirVParsingUtil; + + REQUIRE(spirVParsingUtil.ParseBufferReferences(spirv_bda_uvec2, sizeof(spirv_bda_uvec2))); + auto buffer_references = spirVParsingUtil.GetBufferReferenceInfos(); + + REQUIRE(buffer_references.size() == 2); + + REQUIRE(buffer_references[0].source == gfxrecon::util::SpirVParsingUtil::BufferReferenceLocation::STORAGE_BUFFER); + REQUIRE(buffer_references[0].set == 0); + REQUIRE(buffer_references[0].binding == 0); + REQUIRE(buffer_references[0].buffer_offset == 0); + REQUIRE(buffer_references[0].array_stride == 8); + + REQUIRE(buffer_references[1].source == + gfxrecon::util::SpirVParsingUtil::BufferReferenceLocation::PUSH_CONSTANT_BLOCK); + REQUIRE(buffer_references[1].set == 0); + REQUIRE(buffer_references[1].binding == 0); + REQUIRE(buffer_references[1].buffer_offset == 0); + REQUIRE(buffer_references[1].array_stride == 0); + + gfxrecon::util::Log::Release(); +}