diff options
Diffstat (limited to 'tests')
6 files changed, 168 insertions, 8 deletions
diff --git a/tests/experiments/generic/explicit-specialization-2.slang b/tests/experiments/generic/explicit-specialization-2.slang new file mode 100644 index 000000000..ea5c74813 --- /dev/null +++ b/tests/experiments/generic/explicit-specialization-2.slang @@ -0,0 +1,35 @@ +//DISABLE_TEST:SIMPLE:-target hlsl -entry computeMain -profile cs_6_2 + +/* +The following works, but *requires* the rotateLeft free function to work around the swizzle issue (seen in explicit-specialization.slang). +*/ + +RWStructuredBuffer<int> outputBuffer; + +interface IRotatable +{ + This rotateLeft(); +}; + +extension int : IRotatable +{ + This rotateLeft() { const uint u = this; return This((u << 1) | (u >> 31)); } +}; + +extension uint : IRotatable +{ + This rotateLeft() { let u = this; return This((u << 1) | (u >> 31)); } +}; + +T rotateLeft<T : IRotatable>(T a) { return a.rotateLeft(); } + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + let v = rotateLeft(tid) + rotateLeft((int)tid); + + outputBuffer[tid] = v; +} + diff --git a/tests/experiments/generic/explicit-specialization-3.slang b/tests/experiments/generic/explicit-specialization-3.slang new file mode 100644 index 000000000..e53f97158 --- /dev/null +++ b/tests/experiments/generic/explicit-specialization-3.slang @@ -0,0 +1,56 @@ +//DISABLE_TEST:SIMPLE:-target hlsl -entry computeMain -profile cs_6_2 + +/* +In C++ we are able to explicitly specialize over more than one type/value. Here we try to use a 'dummy' generic +type such that an extension can be applied to it. + +I can't just specialize a function also complicating things. + +If I try explicit function specialization in C++. In g++11.1 it will complain if there isn't a specialition visible. +Visual studio it seems to assume it is available for import and doesn't complain. +*/ + +RWStructuredBuffer<float> outputBuffer; + +interface IDoThing +{ + static float doThing(float v); +}; + +struct Combination<T, let V : int> {}; + +extension Combination<int, 10> : IDoThing +{ + static float doThing(float v) + { + return int(v) + 10; + } +}; + +extension Combination<float, 20> : IDoThing +{ + static float doThing(float v) + { + return float(v) + 20; + } +}; + + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + let v = Combination<float, 20>::doThing(tid) + + Combination<int, 10>::doThing(tid); + + // Produces an error - although the error message of typeof(Combination) + // is probably not great. + // + // slang(35): error 30027: 'doThing' is not a member of 'typeof(Combination)'. + // + //let y = Combination<int, 20>::doThing(tid); + + outputBuffer[tid] = v; +} + diff --git a/tests/experiments/generic/explicit-specialization.slang b/tests/experiments/generic/explicit-specialization.slang new file mode 100644 index 000000000..0eaa1da27 --- /dev/null +++ b/tests/experiments/generic/explicit-specialization.slang @@ -0,0 +1,38 @@ +//DISABLE_TEST:SIMPLE:-target hlsl -entry computeMain -profile cs_6_2 + +/* Slang doesn't have explicit template specialization. +Here's an attempt to use the extension mechanism. + +This doesn't work and produces 9 errors of the form +> error 30052: invalid swizzle pattern 'rotateLeft' on type 'uint' +> let v = tid.rotateLeft(); + +Presumably for each letter of 'rotateLeft' after r, thinking it's a swizzle? +*/ + +RWStructuredBuffer<int> outputBuffer; + +interface IRotatable +{ + This rotateLeft(); +}; + +extension int : IRotatable +{ + This rotateLeft() { const uint u = this; return This((u << 1) | (u >> 31)); } +}; + +extension uint : IRotatable +{ + This rotateLeft() { let u = this; return This((u << 1) | (u >> 31)); } +}; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + uint v = tid.rotateLeft(); + + outputBuffer[tid] = v; +} diff --git a/tests/experiments/generic/return-generic.slang b/tests/experiments/generic/return-generic.slang index d107bdafe..bc152a648 100644 --- a/tests/experiments/generic/return-generic.slang +++ b/tests/experiments/generic/return-generic.slang @@ -1,6 +1,6 @@ //DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -/* A test of a generic function returning a generic struct. types. +/* A test of a generic function returning a generic struct. Since T could be any type, the compiler can't determine if it's convertable from an int. That may be surprising. diff --git a/tests/experiments/generic/type-to-value-3.slang b/tests/experiments/generic/type-to-value-3.slang index 773c0fe5c..e6ddb13c0 100644 --- a/tests/experiments/generic/type-to-value-3.slang +++ b/tests/experiments/generic/type-to-value-3.slang @@ -3,6 +3,9 @@ /* Test here is to try and associate a value with a type This does work. + +Note that it *requires* the getType<T> function as if we try to call say int.getType(), we get an error around +swizzling. */ //TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer diff --git a/tests/experiments/generic/type-to-value-4.slang b/tests/experiments/generic/type-to-value-4.slang index 986fffaf7..741b30791 100644 --- a/tests/experiments/generic/type-to-value-4.slang +++ b/tests/experiments/generic/type-to-value-4.slang @@ -2,12 +2,40 @@ /* Test here is to try and associate a value with a type -This doesn't work - it produces dynamic dispatch code, that is uncompilable because cases -are missing. +This doesn't work without 'public' on struct B. This is necessary such that +those implementations of `IGetE` are visible for dynamic dispatch. -.slang(24): error : control reaches end of non-void function [-Wreturn-type] -dxc: note : } -dxc: note : ^ +Otherwise the error + +> tests/experiments/generic/type-to-value-4.slang(21): error 50100: No type conformances are found for interface 'IGetE'. Code generation for current target requires at least one implementation type present in the linkage. +> interface IGetE + ^~~~~ + +This is somewhat 'surprising' because the code *explicitly* instanciates B, so why is it necessary to make it +public? + +If we make both struct A and struct B public, the following code uses dynamic dispatch in order to implement e.getE(). When it does this it introduces + +```HLSL +struct Tuple_0 +{ + uint2 value0_0; + uint2 value1_0; + AnyValue16 value2_0; +}; + +Tuple_0 _S1; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID_0 : SV_DISPATCHTHREADID) +{ + int _S7 = U_S3tu05IGetE4getEp0p3tu04Enum_0(_S1.value1_0); + + // ... +} +``` + +But _S1 is never intialized (in HLSL it becomes a Global in a constant buffer). Why does creating a local variable produce something in a constant buffer? */ @@ -24,12 +52,12 @@ interface IGetE static Enum getE(); }; -struct A : IGetE +public struct A : IGetE { static Enum getE() { return Enum::A; } }; -struct B : IGetE +public struct B : IGetE { static Enum getE() { return Enum::B; } }; |
