[spirv] Add FixFuncCallArguments options (#4439)

1) promotion of spirv-opt `FixFuncCallArgumentsPass`
2) add tests for the FixFuncCallArguments for the compute shader and
   export linkage shaders
This commit is contained in:
JiaoluAMD 2022-05-14 02:39:08 +08:00 коммит произвёл GitHub
Родитель d3c7fac3c4
Коммит 50c0199c17
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 87 добавлений и 0 удалений

Просмотреть файл

@ -357,6 +357,8 @@ def fspv_flatten_resource_arrays: Flag<["-"], "fspv-flatten-resource-arrays">, G
HelpText<"Flatten arrays of resources so each array element takes one binding number">;
def fspv_reduce_load_size: Flag<["-"], "fspv-reduce-load-size">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
HelpText<"Replaces loads of composite objects to reduce memory pressure for the loads">;
def fspv_fix_func_call_arguments: Flag<["-"], "fspv-fix-func-call-arguments">, Group<spirv_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
HelpText<"Fix function call arguments which are not memory objects">;
def fspv_entrypoint_name_EQ : Joined<["-"], "fspv-entrypoint-name=">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
HelpText<"Specify the SPIR-V entry point name. Defaults to the HLSL entry point name.">;
def fvk_auto_shift_bindings: Flag<["-"], "fvk-auto-shift-bindings">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,

Просмотреть файл

@ -61,6 +61,7 @@ struct SpirvCodeGenOptions {
bool reduceLoadSize;
bool autoShiftBindings;
bool supportNonzeroBaseInstance;
bool fixFuncCallArguments;
/// Maximum length in words for the OpString literal containing the shader
/// source for DebugSource and DebugSourceContinued. If the source code length
/// is larger than this number, we will use DebugSourceContinued instructions

Просмотреть файл

@ -963,6 +963,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
Args.hasFlag(OPT_fspv_flatten_resource_arrays, OPT_INVALID, false);
opts.SpirvOptions.reduceLoadSize =
Args.hasFlag(OPT_fspv_reduce_load_size, OPT_INVALID, false);
opts.SpirvOptions.fixFuncCallArguments =
Args.hasFlag(OPT_fspv_fix_func_call_arguments, OPT_INVALID, false);
opts.SpirvOptions.autoShiftBindings = Args.hasFlag(OPT_fvk_auto_shift_bindings, OPT_INVALID, false);
if (!handleVkShiftArgs(Args, OPT_fvk_b_shift, "b", &opts.SpirvOptions.bShift, errors) ||
@ -1078,6 +1080,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
Args.hasFlag(OPT_fspv_flatten_resource_arrays, OPT_INVALID, false) ||
Args.hasFlag(OPT_fspv_reduce_load_size, OPT_INVALID, false) ||
Args.hasFlag(OPT_fspv_reflect, OPT_INVALID, false) ||
Args.hasFlag(OPT_fspv_fix_func_call_arguments, OPT_INVALID, false) ||
Args.hasFlag(OPT_Wno_vk_ignored_features, OPT_INVALID, false) ||
Args.hasFlag(OPT_Wno_vk_emulated_features, OPT_INVALID, false) ||
Args.hasFlag(OPT_fvk_auto_shift_bindings, OPT_INVALID, false) ||

Просмотреть файл

@ -13111,6 +13111,9 @@ bool SpirvEmitter::spirvToolsLegalize(std::vector<uint32_t> *mod,
optimizer.RegisterPass(spvtools::CreateReplaceInvalidOpcodePass());
optimizer.RegisterPass(spvtools::CreateCompactIdsPass());
optimizer.RegisterPass(spvtools::CreateSpreadVolatileSemanticsPass());
if (spirvOptions.fixFuncCallArguments) {
optimizer.RegisterPass(spvtools::CreateFixFuncCallArgumentsPass());
}
return optimizer.Run(mod->data(), mod->size(), mod, options);
}

Просмотреть файл

@ -0,0 +1,34 @@
// RUN: %dxc -T cs_6_0 -E main -fspv-fix-func-call-arguments -O0
RWStructuredBuffer< float4 > output : register(u1);
[noinline]
float4 foo(inout float f0, inout int f1)
{
return 0;
}
// CHECK: [[s39:%\w+]] = OpVariable %_ptr_Function_int Function
// CHECK: [[s36:%\w+]] = OpVariable %_ptr_Function_float Function
// CHECK: [[s33:%\w+]] = OpAccessChain %_ptr_Uniform_float {{%\w+}} %int_0
// CHECK: [[s34:%\w+]] = OpAccessChain %_ptr_Function_int {{%\w+}} %int_1
// CHECK: [[s37:%\w+]] = OpLoad %float [[s33]]
// CHECK: OpStore [[s36]] [[s37]]
// CHECK: [[s40:%\w+]] = OpLoad %int [[s34]]
// CHECK: OpStore [[s39]] [[s40]]
// CHECK: {{%\w+}} = OpFunctionCall %v4float %foo [[s36]] [[s39]]
// CHECK: [[s41:%\w+]] = OpLoad %int [[s39]]
// CHECK: OpStore [[s34]] [[s41]]
// CHECK: [[s38:%\w+]] = OpLoad %float [[s36]]
// CHECK: OpStore [[s33]] [[s38]]
struct Stru {
int x;
int y;
};
[numthreads(1,1,1)]
void main()
{
Stru stru;
foo(output[0].x, stru.y);
}

Просмотреть файл

@ -0,0 +1,38 @@
// RUN: %dxc -T lib_6_3 -fspv-target-env=universal1.5 -fspv-fix-func-call-arguments -O0
// CHECK: OpCapability Shader
// CHECK: OpCapability Linkage
RWStructuredBuffer< float4 > output : register(u1);
// CHECK: OpDecorate %main LinkageAttributes "main" Export
// CHECK: %main = OpFunction %int None
// CHECK: [[s39:%\w+]] = OpVariable %_ptr_Function_int Function
// CHECK: [[s36:%\w+]] = OpVariable %_ptr_Function_float Function
// CHECK: [[s33:%\w+]] = OpAccessChain %_ptr_StorageBuffer_float {{%\w+}} %int_0
// CHECK: [[s34:%\w+]] = OpAccessChain %_ptr_Function_int %stru %int_1
// CHECK: [[s37:%\w+]] = OpLoad %float [[s33]]
// CHECK: OpStore [[s36]] [[s37]]
// CHECK: [[s40:%\w+]] = OpLoad %int [[s34]]
// CHECK: OpStore [[s39]] [[s40]]
// CHECK: {{%\w+}} = OpFunctionCall %void %func [[s36]] [[s39]]
// CHECK: [[s41:%\w+]] = OpLoad %int [[s39]]
// CHECK: OpStore [[s34]] [[s41]]
// CHECK: [[s38:%\w+]] = OpLoad %float [[s36]]
// CHECK: OpStore [[s33]] [[s38]]
[noinline]
void func(inout float f0, inout int f1) {
}
struct Stru {
int x;
int y;
};
export int main(inout float4 color) {
output[0] = color;
Stru stru;
func(output[0].x, stru.y);
return 1;
}

Просмотреть файл

@ -642,6 +642,12 @@ TEST_F(FileTest, FunctionInCTBuffer) {
TEST_F(FileTest, FunctionNoInline) { runFileTest("fn.noinline.hlsl"); }
TEST_F(FileTest, FunctionExport) { runFileTest("fn.export.hlsl"); }
TEST_F(FileTest, FixFunctionCall) {
runFileTest("fn.fixfuncall-compute.hlsl");
runFileTest("fn.fixfuncall-linkage.hlsl");
}
TEST_F(FileTest, FunctionForwardDecl) {
runFileTest("fn.forward-declaration.hlsl");
}