From 35bfcc9c332fb4c697b8fa5d3f11031b0e63c327 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Sun, 11 Jan 2026 00:20:55 +0100 Subject: [PATCH 1/2] add regression 73_SpirvKeysTest --- 73_SpirvKeysTest/CMakeLists.txt | 138 ++++++++++++++++++++++++++++++++ 73_SpirvKeysTest/input.hlsl | 77 ++++++++++++++++++ 73_SpirvKeysTest/main.cpp | 131 ++++++++++++++++++++++++++++++ 3 files changed, 346 insertions(+) create mode 100644 73_SpirvKeysTest/CMakeLists.txt create mode 100644 73_SpirvKeysTest/input.hlsl create mode 100644 73_SpirvKeysTest/main.cpp diff --git a/73_SpirvKeysTest/CMakeLists.txt b/73_SpirvKeysTest/CMakeLists.txt new file mode 100644 index 000000000..2265f18d0 --- /dev/null +++ b/73_SpirvKeysTest/CMakeLists.txt @@ -0,0 +1,138 @@ +include(common) + +nbl_create_executable_project("" "" "" "") + +set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/auto-gen") +file(MAKE_DIRECTORY "${OUTPUT_DIRECTORY}") + +enable_testing() + +add_test(NAME ${EXECUTABLE_NAME} + COMMAND "$" + WORKING_DIRECTORY "$" + COMMAND_EXPAND_LISTS +) + +set(HLSL_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.hlsl") +file(TO_CMAKE_PATH "${HLSL_INPUT}" HLSL_INPUT) + +set(JSON_TEMPLATE [=[ +[ + { + "INPUT": "@HLSL_INPUT@", + "KEY": "k_plain", + "COMPILE_OPTIONS": ["-T", "cs_6_8"] + }, + { + "INPUT": "@HLSL_INPUT@", + "KEY": "k_ints", + "COMPILE_OPTIONS": ["-T", "cs_6_8", "-DNBL_TEST_HAS_I"], + "CAPS": [ + { + "kind": "custom", + "struct": "i", + "members": [ + { "name": "b1", "type": "bool", "values": [1] }, + { "name": "b0", "type": "bool", "values": [0] }, + { "name": "u16", "type": "uint16_t", "values": [65535] }, + { "name": "u32", "type": "uint32_t", "values": [123456789] }, + { "name": "u64", "type": "uint64_t", "values": [1234567890123] }, + { "name": "s16", "type": "int16_t", "values": [-32768] }, + { "name": "s32", "type": "int32_t", "values": [-123456789] }, + { "name": "s64", "type": "int64_t", "values": [-1234567890123] } + ] + } + ] + }, + { + "INPUT": "@HLSL_INPUT@", + "KEY": "k_two", + "COMPILE_OPTIONS": ["-T", "cs_6_8", "-DNBL_TEST_HAS_T"], + "CAPS": [ + { + "kind": "custom", + "struct": "t", + "members": [ + { "name": "sel", "type": "uint32_t", "values": [0, 1] } + ] + } + ] + }, + { + "INPUT": "@HLSL_INPUT@", + "KEY": "k_f", + "COMPILE_OPTIONS": ["-T", "cs_6_8", "-DNBL_TEST_HAS_F"], + "CAPS": [ + { + "kind": "custom", + "struct": "f", + "members": [ + { "name": "min", "type": "float", "values": [1.17549435e-38] }, + { "name": "max", "type": "float", "values": [3.40282347e+38] }, + { "name": "neg", "type": "float", "values": [-1] }, + { "name": "exp", "type": "float", "values": ["1.25e-1"] } + ] + } + ] + }, + { + "INPUT": "@HLSL_INPUT@", + "KEY": "k_d", + "COMPILE_OPTIONS": ["-T", "cs_6_8", "-DNBL_TEST_HAS_D"], + "CAPS": [ + { + "kind": "custom", + "struct": "d", + "members": [ + { "name": "min", "type": "double", "values": ["2.2250738585072010e-308"] }, + { "name": "max", "type": "double", "values": ["1.7976931348623165e+308"] }, + { "name": "neg", "type": "double", "values": [-1.0] }, + { "name": "exp", "type": "double", "values": ["1.25e-1"] } + ] + } + ] + }, + { + "INPUT": "@HLSL_INPUT@", + "KEY": "k_mix", + "COMPILE_OPTIONS": ["-T", "cs_6_8", "-DNBL_TEST_HAS_M", "-DNBL_TEST_HAS_LIMITS", "-DNBL_TEST_HAS_FEATURES"], + "CAPS": [ + { + "kind": "custom", + "struct": "m", + "members": [ + { "name": "md", "type": "uint32_t", "values": [7] }, + { "name": "en", "type": "bool", "values": [1] }, + { "name": "sc", "type": "float", "values": [1] } + ] + }, + { + "kind": "limits", + "members": [ + { "name": "maxImageDimension2D", "type": "uint32_t", "values": [16384] } + ] + }, + { + "kind": "features", + "members": [ + { "name": "shaderCullDistance", "type": "bool", "values": [1] } + ] + } + ] + } +] +]=]) +string(CONFIGURE "${JSON_TEMPLATE}" JSON @ONLY) + +NBL_CREATE_NSC_COMPILE_RULES( + TARGET ${EXECUTABLE_NAME}SPIRV + LINK_TO ${EXECUTABLE_NAME} + BINARY_DIR ${OUTPUT_DIRECTORY} + MOUNT_POINT_DEFINE NBL_THIS_EXAMPLE_BUILD_MOUNT_POINT + COMMON_OPTIONS -I ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VAR KEYS + INCLUDE nbl/this_example/builtin/build/spirv/keys.hpp + NAMESPACE nbl::this_example::builtin::build + INPUTS ${JSON} + DISCARD_DEFAULT_GLOB +) diff --git a/73_SpirvKeysTest/input.hlsl b/73_SpirvKeysTest/input.hlsl new file mode 100644 index 000000000..b8ce7b132 --- /dev/null +++ b/73_SpirvKeysTest/input.hlsl @@ -0,0 +1,77 @@ +#include "nbl/builtin/hlsl/cpp_compat/basic.h" + +template +struct DummyCaps +{ +#if defined(NBL_TEST_HAS_I) + static const uint32_t u16 = Caps::i::u16; + static const uint32_t u32 = Caps::i::u32; +#endif +#if defined(NBL_TEST_HAS_M) + static const uint32_t md = Caps::m::md; + static const bool en = Caps::m::en; +#endif +#if defined(NBL_TEST_HAS_F) + static const float fmin = Caps::f::min; +#endif +#if defined(NBL_TEST_HAS_D) + static const double dmax = Caps::d::max; +#endif +#if defined(NBL_TEST_HAS_LIMITS) + static const uint32_t lim = Caps::maxImageDimension2D; +#endif +#if defined(NBL_TEST_HAS_FEATURES) + static const bool feat = Caps::shaderCullDistance; +#endif +#if defined(NBL_TEST_HAS_T) + static const uint32_t sel = Caps::t::sel; +#endif +}; + +template +uint32_t dummyValue() +{ + uint32_t v = 0u; +#if defined(NBL_TEST_HAS_I) + v += DummyCaps::u16 + DummyCaps::u32; +#endif +#if defined(NBL_TEST_HAS_M) + v += DummyCaps::md; + v += DummyCaps::en ? 1u : 0u; +#endif +#if defined(NBL_TEST_HAS_FEATURES) + if (DummyCaps::feat) + { +#if defined(NBL_TEST_HAS_LIMITS) + v += DummyCaps::lim; +#endif + } +#elif defined(NBL_TEST_HAS_LIMITS) + v += DummyCaps::lim; +#endif +#if defined(NBL_TEST_HAS_F) + float f = DummyCaps::fmin; + v += uint32_t(f); +#endif +#if defined(NBL_TEST_HAS_D) + double d = DummyCaps::dmax; + v += uint32_t(d); +#endif +#if defined(NBL_TEST_HAS_T) + v += DummyCaps::sel; +#endif + return v; +} + +[numthreads(1, 1, 1)] +[shader("compute")] +void main(uint3 tid : SV_DispatchThreadID) +{ + const uint32_t v = dummyValue(); + if (tid.x == 0u) + { + uint32_t sink = v; + if (sink == 0u) + return; + } +} diff --git a/73_SpirvKeysTest/main.cpp b/73_SpirvKeysTest/main.cpp new file mode 100644 index 000000000..e9e3254d7 --- /dev/null +++ b/73_SpirvKeysTest/main.cpp @@ -0,0 +1,131 @@ +#include + +#include + +#include "nbl/application_templates/MonoDeviceApplication.hpp" +#include "nbl/this_example/builtin/build/spirv/keys.hpp" + +using namespace nbl; +using namespace nbl::core; +using namespace nbl::system; +using namespace nbl::video; +using namespace nbl::application_templates; + +static inline const nbl::video::ILogicalDevice* g_device = nullptr; + +template +constexpr bool buffer_equals(const Buffer& buf) +{ + constexpr size_t expected_size = sizeof(Expected.value) - 1; + if (buf.size() != expected_size) + return false; + for (size_t i = 0; i < expected_size; ++i) + { + if (buf.data()[i] != Expected.value[i]) + return false; + } + return true; +} + +template +bool check_key() +{ + constexpr auto keyBuf = nbl::this_example::builtin::build::get_spirv_key(Args...); + constexpr bool matches_ct = buffer_equals(keyBuf); + static_assert(matches_ct); + + if constexpr (requires { nbl::core::detail::SpirvKeyBuilder::build_from_device(static_cast(nullptr), Args...); }) + { + if (g_device) + return buffer_equals(nbl::this_example::builtin::build::get_spirv_key(g_device, Args...)); + } + + return buffer_equals(nbl::this_example::builtin::build::get_spirv_key(Args...)); +} + +static constexpr struct +{ + bool b1 = true; + bool b0 = false; + uint16_t u16 = 65535u; + uint32_t u32 = 123456789u; + uint64_t u64 = 1234567890123ull; + int16_t s16 = -32768; + int32_t s32 = -123456789; + int64_t s64 = -1234567890123ll; +} userI; + +static constexpr struct +{ + uint32_t sel = 1u; +} userT; + +static constexpr struct +{ + float min = std::numeric_limits::min(); + float max = std::numeric_limits::max(); + float neg = -1.0f; + float exp = 1.25e-1f; +} userF; + +static constexpr struct +{ + double min = std::numeric_limits::min(); + double max = std::numeric_limits::max(); + double neg = -1.0; + double exp = 1.25e-1; +} userD; + +static constexpr struct +{ + uint32_t md = 7u; + bool en = true; + float sc = 1.0f; +} userMix; + +static constexpr struct +{ + uint32_t maxImageDimension2D = 16384u; +} limits; + +static constexpr struct +{ + bool shaderCullDistance = true; +} features; + +class SpirvKeysTestApp final : public MonoDeviceApplication +{ + using device_base_t = MonoDeviceApplication; + +public: + SpirvKeysTestApp(const path& _localInputCWD, const path& _localOutputCWD, const path& _sharedInputCWD, const path& _sharedOutputCWD) : + IApplicationFramework(_localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD) {} + + bool onAppInitialized(smart_refctd_ptr&& system) override + { + if (!device_base_t::onAppInitialized(smart_refctd_ptr(system))) + return false; + g_device = m_device.get(); + + bool ok = true; +#define SPIRV_KEY_TEST(KEY, EXPECTED, ...) ok &= check_key(); + SPIRV_KEY_TEST("k_plain", "Debug/k_plain.spv") + SPIRV_KEY_TEST("k_ints", "Debug/k_ints__i.b1_1.b0_0.u16_65535.u32_123456789.u64_1234567890123.s16_-32768.s32_-123456789.s64_-1234567890123.spv", userI) + SPIRV_KEY_TEST("k_two", "Debug/k_two__t.sel_1.spv", userT) + SPIRV_KEY_TEST("k_f", "Debug/k_f__f.min_1.17549435e-38.max_3.40282347e+38.neg_-1.00000000e+00.exp_1.25000000e-01.spv", userF) + SPIRV_KEY_TEST("k_d", "Debug/k_d__d.min_2.2250738585072010e-308.max_1.7976931348623165e+308.neg_-1.0000000000000000e+00.exp_1.2500000000000000e-01.spv", userD) + SPIRV_KEY_TEST("k_mix", "Debug/k_mix__m.md_7.en_1.sc_1.00000000e+00__limits.maxImageDimension2D_16384__features.shaderCullDistance_1.spv", userMix, limits, features) +#undef SPIRV_KEY_TEST + + if (!ok) + return logFail("SpirvKeysTest failed"); + + return true; + } + + void workLoopBody() override {} + + bool keepRunning() override { return false; } +}; + +NBL_MAIN_FUNC(SpirvKeysTestApp) From f2f4c5f8c42f2de3f86de66ac4e4398c00a792a1 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Sun, 11 Jan 2026 12:58:22 +0100 Subject: [PATCH 2/2] update 73 ex --- 73_SpirvKeysTest/CMakeLists.txt | 2 ++ 73_SpirvKeysTest/main.cpp | 18 ++++++++++++------ CMakeLists.txt | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/73_SpirvKeysTest/CMakeLists.txt b/73_SpirvKeysTest/CMakeLists.txt index 2265f18d0..a101fa5a9 100644 --- a/73_SpirvKeysTest/CMakeLists.txt +++ b/73_SpirvKeysTest/CMakeLists.txt @@ -2,6 +2,8 @@ include(common) nbl_create_executable_project("" "" "" "") +target_compile_definitions(${EXECUTABLE_NAME} PRIVATE NBL_SPIRV_CFG="$") + set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/auto-gen") file(MAKE_DIRECTORY "${OUTPUT_DIRECTORY}") diff --git a/73_SpirvKeysTest/main.cpp b/73_SpirvKeysTest/main.cpp index e9e3254d7..dee9bbecd 100644 --- a/73_SpirvKeysTest/main.cpp +++ b/73_SpirvKeysTest/main.cpp @@ -13,6 +13,12 @@ using namespace nbl::application_templates; static inline const nbl::video::ILogicalDevice* g_device = nullptr; +#ifndef NBL_SPIRV_CFG +#error "NBL_SPIRV_CFG must be defined via target_compile_definitions" +#endif + +#define NBL_SPIRV_CFG_PREFIX NBL_SPIRV_CFG "/" + template constexpr bool buffer_equals(const Buffer& buf) { @@ -109,12 +115,12 @@ class SpirvKeysTestApp final : public MonoDeviceApplication bool ok = true; #define SPIRV_KEY_TEST(KEY, EXPECTED, ...) ok &= check_key(); - SPIRV_KEY_TEST("k_plain", "Debug/k_plain.spv") - SPIRV_KEY_TEST("k_ints", "Debug/k_ints__i.b1_1.b0_0.u16_65535.u32_123456789.u64_1234567890123.s16_-32768.s32_-123456789.s64_-1234567890123.spv", userI) - SPIRV_KEY_TEST("k_two", "Debug/k_two__t.sel_1.spv", userT) - SPIRV_KEY_TEST("k_f", "Debug/k_f__f.min_1.17549435e-38.max_3.40282347e+38.neg_-1.00000000e+00.exp_1.25000000e-01.spv", userF) - SPIRV_KEY_TEST("k_d", "Debug/k_d__d.min_2.2250738585072010e-308.max_1.7976931348623165e+308.neg_-1.0000000000000000e+00.exp_1.2500000000000000e-01.spv", userD) - SPIRV_KEY_TEST("k_mix", "Debug/k_mix__m.md_7.en_1.sc_1.00000000e+00__limits.maxImageDimension2D_16384__features.shaderCullDistance_1.spv", userMix, limits, features) + SPIRV_KEY_TEST("k_plain", NBL_SPIRV_CFG_PREFIX "17607079465834866896.spv") + SPIRV_KEY_TEST("k_ints", NBL_SPIRV_CFG_PREFIX "14243079605119175996.spv", userI) + SPIRV_KEY_TEST("k_two", NBL_SPIRV_CFG_PREFIX "1951476947873668308.spv", userT) + SPIRV_KEY_TEST("k_f", NBL_SPIRV_CFG_PREFIX "13139524696082068358.spv", userF) + SPIRV_KEY_TEST("k_d", NBL_SPIRV_CFG_PREFIX "6202300474512380728.spv", userD) + SPIRV_KEY_TEST("k_mix", NBL_SPIRV_CFG_PREFIX "4015040960322118342.spv", userMix, limits, features) #undef SPIRV_KEY_TEST if (!ok) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66b82f37f..645e21deb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ if(NBL_BUILD_EXAMPLES) add_subdirectory(70_FLIPFluids) add_subdirectory(71_RayTracingPipeline) add_subdirectory(72_CooperativeBinarySearch) + add_subdirectory(73_SpirvKeysTest) # add new examples *before* NBL_GET_ALL_TARGETS invocation, it gathers recursively all targets created so far in this subdirectory NBL_GET_ALL_TARGETS(TARGETS)