From 0e6964b258070b0aa643da42512b1623f1bc046b Mon Sep 17 00:00:00 2001 From: Tomas Davidovic Date: Thu, 12 Jun 2025 11:45:00 +0200 Subject: [PATCH 1/3] Added handling of non-struct ParamBlock writes --- slangpy/tests/device/test_shader_cursor.py | 1 + slangpy/tests/device/test_shader_cursor.slang | 2 ++ src/slangpy_ext/device/cursor_utils.h | 8 +++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/slangpy/tests/device/test_shader_cursor.py b/slangpy/tests/device/test_shader_cursor.py index 19a7f31f4..1d9d500fa 100644 --- a/slangpy/tests/device/test_shader_cursor.py +++ b/slangpy/tests/device/test_shader_cursor.py @@ -128,6 +128,7 @@ class Var: "u_float2x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7]]), "u_float3x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]), "u_float4x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]), + "pb_float4x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]), # float16_t "u_float16_t": Var(kind="scalar", type="float16_t", value=1.2345), "u_float16_t_min": Var(kind="scalar", type="float16_t", value=FLOAT16_MIN), diff --git a/slangpy/tests/device/test_shader_cursor.slang b/slangpy/tests/device/test_shader_cursor.slang index c8611397e..ba695af7d 100644 --- a/slangpy/tests/device/test_shader_cursor.slang +++ b/slangpy/tests/device/test_shader_cursor.slang @@ -85,6 +85,7 @@ uniform float3x3 u_float3x3; uniform float2x4 u_float2x4; uniform float3x4 u_float3x4; uniform float4x4 u_float4x4; +ParameterBlock pb_float4x4; uniform float16_t u_float16_t; uniform float16_t u_float16_t_min; @@ -260,6 +261,7 @@ void compute_main(uint3 tid: SV_DispatchThreadID) writer.write(u_float2x4); writer.write(u_float3x4); writer.write(u_float4x4); + writer.write(pb_float4x4); writer.write(u_float16_t); writer.write(u_float16_t_min); diff --git a/src/slangpy_ext/device/cursor_utils.h b/src/slangpy_ext/device/cursor_utils.h index 74de3efc0..6eb290683 100644 --- a/src/slangpy_ext/device/cursor_utils.h +++ b/src/slangpy_ext/device/cursor_utils.h @@ -518,8 +518,14 @@ class WriteConverterTable { } case TypeReflection::Kind::constant_buffer: case TypeReflection::Kind::parameter_block: + if constexpr (requires { self.dereference(); }) { + // Unwrap constant buffers or parameter blocks for shader cursors + auto child = self.dereference(); + write_internal(child, nbval); + return; + } else + SGL_THROW("constant_buffer and param_block not expected in BufferElementCursor"); case TypeReflection::Kind::struct_: { - // Unwrap constant buffers or parameter blocks if (kind != TypeReflection::Kind::struct_) type_layout = type_layout->getElementTypeLayout(); From 98283e811ec57239846931c1eebb6feb482e6107 Mon Sep 17 00:00:00 2001 From: Tomas Davidovic Date: Thu, 12 Jun 2025 16:33:24 +0200 Subject: [PATCH 2/3] Added tests for ParameterBlock writes --- slangpy/tests/device/test_shader_cursor.py | 34 ++++++++++++- slangpy/tests/device/test_shader_cursor.slang | 49 ++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/slangpy/tests/device/test_shader_cursor.py b/slangpy/tests/device/test_shader_cursor.py index 1d9d500fa..bc7868df1 100644 --- a/slangpy/tests/device/test_shader_cursor.py +++ b/slangpy/tests/device/test_shader_cursor.py @@ -129,6 +129,8 @@ class Var: "u_float3x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]), "u_float4x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]), "pb_float4x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]), + "pb_float4x3": Var(kind="matrix", type="float", value=[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]), + "pb_float3x4": Var(kind="matrix", type="float", value=[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]), # float16_t "u_float16_t": Var(kind="scalar", type="float16_t", value=1.2345), "u_float16_t_min": Var(kind="scalar", type="float16_t", value=FLOAT16_MIN), @@ -168,6 +170,31 @@ class Var: "f_float2": Var(kind="vector", type="float", value=[1.23, 1.234]), "f_float3": Var(kind="vector", type="float", value=[1.23, 1.234, 1.2345]), "f_float4": Var(kind="vector", type="float", value=[1.23, 1.235, 1.23456, 1.234567]), + "f_float4x3": Var(kind="matrix", type="float", value=[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]), + "f_bool_array": Var(kind="array", type="bool", value=[False]), + "f_int_array": Var(kind="array", type="int", value=[-10, 10]), + "f_uint_array": Var(kind="array", type="uint", value=[0, 10, 20]), + "f_float_array": Var(kind="array", type="float", value=[0.1, 0.2, 0.3, 0.4]), + }, + # pb_struct + "pb_struct": { + "f_bool": Var(kind="scalar", type="bool", value=True), + "f_bool2": Var(kind="vector", type="bool", value=[False, True]), + "f_bool3": Var(kind="vector", type="bool", value=[False, True, False]), + "f_bool4": Var(kind="vector", type="bool", value=[False, True, False, True]), + "f_int": Var(kind="scalar", type="int", value=-123), + "f_int2": Var(kind="vector", type="int", value=[-123, 123]), + "f_int3": Var(kind="vector", type="int", value=[-123, 123, -1234]), + "f_int4": Var(kind="vector", type="int", value=[-123, 123, -1234, 1234]), + "f_uint": Var(kind="scalar", type="uint", value=12), + "f_uint2": Var(kind="vector", type="uint", value=[123, 1234]), + "f_uint3": Var(kind="vector", type="uint", value=[123, 1234, 12345]), + "f_uint4": Var(kind="vector", type="uint", value=[123, 1235, 123456, 1234567]), + "f_float": Var(kind="scalar", type="float", value=1.2), + "f_float2": Var(kind="vector", type="float", value=[1.23, 1.234]), + "f_float3": Var(kind="vector", type="float", value=[1.23, 1.234, 1.2345]), + "f_float4": Var(kind="vector", type="float", value=[1.23, 1.235, 1.23456, 1.234567]), + "f_float4x3": Var(kind="matrix", type="float", value=[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]), "f_bool_array": Var(kind="array", type="bool", value=[False]), "f_int_array": Var(kind="array", type="int", value=[-10, 10]), "f_uint_array": Var(kind="array", type="uint", value=[0, 10, 20]), @@ -231,6 +258,7 @@ def convert_matrix(type: str, rows: int, cols: int, values: Any): TABLE = { ("float", 2, 2): spy.float2x2, ("float", 3, 3): spy.float3x3, + ("float", 4, 3): spy.float4x3, ("float", 2, 4): spy.float2x4, ("float", 3, 4): spy.float3x4, ("float", 4, 4): spy.float4x4, @@ -335,6 +363,10 @@ def write_vars( ): if isinstance(vars, dict): for key, var in vars.items(): + # Disabling ParameterBlock tests on Vulkan, due to issue: + # https://github.com/shader-slang/slang/issues/7431 + if device_type == spy.DeviceType.vulkan and key.startswith("pb_"): + continue if isinstance(var, dict): write_vars(device_type, cursor[key], var, key + ".") elif isinstance(var, list): @@ -369,7 +401,7 @@ def write_vars( named_typed_results = list(zip(names, types, results)) for named_typed_result, named_typed_reference in zip( - named_typed_references, named_typed_results + named_typed_results, named_typed_references ): # Vulkan/Metal/CUDA packing rule for certain matrix types are not the same as D3D12's if (device_type in [spy.DeviceType.vulkan, spy.DeviceType.metal, spy.DeviceType.cuda]) and ( diff --git a/slangpy/tests/device/test_shader_cursor.slang b/slangpy/tests/device/test_shader_cursor.slang index ba695af7d..14bcb51d4 100644 --- a/slangpy/tests/device/test_shader_cursor.slang +++ b/slangpy/tests/device/test_shader_cursor.slang @@ -1,5 +1,11 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// Enable (and remove the define) after this issue has been addressed: +// https://github.com/shader-slang/slang/issues/7431 +// Slang currently generates somewhat invalid code, and at the same time, +// the tests fail in a weird fashion (u_struct_array[1:] are not set). +#define ENABLE_PARAMBLOCK_TESTS !defined(__TARGET_VULKAN__) + struct Test { bool f_bool; bool2 f_bool2; @@ -17,6 +23,7 @@ struct Test { float2 f_float2; float3 f_float3; float4 f_float4; + float4x3 f_float4x3; bool f_bool_array[1]; int f_int_array[2]; @@ -85,7 +92,11 @@ uniform float3x3 u_float3x3; uniform float2x4 u_float2x4; uniform float3x4 u_float3x4; uniform float4x4 u_float4x4; +#if ENABLE_PARAMBLOCK_TESTS ParameterBlock pb_float4x4; +ParameterBlock pb_float4x3; +ParameterBlock pb_float3x4; +#endif uniform float16_t u_float16_t; uniform float16_t u_float16_t_min; @@ -109,12 +120,14 @@ uniform uint u_uint_array[4]; uniform float u_float_array[4]; uniform Test u_struct; +#if ENABLE_PARAMBLOCK_TESTS +ParameterBlock pb_struct; +#endif uniform int u_int_array_2[4]; uniform Test u_struct_array[4]; Buffer u_buffer; - RWStructuredBuffer results; struct Writer { @@ -261,7 +274,11 @@ void compute_main(uint3 tid: SV_DispatchThreadID) writer.write(u_float2x4); writer.write(u_float3x4); writer.write(u_float4x4); +#if ENABLE_PARAMBLOCK_TESTS writer.write(pb_float4x4); + writer.write(pb_float4x3); + writer.write(pb_float3x4); +#endif writer.write(u_float16_t); writer.write(u_float16_t_min); @@ -304,6 +321,7 @@ void compute_main(uint3 tid: SV_DispatchThreadID) writer.write(u_struct.f_float2); writer.write(u_struct.f_float3); writer.write(u_struct.f_float4); + writer.write(u_struct.f_float4x3); for (uint i = 0; i < 1; ++i) writer.write(u_struct.f_bool_array[i]); @@ -314,6 +332,35 @@ void compute_main(uint3 tid: SV_DispatchThreadID) for (uint i = 0; i < 4; ++i) writer.write(u_struct.f_float_array[i]); +#if ENABLE_PARAMBLOCK_TESTS + writer.write(pb_struct.f_bool); + writer.write(pb_struct.f_bool2); + writer.write(pb_struct.f_bool3); + writer.write(pb_struct.f_bool4); + writer.write(pb_struct.f_int); + writer.write(pb_struct.f_int2); + writer.write(pb_struct.f_int3); + writer.write(pb_struct.f_int4); + writer.write(pb_struct.f_uint); + writer.write(pb_struct.f_uint2); + writer.write(pb_struct.f_uint3); + writer.write(pb_struct.f_uint4); + writer.write(pb_struct.f_float); + writer.write(pb_struct.f_float2); + writer.write(pb_struct.f_float3); + writer.write(pb_struct.f_float4); + writer.write(pb_struct.f_float4x3); + + for (uint i = 0; i < 1; ++i) + writer.write(pb_struct.f_bool_array[i]); + for (uint i = 0; i < 2; ++i) + writer.write(pb_struct.f_int_array[i]); + for (uint i = 0; i < 3; ++i) + writer.write(pb_struct.f_uint_array[i]); + for (uint i = 0; i < 4; ++i) + writer.write(pb_struct.f_float_array[i]); +#endif + for (uint i = 0; i < 4; ++i) writer.write(u_int_array_2[i]); From 35f97f37496c9bfc8c92bcc4a85f20bc85e2922d Mon Sep 17 00:00:00 2001 From: Tomas Davidovic Date: Thu, 12 Jun 2025 16:28:22 +0200 Subject: [PATCH 3/3] Removed superfluous filter on device type --- slangpy/tests/device/test_buffer_cursor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/slangpy/tests/device/test_buffer_cursor.py b/slangpy/tests/device/test_buffer_cursor.py index 9a010fc54..ea5ac8d5e 100644 --- a/slangpy/tests/device/test_buffer_cursor.py +++ b/slangpy/tests/device/test_buffer_cursor.py @@ -337,8 +337,6 @@ def test_cursor_read_write(device_type: spy.DeviceType, seed: int): # Randomize the order of the tests tests = get_tests(device_type).copy() - if device_type == spy.DeviceType.cuda: - tests = [x for x in tests if "bool" not in x[0]] random.seed(seed) random.shuffle(tests)