From ad5dda9261bae63e32bcb914b109fcb5c92faf25 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Wed, 2 Dec 2020 14:12:51 -0800 Subject: Fix [mutating] generic methods (#1618) Slang generates code that turns the implicit `this` parameter of a method into an explicit parameter. The logic that decides whether that parameter should be `inout` is a bit involved, and there was a bug where a generic method would lead to the use of an `in` modifier (the default) and override the `inout` modifier that was requested by the method itself. This change fixes the logic to treat generic declarations in the parent chain of a leaf method as having no bearing on whether an implicit `this` parameter should be `inout` or not. A test case is included that breaks with the old behavior, and demonstrates that a generic `[mutating]` method can now work correctly. --- tests/bugs/mutating/mutating-generic-method.slang | 50 ++++++++++++++++++++++ .../mutating-generic-method.slang.expected.txt | 4 ++ 2 files changed, 54 insertions(+) create mode 100644 tests/bugs/mutating/mutating-generic-method.slang create mode 100644 tests/bugs/mutating/mutating-generic-method.slang.expected.txt (limited to 'tests/bugs/mutating') diff --git a/tests/bugs/mutating/mutating-generic-method.slang b/tests/bugs/mutating/mutating-generic-method.slang new file mode 100644 index 000000000..18f4d315b --- /dev/null +++ b/tests/bugs/mutating/mutating-generic-method.slang @@ -0,0 +1,50 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +//TEST(compute,vulkan):COMPARE_COMPUTE_EX:-vk -slang -compute + +// Confirm that a generic method marked `[mutating]` +// produces an `inout` parameter for `this`. + +interface IGenerator +{ + [mutating] int generate(); +} + +struct SimpleGenerator : IGenerator +{ + int state = 0; + + [mutating] int generate() { return state++; } +} + + +struct Reducer +{ + int state = 0; + [mutating] void update(inout S g) + { + state = (state << 8) | state; + state = state + g.generate(); + } +} + +int test(int val) +{ + SimpleGenerator g = { 0 }; + Reducer r = { val+1 }; + + r.update(g); + r.update(g); + + return r.state; +} + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out +RWStructuredBuffer outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int tid = dispatchThreadID.x; + int val = test(tid); + outputBuffer[tid] = val; +} \ No newline at end of file diff --git a/tests/bugs/mutating/mutating-generic-method.slang.expected.txt b/tests/bugs/mutating/mutating-generic-method.slang.expected.txt new file mode 100644 index 000000000..5ac358274 --- /dev/null +++ b/tests/bugs/mutating/mutating-generic-method.slang.expected.txt @@ -0,0 +1,4 @@ +10102 +20203 +30304 +40405 -- cgit v1.2.3