Skip to content

HLSL legalization for isomorphic function parameter #2535

@jaebaek

Description

@jaebaek

It would be great if HLSL legalization handled function parameter passing where the argument is actually isomorphic to the parameter but their types are not the same.

For the following HLSL code,

struct R {
  int a;
  void incr() { ++a; }
};

void decr(inout R b) {
  b.a--;
}

RWStructuredBuffer<R> rwsb;

void main() {
  rwsb[0].incr();
  decr(rwsb[0]);
}

DXC generates the following SPIR-V code for calling rwsb[0].incr(); and decr(rwsb[0]);

               OpMemberDecorate %R 0 Offset 0
...
          %R = OpTypeStruct %int
        %R_0 = OpTypeStruct %int
%_ptr_Function_R_0 = OpTypePointer Function %R_0
%_ptr_Uniform_R = OpTypePointer Uniform %R
       %rwsb = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_R Uniform
...
 %temp_var_R = OpVariable %_ptr_Function_R_0 Function
%param_var_b = OpVariable %_ptr_Function_R_0 Function
         %26 = OpAccessChain %_ptr_Uniform_R %rwsb %int_0 %uint_0
         %27 = OpLoad %R %26
         %28 = OpCompositeExtract %int %27 0
         %29 = OpCompositeConstruct %R_0 %28
               OpStore %temp_var_R %29
         %30 = OpFunctionCall %void %R_incr %temp_var_R
         %32 = OpLoad %R_0 %temp_var_R
         %33 = OpCompositeExtract %int %32 0
         %34 = OpCompositeConstruct %R %33
               OpStore %26 %34
         %35 = OpAccessChain %_ptr_Uniform_R %rwsb %int_0 %uint_0
         %36 = OpLoad %R %35
         %37 = OpCompositeExtract %int %36 0
         %38 = OpCompositeConstruct %R_0 %37
               OpStore %param_var_b %38
         %39 = OpFunctionCall %void %decr %param_var_b
         %41 = OpLoad %R_0 %param_var_b
         %42 = OpCompositeExtract %int %41 0
         %43 = OpCompositeConstruct %R %42
               OpStore %35 %43

After fixing #2430, the reason why we cannot directly pass

  • %26 = OpAccessChain %_ptr_Uniform_R %rwsb %int_0 %uint_0 to %R_incr
  • %35 = OpAccessChain %_ptr_Uniform_R %rwsb %int_0 %uint_0 to %decr
    because %R and %R_0 are different types.

It would be nice if HLSL legalization checked isomorphism between the parameter type and the argument type and handled it.

We need two steps for this:

  • spirv-val allows a function argument that is different from the parameter type but they are isomorphic when --relax-logical-pointer option is enabled.
  • spirv-opt HLSL legalization handles it.

test.txt is the full SPIR-V code for the HLSL code.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions