mesa编译器lower ubo出现问题

概述

hlsl源代码

cbuffer cbPerObject : register(b0)
{
    float4x4 gWorld;
};


struct VertexIn
{
    float3 PosL : POSITION;
    float4 Color : COLOR;
};

struct VertexOut
{
    float4 PosH : SV_POSITION;
    float4 Color : COLOR;
};

VertexOut VSMain(VertexIn vin)
{
    VertexOut vout;
	
	// Transform to homogeneous clip space.
    vout.PosH = mul(float4(vin.PosL, 1.0f), gWorld);
	
	// Just pass vertex color into the pixel shader.
    vout.Color = vin.Color;
    
    return vout;
}

spirv

省略掉dxil转spirv的过程。生成的spirv如下所示:

; SPIR-V
; Version: 1.3
; Generator: Unknown(30017); 21022
; Bound: 93
; Schema: 0
OpCapability Shader
%66 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %3 "main" %15 %17 %19 %20
OpName %3 "main"
OpName %10 ""
OpName %15 "POSITION"
OpName %17 "COLOR"
OpName %19 "SV_Position"
OpName %20 "COLOR"
OpDecorate %9 ArrayStride 16
OpMemberDecorate %10 0 Offset 0
OpDecorate %10 Block
OpDecorate %12 DescriptorSet 0
OpDecorate %12 Binding 0
OpDecorate %15 Location 0
OpDecorate %17 Location 1
OpDecorate %19 BuiltIn Position
OpDecorate %20 Location 1
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%5 = OpTypeInt 32 0
%6 = OpConstant %5 4
%7 = OpTypeFloat 32
%8 = OpTypeVector %7 4
%9 = OpTypeArray %8 %6
%10 = OpTypeStruct %9
%11 = OpTypePointer Uniform %10
%12 = OpVariable %11 Uniform
%13 = OpTypeVector %7 3
%14 = OpTypePointer Input %13
%15 = OpVariable %14 Input
%16 = OpTypePointer Input %8
%17 = OpVariable %16 Input
%18 = OpTypePointer Output %8
%19 = OpVariable %18 Output
%20 = OpVariable %18 Output
%21 = OpTypePointer Input %7
%23 = OpConstant %5 0
%26 = OpConstant %5 1
%29 = OpConstant %5 2
%32 = OpConstant %5 3
%40 = OpTypePointer Uniform %8
%82 = OpTypePointer Output %7
%3 = OpFunction %1 None %2
%4 = OpLabel
OpBranch %91
%91 = OpLabel
%22 = OpAccessChain %21 %17 %23
%24 = OpLoad %7 %22
%25 = OpAccessChain %21 %17 %26
%27 = OpLoad %7 %25
%28 = OpAccessChain %21 %17 %29
%30 = OpLoad %7 %28
%31 = OpAccessChain %21 %17 %32
%33 = OpLoad %7 %31
%34 = OpAccessChain %21 %15 %23
%35 = OpLoad %7 %34
%36 = OpAccessChain %21 %15 %26
%37 = OpLoad %7 %36
%38 = OpAccessChain %21 %15 %29
%39 = OpLoad %7 %38
%41 = OpAccessChain %40 %12 %23 %23
%42 = OpLoad %8 %41
%43 = OpCompositeExtract %7 %42 0
%44 = OpCompositeExtract %7 %42 1
%45 = OpCompositeExtract %7 %42 2
%46 = OpCompositeExtract %7 %42 3
%47 = OpAccessChain %40 %12 %23 %26
%48 = OpLoad %8 %47
%49 = OpCompositeExtract %7 %48 0
%50 = OpCompositeExtract %7 %48 1
%51 = OpCompositeExtract %7 %48 2
%52 = OpCompositeExtract %7 %48 3
%53 = OpAccessChain %40 %12 %23 %29
%54 = OpLoad %8 %53
%55 = OpCompositeExtract %7 %54 0
%56 = OpCompositeExtract %7 %54 1
%57 = OpCompositeExtract %7 %54 2
%58 = OpCompositeExtract %7 %54 3
%59 = OpAccessChain %40 %12 %23 %32
%60 = OpLoad %8 %59
%61 = OpCompositeExtract %7 %60 0
%62 = OpCompositeExtract %7 %60 1
%63 = OpCompositeExtract %7 %60 2
%64 = OpCompositeExtract %7 %60 3
%65 = OpFMul %7 %43 %35
%67 = OpExtInst %7 %66 Fma %37 %44 %65
%68 = OpExtInst %7 %66 Fma %39 %45 %67
%69 = OpFAdd %7 %68 %46
%70 = OpFMul %7 %49 %35
%71 = OpExtInst %7 %66 Fma %37 %50 %70
%72 = OpExtInst %7 %66 Fma %39 %51 %71
%73 = OpFAdd %7 %72 %52
%74 = OpFMul %7 %55 %35
%75 = OpExtInst %7 %66 Fma %37 %56 %74
%76 = OpExtInst %7 %66 Fma %39 %57 %75
%77 = OpFAdd %7 %76 %58
%78 = OpFMul %7 %61 %35
%79 = OpExtInst %7 %66 Fma %37 %62 %78
%80 = OpExtInst %7 %66 Fma %39 %63 %79
%81 = OpFAdd %7 %80 %64
%83 = OpAccessChain %82 %19 %23
OpStore %83 %69
%84 = OpAccessChain %82 %19 %26
OpStore %84 %73
%85 = OpAccessChain %82 %19 %29
OpStore %85 %77
%86 = OpAccessChain %82 %19 %32
OpStore %86 %81
%87 = OpAccessChain %82 %20 %23
OpStore %87 %24
%88 = OpAccessChain %82 %20 %26
OpStore %88 %27
%89 = OpAccessChain %82 %20 %29
OpStore %89 %30
%90 = OpAccessChain %82 %20 %32
OpStore %90 %33
OpReturn
OpFunctionEnd

nir

在spirv转nir的函数中,可以选择运行的环境,有三个

enum nir_spirv_execution_environment {
   NIR_SPIRV_VULKAN = 0,
   NIR_SPIRV_OPENCL,
   NIR_SPIRV_OPENGL,
};

函数原型

nir_shader *spirv_to_nir(const uint32_t *words, size_t word_count,
                         struct nir_spirv_specialization *specializations,
                         unsigned num_specializations,
                         gl_shader_stage stage, const char *entry_point_name,
                         const struct spirv_to_nir_options *options,
                         const nir_shader_compiler_options *nir_options);

如果选择vulkan环境,转换成的nir如下:

shader: MESA_SHADER_VERTEX
source_sha1: {0x9bc7cec5, 0x1e123084, 0x66e529c6, 0xe3ec410e, 0x2a9b196d}
internal: false
stage: 0
next_stage: 0
num_ubos: 1
subgroup_size: 0
inputs: 0
outputs: 0
uniforms: 0
decl_var shader_in INTERP_MODE_NONE none vec3 POSITION (VERT_ATTRIB_GENERIC0.xyz, 0, 0)
decl_var shader_in INTERP_MODE_NONE none vec4 COLOR (VERT_ATTRIB_GENERIC1.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE none vec4 SV_Position (VARYING_SLOT_POS.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE none vec4 COLOR#0 (VARYING_SLOT_VAR1.xyzw, 0, 0)
decl_var ubo INTERP_MODE_NONE none  #1 (~0, 0, 0)
decl_function main (0 params)

impl main {
    con block b0:   // preds:
    32     %0 = deref_var &COLOR (shader_in vec4)
    32x4   %1 = @load_deref (%0) (access=none)
    32     %8 = deref_var &POSITION (shader_in vec3)
    32x3   %9 = @load_deref (%8) (access=none)
    32    %14 = load_const (0x00000000 = 0.000000)
    32x2  %15 = @vulkan_resource_index (%14) (desc_set=0, binding=0, desc_type=UBO)
    32x2  %16 = @load_vulkan_descriptor (%15) (desc_type=UBO)
    32x2  %17 = deref_cast ( *)%16 (ubo )  (ptr_stride=0, align_mul=0, align_offset=0)
    32x2  %18 = deref_struct &%17->field0 (ubo vec4[4])  // &(( *)%16)->field0
    32x2  %20 = deref_array &(*%18)[0] (ubo vec4)  // &(( *)%16)->field0[0]
    32x4  %21 = @load_deref (%20) (access=none)
    32    %27 = load_const (0x00000001 = 0.000000)
    32x2  %28 = deref_array &(*%18)[1] (ubo vec4)  // &(( *)%16)->field0[1]
    32x4  %29 = @load_deref (%28) (access=none)
    32    %35 = load_const (0x00000002 = 0.000000)
    32x2  %36 = deref_array &(*%18)[2] (ubo vec4)  // &(( *)%16)->field0[2]
    32x4  %37 = @load_deref (%36) (access=none)
    32    %43 = load_const (0x00000003 = 0.000000)
    32x2  %44 = deref_array &(*%18)[3] (ubo vec4)  // &(( *)%16)->field0[3]
    32x4  %45 = @load_deref (%44) (access=none)
    32    %46 = fmul %21.x, %9.x
    32    %47 = ffma %9.y, %21.y, %46
    32    %48 = ffma %9.z, %21.z, %47
    32    %49 = fadd %48, %21.w
    32    %50 = fmul %29.x, %9.x
    32    %51 = ffma %9.y, %29.y, %50
    32    %52 = ffma %9.z, %29.z, %51
    32    %53 = fadd %52, %29.w
    32    %54 = fmul %37.x, %9.x
    32    %55 = ffma %9.y, %37.y, %54
    32    %56 = ffma %9.z, %37.z, %55
    32    %57 = fadd %56, %37.w
    32    %58 = fmul %45.x, %9.x
    32    %59 = ffma %9.y, %45.y, %58
    32    %60 = ffma %9.z, %45.z, %59
    32    %61 = fadd %60, %45.w
    32    %62 = deref_var &SV_Position (shader_out vec4)
    32x4  %63 = @load_deref (%62) (access=none)
    32x4  %64 = vec4 %49, %63.y, %63.z, %63.w
                @store_deref (%62, %64) (wrmask=xyzw, access=none)
    32x4  %66 = @load_deref (%62) (access=none)
    32x4  %67 = vec4 %66.x, %53, %66.z, %66.w
                @store_deref (%62, %67) (wrmask=xyzw, access=none)
    32x4  %69 = @load_deref (%62) (access=none)
    32x4  %70 = vec4 %69.x, %69.y, %57, %69.w
                @store_deref (%62, %70) (wrmask=xyzw, access=none)
    32x4  %72 = @load_deref (%62) (access=none)
    32x4  %73 = vec4 %72.x, %72.y, %72.z, %61
                @store_deref (%62, %73) (wrmask=xyzw, access=none)
    32    %74 = deref_var &COLOR#0 (shader_out vec4)
    32x4  %75 = @load_deref (%74) (access=none)
    32x4  %76 = vec4 %1.x, %75.y, %75.z, %75.w
                @store_deref (%74, %76) (wrmask=xyzw, access=none)
    32x4  %78 = @load_deref (%74) (access=none)
    32x4  %79 = vec4 %78.x, %1.y, %78.z, %78.w
                @store_deref (%74, %79) (wrmask=xyzw, access=none)
    32x4  %81 = @load_deref (%74) (access=none)
    32x4  %82 = vec4 %81.x, %81.y, %1.z, %81.w
                @store_deref (%74, %82) (wrmask=xyzw, access=none)
    32x4  %84 = @load_deref (%74) (access=none)
    32x4  %85 = vec4 %84.x, %84.y, %84.z, %1.w
                @store_deref (%74, %85) (wrmask=xyzw, access=none)
                return (pass_flags: 0xcd)
                // succs: b1
    block b1:
}

其中,下面的COLOR 和POSITION ,可以在nir_lower_io() pass中转换为load input

    32     %0 = deref_var &COLOR (shader_in vec4)
    32x4   %1 = @load_deref (%0) (access=none)
    32     %8 = deref_var &POSITION (shader_in vec3)
    32x3   %9 = @load_deref (%8) (access=none)

但是后面的ubo该如何去转换?

如果选择opengl环境,转换成的nir如下:

shader: MESA_SHADER_VERTEX
source_sha1: {0x9bc7cec5, 0x1e123084, 0x66e529c6, 0xe3ec410e, 0x2a9b196d}
internal: false
stage: 0
next_stage: 0
num_ubos: 1
subgroup_size: 0
inputs: 0
outputs: 0
uniforms: 0
decl_var shader_in INTERP_MODE_NONE none vec3 POSITION (VERT_ATTRIB_GENERIC0.xyz, 0, 0)
decl_var shader_in INTERP_MODE_NONE none vec4 COLOR (VERT_ATTRIB_GENERIC1.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE none vec4 SV_Position (VARYING_SLOT_POS.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE none vec4 COLOR#0 (VARYING_SLOT_VAR1.xyzw, 0, 0)
decl_var ubo INTERP_MODE_NONE none  #1 (~0, 0, 0)
decl_function main (0 params)

impl main {
    con block b0:   // preds:
    32     %0 = deref_var &COLOR (shader_in vec4)
    32x4   %1 = @load_deref (%0) (access=none)
    32     %8 = deref_var &POSITION (shader_in vec3)
    32x3   %9 = @load_deref (%8) (access=none)
    32x2  %14 = deref_var &#1 (ubo )
    32x2  %15 = deref_struct &%14->field0 (ubo vec4[4])  // &#1.field0
    32    %16 = load_const (0x00000000 = 0.000000)
    32x2  %17 = deref_array &(*%15)[0] (ubo vec4)  // &#1.field0[0]
    32x4  %18 = @load_deref (%17) (access=none)
    32    %21 = load_const (0x00000001 = 0.000000)
    32x2  %22 = deref_array &(*%15)[1] (ubo vec4)  // &#1.field0[1]
    32x4  %23 = @load_deref (%22) (access=none)
    32    %26 = load_const (0x00000002 = 0.000000)
    32x2  %27 = deref_array &(*%15)[2] (ubo vec4)  // &#1.field0[2]
    32x4  %28 = @load_deref (%27) (access=none)
    32    %31 = load_const (0x00000003 = 0.000000)
    32x2  %32 = deref_array &(*%15)[3] (ubo vec4)  // &#1.field0[3]
    32x4  %33 = @load_deref (%32) (access=none)
    32    %34 = fmul %18.x, %9.x
    32    %35 = ffma %9.y, %18.y, %34
    32    %36 = ffma %9.z, %18.z, %35
    32    %37 = fadd %36, %18.w
    32    %38 = fmul %23.x, %9.x
    32    %39 = ffma %9.y, %23.y, %38
    32    %40 = ffma %9.z, %23.z, %39
    32    %41 = fadd %40, %23.w
    32    %42 = fmul %28.x, %9.x
    32    %43 = ffma %9.y, %28.y, %42
    32    %44 = ffma %9.z, %28.z, %43
    32    %45 = fadd %44, %28.w
    32    %46 = fmul %33.x, %9.x
    32    %47 = ffma %9.y, %33.y, %46
    32    %48 = ffma %9.z, %33.z, %47
    32    %49 = fadd %48, %33.w
    32    %50 = deref_var &SV_Position (shader_out vec4)
    32x4  %51 = @load_deref (%50) (access=none)
    32x4  %52 = vec4 %37, %51.y, %51.z, %51.w
                @store_deref (%50, %52) (wrmask=xyzw, access=none)
    32x4  %54 = @load_deref (%50) (access=none)
    32x4  %55 = vec4 %54.x, %41, %54.z, %54.w
                @store_deref (%50, %55) (wrmask=xyzw, access=none)
    32x4  %57 = @load_deref (%50) (access=none)
    32x4  %58 = vec4 %57.x, %57.y, %45, %57.w
                @store_deref (%50, %58) (wrmask=xyzw, access=none)
    32x4  %60 = @load_deref (%50) (access=none)
    32x4  %61 = vec4 %60.x, %60.y, %60.z, %49
                @store_deref (%50, %61) (wrmask=xyzw, access=none)
    32    %62 = deref_var &COLOR#0 (shader_out vec4)
    32x4  %63 = @load_deref (%62) (access=none)
    32x4  %64 = vec4 %1.x, %63.y, %63.z, %63.w
                @store_deref (%62, %64) (wrmask=xyzw, access=none)
    32x4  %66 = @load_deref (%62) (access=none)
    32x4  %67 = vec4 %66.x, %1.y, %66.z, %66.w
                @store_deref (%62, %67) (wrmask=xyzw, access=none)
    32x4  %69 = @load_deref (%62) (access=none)
    32x4  %70 = vec4 %69.x, %69.y, %1.z, %69.w
                @store_deref (%62, %70) (wrmask=xyzw, access=none)
    32x4  %72 = @load_deref (%62) (access=none)
    32x4  %73 = vec4 %72.x, %72.y, %72.z, %1.w
                @store_deref (%62, %73) (wrmask=xyzw, access=none)
                return (pass_flags: 0xcd)
                // succs: b1
    block b1:
}

同样的,下面的COLOR 和POSITION ,可以在nir_lower_io() pass中转换为load input

    32     %0 = deref_var &COLOR (shader_in vec4)
    32x4   %1 = @load_deref (%0) (access=none)
    32     %8 = deref_var &POSITION (shader_in vec3)
    32x3   %9 = @load_deref (%8) (access=none)

但是后面的ubo该如何去转换?

分析

目前有两种解决方案

使用OpenGL环境

需要调用一个pass

NIR_PASS_V(nir, gl_nir_lower_buffers, prog);

函数实现如下

bool
gl_nir_lower_buffers(nir_shader *shader,
                     const struct gl_shader_program *shader_program)
{
   bool progress = false;

   nir_foreach_variable_with_modes(var, shader, nir_var_mem_ubo | nir_var_mem_ssbo) {
      var->data.driver_location = -1;
      progress = true;
   }

   /* First, we lower the derefs to turn block variable and array derefs into
    * a nir_address_format_32bit_index_offset pointer.  From there forward,
    * we leave the derefs in place and let nir_lower_explicit_io handle them.
    */
   nir_foreach_function_impl(impl, shader) {
      if (lower_buffer_interface_derefs_impl(impl, shader_program))
         progress = true;
   }

   /* If that did something, we validate and then call nir_lower_explicit_io
    * to finish the process.
    */
   if (progress) {
      nir_validate_shader(shader, "Lowering buffer interface derefs");
      nir_lower_explicit_io(shader, nir_var_mem_ubo | nir_var_mem_ssbo,
                            nir_address_format_32bit_index_offset);
   }

   return progress;
}

它可以lower ubo与ssbo,但是它需要gl_shader_program结构,它是mesa编译器编译gl后的一个结构,如果选择该解决方案需要填充该结构。

使用Vulkan环境

需要调用以下代码

NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ubo | nir_var_mem_ssbo, nir_address_format_32bit_index_offset);
nir_shader_lower_instructions(nir, lower_vulkan_resource_index, lower_vri_instr, 0);

它可以lower ubo与ssbo。

static nir_def *lower_vri_instr(struct nir_builder *b,
                                    nir_instr *instr, void *data_cb)
{
   if (instr->type == nir_instr_type_intrinsic) {
      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
      switch (intrin->intrinsic) {
      case nir_intrinsic_vulkan_resource_index:
         return lower_vri_intrin_vri(b, instr, data_cb);

      case nir_intrinsic_vulkan_resource_reindex:
         return lower_vri_intrin_vrri(b, instr, data_cb);

      case nir_intrinsic_load_vulkan_descriptor:
         return lower_vri_intrin_lvd(b, instr, data_cb);

      case nir_intrinsic_get_ssbo_size: {
         /* Ignore the offset component. */
         b->cursor = nir_before_instr(instr);
         nir_def *resource = intrin->src[0].ssa;
         nir_src_rewrite(&intrin->src[0], resource);
         return NULL;
      }
      case nir_intrinsic_image_deref_sparse_load:
      case nir_intrinsic_image_deref_load:
      case nir_intrinsic_image_deref_store:
      case nir_intrinsic_image_deref_atomic:
      case nir_intrinsic_image_deref_atomic_swap:
      case nir_intrinsic_image_deref_size:
      case nir_intrinsic_image_deref_samples:
         b->cursor = nir_before_instr(instr);
         lower_image_intrinsic(b, intrin, data_cb);
         return NULL;

      default:
         return NULL;
      }
   }

   if (instr->type == nir_instr_type_tex) {
      b->cursor = nir_before_instr(instr);
      lower_vri_instr_tex(b, nir_instr_as_tex(instr), data_cb);
   }

   return NULL;
}

它可以lower 掉 resource_index 与 vulkan_descriptor,不过在lower的过程中也是需要vulkan的一些结构。

解决

综合考虑下,还是选择vulkan的环境,稍微简单点,而且可以面对各种灵活的转换。
lower后生成的nir如下

shader: MESA_SHADER_VERTEX
source_sha1: {0x9bc7cec5, 0x1e123084, 0x66e529c6, 0xe3ec410e, 0x2a9b196d}
internal: false
stage: 0
next_stage: 0
num_ubos: 1
subgroup_size: 0
inputs: 0
outputs: 0
uniforms: 0
decl_var shader_in INTERP_MODE_NONE none vec3 POSITION (VERT_ATTRIB_GENERIC0.xyz, 0, 0)
decl_var shader_in INTERP_MODE_NONE none vec4 COLOR (VERT_ATTRIB_GENERIC1.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE none vec4 SV_Position (VARYING_SLOT_POS.xyzw, 0, 0)
decl_var shader_out INTERP_MODE_NONE none vec4 COLOR#0 (VARYING_SLOT_VAR1.xyzw, 0, 0)
decl_var ubo INTERP_MODE_NONE none  #1 (~0, 0, 0)
decl_function main (0 params)

impl main {
    con block b0:   // preds:
    32     %0 = deref_var &COLOR (shader_in vec4)
    32     %1 = load_const (0x00000000 = 0.000000)
    32x4   %2 = @load_input (%1) (base=0, range=1, component=0, dest_type=float32, io location=VERT_ATTRIB_GENERIC1 slots=1)  // POSITION
    32     %3 = deref_var &POSITION (shader_in vec3)
    32     %4 = load_const (0x00000000 = 0.000000)
    32x3   %5 = @load_input (%4) (base=0, range=1, component=0, dest_type=float32, io location=VERT_ATTRIB_GENERIC0 slots=1)  // POSITION
    32     %6 = load_const (0x00000000 = 0.000000)
    32    %71 = load_const (0x00000000 = 0.000000)
    32    %72 = load_const (0x00000001 = 0.000000)
    32x3  %73 = vec3 %72, %6, %71
    32     %9 = load_const (0x00000010 = 0.000000 = 16)
    32    %10 = amul %6, %9
    32    %11 = mov %73.y
    32    %12 = iadd %11, %10
    32x2  %13 = vec2 %73.x, %12
    32    %14 = mov %13.x
    32    %15 = mov %13.y
    32x4  %16 = @load_ubo (%14, %15) (access=none, align_mul=4, align_offset=0, range_base=0, range=16)
    32    %17 = load_const (0x00000001 = 0.000000)
    32    %18 = load_const (0x00000010 = 0.000000 = 16)
    32    %19 = amul %17, %18
    32    %20 = mov %73.y
    32    %21 = iadd %20, %19
    32x2  %22 = vec2 %73.x, %21
    32    %23 = mov %22.x
    32    %24 = mov %22.y
    32x4  %25 = @load_ubo (%23, %24) (access=none, align_mul=4, align_offset=0, range_base=16, range=16)
    32    %26 = load_const (0x00000002 = 0.000000)
    32    %27 = load_const (0x00000010 = 0.000000 = 16)
    32    %28 = amul %26, %27
    32    %29 = mov %73.y
    32    %30 = iadd %29, %28
    32x2  %31 = vec2 %73.x, %30
    32    %32 = mov %31.x
    32    %33 = mov %31.y
    32x4  %34 = @load_ubo (%32, %33) (access=none, align_mul=4, align_offset=0, range_base=32, range=16)
    32    %35 = load_const (0x00000003 = 0.000000)
    32    %36 = load_const (0x00000010 = 0.000000 = 16)
    32    %37 = amul %35, %36
    32    %38 = mov %73.y
    32    %39 = iadd %38, %37
    32x2  %40 = vec2 %73.x, %39
    32    %41 = mov %40.x
    32    %42 = mov %40.y
    32x4  %43 = @load_ubo (%41, %42) (access=none, align_mul=4, align_offset=0, range_base=48, range=16)
    32    %44 = fmul %16.x, %5.x
    32    %45 = fmul %5.y, %16.y
    32    %46 = fadd %45, %44
    32    %47 = fmul %5.z, %16.z
    32    %48 = fadd %47, %46
    32    %49 = fadd %48, %16.w
    32    %50 = fmul %25.x, %5.x
    32    %51 = fmul %5.y, %25.y
    32    %52 = fadd %51, %50
    32    %53 = fmul %5.z, %25.z
    32    %54 = fadd %53, %52
    32    %55 = fadd %54, %25.w
    32    %56 = fmul %34.x, %5.x
    32    %57 = fmul %5.y, %34.y
    32    %58 = fadd %57, %56
    32    %59 = fmul %5.z, %34.z
    32    %60 = fadd %59, %58
    32    %61 = fadd %60, %34.w
    32    %62 = fmul %43.x, %5.x
    32    %63 = fmul %5.y, %43.y
    32    %64 = fadd %63, %62
    32    %65 = fmul %5.z, %43.z
    32    %66 = fadd %65, %64
    32    %67 = fadd %66, %43.w
    32    %68 = deref_var &SV_Position (shader_out vec4)
    32x4  %69 = vec4 %49, %55, %61, %67
                @store_deref (%68, %69) (wrmask=xyzw, access=none)
    32    %70 = deref_var &COLOR#0 (shader_out vec4)
                @store_deref (%70, %2) (wrmask=xyzw, access=none)
                return (pass_flags: 0xcd)
                // succs: b1
    block b1:
}
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值