Using matrix addition & subtractions generates faulty spirv code
Hello!
Using the operators !+! or !-! generates faulty programs that crash.
For instance, this shader:
vertex :: ShaderModule "main" VertexShader VertexDefs _
vertex = shader do
put @"out_colour" (Vec4 1 1 1 1)
put @"gl_Position" $
(identity !+! identity) !*^ Vec4 1 1 1 1
Generates a shader with this error:
spirv-val ./shader.spv
error: line 18: OpTypeVector Component Type <id> '7[%v4float]' is not a scalar type.
%v4v4float = OpTypeVector %v4float 4
The cause is SPIRV doesn't seem to support vectors of vectors, only vectors with scalars or perhaps some other type.
I think that using !+! causes a vector of vector to appear in the code because the definition of !+! unwraps the matrices into vectors and adds them, writing the result as vectors of vectors. The Mat then fails to even try to convert them back into a matrix:
(!+!) :: forall i j. (KnownNat i, KnownNat j)
=> Code (M i j a) -> Code (M i j a) -> Code (M i j a)
x !+! y = Mat :$ ( vecAdd <$$> (UnMat :$ x) <**> (UnMat :$ y) )
where vecAdd :: Code (V i a) -> Code (V i a) -> Code (V i a)
vecAdd = primOp @(V i a) @('Vectorise SPIRV.Add)
Here is the SPIRV code of the offending shader:
; SPIR-V
; Version: 1.0
; Generator: Unknown(8530); 18758
; Bound: 70
; Schema: 0
OpCapability Matrix
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %3 "main" %69 %9
OpName %3 "main"
OpName %69 "gl_Position"
OpName %9 "out_colour"
OpDecorate %9 Location 0
OpDecorate %69 BuiltIn Position
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%5 = OpTypeFloat 32
%6 = OpConstant %5 1
%7 = OpTypeVector %5 4
%10 = OpTypePointer Output %7
%11 = OpConstant %5 0
%16 = OpTypeMatrix %7 4
%65 = OpTypeVector %7 4
%69 = OpVariable %10 Output
%9 = OpVariable %10 Output
%3 = OpFunction %1 None %2
%4 = OpLabel
%8 = OpCompositeConstruct %7 %6 %6 %6 %6
OpStore %9 %8
%12 = OpCompositeConstruct %7 %6 %11 %11 %11
%13 = OpCompositeConstruct %7 %11 %6 %11 %11
%14 = OpCompositeConstruct %7 %11 %11 %6 %11
%15 = OpCompositeConstruct %7 %11 %11 %11 %6
%17 = OpCompositeConstruct %16 %12 %13 %14 %15
%18 = OpCompositeExtract %7 %17 0
%19 = OpCompositeConstruct %7 %6 %11 %11 %11
%20 = OpCompositeConstruct %7 %11 %6 %11 %11
%21 = OpCompositeConstruct %7 %11 %11 %6 %11
%22 = OpCompositeConstruct %7 %11 %11 %11 %6
%23 = OpCompositeConstruct %16 %19 %20 %21 %22
%24 = OpCompositeExtract %7 %23 0
%25 = OpFAdd %7 %18 %24
%26 = OpCompositeConstruct %7 %6 %11 %11 %11
%27 = OpCompositeConstruct %7 %11 %6 %11 %11
%28 = OpCompositeConstruct %7 %11 %11 %6 %11
%29 = OpCompositeConstruct %7 %11 %11 %11 %6
%30 = OpCompositeConstruct %16 %26 %27 %28 %29
%31 = OpCompositeExtract %7 %30 1
%32 = OpCompositeConstruct %7 %6 %11 %11 %11
%33 = OpCompositeConstruct %7 %11 %6 %11 %11
%34 = OpCompositeConstruct %7 %11 %11 %6 %11
%35 = OpCompositeConstruct %7 %11 %11 %11 %6
%36 = OpCompositeConstruct %16 %32 %33 %34 %35
%37 = OpCompositeExtract %7 %36 1
%38 = OpFAdd %7 %31 %37
%39 = OpCompositeConstruct %7 %6 %11 %11 %11
%40 = OpCompositeConstruct %7 %11 %6 %11 %11
%41 = OpCompositeConstruct %7 %11 %11 %6 %11
%42 = OpCompositeConstruct %7 %11 %11 %11 %6
%43 = OpCompositeConstruct %16 %39 %40 %41 %42
%44 = OpCompositeExtract %7 %43 2
%45 = OpCompositeConstruct %7 %6 %11 %11 %11
%46 = OpCompositeConstruct %7 %11 %6 %11 %11
%47 = OpCompositeConstruct %7 %11 %11 %6 %11
%48 = OpCompositeConstruct %7 %11 %11 %11 %6
%49 = OpCompositeConstruct %16 %45 %46 %47 %48
%50 = OpCompositeExtract %7 %49 2
%51 = OpFAdd %7 %44 %50
%52 = OpCompositeConstruct %7 %6 %11 %11 %11
%53 = OpCompositeConstruct %7 %11 %6 %11 %11
%54 = OpCompositeConstruct %7 %11 %11 %6 %11
%55 = OpCompositeConstruct %7 %11 %11 %11 %6
%56 = OpCompositeConstruct %16 %52 %53 %54 %55
%57 = OpCompositeExtract %7 %56 3
%58 = OpCompositeConstruct %7 %6 %11 %11 %11
%59 = OpCompositeConstruct %7 %11 %6 %11 %11
%60 = OpCompositeConstruct %7 %11 %11 %6 %11
%61 = OpCompositeConstruct %7 %11 %11 %11 %6
%62 = OpCompositeConstruct %16 %58 %59 %60 %61
%63 = OpCompositeExtract %7 %62 3
%64 = OpFAdd %7 %57 %63
%66 = OpCompositeConstruct %65 %25 %38 %51 %64
%67 = OpCompositeConstruct %7 %6 %6 %6 %6
%68 = OpMatrixTimesVector %7 %66 %67
OpStore %69 %68
OpReturn
OpFunctionEnd
You can fix it by simply making this change:
%66 = OpCompositeConstruct %65 %25 %38 %51 %64
->
%66 = OpCompositeConstruct %16 %25 %38 %51 %64
I haven't been able to fix this issue myself yet due to my unfamiliarity with this codebase. I will update this if I'm able to.
Thanks!
Edited by Sebastian Wålinder