From 4730d54b478ab4aa4496e7a3c2972081f9aae356 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:27:47 -0700 Subject: Implement texture_storage_Xd in WGSL (#5158) * Implement texture_storage_Xd in WGSL This commit implements `texture_storage_Xd` in WGSL, which is similar to RWTextureXD in HLSL. It is intresting that `texture_storage_Xd` doesn't take the shader type as its input argument at all. Instead, it takes "texel format" enum value as its first template parameter, which can be found here: https://www.w3.org/TR/WGSL/#storage-texel-formats As an example, `texture_storage_2d` expects vec4 as a value type for `Load` and `Store`, where Z-component will be ignored and treated as zero and W-component will be treated always as 1. The type `u32` is inferred from the enum value `rg32uint`. Note that the number of component is always fixed to 4 regardless how many components are actually stored. --- tests/wgsl/texture-storage.slang | 136 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 tests/wgsl/texture-storage.slang (limited to 'tests') diff --git a/tests/wgsl/texture-storage.slang b/tests/wgsl/texture-storage.slang new file mode 100644 index 000000000..84921870b --- /dev/null +++ b/tests/wgsl/texture-storage.slang @@ -0,0 +1,136 @@ +//TEST:SIMPLE(filecheck=WGSL): -stage fragment -entry fragMain -target wgsl + +// In WGSL, `textureSample` and other variants work only for f32 type. +// But textureLoad works for i32, u32 and f32. + +//TEST_INPUT: ubuffer(data=[0], stride=4):out,name outputBuffer +RWStructuredBuffer outputBuffer; + +// f32 types + +//TEST_INPUT: RWTexture1D(format=R32G32_FLOAT, size=4, content = zero):name w1D_f32v2 +//TEST_INPUT: RWTexture2D(format=R32G32_FLOAT, size=4, content = zero):name w2D_f32v2 +//TEST_INPUT: RWTexture3D(format=R32G32_FLOAT, size=4, content = zero):name w3D_f32v2 +//TEST_INPUT: RWTexture2D(format=R32G32_FLOAT, size=4, content = zero, arrayLength=2):name w2DArray_f32v2 +// WGSL: var w1D_f32v2{{[^:]*}}: texture_storage_1d +[format("rg32f")] RWTexture1D w1D_f32v2; +[format("rg32f")] RWTexture2D w2D_f32v2; +[format("rg32f")] RWTexture3D w3D_f32v2; +[format("rg32f")] RWTexture2DArray w2DArray_f32v2; + +//TEST_INPUT: RWTexture1D(format=R8G8B8A8_UNORM, size=4, content = zero):name w1D_f32v4 +//TEST_INPUT: RWTexture2D(format=R8G8B8A8_UNORM, size=4, content = zero):name w2D_f32v4 +//TEST_INPUT: RWTexture3D(format=R8G8B8A8_UNORM, size=4, content = zero):name w3D_f32v4 +//TEST_INPUT: RWTexture2D(format=R8G8B8A8_UNORM, size=4, content = zero, arrayLength=2):name w2DArray_f32v4 +// WGSL: var w1D_f32v4{{[^:]*}}: texture_storage_1d +[format("rgba8")] RWTexture1D w1D_f32v4; +[format("rgba8")] RWTexture2D w2D_f32v4; +[format("rgba8")] RWTexture3D w3D_f32v4; +[format("rgba8")] RWTexture2DArray w2DArray_f32v4; + +// i32 types + +//TEST_INPUT: RWTexture1D(format=R32G32_SINT, size=4, content = zero):name w1D_i32v2 +//TEST_INPUT: RWTexture2D(format=R32G32_SINT, size=4, content = zero):name w2D_i32v2 +//TEST_INPUT: RWTexture3D(format=R32G32_SINT, size=4, content = zero):name w3D_i32v2 +//TEST_INPUT: RWTexture2D(format=R32G32_SINT, size=4, content = zero, arrayLength=2):name w2DArray_i32v2 +// WGSL: var w1D_i32v2{{[^:]*}}: texture_storage_1d +[format("rg32i")] RWTexture1D w1D_i32v2; +[format("rg32i")] RWTexture2D w2D_i32v2; +[format("rg32i")] RWTexture3D w3D_i32v2; +[format("rg32i")] RWTexture2DArray w2DArray_i32v2; + +//TEST_INPUT: RWTexture1D(format=R32G32B32A32_SINT, size=4, content = zero):name w1D_i32v4 +//TEST_INPUT: RWTexture2D(format=R32G32B32A32_SINT, size=4, content = zero):name w2D_i32v4 +//TEST_INPUT: RWTexture3D(format=R32G32B32A32_SINT, size=4, content = zero):name w3D_i32v4 +//TEST_INPUT: RWTexture2D(format=R32G32B32A32_SINT, size=4, content = zero, arrayLength=2):name w2DArray_i32v4 +// WGSL: var w1D_i32v4{{[^:]*}}: texture_storage_1d +[format("rgba32i")] RWTexture1D w1D_i32v4; +[format("rgba32i")] RWTexture2D w2D_i32v4; +[format("rgba32i")] RWTexture3D w3D_i32v4; +[format("rgba32i")] RWTexture2DArray w2DArray_i32v4; + +// u32 types + +//TEST_INPUT: RWTexture1D(format=R32G32_UINT, size=4, content = zero):name w1D_u32v2 +//TEST_INPUT: RWTexture2D(format=R32G32_UINT, size=4, content = zero):name w2D_u32v2 +//TEST_INPUT: RWTexture3D(format=R32G32_UINT, size=4, content = zero):name w3D_u32v2 +//TEST_INPUT: RWTexture2D(format=R32G32_UINT, size=4, content = zero, arrayLength=2):name w2DArray_u32v2 +// WGSL: var w1D_u32v2{{[^:]*}}: texture_storage_1d +[format("rg32ui")] RWTexture1D w1D_u32v2; +[format("rg32ui")] RWTexture2D w2D_u32v2; +[format("rg32ui")] RWTexture3D w3D_u32v2; +[format("rg32ui")] RWTexture2DArray w2DArray_u32v2; + +//TEST_INPUT: RWTexture1D(format=R16G16B16A16_UINT, size=4, content = zero):name w1D_u32v4 +//TEST_INPUT: RWTexture2D(format=R16G16B16A16_UINT, size=4, content = zero):name w2D_u32v4 +//TEST_INPUT: RWTexture3D(format=R16G16B16A16_UINT, size=4, content = zero):name w3D_u32v4 +//TEST_INPUT: RWTexture2D(format=R16G16B16A16_UINT, size=4, content = zero, arrayLength=2):name w2DArray_u32v4 +// WGSL: var w1D_u32v4{{[^:]*}}: texture_storage_1d +[format("rgba16ui")] RWTexture1D w1D_u32v4; +[format("rgba16ui")] RWTexture2D w2D_u32v4; +[format("rgba16ui")] RWTexture3D w3D_u32v4; +[format("rgba16ui")] RWTexture2DArray w2DArray_u32v4; + + +__generic +[ForceInline] // Workaround for a WGSL requirement that `texture_storage_Xd` must always be a global variable +bool TEST_textureStorage_StoreLoad( + RWTexture1D, sampleIndex, format> w1D, + RWTexture2D, sampleIndex, format> w2D, + RWTexture3D, sampleIndex, format> w3D, + RWTexture2DArray, sampleIndex, format> w2DArray) +{ + typealias Tvn = vector; + + // =================== + // o[i] = v; + // https://www.w3.org/TR/WGSL/#texturestore + // =================== + + // TODO: store before load + // WGSL: textureStore({{\(*}}w1D + w1D[0] = Tvn(T(1)); + + // WGSL: textureStore({{\(*}}w2D + w2D[0] = Tvn(T(1)); + + // WGSL: textureStore({{\(*}}w3D + w3D[0] = Tvn(T(1)); + + // WGSL: textureStore({{\(*}}w2DArray + w2DArray[0] = Tvn(T(1)); + + return true + // =================== + // T Load() + // https://www.w3.org/TR/WGSL/#textureload + // =================== + + // WGSL: textureLoad({{\(*}}w1D + && all(Tvn(T(0)) == w1D.Load(0)) + + // WGSL: textureLoad({{\(*}}w2D + && all(Tvn(T(0)) == w2D.Load(int2(0, 0))) + + // WGSL: textureLoad({{\(*}}w3D + && all(Tvn(T(0)) == w3D.Load(int3(0, 0, 0))) + + // WGSL: textureLoad({{\(*}}w2DArray + && all(Tvn(T(0)) == w2DArray.Load(int3(0, 0, 0))) + ; +} + +void fragMain() +{ + bool result = true + && TEST_textureStorage_StoreLoad(w1D_f32v2, w2D_f32v2, w3D_f32v2, w2DArray_f32v2) + && TEST_textureStorage_StoreLoad(w1D_f32v4, w2D_f32v4, w3D_f32v4, w2DArray_f32v4) + && TEST_textureStorage_StoreLoad(w1D_i32v2, w2D_i32v2, w3D_i32v2, w2DArray_i32v2) + && TEST_textureStorage_StoreLoad(w1D_i32v4, w2D_i32v4, w3D_i32v4, w2DArray_i32v4) + && TEST_textureStorage_StoreLoad(w1D_u32v2, w2D_u32v2, w3D_u32v2, w2DArray_u32v2) + && TEST_textureStorage_StoreLoad(w1D_u32v4, w2D_u32v4, w3D_u32v4, w2DArray_u32v4) + ; + + outputBuffer[0] = int(result); +} -- cgit v1.2.3