From eaf3f040bbdf1e8c32dbf328251b0c133ac4b250 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 24 Jul 2020 12:07:39 -0700 Subject: Handle case of no global parameters for CPU/CUDA (#1457) The IR pass that introduces an explicit `KernelContext` for the CPU/CUDA back-ends was also responsible for adding an explicit parameter to the kernel entry point to receive the constant buffer (pointer) with all the global uniform parameters. However, if there were no global uniform parameters, this parameter wasn't getting introduced, which changed the signature/ABI of the generated entry point function. This change makes it so that the pass unconditionally adds a parameter. In the case where there are no global uniforms it just adds a `void*` parameter that never gets used. In order to avoid future regressions, this change also adds a test case to confirm that things work correctly when a kernel has only entry-point parameters and no global parameters. --- source/slang/slang-ir-explicit-global-context.cpp | 9 +++++ .../shader-params/entry-point-uniform-params.slang | 38 ++++++++++++++++++++++ .../entry-point-uniform-params.slang.expected.txt | 4 +++ 3 files changed, 51 insertions(+) create mode 100644 tests/language-feature/shader-params/entry-point-uniform-params.slang create mode 100644 tests/language-feature/shader-params/entry-point-uniform-params.slang.expected.txt diff --git a/source/slang/slang-ir-explicit-global-context.cpp b/source/slang/slang-ir-explicit-global-context.cpp index 68f23461b..8f11bce2c 100644 --- a/source/slang/slang-ir-explicit-global-context.cpp +++ b/source/slang/slang-ir-explicit-global-context.cpp @@ -270,6 +270,15 @@ struct IntroduceExplicitGlobalContextPass // globalUniformsParam->insertBefore(firstOrdinary); } + else + { + // The nature of our current ABI for entry points on CPU/CUDA + // means that we need an explicit parameter to be *declared* + // for the global uniforms, even if it is never used. + // + auto placeholderParam = builder.createParam(builder.getRawPointerType()); + placeholderParam->insertBefore(firstOrdinary); + } // The `KernelContext` to use inside the entry point // will be a local variable declared in the first block. diff --git a/tests/language-feature/shader-params/entry-point-uniform-params.slang b/tests/language-feature/shader-params/entry-point-uniform-params.slang new file mode 100644 index 000000000..b94fc4556 --- /dev/null +++ b/tests/language-feature/shader-params/entry-point-uniform-params.slang @@ -0,0 +1,38 @@ +// entry-point-uniform-params.slang + +//TEST(compute):COMPARE_COMPUTE: +//TEST(compute):COMPARE_COMPUTE:-cuda +//TEST(compute):COMPARE_COMPUTE:-cpu + +// Test that a shader can be written that +// only uses entry point `uniform` parameters, +// without any global parameters. + +struct Data +{ + int a; + int b; +} + +int test(int val, int a, int b) +{ + return a*(val+1) + b*(val+2); +} + +[numthreads(4, 1, 1)] +[shader("compute")] +void computeMain( + +//TEST_INPUT:cbuffer(data=[256 1]):name=d + uniform Data d, + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer + uniform RWStructuredBuffer outputBuffer, + + uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + int inVal = tid; + int outVal = test(inVal, d.a, d.b); + outputBuffer[tid] = outVal; +} diff --git a/tests/language-feature/shader-params/entry-point-uniform-params.slang.expected.txt b/tests/language-feature/shader-params/entry-point-uniform-params.slang.expected.txt new file mode 100644 index 000000000..4cf6581b3 --- /dev/null +++ b/tests/language-feature/shader-params/entry-point-uniform-params.slang.expected.txt @@ -0,0 +1,4 @@ +102 +203 +304 +405 -- cgit v1.2.3