diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2024-03-01 01:50:19 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-01 01:50:19 +0800 |
| commit | d979b5048009c3909cfc13476a78a12ae5f4d61b (patch) | |
| tree | 550815d37916be845fb0aa1dcc6131960c2bf517 /tests | |
| parent | 21f86773771c26da8bf3c458642e51b1728d419c (diff) | |
Add support for bitfields (#3639)
* Add support for bitfields
Closes https://github.com/shader-slang/slang/issues/3559
* Set scopes for syntsized bitfield accessors
* Simplify generated code for bitfield accessors
* spelling
* regenerate vs project
* warnings
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/language-feature/bitfield/generic.slang | 29 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/non-integral.slang | 14 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/overflow.slang | 29 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/simple.slang | 74 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/sizeof.slang | 42 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/too-large.slang | 14 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/type-alias.slang | 32 | ||||
| -rw-r--r-- | tests/language-feature/bitfield/zero-width.slang | 28 |
8 files changed, 262 insertions, 0 deletions
diff --git a/tests/language-feature/bitfield/generic.slang b/tests/language-feature/bitfield/generic.slang new file mode 100644 index 000000000..f1789a04c --- /dev/null +++ b/tests/language-feature/bitfield/generic.slang @@ -0,0 +1,29 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type + +// CHECK: 123 +// CHECK-NEXT: 4567 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<uint> outputBuffer; + +struct S<T> { + int foo : 8; + uint bar : 24; + T baz; +}; + +[numthreads(1, 1, 1)] +void computeMain() +{ + S<int> s; + s.foo = 123; + s.bar = 4567; + outputBuffer[0] = s.foo; + outputBuffer[1] = s.bar; + s.foo = 0; + s.bar = 0; + outputBuffer[2] = s.foo; + outputBuffer[3] = s.bar; +} diff --git a/tests/language-feature/bitfield/non-integral.slang b/tests/language-feature/bitfield/non-integral.slang new file mode 100644 index 000000000..9d477c1f8 --- /dev/null +++ b/tests/language-feature/bitfield/non-integral.slang @@ -0,0 +1,14 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): + +struct S +{ + float foo : 10; + // CHECK: non-integral.slang([[#@LINE-1]]): error 31301: bit-field type (float) must be an integral type + S bar : 10; + // CHECK: non-integral.slang([[#@LINE-1]]): error 31301: bit-field type (S) must be an integral type +}; + +[numthreads(1, 1, 1)] +void computeMain() +{ +} diff --git a/tests/language-feature/bitfield/overflow.slang b/tests/language-feature/bitfield/overflow.slang new file mode 100644 index 000000000..cd217e92a --- /dev/null +++ b/tests/language-feature/bitfield/overflow.slang @@ -0,0 +1,29 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type + +// CHECK: 123 +// CHECK-NEXT: 4567 +// CHECK-NEXT: -10 +// CHECK-NEXT: 16772649 + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<int> outputBuffer; + +struct S { + int foo : 8; + uint bar : 24; +}; + +[numthreads(1, 1, 1)] +void computeMain() +{ + S s; + s.foo = 123; + s.bar = 4567; + outputBuffer[0] = s.foo; + outputBuffer[1] = s.bar; + + s.foo *= 2; + s.bar *= 0xffffff; + outputBuffer[2] = s.foo; + outputBuffer[3] = s.bar; +} diff --git a/tests/language-feature/bitfield/simple.slang b/tests/language-feature/bitfield/simple.slang new file mode 100644 index 000000000..dee654259 --- /dev/null +++ b/tests/language-feature/bitfield/simple.slang @@ -0,0 +1,74 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type + +// CHECK: 123 +// CHECK-NEXT: 4567 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<uint> outputBuffer; + +struct S { + int foo : 8; + uint bar : 24; +}; + +// Generates the equivalent of this: +/* +struct S { + int _backing; + + property foo : int + { + // int foo : 8; + get + { + let backingWidth = 32; + let fooWidth = 8; + let topOfFoo = 8; + // Shift left and then right to sign-extend foo properly + return (int(_backing) << (backingWidth-topOfFoo)) >> (backingWidth-fooWidth); + } + [mutating] set(int x) + { + let fooMask = 0x000000FF; + let bottomOfFoo = 0; + _backing = int((_backing & ~fooMask) | ((int(x) << bottomOfFoo) & fooMask)); + } + } + + // int bar : 24; + property bar : int + { + get + { + let backingWidth = 32; + let barWidth = 24; + let topOfBar = 32; + // Shift left and then right to sign-extend bar properly + return (uint(_backing) << (backingWidth-topOfBar)) >> (backingWidth-barWidth); + } + [mutating] set(int x) + { + let barMask = 0xFFFFFF00; + let bottomOfBar = 8; + _backing = int((_backing & ~barMask) | ((int(x) << bottomOfBar) & barMask)); + } + } +}; +*/ + +[numthreads(1, 1, 1)] +void computeMain() +{ + S s; + s.foo = 123; + s.bar = 4567; + outputBuffer[0] = s.foo; + outputBuffer[1] = s.bar; + + s.foo = 0; + s.bar = 0; + outputBuffer[2] = s.foo; + outputBuffer[3] = s.bar; +} diff --git a/tests/language-feature/bitfield/sizeof.slang b/tests/language-feature/bitfield/sizeof.slang new file mode 100644 index 000000000..57056d1b2 --- /dev/null +++ b/tests/language-feature/bitfield/sizeof.slang @@ -0,0 +1,42 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type + +// CHECK: 1 +// CHECK-NEXT: 1 +// CHECK-NEXT: 1 +// CHECK-NEXT: 1 + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<uint> outputBuffer; + +struct S { + int foo : 8; + int bar : 24; +}; + +// This packs the smaller int into the int64 +struct T { + int64_t foo : 33; + int bar : 24; +}; + +// This takes two ints to store all the bits +struct P { + int foo : 24; + int bar : 24; +}; + +// Even though the smaller field comes first, it's still packed with the larger +// one +struct Q { + int8_t foo : 1; + int64_t bar : 63; +}; + +[numthreads(1, 1, 1)] +void computeMain() +{ + outputBuffer[0] = sizeof(S) == sizeof(int); + outputBuffer[1] = sizeof(T) == sizeof(int64_t); + outputBuffer[2] = sizeof(P) == sizeof(int) * 2; + outputBuffer[3] = sizeof(Q) == sizeof(int64_t); +} diff --git a/tests/language-feature/bitfield/too-large.slang b/tests/language-feature/bitfield/too-large.slang new file mode 100644 index 000000000..0780b8206 --- /dev/null +++ b/tests/language-feature/bitfield/too-large.slang @@ -0,0 +1,14 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): + +struct S +{ + int foo : 33; + // CHECK: too-large.slang([[#@LINE-1]]): error 31300: bit-field size (33) exceeds the width of its type int (32) + int64_t bar : 999; + // CHECK: too-large.slang([[#@LINE-1]]): error 31300: bit-field size (999) exceeds the width of its type int64_t (64) +}; + +[numthreads(1, 1, 1)] +void computeMain() +{ +} diff --git a/tests/language-feature/bitfield/type-alias.slang b/tests/language-feature/bitfield/type-alias.slang new file mode 100644 index 000000000..7a33e2c50 --- /dev/null +++ b/tests/language-feature/bitfield/type-alias.slang @@ -0,0 +1,32 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type + +// CHECK: 123 +// CHECK-NEXT: 4567 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<uint> outputBuffer; + +typedef uint MyUInt; + +struct S { + MyInt foo : 8; + MyUInt bar : 24; +}; + +typealias MyInt = int; + +[numthreads(1, 1, 1)] +void computeMain() +{ + S s; + s.foo = 123; + s.bar = 4567; + outputBuffer[0] = s.foo; + outputBuffer[1] = s.bar; + s.foo = 0; + s.bar = 0; + outputBuffer[2] = s.foo; + outputBuffer[3] = s.bar; +} diff --git a/tests/language-feature/bitfield/zero-width.slang b/tests/language-feature/bitfield/zero-width.slang new file mode 100644 index 000000000..457b31456 --- /dev/null +++ b/tests/language-feature/bitfield/zero-width.slang @@ -0,0 +1,28 @@ +//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type + +// CHECK: 123 +// CHECK-NEXT: 4567 +// CHECK-NEXT: 1 +// CHECK-NEXT: 0 + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer<uint> outputBuffer; + +struct S { + int foo : 8; + int breaker : 0; + int bar : 24; +}; + +[numthreads(1, 1, 1)] +void computeMain() +{ + S s; + s.foo = 123; + s.bar = 4567; + s.breaker = 9999; + outputBuffer[0] = s.foo; + outputBuffer[1] = s.bar; + outputBuffer[2] = sizeof(S) == sizeof(int) * 2; + outputBuffer[3] = s.breaker; +} |
