[go: up one dir, main page]

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