PENGUINLIONG / spirq-rs

Light weight SPIR-V reflection library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CorruptedSpirv("missing decoration") on valid spir-v

JeremyS2002 opened this issue · comments

Structs with matrix members in uniform buffers cause errors when loading the struct whole struct from the buffer.

glsl that causes the error:

#version 450

struct Foo {
    mat4 matrix;
};

layout(set = 0, binding = 0) uniform FooData {
    Foo data;
} u_foo_data;

void main() {
    Foo f = u_foo_data.data;
}

spir-v that causes the error (compiled with glslc, displayed with rspirv)

; SPIR-V
; Version: 1.0
; Generator: rspirv
; Bound: 24
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %4 "main"
OpName %9 "Foo"
OpMemberName %9 0 "matrix"
OpName %11 "f"
OpName %12 "Foo"
OpMemberName %12 0 "matrix"
OpName %13 "FooData"
OpMemberName %13 0 "data"
OpName %15 "u_foo_data"
OpMemberDecorate %12 0 ColMajor
OpMemberDecorate %12 0 Offset 0
OpMemberDecorate %12 0 MatrixStride 16
OpMemberDecorate %13 0 Offset 0
OpDecorate %13 Block
OpDecorate %15 DescriptorSet 0
OpDecorate %15 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeMatrix %7 4
%9 = OpTypeStruct %8
%10 = OpTypePointer Function %9
%12 = OpTypeStruct %8
%13 = OpTypeStruct %12
%14 = OpTypePointer Uniform %13
%15 = OpVariable  %14  Uniform
%16 = OpTypeInt 32 1
%17 = OpConstant  %16  0
%18 = OpTypePointer Uniform %12
%22 = OpTypePointer Function %8
%4 = OpFunction  %2  None %3
%5 = OpLabel
%11 = OpVariable  %10  Function
%19 = OpAccessChain  %18  %15 %17
%20 = OpLoad  %12  %19
%21 = OpCompositeExtract  %8  %20 0
%23 = OpAccessChain  %22  %11 %17
OpStore %23 %21
OpReturn
OpFunctionEnd

My speculation as to the cause:
The way glslc compiles the following glsl causes the error.
Because glslc generates two identical structs one for interface blocks and one for internal usage, since only the first gets matrix stride decorations and the second one doesn't I think this causes an incorrect error return on line 1045 of src/reflect.rs when parsing the second struct type. Specifically %9 and %12 both represent the same struct but only %12 is decorated with matrix stride as only %12 is exposed in interface blocks so when parsing %9 an incorrect error is caused.

Interesting. Let's see how we can workaround this... Please feel free to PR if you have already started with something. I'm gonna work on it a bit later, like tomorrow, otherwise.

I've done a quick workaround by making the stride and major fields of MatrixType optional. This fixes my issue but I think it will now accept invalid spir-v as well.

Haven't made a PR since this feels like a bit of a hacky solution maybe.

Thanks, will work with it