summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/compute/tagged-union.slang108
-rw-r--r--tests/compute/tagged-union.slang.2.expected.txt4
-rw-r--r--tests/compute/tagged-union.slang.expected.txt4
3 files changed, 116 insertions, 0 deletions
diff --git a/tests/compute/tagged-union.slang b/tests/compute/tagged-union.slang
new file mode 100644
index 000000000..5089ec5a7
--- /dev/null
+++ b/tests/compute/tagged-union.slang
@@ -0,0 +1,108 @@
+// tagged-union.slang
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
+
+
+// The goal of this test is to show that we can generate
+// dynamic-dispatch logic from Slang code written using
+// interface+generics, entirely from the compiler API side
+// and without code changes.
+
+// We are going to define a dummy interface just for testing
+// purposes, that can be used to see which implmentation
+// got invoked at runtime.
+//
+interface IFrobnicator
+{
+ int frobnicate(int value);
+}
+
+// Now we will define two different implemetnations that
+// "frobnicate" values differently. The first will just
+// add to the value from a member variable.
+//
+struct A : IFrobnicator
+{
+ int a;
+ int frobnicate(int value)
+ {
+ return value + a;
+ }
+}
+
+// The second implementation will have an additional field
+// of local state, and will do a tiny bit more math.
+//
+struct B : IFrobnicator
+{
+ int b;
+ int y;
+ int frobnicate(int value)
+ {
+ return value * b + y;
+ }
+}
+
+// Now we will define the generic type parameter for our shader,
+// which will be constraints to be a type that implements our
+// `IFrobnicator` interface.
+//
+type_param T : IFrobnicator;
+//
+// For the actual test runner, we will instruct it to plug in
+// a tagged-union type over the two concrete implemetnations.
+// Note that while we are writing this line in the source file,
+// it is in comments so that the Slang compiler only knows about
+// our intention when it is informed via the API.
+//
+//TEST_INPUT: type __TaggedUnion(A,B)
+
+// Next we need to pass in the actual parameter data for our
+// chosen `IFrobnicator` implementation. The decalration of
+// the constant buffer follows the conventional approach for
+// using global generic parameters, so there is nothing much
+// to say.
+//
+// Note: We are not using `ParameterBlock<_>` here because
+// the `render-test` tool doesn't yet support code that
+// uses multiple descriptor tables/sets.
+//
+ConstantBuffer<T> gFrobnicator;
+
+// Where things get interesting is when we go to provide the
+// data that will be used by the parameter block.
+//
+// Because we are plugging in a taggd union type, the actual
+// data type that we fill in will be something kind of like:
+//
+// struct S { union { A a; B b; }; uint tag; };
+//
+// When compiling for D3D, the size of that union will be
+// 8 bytes (for the largest case), and so the tag will come
+// as the third 32-bit value. We will initialize our data
+// buffer for a `B` value then, which will get the tag `1`
+// since it was the second option in our `__TaggedUnion`.
+//
+// In the Vulkan case the size of both `A` and `B` is 16 bytes
+// (because they round up structure sizes to their alignement)
+// and so the tag value will be the fifth 32-bit value.
+// We will thus set up the same data buffer to look like an `A`
+// value to Vulkan!
+//
+//TEST_INPUT: cbuffer(data=[16 9 1 0 0], stride=4):dxbinding(0),glbinding(0)
+
+int test(int val)
+{
+ return gFrobnicator.frobnicate(val);
+}
+
+//TEST_INPUT: ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(1),out
+RWStructuredBuffer<int> gOutputBuffer;
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ uint tid = dispatchThreadID.x;
+ gOutputBuffer[tid] = test(tid);
+}
diff --git a/tests/compute/tagged-union.slang.2.expected.txt b/tests/compute/tagged-union.slang.2.expected.txt
new file mode 100644
index 000000000..a0d427709
--- /dev/null
+++ b/tests/compute/tagged-union.slang.2.expected.txt
@@ -0,0 +1,4 @@
+10
+11
+12
+13
diff --git a/tests/compute/tagged-union.slang.expected.txt b/tests/compute/tagged-union.slang.expected.txt
new file mode 100644
index 000000000..7ba203156
--- /dev/null
+++ b/tests/compute/tagged-union.slang.expected.txt
@@ -0,0 +1,4 @@
+9
+19
+29
+39