From 210febaf2845d58bfcc7fd7e70718e3ae0a01d24 Mon Sep 17 00:00:00 2001 From: Matthias Huerbe Date: Tue, 7 Jul 2026 09:52:04 +0200 Subject: [PATCH 1/3] fixed wgpu unit tests not running because of missing dlls with prebuild on windows --- unittests/webgpu_engine/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/unittests/webgpu_engine/CMakeLists.txt b/unittests/webgpu_engine/CMakeLists.txt index 4193edd9c..7432e1bbc 100644 --- a/unittests/webgpu_engine/CMakeLists.txt +++ b/unittests/webgpu_engine/CMakeLists.txt @@ -47,5 +47,18 @@ if (WIN32 AND NOT EMSCRIPTEN) COMMENT "Copying SDL2.dll to unittests" ) endif() + + # Copy DXC DLLs (dxcompiler.dll, dxil.dll) required by prebuilt Dawn's D3D12 backend + include("${CMAKE_SOURCE_DIR}/cmake/alp_provide_dawn_dxc.cmake") + alp_provide_dawn_dxc_dlls(ALP_DAWN_DXC_DLLS) + foreach(ALP_DAWN_DXC_DLL IN LISTS ALP_DAWN_DXC_DLLS) + get_filename_component(ALP_DAWN_DXC_DLL_NAME "${ALP_DAWN_DXC_DLL}" NAME) + add_custom_command(TARGET unittests_webgpu_engine POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${ALP_DAWN_DXC_DLL}" + "$" + COMMENT "Copying ${ALP_DAWN_DXC_DLL_NAME} to unittests" + ) + endforeach() endif() From 171486281c4f359cfd138bda40ecb82194ea2c31 Mon Sep 17 00:00:00 2001 From: Matthias Huerbe Date: Tue, 7 Jul 2026 10:22:11 +0200 Subject: [PATCH 2/3] added utilities to create WGPUStringViews from std::string, std::string_view & const char* - added unit tests for the WGPUStringViews utilities --- unittests/webgpu_engine/CMakeLists.txt | 1 + unittests/webgpu_engine/test_wgpu_string.cpp | 99 ++++++++++++++++++++ webgpu/base/CMakeLists.txt | 2 +- webgpu/base/wgpu_string.h | 39 ++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 unittests/webgpu_engine/test_wgpu_string.cpp create mode 100644 webgpu/base/wgpu_string.h diff --git a/unittests/webgpu_engine/CMakeLists.txt b/unittests/webgpu_engine/CMakeLists.txt index 7432e1bbc..9fe24a890 100644 --- a/unittests/webgpu_engine/CMakeLists.txt +++ b/unittests/webgpu_engine/CMakeLists.txt @@ -24,6 +24,7 @@ alp_add_unittest(unittests_webgpu_engine UnittestWebgpuContext.h UnittestWebgpuContext.cpp test_GpuShaderFunctions.cpp test_ShaderPreprocessor.cpp + test_wgpu_string.cpp ) target_link_libraries(unittests_webgpu_engine PUBLIC webgpu_engine) diff --git a/unittests/webgpu_engine/test_wgpu_string.cpp b/unittests/webgpu_engine/test_wgpu_string.cpp new file mode 100644 index 000000000..9c1012c4e --- /dev/null +++ b/unittests/webgpu_engine/test_wgpu_string.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include + +using namespace webgpu; + +static_assert(""_wsv.length == 0); +static_assert("hello"_wsv.length == 5); +static_assert("a\0b"_wsv.length == 3); + +TEST_CASE("wsv literal - construct", "[wgpu_string]") +{ + auto str = "hello"_wsv; + CHECK(str.length == 5); + CHECK(std::memcmp(str.data, "hello", 5) == 0); +} + +TEST_CASE("wsv literal - empty", "[wgpu_string]") +{ + CHECK(""_wsv.length == 0); +} + +TEST_CASE("wsv literal - keeps embedded NUL", "[wgpu_string]") +{ + auto str = "a\0b"_wsv; + CHECK(str.length == 3); + CHECK(std::memcmp(str.data, "a\0b", 3) == 0); +} + +TEST_CASE("wsv() - from string_view / string / const char*", "[wgpu_string]") +{ + std::string_view sv = "hello"; + CHECK(wsv(sv) == "hello"_wsv); + + std::string str = "world"; + CHECK(wsv(str) == "world"_wsv); + + CHECK(wsv("literal") == "literal"_wsv); + + CHECK(wsv(std::string_view("hello", 3)).length == 3); + CHECK(wsv(std::string_view("hello", 3)) == "hel"_wsv); +} + +TEST_CASE("wsv() - empty", "[wgpu_string]") +{ + CHECK(wsv(std::string_view {}).length == 0); + CHECK(wsv("") == ""_wsv); +} + +TEST_CASE("wsv_length - explicit length returned as-is", "[wgpu_string]") +{ + CHECK(wsv_length(WGPUStringView { "hello", 5 }) == 5); + CHECK(wsv_length(WGPUStringView { "hello", 2 }) == 2); + CHECK(wsv_length(WGPUStringView { "abc", 0 }) == 0); +} + +TEST_CASE("wsv_length - WGPU_STRLEN sentinel uses strlen", "[wgpu_string]") +{ + CHECK(wsv_length(WGPUStringView { "hello", WGPU_STRLEN }) == 5); + CHECK(wsv_length(WGPUStringView { "", WGPU_STRLEN }) == 0); +} + +TEST_CASE("wsv_length - sentinel with null data is 0", "[wgpu_string]") +{ + CHECK(wsv_length(WGPUStringView { nullptr, WGPU_STRLEN }) == 0); +} + +TEST_CASE("operator== - equal content", "[wgpu_string]") +{ + CHECK("hello"_wsv == WGPUStringView { "hello", 5 }); + CHECK("hello"_wsv == WGPUStringView { "hello", WGPU_STRLEN }); +} + +TEST_CASE("operator== - different content, same length", "[wgpu_string]") +{ + CHECK_FALSE("hello"_wsv == "world"_wsv); + CHECK("hello"_wsv != "world"_wsv); +} + +TEST_CASE("operator== - different length", "[wgpu_string]") +{ + CHECK_FALSE("hello"_wsv == "hell"_wsv); + CHECK_FALSE("hello"_wsv == "hello!"_wsv); +} + +TEST_CASE("operator== - empty views", "[wgpu_string]") +{ + CHECK(""_wsv == ""_wsv); + CHECK(WGPUStringView { nullptr, WGPU_STRLEN } == ""_wsv); + CHECK_FALSE(""_wsv == "x"_wsv); +} + +TEST_CASE("operator== - NUL-safe, not strlen-based", "[wgpu_string]") +{ + CHECK("a\0b"_wsv == WGPUStringView { "a\0b", 3 }); + CHECK_FALSE("a\0b"_wsv == WGPUStringView { "a\0c", 3 }); +} diff --git a/webgpu/base/CMakeLists.txt b/webgpu/base/CMakeLists.txt index 981626486..ac966abd2 100644 --- a/webgpu/base/CMakeLists.txt +++ b/webgpu/base/CMakeLists.txt @@ -60,7 +60,7 @@ set(SOURCES Context.h RenderResourceRegistry.h RenderResourceRegistry.cpp gpu_utils.h gpu_utils.cpp - + wgpu_string.h webgpu_interface.hpp webgpu_interface.cpp) add_library(webgpu STATIC ${SOURCES}) diff --git a/webgpu/base/wgpu_string.h b/webgpu/base/wgpu_string.h new file mode 100644 index 000000000..428039ba6 --- /dev/null +++ b/webgpu/base/wgpu_string.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include // std::strlen & std::memcmp +#include + +namespace webgpu +{ + +// utility to create a webgpu string view from the string literal +inline constexpr WGPUStringView operator""_wsv(const char* s, size_t l) noexcept +{ + return { s, l }; +} + +// utility to create a webgpu string view from std::string, std::string_view, const char* +inline constexpr WGPUStringView wsv(std::string_view s) noexcept +{ + return { s.data(), s.size() }; +} + +// length of a possibly WGPU_STRLEN-sentinel string view +inline constexpr size_t wsv_length(WGPUStringView s) noexcept +{ + return (s.length == WGPU_STRLEN) ? (s.data ? std::strlen(s.data) : 0) : s.length; +} + +// content equality of two string views +inline constexpr bool operator==(WGPUStringView a, WGPUStringView b) noexcept +{ + size_t na = wsv_length(a), nb = wsv_length(b); + return na == nb && (na == 0 || std::memcmp(a.data, b.data, na) == 0); +} + +} // namespace webgpu + +// usable by include +using webgpu::operator""_wsv; +using webgpu::operator==; From 135e97c85219a65af89f7ea99ab2d1564808110e Mon Sep 17 00:00:00 2001 From: Matthias Huerbe Date: Tue, 7 Jul 2026 11:04:31 +0000 Subject: [PATCH 3/3] updated copyrigh notice --- unittests/webgpu_engine/test_wgpu_string.cpp | 18 ++++++++++++++++++ webgpu/base/wgpu_string.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/unittests/webgpu_engine/test_wgpu_string.cpp b/unittests/webgpu_engine/test_wgpu_string.cpp index 9c1012c4e..5e5437460 100644 --- a/unittests/webgpu_engine/test_wgpu_string.cpp +++ b/unittests/webgpu_engine/test_wgpu_string.cpp @@ -1,3 +1,21 @@ +/***************************************************************************** + * weBIGeo + * Copyright (C) 2026 Matthias Huerbe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + #include #include #include diff --git a/webgpu/base/wgpu_string.h b/webgpu/base/wgpu_string.h index 428039ba6..05ebff521 100644 --- a/webgpu/base/wgpu_string.h +++ b/webgpu/base/wgpu_string.h @@ -1,3 +1,21 @@ +/***************************************************************************** + * weBIGeo + * Copyright (C) 2026 Matthias Huerbe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ + #pragma once #include