PENGUINLIONG / spirq-rs

Light weight SPIR-V reflection library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error on OpSpecConstantOp

farnoy opened this issue · comments

Hi,

This is a similar issue to #41, the following fragment trips up spirq's reflection:

%493 = OpSpecConstant %uint 1
%gl_WorkGroupSize = OpSpecConstantComposite %v3uint %493 %uint_1 %uint_1
; The next one is the culprit?
%495 = OpSpecConstantOp %uint CompositeExtract %gl_WorkGroupSize 0
%_arr_uint_495 = OpTypeArray %uint %495
%_ptr_Workgroup__arr_uint_495 = OpTypePointer Workgroup %_arr_uint_495
%test_shared_variable = OpVariable %_ptr_Workgroup__arr_uint_495 Workgroup

Which is generated from a GLSL fragment like this:

layout (local_size_x_id = 1) in;

shared uint test_shared_variable[gl_WorkGroupSize.x];

never thought about such use case before.😂 will look into it.

So I actually have thought about it before and have even made a comment on this.

spirq-rs/src/reflect.rs

Lines 423 to 431 in cc7cf79

// Some notes about specialization constants.
//
// Using specialization constants for array sizes might lead
// to UNDEFINED BEHAVIOR because structure size MUST be
// definitive at compile time and CANNOT be specialized at
// runtime according to Khronos members, but the default
// behavior of `glslang` is to treat the specialization
// constants as normal constants, then I would say...
// probably it's fine to size array with them?

I asked about this probably last year to a Khronos member and according to them, it leads to undefined behavior to use specialization constant to specify array size. But if your shader works as expected on most platforms, it's probably worthy to follow such bad practice. So I probably need more time to check the availability of this feature on multiple platforms before fixing SPIR-Q.

I haven't started using code like this, but it seemed like an obvious thing. I can see the AMD compiler recognizing it well offline, but I haven't tested by re-specializing the pipeline at runtime (it might "work" without adjusting the LDS allocation size for the pipeline, making the whole approach useless).

I see that glslang accepts such usage and frontends depending on glslang like glslangValidator and ShaderC certainly follows. I'm skimming through the specification to see if they have concrete words on this.

It seems your code is legal in Vulkan-flavored GLSL. The aforementioned note applies to UBOs and SSBOs because they need offset and stride decoration which cannot be derived from specialization constants, but on-chip memory is certainly nothing alike. I will work on supporting OpSpecConstantOp and your code should reflect in the next release. 🧙‍♂️

Should have been resolved by #68 .