From 7970f630b63cbd435681b615cb355fb2b24bae48 Mon Sep 17 00:00:00 2001 From: MineBill Date: Wed, 9 Oct 2024 07:39:48 +0300 Subject: [PATCH] Switch to custom build of wgpu until passthrough PR is merged. https://github.com/gfx-rs/wgpu-native/pull/436 --- Editor/Editor.lua | 2 +- Fussion/Fussion.lua | 13 ++-- .../Source/Fussion/GPU/EnumConversions.cpp | 6 ++ Fussion/Source/Fussion/GPU/Enums.h | 7 ++ Fussion/Source/Fussion/GPU/GPU.cpp | 16 ++++- Fussion/Source/Fussion/GPU/GPU.h | 15 +++++ Fussion/Source/Fussion/Rendering/Renderer.cpp | 1 + Vendor.lua | 67 +++++++++++++++---- 8 files changed, 104 insertions(+), 23 deletions(-) diff --git a/Editor/Editor.lua b/Editor/Editor.lua index ca633d1c..9e8464cc 100644 --- a/Editor/Editor.lua +++ b/Editor/Editor.lua @@ -43,7 +43,7 @@ target "Editor" add_deps("Fussion", "argparse") -- We need an explicit link to glfw here to be able to build the glfw imgui backend. - add_packages("glfw", "wgpu-native", "meshoptimizer") + add_packages("glfw", "wgpu-native-custom", "meshoptimizer") set_pcxxheader("Source/EditorPCH.h") diff --git a/Fussion/Fussion.lua b/Fussion/Fussion.lua index 4e1876b3..bbc63c26 100644 --- a/Fussion/Fussion.lua +++ b/Fussion/Fussion.lua @@ -1,4 +1,7 @@ add_requires("wgpu-native") +add_requires("wgpu-native-custom") +add_requires("spirv-cross", "shaderc") +add_requires("slang", {config = {slang_glslang = true}}) target("Fussion") set_kind("static") @@ -10,8 +13,6 @@ target("Fussion") "Source/**.cpp", "Source/**.c", "Impl/**.cpp" - - -- "Vendor/tracy/public/TracyClient.cpp" ) if is_plat("windows") then add_files("Platform/Windows/**.cpp") @@ -36,7 +37,10 @@ target("Fussion") add_includedirs("Vendor/entt/src", {public = true}) add_packages("fmt", "cpptrace", {public = true}) - add_packages("glfw", "VMA", "wgpu-native", "JoltPhysics") + add_packages("glfw", "wgpu-native-custom", "JoltPhysics") + + add_packages("spirv-cross", "shaderc", "slang") + add_deps("magic_enum") add_deps("glm", {public = true}) add_deps("AngelScript") @@ -63,9 +67,6 @@ target("Fussion") add_cxxflags("cl::/utf-8", {public = true}) elseif is_plat("linux") then add_defines("OS_LINUX", {public = true}) - add_links("shaderc_shared") - - add_packages("spirv-cross") elseif is_plat("macos") then add_defines("OS_MACOS") end diff --git a/Fussion/Source/Fussion/GPU/EnumConversions.cpp b/Fussion/Source/Fussion/GPU/EnumConversions.cpp index d153f2f9..adb2f64e 100644 --- a/Fussion/Source/Fussion/GPU/EnumConversions.cpp +++ b/Fussion/Source/Fussion/GPU/EnumConversions.cpp @@ -29,7 +29,11 @@ namespace Fussion::GPU { return WGPUFeatureName_Float32Filterable; case Feature::PipelineStatistics: return CAST(WGPUFeatureName, WGPUNativeFeature_PipelineStatisticsQuery); +#ifdef WGPU_LOCAL + case Feature::SpirVPassthrough: + return CAST(WGPUFeatureName, WGPUNativeFeature_SpirvShaderPassthrough); } +#endif UNREACHABLE; } @@ -217,6 +221,8 @@ namespace Fussion::GPU { auto ToWGPU(ShaderStageFlags flags) -> WGPUShaderStageFlags { WGPUShaderStageFlags result = 0; + if (flags.test(ShaderStage::None)) + result |= WGPUShaderStage_None; if (flags.test(ShaderStage::Vertex)) result |= WGPUShaderStage_Vertex; if (flags.test(ShaderStage::Fragment)) diff --git a/Fussion/Source/Fussion/GPU/Enums.h b/Fussion/Source/Fussion/GPU/Enums.h index b6f92583..39afd82f 100644 --- a/Fussion/Source/Fussion/GPU/Enums.h +++ b/Fussion/Source/Fussion/GPU/Enums.h @@ -2,6 +2,8 @@ #include #include +#define WGPU_LOCAL + namespace Fussion::GPU { enum class BackendRenderer { Vulkan, @@ -14,6 +16,10 @@ namespace Fussion::GPU { TimestampQuery, PipelineStatistics, Float32Filterable, + +#ifdef WGPU_LOCAL + SpirVPassthrough, +#endif }; // enum class QueryType { @@ -74,6 +80,7 @@ namespace Fussion::GPU { BITFLAGS(TextureUsage); enum class ShaderStage { + None = 0, Vertex = 1 << 0, Fragment = 1 << 1, Compute = 1 << 2, diff --git a/Fussion/Source/Fussion/GPU/GPU.cpp b/Fussion/Source/Fussion/GPU/GPU.cpp index 2224403c..0cc08c0a 100644 --- a/Fussion/Source/Fussion/GPU/GPU.cpp +++ b/Fussion/Source/Fussion/GPU/GPU.cpp @@ -1045,6 +1045,18 @@ namespace Fussion::GPU { return ShaderModule { module, spec }; } +#ifdef WGPU_DEV + auto Device::CreateShaderModuleSpirV(SpirVShaderSpec const& spec) const -> ShaderModule + { + WGPUShaderModuleDescriptorSpirV desc; + desc.label = spec.Label.ValueOr("SpirVShaderModule"sv).data(); + desc.sourceSize = CAST(u32, spec.Data.size()); + desc.source = spec.Data.data(); + auto module = wgpuDeviceCreateShaderModuleSpirV(CAST(WGPUDevice, Handle), &desc); + return ShaderModule { module }; + } +#endif + auto Device::CreatePipelineLayout(PipelineLayoutSpec const& spec) const -> PipelineLayout { std::vector layouts {}; @@ -1093,7 +1105,7 @@ namespace Fussion::GPU { WGPUVertexState vertex { .nextInChain = nullptr, .module = vert_module.As(), - .entryPoint = vert_module.Spec.VertexEntryPoint.data(), + .entryPoint = spec.VertexEntryPointOverride.ValueOr(vert_module.Spec.VertexEntryPoint).data(), .constantCount = 0, .constants = nullptr, .bufferCount = CAST(u32, vertex_buffer_layouts.size()), @@ -1127,7 +1139,7 @@ namespace Fussion::GPU { if (spec.Fragment.HasValue()) { fragment.module = frag_module.As(); - fragment.entryPoint = frag_module.Spec.FragmentEntryPoint.data(); + fragment.entryPoint = spec.FragmentEntryPointOverride.ValueOr(frag_module.Spec.FragmentEntryPoint).data(); fragment.constantCount = 0; fragment.constants = nullptr; // Resize to a max of spec.Fragment.Targets.size() to prevent reallocations diff --git a/Fussion/Source/Fussion/GPU/GPU.h b/Fussion/Source/Fussion/GPU/GPU.h index 983dcc4c..356700ee 100644 --- a/Fussion/Source/Fussion/GPU/GPU.h +++ b/Fussion/Source/Fussion/GPU/GPU.h @@ -13,6 +13,8 @@ #include #include +#define WGPU_DEV + // TODO: Add tests for this template struct Range { @@ -430,6 +432,11 @@ namespace Fussion::GPU { std::string_view FragmentEntryPoint {}; }; + struct SpirVShaderSpec { + Maybe Label {}; + std::span Data {}; + }; + struct ShaderModule final : GPUHandle { using GPUHandle::GPUHandle; @@ -438,6 +445,7 @@ namespace Fussion::GPU { /// Vertex inputs (attributes) to shaders. struct VertexAttribute { + std::string Name {}; /// Format of the input ElementType Type {}; /// Byte offset of the start of the input @@ -581,6 +589,10 @@ namespace Fussion::GPU { Maybe DepthStencil {}; MultiSampleState MultiSample {}; Maybe Fragment {}; + /// Used if the shader module is a SpirV binary. + Maybe VertexEntryPointOverride {}; + /// Used if the shader module is a SpirV binary. + Maybe FragmentEntryPointOverride {}; // MutliView // Cache }; @@ -754,6 +766,9 @@ namespace Fussion::GPU { [[nodiscard]] auto CreateQuerySet(QuerySetSpec const& spec) const -> QuerySet; [[nodiscard]] auto CreateShaderModule(ShaderModuleSpec const& spec) const -> ShaderModule; +#ifdef WGPU_DEV + [[nodiscard]] auto CreateShaderModuleSpirV(SpirVShaderSpec const& spec) const -> ShaderModule; +#endif [[nodiscard]] auto CreatePipelineLayout(PipelineLayoutSpec const& spec) const -> PipelineLayout; [[nodiscard]] auto CreateRenderPipeline(ShaderModule const& vert_module, ShaderModule const& frag_module, RenderPipelineSpec const& spec) const -> RenderPipeline; diff --git a/Fussion/Source/Fussion/Rendering/Renderer.cpp b/Fussion/Source/Fussion/Rendering/Renderer.cpp index de35c7fa..84f48fd9 100644 --- a/Fussion/Source/Fussion/Rendering/Renderer.cpp +++ b/Fussion/Source/Fussion/Rendering/Renderer.cpp @@ -33,6 +33,7 @@ namespace Fussion { .RequiredFeatures = { GPU::Feature::Float32Filterable, GPU::Feature::TimestampQuery, + GPU::Feature::SpirVPassthrough, } }; diff --git a/Vendor.lua b/Vendor.lua index a2f0b309..7767072e 100644 --- a/Vendor.lua +++ b/Vendor.lua @@ -195,9 +195,6 @@ package("wgpu-native") elseif is_plat("linux") and is_arch("x86_64") then add_urls("https://github.com/gfx-rs/wgpu-native/releases/download/$(version)/wgpu-linux-x86_64-release.zip", {version = function(version) return version:gsub("%+", ".") end}) add_versions("v22.1.0+5", "851984418f237aae593cda2a6f44a03afc1cc6e444662222ed2f9f6bc4c776fc") - elseif is_plat("macosx") and is_arch("x86_64") then - add_urls("https://github.com/gfx-rs/wgpu-native/releases/download/$(version)/wgpu-macos-x86_64-release.zip", {version = function(version) return version:gsub("%+", ".") end}) - add_versions("v22.1.0+5", "1488fc2fb19b156266f0b50ef026d677a261ae2dc30a13d6624f0ff701b489e7") end if is_plat("windows") then @@ -218,14 +215,7 @@ package("wgpu-native") end end) - on_load("macosx", function (package) - if not package:config("shared") then - package:add("syslinks", "objc") - package:add("frameworks", "Metal", "QuartzCore") - end - end) - - on_install("windows|x64", "windows|x86", "linux|arm64-v8a", "linux|x86_64", "macosx|x86_64", "macosx|arm64", function (package) + on_install("windows|x64", "windows|x86", "linux|arm64-v8a", "linux|x86_64", function (package) os.cp("include/**.h", package:installdir("include", "webgpu")) if package:is_plat("windows") then if package:config("shared") then @@ -241,9 +231,58 @@ package("wgpu-native") else os.cp("lib/libwgpu_native.a", package:installdir("lib")) end - elseif package:is_plat("macosx") then + end + end) + + on_test(function (package) + assert(package:has_cfuncs("wgpuCreateInstance", {includes = "wgpu.h"})) + end) +package_end() + +package("wgpu-native-custom") + set_homepage("https://github.com/MineBill/wgpu-native") + set_description("Native WebGPU implementation based on wgpu-core") + set_license("Apache-2.0") + + if is_plat("windows") and is_arch("x64") then + add_urls("https://github.com/MineBill/wgpu-native/releases/download/$(version)/wgpu-windows-x86_64-msvc-release.zip", {version = function(version) return version:gsub("%+", ".") end}) + add_versions("v22.1.0+5-custom", "afc9c5e9d4fe1625e2e1c906b8b7ef950b17605e1ada25d8d834adeb928eeb53") + elseif is_plat("linux") and is_arch("x86_64") then + add_urls("https://github.com/MineBill/wgpu-native/releases/download/$(version)/wgpu-linux-x86_64-release.zip", {version = function(version) return version:gsub("%+", ".") end}) + add_versions("v22.1.0+5-custom", "d28938ff05d641e61872953010e9a960cac5c60fa0fbfe70a9368399c7e423b7") + end + + if is_plat("windows") then + add_configs("vs_runtime", {description = "Set vs compiler runtime.", default = "MD", readonly = true}) + end + + add_includedirs("include", "include/webgpu") + + on_load("windows", function (package) + if not package:config("shared") then + package:add("syslinks", "Advapi32", "bcrypt", "d3dcompiler", "NtDll", "User32", "Userenv", "WS2_32", "Gdi32", "Opengl32", "OleAut32", "Ole32") + end + end) + + on_load("linux", function (package) + if not package:config("shared") then + package:add("syslinks", "dl", "pthread") + end + end) + + on_install("windows|x64", "windows|x86", "linux|arm64-v8a", "linux|x86_64", function (package) + os.cp("include/**.h", package:installdir("include", "webgpu")) + if package:is_plat("windows") then + if package:config("shared") then + os.cp("lib/wgpu_native.dll", package:installdir("bin")) + os.cp("lib/wgpu_native.pdb", package:installdir("bin")) + os.cp("lib/wgpu_native.dll.lib", package:installdir("lib")) + else + os.cp("lib/wgpu_native.lib", package:installdir("lib")) + end + elseif package:is_plat("linux") then if package:config("shared") then - os.cp("lib/libwgpu_native.dylib", package:installdir("bin")) + os.cp("lib/libwgpu_native.so", package:installdir("bin")) else os.cp("lib/libwgpu_native.a", package:installdir("lib")) end @@ -253,4 +292,4 @@ package("wgpu-native") on_test(function (package) assert(package:has_cfuncs("wgpuCreateInstance", {includes = "wgpu.h"})) end) -package_end() +package_end() \ No newline at end of file