DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

[spirv] Change in/inout function argument process

Open jiaolu opened this issue 5 years ago • 13 comments

According to the spirv spec validation rules: Any pointer operand to an OpFunctionCall must be

  • a memory object declaration, or
  • a pointer to an element in an array that is a memory object declaration, where the element type is OpTypeSampler or OpTypeImage.

So for in/inout function argument, spirv also need to create temporary variable to hold it before passed in as argument

jiaolu avatar Nov 27 '20 04:11 jiaolu

:white_check_mark: Build DirectXShaderCompiler 1.0.3928 completed (commit https://github.com/Microsoft/DirectXShaderCompiler/commit/b103b50d96 by @jiaolu)

AppVeyorBot avatar Nov 27 '20 05:11 AppVeyorBot

@ehsannas @jaebaek any comment can be given on this PR ? thanks

jiaolu avatar Dec 08 '20 02:12 jiaolu

@ehsannas @jaebaek , guys, Is there any comment on this PR?

jiaolu avatar Jan 06 '21 02:01 jiaolu

So for in/inout function argument, spirv also need to create temporary variable to hold it before passed in as argument

This is not true.

Take this as an example (this is one of the unit tests that you've modified): http://shader-playground.timjones.io/0ad9923765d5212ec79f8f2ace90c055

There's no reason to create temporary variables for %m, %n, and %p as OpFunctionCall arguments because they (%m, %n, and %p) are already memory object declarations.

ehsannas avatar Jan 06 '21 21:01 ehsannas

New commit to address review issues.

jiaolu avatar Jan 07 '21 09:01 jiaolu

:white_check_mark: Build DirectXShaderCompiler 1.0.4049 completed (commit https://github.com/Microsoft/DirectXShaderCompiler/commit/33f588be78 by @jiaolu)

AppVeyorBot avatar Jan 07 '21 10:01 AppVeyorBot

It's still not clear to me why this change is being made. Is there a bug? (The changes in the unit tests are making the results worse than they were before.)

well spirv-val can not validate spirv generated from dxc. one use case is LunarG optimization Pass require spirv validated before applying Patch process

jiaolu avatar Jan 07 '21 15:01 jiaolu

well it's obvious, spirv-val can not validate spirv genated from dxc.

It cannot validate the pre-legalization SPIR-V generated from DXC. (The spir-v used in the unit tests is not legalized. it's used for strict checking of code generation).

Is there a case where the final DXC output (after legalization passes are run) is invalid?

ehsannas avatar Jan 07 '21 15:01 ehsannas

It cannot validate the pre-legalization SPIR-V generated from DXC. (The spir-v used in the unit tests is not legalized. it's used for strict checking of code generation).

Is there a case where the final DXC output (after legalization passes are run) is invalid?

our internal hlsl if enabled legalization, spirv can not get generated. if disable legalization, then spv generated would report validation error of memory object.

jiaolu avatar Jan 07 '21 16:01 jiaolu

// Run: %dxc -T vs_6_0 -E main

RWBuffer<float4>    MyRWBuffer;
RWTexture2D<float3> MyRWTexture;

void foo(inout float4 a, out float3 b);
[noinline]
void bar(inout float4 x, out float3 y, inout float2 z, out float w);

float4 main() : C {
    foo(MyRWBuffer[5], MyRWTexture[uint2(6, 7)]);
    float4 val;
    bar(val, val.zwx, val.xy, val.z);
    return MyRWBuffer[0] + val;
}

void foo(inout float4 a, out float3 b) {
    a = 4.2;
    b = 2.4;
}

void bar(inout float4 x, out float3 y, inout float2 z, out float w) {

    x = 1.1;
    y = 2.2;
    z = 3.3;
    w = 4.4;
}

Here is simple case, if a function can not be inlined. the dxc would generated unvalidated spv

jiaolu avatar Jan 08 '21 03:01 jiaolu

dxc.exe -T vs_6_0 -E main -spirv tools\clang\test\CodeGenSPIRV\fn.param.inout.vector.hlsl -Fo fn.param.inout.vector.hlsl.spv
spirv-val fn.param.inout.vector.hlsl.spv
error: line 78: Pointer operand 56[%56] must be a memory object declaration
  %57 = OpFunctionCall %void %bar %47 %48 %49 %56

jiaolu avatar Jan 08 '21 03:01 jiaolu

Without inlining, it is almost guaranteed that the dxc output is invalid. The function parameter is only a simple case. There are much more complicated patterns (see these examples) that need to be handled. And they all require function inlining. That's why legalization passes must be performed. Also see https://github.com/microsoft/DirectXShaderCompiler/blob/master/docs/SPIRV-Cookbook.rst for more information. Thanks

ehsannas avatar Jan 08 '21 15:01 ehsannas

Remembering , there was a PR about "export attribute", here we have a library hlsl, which includes a lot of functions. some of functions are not allowed inlined.

e.g.

#ifdef AMD_VULKAN
#define DUMMY_VOID_FUNC   { }
#define DUMMY_UINT_FUNC   { return 0; }
#endif

uint Amdxxxfunc0(inout uint stackAddr, uint lastVisited, uint4 data) DUMMY_UINT_FUNC
void Amdxxxfunc1(out uint timerHi, out uint timerLo) DUMMY_VOID_FUNC

These empty functions are called in the exported functions, After hlsl=>spriv ==>llvm, in the llvm, these functions would be patched according to the current hardware spec/current shader stages.

i admit this may not be regular user case , i still hope the spv generated from dxc can be validated. If you are not satisfied with current implementation, do you have any suggestion to validate the spv generated from this kind of spv.

Thanks.

jiaolu avatar Jan 11 '21 02:01 jiaolu

Stale, so I am closing.

s-perron avatar Jun 28 '23 15:06 s-perron