はじめに

SPIRV のコードを読み解きます。

ソースとなる glsl と spirv-dis した asm を掲載します。

#version 430

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 normal;

out VertexData
{
	vec4 position;
	vec4 normal;
	vec4 color;
} OUT;

layout(std140, binding = 2) uniform Option
{
	vec4 const_color;
};

layout(std140, binding = 3) uniform Material
{
	vec4 mat_color;
};

void main()
{
	OUT.position = position;
	OUT.normal = normal;
	OUT.color = const_color + mat_color;
}

spirv にアセンブルします。

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 1
; Bound: 36
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint Vertex %main "main" %OUT %position %normal
               OpSource GLSL 430
               OpName %main "main"
               OpName %VertexData "VertexData"
               OpMemberName %VertexData 0 "position"
               OpMemberName %VertexData 1 "normal"
               OpMemberName %VertexData 2 "color"
               OpName %OUT "OUT"
               OpName %position "position"
               OpName %normal "normal"
               OpName %Option "Option"
               OpMemberName %Option 0 "const_color"
               OpName %_ ""
               OpName %Material "Material"
               OpMemberName %Material 0 "mat_color"
               OpName %__0 ""
               OpDecorate %VertexData Block
               OpDecorate %position Location 0
               OpDecorate %normal Location 1
               OpMemberDecorate %Option 0 Offset 0
               OpDecorate %Option Block
               OpDecorate %_ DescriptorSet 0
               OpDecorate %_ Binding 2
               OpMemberDecorate %Material 0 Offset 0
               OpDecorate %Material Block
               OpDecorate %__0 DescriptorSet 0
               OpDecorate %__0 Binding 3
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
 %VertexData = OpTypeStruct %v4float %v4float %v4float
%_ptr_Output_VertexData = OpTypePointer Output %VertexData
        %OUT = OpVariable %_ptr_Output_VertexData Output
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
%_ptr_Input_v4float = OpTypePointer Input %v4float
   %position = OpVariable %_ptr_Input_v4float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
      %int_1 = OpConstant %int 1
     %normal = OpVariable %_ptr_Input_v4float Input
      %int_2 = OpConstant %int 2
     %Option = OpTypeStruct %v4float
%_ptr_Uniform_Option = OpTypePointer Uniform %Option
          %_ = OpVariable %_ptr_Uniform_Option Uniform
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
   %Material = OpTypeStruct %v4float
%_ptr_Uniform_Material = OpTypePointer Uniform %Material
        %__0 = OpVariable %_ptr_Uniform_Material Uniform
       %main = OpFunction %void None %3
          %5 = OpLabel
         %15 = OpLoad %v4float %position
         %17 = OpAccessChain %_ptr_Output_v4float %OUT %int_0
               OpStore %17 %15
         %20 = OpLoad %v4float %normal
         %21 = OpAccessChain %_ptr_Output_v4float %OUT %int_1
               OpStore %21 %20
         %27 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0
         %28 = OpLoad %v4float %27
         %32 = OpAccessChain %_ptr_Uniform_v4float %__0 %int_0
         %33 = OpLoad %v4float %32
         %34 = OpFAdd %v4float %28 %33
         %35 = OpAccessChain %_ptr_Output_v4float %OUT %int_2
               OpStore %35 %34
               OpReturn
               OpFunctionEnd