From baa83137f5b74f5f8602ed95b99dccaf19de0703 Mon Sep 17 00:00:00 2001 From: dav Date: Sat, 23 Mar 2024 15:09:21 -0700 Subject: [PATCH 01/19] Implement initial init for WebGPU on linuxbsd x11 --- SConstruct | 9 +- drivers/SCsub | 2 + drivers/webgpu/SCsub | 24 + .../rendering_context_driver_webgpu.cpp | 117 ++ .../webgpu/rendering_context_driver_webgpu.h | 46 + main/main.cpp | 3 + platform/linuxbsd/detect.py | 3 + .../wayland/display_server_wayland.cpp | 2 +- platform/linuxbsd/x11/SCsub | 3 + platform/linuxbsd/x11/display_server_x11.cpp | 19 +- platform/linuxbsd/x11/display_server_x11.h | 4 + .../rendering_context_driver_webgpu_x11.cpp | 43 + .../x11/rendering_context_driver_webgpu_x11.h | 26 + thirdparty/wgpu/commit-sha | 1 + thirdparty/wgpu/webgpu.h | 1806 +++++++++++++++++ thirdparty/wgpu/wgpu.h | 265 +++ 16 files changed, 2367 insertions(+), 6 deletions(-) create mode 100644 drivers/webgpu/SCsub create mode 100644 drivers/webgpu/rendering_context_driver_webgpu.cpp create mode 100644 drivers/webgpu/rendering_context_driver_webgpu.h create mode 100644 platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.cpp create mode 100644 platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.h create mode 100644 thirdparty/wgpu/commit-sha create mode 100644 thirdparty/wgpu/webgpu.h create mode 100644 thirdparty/wgpu/wgpu.h diff --git a/SConstruct b/SConstruct index 753cea40e33c..75042eaa2451 100644 --- a/SConstruct +++ b/SConstruct @@ -190,11 +190,12 @@ opts.Add(EnumVariable("precision", "Set the floating-point precision level", "si opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True)) opts.Add(BoolVariable("brotli", "Enable Brotli for decompresson and WOFF2 fonts support", True)) opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) -opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True)) -opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True)) +opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", False)) +opts.Add(BoolVariable("webgpu", "Enable the webgpu rendering driver", True)) +opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", False)) opts.Add(BoolVariable("d3d12", "Enable the Direct3D 12 rendering driver (Windows only)", False)) -opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True)) -opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True)) +opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", False)) +opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", False)) opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", True)) opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) diff --git a/drivers/SCsub b/drivers/SCsub index 9c8b16d3e594..62d781864758 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -23,6 +23,8 @@ SConscript("coremidi/SCsub") SConscript("winmidi/SCsub") # Graphics drivers +if env["webgpu"]: + SConscript("webgpu/SCsub") if env["vulkan"]: SConscript("vulkan/SCsub") if env["d3d12"]: diff --git a/drivers/webgpu/SCsub b/drivers/webgpu/SCsub new file mode 100644 index 000000000000..8e98023ed50b --- /dev/null +++ b/drivers/webgpu/SCsub @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +Import("env") + +thirdparty_obj = [] +thirdparty_dir = "#thirdparty/wgpu" + +# Use WebGpu headers +env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include"]) + +env.drivers_sources += thirdparty_obj + +# Godot source files + +driver_obj = [] + +env.add_source_files(driver_obj, "*.cpp") +env.drivers_sources += driver_obj + +# Needed to force rebuilding the driver files when the thirdparty code is updated. +env.Depends(driver_obj, thirdparty_obj) + +env.Prepend(LIBS=["wgpu_native"]) +env.Prepend(LIBPATH=[thirdparty_dir]) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp new file mode 100644 index 000000000000..c755f1df40ed --- /dev/null +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -0,0 +1,117 @@ +#include "rendering_context_driver_webgpu.h" +#include "core/error/error_macros.h" +#include + +static void handleRequestAdapter(WGPURequestAdapterStatus status, + WGPUAdapter adapter, char const *message, + void *userdata) { + RenderingContextDriverWebGpu *context = (RenderingContextDriverWebGpu *)userdata; + context->adapter_set( + adapter); + ERR_FAIL_COND_V_MSG( + status != WGPURequestAdapterStatus_Success, (void)0, + vformat("Failed to get wgpu adapter: %s", message)); +} + +RenderingContextDriverWebGpu::RenderingContextDriverWebGpu() { +} + +RenderingContextDriverWebGpu::~RenderingContextDriverWebGpu() { +} + +Error RenderingContextDriverWebGpu::initialize() { + instance = wgpuCreateInstance(nullptr); + + WGPURequestAdapterOptions adapter_options = {}; + wgpuInstanceRequestAdapter(instance, + &adapter_options, + handleRequestAdapter, this); + return OK; +} + +const RenderingContextDriver::Device &RenderingContextDriverWebGpu::device_get(uint32_t p_device_index) const { + DEV_ASSERT(false) + // TODO +} + +uint32_t RenderingContextDriverWebGpu::device_get_count() const { + DEV_ASSERT(false) + // TODO +} + +bool RenderingContextDriverWebGpu::device_supports_present(uint32_t p_device_index, SurfaceID p_surface) const { + DEV_ASSERT(false) + // TODO +} + +RenderingDeviceDriver *RenderingContextDriverWebGpu::driver_create() { + DEV_ASSERT(false) + // TODO +} + +void RenderingContextDriverWebGpu::driver_free(RenderingDeviceDriver *p_driver) { + DEV_ASSERT(false) + // TODO +} + +RenderingContextDriver::SurfaceID RenderingContextDriverWebGpu::surface_create(const void *p_platform_data) { + DEV_ASSERT(false && "Surface creation should not be called on the platform-agnostic version of the driver."); + return SurfaceID(); +} + +void RenderingContextDriverWebGpu::surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) { + DEV_ASSERT(false) + // TODO +} + +void RenderingContextDriverWebGpu::surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) { + DEV_ASSERT(false) + // TODO +} + +DisplayServer::VSyncMode RenderingContextDriverWebGpu::surface_get_vsync_mode(SurfaceID p_surface) const { + DEV_ASSERT(false) + // TODO + return DisplayServer::VSyncMode::VSYNC_DISABLED; +} + +uint32_t RenderingContextDriverWebGpu::surface_get_width(SurfaceID p_surface) const { + DEV_ASSERT(false) + // TODO + return 0; +} + +uint32_t RenderingContextDriverWebGpu::surface_get_height(SurfaceID p_surface) const { + DEV_ASSERT(false) + // TODO + return 0; +} + +void RenderingContextDriverWebGpu::surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) { + DEV_ASSERT(false) + // TODO +} + +bool RenderingContextDriverWebGpu::surface_get_needs_resize(SurfaceID p_surface) const { + DEV_ASSERT(false) + // TODO + return false; +} + +void RenderingContextDriverWebGpu::surface_destroy(SurfaceID p_surface) { + DEV_ASSERT(false) + // TODO +} +bool RenderingContextDriverWebGpu::is_debug_utils_enabled() const { + DEV_ASSERT(false) + // TODO + return false; +} + +void RenderingContextDriverWebGpu::adapter_set(WGPUAdapter new_adapter) { + adapter = new_adapter; +} + +WGPUInstance RenderingContextDriverWebGpu::instance_get() const { + return instance; +} diff --git a/drivers/webgpu/rendering_context_driver_webgpu.h b/drivers/webgpu/rendering_context_driver_webgpu.h new file mode 100644 index 000000000000..4b7b318d1acc --- /dev/null +++ b/drivers/webgpu/rendering_context_driver_webgpu.h @@ -0,0 +1,46 @@ +#ifndef RENDERING_CONTEXT_DRIVER_WGPU_H +#define RENDERING_CONTEXT_DRIVER_WGPU_H + +#include "servers/rendering/rendering_context_driver.h" + +#include + +class RenderingContextDriverWebGpu : public RenderingContextDriver { +private: + WGPUInstance instance = nullptr; + WGPUAdapter adapter = nullptr; +public: + virtual Error initialize() override; + virtual const RenderingContextDriver::Device &device_get(uint32_t p_device_index) const override; + virtual uint32_t device_get_count() const override; + virtual bool device_supports_present(uint32_t p_device_index, SurfaceID p_surface) const override; + virtual RenderingDeviceDriver *driver_create() override; + virtual void driver_free(RenderingDeviceDriver *p_driver) override; + virtual SurfaceID surface_create(const void *p_platform_data) override; + virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) override; + virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) override; + virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const override; + virtual uint32_t surface_get_width(SurfaceID p_surface) const override; + virtual uint32_t surface_get_height(SurfaceID p_surface) const override; + virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) override; + virtual bool surface_get_needs_resize(SurfaceID p_surface) const override; + virtual void surface_destroy(SurfaceID p_surface) override; + virtual bool is_debug_utils_enabled() const override; + + RenderingContextDriverWebGpu(); + virtual ~RenderingContextDriverWebGpu() override; + + void adapter_set(WGPUAdapter new_adapter); + + struct Surface { + WGPUSurface surface; + uint32_t width = 0; + uint32_t height = 0; + DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED; + bool needs_resize = false; + }; + + WGPUInstance instance_get() const; +}; + +#endif // RENDERING_CONTEXT_DRIVER_WGPU_H diff --git a/main/main.cpp b/main/main.cpp index 9215f2e848ea..0fc38be39e8e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2102,6 +2102,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph bool valid_combination = false; Vector available_drivers; if (rendering_method == "forward_plus" || rendering_method == "mobile") { +#ifdef WEBGPU_ENABLED + available_drivers.push_back("webgpu"); +#endif #ifdef VULKAN_ENABLED available_drivers.push_back("vulkan"); #endif diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 27dec73b655e..b32f50accad1 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -472,6 +472,9 @@ def configure(env: "SConsEnvironment"): env.Append(CPPDEFINES=["WAYLAND_ENABLED"]) env.Append(LIBS=["rt"]) # Needed by glibc, used by _allocate_shm_file + if env["webgpu"]: + env.Append(CPPDEFINES=["WEBGPU_ENABLED", "RD_ENABLED"]) + if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"]) if not env["use_volk"]: diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 80b6029c9d8f..4e873b18322b 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -39,7 +39,7 @@ #define DEBUG_LOG_WAYLAND(...) #endif -#ifdef VULKAN_ENABLED +#ifdef RD_ENABLED #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif diff --git a/platform/linuxbsd/x11/SCsub b/platform/linuxbsd/x11/SCsub index 75fe584ad58c..fd40fb7e6458 100644 --- a/platform/linuxbsd/x11/SCsub +++ b/platform/linuxbsd/x11/SCsub @@ -20,6 +20,9 @@ if env["use_sowrap"]: ] ) +if env["webgpu"]: + source_files.append("rendering_context_driver_webgpu_x11.cpp") + if env["vulkan"]: source_files.append("rendering_context_driver_vulkan_x11.cpp") diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 34aa15abbb7a..93b8173b2078 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -42,7 +42,7 @@ #include "drivers/png/png_driver_common.h" #include "main/main.h" -#if defined(VULKAN_ENABLED) +#if defined(RD_ENABLED) #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif @@ -5310,6 +5310,9 @@ DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_wind Vector DisplayServerX11::get_rendering_drivers_func() { Vector drivers; +#ifdef WEBGPU_ENABLED + drivers.push_back("webgpu"); +#endif #ifdef VULKAN_ENABLED drivers.push_back("vulkan"); #endif @@ -5638,10 +5641,19 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V #if defined(RD_ENABLED) if (rendering_context) { union { +#ifdef WEBGPU_ENABLED + RenderingContextDriverWebGpuX11::WindowPlatformData webgpu; +#endif #ifdef VULKAN_ENABLED RenderingContextDriverVulkanX11::WindowPlatformData vulkan; #endif } wpd; +#ifdef WEBGPU_ENABLED + if (rendering_driver == "webgpu") { + wpd.webgpu.window = wd.x11_window; + wpd.webgpu.display = x11_display; + } +#endif #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { wpd.vulkan.window = wd.x11_window; @@ -6054,6 +6066,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode bool driver_found = false; #if defined(RD_ENABLED) +#if defined(WEBGPU_ENABLED) + if (rendering_driver == "webgpu") { + rendering_context = memnew(RenderingContextDriverWebGpuX11); + } +#endif #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { rendering_context = memnew(RenderingContextDriverVulkanX11); diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 715a8e48e662..0594af1e2efd 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -60,6 +60,10 @@ #if defined(RD_ENABLED) #include "servers/rendering/rendering_device.h" +#if defined(WEBGPU_ENABLED) +#include "x11/rendering_context_driver_webgpu_x11.h" +#endif + #if defined(VULKAN_ENABLED) #include "x11/rendering_context_driver_vulkan_x11.h" #endif diff --git a/platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.cpp b/platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.cpp new file mode 100644 index 000000000000..59a4208e9d78 --- /dev/null +++ b/platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.cpp @@ -0,0 +1,43 @@ +#ifdef WEBGPU_ENABLED + +#include "rendering_context_driver_webgpu_x11.h" + +RenderingContextDriver::SurfaceID RenderingContextDriverWebGpuX11::surface_create(const void *p_platform_data) { + const WindowPlatformData *wpd = (const WindowPlatformData *)(p_platform_data); + + const WGPUSurfaceDescriptorFromXlibWindow xlib_desc = + (const WGPUSurfaceDescriptorFromXlibWindow){ + .chain = + (const WGPUChainedStruct){ + .sType = WGPUSType_SurfaceDescriptorFromXlibWindow, + }, + .display = wpd->display, + .window = wpd->window, + }; + + WGPUSurfaceDescriptor surface_desc = + (WGPUSurfaceDescriptor){ + .nextInChain = + (const WGPUChainedStruct *)&xlib_desc + }; + + WGPUSurface wgpu_surface = wgpuInstanceCreateSurface( + instance_get(), + &surface_desc); + + ERR_FAIL_COND_V(!wgpu_surface, SurfaceID()); + + Surface *surface = memnew(Surface); + surface->surface = wgpu_surface; + return SurfaceID(surface); +} + +RenderingContextDriverWebGpuX11::RenderingContextDriverWebGpuX11() { + // Does nothing. +} + +RenderingContextDriverWebGpuX11::~RenderingContextDriverWebGpuX11() { + // Does nothing. +} + +#endif // WEBGPU_ENABLED diff --git a/platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.h b/platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.h new file mode 100644 index 000000000000..f5facba83ebc --- /dev/null +++ b/platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.h @@ -0,0 +1,26 @@ +#ifndef RENDERING_CONTEXT_DRIVER_WEBGPU_X11_H +#define RENDERING_CONTEXT_DRIVER_WEBGPU_X11_H + +#ifdef WEBGPU_ENABLED + +#include "drivers/webgpu/rendering_context_driver_webgpu.h" + +#include + +class RenderingContextDriverWebGpuX11 : public RenderingContextDriverWebGpu { +protected: + SurfaceID surface_create(const void *p_platform_data) override final; + +public: + struct WindowPlatformData { + ::Window window; + Display *display; + }; + + RenderingContextDriverWebGpuX11(); + ~RenderingContextDriverWebGpuX11(); +}; + +#endif // WEBGPU_ENABLED + +#endif // RENDERING_CONTEXT_DRIVER_WEBGPU_X11_H diff --git a/thirdparty/wgpu/commit-sha b/thirdparty/wgpu/commit-sha new file mode 100644 index 000000000000..591a41cddfd7 --- /dev/null +++ b/thirdparty/wgpu/commit-sha @@ -0,0 +1 @@ +v0.19.3.1 diff --git a/thirdparty/wgpu/webgpu.h b/thirdparty/wgpu/webgpu.h new file mode 100644 index 000000000000..d2533513583c --- /dev/null +++ b/thirdparty/wgpu/webgpu.h @@ -0,0 +1,1806 @@ +// BSD 3-Clause License +// +// Copyright (c) 2019, "WebGPU native" developers +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef WEBGPU_H_ +#define WEBGPU_H_ + +#if defined(WGPU_SHARED_LIBRARY) +# if defined(_WIN32) +# if defined(WGPU_IMPLEMENTATION) +# define WGPU_EXPORT __declspec(dllexport) +# else +# define WGPU_EXPORT __declspec(dllimport) +# endif +# else // defined(_WIN32) +# if defined(WGPU_IMPLEMENTATION) +# define WGPU_EXPORT __attribute__((visibility("default"))) +# else +# define WGPU_EXPORT +# endif +# endif // defined(_WIN32) +#else // defined(WGPU_SHARED_LIBRARY) +# define WGPU_EXPORT +#endif // defined(WGPU_SHARED_LIBRARY) + +#if !defined(WGPU_OBJECT_ATTRIBUTE) +#define WGPU_OBJECT_ATTRIBUTE +#endif +#if !defined(WGPU_ENUM_ATTRIBUTE) +#define WGPU_ENUM_ATTRIBUTE +#endif +#if !defined(WGPU_STRUCTURE_ATTRIBUTE) +#define WGPU_STRUCTURE_ATTRIBUTE +#endif +#if !defined(WGPU_FUNCTION_ATTRIBUTE) +#define WGPU_FUNCTION_ATTRIBUTE +#endif +#if !defined(WGPU_NULLABLE) +#define WGPU_NULLABLE +#endif + +#include +#include + +#define WGPU_ARRAY_LAYER_COUNT_UNDEFINED (0xffffffffUL) +#define WGPU_COPY_STRIDE_UNDEFINED (0xffffffffUL) +#define WGPU_LIMIT_U32_UNDEFINED (0xffffffffUL) +#define WGPU_LIMIT_U64_UNDEFINED (0xffffffffffffffffULL) +#define WGPU_MIP_LEVEL_COUNT_UNDEFINED (0xffffffffUL) +#define WGPU_QUERY_SET_INDEX_UNDEFINED (0xffffffffUL) +#define WGPU_WHOLE_MAP_SIZE SIZE_MAX +#define WGPU_WHOLE_SIZE (0xffffffffffffffffULL) + +typedef uint32_t WGPUFlags; +typedef uint32_t WGPUBool; + +typedef struct WGPUAdapterImpl* WGPUAdapter WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBindGroupImpl* WGPUBindGroup WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBindGroupLayoutImpl* WGPUBindGroupLayout WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUBufferImpl* WGPUBuffer WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUCommandBufferImpl* WGPUCommandBuffer WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUCommandEncoderImpl* WGPUCommandEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUComputePassEncoderImpl* WGPUComputePassEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUComputePipelineImpl* WGPUComputePipeline WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUDeviceImpl* WGPUDevice WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUInstanceImpl* WGPUInstance WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUPipelineLayoutImpl* WGPUPipelineLayout WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUQuerySetImpl* WGPUQuerySet WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUQueueImpl* WGPUQueue WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderBundleImpl* WGPURenderBundle WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderBundleEncoderImpl* WGPURenderBundleEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPURenderPipelineImpl* WGPURenderPipeline WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSamplerImpl* WGPUSampler WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUShaderModuleImpl* WGPUShaderModule WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUSurfaceImpl* WGPUSurface WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUTextureImpl* WGPUTexture WGPU_OBJECT_ATTRIBUTE; +typedef struct WGPUTextureViewImpl* WGPUTextureView WGPU_OBJECT_ATTRIBUTE; + +// Structure forward declarations +struct WGPUAdapterProperties; +struct WGPUBindGroupEntry; +struct WGPUBlendComponent; +struct WGPUBufferBindingLayout; +struct WGPUBufferDescriptor; +struct WGPUColor; +struct WGPUCommandBufferDescriptor; +struct WGPUCommandEncoderDescriptor; +struct WGPUCompilationMessage; +struct WGPUComputePassTimestampWrites; +struct WGPUConstantEntry; +struct WGPUExtent3D; +struct WGPUInstanceDescriptor; +struct WGPULimits; +struct WGPUMultisampleState; +struct WGPUOrigin3D; +struct WGPUPipelineLayoutDescriptor; +struct WGPUPrimitiveDepthClipControl; +struct WGPUPrimitiveState; +struct WGPUQuerySetDescriptor; +struct WGPUQueueDescriptor; +struct WGPURenderBundleDescriptor; +struct WGPURenderBundleEncoderDescriptor; +struct WGPURenderPassDepthStencilAttachment; +struct WGPURenderPassDescriptorMaxDrawCount; +struct WGPURenderPassTimestampWrites; +struct WGPURequestAdapterOptions; +struct WGPUSamplerBindingLayout; +struct WGPUSamplerDescriptor; +struct WGPUShaderModuleCompilationHint; +struct WGPUShaderModuleSPIRVDescriptor; +struct WGPUShaderModuleWGSLDescriptor; +struct WGPUStencilFaceState; +struct WGPUStorageTextureBindingLayout; +struct WGPUSurfaceCapabilities; +struct WGPUSurfaceConfiguration; +struct WGPUSurfaceDescriptor; +struct WGPUSurfaceDescriptorFromAndroidNativeWindow; +struct WGPUSurfaceDescriptorFromCanvasHTMLSelector; +struct WGPUSurfaceDescriptorFromMetalLayer; +struct WGPUSurfaceDescriptorFromWaylandSurface; +struct WGPUSurfaceDescriptorFromWindowsHWND; +struct WGPUSurfaceDescriptorFromXcbWindow; +struct WGPUSurfaceDescriptorFromXlibWindow; +struct WGPUSurfaceTexture; +struct WGPUTextureBindingLayout; +struct WGPUTextureDataLayout; +struct WGPUTextureViewDescriptor; +struct WGPUVertexAttribute; +struct WGPUBindGroupDescriptor; +struct WGPUBindGroupLayoutEntry; +struct WGPUBlendState; +struct WGPUCompilationInfo; +struct WGPUComputePassDescriptor; +struct WGPUDepthStencilState; +struct WGPUImageCopyBuffer; +struct WGPUImageCopyTexture; +struct WGPUProgrammableStageDescriptor; +struct WGPURenderPassColorAttachment; +struct WGPURequiredLimits; +struct WGPUShaderModuleDescriptor; +struct WGPUSupportedLimits; +struct WGPUTextureDescriptor; +struct WGPUVertexBufferLayout; +struct WGPUBindGroupLayoutDescriptor; +struct WGPUColorTargetState; +struct WGPUComputePipelineDescriptor; +struct WGPUDeviceDescriptor; +struct WGPURenderPassDescriptor; +struct WGPUVertexState; +struct WGPUFragmentState; +struct WGPURenderPipelineDescriptor; + +typedef enum WGPUAdapterType { + WGPUAdapterType_DiscreteGPU = 0x00000000, + WGPUAdapterType_IntegratedGPU = 0x00000001, + WGPUAdapterType_CPU = 0x00000002, + WGPUAdapterType_Unknown = 0x00000003, + WGPUAdapterType_Force32 = 0x7FFFFFFF +} WGPUAdapterType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUAddressMode { + WGPUAddressMode_Repeat = 0x00000000, + WGPUAddressMode_MirrorRepeat = 0x00000001, + WGPUAddressMode_ClampToEdge = 0x00000002, + WGPUAddressMode_Force32 = 0x7FFFFFFF +} WGPUAddressMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBackendType { + WGPUBackendType_Undefined = 0x00000000, + WGPUBackendType_Null = 0x00000001, + WGPUBackendType_WebGPU = 0x00000002, + WGPUBackendType_D3D11 = 0x00000003, + WGPUBackendType_D3D12 = 0x00000004, + WGPUBackendType_Metal = 0x00000005, + WGPUBackendType_Vulkan = 0x00000006, + WGPUBackendType_OpenGL = 0x00000007, + WGPUBackendType_OpenGLES = 0x00000008, + WGPUBackendType_Force32 = 0x7FFFFFFF +} WGPUBackendType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBlendFactor { + WGPUBlendFactor_Zero = 0x00000000, + WGPUBlendFactor_One = 0x00000001, + WGPUBlendFactor_Src = 0x00000002, + WGPUBlendFactor_OneMinusSrc = 0x00000003, + WGPUBlendFactor_SrcAlpha = 0x00000004, + WGPUBlendFactor_OneMinusSrcAlpha = 0x00000005, + WGPUBlendFactor_Dst = 0x00000006, + WGPUBlendFactor_OneMinusDst = 0x00000007, + WGPUBlendFactor_DstAlpha = 0x00000008, + WGPUBlendFactor_OneMinusDstAlpha = 0x00000009, + WGPUBlendFactor_SrcAlphaSaturated = 0x0000000A, + WGPUBlendFactor_Constant = 0x0000000B, + WGPUBlendFactor_OneMinusConstant = 0x0000000C, + WGPUBlendFactor_Force32 = 0x7FFFFFFF +} WGPUBlendFactor WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBlendOperation { + WGPUBlendOperation_Add = 0x00000000, + WGPUBlendOperation_Subtract = 0x00000001, + WGPUBlendOperation_ReverseSubtract = 0x00000002, + WGPUBlendOperation_Min = 0x00000003, + WGPUBlendOperation_Max = 0x00000004, + WGPUBlendOperation_Force32 = 0x7FFFFFFF +} WGPUBlendOperation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferBindingType { + WGPUBufferBindingType_Undefined = 0x00000000, + WGPUBufferBindingType_Uniform = 0x00000001, + WGPUBufferBindingType_Storage = 0x00000002, + WGPUBufferBindingType_ReadOnlyStorage = 0x00000003, + WGPUBufferBindingType_Force32 = 0x7FFFFFFF +} WGPUBufferBindingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferMapAsyncStatus { + WGPUBufferMapAsyncStatus_Success = 0x00000000, + WGPUBufferMapAsyncStatus_ValidationError = 0x00000001, + WGPUBufferMapAsyncStatus_Unknown = 0x00000002, + WGPUBufferMapAsyncStatus_DeviceLost = 0x00000003, + WGPUBufferMapAsyncStatus_DestroyedBeforeCallback = 0x00000004, + WGPUBufferMapAsyncStatus_UnmappedBeforeCallback = 0x00000005, + WGPUBufferMapAsyncStatus_MappingAlreadyPending = 0x00000006, + WGPUBufferMapAsyncStatus_OffsetOutOfRange = 0x00000007, + WGPUBufferMapAsyncStatus_SizeOutOfRange = 0x00000008, + WGPUBufferMapAsyncStatus_Force32 = 0x7FFFFFFF +} WGPUBufferMapAsyncStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferMapState { + WGPUBufferMapState_Unmapped = 0x00000000, + WGPUBufferMapState_Pending = 0x00000001, + WGPUBufferMapState_Mapped = 0x00000002, + WGPUBufferMapState_Force32 = 0x7FFFFFFF +} WGPUBufferMapState WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompareFunction { + WGPUCompareFunction_Undefined = 0x00000000, + WGPUCompareFunction_Never = 0x00000001, + WGPUCompareFunction_Less = 0x00000002, + WGPUCompareFunction_LessEqual = 0x00000003, + WGPUCompareFunction_Greater = 0x00000004, + WGPUCompareFunction_GreaterEqual = 0x00000005, + WGPUCompareFunction_Equal = 0x00000006, + WGPUCompareFunction_NotEqual = 0x00000007, + WGPUCompareFunction_Always = 0x00000008, + WGPUCompareFunction_Force32 = 0x7FFFFFFF +} WGPUCompareFunction WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompilationInfoRequestStatus { + WGPUCompilationInfoRequestStatus_Success = 0x00000000, + WGPUCompilationInfoRequestStatus_Error = 0x00000001, + WGPUCompilationInfoRequestStatus_DeviceLost = 0x00000002, + WGPUCompilationInfoRequestStatus_Unknown = 0x00000003, + WGPUCompilationInfoRequestStatus_Force32 = 0x7FFFFFFF +} WGPUCompilationInfoRequestStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompilationMessageType { + WGPUCompilationMessageType_Error = 0x00000000, + WGPUCompilationMessageType_Warning = 0x00000001, + WGPUCompilationMessageType_Info = 0x00000002, + WGPUCompilationMessageType_Force32 = 0x7FFFFFFF +} WGPUCompilationMessageType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCompositeAlphaMode { + WGPUCompositeAlphaMode_Auto = 0x00000000, + WGPUCompositeAlphaMode_Opaque = 0x00000001, + WGPUCompositeAlphaMode_Premultiplied = 0x00000002, + WGPUCompositeAlphaMode_Unpremultiplied = 0x00000003, + WGPUCompositeAlphaMode_Inherit = 0x00000004, + WGPUCompositeAlphaMode_Force32 = 0x7FFFFFFF +} WGPUCompositeAlphaMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCreatePipelineAsyncStatus { + WGPUCreatePipelineAsyncStatus_Success = 0x00000000, + WGPUCreatePipelineAsyncStatus_ValidationError = 0x00000001, + WGPUCreatePipelineAsyncStatus_InternalError = 0x00000002, + WGPUCreatePipelineAsyncStatus_DeviceLost = 0x00000003, + WGPUCreatePipelineAsyncStatus_DeviceDestroyed = 0x00000004, + WGPUCreatePipelineAsyncStatus_Unknown = 0x00000005, + WGPUCreatePipelineAsyncStatus_Force32 = 0x7FFFFFFF +} WGPUCreatePipelineAsyncStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUCullMode { + WGPUCullMode_None = 0x00000000, + WGPUCullMode_Front = 0x00000001, + WGPUCullMode_Back = 0x00000002, + WGPUCullMode_Force32 = 0x7FFFFFFF +} WGPUCullMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUDeviceLostReason { + WGPUDeviceLostReason_Undefined = 0x00000000, + WGPUDeviceLostReason_Destroyed = 0x00000001, + WGPUDeviceLostReason_Force32 = 0x7FFFFFFF +} WGPUDeviceLostReason WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUErrorFilter { + WGPUErrorFilter_Validation = 0x00000000, + WGPUErrorFilter_OutOfMemory = 0x00000001, + WGPUErrorFilter_Internal = 0x00000002, + WGPUErrorFilter_Force32 = 0x7FFFFFFF +} WGPUErrorFilter WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUErrorType { + WGPUErrorType_NoError = 0x00000000, + WGPUErrorType_Validation = 0x00000001, + WGPUErrorType_OutOfMemory = 0x00000002, + WGPUErrorType_Internal = 0x00000003, + WGPUErrorType_Unknown = 0x00000004, + WGPUErrorType_DeviceLost = 0x00000005, + WGPUErrorType_Force32 = 0x7FFFFFFF +} WGPUErrorType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFeatureName { + WGPUFeatureName_Undefined = 0x00000000, + WGPUFeatureName_DepthClipControl = 0x00000001, + WGPUFeatureName_Depth32FloatStencil8 = 0x00000002, + WGPUFeatureName_TimestampQuery = 0x00000003, + WGPUFeatureName_TextureCompressionBC = 0x00000004, + WGPUFeatureName_TextureCompressionETC2 = 0x00000005, + WGPUFeatureName_TextureCompressionASTC = 0x00000006, + WGPUFeatureName_IndirectFirstInstance = 0x00000007, + WGPUFeatureName_ShaderF16 = 0x00000008, + WGPUFeatureName_RG11B10UfloatRenderable = 0x00000009, + WGPUFeatureName_BGRA8UnormStorage = 0x0000000A, + WGPUFeatureName_Float32Filterable = 0x0000000B, + WGPUFeatureName_Force32 = 0x7FFFFFFF +} WGPUFeatureName WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFilterMode { + WGPUFilterMode_Nearest = 0x00000000, + WGPUFilterMode_Linear = 0x00000001, + WGPUFilterMode_Force32 = 0x7FFFFFFF +} WGPUFilterMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUFrontFace { + WGPUFrontFace_CCW = 0x00000000, + WGPUFrontFace_CW = 0x00000001, + WGPUFrontFace_Force32 = 0x7FFFFFFF +} WGPUFrontFace WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUIndexFormat { + WGPUIndexFormat_Undefined = 0x00000000, + WGPUIndexFormat_Uint16 = 0x00000001, + WGPUIndexFormat_Uint32 = 0x00000002, + WGPUIndexFormat_Force32 = 0x7FFFFFFF +} WGPUIndexFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPULoadOp { + WGPULoadOp_Undefined = 0x00000000, + WGPULoadOp_Clear = 0x00000001, + WGPULoadOp_Load = 0x00000002, + WGPULoadOp_Force32 = 0x7FFFFFFF +} WGPULoadOp WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUMipmapFilterMode { + WGPUMipmapFilterMode_Nearest = 0x00000000, + WGPUMipmapFilterMode_Linear = 0x00000001, + WGPUMipmapFilterMode_Force32 = 0x7FFFFFFF +} WGPUMipmapFilterMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPowerPreference { + WGPUPowerPreference_Undefined = 0x00000000, + WGPUPowerPreference_LowPower = 0x00000001, + WGPUPowerPreference_HighPerformance = 0x00000002, + WGPUPowerPreference_Force32 = 0x7FFFFFFF +} WGPUPowerPreference WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPresentMode { + WGPUPresentMode_Fifo = 0x00000000, + WGPUPresentMode_FifoRelaxed = 0x00000001, + WGPUPresentMode_Immediate = 0x00000002, + WGPUPresentMode_Mailbox = 0x00000003, + WGPUPresentMode_Force32 = 0x7FFFFFFF +} WGPUPresentMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUPrimitiveTopology { + WGPUPrimitiveTopology_PointList = 0x00000000, + WGPUPrimitiveTopology_LineList = 0x00000001, + WGPUPrimitiveTopology_LineStrip = 0x00000002, + WGPUPrimitiveTopology_TriangleList = 0x00000003, + WGPUPrimitiveTopology_TriangleStrip = 0x00000004, + WGPUPrimitiveTopology_Force32 = 0x7FFFFFFF +} WGPUPrimitiveTopology WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUQueryType { + WGPUQueryType_Occlusion = 0x00000000, + WGPUQueryType_Timestamp = 0x00000001, + WGPUQueryType_Force32 = 0x7FFFFFFF +} WGPUQueryType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUQueueWorkDoneStatus { + WGPUQueueWorkDoneStatus_Success = 0x00000000, + WGPUQueueWorkDoneStatus_Error = 0x00000001, + WGPUQueueWorkDoneStatus_Unknown = 0x00000002, + WGPUQueueWorkDoneStatus_DeviceLost = 0x00000003, + WGPUQueueWorkDoneStatus_Force32 = 0x7FFFFFFF +} WGPUQueueWorkDoneStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURequestAdapterStatus { + WGPURequestAdapterStatus_Success = 0x00000000, + WGPURequestAdapterStatus_Unavailable = 0x00000001, + WGPURequestAdapterStatus_Error = 0x00000002, + WGPURequestAdapterStatus_Unknown = 0x00000003, + WGPURequestAdapterStatus_Force32 = 0x7FFFFFFF +} WGPURequestAdapterStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPURequestDeviceStatus { + WGPURequestDeviceStatus_Success = 0x00000000, + WGPURequestDeviceStatus_Error = 0x00000001, + WGPURequestDeviceStatus_Unknown = 0x00000002, + WGPURequestDeviceStatus_Force32 = 0x7FFFFFFF +} WGPURequestDeviceStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSType { + WGPUSType_Invalid = 0x00000000, + WGPUSType_SurfaceDescriptorFromMetalLayer = 0x00000001, + WGPUSType_SurfaceDescriptorFromWindowsHWND = 0x00000002, + WGPUSType_SurfaceDescriptorFromXlibWindow = 0x00000003, + WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector = 0x00000004, + WGPUSType_ShaderModuleSPIRVDescriptor = 0x00000005, + WGPUSType_ShaderModuleWGSLDescriptor = 0x00000006, + WGPUSType_PrimitiveDepthClipControl = 0x00000007, + WGPUSType_SurfaceDescriptorFromWaylandSurface = 0x00000008, + WGPUSType_SurfaceDescriptorFromAndroidNativeWindow = 0x00000009, + WGPUSType_SurfaceDescriptorFromXcbWindow = 0x0000000A, + WGPUSType_RenderPassDescriptorMaxDrawCount = 0x0000000F, + WGPUSType_Force32 = 0x7FFFFFFF +} WGPUSType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSamplerBindingType { + WGPUSamplerBindingType_Undefined = 0x00000000, + WGPUSamplerBindingType_Filtering = 0x00000001, + WGPUSamplerBindingType_NonFiltering = 0x00000002, + WGPUSamplerBindingType_Comparison = 0x00000003, + WGPUSamplerBindingType_Force32 = 0x7FFFFFFF +} WGPUSamplerBindingType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStencilOperation { + WGPUStencilOperation_Keep = 0x00000000, + WGPUStencilOperation_Zero = 0x00000001, + WGPUStencilOperation_Replace = 0x00000002, + WGPUStencilOperation_Invert = 0x00000003, + WGPUStencilOperation_IncrementClamp = 0x00000004, + WGPUStencilOperation_DecrementClamp = 0x00000005, + WGPUStencilOperation_IncrementWrap = 0x00000006, + WGPUStencilOperation_DecrementWrap = 0x00000007, + WGPUStencilOperation_Force32 = 0x7FFFFFFF +} WGPUStencilOperation WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStorageTextureAccess { + WGPUStorageTextureAccess_Undefined = 0x00000000, + WGPUStorageTextureAccess_WriteOnly = 0x00000001, + WGPUStorageTextureAccess_ReadOnly = 0x00000002, + WGPUStorageTextureAccess_ReadWrite = 0x00000003, + WGPUStorageTextureAccess_Force32 = 0x7FFFFFFF +} WGPUStorageTextureAccess WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUStoreOp { + WGPUStoreOp_Undefined = 0x00000000, + WGPUStoreOp_Store = 0x00000001, + WGPUStoreOp_Discard = 0x00000002, + WGPUStoreOp_Force32 = 0x7FFFFFFF +} WGPUStoreOp WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUSurfaceGetCurrentTextureStatus { + WGPUSurfaceGetCurrentTextureStatus_Success = 0x00000000, + WGPUSurfaceGetCurrentTextureStatus_Timeout = 0x00000001, + WGPUSurfaceGetCurrentTextureStatus_Outdated = 0x00000002, + WGPUSurfaceGetCurrentTextureStatus_Lost = 0x00000003, + WGPUSurfaceGetCurrentTextureStatus_OutOfMemory = 0x00000004, + WGPUSurfaceGetCurrentTextureStatus_DeviceLost = 0x00000005, + WGPUSurfaceGetCurrentTextureStatus_Force32 = 0x7FFFFFFF +} WGPUSurfaceGetCurrentTextureStatus WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureAspect { + WGPUTextureAspect_All = 0x00000000, + WGPUTextureAspect_StencilOnly = 0x00000001, + WGPUTextureAspect_DepthOnly = 0x00000002, + WGPUTextureAspect_Force32 = 0x7FFFFFFF +} WGPUTextureAspect WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureDimension { + WGPUTextureDimension_1D = 0x00000000, + WGPUTextureDimension_2D = 0x00000001, + WGPUTextureDimension_3D = 0x00000002, + WGPUTextureDimension_Force32 = 0x7FFFFFFF +} WGPUTextureDimension WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureFormat { + WGPUTextureFormat_Undefined = 0x00000000, + WGPUTextureFormat_R8Unorm = 0x00000001, + WGPUTextureFormat_R8Snorm = 0x00000002, + WGPUTextureFormat_R8Uint = 0x00000003, + WGPUTextureFormat_R8Sint = 0x00000004, + WGPUTextureFormat_R16Uint = 0x00000005, + WGPUTextureFormat_R16Sint = 0x00000006, + WGPUTextureFormat_R16Float = 0x00000007, + WGPUTextureFormat_RG8Unorm = 0x00000008, + WGPUTextureFormat_RG8Snorm = 0x00000009, + WGPUTextureFormat_RG8Uint = 0x0000000A, + WGPUTextureFormat_RG8Sint = 0x0000000B, + WGPUTextureFormat_R32Float = 0x0000000C, + WGPUTextureFormat_R32Uint = 0x0000000D, + WGPUTextureFormat_R32Sint = 0x0000000E, + WGPUTextureFormat_RG16Uint = 0x0000000F, + WGPUTextureFormat_RG16Sint = 0x00000010, + WGPUTextureFormat_RG16Float = 0x00000011, + WGPUTextureFormat_RGBA8Unorm = 0x00000012, + WGPUTextureFormat_RGBA8UnormSrgb = 0x00000013, + WGPUTextureFormat_RGBA8Snorm = 0x00000014, + WGPUTextureFormat_RGBA8Uint = 0x00000015, + WGPUTextureFormat_RGBA8Sint = 0x00000016, + WGPUTextureFormat_BGRA8Unorm = 0x00000017, + WGPUTextureFormat_BGRA8UnormSrgb = 0x00000018, + WGPUTextureFormat_RGB10A2Uint = 0x00000019, + WGPUTextureFormat_RGB10A2Unorm = 0x0000001A, + WGPUTextureFormat_RG11B10Ufloat = 0x0000001B, + WGPUTextureFormat_RGB9E5Ufloat = 0x0000001C, + WGPUTextureFormat_RG32Float = 0x0000001D, + WGPUTextureFormat_RG32Uint = 0x0000001E, + WGPUTextureFormat_RG32Sint = 0x0000001F, + WGPUTextureFormat_RGBA16Uint = 0x00000020, + WGPUTextureFormat_RGBA16Sint = 0x00000021, + WGPUTextureFormat_RGBA16Float = 0x00000022, + WGPUTextureFormat_RGBA32Float = 0x00000023, + WGPUTextureFormat_RGBA32Uint = 0x00000024, + WGPUTextureFormat_RGBA32Sint = 0x00000025, + WGPUTextureFormat_Stencil8 = 0x00000026, + WGPUTextureFormat_Depth16Unorm = 0x00000027, + WGPUTextureFormat_Depth24Plus = 0x00000028, + WGPUTextureFormat_Depth24PlusStencil8 = 0x00000029, + WGPUTextureFormat_Depth32Float = 0x0000002A, + WGPUTextureFormat_Depth32FloatStencil8 = 0x0000002B, + WGPUTextureFormat_BC1RGBAUnorm = 0x0000002C, + WGPUTextureFormat_BC1RGBAUnormSrgb = 0x0000002D, + WGPUTextureFormat_BC2RGBAUnorm = 0x0000002E, + WGPUTextureFormat_BC2RGBAUnormSrgb = 0x0000002F, + WGPUTextureFormat_BC3RGBAUnorm = 0x00000030, + WGPUTextureFormat_BC3RGBAUnormSrgb = 0x00000031, + WGPUTextureFormat_BC4RUnorm = 0x00000032, + WGPUTextureFormat_BC4RSnorm = 0x00000033, + WGPUTextureFormat_BC5RGUnorm = 0x00000034, + WGPUTextureFormat_BC5RGSnorm = 0x00000035, + WGPUTextureFormat_BC6HRGBUfloat = 0x00000036, + WGPUTextureFormat_BC6HRGBFloat = 0x00000037, + WGPUTextureFormat_BC7RGBAUnorm = 0x00000038, + WGPUTextureFormat_BC7RGBAUnormSrgb = 0x00000039, + WGPUTextureFormat_ETC2RGB8Unorm = 0x0000003A, + WGPUTextureFormat_ETC2RGB8UnormSrgb = 0x0000003B, + WGPUTextureFormat_ETC2RGB8A1Unorm = 0x0000003C, + WGPUTextureFormat_ETC2RGB8A1UnormSrgb = 0x0000003D, + WGPUTextureFormat_ETC2RGBA8Unorm = 0x0000003E, + WGPUTextureFormat_ETC2RGBA8UnormSrgb = 0x0000003F, + WGPUTextureFormat_EACR11Unorm = 0x00000040, + WGPUTextureFormat_EACR11Snorm = 0x00000041, + WGPUTextureFormat_EACRG11Unorm = 0x00000042, + WGPUTextureFormat_EACRG11Snorm = 0x00000043, + WGPUTextureFormat_ASTC4x4Unorm = 0x00000044, + WGPUTextureFormat_ASTC4x4UnormSrgb = 0x00000045, + WGPUTextureFormat_ASTC5x4Unorm = 0x00000046, + WGPUTextureFormat_ASTC5x4UnormSrgb = 0x00000047, + WGPUTextureFormat_ASTC5x5Unorm = 0x00000048, + WGPUTextureFormat_ASTC5x5UnormSrgb = 0x00000049, + WGPUTextureFormat_ASTC6x5Unorm = 0x0000004A, + WGPUTextureFormat_ASTC6x5UnormSrgb = 0x0000004B, + WGPUTextureFormat_ASTC6x6Unorm = 0x0000004C, + WGPUTextureFormat_ASTC6x6UnormSrgb = 0x0000004D, + WGPUTextureFormat_ASTC8x5Unorm = 0x0000004E, + WGPUTextureFormat_ASTC8x5UnormSrgb = 0x0000004F, + WGPUTextureFormat_ASTC8x6Unorm = 0x00000050, + WGPUTextureFormat_ASTC8x6UnormSrgb = 0x00000051, + WGPUTextureFormat_ASTC8x8Unorm = 0x00000052, + WGPUTextureFormat_ASTC8x8UnormSrgb = 0x00000053, + WGPUTextureFormat_ASTC10x5Unorm = 0x00000054, + WGPUTextureFormat_ASTC10x5UnormSrgb = 0x00000055, + WGPUTextureFormat_ASTC10x6Unorm = 0x00000056, + WGPUTextureFormat_ASTC10x6UnormSrgb = 0x00000057, + WGPUTextureFormat_ASTC10x8Unorm = 0x00000058, + WGPUTextureFormat_ASTC10x8UnormSrgb = 0x00000059, + WGPUTextureFormat_ASTC10x10Unorm = 0x0000005A, + WGPUTextureFormat_ASTC10x10UnormSrgb = 0x0000005B, + WGPUTextureFormat_ASTC12x10Unorm = 0x0000005C, + WGPUTextureFormat_ASTC12x10UnormSrgb = 0x0000005D, + WGPUTextureFormat_ASTC12x12Unorm = 0x0000005E, + WGPUTextureFormat_ASTC12x12UnormSrgb = 0x0000005F, + WGPUTextureFormat_Force32 = 0x7FFFFFFF +} WGPUTextureFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureSampleType { + WGPUTextureSampleType_Undefined = 0x00000000, + WGPUTextureSampleType_Float = 0x00000001, + WGPUTextureSampleType_UnfilterableFloat = 0x00000002, + WGPUTextureSampleType_Depth = 0x00000003, + WGPUTextureSampleType_Sint = 0x00000004, + WGPUTextureSampleType_Uint = 0x00000005, + WGPUTextureSampleType_Force32 = 0x7FFFFFFF +} WGPUTextureSampleType WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureViewDimension { + WGPUTextureViewDimension_Undefined = 0x00000000, + WGPUTextureViewDimension_1D = 0x00000001, + WGPUTextureViewDimension_2D = 0x00000002, + WGPUTextureViewDimension_2DArray = 0x00000003, + WGPUTextureViewDimension_Cube = 0x00000004, + WGPUTextureViewDimension_CubeArray = 0x00000005, + WGPUTextureViewDimension_3D = 0x00000006, + WGPUTextureViewDimension_Force32 = 0x7FFFFFFF +} WGPUTextureViewDimension WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUVertexFormat { + WGPUVertexFormat_Undefined = 0x00000000, + WGPUVertexFormat_Uint8x2 = 0x00000001, + WGPUVertexFormat_Uint8x4 = 0x00000002, + WGPUVertexFormat_Sint8x2 = 0x00000003, + WGPUVertexFormat_Sint8x4 = 0x00000004, + WGPUVertexFormat_Unorm8x2 = 0x00000005, + WGPUVertexFormat_Unorm8x4 = 0x00000006, + WGPUVertexFormat_Snorm8x2 = 0x00000007, + WGPUVertexFormat_Snorm8x4 = 0x00000008, + WGPUVertexFormat_Uint16x2 = 0x00000009, + WGPUVertexFormat_Uint16x4 = 0x0000000A, + WGPUVertexFormat_Sint16x2 = 0x0000000B, + WGPUVertexFormat_Sint16x4 = 0x0000000C, + WGPUVertexFormat_Unorm16x2 = 0x0000000D, + WGPUVertexFormat_Unorm16x4 = 0x0000000E, + WGPUVertexFormat_Snorm16x2 = 0x0000000F, + WGPUVertexFormat_Snorm16x4 = 0x00000010, + WGPUVertexFormat_Float16x2 = 0x00000011, + WGPUVertexFormat_Float16x4 = 0x00000012, + WGPUVertexFormat_Float32 = 0x00000013, + WGPUVertexFormat_Float32x2 = 0x00000014, + WGPUVertexFormat_Float32x3 = 0x00000015, + WGPUVertexFormat_Float32x4 = 0x00000016, + WGPUVertexFormat_Uint32 = 0x00000017, + WGPUVertexFormat_Uint32x2 = 0x00000018, + WGPUVertexFormat_Uint32x3 = 0x00000019, + WGPUVertexFormat_Uint32x4 = 0x0000001A, + WGPUVertexFormat_Sint32 = 0x0000001B, + WGPUVertexFormat_Sint32x2 = 0x0000001C, + WGPUVertexFormat_Sint32x3 = 0x0000001D, + WGPUVertexFormat_Sint32x4 = 0x0000001E, + WGPUVertexFormat_Force32 = 0x7FFFFFFF +} WGPUVertexFormat WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUVertexStepMode { + WGPUVertexStepMode_Vertex = 0x00000000, + WGPUVertexStepMode_Instance = 0x00000001, + WGPUVertexStepMode_VertexBufferNotUsed = 0x00000002, + WGPUVertexStepMode_Force32 = 0x7FFFFFFF +} WGPUVertexStepMode WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUBufferUsage { + WGPUBufferUsage_None = 0x00000000, + WGPUBufferUsage_MapRead = 0x00000001, + WGPUBufferUsage_MapWrite = 0x00000002, + WGPUBufferUsage_CopySrc = 0x00000004, + WGPUBufferUsage_CopyDst = 0x00000008, + WGPUBufferUsage_Index = 0x00000010, + WGPUBufferUsage_Vertex = 0x00000020, + WGPUBufferUsage_Uniform = 0x00000040, + WGPUBufferUsage_Storage = 0x00000080, + WGPUBufferUsage_Indirect = 0x00000100, + WGPUBufferUsage_QueryResolve = 0x00000200, + WGPUBufferUsage_Force32 = 0x7FFFFFFF +} WGPUBufferUsage WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUBufferUsageFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUColorWriteMask { + WGPUColorWriteMask_None = 0x00000000, + WGPUColorWriteMask_Red = 0x00000001, + WGPUColorWriteMask_Green = 0x00000002, + WGPUColorWriteMask_Blue = 0x00000004, + WGPUColorWriteMask_Alpha = 0x00000008, + WGPUColorWriteMask_All = 0x0000000F, + WGPUColorWriteMask_Force32 = 0x7FFFFFFF +} WGPUColorWriteMask WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUColorWriteMaskFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUMapMode { + WGPUMapMode_None = 0x00000000, + WGPUMapMode_Read = 0x00000001, + WGPUMapMode_Write = 0x00000002, + WGPUMapMode_Force32 = 0x7FFFFFFF +} WGPUMapMode WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUMapModeFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUShaderStage { + WGPUShaderStage_None = 0x00000000, + WGPUShaderStage_Vertex = 0x00000001, + WGPUShaderStage_Fragment = 0x00000002, + WGPUShaderStage_Compute = 0x00000004, + WGPUShaderStage_Force32 = 0x7FFFFFFF +} WGPUShaderStage WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUShaderStageFlags WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUTextureUsage { + WGPUTextureUsage_None = 0x00000000, + WGPUTextureUsage_CopySrc = 0x00000001, + WGPUTextureUsage_CopyDst = 0x00000002, + WGPUTextureUsage_TextureBinding = 0x00000004, + WGPUTextureUsage_StorageBinding = 0x00000008, + WGPUTextureUsage_RenderAttachment = 0x00000010, + WGPUTextureUsage_Force32 = 0x7FFFFFFF +} WGPUTextureUsage WGPU_ENUM_ATTRIBUTE; +typedef WGPUFlags WGPUTextureUsageFlags WGPU_ENUM_ATTRIBUTE; + +typedef void (*WGPUBufferMapCallback)(WGPUBufferMapAsyncStatus status, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUCompilationInfoCallback)(WGPUCompilationInfoRequestStatus status, struct WGPUCompilationInfo const * compilationInfo, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUCreateComputePipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUCreateRenderPipelineAsyncCallback)(WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUDeviceLostCallback)(WGPUDeviceLostReason reason, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUErrorCallback)(WGPUErrorType type, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProc)(void) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUQueueWorkDoneCallback)(WGPUQueueWorkDoneStatus status, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPURequestAdapterCallback)(WGPURequestAdapterStatus status, WGPUAdapter adapter, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPURequestDeviceCallback)(WGPURequestDeviceStatus status, WGPUDevice device, char const * message, void * userdata) WGPU_FUNCTION_ATTRIBUTE; + +typedef struct WGPUChainedStruct { + struct WGPUChainedStruct const * next; + WGPUSType sType; +} WGPUChainedStruct WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUChainedStructOut { + struct WGPUChainedStructOut * next; + WGPUSType sType; +} WGPUChainedStructOut WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUAdapterProperties { + WGPUChainedStructOut * nextInChain; + uint32_t vendorID; + char const * vendorName; + char const * architecture; + uint32_t deviceID; + char const * name; + char const * driverDescription; + WGPUAdapterType adapterType; + WGPUBackendType backendType; +} WGPUAdapterProperties WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupEntry { + WGPUChainedStruct const * nextInChain; + uint32_t binding; + WGPU_NULLABLE WGPUBuffer buffer; + uint64_t offset; + uint64_t size; + WGPU_NULLABLE WGPUSampler sampler; + WGPU_NULLABLE WGPUTextureView textureView; +} WGPUBindGroupEntry WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBlendComponent { + WGPUBlendOperation operation; + WGPUBlendFactor srcFactor; + WGPUBlendFactor dstFactor; +} WGPUBlendComponent WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBufferBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUBufferBindingType type; + WGPUBool hasDynamicOffset; + uint64_t minBindingSize; +} WGPUBufferBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBufferDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUBufferUsageFlags usage; + uint64_t size; + WGPUBool mappedAtCreation; +} WGPUBufferDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUColor { + double r; + double g; + double b; + double a; +} WGPUColor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCommandBufferDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUCommandBufferDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCommandEncoderDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUCommandEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCompilationMessage { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * message; + WGPUCompilationMessageType type; + uint64_t lineNum; + uint64_t linePos; + uint64_t offset; + uint64_t length; + uint64_t utf16LinePos; + uint64_t utf16Offset; + uint64_t utf16Length; +} WGPUCompilationMessage WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUComputePassTimestampWrites { + WGPUQuerySet querySet; + uint32_t beginningOfPassWriteIndex; + uint32_t endOfPassWriteIndex; +} WGPUComputePassTimestampWrites WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUConstantEntry { + WGPUChainedStruct const * nextInChain; + char const * key; + double value; +} WGPUConstantEntry WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUExtent3D { + uint32_t width; + uint32_t height; + uint32_t depthOrArrayLayers; +} WGPUExtent3D WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUInstanceDescriptor { + WGPUChainedStruct const * nextInChain; +} WGPUInstanceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPULimits { + uint32_t maxTextureDimension1D; + uint32_t maxTextureDimension2D; + uint32_t maxTextureDimension3D; + uint32_t maxTextureArrayLayers; + uint32_t maxBindGroups; + uint32_t maxBindGroupsPlusVertexBuffers; + uint32_t maxBindingsPerBindGroup; + uint32_t maxDynamicUniformBuffersPerPipelineLayout; + uint32_t maxDynamicStorageBuffersPerPipelineLayout; + uint32_t maxSampledTexturesPerShaderStage; + uint32_t maxSamplersPerShaderStage; + uint32_t maxStorageBuffersPerShaderStage; + uint32_t maxStorageTexturesPerShaderStage; + uint32_t maxUniformBuffersPerShaderStage; + uint64_t maxUniformBufferBindingSize; + uint64_t maxStorageBufferBindingSize; + uint32_t minUniformBufferOffsetAlignment; + uint32_t minStorageBufferOffsetAlignment; + uint32_t maxVertexBuffers; + uint64_t maxBufferSize; + uint32_t maxVertexAttributes; + uint32_t maxVertexBufferArrayStride; + uint32_t maxInterStageShaderComponents; + uint32_t maxInterStageShaderVariables; + uint32_t maxColorAttachments; + uint32_t maxColorAttachmentBytesPerSample; + uint32_t maxComputeWorkgroupStorageSize; + uint32_t maxComputeInvocationsPerWorkgroup; + uint32_t maxComputeWorkgroupSizeX; + uint32_t maxComputeWorkgroupSizeY; + uint32_t maxComputeWorkgroupSizeZ; + uint32_t maxComputeWorkgroupsPerDimension; +} WGPULimits WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUMultisampleState { + WGPUChainedStruct const * nextInChain; + uint32_t count; + uint32_t mask; + WGPUBool alphaToCoverageEnabled; +} WGPUMultisampleState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUOrigin3D { + uint32_t x; + uint32_t y; + uint32_t z; +} WGPUOrigin3D WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUPipelineLayoutDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t bindGroupLayoutCount; + WGPUBindGroupLayout const * bindGroupLayouts; +} WGPUPipelineLayoutDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUPrimitiveState +typedef struct WGPUPrimitiveDepthClipControl { + WGPUChainedStruct chain; + WGPUBool unclippedDepth; +} WGPUPrimitiveDepthClipControl WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUPrimitiveState { + WGPUChainedStruct const * nextInChain; + WGPUPrimitiveTopology topology; + WGPUIndexFormat stripIndexFormat; + WGPUFrontFace frontFace; + WGPUCullMode cullMode; +} WGPUPrimitiveState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUQuerySetDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUQueryType type; + uint32_t count; +} WGPUQuerySetDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUQueueDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUQueueDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderBundleDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPURenderBundleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderBundleEncoderDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t colorFormatCount; + WGPUTextureFormat const * colorFormats; + WGPUTextureFormat depthStencilFormat; + uint32_t sampleCount; + WGPUBool depthReadOnly; + WGPUBool stencilReadOnly; +} WGPURenderBundleEncoderDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassDepthStencilAttachment { + WGPUTextureView view; + WGPULoadOp depthLoadOp; + WGPUStoreOp depthStoreOp; + float depthClearValue; + WGPUBool depthReadOnly; + WGPULoadOp stencilLoadOp; + WGPUStoreOp stencilStoreOp; + uint32_t stencilClearValue; + WGPUBool stencilReadOnly; +} WGPURenderPassDepthStencilAttachment WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPURenderPassDescriptor +typedef struct WGPURenderPassDescriptorMaxDrawCount { + WGPUChainedStruct chain; + uint64_t maxDrawCount; +} WGPURenderPassDescriptorMaxDrawCount WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassTimestampWrites { + WGPUQuerySet querySet; + uint32_t beginningOfPassWriteIndex; + uint32_t endOfPassWriteIndex; +} WGPURenderPassTimestampWrites WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURequestAdapterOptions { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE WGPUSurface compatibleSurface; + WGPUPowerPreference powerPreference; + WGPUBackendType backendType; + WGPUBool forceFallbackAdapter; +} WGPURequestAdapterOptions WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSamplerBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUSamplerBindingType type; +} WGPUSamplerBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSamplerDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUAddressMode addressModeU; + WGPUAddressMode addressModeV; + WGPUAddressMode addressModeW; + WGPUFilterMode magFilter; + WGPUFilterMode minFilter; + WGPUMipmapFilterMode mipmapFilter; + float lodMinClamp; + float lodMaxClamp; + WGPUCompareFunction compare; + uint16_t maxAnisotropy; +} WGPUSamplerDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUShaderModuleCompilationHint { + WGPUChainedStruct const * nextInChain; + char const * entryPoint; + WGPUPipelineLayout layout; +} WGPUShaderModuleCompilationHint WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUShaderModuleSPIRVDescriptor { + WGPUChainedStruct chain; + uint32_t codeSize; + uint32_t const * code; +} WGPUShaderModuleSPIRVDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUShaderModuleDescriptor +typedef struct WGPUShaderModuleWGSLDescriptor { + WGPUChainedStruct chain; + char const * code; +} WGPUShaderModuleWGSLDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUStencilFaceState { + WGPUCompareFunction compare; + WGPUStencilOperation failOp; + WGPUStencilOperation depthFailOp; + WGPUStencilOperation passOp; +} WGPUStencilFaceState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUStorageTextureBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUStorageTextureAccess access; + WGPUTextureFormat format; + WGPUTextureViewDimension viewDimension; +} WGPUStorageTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSurfaceCapabilities { + WGPUChainedStructOut * nextInChain; + size_t formatCount; + WGPUTextureFormat * formats; + size_t presentModeCount; + WGPUPresentMode * presentModes; + size_t alphaModeCount; + WGPUCompositeAlphaMode * alphaModes; +} WGPUSurfaceCapabilities WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSurfaceConfiguration { + WGPUChainedStruct const * nextInChain; + WGPUDevice device; + WGPUTextureFormat format; + WGPUTextureUsageFlags usage; + size_t viewFormatCount; + WGPUTextureFormat const * viewFormats; + WGPUCompositeAlphaMode alphaMode; + uint32_t width; + uint32_t height; + WGPUPresentMode presentMode; +} WGPUSurfaceConfiguration WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSurfaceDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; +} WGPUSurfaceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromAndroidNativeWindow { + WGPUChainedStruct chain; + void * window; +} WGPUSurfaceDescriptorFromAndroidNativeWindow WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromCanvasHTMLSelector { + WGPUChainedStruct chain; + char const * selector; +} WGPUSurfaceDescriptorFromCanvasHTMLSelector WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromMetalLayer { + WGPUChainedStruct chain; + void * layer; +} WGPUSurfaceDescriptorFromMetalLayer WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromWaylandSurface { + WGPUChainedStruct chain; + void * display; + void * surface; +} WGPUSurfaceDescriptorFromWaylandSurface WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromWindowsHWND { + WGPUChainedStruct chain; + void * hinstance; + void * hwnd; +} WGPUSurfaceDescriptorFromWindowsHWND WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromXcbWindow { + WGPUChainedStruct chain; + void * connection; + uint32_t window; +} WGPUSurfaceDescriptorFromXcbWindow WGPU_STRUCTURE_ATTRIBUTE; + +// Can be chained in WGPUSurfaceDescriptor +typedef struct WGPUSurfaceDescriptorFromXlibWindow { + WGPUChainedStruct chain; + void * display; + uint64_t window; +} WGPUSurfaceDescriptorFromXlibWindow WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSurfaceTexture { + WGPUTexture texture; + WGPUBool suboptimal; + WGPUSurfaceGetCurrentTextureStatus status; +} WGPUSurfaceTexture WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureBindingLayout { + WGPUChainedStruct const * nextInChain; + WGPUTextureSampleType sampleType; + WGPUTextureViewDimension viewDimension; + WGPUBool multisampled; +} WGPUTextureBindingLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureDataLayout { + WGPUChainedStruct const * nextInChain; + uint64_t offset; + uint32_t bytesPerRow; + uint32_t rowsPerImage; +} WGPUTextureDataLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureViewDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUTextureFormat format; + WGPUTextureViewDimension dimension; + uint32_t baseMipLevel; + uint32_t mipLevelCount; + uint32_t baseArrayLayer; + uint32_t arrayLayerCount; + WGPUTextureAspect aspect; +} WGPUTextureViewDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUVertexAttribute { + WGPUVertexFormat format; + uint64_t offset; + uint32_t shaderLocation; +} WGPUVertexAttribute WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUBindGroupLayout layout; + size_t entryCount; + WGPUBindGroupEntry const * entries; +} WGPUBindGroupDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupLayoutEntry { + WGPUChainedStruct const * nextInChain; + uint32_t binding; + WGPUShaderStageFlags visibility; + WGPUBufferBindingLayout buffer; + WGPUSamplerBindingLayout sampler; + WGPUTextureBindingLayout texture; + WGPUStorageTextureBindingLayout storageTexture; +} WGPUBindGroupLayoutEntry WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBlendState { + WGPUBlendComponent color; + WGPUBlendComponent alpha; +} WGPUBlendState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUCompilationInfo { + WGPUChainedStruct const * nextInChain; + size_t messageCount; + WGPUCompilationMessage const * messages; +} WGPUCompilationInfo WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUComputePassDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPU_NULLABLE WGPUComputePassTimestampWrites const * timestampWrites; +} WGPUComputePassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUDepthStencilState { + WGPUChainedStruct const * nextInChain; + WGPUTextureFormat format; + WGPUBool depthWriteEnabled; + WGPUCompareFunction depthCompare; + WGPUStencilFaceState stencilFront; + WGPUStencilFaceState stencilBack; + uint32_t stencilReadMask; + uint32_t stencilWriteMask; + int32_t depthBias; + float depthBiasSlopeScale; + float depthBiasClamp; +} WGPUDepthStencilState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUImageCopyBuffer { + WGPUChainedStruct const * nextInChain; + WGPUTextureDataLayout layout; + WGPUBuffer buffer; +} WGPUImageCopyBuffer WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUImageCopyTexture { + WGPUChainedStruct const * nextInChain; + WGPUTexture texture; + uint32_t mipLevel; + WGPUOrigin3D origin; + WGPUTextureAspect aspect; +} WGPUImageCopyTexture WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUProgrammableStageDescriptor { + WGPUChainedStruct const * nextInChain; + WGPUShaderModule module; + WGPU_NULLABLE char const * entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; +} WGPUProgrammableStageDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassColorAttachment { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE WGPUTextureView view; + WGPU_NULLABLE WGPUTextureView resolveTarget; + WGPULoadOp loadOp; + WGPUStoreOp storeOp; + WGPUColor clearValue; +} WGPURenderPassColorAttachment WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURequiredLimits { + WGPUChainedStruct const * nextInChain; + WGPULimits limits; +} WGPURequiredLimits WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUShaderModuleDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t hintCount; + WGPUShaderModuleCompilationHint const * hints; +} WGPUShaderModuleDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSupportedLimits { + WGPUChainedStructOut * nextInChain; + WGPULimits limits; +} WGPUSupportedLimits WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUTextureDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPUTextureUsageFlags usage; + WGPUTextureDimension dimension; + WGPUExtent3D size; + WGPUTextureFormat format; + uint32_t mipLevelCount; + uint32_t sampleCount; + size_t viewFormatCount; + WGPUTextureFormat const * viewFormats; +} WGPUTextureDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUVertexBufferLayout { + uint64_t arrayStride; + WGPUVertexStepMode stepMode; + size_t attributeCount; + WGPUVertexAttribute const * attributes; +} WGPUVertexBufferLayout WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUBindGroupLayoutDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t entryCount; + WGPUBindGroupLayoutEntry const * entries; +} WGPUBindGroupLayoutDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUColorTargetState { + WGPUChainedStruct const * nextInChain; + WGPUTextureFormat format; + WGPU_NULLABLE WGPUBlendState const * blend; + WGPUColorWriteMaskFlags writeMask; +} WGPUColorTargetState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUComputePipelineDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPU_NULLABLE WGPUPipelineLayout layout; + WGPUProgrammableStageDescriptor compute; +} WGPUComputePipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUDeviceDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t requiredFeatureCount; + WGPUFeatureName const * requiredFeatures; + WGPU_NULLABLE WGPURequiredLimits const * requiredLimits; + WGPUQueueDescriptor defaultQueue; + WGPUDeviceLostCallback deviceLostCallback; + void * deviceLostUserdata; +} WGPUDeviceDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPassDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + size_t colorAttachmentCount; + WGPURenderPassColorAttachment const * colorAttachments; + WGPU_NULLABLE WGPURenderPassDepthStencilAttachment const * depthStencilAttachment; + WGPU_NULLABLE WGPUQuerySet occlusionQuerySet; + WGPU_NULLABLE WGPURenderPassTimestampWrites const * timestampWrites; +} WGPURenderPassDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUVertexState { + WGPUChainedStruct const * nextInChain; + WGPUShaderModule module; + WGPU_NULLABLE char const * entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; + size_t bufferCount; + WGPUVertexBufferLayout const * buffers; +} WGPUVertexState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUFragmentState { + WGPUChainedStruct const * nextInChain; + WGPUShaderModule module; + WGPU_NULLABLE char const * entryPoint; + size_t constantCount; + WGPUConstantEntry const * constants; + size_t targetCount; + WGPUColorTargetState const * targets; +} WGPUFragmentState WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPURenderPipelineDescriptor { + WGPUChainedStruct const * nextInChain; + WGPU_NULLABLE char const * label; + WGPU_NULLABLE WGPUPipelineLayout layout; + WGPUVertexState vertex; + WGPUPrimitiveState primitive; + WGPU_NULLABLE WGPUDepthStencilState const * depthStencil; + WGPUMultisampleState multisample; + WGPU_NULLABLE WGPUFragmentState const * fragment; +} WGPURenderPipelineDescriptor WGPU_STRUCTURE_ATTRIBUTE; + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(WGPU_SKIP_PROCS) + +typedef WGPUInstance (*WGPUProcCreateInstance)(WGPU_NULLABLE WGPUInstanceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procName) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Adapter +typedef size_t (*WGPUProcAdapterEnumerateFeatures)(WGPUAdapter adapter, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcAdapterGetLimits)(WGPUAdapter adapter, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterGetProperties)(WGPUAdapter adapter, WGPUAdapterProperties * properties) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcAdapterHasFeature)(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterRequestDevice)(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterReference)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcAdapterRelease)(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of BindGroup +typedef void (*WGPUProcBindGroupSetLabel)(WGPUBindGroup bindGroup, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupReference)(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupRelease)(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of BindGroupLayout +typedef void (*WGPUProcBindGroupLayoutSetLabel)(WGPUBindGroupLayout bindGroupLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupLayoutReference)(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBindGroupLayoutRelease)(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Buffer +typedef void (*WGPUProcBufferDestroy)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void const * (*WGPUProcBufferGetConstMappedRange)(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBufferMapState (*WGPUProcBufferGetMapState)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void * (*WGPUProcBufferGetMappedRange)(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef uint64_t (*WGPUProcBufferGetSize)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBufferUsageFlags (*WGPUProcBufferGetUsage)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferMapAsync)(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferSetLabel)(WGPUBuffer buffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferUnmap)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferReference)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcBufferRelease)(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of CommandBuffer +typedef void (*WGPUProcCommandBufferSetLabel)(WGPUCommandBuffer commandBuffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandBufferReference)(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandBufferRelease)(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of CommandEncoder +typedef WGPUComputePassEncoder (*WGPUProcCommandEncoderBeginComputePass)(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUComputePassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderPassEncoder (*WGPUProcCommandEncoderBeginRenderPass)(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderClearBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyBufferToBuffer)(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyBufferToTexture)(WGPUCommandEncoder commandEncoder, WGPUImageCopyBuffer const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToBuffer)(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyBuffer const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderCopyTextureToTexture)(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUCommandBuffer (*WGPUProcCommandEncoderFinish)(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderInsertDebugMarker)(WGPUCommandEncoder commandEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderPopDebugGroup)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderPushDebugGroup)(WGPUCommandEncoder commandEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderResolveQuerySet)(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderSetLabel)(WGPUCommandEncoder commandEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderWriteTimestamp)(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderReference)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcCommandEncoderRelease)(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ComputePassEncoder +typedef void (*WGPUProcComputePassEncoderDispatchWorkgroups)(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderDispatchWorkgroupsIndirect)(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderEnd)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderInsertDebugMarker)(WGPUComputePassEncoder computePassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderPopDebugGroup)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderPushDebugGroup)(WGPUComputePassEncoder computePassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetBindGroup)(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetLabel)(WGPUComputePassEncoder computePassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderSetPipeline)(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderReference)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePassEncoderRelease)(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ComputePipeline +typedef WGPUBindGroupLayout (*WGPUProcComputePipelineGetBindGroupLayout)(WGPUComputePipeline computePipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineSetLabel)(WGPUComputePipeline computePipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineReference)(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcComputePipelineRelease)(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Device +typedef WGPUBindGroup (*WGPUProcDeviceCreateBindGroup)(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBindGroupLayout (*WGPUProcDeviceCreateBindGroupLayout)(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBuffer (*WGPUProcDeviceCreateBuffer)(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUCommandEncoder (*WGPUProcDeviceCreateCommandEncoder)(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUComputePipeline (*WGPUProcDeviceCreateComputePipeline)(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceCreateComputePipelineAsync)(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUPipelineLayout (*WGPUProcDeviceCreatePipelineLayout)(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQuerySet (*WGPUProcDeviceCreateQuerySet)(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderBundleEncoder (*WGPUProcDeviceCreateRenderBundleEncoder)(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderPipeline (*WGPUProcDeviceCreateRenderPipeline)(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceCreateRenderPipelineAsync)(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUSampler (*WGPUProcDeviceCreateSampler)(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUShaderModule (*WGPUProcDeviceCreateShaderModule)(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTexture (*WGPUProcDeviceCreateTexture)(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceDestroy)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef size_t (*WGPUProcDeviceEnumerateFeatures)(WGPUDevice device, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcDeviceGetLimits)(WGPUDevice device, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQueue (*WGPUProcDeviceGetQueue)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUBool (*WGPUProcDeviceHasFeature)(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDevicePopErrorScope)(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDevicePushErrorScope)(WGPUDevice device, WGPUErrorFilter filter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetLabel)(WGPUDevice device, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceSetUncapturedErrorCallback)(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceReference)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcDeviceRelease)(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Instance +typedef WGPUSurface (*WGPUProcInstanceCreateSurface)(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceProcessEvents)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceRequestAdapter)(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceReference)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcInstanceRelease)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of PipelineLayout +typedef void (*WGPUProcPipelineLayoutSetLabel)(WGPUPipelineLayout pipelineLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcPipelineLayoutReference)(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcPipelineLayoutRelease)(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of QuerySet +typedef void (*WGPUProcQuerySetDestroy)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcQuerySetGetCount)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUQueryType (*WGPUProcQuerySetGetType)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetSetLabel)(WGPUQuerySet querySet, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetReference)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQuerySetRelease)(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Queue +typedef void (*WGPUProcQueueOnSubmittedWorkDone)(WGPUQueue queue, WGPUQueueWorkDoneCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueSetLabel)(WGPUQueue queue, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueSubmit)(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueWriteBuffer)(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueWriteTexture)(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueReference)(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcQueueRelease)(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderBundle +typedef void (*WGPUProcRenderBundleSetLabel)(WGPURenderBundle renderBundle, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleReference)(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleRelease)(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderBundleEncoder +typedef void (*WGPUProcRenderBundleEncoderDraw)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndexed)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndexedIndirect)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderDrawIndirect)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPURenderBundle (*WGPUProcRenderBundleEncoderFinish)(WGPURenderBundleEncoder renderBundleEncoder, WGPU_NULLABLE WGPURenderBundleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderInsertDebugMarker)(WGPURenderBundleEncoder renderBundleEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderPopDebugGroup)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderPushDebugGroup)(WGPURenderBundleEncoder renderBundleEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetBindGroup)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetIndexBuffer)(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetLabel)(WGPURenderBundleEncoder renderBundleEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetPipeline)(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderSetVertexBuffer)(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderReference)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderBundleEncoderRelease)(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderPassEncoder +typedef void (*WGPUProcRenderPassEncoderBeginOcclusionQuery)(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDraw)(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndexed)(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndexedIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderDrawIndirect)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderEnd)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderEndOcclusionQuery)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderExecuteBundles)(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderInsertDebugMarker)(WGPURenderPassEncoder renderPassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderPopDebugGroup)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderPushDebugGroup)(WGPURenderPassEncoder renderPassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetBindGroup)(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetBlendConstant)(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetIndexBuffer)(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetLabel)(WGPURenderPassEncoder renderPassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetPipeline)(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetScissorRect)(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetStencilReference)(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetVertexBuffer)(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderSetViewport)(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderReference)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPassEncoderRelease)(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of RenderPipeline +typedef WGPUBindGroupLayout (*WGPUProcRenderPipelineGetBindGroupLayout)(WGPURenderPipeline renderPipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineSetLabel)(WGPURenderPipeline renderPipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineReference)(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcRenderPipelineRelease)(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Sampler +typedef void (*WGPUProcSamplerSetLabel)(WGPUSampler sampler, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSamplerReference)(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSamplerRelease)(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of ShaderModule +typedef void (*WGPUProcShaderModuleGetCompilationInfo)(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleSetLabel)(WGPUShaderModule shaderModule, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleReference)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcShaderModuleRelease)(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Surface +typedef void (*WGPUProcSurfaceConfigure)(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceGetCapabilities)(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceGetCurrentTexture)(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureFormat (*WGPUProcSurfaceGetPreferredFormat)(WGPUSurface surface, WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfacePresent)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceUnconfigure)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceReference)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcSurfaceRelease)(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of SurfaceCapabilities +typedef void (*WGPUProcSurfaceCapabilitiesFreeMembers)(WGPUSurfaceCapabilities capabilities) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of Texture +typedef WGPUTextureView (*WGPUProcTextureCreateView)(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureDestroy)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetDepthOrArrayLayers)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureDimension (*WGPUProcTextureGetDimension)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureFormat (*WGPUProcTextureGetFormat)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetHeight)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetMipLevelCount)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetSampleCount)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef WGPUTextureUsageFlags (*WGPUProcTextureGetUsage)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef uint32_t (*WGPUProcTextureGetWidth)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureSetLabel)(WGPUTexture texture, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureReference)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureRelease)(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +// Procs of TextureView +typedef void (*WGPUProcTextureViewSetLabel)(WGPUTextureView textureView, char const * label) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureViewReference)(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; +typedef void (*WGPUProcTextureViewRelease)(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; + +#endif // !defined(WGPU_SKIP_PROCS) + +#if !defined(WGPU_SKIP_DECLARATIONS) + +WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPU_NULLABLE WGPUInstanceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Adapter +WGPU_EXPORT size_t wgpuAdapterEnumerateFeatures(WGPUAdapter adapter, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuAdapterGetLimits(WGPUAdapter adapter, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterGetProperties(WGPUAdapter adapter, WGPUAdapterProperties * properties) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuAdapterHasFeature(WGPUAdapter adapter, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterRequestDevice(WGPUAdapter adapter, WGPU_NULLABLE WGPUDeviceDescriptor const * descriptor, WGPURequestDeviceCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterReference(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuAdapterRelease(WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of BindGroup +WGPU_EXPORT void wgpuBindGroupSetLabel(WGPUBindGroup bindGroup, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupReference(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupRelease(WGPUBindGroup bindGroup) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of BindGroupLayout +WGPU_EXPORT void wgpuBindGroupLayoutSetLabel(WGPUBindGroupLayout bindGroupLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupLayoutReference(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBindGroupLayoutRelease(WGPUBindGroupLayout bindGroupLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Buffer +WGPU_EXPORT void wgpuBufferDestroy(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void const * wgpuBufferGetConstMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBufferMapState wgpuBufferGetMapState(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void * wgpuBufferGetMappedRange(WGPUBuffer buffer, size_t offset, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint64_t wgpuBufferGetSize(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBufferUsageFlags wgpuBufferGetUsage(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferMapAsync(WGPUBuffer buffer, WGPUMapModeFlags mode, size_t offset, size_t size, WGPUBufferMapCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferSetLabel(WGPUBuffer buffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferUnmap(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferReference(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuBufferRelease(WGPUBuffer buffer) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of CommandBuffer +WGPU_EXPORT void wgpuCommandBufferSetLabel(WGPUCommandBuffer commandBuffer, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandBufferReference(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandBufferRelease(WGPUCommandBuffer commandBuffer) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of CommandEncoder +WGPU_EXPORT WGPUComputePassEncoder wgpuCommandEncoderBeginComputePass(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUComputePassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderPassEncoder wgpuCommandEncoderBeginRenderPass(WGPUCommandEncoder commandEncoder, WGPURenderPassDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderClearBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyBufferToBuffer(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyBufferToTexture(WGPUCommandEncoder commandEncoder, WGPUImageCopyBuffer const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToBuffer(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyBuffer const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderCopyTextureToTexture(WGPUCommandEncoder commandEncoder, WGPUImageCopyTexture const * source, WGPUImageCopyTexture const * destination, WGPUExtent3D const * copySize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUCommandBuffer wgpuCommandEncoderFinish(WGPUCommandEncoder commandEncoder, WGPU_NULLABLE WGPUCommandBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderInsertDebugMarker(WGPUCommandEncoder commandEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderPopDebugGroup(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderPushDebugGroup(WGPUCommandEncoder commandEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderResolveQuerySet(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderSetLabel(WGPUCommandEncoder commandEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderWriteTimestamp(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderReference(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuCommandEncoderRelease(WGPUCommandEncoder commandEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ComputePassEncoder +WGPU_EXPORT void wgpuComputePassEncoderDispatchWorkgroups(WGPUComputePassEncoder computePassEncoder, uint32_t workgroupCountX, uint32_t workgroupCountY, uint32_t workgroupCountZ) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderDispatchWorkgroupsIndirect(WGPUComputePassEncoder computePassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderEnd(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderInsertDebugMarker(WGPUComputePassEncoder computePassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderPopDebugGroup(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderPushDebugGroup(WGPUComputePassEncoder computePassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetBindGroup(WGPUComputePassEncoder computePassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetLabel(WGPUComputePassEncoder computePassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderSetPipeline(WGPUComputePassEncoder computePassEncoder, WGPUComputePipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderReference(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePassEncoderRelease(WGPUComputePassEncoder computePassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ComputePipeline +WGPU_EXPORT WGPUBindGroupLayout wgpuComputePipelineGetBindGroupLayout(WGPUComputePipeline computePipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineSetLabel(WGPUComputePipeline computePipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineReference(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuComputePipelineRelease(WGPUComputePipeline computePipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Device +WGPU_EXPORT WGPUBindGroup wgpuDeviceCreateBindGroup(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBindGroupLayout wgpuDeviceCreateBindGroupLayout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBuffer wgpuDeviceCreateBuffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUCommandEncoder wgpuDeviceCreateCommandEncoder(WGPUDevice device, WGPU_NULLABLE WGPUCommandEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUComputePipeline wgpuDeviceCreateComputePipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceCreateComputePipelineAsync(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, WGPUCreateComputePipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUPipelineLayout wgpuDeviceCreatePipelineLayout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQuerySet wgpuDeviceCreateQuerySet(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderBundleEncoder wgpuDeviceCreateRenderBundleEncoder(WGPUDevice device, WGPURenderBundleEncoderDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderPipeline wgpuDeviceCreateRenderPipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceCreateRenderPipelineAsync(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, WGPUCreateRenderPipelineAsyncCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUSampler wgpuDeviceCreateSampler(WGPUDevice device, WGPU_NULLABLE WGPUSamplerDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUShaderModule wgpuDeviceCreateShaderModule(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTexture wgpuDeviceCreateTexture(WGPUDevice device, WGPUTextureDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceDestroy(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT size_t wgpuDeviceEnumerateFeatures(WGPUDevice device, WGPUFeatureName * features) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuDeviceGetLimits(WGPUDevice device, WGPUSupportedLimits * limits) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQueue wgpuDeviceGetQueue(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUBool wgpuDeviceHasFeature(WGPUDevice device, WGPUFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDevicePopErrorScope(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDevicePushErrorScope(WGPUDevice device, WGPUErrorFilter filter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetLabel(WGPUDevice device, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceSetUncapturedErrorCallback(WGPUDevice device, WGPUErrorCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceReference(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuDeviceRelease(WGPUDevice device) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Instance +WGPU_EXPORT WGPUSurface wgpuInstanceCreateSurface(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceProcessEvents(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceRequestAdapter(WGPUInstance instance, WGPU_NULLABLE WGPURequestAdapterOptions const * options, WGPURequestAdapterCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceReference(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuInstanceRelease(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of PipelineLayout +WGPU_EXPORT void wgpuPipelineLayoutSetLabel(WGPUPipelineLayout pipelineLayout, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuPipelineLayoutReference(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuPipelineLayoutRelease(WGPUPipelineLayout pipelineLayout) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of QuerySet +WGPU_EXPORT void wgpuQuerySetDestroy(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuQuerySetGetCount(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUQueryType wgpuQuerySetGetType(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetSetLabel(WGPUQuerySet querySet, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetReference(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQuerySetRelease(WGPUQuerySet querySet) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Queue +WGPU_EXPORT void wgpuQueueOnSubmittedWorkDone(WGPUQueue queue, WGPUQueueWorkDoneCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueSetLabel(WGPUQueue queue, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueSubmit(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueWriteBuffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueWriteTexture(WGPUQueue queue, WGPUImageCopyTexture const * destination, void const * data, size_t dataSize, WGPUTextureDataLayout const * dataLayout, WGPUExtent3D const * writeSize) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueReference(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuQueueRelease(WGPUQueue queue) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderBundle +WGPU_EXPORT void wgpuRenderBundleSetLabel(WGPURenderBundle renderBundle, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleReference(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleRelease(WGPURenderBundle renderBundle) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderBundleEncoder +WGPU_EXPORT void wgpuRenderBundleEncoderDraw(WGPURenderBundleEncoder renderBundleEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndexed(WGPURenderBundleEncoder renderBundleEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndexedIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderDrawIndirect(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPURenderBundle wgpuRenderBundleEncoderFinish(WGPURenderBundleEncoder renderBundleEncoder, WGPU_NULLABLE WGPURenderBundleDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderInsertDebugMarker(WGPURenderBundleEncoder renderBundleEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderPopDebugGroup(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderPushDebugGroup(WGPURenderBundleEncoder renderBundleEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetBindGroup(WGPURenderBundleEncoder renderBundleEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetIndexBuffer(WGPURenderBundleEncoder renderBundleEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetLabel(WGPURenderBundleEncoder renderBundleEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetPipeline(WGPURenderBundleEncoder renderBundleEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderSetVertexBuffer(WGPURenderBundleEncoder renderBundleEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderReference(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderBundleEncoderRelease(WGPURenderBundleEncoder renderBundleEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderPassEncoder +WGPU_EXPORT void wgpuRenderPassEncoderBeginOcclusionQuery(WGPURenderPassEncoder renderPassEncoder, uint32_t queryIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDraw(WGPURenderPassEncoder renderPassEncoder, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndexed(WGPURenderPassEncoder renderPassEncoder, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t baseVertex, uint32_t firstInstance) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndexedIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderDrawIndirect(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer indirectBuffer, uint64_t indirectOffset) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderEnd(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderEndOcclusionQuery(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderExecuteBundles(WGPURenderPassEncoder renderPassEncoder, size_t bundleCount, WGPURenderBundle const * bundles) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderInsertDebugMarker(WGPURenderPassEncoder renderPassEncoder, char const * markerLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderPopDebugGroup(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderPushDebugGroup(WGPURenderPassEncoder renderPassEncoder, char const * groupLabel) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetBindGroup(WGPURenderPassEncoder renderPassEncoder, uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, size_t dynamicOffsetCount, uint32_t const * dynamicOffsets) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetBlendConstant(WGPURenderPassEncoder renderPassEncoder, WGPUColor const * color) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetIndexBuffer(WGPURenderPassEncoder renderPassEncoder, WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetLabel(WGPURenderPassEncoder renderPassEncoder, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetPipeline(WGPURenderPassEncoder renderPassEncoder, WGPURenderPipeline pipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetScissorRect(WGPURenderPassEncoder renderPassEncoder, uint32_t x, uint32_t y, uint32_t width, uint32_t height) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetStencilReference(WGPURenderPassEncoder renderPassEncoder, uint32_t reference) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetVertexBuffer(WGPURenderPassEncoder renderPassEncoder, uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, uint64_t size) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderSetViewport(WGPURenderPassEncoder renderPassEncoder, float x, float y, float width, float height, float minDepth, float maxDepth) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderReference(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPassEncoderRelease(WGPURenderPassEncoder renderPassEncoder) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of RenderPipeline +WGPU_EXPORT WGPUBindGroupLayout wgpuRenderPipelineGetBindGroupLayout(WGPURenderPipeline renderPipeline, uint32_t groupIndex) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineSetLabel(WGPURenderPipeline renderPipeline, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineReference(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuRenderPipelineRelease(WGPURenderPipeline renderPipeline) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Sampler +WGPU_EXPORT void wgpuSamplerSetLabel(WGPUSampler sampler, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSamplerReference(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSamplerRelease(WGPUSampler sampler) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of ShaderModule +WGPU_EXPORT void wgpuShaderModuleGetCompilationInfo(WGPUShaderModule shaderModule, WGPUCompilationInfoCallback callback, void * userdata) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleReference(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuShaderModuleRelease(WGPUShaderModule shaderModule) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Surface +WGPU_EXPORT void wgpuSurfaceConfigure(WGPUSurface surface, WGPUSurfaceConfiguration const * config) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceGetCapabilities(WGPUSurface surface, WGPUAdapter adapter, WGPUSurfaceCapabilities * capabilities) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceGetCurrentTexture(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureFormat wgpuSurfaceGetPreferredFormat(WGPUSurface surface, WGPUAdapter adapter) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfacePresent(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceUnconfigure(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceReference(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuSurfaceRelease(WGPUSurface surface) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of SurfaceCapabilities +WGPU_EXPORT void wgpuSurfaceCapabilitiesFreeMembers(WGPUSurfaceCapabilities capabilities) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of Texture +WGPU_EXPORT WGPUTextureView wgpuTextureCreateView(WGPUTexture texture, WGPU_NULLABLE WGPUTextureViewDescriptor const * descriptor) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureDestroy(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetDepthOrArrayLayers(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureDimension wgpuTextureGetDimension(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureFormat wgpuTextureGetFormat(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetHeight(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetMipLevelCount(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetSampleCount(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT WGPUTextureUsageFlags wgpuTextureGetUsage(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT uint32_t wgpuTextureGetWidth(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureSetLabel(WGPUTexture texture, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureReference(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureRelease(WGPUTexture texture) WGPU_FUNCTION_ATTRIBUTE; + +// Methods of TextureView +WGPU_EXPORT void wgpuTextureViewSetLabel(WGPUTextureView textureView, char const * label) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureViewReference(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; +WGPU_EXPORT void wgpuTextureViewRelease(WGPUTextureView textureView) WGPU_FUNCTION_ATTRIBUTE; + +#endif // !defined(WGPU_SKIP_DECLARATIONS) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // WEBGPU_H_ diff --git a/thirdparty/wgpu/wgpu.h b/thirdparty/wgpu/wgpu.h new file mode 100644 index 000000000000..ce9c7589cf10 --- /dev/null +++ b/thirdparty/wgpu/wgpu.h @@ -0,0 +1,265 @@ +#ifndef WGPU_H_ +#define WGPU_H_ + +#include "webgpu.h" + +typedef enum WGPUNativeSType { + // Start at 0003 since that's allocated range for wgpu-native + WGPUSType_DeviceExtras = 0x00030001, + WGPUSType_RequiredLimitsExtras = 0x00030002, + WGPUSType_PipelineLayoutExtras = 0x00030003, + WGPUSType_ShaderModuleGLSLDescriptor = 0x00030004, + WGPUSType_SupportedLimitsExtras = 0x00030005, + WGPUSType_InstanceExtras = 0x00030006, + WGPUSType_BindGroupEntryExtras = 0x00030007, + WGPUSType_BindGroupLayoutEntryExtras = 0x00030008, + WGPUSType_QuerySetDescriptorExtras = 0x00030009, + WGPUSType_SurfaceConfigurationExtras = 0x0003000A, + WGPUNativeSType_Force32 = 0x7FFFFFFF +} WGPUNativeSType; + +typedef enum WGPUNativeFeature { + WGPUNativeFeature_PushConstants = 0x00030001, + WGPUNativeFeature_TextureAdapterSpecificFormatFeatures = 0x00030002, + WGPUNativeFeature_MultiDrawIndirect = 0x00030003, + WGPUNativeFeature_MultiDrawIndirectCount = 0x00030004, + WGPUNativeFeature_VertexWritableStorage = 0x00030005, + WGPUNativeFeature_TextureBindingArray = 0x00030006, + WGPUNativeFeature_SampledTextureAndStorageBufferArrayNonUniformIndexing = 0x00030007, + WGPUNativeFeature_PipelineStatisticsQuery = 0x00030008, + WGPUNativeFeature_StorageResourceBindingArray = 0x00030009, + WGPUNativeFeature_PartiallyBoundBindingArray = 0x0003000A, + WGPUNativeFeature_Force32 = 0x7FFFFFFF +} WGPUNativeFeature; + +typedef enum WGPULogLevel { + WGPULogLevel_Off = 0x00000000, + WGPULogLevel_Error = 0x00000001, + WGPULogLevel_Warn = 0x00000002, + WGPULogLevel_Info = 0x00000003, + WGPULogLevel_Debug = 0x00000004, + WGPULogLevel_Trace = 0x00000005, + WGPULogLevel_Force32 = 0x7FFFFFFF +} WGPULogLevel; + +typedef enum WGPUInstanceBackend { + WGPUInstanceBackend_All = 0x00000000, + WGPUInstanceBackend_Vulkan = 1 << 0, + WGPUInstanceBackend_GL = 1 << 1, + WGPUInstanceBackend_Metal = 1 << 2, + WGPUInstanceBackend_DX12 = 1 << 3, + WGPUInstanceBackend_DX11 = 1 << 4, + WGPUInstanceBackend_BrowserWebGPU = 1 << 5, + WGPUInstanceBackend_Primary = WGPUInstanceBackend_Vulkan | WGPUInstanceBackend_Metal | + WGPUInstanceBackend_DX12 | + WGPUInstanceBackend_BrowserWebGPU, + WGPUInstanceBackend_Secondary = WGPUInstanceBackend_GL | WGPUInstanceBackend_DX11, + WGPUInstanceBackend_Force32 = 0x7FFFFFFF +} WGPUInstanceBackend; +typedef WGPUFlags WGPUInstanceBackendFlags; + +typedef enum WGPUInstanceFlag { + WGPUInstanceFlag_Default = 0x00000000, + WGPUInstanceFlag_Debug = 1 << 0, + WGPUInstanceFlag_Validation = 1 << 1, + WGPUInstanceFlag_DiscardHalLabels = 1 << 2, + WGPUInstanceFlag_Force32 = 0x7FFFFFFF +} WGPUInstanceFlag; +typedef WGPUFlags WGPUInstanceFlags; + +typedef enum WGPUDx12Compiler { + WGPUDx12Compiler_Undefined = 0x00000000, + WGPUDx12Compiler_Fxc = 0x00000001, + WGPUDx12Compiler_Dxc = 0x00000002, + WGPUDx12Compiler_Force32 = 0x7FFFFFFF +} WGPUDx12Compiler; + +typedef enum WGPUGles3MinorVersion { + WGPUGles3MinorVersion_Automatic = 0x00000000, + WGPUGles3MinorVersion_Version0 = 0x00000001, + WGPUGles3MinorVersion_Version1 = 0x00000002, + WGPUGles3MinorVersion_Version2 = 0x00000003, + WGPUGles3MinorVersion_Force32 = 0x7FFFFFFF +} WGPUGles3MinorVersion; + +typedef enum WGPUPipelineStatisticName { + WGPUPipelineStatisticName_VertexShaderInvocations = 0x00000000, + WGPUPipelineStatisticName_ClipperInvocations = 0x00000001, + WGPUPipelineStatisticName_ClipperPrimitivesOut = 0x00000002, + WGPUPipelineStatisticName_FragmentShaderInvocations = 0x00000003, + WGPUPipelineStatisticName_ComputeShaderInvocations = 0x00000004, + WGPUPipelineStatisticName_Force32 = 0x7FFFFFFF +} WGPUPipelineStatisticName WGPU_ENUM_ATTRIBUTE; + +typedef enum WGPUNativeQueryType { + WGPUNativeQueryType_PipelineStatistics = 0x00030000, + WGPUNativeQueryType_Force32 = 0x7FFFFFFF +} WGPUNativeQueryType WGPU_ENUM_ATTRIBUTE; + +typedef struct WGPUInstanceExtras { + WGPUChainedStruct chain; + WGPUInstanceBackendFlags backends; + WGPUInstanceFlags flags; + WGPUDx12Compiler dx12ShaderCompiler; + WGPUGles3MinorVersion gles3MinorVersion; + const char * dxilPath; + const char * dxcPath; +} WGPUInstanceExtras; + +typedef struct WGPUDeviceExtras { + WGPUChainedStruct chain; + const char * tracePath; +} WGPUDeviceExtras; + +typedef struct WGPUNativeLimits { + uint32_t maxPushConstantSize; + uint32_t maxNonSamplerBindings; +} WGPUNativeLimits; + +typedef struct WGPURequiredLimitsExtras { + WGPUChainedStruct chain; + WGPUNativeLimits limits; +} WGPURequiredLimitsExtras; + +typedef struct WGPUSupportedLimitsExtras { + WGPUChainedStructOut chain; + WGPUNativeLimits limits; +} WGPUSupportedLimitsExtras; + +typedef struct WGPUPushConstantRange { + WGPUShaderStageFlags stages; + uint32_t start; + uint32_t end; +} WGPUPushConstantRange; + +typedef struct WGPUPipelineLayoutExtras { + WGPUChainedStruct chain; + size_t pushConstantRangeCount; + WGPUPushConstantRange const * pushConstantRanges; +} WGPUPipelineLayoutExtras; + +typedef uint64_t WGPUSubmissionIndex; + +typedef struct WGPUWrappedSubmissionIndex { + WGPUQueue queue; + WGPUSubmissionIndex submissionIndex; +} WGPUWrappedSubmissionIndex; + +typedef struct WGPUShaderDefine { + char const * name; + char const * value; +} WGPUShaderDefine; + +typedef struct WGPUShaderModuleGLSLDescriptor { + WGPUChainedStruct chain; + WGPUShaderStage stage; + char const * code; + uint32_t defineCount; + WGPUShaderDefine * defines; +} WGPUShaderModuleGLSLDescriptor; + +typedef struct WGPURegistryReport { + size_t numAllocated; + size_t numKeptFromUser; + size_t numReleasedFromUser; + size_t numError; + size_t elementSize; +} WGPURegistryReport; + +typedef struct WGPUHubReport { + WGPURegistryReport adapters; + WGPURegistryReport devices; + WGPURegistryReport queues; + WGPURegistryReport pipelineLayouts; + WGPURegistryReport shaderModules; + WGPURegistryReport bindGroupLayouts; + WGPURegistryReport bindGroups; + WGPURegistryReport commandBuffers; + WGPURegistryReport renderBundles; + WGPURegistryReport renderPipelines; + WGPURegistryReport computePipelines; + WGPURegistryReport querySets; + WGPURegistryReport buffers; + WGPURegistryReport textures; + WGPURegistryReport textureViews; + WGPURegistryReport samplers; +} WGPUHubReport; + +typedef struct WGPUGlobalReport { + WGPURegistryReport surfaces; + WGPUBackendType backendType; + WGPUHubReport vulkan; + WGPUHubReport metal; + WGPUHubReport dx12; + WGPUHubReport gl; +} WGPUGlobalReport; + +typedef struct WGPUInstanceEnumerateAdapterOptions { + WGPUChainedStruct const * nextInChain; + WGPUInstanceBackendFlags backends; +} WGPUInstanceEnumerateAdapterOptions; + +typedef struct WGPUBindGroupEntryExtras { + WGPUChainedStruct chain; + WGPUBuffer const * buffers; + size_t bufferCount; + WGPUSampler const * samplers; + size_t samplerCount; + WGPUTextureView const * textureViews; + size_t textureViewCount; +} WGPUBindGroupEntryExtras; + +typedef struct WGPUBindGroupLayoutEntryExtras { + WGPUChainedStruct chain; + uint32_t count; +} WGPUBindGroupLayoutEntryExtras; + +typedef struct WGPUQuerySetDescriptorExtras { + WGPUChainedStruct chain; + WGPUPipelineStatisticName const * pipelineStatistics; + size_t pipelineStatisticCount; +} WGPUQuerySetDescriptorExtras WGPU_STRUCTURE_ATTRIBUTE; + +typedef struct WGPUSurfaceConfigurationExtras { + WGPUChainedStruct chain; + WGPUBool desiredMaximumFrameLatency; +} WGPUSurfaceConfigurationExtras WGPU_STRUCTURE_ATTRIBUTE; + +typedef void (*WGPULogCallback)(WGPULogLevel level, char const * message, void * userdata); + +#ifdef __cplusplus +extern "C" { +#endif + +void wgpuGenerateReport(WGPUInstance instance, WGPUGlobalReport * report); +size_t wgpuInstanceEnumerateAdapters(WGPUInstance instance, WGPU_NULLABLE WGPUInstanceEnumerateAdapterOptions const * options, WGPUAdapter * adapters); + +WGPUSubmissionIndex wgpuQueueSubmitForIndex(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands); + +// Returns true if the queue is empty, or false if there are more queue submissions still in flight. +WGPUBool wgpuDevicePoll(WGPUDevice device, WGPUBool wait, WGPU_NULLABLE WGPUWrappedSubmissionIndex const * wrappedSubmissionIndex); + +void wgpuSetLogCallback(WGPULogCallback callback, void * userdata); + +void wgpuSetLogLevel(WGPULogLevel level); + +uint32_t wgpuGetVersion(void); + +void wgpuRenderPassEncoderSetPushConstants(WGPURenderPassEncoder encoder, WGPUShaderStageFlags stages, uint32_t offset, uint32_t sizeBytes, void const * data); + +void wgpuRenderPassEncoderMultiDrawIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); +void wgpuRenderPassEncoderMultiDrawIndexedIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); + +void wgpuRenderPassEncoderMultiDrawIndirectCount(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, WGPUBuffer count_buffer, uint64_t count_buffer_offset, uint32_t max_count); +void wgpuRenderPassEncoderMultiDrawIndexedIndirectCount(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, WGPUBuffer count_buffer, uint64_t count_buffer_offset, uint32_t max_count); + +void wgpuComputePassEncoderBeginPipelineStatisticsQuery(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); +void wgpuComputePassEncoderEndPipelineStatisticsQuery(WGPUComputePassEncoder computePassEncoder); +void wgpuRenderPassEncoderBeginPipelineStatisticsQuery(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); +void wgpuRenderPassEncoderEndPipelineStatisticsQuery(WGPURenderPassEncoder renderPassEncoder); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif From 0971a5cbc4b33268084217dd5e1109fa9fa2bae7 Mon Sep 17 00:00:00 2001 From: dav Date: Sat, 23 Mar 2024 19:31:36 -0700 Subject: [PATCH 02/19] Implement context driver surface getters and setters --- .../rendering_context_driver_webgpu.cpp | 44 +++++++++---------- .../webgpu/rendering_context_driver_webgpu.h | 3 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp index c755f1df40ed..555a6ba1ef93 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -49,7 +49,7 @@ RenderingDeviceDriver *RenderingContextDriverWebGpu::driver_create() { // TODO } -void RenderingContextDriverWebGpu::driver_free(RenderingDeviceDriver *p_driver) { +void RenderingContextDriverWebGpu::driver_free(RenderingDeviceDriver *p_driver){ DEV_ASSERT(false) // TODO } @@ -60,47 +60,47 @@ RenderingContextDriver::SurfaceID RenderingContextDriverWebGpu::surface_create(c } void RenderingContextDriverWebGpu::surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) { - DEV_ASSERT(false) - // TODO + Surface *surface = (Surface *)(p_surface); + surface->width = p_width; + surface->width = p_height; + surface->needs_resize = true; } -void RenderingContextDriverWebGpu::surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) { - DEV_ASSERT(false) - // TODO +void RenderingContextDriverWebGpu::surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode){ + Surface *surface = (Surface *)(p_surface); + surface->vsync_mode = p_vsync_mode; + surface->needs_resize = true; } DisplayServer::VSyncMode RenderingContextDriverWebGpu::surface_get_vsync_mode(SurfaceID p_surface) const { - DEV_ASSERT(false) - // TODO - return DisplayServer::VSyncMode::VSYNC_DISABLED; + Surface *surface = (Surface *)(p_surface); + return surface->vsync_mode; } uint32_t RenderingContextDriverWebGpu::surface_get_width(SurfaceID p_surface) const { - DEV_ASSERT(false) - // TODO - return 0; + Surface *surface = (Surface *)(p_surface); + return surface->width; } uint32_t RenderingContextDriverWebGpu::surface_get_height(SurfaceID p_surface) const { - DEV_ASSERT(false) - // TODO - return 0; + Surface *surface = (Surface *)(p_surface); + return surface->height; } void RenderingContextDriverWebGpu::surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) { - DEV_ASSERT(false) - // TODO + Surface *surface = (Surface *)(p_surface); + surface->needs_resize = p_needs_resize; } bool RenderingContextDriverWebGpu::surface_get_needs_resize(SurfaceID p_surface) const { - DEV_ASSERT(false) - // TODO - return false; + Surface *surface = (Surface *)(p_surface); + return surface->needs_resize; } void RenderingContextDriverWebGpu::surface_destroy(SurfaceID p_surface) { - DEV_ASSERT(false) - // TODO + Surface *surface = (Surface *)(p_surface); + wgpuSurfaceRelease(surface->surface); + memdelete(surface); } bool RenderingContextDriverWebGpu::is_debug_utils_enabled() const { DEV_ASSERT(false) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.h b/drivers/webgpu/rendering_context_driver_webgpu.h index 4b7b318d1acc..941aeeb69544 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.h +++ b/drivers/webgpu/rendering_context_driver_webgpu.h @@ -30,8 +30,6 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { RenderingContextDriverWebGpu(); virtual ~RenderingContextDriverWebGpu() override; - void adapter_set(WGPUAdapter new_adapter); - struct Surface { WGPUSurface surface; uint32_t width = 0; @@ -40,6 +38,7 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { bool needs_resize = false; }; + void adapter_set(WGPUAdapter new_adapter); WGPUInstance instance_get() const; }; From 9695dfd8308f5fb695b2881425ac11d6531ec5af Mon Sep 17 00:00:00 2001 From: dav Date: Sat, 23 Mar 2024 20:40:27 -0700 Subject: [PATCH 03/19] Add device driver header and empty definitions --- .../vulkan/rendering_device_driver_vulkan.cpp | 5 + .../vulkan/rendering_device_driver_vulkan.h | 4 + .../rendering_context_driver_webgpu.cpp | 17 +- .../webgpu/rendering_device_driver_webgpu.cpp | 297 +++++++++++++++++ .../webgpu/rendering_device_driver_webgpu.h | 310 ++++++++++++++++++ 5 files changed, 626 insertions(+), 7 deletions(-) create mode 100644 drivers/webgpu/rendering_device_driver_webgpu.cpp create mode 100644 drivers/webgpu/rendering_device_driver_webgpu.h diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 297407da41ba..76143f34d2e8 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -28,6 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ +#ifdef VULKAN_ENABLED + #include "rendering_device_driver_vulkan.h" #include "core/config/project_settings.h" @@ -4960,3 +4962,6 @@ RenderingDeviceDriverVulkan::~RenderingDeviceDriverVulkan() { vkDestroyDevice(vk_device, nullptr); } } + +#endif // VULKAN_ENABLED + diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index 70c4cebba5ed..fa8651ac74e1 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -31,6 +31,8 @@ #ifndef RENDERING_DEVICE_DRIVER_VULKAN_H #define RENDERING_DEVICE_DRIVER_VULKAN_H +#ifdef VULKAN_ENABLED + #include "core/templates/hash_map.h" #include "core/templates/paged_allocator.h" #include "drivers/vulkan/rendering_context_driver_vulkan.h" @@ -646,4 +648,6 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver { virtual ~RenderingDeviceDriverVulkan(); }; +#endif // VULKAN_ENABLED + #endif // RENDERING_DEVICE_DRIVER_VULKAN_H diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp index 555a6ba1ef93..8709d8ee4c9f 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -1,5 +1,8 @@ +#ifdef WEBGPU_ENABLED + #include "rendering_context_driver_webgpu.h" #include "core/error/error_macros.h" +#include "rendering_device_driver_webgpu.h" #include static void handleRequestAdapter(WGPURequestAdapterStatus status, @@ -45,13 +48,11 @@ bool RenderingContextDriverWebGpu::device_supports_present(uint32_t p_device_ind } RenderingDeviceDriver *RenderingContextDriverWebGpu::driver_create() { - DEV_ASSERT(false) - // TODO + return memnew(RenderingDeviceDriverWebGpu(this)); } -void RenderingContextDriverWebGpu::driver_free(RenderingDeviceDriver *p_driver){ - DEV_ASSERT(false) - // TODO +void RenderingContextDriverWebGpu::driver_free(RenderingDeviceDriver *p_driver) { + memdelete(p_driver); } RenderingContextDriver::SurfaceID RenderingContextDriverWebGpu::surface_create(const void *p_platform_data) { @@ -66,7 +67,7 @@ void RenderingContextDriverWebGpu::surface_set_size(SurfaceID p_surface, uint32_ surface->needs_resize = true; } -void RenderingContextDriverWebGpu::surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode){ +void RenderingContextDriverWebGpu::surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) { Surface *surface = (Surface *)(p_surface); surface->vsync_mode = p_vsync_mode; surface->needs_resize = true; @@ -105,7 +106,7 @@ void RenderingContextDriverWebGpu::surface_destroy(SurfaceID p_surface) { bool RenderingContextDriverWebGpu::is_debug_utils_enabled() const { DEV_ASSERT(false) // TODO - return false; + return true; } void RenderingContextDriverWebGpu::adapter_set(WGPUAdapter new_adapter) { @@ -115,3 +116,5 @@ void RenderingContextDriverWebGpu::adapter_set(WGPUAdapter new_adapter) { WGPUInstance RenderingContextDriverWebGpu::instance_get() const { return instance; } + +#endif // WEBGPU_ENABLED diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp new file mode 100644 index 000000000000..c0de5cc71c54 --- /dev/null +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -0,0 +1,297 @@ +#include "rendering_device_driver_webgpu.h" + +Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t p_frame_count) { +} + +/*****************/ +/**** BUFFERS ****/ +/*****************/ + +RenderingDeviceDriverWebGpu::BufferID RenderingDeviceDriverWebGpu::buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType p_allocation_type) { +} +bool RenderingDeviceDriverWebGpu::buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) { +} +void RenderingDeviceDriverWebGpu::buffer_free(BufferID p_buffer) { +} +uint64_t RenderingDeviceDriverWebGpu::buffer_get_allocation_size(BufferID p_buffer) { +} +uint8_t *RenderingDeviceDriverWebGpu::buffer_map(BufferID p_buffer) {} +void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) {} + +/*****************/ +/**** TEXTURE ****/ +/*****************/ + +RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create(const TextureFormat &p_format, const TextureView &p_view) {} +RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) {} +RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) {} +RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) {} +void RenderingDeviceDriverWebGpu::texture_free(TextureID p_texture) {} +uint64_t RenderingDeviceDriverWebGpu::texture_get_allocation_size(TextureID p_texture) {} +void RenderingDeviceDriverWebGpu::texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) {} +uint8_t *RenderingDeviceDriverWebGpu::texture_map(TextureID p_texture, const TextureSubresource &p_subresource) {} +void RenderingDeviceDriverWebGpu::texture_unmap(TextureID p_texture) {} +BitField RenderingDeviceDriverWebGpu::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) {} + +/*****************/ +/**** SAMPLER ****/ +/*****************/ + +RenderingDeviceDriver::SamplerID RenderingDeviceDriverWebGpu::sampler_create(const SamplerState &p_state) {} +void RenderingDeviceDriverWebGpu::sampler_free(SamplerID p_sampler) {} +bool RenderingDeviceDriverWebGpu::sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) {} + +/**********************/ +/**** VERTEX ARRAY ****/ +/**********************/ + +RenderingDeviceDriver::VertexFormatID RenderingDeviceDriverWebGpu::vertex_format_create(VectorView p_vertex_attribs) {} +void RenderingDeviceDriverWebGpu::vertex_format_free(VertexFormatID p_vertex_format) {} + +/******************/ +/**** BARRIERS ****/ +/******************/ + +void RenderingDeviceDriverWebGpu::command_pipeline_barrier( + CommandBufferID p_cmd_buffer, + BitField p_src_stages, + BitField p_dst_stages, + VectorView p_memory_barriers, + VectorView p_buffer_barriers, + VectorView p_texture_barriers) {} + +/****************/ +/**** FENCES ****/ +/****************/ + +RenderingDeviceDriver::FenceID RenderingDeviceDriverWebGpu::fence_create() {} +Error RenderingDeviceDriverWebGpu::fence_wait(FenceID p_fence) {} +void RenderingDeviceDriverWebGpu::fence_free(FenceID p_fence) {} + +/********************/ +/**** SEMAPHORES ****/ +/********************/ + +RenderingDeviceDriver::SemaphoreID RenderingDeviceDriverWebGpu::semaphore_create() {} +void RenderingDeviceDriverWebGpu::semaphore_free(SemaphoreID p_semaphore) {} + +/******************/ +/**** COMMANDS ****/ +/******************/ + +// ----- QUEUE FAMILY ----- + +RenderingDeviceDriver::CommandQueueFamilyID RenderingDeviceDriverWebGpu::command_queue_family_get(BitField p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID p_surface) {} + +// ----- QUEUE ----- + +RenderingDeviceDriver::CommandQueueID RenderingDeviceDriverWebGpu::command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue) {} +Error RenderingDeviceDriverWebGpu::command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView p_wait_semaphores, VectorView p_cmd_buffers, VectorView p_cmd_semaphores, FenceID p_cmd_fence, VectorView p_swap_chains) {} +void RenderingDeviceDriverWebGpu::command_queue_free(CommandQueueID p_cmd_queue) {} + +// ----- POOL ----- + +RenderingDeviceDriver::CommandPoolID RenderingDeviceDriverWebGpu::command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) {} +void RenderingDeviceDriverWebGpu::command_pool_free(CommandPoolID p_cmd_pool) {} + +// ----- BUFFER ----- + +RenderingDeviceDriver::CommandBufferID RenderingDeviceDriverWebGpu::command_buffer_create(CommandPoolID p_cmd_pool) {} +bool RenderingDeviceDriverWebGpu::command_buffer_begin(CommandBufferID p_cmd_buffer) {} +bool RenderingDeviceDriverWebGpu::command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) {} +void RenderingDeviceDriverWebGpu::command_buffer_end(CommandBufferID p_cmd_buffer) {} +void RenderingDeviceDriverWebGpu::command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView p_secondary_cmd_buffers) {} + +/********************/ +/**** SWAP CHAIN ****/ +/********************/ + +RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {} +Error RenderingDeviceDriverWebGpu::swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) {} +RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) {} +RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::swap_chain_get_render_pass(SwapChainID p_swap_chain) {} +RenderingDeviceDriver::DataFormat RenderingDeviceDriverWebGpu::swap_chain_get_format(SwapChainID p_swap_chain) {} +void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID p_swap_chain) {} + +/*********************/ +/**** FRAMEBUFFER ****/ +/*********************/ + +RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::framebuffer_create(RenderPassID p_render_pass, VectorView p_attachments, uint32_t p_width, uint32_t p_height) {} +void RenderingDeviceDriverWebGpu::framebuffer_free(FramebufferID p_framebuffer) {} + +/****************/ +/**** SHADER ****/ +/****************/ + +String RenderingDeviceDriverWebGpu::shader_get_binary_cache_key() {} +Vector RenderingDeviceDriverWebGpu::shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) {} +RenderingDeviceDriver::ShaderID RenderingDeviceDriverWebGpu::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) {} +void RenderingDeviceDriverWebGpu::shader_free(ShaderID p_shader) {} + +/*********************/ +/**** UNIFORM SET ****/ +/*********************/ + +RenderingDeviceDriver::UniformSetID RenderingDeviceDriverWebGpu::uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) {} +void RenderingDeviceDriverWebGpu::uniform_set_free(UniformSetID p_uniform_set) {} + +// ----- COMMANDS ----- + +void RenderingDeviceDriverWebGpu::command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) {} + +/******************/ +/**** TRANSFER ****/ +/******************/ + +void RenderingDeviceDriverWebGpu::command_clear_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, uint64_t p_offset, uint64_t p_size) {} +void RenderingDeviceDriverWebGpu::command_copy_buffer(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, BufferID p_dst_buffer, VectorView p_regions) {} + +void RenderingDeviceDriverWebGpu::command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) {} +void RenderingDeviceDriverWebGpu::command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) {} +void RenderingDeviceDriverWebGpu::command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) {} + +void RenderingDeviceDriverWebGpu::command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) {} +void RenderingDeviceDriverWebGpu::command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView p_regions) {} + +/******************/ +/**** PIPELINE ****/ +/******************/ + +void RenderingDeviceDriverWebGpu::pipeline_free(PipelineID p_pipeline) {} + +// ----- BINDING ----- + +void RenderingDeviceDriverWebGpu::command_bind_push_constants(CommandBufferID p_cmd_buffer, ShaderID p_shader, uint32_t p_first_index, VectorView p_data) {} + +// ----- CACHE ----- + +bool RenderingDeviceDriverWebGpu::pipeline_cache_create(const Vector &p_data) {} +void RenderingDeviceDriverWebGpu::pipeline_cache_free() {} +size_t RenderingDeviceDriverWebGpu::pipeline_cache_query_size() {} +Vector RenderingDeviceDriverWebGpu::pipeline_cache_serialize() {} + +/*******************/ +/**** RENDERING ****/ +/*******************/ + +// ----- SUBPASS ----- + +RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::render_pass_create(VectorView p_attachments, VectorView p_subpasses, VectorView p_subpass_dependencies, uint32_t p_view_count) {} +void RenderingDeviceDriverWebGpu::render_pass_free(RenderPassID p_render_pass) {} + +// ----- COMMANDS ----- + +void RenderingDeviceDriverWebGpu::command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView p_clear_values) {} +void RenderingDeviceDriverWebGpu::command_end_render_pass(CommandBufferID p_cmd_buffer) {} +void RenderingDeviceDriverWebGpu::command_next_render_subpass(CommandBufferID p_cmd_buffer, CommandBufferType p_cmd_buffer_type) {} +void RenderingDeviceDriverWebGpu::command_render_set_viewport(CommandBufferID p_cmd_buffer, VectorView p_viewports) {} +void RenderingDeviceDriverWebGpu::command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView p_scissors) {} +void RenderingDeviceDriverWebGpu::command_render_clear_attachments(CommandBufferID p_cmd_buffer, VectorView p_attachment_clears, VectorView p_rects) {} + +// Binding. +void RenderingDeviceDriverWebGpu::command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) {} +void RenderingDeviceDriverWebGpu::command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) {} + +// Drawing. +void RenderingDeviceDriverWebGpu::command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) {} +void RenderingDeviceDriverWebGpu::command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) {} +void RenderingDeviceDriverWebGpu::command_render_draw_indexed_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) {} +void RenderingDeviceDriverWebGpu::command_render_draw_indexed_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) {} +void RenderingDeviceDriverWebGpu::command_render_draw_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) {} +void RenderingDeviceDriverWebGpu::command_render_draw_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) {} + +// Buffer binding. +void RenderingDeviceDriverWebGpu::command_render_bind_vertex_buffers(CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) {} +void RenderingDeviceDriverWebGpu::command_render_bind_index_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, IndexBufferFormat p_format, uint64_t p_offset) {} + +// Dynamic state. +void RenderingDeviceDriverWebGpu::command_render_set_blend_constants(CommandBufferID p_cmd_buffer, const Color &p_constants) {} +void RenderingDeviceDriverWebGpu::command_render_set_line_width(CommandBufferID p_cmd_buffer, float p_width) {} + +// ----- PIPELINE ----- + +RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::render_pipeline_create( + ShaderID p_shader, + VertexFormatID p_vertex_format, + RenderPrimitive p_render_primitive, + PipelineRasterizationState p_rasterization_state, + PipelineMultisampleState p_multisample_state, + PipelineDepthStencilState p_depth_stencil_state, + PipelineColorBlendState p_blend_state, + VectorView p_color_attachments, + BitField p_dynamic_state, + RenderPassID p_render_pass, + uint32_t p_render_subpass, + VectorView p_specialization_constants) {} + +/*****************/ +/**** COMPUTE ****/ +/*****************/ + +// ----- COMMANDS ----- + +// Binding. +void RenderingDeviceDriverWebGpu::command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) {} +void RenderingDeviceDriverWebGpu::command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) {} + +// Dispatching. +void RenderingDeviceDriverWebGpu::command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) {} +void RenderingDeviceDriverWebGpu::command_compute_dispatch_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset) {} + +// ----- PIPELINE ----- + +RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::compute_pipeline_create(ShaderID p_shader, VectorView p_specialization_constants) {} + +/*****************/ +/**** QUERIES ****/ +/*****************/ + +// ----- TIMESTAMP ----- + +// Basic. +RenderingDeviceDriver::QueryPoolID RenderingDeviceDriverWebGpu::timestamp_query_pool_create(uint32_t p_query_count) {} +void RenderingDeviceDriverWebGpu::timestamp_query_pool_free(QueryPoolID p_pool_id) {} +void RenderingDeviceDriverWebGpu::timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) {} +uint64_t RenderingDeviceDriverWebGpu::timestamp_query_result_to_time(uint64_t p_result) {} + +// Commands. +void RenderingDeviceDriverWebGpu::command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) {} +void RenderingDeviceDriverWebGpu::command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) {} + +/****************/ +/**** LABELS ****/ +/****************/ + +void RenderingDeviceDriverWebGpu::command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) {} +void RenderingDeviceDriverWebGpu::command_end_label(CommandBufferID p_cmd_buffer) {} + +/********************/ +/**** SUBMISSION ****/ +/********************/ + +void RenderingDeviceDriverWebGpu::begin_segment(uint32_t p_frame_index, uint32_t p_frames_drawn) {} +void RenderingDeviceDriverWebGpu::end_segment() {} + +/**************/ +/**** MISC ****/ +/**************/ + +void RenderingDeviceDriverWebGpu::set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) {} +uint64_t RenderingDeviceDriverWebGpu::get_resource_native_handle(DriverResource p_type, ID p_driver_id) {} +uint64_t RenderingDeviceDriverWebGpu::get_total_memory_used() {} +uint64_t RenderingDeviceDriverWebGpu::limit_get(Limit p_limit) {} +uint64_t RenderingDeviceDriverWebGpu::api_trait_get(ApiTrait p_trait) {} +bool RenderingDeviceDriverWebGpu::has_feature(Features p_feature) {} +const RenderingDeviceDriver::MultiviewCapabilities &RenderingDeviceDriverWebGpu::get_multiview_capabilities() {} +String RenderingDeviceDriverWebGpu::get_api_name() const {} +String RenderingDeviceDriverWebGpu::get_api_version() const {} +String RenderingDeviceDriverWebGpu::get_pipeline_cache_uuid() const {} +const RenderingDeviceDriver::Capabilities &RenderingDeviceDriverWebGpu::get_capabilities() const {} + +RenderingDeviceDriverWebGpu::RenderingDeviceDriverWebGpu(RenderingContextDriverWebGpu *p_context_driver) { + DEV_ASSERT(p_context_driver != nullptr); + + context_driver = p_context_driver; +} +RenderingDeviceDriverWebGpu::~RenderingDeviceDriverWebGpu() {} diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h new file mode 100644 index 000000000000..b701bae02821 --- /dev/null +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -0,0 +1,310 @@ +#ifndef RENDERING_DEVICE_DRIVER_WEBGPU_H +#define RENDERING_DEVICE_DRIVER_WEBGPU_H + +#include "drivers/webgpu/rendering_context_driver_webgpu.h" +#include "servers/rendering/rendering_device_driver.h" + +class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { + RenderingContextDriverWebGpu *context_driver = nullptr; +public: + Error initialize(uint32_t p_device_index, uint32_t p_frame_count) override final; + +public: + /*****************/ + /**** BUFFERS ****/ + /*****************/ + +public: + virtual BufferID buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType p_allocation_type) override final; + virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) override final; + virtual void buffer_free(BufferID p_buffer) override final; + virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) override final; + virtual uint8_t *buffer_map(BufferID p_buffer) override final; + virtual void buffer_unmap(BufferID p_buffer) override final; + + /*****************/ + /**** TEXTURE ****/ + /*****************/ + +public: + virtual TextureID texture_create(const TextureFormat &p_format, const TextureView &p_view) override final; + virtual TextureID texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) override final; + virtual TextureID texture_create_shared(TextureID p_original_texture, const TextureView &p_view) override final; + virtual TextureID texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) override final; + virtual void texture_free(TextureID p_texture) override final; + virtual uint64_t texture_get_allocation_size(TextureID p_texture) override final; + virtual void texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) override final; + virtual uint8_t *texture_map(TextureID p_texture, const TextureSubresource &p_subresource) override final; + virtual void texture_unmap(TextureID p_texture) override final; + virtual BitField texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) override final; + + /*****************/ + /**** SAMPLER ****/ + /*****************/ + +public: + virtual SamplerID sampler_create(const SamplerState &p_state) override final; + virtual void sampler_free(SamplerID p_sampler) override final; + virtual bool sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) override final; + + /**********************/ + /**** VERTEX ARRAY ****/ + /**********************/ + +public: + virtual VertexFormatID vertex_format_create(VectorView p_vertex_attribs) override final; + virtual void vertex_format_free(VertexFormatID p_vertex_format) override final; + + /******************/ + /**** BARRIERS ****/ + /******************/ + +public: + virtual void command_pipeline_barrier( + CommandBufferID p_cmd_buffer, + BitField p_src_stages, + BitField p_dst_stages, + VectorView p_memory_barriers, + VectorView p_buffer_barriers, + VectorView p_texture_barriers) override final; + + /****************/ + /**** FENCES ****/ + /****************/ + +public: + virtual FenceID fence_create() override final; + virtual Error fence_wait(FenceID p_fence) override final; + virtual void fence_free(FenceID p_fence) override final; + + /********************/ + /**** SEMAPHORES ****/ + /********************/ + + virtual SemaphoreID semaphore_create() override final; + virtual void semaphore_free(SemaphoreID p_semaphore) override final; + + /******************/ + /**** COMMANDS ****/ + /******************/ + + // ----- QUEUE FAMILY ----- + + virtual CommandQueueFamilyID command_queue_family_get(BitField p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID p_surface = 0) override final; + + // ----- QUEUE ----- +public: + virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override final; + virtual Error command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView p_wait_semaphores, VectorView p_cmd_buffers, VectorView p_cmd_semaphores, FenceID p_cmd_fence, VectorView p_swap_chains) override final; + virtual void command_queue_free(CommandQueueID p_cmd_queue) override final; + + // ----- POOL ----- + +public: + virtual CommandPoolID command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) override final; + virtual void command_pool_free(CommandPoolID p_cmd_pool) override final; + + // ----- BUFFER ----- + + virtual CommandBufferID command_buffer_create(CommandPoolID p_cmd_pool) override final; + virtual bool command_buffer_begin(CommandBufferID p_cmd_buffer) override final; + virtual bool command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) override final; + virtual void command_buffer_end(CommandBufferID p_cmd_buffer) override final; + virtual void command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView p_secondary_cmd_buffers) override final; + + /********************/ + /**** SWAP CHAIN ****/ + /********************/ + +public: + virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override final; + virtual Error swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) override final; + virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override final; + virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final; + virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final; + virtual void swap_chain_free(SwapChainID p_swap_chain) override final; + + /*********************/ + /**** FRAMEBUFFER ****/ + /*********************/ + + virtual FramebufferID framebuffer_create(RenderPassID p_render_pass, VectorView p_attachments, uint32_t p_width, uint32_t p_height) override final; + virtual void framebuffer_free(FramebufferID p_framebuffer) override final; + + /****************/ + /**** SHADER ****/ + /****************/ + +public: + virtual String shader_get_binary_cache_key() override final; + virtual Vector shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) override final; + virtual ShaderID shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) override final; + virtual void shader_free(ShaderID p_shader) override final; + + /*********************/ + /**** UNIFORM SET ****/ + /*********************/ + +public: + virtual UniformSetID uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) override final; + virtual void uniform_set_free(UniformSetID p_uniform_set) override final; + + // ----- COMMANDS ----- + + virtual void command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final; + + /******************/ + /**** TRANSFER ****/ + /******************/ + + virtual void command_clear_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, uint64_t p_offset, uint64_t p_size) override final; + virtual void command_copy_buffer(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, BufferID p_dst_buffer, VectorView p_regions) override final; + + virtual void command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) override final; + virtual void command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) override final; + virtual void command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) override final; + + virtual void command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView p_regions) override final; + virtual void command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView p_regions) override final; + + /******************/ + /**** PIPELINE ****/ + /******************/ +public: + virtual void pipeline_free(PipelineID p_pipeline) override final; + + // ----- BINDING ----- + + virtual void command_bind_push_constants(CommandBufferID p_cmd_buffer, ShaderID p_shader, uint32_t p_first_index, VectorView p_data) override final; + + // ----- CACHE ----- + + virtual bool pipeline_cache_create(const Vector &p_data) override final; + virtual void pipeline_cache_free() override final; + virtual size_t pipeline_cache_query_size() override final; + virtual Vector pipeline_cache_serialize() override final; + + /*******************/ + /**** RENDERING ****/ + /*******************/ + + // ----- SUBPASS ----- + + virtual RenderPassID render_pass_create(VectorView p_attachments, VectorView p_subpasses, VectorView p_subpass_dependencies, uint32_t p_view_count) override final; + virtual void render_pass_free(RenderPassID p_render_pass) override final; + + // ----- COMMANDS ----- + + virtual void command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView p_clear_values) override final; + virtual void command_end_render_pass(CommandBufferID p_cmd_buffer) override final; + virtual void command_next_render_subpass(CommandBufferID p_cmd_buffer, CommandBufferType p_cmd_buffer_type) override final; + virtual void command_render_set_viewport(CommandBufferID p_cmd_buffer, VectorView p_viewports) override final; + virtual void command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView p_scissors) override final; + virtual void command_render_clear_attachments(CommandBufferID p_cmd_buffer, VectorView p_attachment_clears, VectorView p_rects) override final; + + // Binding. + virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final; + virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final; + + // Drawing. + virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) override final; + virtual void command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) override final; + virtual void command_render_draw_indexed_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) override final; + virtual void command_render_draw_indexed_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) override final; + virtual void command_render_draw_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) override final; + virtual void command_render_draw_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) override final; + + // Buffer binding. + virtual void command_render_bind_vertex_buffers(CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) override final; + virtual void command_render_bind_index_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, IndexBufferFormat p_format, uint64_t p_offset) override final; + + // Dynamic state. + virtual void command_render_set_blend_constants(CommandBufferID p_cmd_buffer, const Color &p_constants) override final; + virtual void command_render_set_line_width(CommandBufferID p_cmd_buffer, float p_width) override final; + + // ----- PIPELINE ----- + + virtual PipelineID render_pipeline_create( + ShaderID p_shader, + VertexFormatID p_vertex_format, + RenderPrimitive p_render_primitive, + PipelineRasterizationState p_rasterization_state, + PipelineMultisampleState p_multisample_state, + PipelineDepthStencilState p_depth_stencil_state, + PipelineColorBlendState p_blend_state, + VectorView p_color_attachments, + BitField p_dynamic_state, + RenderPassID p_render_pass, + uint32_t p_render_subpass, + VectorView p_specialization_constants) override final; + + /*****************/ + /**** COMPUTE ****/ + /*****************/ + + // ----- COMMANDS ----- + + // Binding. + virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final; + virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final; + + // Dispatching. + virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) override final; + virtual void command_compute_dispatch_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset) override final; + + // ----- PIPELINE ----- + + virtual PipelineID compute_pipeline_create(ShaderID p_shader, VectorView p_specialization_constants) override final; + + /*****************/ + /**** QUERIES ****/ + /*****************/ + + // ----- TIMESTAMP ----- + + // Basic. + virtual QueryPoolID timestamp_query_pool_create(uint32_t p_query_count) override final; + virtual void timestamp_query_pool_free(QueryPoolID p_pool_id) override final; + virtual void timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) override final; + virtual uint64_t timestamp_query_result_to_time(uint64_t p_result) override final; + + // Commands. + virtual void command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) override final; + virtual void command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) override final; + + /****************/ + /**** LABELS ****/ + /****************/ + + virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) override final; + virtual void command_end_label(CommandBufferID p_cmd_buffer) override final; + + /********************/ + /**** SUBMISSION ****/ + /********************/ + + virtual void begin_segment(uint32_t p_frame_index, uint32_t p_frames_drawn) override final; + virtual void end_segment() override final; + + /**************/ + /**** MISC ****/ + /**************/ + + virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) override final; + virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) override final; + virtual uint64_t get_total_memory_used() override final; + virtual uint64_t limit_get(Limit p_limit) override final; + virtual uint64_t api_trait_get(ApiTrait p_trait) override final; + virtual bool has_feature(Features p_feature) override final; + virtual const MultiviewCapabilities &get_multiview_capabilities() override final; + virtual String get_api_name() const override final; + virtual String get_api_version() const override final; + virtual String get_pipeline_cache_uuid() const override final; + virtual const Capabilities &get_capabilities() const override final; + +public: + RenderingDeviceDriverWebGpu(RenderingContextDriverWebGpu *p_context_driver); + virtual ~RenderingDeviceDriverWebGpu(); +}; + +#endif // RENDERING_DEVICE_DRIVER_WEBGPU_H From 7a014e159efec923e5c1d970a20090963cd1503c Mon Sep 17 00:00:00 2001 From: dav Date: Sun, 24 Mar 2024 10:44:19 -0700 Subject: [PATCH 04/19] Complete initial rendering context driver --- .../rendering_context_driver_webgpu.cpp | 67 ++++++++++++++----- .../webgpu/rendering_context_driver_webgpu.h | 6 +- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp index 8709d8ee4c9f..8ce580d25da4 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -1,50 +1,82 @@ +#include "webgpu.h" #ifdef WEBGPU_ENABLED #include "rendering_context_driver_webgpu.h" + #include "core/error/error_macros.h" + #include "rendering_device_driver_webgpu.h" -#include static void handleRequestAdapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, char const *message, void *userdata) { - RenderingContextDriverWebGpu *context = (RenderingContextDriverWebGpu *)userdata; - context->adapter_set( - adapter); ERR_FAIL_COND_V_MSG( status != WGPURequestAdapterStatus_Success, (void)0, vformat("Failed to get wgpu adapter: %s", message)); + + WGPUAdapterProperties props; + wgpuAdapterGetProperties(adapter, &props); + + RenderingContextDriver::Device device; + device.name = String(props.name); + device.vendor = (RenderingContextDriver::Vendor)props.vendorID; + device.type = (RenderingContextDriver::DeviceType)props.adapterType; + + RenderingContextDriverWebGpu *context = (RenderingContextDriverWebGpu *)userdata; + context->adapter_push_back( + adapter, device); } RenderingContextDriverWebGpu::RenderingContextDriverWebGpu() { } RenderingContextDriverWebGpu::~RenderingContextDriverWebGpu() { + if (instance != nullptr) { + wgpuInstanceRelease(instance); + } + + for (WGPUAdapter &adapter : adapters) { + wgpuAdapterRelease(adapter); + } } Error RenderingContextDriverWebGpu::initialize() { instance = wgpuCreateInstance(nullptr); WGPURequestAdapterOptions adapter_options = {}; + + // There is no way to request all adapters, so we just get the high and low power ones. + + adapter_options.powerPreference = WGPUPowerPreference::WGPUPowerPreference_HighPerformance; wgpuInstanceRequestAdapter(instance, &adapter_options, handleRequestAdapter, this); + + adapter_options.powerPreference = WGPUPowerPreference::WGPUPowerPreference_LowPower; + wgpuInstanceRequestAdapter(instance, + &adapter_options, + handleRequestAdapter, this); + return OK; } const RenderingContextDriver::Device &RenderingContextDriverWebGpu::device_get(uint32_t p_device_index) const { - DEV_ASSERT(false) - // TODO + DEV_ASSERT(p_device_index < adapters.size()); + const RenderingContextDriver::Device &driver_device = driver_devices[p_device_index]; + return driver_device; } uint32_t RenderingContextDriverWebGpu::device_get_count() const { - DEV_ASSERT(false) - // TODO + return adapters.size(); } bool RenderingContextDriverWebGpu::device_supports_present(uint32_t p_device_index, SurfaceID p_surface) const { - DEV_ASSERT(false) - // TODO + DEV_ASSERT(p_device_index < adapters.size()); + WGPUAdapter adapter = adapters[p_device_index]; + Surface *surface = (Surface *)p_surface; + WGPUSurfaceCapabilities caps; + wgpuSurfaceGetCapabilities(surface->surface, adapter, &caps); + return caps.formatCount != 0; } RenderingDeviceDriver *RenderingContextDriverWebGpu::driver_create() { @@ -104,17 +136,18 @@ void RenderingContextDriverWebGpu::surface_destroy(SurfaceID p_surface) { memdelete(surface); } bool RenderingContextDriverWebGpu::is_debug_utils_enabled() const { - DEV_ASSERT(false) - // TODO - return true; -} - -void RenderingContextDriverWebGpu::adapter_set(WGPUAdapter new_adapter) { - adapter = new_adapter; + // Although there is a flag to enable validation in WGPU, the spec doesn't support this. + // See: https://docs.rs/wgpu/latest/wgpu/struct.InstanceFlags.html#associatedconstant.DEBUG + return false; } WGPUInstance RenderingContextDriverWebGpu::instance_get() const { return instance; } +void RenderingContextDriverWebGpu::adapter_push_back(WGPUAdapter p_adapter, Device p_device) { + adapters.push_back(p_adapter); + driver_devices.push_back(p_device); +} + #endif // WEBGPU_ENABLED diff --git a/drivers/webgpu/rendering_context_driver_webgpu.h b/drivers/webgpu/rendering_context_driver_webgpu.h index 941aeeb69544..2fe466859ee8 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.h +++ b/drivers/webgpu/rendering_context_driver_webgpu.h @@ -8,7 +8,9 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { private: WGPUInstance instance = nullptr; - WGPUAdapter adapter = nullptr; + TightLocalVector adapters; + TightLocalVector driver_devices; + public: virtual Error initialize() override; virtual const RenderingContextDriver::Device &device_get(uint32_t p_device_index) const override; @@ -38,8 +40,8 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { bool needs_resize = false; }; - void adapter_set(WGPUAdapter new_adapter); WGPUInstance instance_get() const; + void adapter_push_back(WGPUAdapter p_adapter, Device p_device); }; #endif // RENDERING_CONTEXT_DRIVER_WGPU_H From 18d31614d9ecd580d4cf394e88c9d9850393b923 Mon Sep 17 00:00:00 2001 From: dav Date: Sun, 24 Mar 2024 17:32:11 -0700 Subject: [PATCH 05/19] Create webgpu device and queue --- .../rendering_context_driver_webgpu.cpp | 6 ++++ .../webgpu/rendering_context_driver_webgpu.h | 1 + .../webgpu/rendering_device_driver_webgpu.cpp | 33 ++++++++++++++++++- .../webgpu/rendering_device_driver_webgpu.h | 6 ++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp index 8ce580d25da4..40d526b78058 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -145,6 +145,12 @@ WGPUInstance RenderingContextDriverWebGpu::instance_get() const { return instance; } +WGPUAdapter RenderingContextDriverWebGpu::adapter_get(uint32_t p_adapter_index) const { + DEV_ASSERT(p_adapter_index < adapters.size()); + WGPUAdapter adapter = adapters[p_adapter_index]; + return adapter; +} + void RenderingContextDriverWebGpu::adapter_push_back(WGPUAdapter p_adapter, Device p_device) { adapters.push_back(p_adapter); driver_devices.push_back(p_device); diff --git a/drivers/webgpu/rendering_context_driver_webgpu.h b/drivers/webgpu/rendering_context_driver_webgpu.h index 2fe466859ee8..40334c91acde 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.h +++ b/drivers/webgpu/rendering_context_driver_webgpu.h @@ -41,6 +41,7 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { }; WGPUInstance instance_get() const; + WGPUAdapter adapter_get(uint32_t p_adapter_index) const; void adapter_push_back(WGPUAdapter p_adapter, Device p_device); }; diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index c0de5cc71c54..190eb44ba5df 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -1,6 +1,24 @@ #include "rendering_device_driver_webgpu.h" +#include "core/error/error_macros.h" + +static void handle_request_device(WGPURequestDeviceStatus status, + WGPUDevice device, char const *message, + void *userdata) { + *(WGPUDevice *)userdata = device; +} + Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t p_frame_count) { + WGPUAdapter adapter = context_driver->adapter_get(p_device_index); + this->context_device = context_driver->device_get(p_device_index); + + wgpuAdapterRequestDevice(adapter, nullptr, handle_request_device, &this->device); + ERR_FAIL_COND_V(!this->device, FAILED); + + this->queue = wgpuDeviceGetQueue(device); + ERR_FAIL_COND_V(!this->queue, FAILED); + + return OK; } /*****************/ @@ -9,13 +27,18 @@ Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t RenderingDeviceDriverWebGpu::BufferID RenderingDeviceDriverWebGpu::buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType p_allocation_type) { } + bool RenderingDeviceDriverWebGpu::buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) { } + void RenderingDeviceDriverWebGpu::buffer_free(BufferID p_buffer) { } + uint64_t RenderingDeviceDriverWebGpu::buffer_get_allocation_size(BufferID p_buffer) { } + uint8_t *RenderingDeviceDriverWebGpu::buffer_map(BufferID p_buffer) {} + void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) {} /*****************/ @@ -294,4 +317,12 @@ RenderingDeviceDriverWebGpu::RenderingDeviceDriverWebGpu(RenderingContextDriverW context_driver = p_context_driver; } -RenderingDeviceDriverWebGpu::~RenderingDeviceDriverWebGpu() {} +RenderingDeviceDriverWebGpu::~RenderingDeviceDriverWebGpu() { + if (queue != nullptr) { + wgpuQueueRelease(queue); + } + + if (device != nullptr) { + wgpuDeviceRelease(device); + } +} diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index b701bae02821..96e1cdc57e43 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -2,10 +2,16 @@ #define RENDERING_DEVICE_DRIVER_WEBGPU_H #include "drivers/webgpu/rendering_context_driver_webgpu.h" + +#include "servers/rendering/rendering_context_driver.h" #include "servers/rendering/rendering_device_driver.h" class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { + WGPUDevice device = nullptr; + WGPUQueue queue = nullptr; RenderingContextDriverWebGpu *context_driver = nullptr; + RenderingContextDriver::Device context_device; + public: Error initialize(uint32_t p_device_index, uint32_t p_frame_count) override final; From abc3151a353a78cdd17d053045423e277a5059d7 Mon Sep 17 00:00:00 2001 From: dav Date: Sun, 31 Mar 2024 15:03:30 -0700 Subject: [PATCH 06/19] Fixes and stubs up to first buffer_create --- .../webgpu/rendering_device_driver_webgpu.cpp | 128 +++++++++++++++--- .../webgpu/rendering_device_driver_webgpu.h | 4 + 2 files changed, 111 insertions(+), 21 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 190eb44ba5df..06f537ade989 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -87,16 +87,31 @@ void RenderingDeviceDriverWebGpu::command_pipeline_barrier( /**** FENCES ****/ /****************/ -RenderingDeviceDriver::FenceID RenderingDeviceDriverWebGpu::fence_create() {} -Error RenderingDeviceDriverWebGpu::fence_wait(FenceID p_fence) {} -void RenderingDeviceDriverWebGpu::fence_free(FenceID p_fence) {} +RenderingDeviceDriver::FenceID RenderingDeviceDriverWebGpu::fence_create() { + // The usage of fences in godot to sync frames is already handled by WebGpu. + return FenceID(1); +} + +Error RenderingDeviceDriverWebGpu::fence_wait(FenceID _p_fence) { + return OK; +} + +void RenderingDeviceDriverWebGpu::fence_free(FenceID p_fence) { + // Empty. +} /********************/ /**** SEMAPHORES ****/ /********************/ -RenderingDeviceDriver::SemaphoreID RenderingDeviceDriverWebGpu::semaphore_create() {} -void RenderingDeviceDriverWebGpu::semaphore_free(SemaphoreID p_semaphore) {} +RenderingDeviceDriver::SemaphoreID RenderingDeviceDriverWebGpu::semaphore_create() { + // The usage of fences in godot to sync frames is already handled by WebGpu. + return SemaphoreID(1); +} + +void RenderingDeviceDriverWebGpu::semaphore_free(SemaphoreID _p_semaphore) { + // Empty. +} /******************/ /**** COMMANDS ****/ @@ -104,25 +119,69 @@ void RenderingDeviceDriverWebGpu::semaphore_free(SemaphoreID p_semaphore) {} // ----- QUEUE FAMILY ----- -RenderingDeviceDriver::CommandQueueFamilyID RenderingDeviceDriverWebGpu::command_queue_family_get(BitField p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID p_surface) {} +RenderingDeviceDriver::CommandQueueFamilyID RenderingDeviceDriverWebGpu::command_queue_family_get(BitField _p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID _p_surface) { + // WebGpu has no concept of queue families, so this value is unused. + return CommandQueueFamilyID(1); +} // ----- QUEUE ----- -RenderingDeviceDriver::CommandQueueID RenderingDeviceDriverWebGpu::command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue) {} +RenderingDeviceDriver::CommandQueueID RenderingDeviceDriverWebGpu::command_queue_create(CommandQueueFamilyID _p_cmd_queue_family, bool _p_identify_as_main_queue) { + // WebGpu has only one queue, so this value is unused. + return CommandQueueID(1); +} + Error RenderingDeviceDriverWebGpu::command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView p_wait_semaphores, VectorView p_cmd_buffers, VectorView p_cmd_semaphores, FenceID p_cmd_fence, VectorView p_swap_chains) {} -void RenderingDeviceDriverWebGpu::command_queue_free(CommandQueueID p_cmd_queue) {} + +void RenderingDeviceDriverWebGpu::command_queue_free(CommandQueueID _p_cmd_queue) { + // Empty. +} // ----- POOL ----- -RenderingDeviceDriver::CommandPoolID RenderingDeviceDriverWebGpu::command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) {} -void RenderingDeviceDriverWebGpu::command_pool_free(CommandPoolID p_cmd_pool) {} +RenderingDeviceDriver::CommandPoolID RenderingDeviceDriverWebGpu::command_pool_create(CommandQueueFamilyID _p_cmd_queue_family, CommandBufferType _p_cmd_buffer_type) { + // WebGpu has no concept of command pools. + // However, we will free command encoders with command_pool_free because command buffers are tied to the lifetime of command pools. + return CommandPoolID(1); +} + +void RenderingDeviceDriverWebGpu::command_pool_free(CommandPoolID _p_cmd_pool) { + // Empty. +} // ----- BUFFER ----- -RenderingDeviceDriver::CommandBufferID RenderingDeviceDriverWebGpu::command_buffer_create(CommandPoolID p_cmd_pool) {} -bool RenderingDeviceDriverWebGpu::command_buffer_begin(CommandBufferID p_cmd_buffer) {} -bool RenderingDeviceDriverWebGpu::command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) {} -void RenderingDeviceDriverWebGpu::command_buffer_end(CommandBufferID p_cmd_buffer) {} +RenderingDeviceDriver::CommandBufferID RenderingDeviceDriverWebGpu::command_buffer_create(CommandPoolID _p_cmd_pool) { + command_encoders.push_back(nullptr); + return CommandBufferID(command_encoders.size() - 1 + 1); +} + +bool RenderingDeviceDriverWebGpu::command_buffer_begin(CommandBufferID p_cmd_buffer) { + DEV_ASSERT(p_cmd_buffer - 1 < command_encoders.size()); + + WGPUCommandEncoder& encoder_spot = command_encoders[p_cmd_buffer - 1]; + DEV_ASSERT(encoder_spot == nullptr); + + WGPUCommandEncoderDescriptor desc = (WGPUCommandEncoderDescriptor){}; + WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, &desc); + + encoder_spot = encoder; + + return false; +} + +bool RenderingDeviceDriverWebGpu::command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) { +} + +void RenderingDeviceDriverWebGpu::command_buffer_end(CommandBufferID p_cmd_buffer) { + DEV_ASSERT(p_cmd_buffer - 1 < command_encoders.size()); + + WGPUCommandEncoder& encoder = command_encoders[p_cmd_buffer - 1]; + DEV_ASSERT(encoder == nullptr); + + wgpuCommandEncoderRelease(encoder); +} + void RenderingDeviceDriverWebGpu::command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView p_secondary_cmd_buffers) {} /********************/ @@ -273,10 +332,23 @@ RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::compute_pipeline_ // ----- TIMESTAMP ----- // Basic. -RenderingDeviceDriver::QueryPoolID RenderingDeviceDriverWebGpu::timestamp_query_pool_create(uint32_t p_query_count) {} -void RenderingDeviceDriverWebGpu::timestamp_query_pool_free(QueryPoolID p_pool_id) {} -void RenderingDeviceDriverWebGpu::timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) {} -uint64_t RenderingDeviceDriverWebGpu::timestamp_query_result_to_time(uint64_t p_result) {} +RenderingDeviceDriver::QueryPoolID RenderingDeviceDriverWebGpu::timestamp_query_pool_create(uint32_t p_query_count) { + // TODO + return QueryPoolID(1); +} + +void RenderingDeviceDriverWebGpu::timestamp_query_pool_free(QueryPoolID p_pool_id) { + // TODO +} + +void RenderingDeviceDriverWebGpu::timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) { + // TODO +} + +uint64_t RenderingDeviceDriverWebGpu::timestamp_query_result_to_time(uint64_t p_result) { + // TODO + return 1; +} // Commands. void RenderingDeviceDriverWebGpu::command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) {} @@ -304,11 +376,25 @@ void RenderingDeviceDriverWebGpu::set_object_name(ObjectType p_type, ID p_driver uint64_t RenderingDeviceDriverWebGpu::get_resource_native_handle(DriverResource p_type, ID p_driver_id) {} uint64_t RenderingDeviceDriverWebGpu::get_total_memory_used() {} uint64_t RenderingDeviceDriverWebGpu::limit_get(Limit p_limit) {} -uint64_t RenderingDeviceDriverWebGpu::api_trait_get(ApiTrait p_trait) {} + +uint64_t RenderingDeviceDriverWebGpu::api_trait_get(ApiTrait p_trait) { + // TODO + return RenderingDeviceDriver::api_trait_get(p_trait); +} + bool RenderingDeviceDriverWebGpu::has_feature(Features p_feature) {} + const RenderingDeviceDriver::MultiviewCapabilities &RenderingDeviceDriverWebGpu::get_multiview_capabilities() {} -String RenderingDeviceDriverWebGpu::get_api_name() const {} -String RenderingDeviceDriverWebGpu::get_api_version() const {} + +String RenderingDeviceDriverWebGpu::get_api_name() const { + return "WebGpu"; +} + +String RenderingDeviceDriverWebGpu::get_api_version() const { + // We should compile this in based on the wgpu / dawn version + return "v0.19.3.1 (wgpu)"; +} + String RenderingDeviceDriverWebGpu::get_pipeline_cache_uuid() const {} const RenderingDeviceDriver::Capabilities &RenderingDeviceDriverWebGpu::get_capabilities() const {} diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 96e1cdc57e43..34387c9197a9 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -1,6 +1,7 @@ #ifndef RENDERING_DEVICE_DRIVER_WEBGPU_H #define RENDERING_DEVICE_DRIVER_WEBGPU_H +#include "core/templates/local_vector.h" #include "drivers/webgpu/rendering_context_driver_webgpu.h" #include "servers/rendering/rendering_context_driver.h" @@ -12,6 +13,9 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { RenderingContextDriverWebGpu *context_driver = nullptr; RenderingContextDriver::Device context_device; + // Note: Indexed by CommandBufferID with offset of 1, so that index 0 => 1. + TightLocalVector command_encoders; + public: Error initialize(uint32_t p_device_index, uint32_t p_frame_count) override final; From f738362bf7468aa79db9e1d96d154228cb52b272 Mon Sep 17 00:00:00 2001 From: dav Date: Sun, 31 Mar 2024 15:44:24 -0700 Subject: [PATCH 07/19] Properly name rendering_context_driver_webgpu.h header guard --- drivers/webgpu/rendering_context_driver_webgpu.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.h b/drivers/webgpu/rendering_context_driver_webgpu.h index 40334c91acde..86b823b244a2 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.h +++ b/drivers/webgpu/rendering_context_driver_webgpu.h @@ -1,5 +1,5 @@ -#ifndef RENDERING_CONTEXT_DRIVER_WGPU_H -#define RENDERING_CONTEXT_DRIVER_WGPU_H +#ifndef RENDERING_CONTEXT_DRIVER_WEBGPU_H +#define RENDERING_CONTEXT_DRIVER_WEBGPU_H #include "servers/rendering/rendering_context_driver.h" @@ -45,4 +45,4 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { void adapter_push_back(WGPUAdapter p_adapter, Device p_device); }; -#endif // RENDERING_CONTEXT_DRIVER_WGPU_H +#endif // RENDERING_CONTEXT_DRIVER_WEBGPU_H From 527d3b7bb68083097a2c7ccf5a76354e855f0ee8 Mon Sep 17 00:00:00 2001 From: dav Date: Sun, 31 Mar 2024 19:52:49 -0700 Subject: [PATCH 08/19] Fixes and stubs up to first texture_get_usages_supported_by_format --- .../rendering_context_driver_webgpu.cpp | 6 +- .../webgpu/rendering_device_driver_webgpu.cpp | 90 ++++++++++++++++--- .../webgpu/rendering_device_driver_webgpu.h | 7 +- drivers/webgpu/webgpu_conv.cpp | 30 +++++++ drivers/webgpu/webgpu_conv.h | 9 ++ 5 files changed, 124 insertions(+), 18 deletions(-) create mode 100644 drivers/webgpu/webgpu_conv.cpp create mode 100644 drivers/webgpu/webgpu_conv.h diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp index 40d526b78058..09e36ef4d68a 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -7,7 +7,7 @@ #include "rendering_device_driver_webgpu.h" -static void handleRequestAdapter(WGPURequestAdapterStatus status, +static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, char const *message, void *userdata) { ERR_FAIL_COND_V_MSG( @@ -50,12 +50,12 @@ Error RenderingContextDriverWebGpu::initialize() { adapter_options.powerPreference = WGPUPowerPreference::WGPUPowerPreference_HighPerformance; wgpuInstanceRequestAdapter(instance, &adapter_options, - handleRequestAdapter, this); + handle_request_adapter, this); adapter_options.powerPreference = WGPUPowerPreference::WGPUPowerPreference_LowPower; wgpuInstanceRequestAdapter(instance, &adapter_options, - handleRequestAdapter, this); + handle_request_adapter, this); return OK; } diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 06f537ade989..b2da31d52299 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -1,6 +1,7 @@ #include "rendering_device_driver_webgpu.h" +#include "webgpu_conv.h" -#include "core/error/error_macros.h" +#include static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, char const *message, @@ -25,21 +26,59 @@ Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t /**** BUFFERS ****/ /*****************/ -RenderingDeviceDriverWebGpu::BufferID RenderingDeviceDriverWebGpu::buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType p_allocation_type) { +RenderingDeviceDriverWebGpu::BufferID RenderingDeviceDriverWebGpu::buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType _p_allocation_type) { + WGPUBufferDescriptor desc = (WGPUBufferDescriptor){ + .usage = rd_to_webgpu_buffer_usage(p_usage), + .size = p_size, + .mappedAtCreation = false, + }; + WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &desc); + + BufferInfo *buffer_info = memnew(BufferInfo); + buffer_info->size = p_size; + buffer_info->buffer = buffer; + + return BufferID(buffer_info); } bool RenderingDeviceDriverWebGpu::buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) { } void RenderingDeviceDriverWebGpu::buffer_free(BufferID p_buffer) { + BufferInfo *buffer_info = (BufferInfo *)p_buffer.id; + wgpuBufferRelease(buffer_info->buffer); + memdelete(buffer_info); } uint64_t RenderingDeviceDriverWebGpu::buffer_get_allocation_size(BufferID p_buffer) { + // TODO + return 0; +} + +static void handle_buffer_map(WGPUBufferMapAsyncStatus status, void *userdata) { + ERR_FAIL_COND_V_MSG( + status != WGPUBufferMapAsyncStatus_Success, (void)0, + vformat("Failed to map buffer")); +} + +uint8_t *RenderingDeviceDriverWebGpu::buffer_map(BufferID p_buffer) { + BufferInfo *buffer_info = (BufferInfo *)p_buffer.id; + + uint64_t offset = 0; + uint64_t size = buffer_info->size; + + wgpuBufferMapAsync( + buffer_info->buffer, WGPUMapMode::WGPUMapMode_Write, offset, size, handle_buffer_map, nullptr); + wgpuDevicePoll(device, true, nullptr); + const void *data = wgpuBufferGetConstMappedRange(buffer_info->buffer, offset, size); + return (uint8_t *)data; } -uint8_t *RenderingDeviceDriverWebGpu::buffer_map(BufferID p_buffer) {} +void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) { + WGPUBuffer buffer = (WGPUBuffer)p_buffer.id; -void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) {} + wgpuBufferUnmap(buffer); +} /*****************/ /**** TEXTURE ****/ @@ -159,7 +198,7 @@ RenderingDeviceDriver::CommandBufferID RenderingDeviceDriverWebGpu::command_buff bool RenderingDeviceDriverWebGpu::command_buffer_begin(CommandBufferID p_cmd_buffer) { DEV_ASSERT(p_cmd_buffer - 1 < command_encoders.size()); - WGPUCommandEncoder& encoder_spot = command_encoders[p_cmd_buffer - 1]; + WGPUCommandEncoder &encoder_spot = command_encoders[p_cmd_buffer - 1]; DEV_ASSERT(encoder_spot == nullptr); WGPUCommandEncoderDescriptor desc = (WGPUCommandEncoderDescriptor){}; @@ -176,7 +215,7 @@ bool RenderingDeviceDriverWebGpu::command_buffer_begin_secondary(CommandBufferID void RenderingDeviceDriverWebGpu::command_buffer_end(CommandBufferID p_cmd_buffer) { DEV_ASSERT(p_cmd_buffer - 1 < command_encoders.size()); - WGPUCommandEncoder& encoder = command_encoders[p_cmd_buffer - 1]; + WGPUCommandEncoder &encoder = command_encoders[p_cmd_buffer - 1]; DEV_ASSERT(encoder == nullptr); wgpuCommandEncoderRelease(encoder); @@ -188,12 +227,22 @@ void RenderingDeviceDriverWebGpu::command_buffer_execute_secondary(CommandBuffer /**** SWAP CHAIN ****/ /********************/ -RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {} -Error RenderingDeviceDriverWebGpu::swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) {} +RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_create(RenderingContextDriver::SurfaceID _p_surface) { + return SwapChainID(1); +} + +Error RenderingDeviceDriverWebGpu::swap_chain_resize(CommandQueueID _p_cmd_queue, SwapChainID _p_swap_chain, uint32_t _p_desired_framebuffer_count) { + // WebGpu's swapchain is contained within the surface. + return OK; +} + RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) {} RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::swap_chain_get_render_pass(SwapChainID p_swap_chain) {} RenderingDeviceDriver::DataFormat RenderingDeviceDriverWebGpu::swap_chain_get_format(SwapChainID p_swap_chain) {} -void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID p_swap_chain) {} + +void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID _p_swap_chain) { + // Empty. +} /*********************/ /**** FRAMEBUFFER ****/ @@ -206,7 +255,11 @@ void RenderingDeviceDriverWebGpu::framebuffer_free(FramebufferID p_framebuffer) /**** SHADER ****/ /****************/ -String RenderingDeviceDriverWebGpu::shader_get_binary_cache_key() {} +String RenderingDeviceDriverWebGpu::shader_get_binary_cache_key() { + // TODO + return ""; +} + Vector RenderingDeviceDriverWebGpu::shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) {} RenderingDeviceDriver::ShaderID RenderingDeviceDriverWebGpu::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) {} void RenderingDeviceDriverWebGpu::shader_free(ShaderID p_shader) {} @@ -248,10 +301,19 @@ void RenderingDeviceDriverWebGpu::command_bind_push_constants(CommandBufferID p_ // ----- CACHE ----- -bool RenderingDeviceDriverWebGpu::pipeline_cache_create(const Vector &p_data) {} -void RenderingDeviceDriverWebGpu::pipeline_cache_free() {} -size_t RenderingDeviceDriverWebGpu::pipeline_cache_query_size() {} -Vector RenderingDeviceDriverWebGpu::pipeline_cache_serialize() {} +bool RenderingDeviceDriverWebGpu::pipeline_cache_create(const Vector &_p_data) { + // WebGpu does not have pipeline caches. + return false; +} +void RenderingDeviceDriverWebGpu::pipeline_cache_free() { + // Empty. +} +size_t RenderingDeviceDriverWebGpu::pipeline_cache_query_size() { + return 0; +} +Vector RenderingDeviceDriverWebGpu::pipeline_cache_serialize() { + return Vector(); +} /*******************/ /**** RENDERING ****/ diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 34387c9197a9..89ac11aba135 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -19,11 +19,16 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { public: Error initialize(uint32_t p_device_index, uint32_t p_frame_count) override final; -public: +private: /*****************/ /**** BUFFERS ****/ /*****************/ + struct BufferInfo { + WGPUBuffer buffer; + uint64_t size; + }; + public: virtual BufferID buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType p_allocation_type) override final; virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) override final; diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp new file mode 100644 index 000000000000..737b43a3e7e1 --- /dev/null +++ b/drivers/webgpu/webgpu_conv.cpp @@ -0,0 +1,30 @@ +#include "webgpu_conv.h" + +WGPUBufferUsage rd_to_webgpu_buffer_usage(BitField p_buffer_usage) { + int ret = 0; + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_TRANSFER_FROM_BIT) { + ret |= WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_TRANSFER_TO_BIT) { + ret = WGPUBufferUsage_MapWrite | WGPUBufferUsage_CopySrc; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_TEXEL_BIT) { + ret = WGPUBufferUsage_MapWrite | WGPUBufferUsage_CopySrc; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_UNIFORM_BIT) { + ret = WGPUBufferUsage_Uniform; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_STORAGE_BIT) { + ret = WGPUBufferUsage_Storage; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_INDEX_BIT) { + ret = WGPUBufferUsage_Index; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_VERTEX_BIT) { + ret = WGPUBufferUsage_Vertex; + } + if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_INDIRECT_BIT) { + ret = WGPUBufferUsage_Indirect; + } + return (WGPUBufferUsage)ret; +} diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h new file mode 100644 index 000000000000..0afa5189b265 --- /dev/null +++ b/drivers/webgpu/webgpu_conv.h @@ -0,0 +1,9 @@ +#ifndef WEBGPU_CONV_H +#define WEBGPU_CONV_H + +#include "servers/rendering/rendering_device.h" +#include + +WGPUBufferUsage rd_to_webgpu_buffer_usage(BitField p_buffer_usage); + +#endif // WEBGPU_CONV_H From 7fc742032d20d6e9b92279979682fcff72607005 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 10:22:51 -0700 Subject: [PATCH 09/19] ixes and stubs up to first sampler_create --- .../rendering_context_driver_webgpu.cpp | 1 + .../webgpu/rendering_device_driver_webgpu.cpp | 162 ++++++++++++++++-- .../webgpu/rendering_device_driver_webgpu.h | 13 ++ drivers/webgpu/webgpu_conv.cpp | 132 +++++++++++++- drivers/webgpu/webgpu_conv.h | 3 +- 5 files changed, 296 insertions(+), 15 deletions(-) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.cpp b/drivers/webgpu/rendering_context_driver_webgpu.cpp index 09e36ef4d68a..16e1b0ae7d27 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_context_driver_webgpu.cpp @@ -1,4 +1,5 @@ #include "webgpu.h" + #ifdef WEBGPU_ENABLED #include "rendering_context_driver_webgpu.h" diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index b2da31d52299..67caa92f074d 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -27,21 +27,38 @@ Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t /*****************/ RenderingDeviceDriverWebGpu::BufferID RenderingDeviceDriverWebGpu::buffer_create(uint64_t p_size, BitField p_usage, MemoryAllocationType _p_allocation_type) { + WGPUBufferUsage usage = webgpu_buffer_usage_from_rd(p_usage); + uint32_t map_mode = 0; + bool is_transfer_buffer = false; + + if (usage & WGPUBufferUsage_MapRead) { + map_mode |= WGPUMapMode_Read; + is_transfer_buffer = true; + } + if (usage & WGPUBufferUsage_MapWrite) { + map_mode |= WGPUMapMode_Write; + is_transfer_buffer = true; + } + WGPUBufferDescriptor desc = (WGPUBufferDescriptor){ - .usage = rd_to_webgpu_buffer_usage(p_usage), + .usage = usage, .size = p_size, - .mappedAtCreation = false, + .mappedAtCreation = is_transfer_buffer, }; WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &desc); BufferInfo *buffer_info = memnew(BufferInfo); buffer_info->size = p_size; buffer_info->buffer = buffer; + buffer_info->map_mode = (WGPUMapMode)map_mode; + buffer_info->is_transfer_first_map = is_transfer_buffer; return BufferID(buffer_info); } bool RenderingDeviceDriverWebGpu::buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) { + // TODO + return true; } void RenderingDeviceDriverWebGpu::buffer_free(BufferID p_buffer) { @@ -67,33 +84,151 @@ uint8_t *RenderingDeviceDriverWebGpu::buffer_map(BufferID p_buffer) { uint64_t offset = 0; uint64_t size = buffer_info->size; - wgpuBufferMapAsync( - buffer_info->buffer, WGPUMapMode::WGPUMapMode_Write, offset, size, handle_buffer_map, nullptr); - wgpuDevicePoll(device, true, nullptr); + if (!buffer_info->is_transfer_first_map) { + wgpuBufferMapAsync( + buffer_info->buffer, buffer_info->map_mode, offset, size, handle_buffer_map, nullptr); + wgpuDevicePoll(device, true, nullptr); + } else { + buffer_info->is_transfer_first_map = false; + } const void *data = wgpuBufferGetConstMappedRange(buffer_info->buffer, offset, size); return (uint8_t *)data; } void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) { - WGPUBuffer buffer = (WGPUBuffer)p_buffer.id; + BufferInfo* buffer_info = (BufferInfo*)p_buffer.id; - wgpuBufferUnmap(buffer); + wgpuBufferUnmap(buffer_info->buffer); } /*****************/ /**** TEXTURE ****/ /*****************/ -RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create(const TextureFormat &p_format, const TextureView &p_view) {} +RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create(const TextureFormat &p_format, const TextureView &p_view) { + WGPUFlags usage_bits = WGPUTextureUsage_None; + if ((p_format.usage_bits & TEXTURE_USAGE_STORAGE_BIT)) { + usage_bits |= WGPUTextureUsage_StorageBinding; + } + if ((p_format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) { + usage_bits |= WGPUTextureUsage_TextureBinding; + } + if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) || (p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) { + usage_bits |= WGPUTextureUsage_RenderAttachment; + } + if ((p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT)) { + usage_bits |= WGPUTextureUsage_CopyDst; + } + if ((p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_FROM_BIT)) { + usage_bits |= WGPUTextureUsage_CopySrc; + } + if ((p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_TO_BIT)) { + usage_bits |= WGPUTextureUsage_CopyDst; + } + WGPUTextureUsage usage = (WGPUTextureUsage)usage_bits; + + WGPUExtent3D size; + size.width = p_format.width; + size.height = p_format.height; + size.depthOrArrayLayers = 1; + WGPUTextureDimension dimension; + bool is_using_depth = false; + + if (p_format.texture_type == TEXTURE_TYPE_1D) { + dimension = WGPUTextureDimension_1D; + } else if (p_format.texture_type == TEXTURE_TYPE_2D) { + size.depthOrArrayLayers = p_format.array_layers; + dimension = WGPUTextureDimension_2D; + } else if (p_format.texture_type == TEXTURE_TYPE_3D) { + size.depthOrArrayLayers = p_format.depth; + is_using_depth = true; + dimension = WGPUTextureDimension_3D; + } else if (p_format.texture_type == TEXTURE_TYPE_1D_ARRAY) { + size.depthOrArrayLayers = p_format.array_layers; + dimension = WGPUTextureDimension_1D; + } else if (p_format.texture_type == TEXTURE_TYPE_2D_ARRAY) { + size.depthOrArrayLayers = p_format.array_layers; + dimension = WGPUTextureDimension_2D; + } else if (p_format.texture_type == TEXTURE_TYPE_CUBE) { + size.depthOrArrayLayers = p_format.array_layers; + dimension = WGPUTextureDimension_2D; + } else if (p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY) { + size.depthOrArrayLayers = p_format.array_layers; + dimension = WGPUTextureDimension_2D; + } + + if (p_format.samples > TextureSamples::TEXTURE_SAMPLES_1) { + usage_bits |= WGPUTextureUsage_RenderAttachment; + } + + uint32_t mip_level_count = p_format.mipmaps ? p_format.mipmaps : 1; + + // TODO: Assert that p_format.samples follows this behavior. + uint32_t sample_count = pow(2, (uint32_t)p_format.samples); + + Vector view_formats; + + for (int i = 0; i < p_format.shareable_formats.size(); i++) { + DataFormat format = p_format.shareable_formats[i]; + view_formats.push_back(webgpu_texture_format_from_rd(format)); + } + + WGPUTextureDescriptor texture_desc = (WGPUTextureDescriptor){ + .usage = usage, + .dimension = dimension, + .size = size, + .format = webgpu_texture_format_from_rd(p_format.format), + .mipLevelCount = mip_level_count, + .sampleCount = sample_count, + .viewFormatCount = (size_t)view_formats.size(), + .viewFormats = view_formats.ptr(), + }; + + WGPUTexture texture = wgpuDeviceCreateTexture(device, &texture_desc); + + WGPUTextureViewDescriptor texture_view_desc = (WGPUTextureViewDescriptor){ + .format = webgpu_texture_format_from_rd(p_view.format), + .mipLevelCount = texture_desc.mipLevelCount, + .arrayLayerCount = is_using_depth ? 1 : texture_desc.size.depthOrArrayLayers, + }; + + WGPUTextureView view = wgpuTextureCreateView(texture, &texture_view_desc); + + TextureInfo *texture_info = memnew(TextureInfo); + texture_info->texture = texture; + texture_info->view = view; + texture_info->width = size.width; + texture_info->height = size.height; + texture_info->depth_or_array = size.depthOrArrayLayers; + + return TextureID(texture_info); +} + RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) {} RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) {} RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) {} -void RenderingDeviceDriverWebGpu::texture_free(TextureID p_texture) {} -uint64_t RenderingDeviceDriverWebGpu::texture_get_allocation_size(TextureID p_texture) {} + +void RenderingDeviceDriverWebGpu::texture_free(TextureID p_texture) { + TextureInfo *texture_info = (TextureInfo *)p_texture.id; + wgpuTextureRelease(texture_info->texture); + wgpuTextureViewRelease(texture_info->view); + memdelete(texture_info); +} + +uint64_t RenderingDeviceDriverWebGpu::texture_get_allocation_size(TextureID p_texture) { + // TODO + return 1; +} + void RenderingDeviceDriverWebGpu::texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) {} uint8_t *RenderingDeviceDriverWebGpu::texture_map(TextureID p_texture, const TextureSubresource &p_subresource) {} void RenderingDeviceDriverWebGpu::texture_unmap(TextureID p_texture) {} -BitField RenderingDeviceDriverWebGpu::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) {} + +BitField RenderingDeviceDriverWebGpu::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) { + // TODO: Read this https://www.w3.org/TR/webgpu/#texture-format-caps + BitField supported = INT64_MAX; + return supported; +} /*****************/ /**** SAMPLER ****/ @@ -444,7 +579,10 @@ uint64_t RenderingDeviceDriverWebGpu::api_trait_get(ApiTrait p_trait) { return RenderingDeviceDriver::api_trait_get(p_trait); } -bool RenderingDeviceDriverWebGpu::has_feature(Features p_feature) {} +bool RenderingDeviceDriverWebGpu::has_feature(Features p_feature) { + // TODO + return false; +} const RenderingDeviceDriver::MultiviewCapabilities &RenderingDeviceDriverWebGpu::get_multiview_capabilities() {} diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 89ac11aba135..17a61ff76e8d 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -26,7 +26,11 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { struct BufferInfo { WGPUBuffer buffer; + WGPUMapMode map_mode; uint64_t size; + + // Transfer buffers will be mapped on creation. + bool is_transfer_first_map; }; public: @@ -41,6 +45,15 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { /**** TEXTURE ****/ /*****************/ +private: + struct TextureInfo { + WGPUTexture texture; + WGPUTextureView view; + uint32_t width; + uint32_t height; + uint32_t depth_or_array; + }; + public: virtual TextureID texture_create(const TextureFormat &p_format, const TextureView &p_view) override final; virtual TextureID texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) override final; diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp index 737b43a3e7e1..0a09262aef71 100644 --- a/drivers/webgpu/webgpu_conv.cpp +++ b/drivers/webgpu/webgpu_conv.cpp @@ -1,7 +1,8 @@ #include "webgpu_conv.h" +#include "webgpu.h" -WGPUBufferUsage rd_to_webgpu_buffer_usage(BitField p_buffer_usage) { - int ret = 0; +WGPUBufferUsage webgpu_buffer_usage_from_rd(BitField p_buffer_usage) { + uint32_t ret = 0; if (p_buffer_usage & RDD::BufferUsageBits::BUFFER_USAGE_TRANSFER_FROM_BIT) { ret |= WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst; } @@ -28,3 +29,130 @@ WGPUBufferUsage rd_to_webgpu_buffer_usage(BitField p_buffe } return (WGPUBufferUsage)ret; } + +WGPUTextureFormat webgpu_texture_format_from_rd(RDD::DataFormat p_data_format) { + WGPUTextureFormat ret = WGPUTextureFormat_Undefined; + + // See https://www.w3.org/TR/webgpu/#enumdef-gputextureformat + // TODO: The BC, ETC2, and ASTC compressed formats have been left out. + switch (p_data_format) { + case RDD::DataFormat::DATA_FORMAT_R8_UNORM: + ret = WGPUTextureFormat_R8Unorm; + break; + case RDD::DataFormat::DATA_FORMAT_R8_SNORM: + ret = WGPUTextureFormat_R8Snorm; + break; + case RDD::DataFormat::DATA_FORMAT_R8_UINT: + ret = WGPUTextureFormat_R8Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R8_SINT: + ret = WGPUTextureFormat_R8Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R16_UINT: + ret = WGPUTextureFormat_R16Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R16_SINT: + ret = WGPUTextureFormat_R16Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R16_SFLOAT: + ret = WGPUTextureFormat_R16Float; + break; + case RDD::DataFormat::DATA_FORMAT_R32_UINT: + ret = WGPUTextureFormat_R32Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R32_SINT: + ret = WGPUTextureFormat_R32Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R32_SFLOAT: + ret = WGPUTextureFormat_R32Float; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8_UNORM: + ret = WGPUTextureFormat_RG8Unorm; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8_SNORM: + ret = WGPUTextureFormat_RG8Snorm; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8_UINT: + ret = WGPUTextureFormat_RG8Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8_SINT: + ret = WGPUTextureFormat_RG8Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16_UINT: + ret = WGPUTextureFormat_RG16Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16_SINT: + ret = WGPUTextureFormat_RG16Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16_SFLOAT: + ret = WGPUTextureFormat_RG16Float; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_UNORM: + ret = WGPUTextureFormat_RGBA8Unorm; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_SRGB: + ret = WGPUTextureFormat_RGBA8UnormSrgb; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_SNORM: + ret = WGPUTextureFormat_RGBA8Snorm; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_UINT: + ret = WGPUTextureFormat_RGBA8Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_SINT: + ret = WGPUTextureFormat_RGBA8Sint; + break; + case RDD::DataFormat::DATA_FORMAT_B8G8R8A8_UNORM: + ret = WGPUTextureFormat_BGRA8Unorm; + break; + case RDD::DataFormat::DATA_FORMAT_B8G8R8A8_SRGB: + ret = WGPUTextureFormat_BGRA8UnormSrgb; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32_UINT: + ret = WGPUTextureFormat_RG32Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32_SINT: + ret = WGPUTextureFormat_RG32Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32_SFLOAT: + ret = WGPUTextureFormat_RG32Float; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16B16A16_UINT: + ret = WGPUTextureFormat_RGBA16Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16B16A16_SINT: + ret = WGPUTextureFormat_RGBA16Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16B16A16_SFLOAT: + ret = WGPUTextureFormat_RGBA16Float; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32B32A32_UINT: + ret = WGPUTextureFormat_RGBA32Uint; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32B32A32_SINT: + ret = WGPUTextureFormat_RGBA32Sint; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32B32A32_SFLOAT: + ret = WGPUTextureFormat_RGBA32Float; + break; + case RDD::DataFormat::DATA_FORMAT_S8_UINT: + ret = WGPUTextureFormat_Stencil8; + break; + case RDD::DataFormat::DATA_FORMAT_D16_UNORM: + ret = WGPUTextureFormat_Depth16Unorm; + break; + case RDD::DataFormat::DATA_FORMAT_D24_UNORM_S8_UINT: + ret = WGPUTextureFormat_Depth24PlusStencil8; + break; + case RDD::DataFormat::DATA_FORMAT_D32_SFLOAT: + ret = WGPUTextureFormat_Depth32Float; + break; + case RDD::DataFormat::DATA_FORMAT_D32_SFLOAT_S8_UINT: + ret = WGPUTextureFormat_Depth32FloatStencil8; + break; + default: + break; + } + + return ret; +} diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h index 0afa5189b265..5632ce9c82ee 100644 --- a/drivers/webgpu/webgpu_conv.h +++ b/drivers/webgpu/webgpu_conv.h @@ -4,6 +4,7 @@ #include "servers/rendering/rendering_device.h" #include -WGPUBufferUsage rd_to_webgpu_buffer_usage(BitField p_buffer_usage); +WGPUBufferUsage webgpu_buffer_usage_from_rd(BitField p_buffer_usage); +WGPUTextureFormat webgpu_texture_format_from_rd(RDD::DataFormat p_data_format); #endif // WEBGPU_CONV_H From b8f3242bbf1dbbe7b8415f3d67a4486a600fd610 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 11:03:53 -0700 Subject: [PATCH 10/19] Implement sampler create and free --- .../webgpu/rendering_device_driver_webgpu.cpp | 29 ++++++++-- drivers/webgpu/webgpu_conv.cpp | 54 +++++++++++++++++++ drivers/webgpu/webgpu_conv.h | 4 ++ 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 67caa92f074d..152489a460a2 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -96,7 +96,7 @@ uint8_t *RenderingDeviceDriverWebGpu::buffer_map(BufferID p_buffer) { } void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) { - BufferInfo* buffer_info = (BufferInfo*)p_buffer.id; + BufferInfo *buffer_info = (BufferInfo *)p_buffer.id; wgpuBufferUnmap(buffer_info->buffer); } @@ -234,8 +234,31 @@ BitField RenderingDeviceDriverWebGpu::t /**** SAMPLER ****/ /*****************/ -RenderingDeviceDriver::SamplerID RenderingDeviceDriverWebGpu::sampler_create(const SamplerState &p_state) {} -void RenderingDeviceDriverWebGpu::sampler_free(SamplerID p_sampler) {} +RenderingDeviceDriver::SamplerID RenderingDeviceDriverWebGpu::sampler_create(const SamplerState &p_state) { + // STUB: Samplers with anisotropy enabled cannot support nearest filtering. + // See https://gpuweb.github.io/gpuweb/#sampler-creation + WGPUSamplerDescriptor sampler_desc = (WGPUSamplerDescriptor){ + .addressModeU = webgpu_address_mode_from_rd(p_state.repeat_u), + .addressModeV = webgpu_address_mode_from_rd(p_state.repeat_v), + .addressModeW = webgpu_address_mode_from_rd(p_state.repeat_w), + .magFilter = p_state.use_anisotropy ? WGPUFilterMode_Linear : webgpu_filter_mode_from_rd(p_state.mag_filter), + .minFilter = p_state.use_anisotropy ? WGPUFilterMode_Linear : webgpu_filter_mode_from_rd(p_state.min_filter), + .mipmapFilter = p_state.use_anisotropy ? WGPUMipmapFilterMode_Linear : webgpu_mipmap_filter_mode_from_rd(p_state.mip_filter), + .lodMinClamp = p_state.min_lod, + .lodMaxClamp = p_state.max_lod, + .compare = p_state.enable_compare ? webgpu_compare_mode_from_rd(p_state.compare_op) : WGPUCompareFunction_Always, + .maxAnisotropy = p_state.use_anisotropy ? (uint16_t)p_state.anisotropy_max : (uint16_t)1, + }; + + WGPUSampler sampler = wgpuDeviceCreateSampler(device, &sampler_desc); + return SamplerID(sampler); +} + +void RenderingDeviceDriverWebGpu::sampler_free(SamplerID p_sampler) { + WGPUSampler sampler = (WGPUSampler)p_sampler.id; + wgpuSamplerRelease(sampler); +} + bool RenderingDeviceDriverWebGpu::sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) {} /**********************/ diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp index 0a09262aef71..9844c924c183 100644 --- a/drivers/webgpu/webgpu_conv.cpp +++ b/drivers/webgpu/webgpu_conv.cpp @@ -156,3 +156,57 @@ WGPUTextureFormat webgpu_texture_format_from_rd(RDD::DataFormat p_data_format) { return ret; } + +WGPUFilterMode webgpu_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter) { + static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_NEAREST, WGPUFilterMode_Nearest)); + static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_LINEAR, WGPUFilterMode_Linear)); + return (WGPUFilterMode)p_sampler_filter; +} + +WGPUMipmapFilterMode webgpu_mipmap_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter) { + static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_NEAREST, WGPUMipmapFilterMode_Nearest)); + static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_LINEAR, WGPUMipmapFilterMode_Linear)); + return (WGPUMipmapFilterMode)p_sampler_filter; +} + +WGPUAddressMode webgpu_address_mode_from_rd(RDD::SamplerRepeatMode p_sampler_repeat_mode) { + // Not all of these exist, so we'll default to clamp to edge. + // See https://gpuweb.github.io/gpuweb/#enumdef-gpuaddressmode + switch (p_sampler_repeat_mode) { + case RenderingDeviceCommons::SAMPLER_REPEAT_MODE_REPEAT: + return WGPUAddressMode_Repeat; + case RenderingDeviceCommons::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT: + return WGPUAddressMode_MirrorRepeat; + case RenderingDeviceCommons::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE: + return WGPUAddressMode_ClampToEdge; + case RenderingDeviceCommons::SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER: + return WGPUAddressMode_ClampToEdge; + case RenderingDeviceCommons::SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE: + return WGPUAddressMode_ClampToEdge; + case RenderingDeviceCommons::SAMPLER_REPEAT_MODE_MAX: + return WGPUAddressMode_ClampToEdge; + } +} + +WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_operator) { + switch (p_compare_operator) { + case RenderingDeviceCommons::COMPARE_OP_NEVER: + return WGPUCompareFunction_Never; + case RenderingDeviceCommons::COMPARE_OP_LESS: + return WGPUCompareFunction_Less; + case RenderingDeviceCommons::COMPARE_OP_EQUAL: + return WGPUCompareFunction_Equal; + case RenderingDeviceCommons::COMPARE_OP_LESS_OR_EQUAL: + return WGPUCompareFunction_LessEqual; + case RenderingDeviceCommons::COMPARE_OP_GREATER: + return WGPUCompareFunction_Greater; + case RenderingDeviceCommons::COMPARE_OP_NOT_EQUAL: + return WGPUCompareFunction_NotEqual; + case RenderingDeviceCommons::COMPARE_OP_GREATER_OR_EQUAL: + return WGPUCompareFunction_GreaterEqual; + case RenderingDeviceCommons::COMPARE_OP_ALWAYS: + return WGPUCompareFunction_Always; + case RenderingDeviceCommons::COMPARE_OP_MAX: + return WGPUCompareFunction_Undefined; + } +} diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h index 5632ce9c82ee..c680ab696347 100644 --- a/drivers/webgpu/webgpu_conv.h +++ b/drivers/webgpu/webgpu_conv.h @@ -6,5 +6,9 @@ WGPUBufferUsage webgpu_buffer_usage_from_rd(BitField p_buffer_usage); WGPUTextureFormat webgpu_texture_format_from_rd(RDD::DataFormat p_data_format); +WGPUFilterMode webgpu_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter); +WGPUMipmapFilterMode webgpu_mipmap_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter); +WGPUAddressMode webgpu_address_mode_from_rd(RDD::SamplerRepeatMode p_sampler_repeat_mode); +WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_operator); #endif // WEBGPU_CONV_H From 3381956e831d386c485dd7c75811b10540de6f08 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 13:34:11 -0700 Subject: [PATCH 11/19] Implement get limits and render pass --- .../webgpu/rendering_device_driver_webgpu.cpp | 35 +++++-- .../webgpu/rendering_device_driver_webgpu.h | 6 ++ drivers/webgpu/webgpu_conv.cpp | 95 +++++++++++++++++++ drivers/webgpu/webgpu_conv.h | 2 + 4 files changed, 131 insertions(+), 7 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 152489a460a2..9b327c820b18 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -10,13 +10,13 @@ static void handle_request_device(WGPURequestDeviceStatus status, } Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t p_frame_count) { - WGPUAdapter adapter = context_driver->adapter_get(p_device_index); - this->context_device = context_driver->device_get(p_device_index); + adapter = context_driver->adapter_get(p_device_index); + context_device = context_driver->device_get(p_device_index); wgpuAdapterRequestDevice(adapter, nullptr, handle_request_device, &this->device); ERR_FAIL_COND_V(!this->device, FAILED); - this->queue = wgpuDeviceGetQueue(device); + queue = wgpuDeviceGetQueue(device); ERR_FAIL_COND_V(!this->queue, FAILED); return OK; @@ -241,7 +241,7 @@ RenderingDeviceDriver::SamplerID RenderingDeviceDriverWebGpu::sampler_create(con .addressModeU = webgpu_address_mode_from_rd(p_state.repeat_u), .addressModeV = webgpu_address_mode_from_rd(p_state.repeat_v), .addressModeW = webgpu_address_mode_from_rd(p_state.repeat_w), - .magFilter = p_state.use_anisotropy ? WGPUFilterMode_Linear : webgpu_filter_mode_from_rd(p_state.mag_filter), + .magFilter = p_state.use_anisotropy ? WGPUFilterMode_Linear : webgpu_filter_mode_from_rd(p_state.mag_filter), .minFilter = p_state.use_anisotropy ? WGPUFilterMode_Linear : webgpu_filter_mode_from_rd(p_state.min_filter), .mipmapFilter = p_state.use_anisotropy ? WGPUMipmapFilterMode_Linear : webgpu_mipmap_filter_mode_from_rd(p_state.mip_filter), .lodMinClamp = p_state.min_lod, @@ -479,8 +479,23 @@ Vector RenderingDeviceDriverWebGpu::pipeline_cache_serialize() { // ----- SUBPASS ----- -RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::render_pass_create(VectorView p_attachments, VectorView p_subpasses, VectorView p_subpass_dependencies, uint32_t p_view_count) {} -void RenderingDeviceDriverWebGpu::render_pass_free(RenderPassID p_render_pass) {} +RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::render_pass_create(VectorView p_attachments, VectorView _p_subpasses, VectorView _p_subpass_dependencies, uint32_t p_view_count) { + // WebGpu does not have subpasses so we will store this info until we create a render pipeline later. + RenderPassInfo *render_pass_info = memnew(RenderPassInfo); + + render_pass_info->attachments = Vector(); + for (int i = 0; i < p_attachments.size(); i++) { + render_pass_info->attachments.push_back(p_attachments[i]); + } + + render_pass_info->view_count = p_view_count; + + return RenderPassID(render_pass_info); +} +void RenderingDeviceDriverWebGpu::render_pass_free(RenderPassID p_render_pass) { + RenderPassInfo *render_pass_info = (RenderPassInfo *)p_render_pass.id; + memdelete(render_pass_info); +} // ----- COMMANDS ----- @@ -595,7 +610,13 @@ void RenderingDeviceDriverWebGpu::end_segment() {} void RenderingDeviceDriverWebGpu::set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) {} uint64_t RenderingDeviceDriverWebGpu::get_resource_native_handle(DriverResource p_type, ID p_driver_id) {} uint64_t RenderingDeviceDriverWebGpu::get_total_memory_used() {} -uint64_t RenderingDeviceDriverWebGpu::limit_get(Limit p_limit) {} +uint64_t RenderingDeviceDriverWebGpu::limit_get(Limit p_limit) { + WGPUSupportedLimitsExtras extras; + WGPUSupportedLimits limits; + limits.nextInChain = (WGPUChainedStructOut *)&extras; + wgpuDeviceGetLimits(device, &limits); + return rd_limit_from_webgpu(p_limit, limits); +} uint64_t RenderingDeviceDriverWebGpu::api_trait_get(ApiTrait p_trait) { // TODO diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 17a61ff76e8d..43dcfe152b67 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -9,6 +9,7 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { WGPUDevice device = nullptr; + WGPUAdapter adapter = nullptr; WGPUQueue queue = nullptr; RenderingContextDriverWebGpu *context_driver = nullptr; RenderingContextDriver::Device context_device; @@ -218,6 +219,11 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { // ----- SUBPASS ----- + struct RenderPassInfo { + Vector attachments; + uint32_t view_count; + }; + virtual RenderPassID render_pass_create(VectorView p_attachments, VectorView p_subpasses, VectorView p_subpass_dependencies, uint32_t p_view_count) override final; virtual void render_pass_free(RenderPassID p_render_pass) override final; diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp index 9844c924c183..598ce0da52c9 100644 --- a/drivers/webgpu/webgpu_conv.cpp +++ b/drivers/webgpu/webgpu_conv.cpp @@ -210,3 +210,98 @@ WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_o return WGPUCompareFunction_Undefined; } } + +uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits) { + WGPULimits limits = p_limits.limits; + // Note: For limits that aren't supported, I've put the max uint64 value. This may cause issues. + switch (p_selected_limit) { + case RenderingDeviceCommons::LIMIT_MAX_BOUND_UNIFORM_SETS: + return limits.maxBindGroups; + case RenderingDeviceCommons::LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS: + return limits.maxColorAttachments; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURES_PER_UNIFORM_SET: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET: + return limits.maxUniformBuffersPerShaderStage; + case RenderingDeviceCommons::LIMIT_MAX_DRAW_INDEXED_INDEX: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_FRAMEBUFFER_HEIGHT: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_FRAMEBUFFER_WIDTH: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURE_ARRAY_LAYERS: + return limits.maxTextureArrayLayers; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURE_SIZE_1D: + return limits.maxTextureDimension1D; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURE_SIZE_2D: + return limits.maxTextureDimension2D; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURE_SIZE_3D: + return limits.maxTextureDimension3D; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURE_SIZE_CUBE: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE: + return limits.maxSampledTexturesPerShaderStage; + case RenderingDeviceCommons::LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE: + return limits.maxSamplersPerShaderStage; + case RenderingDeviceCommons::LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: + return limits.maxStorageBuffersPerShaderStage; + case RenderingDeviceCommons::LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE: + return limits.maxStorageTexturesPerShaderStage; + case RenderingDeviceCommons::LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE: + return limits.maxUniformBuffersPerShaderStage; + case RenderingDeviceCommons::LIMIT_MAX_PUSH_CONSTANT_SIZE: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_UNIFORM_BUFFER_SIZE: + return limits.maxUniformBufferBindingSize; + case RenderingDeviceCommons::LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES: + return limits.maxVertexAttributes; + case RenderingDeviceCommons::LIMIT_MAX_VERTEX_INPUT_BINDINGS: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + return limits.minUniformBufferOffsetAlignment; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS: + return limits.maxComputeInvocationsPerWorkgroup; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X: + return limits.maxComputeWorkgroupSizeX; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y: + return limits.maxComputeWorkgroupSizeY; + case RenderingDeviceCommons::LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z: + return limits.maxComputeWorkgroupSizeZ; + case RenderingDeviceCommons::LIMIT_MAX_VIEWPORT_DIMENSIONS_X: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_MAX_VIEWPORT_DIMENSIONS_Y: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_SUBGROUP_SIZE: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_SUBGROUP_MIN_SIZE: + return 0; + case RenderingDeviceCommons::LIMIT_SUBGROUP_MAX_SIZE: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_SUBGROUP_IN_SHADERS: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_SUBGROUP_OPERATIONS: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_VRS_TEXEL_WIDTH: + return UINT64_MAX; + case RenderingDeviceCommons::LIMIT_VRS_TEXEL_HEIGHT: + return UINT64_MAX; + } +} diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h index c680ab696347..554d5b69797d 100644 --- a/drivers/webgpu/webgpu_conv.h +++ b/drivers/webgpu/webgpu_conv.h @@ -11,4 +11,6 @@ WGPUMipmapFilterMode webgpu_mipmap_filter_mode_from_rd(RDD::SamplerFilter p_samp WGPUAddressMode webgpu_address_mode_from_rd(RDD::SamplerRepeatMode p_sampler_repeat_mode); WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_operator); +uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits); + #endif // WEBGPU_CONV_H From 64640df4d304140a61412aaf7187f16fca5d8898 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 19:33:40 -0700 Subject: [PATCH 12/19] Implement vertex array --- .../webgpu/rendering_device_driver_webgpu.cpp | 31 ++++++++- drivers/webgpu/webgpu_conv.cpp | 68 +++++++++++++++++++ drivers/webgpu/webgpu_conv.h | 1 + 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 9b327c820b18..d6bfd211143e 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -265,8 +265,35 @@ bool RenderingDeviceDriverWebGpu::sampler_is_format_supported_for_filter(DataFor /**** VERTEX ARRAY ****/ /**********************/ -RenderingDeviceDriver::VertexFormatID RenderingDeviceDriverWebGpu::vertex_format_create(VectorView p_vertex_attribs) {} -void RenderingDeviceDriverWebGpu::vertex_format_free(VertexFormatID p_vertex_format) {} +// NOTE: The attributes in `p_vertex_attribs` must be in order. +RenderingDeviceDriver::VertexFormatID RenderingDeviceDriverWebGpu::vertex_format_create(VectorView p_vertex_attribs) { + WGPUVertexAttribute *vertex_attributes = memnew_arr(WGPUVertexAttribute, p_vertex_attribs.size()); + uint64_t array_stride = 0; + for (int i = 0; i < p_vertex_attribs.size(); i++) { + VertexAttribute attrib = p_vertex_attribs[i]; + vertex_attributes[i] = (WGPUVertexAttribute){ + .format = webgpu_vertex_format_from_rd(attrib.format), + .offset = attrib.offset, + .shaderLocation = attrib.location, + }; + array_stride += attrib.stride; + } + + WGPUVertexStepMode step_mode = p_vertex_attribs[0].frequency == VertexFrequency::VERTEX_FREQUENCY_VERTEX ? WGPUVertexStepMode_Vertex : WGPUVertexStepMode_Instance; + + WGPUVertexBufferLayout *layout = memnew(WGPUVertexBufferLayout); + layout->attributes = vertex_attributes; + layout->attributeCount = p_vertex_attribs.size(); + layout->stepMode = step_mode; + layout->arrayStride = array_stride; + return VertexFormatID(layout); +} + +void RenderingDeviceDriverWebGpu::vertex_format_free(VertexFormatID p_vertex_format) { + WGPUVertexBufferLayout *layout = (WGPUVertexBufferLayout *)p_vertex_format.id; + memdelete_arr(layout->attributes); + memdelete(layout); +} /******************/ /**** BARRIERS ****/ diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp index 598ce0da52c9..54abf69ddcbe 100644 --- a/drivers/webgpu/webgpu_conv.cpp +++ b/drivers/webgpu/webgpu_conv.cpp @@ -211,6 +211,74 @@ WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_o } } +WGPUVertexFormat webgpu_vertex_format_from_rd(RDD::DataFormat p_data_format) { + WGPUVertexFormat ret = WGPUVertexFormat_Undefined; + + switch (p_data_format) { + case RDD::DataFormat::DATA_FORMAT_R32_UINT: + ret = WGPUVertexFormat_Uint32; + break; + case RDD::DataFormat::DATA_FORMAT_R32_SINT: + ret = WGPUVertexFormat_Sint32; + break; + case RDD::DataFormat::DATA_FORMAT_R32_SFLOAT: + ret = WGPUVertexFormat_Float32; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8_UINT: + ret = WGPUVertexFormat_Uint8x2; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8_SINT: + ret = WGPUVertexFormat_Sint8x2; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16_UINT: + ret = WGPUVertexFormat_Uint16x2; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16_SINT: + ret = WGPUVertexFormat_Sint16x2; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16_SFLOAT: + ret = WGPUVertexFormat_Float16x2; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_UINT: + ret = WGPUVertexFormat_Uint8x4; + break; + case RDD::DataFormat::DATA_FORMAT_R8G8B8A8_SINT: + ret = WGPUVertexFormat_Sint8x4; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32_UINT: + ret = WGPUVertexFormat_Uint32x2; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32_SINT: + ret = WGPUVertexFormat_Sint32x2; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32_SFLOAT: + ret = WGPUVertexFormat_Float32x2; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16B16A16_UINT: + ret = WGPUVertexFormat_Uint16x4; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16B16A16_SINT: + ret = WGPUVertexFormat_Sint16x4; + break; + case RDD::DataFormat::DATA_FORMAT_R16G16B16A16_SFLOAT: + ret = WGPUVertexFormat_Float16x4; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32B32A32_UINT: + ret = WGPUVertexFormat_Uint32x4; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32B32A32_SINT: + ret = WGPUVertexFormat_Sint32x4; + break; + case RDD::DataFormat::DATA_FORMAT_R32G32B32A32_SFLOAT: + ret = WGPUVertexFormat_Float32x4; + break; + default: + break; + } + + return ret; +} + uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits) { WGPULimits limits = p_limits.limits; // Note: For limits that aren't supported, I've put the max uint64 value. This may cause issues. diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h index 554d5b69797d..3dfebf70f3c1 100644 --- a/drivers/webgpu/webgpu_conv.h +++ b/drivers/webgpu/webgpu_conv.h @@ -10,6 +10,7 @@ WGPUFilterMode webgpu_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter); WGPUMipmapFilterMode webgpu_mipmap_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter); WGPUAddressMode webgpu_address_mode_from_rd(RDD::SamplerRepeatMode p_sampler_repeat_mode); WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_operator); +WGPUVertexFormat webgpu_vertex_format_from_rd(RDD::DataFormat p_data_format); uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits); From fa91ec4bae26cf901641d118a3b0667611c13f0c Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 19:41:13 -0700 Subject: [PATCH 13/19] Texture usage corrections --- drivers/webgpu/rendering_device_driver_webgpu.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index d6bfd211143e..b1ef39b83095 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -107,23 +107,22 @@ void RenderingDeviceDriverWebGpu::buffer_unmap(BufferID p_buffer) { RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create(const TextureFormat &p_format, const TextureView &p_view) { WGPUFlags usage_bits = WGPUTextureUsage_None; - if ((p_format.usage_bits & TEXTURE_USAGE_STORAGE_BIT)) { - usage_bits |= WGPUTextureUsage_StorageBinding; - } - if ((p_format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) { + if ((p_format.usage_bits & TEXTURE_USAGE_SAMPLING_BIT)) { usage_bits |= WGPUTextureUsage_TextureBinding; } - if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) || (p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) { + if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) || + (p_format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) || + (p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) { usage_bits |= WGPUTextureUsage_RenderAttachment; } - if ((p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT)) { + if ((p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT) || (p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_TO_BIT)) { usage_bits |= WGPUTextureUsage_CopyDst; } if ((p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_FROM_BIT)) { usage_bits |= WGPUTextureUsage_CopySrc; } - if ((p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_TO_BIT)) { - usage_bits |= WGPUTextureUsage_CopyDst; + if ((p_format.usage_bits & TEXTURE_USAGE_STORAGE_BIT)) { + usage_bits |= WGPUTextureUsage_StorageBinding; } WGPUTextureUsage usage = (WGPUTextureUsage)usage_bits; From b84edfb2b091164a97d252a2d94fc012c601a566 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 20:11:47 -0700 Subject: [PATCH 14/19] Fixes and stubs up to first swap_chain_get_render_pass --- .../webgpu/rendering_context_driver_webgpu.h | 3 +- .../webgpu/rendering_device_driver_webgpu.cpp | 52 ++++++++++++++++--- .../webgpu/rendering_device_driver_webgpu.h | 3 ++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/drivers/webgpu/rendering_context_driver_webgpu.h b/drivers/webgpu/rendering_context_driver_webgpu.h index 86b823b244a2..a0859f6c61c3 100644 --- a/drivers/webgpu/rendering_context_driver_webgpu.h +++ b/drivers/webgpu/rendering_context_driver_webgpu.h @@ -1,6 +1,7 @@ #ifndef RENDERING_CONTEXT_DRIVER_WEBGPU_H #define RENDERING_CONTEXT_DRIVER_WEBGPU_H +#include "servers/rendering/rendering_device_driver.h" #include "servers/rendering/rendering_context_driver.h" #include @@ -33,7 +34,7 @@ class RenderingContextDriverWebGpu : public RenderingContextDriver { virtual ~RenderingContextDriverWebGpu() override; struct Surface { - WGPUSurface surface; + WGPUSurface surface = nullptr; uint32_t width = 0; uint32_t height = 0; DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED; diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index b1ef39b83095..5250dbd8c5e3 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -195,21 +195,45 @@ RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create(con TextureInfo *texture_info = memnew(TextureInfo); texture_info->texture = texture; + texture_info->is_original_texture = true; texture_info->view = view; texture_info->width = size.width; texture_info->height = size.height; texture_info->depth_or_array = size.depthOrArrayLayers; + texture_info->is_using_depth = is_using_depth; + texture_info->mip_level_count = mip_level_count; return TextureID(texture_info); } RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) {} -RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) {} + +RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) { + TextureInfo *texture_info = (TextureInfo *)p_original_texture.id; + + WGPUTextureViewDescriptor texture_view_desc = (WGPUTextureViewDescriptor){ + .format = webgpu_texture_format_from_rd(p_view.format), + .mipLevelCount = texture_info->mip_level_count, + .arrayLayerCount = texture_info->is_using_depth ? 1 : texture_info->depth_or_array, + }; + + WGPUTextureView view = wgpuTextureCreateView(texture_info->texture, &texture_view_desc); + + TextureInfo* new_texture_info = memnew(TextureInfo); + *new_texture_info = *texture_info; + new_texture_info->view = view; + new_texture_info->is_original_texture = false; + + return TextureID(new_texture_info); +} + RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) {} void RenderingDeviceDriverWebGpu::texture_free(TextureID p_texture) { TextureInfo *texture_info = (TextureInfo *)p_texture.id; - wgpuTextureRelease(texture_info->texture); + if (texture_info->is_original_texture) { + wgpuTextureRelease(texture_info->texture); + } wgpuTextureViewRelease(texture_info->view); memdelete(texture_info); } @@ -411,8 +435,8 @@ void RenderingDeviceDriverWebGpu::command_buffer_execute_secondary(CommandBuffer /**** SWAP CHAIN ****/ /********************/ -RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_create(RenderingContextDriver::SurfaceID _p_surface) { - return SwapChainID(1); +RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) { + return SwapChainID(p_surface); } Error RenderingDeviceDriverWebGpu::swap_chain_resize(CommandQueueID _p_cmd_queue, SwapChainID _p_swap_chain, uint32_t _p_desired_framebuffer_count) { @@ -420,9 +444,25 @@ Error RenderingDeviceDriverWebGpu::swap_chain_resize(CommandQueueID _p_cmd_queue return OK; } -RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) {} +RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) { + return FramebufferID(1); +} + RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::swap_chain_get_render_pass(SwapChainID p_swap_chain) {} -RenderingDeviceDriver::DataFormat RenderingDeviceDriverWebGpu::swap_chain_get_format(SwapChainID p_swap_chain) {} + +// NOTE: In theory, this function's result doesn't matter. +// We take this to create a framebuffer attachment that we never end up using since WebGpu does not support framebuffers. +RenderingDeviceDriver::DataFormat RenderingDeviceDriverWebGpu::swap_chain_get_format(SwapChainID p_swap_chain) { + // The surface can't present yet, so this fails anyway. + // + // RenderingContextDriverWebGpu::Surface *surface = (RenderingContextDriverWebGpu::Surface *)p_swap_chain.id; + // + // WGPUSurfaceTexture texture; + // wgpuSurfaceGetCurrentTexture(surface->surface, &texture); + // WGPUTextureFormat format = wgpuTextureGetFormat(texture.texture); + // TODO: I don't want to write a massive boilerplate-y function just for this one function. + return DATA_FORMAT_ASTC_4x4_SRGB_BLOCK; +} void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID _p_swap_chain) { // Empty. diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 43dcfe152b67..109d07048812 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -49,10 +49,13 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { private: struct TextureInfo { WGPUTexture texture; + bool is_original_texture; WGPUTextureView view; uint32_t width; uint32_t height; uint32_t depth_or_array; + bool is_using_depth; + uint32_t mip_level_count; }; public: From 300f7aec804d13729a8dbd676c690e5d5ba51298 Mon Sep 17 00:00:00 2001 From: dav Date: Mon, 8 Apr 2024 23:05:05 -0700 Subject: [PATCH 15/19] Fix up swapchain_create and implement swap_chain_get_render_pass --- .../webgpu/rendering_device_driver_webgpu.cpp | 70 ++++++++++++++----- .../webgpu/rendering_device_driver_webgpu.h | 19 ++++- drivers/webgpu/webgpu_conv.cpp | 30 ++++++-- drivers/webgpu/webgpu_conv.h | 2 + 4 files changed, 98 insertions(+), 23 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 5250dbd8c5e3..d3c984ee83c2 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -219,7 +219,7 @@ RenderingDeviceDriver::TextureID RenderingDeviceDriverWebGpu::texture_create_sha WGPUTextureView view = wgpuTextureCreateView(texture_info->texture, &texture_view_desc); - TextureInfo* new_texture_info = memnew(TextureInfo); + TextureInfo *new_texture_info = memnew(TextureInfo); *new_texture_info = *texture_info; new_texture_info->view = view; new_texture_info->is_original_texture = false; @@ -436,11 +436,32 @@ void RenderingDeviceDriverWebGpu::command_buffer_execute_secondary(CommandBuffer /********************/ RenderingDeviceDriver::SwapChainID RenderingDeviceDriverWebGpu::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) { - return SwapChainID(p_surface); + RenderingContextDriverWebGpu::Surface *surface = (RenderingContextDriverWebGpu::Surface *)p_surface; + + RenderPassInfo *render_pass_info = memnew(RenderPassInfo); + + // NOTE: This is not the best way of getting the format of the surface. + WGPUTextureFormat surface_format = wgpuSurfaceGetPreferredFormat(surface->surface, adapter); + + render_pass_info->attachments = Vector({ (RenderPassAttachmentInfo){ + .format = surface_format, + .sample_count = 1, + .load_op = WGPULoadOp_Clear, + .store_op = WGPUStoreOp_Store, + .stencil_load_op = WGPULoadOp_Undefined, + .stencil_store_op = WGPUStoreOp_Undefined, + } }); + // TODO: The multiview feature is currently disabled, so I will ignore this. + render_pass_info->view_count = 1; + + SwapChainInfo *swapchain_info = memnew(SwapChainInfo); + swapchain_info->surface = p_surface; + swapchain_info->render_pass = RenderPassID(render_pass_info); + + return SwapChainID(swapchain_info); } Error RenderingDeviceDriverWebGpu::swap_chain_resize(CommandQueueID _p_cmd_queue, SwapChainID _p_swap_chain, uint32_t _p_desired_framebuffer_count) { - // WebGpu's swapchain is contained within the surface. return OK; } @@ -448,24 +469,27 @@ RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::swap_chain_acq return FramebufferID(1); } -RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::swap_chain_get_render_pass(SwapChainID p_swap_chain) {} +RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::swap_chain_get_render_pass(SwapChainID p_swap_chain) { + SwapChainInfo *swapchain_info = (SwapChainInfo *)p_swap_chain.id; + return swapchain_info->render_pass; +} // NOTE: In theory, this function's result doesn't matter. // We take this to create a framebuffer attachment that we never end up using since WebGpu does not support framebuffers. RenderingDeviceDriver::DataFormat RenderingDeviceDriverWebGpu::swap_chain_get_format(SwapChainID p_swap_chain) { - // The surface can't present yet, so this fails anyway. - // - // RenderingContextDriverWebGpu::Surface *surface = (RenderingContextDriverWebGpu::Surface *)p_swap_chain.id; - // - // WGPUSurfaceTexture texture; - // wgpuSurfaceGetCurrentTexture(surface->surface, &texture); - // WGPUTextureFormat format = wgpuTextureGetFormat(texture.texture); - // TODO: I don't want to write a massive boilerplate-y function just for this one function. + SwapChainInfo *swapchain_info = (SwapChainInfo *)p_swap_chain.id; + RenderingContextDriverWebGpu::Surface *surface = (RenderingContextDriverWebGpu::Surface *)swapchain_info->surface; + // NOTE: This is not the best way of getting the format of the surface. + // return wgpuSurfaceGetPreferredFormat(surface->surface, adapter); + // TODO: I don't want to write a conversion just for this one useless function. return DATA_FORMAT_ASTC_4x4_SRGB_BLOCK; } -void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID _p_swap_chain) { - // Empty. +void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID p_swap_chain) { + SwapChainInfo *swapchain_info = (SwapChainInfo *)p_swap_chain.id; + + memdelete((RenderPassInfo *)swapchain_info->render_pass.id); + memdelete(swapchain_info); } /*********************/ @@ -549,9 +573,19 @@ RenderingDeviceDriver::RenderPassID RenderingDeviceDriverWebGpu::render_pass_cre // WebGpu does not have subpasses so we will store this info until we create a render pipeline later. RenderPassInfo *render_pass_info = memnew(RenderPassInfo); - render_pass_info->attachments = Vector(); + render_pass_info->attachments = Vector(); for (int i = 0; i < p_attachments.size(); i++) { - render_pass_info->attachments.push_back(p_attachments[i]); + Attachment attachment = p_attachments[i]; + RenderPassAttachmentInfo attachment_info = (RenderPassAttachmentInfo){ + .format = webgpu_texture_format_from_rd(attachment.format), + // TODO: Assert that p_format.samples follows this behavior. + .sample_count = (uint32_t)pow(2, (uint32_t)attachment.samples), + .load_op = webgpu_load_op_from_rd(attachment.load_op), + .store_op = webgpu_store_op_from_rd(attachment.store_op), + .stencil_load_op = webgpu_load_op_from_rd(attachment.stencil_load_op), + .stencil_store_op = webgpu_store_op_from_rd(attachment.stencil_store_op), + }; + render_pass_info->attachments.push_back(attachment_info); } render_pass_info->view_count = p_view_count; @@ -718,6 +752,10 @@ RenderingDeviceDriverWebGpu::~RenderingDeviceDriverWebGpu() { wgpuQueueRelease(queue); } + if (queue != nullptr) { + wgpuAdapterRelease(adapter); + } + if (device != nullptr) { wgpuDeviceRelease(device); } diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 109d07048812..f8f34adbb147 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -14,7 +14,7 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { RenderingContextDriverWebGpu *context_driver = nullptr; RenderingContextDriver::Device context_device; - // Note: Indexed by CommandBufferID with offset of 1, so that index 0 => 1. + // NOTE: Indexed by CommandBufferID with offset of 1, so that index 0 => 1. TightLocalVector command_encoders; public: @@ -148,6 +148,12 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { /**** SWAP CHAIN ****/ /********************/ +private: + struct SwapChainInfo { + RenderingContextDriver::SurfaceID surface; + RenderPassID render_pass; + }; + public: virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override final; virtual Error swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) override final; @@ -222,8 +228,17 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { // ----- SUBPASS ----- + struct RenderPassAttachmentInfo { + WGPUTextureFormat format; + uint32_t sample_count; + WGPULoadOp load_op; + WGPUStoreOp store_op; + WGPULoadOp stencil_load_op; + WGPUStoreOp stencil_store_op; + }; + struct RenderPassInfo { - Vector attachments; + Vector attachments; uint32_t view_count; }; diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp index 54abf69ddcbe..84d498906ed0 100644 --- a/drivers/webgpu/webgpu_conv.cpp +++ b/drivers/webgpu/webgpu_conv.cpp @@ -157,15 +157,15 @@ WGPUTextureFormat webgpu_texture_format_from_rd(RDD::DataFormat p_data_format) { return ret; } +static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_NEAREST, WGPUFilterMode_Nearest)); +static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_LINEAR, WGPUFilterMode_Linear)); WGPUFilterMode webgpu_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter) { - static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_NEAREST, WGPUFilterMode_Nearest)); - static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_LINEAR, WGPUFilterMode_Linear)); return (WGPUFilterMode)p_sampler_filter; } +static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_NEAREST, WGPUMipmapFilterMode_Nearest)); +static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_LINEAR, WGPUMipmapFilterMode_Linear)); WGPUMipmapFilterMode webgpu_mipmap_filter_mode_from_rd(RDD::SamplerFilter p_sampler_filter) { - static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_NEAREST, WGPUMipmapFilterMode_Nearest)); - static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_FILTER_LINEAR, WGPUMipmapFilterMode_Linear)); return (WGPUMipmapFilterMode)p_sampler_filter; } @@ -279,9 +279,29 @@ WGPUVertexFormat webgpu_vertex_format_from_rd(RDD::DataFormat p_data_format) { return ret; } +WGPULoadOp webgpu_load_op_from_rd(RDD::AttachmentLoadOp p_load_op) { + switch(p_load_op) { + case RenderingDeviceDriver::ATTACHMENT_LOAD_OP_LOAD: + return WGPULoadOp_Load; + case RenderingDeviceDriver::ATTACHMENT_LOAD_OP_CLEAR: + return WGPULoadOp_Clear; + case RenderingDeviceDriver::ATTACHMENT_LOAD_OP_DONT_CARE: + return WGPULoadOp_Undefined; + } +} + +WGPUStoreOp webgpu_store_op_from_rd(RDD::AttachmentStoreOp p_store_op) { + switch (p_store_op) { + case RenderingDeviceDriver::ATTACHMENT_STORE_OP_STORE: + return WGPUStoreOp_Store; + case RenderingDeviceDriver::ATTACHMENT_STORE_OP_DONT_CARE: + return WGPUStoreOp_Undefined; + } +} + uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits) { WGPULimits limits = p_limits.limits; - // Note: For limits that aren't supported, I've put the max uint64 value. This may cause issues. + // NOTE: For limits that aren't supported, I've put the max uint64 value. This may cause issues. switch (p_selected_limit) { case RenderingDeviceCommons::LIMIT_MAX_BOUND_UNIFORM_SETS: return limits.maxBindGroups; diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h index 3dfebf70f3c1..26fd08303d49 100644 --- a/drivers/webgpu/webgpu_conv.h +++ b/drivers/webgpu/webgpu_conv.h @@ -11,6 +11,8 @@ WGPUMipmapFilterMode webgpu_mipmap_filter_mode_from_rd(RDD::SamplerFilter p_samp WGPUAddressMode webgpu_address_mode_from_rd(RDD::SamplerRepeatMode p_sampler_repeat_mode); WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_operator); WGPUVertexFormat webgpu_vertex_format_from_rd(RDD::DataFormat p_data_format); +WGPULoadOp webgpu_load_op_from_rd(RDD::AttachmentLoadOp p_load_op); +WGPUStoreOp webgpu_store_op_from_rd(RDD::AttachmentStoreOp p_store_op); uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits); From e801e04dc46829ac39222324b078a6bd6b77f021 Mon Sep 17 00:00:00 2001 From: dav Date: Tue, 9 Apr 2024 11:10:26 -0700 Subject: [PATCH 16/19] Enable glslc and mark todo code --- .../webgpu/rendering_device_driver_webgpu.cpp | 55 ++++++++++++++++--- .../webgpu/rendering_device_driver_webgpu.h | 2 + modules/glslang/config.py | 4 +- modules/glslang/register_types.cpp | 4 ++ servers/rendering/rendering_device_driver.h | 1 + 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index d3c984ee83c2..6010161cd3dd 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -19,6 +19,13 @@ Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t queue = wgpuDeviceGetQueue(device); ERR_FAIL_COND_V(!this->queue, FAILED); + capabilties = (RenderingDeviceDriver::Capabilities){ + // TODO: This information is not accurate, see modules/glslang/register_types.cpp:78. + .device_family = DEVICE_WEBGPU, + .version_major = 0, + .version_minor = 19, + }; + return OK; } @@ -496,7 +503,12 @@ void RenderingDeviceDriverWebGpu::swap_chain_free(SwapChainID p_swap_chain) { /**** FRAMEBUFFER ****/ /*********************/ -RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::framebuffer_create(RenderPassID p_render_pass, VectorView p_attachments, uint32_t p_width, uint32_t p_height) {} +RenderingDeviceDriver::FramebufferID RenderingDeviceDriverWebGpu::framebuffer_create(RenderPassID p_render_pass, VectorView p_attachments, uint32_t p_width, uint32_t p_height) { + // TODO: impl + print_error("TODO --> framebuffer_create"); + exit(1); +} + void RenderingDeviceDriverWebGpu::framebuffer_free(FramebufferID p_framebuffer) {} /****************/ @@ -508,15 +520,29 @@ String RenderingDeviceDriverWebGpu::shader_get_binary_cache_key() { return ""; } -Vector RenderingDeviceDriverWebGpu::shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) {} -RenderingDeviceDriver::ShaderID RenderingDeviceDriverWebGpu::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) {} -void RenderingDeviceDriverWebGpu::shader_free(ShaderID p_shader) {} +Vector RenderingDeviceDriverWebGpu::shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) { + return Vector({ 1, 1 }); +} + +RenderingDeviceDriver::ShaderID RenderingDeviceDriverWebGpu::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) { + // TODO: impl + print_error("TODO --> shader_create_from_bytecode"); + exit(1); +} + +void RenderingDeviceDriverWebGpu::shader_free(ShaderID p_shader) { +} /*********************/ /**** UNIFORM SET ****/ /*********************/ -RenderingDeviceDriver::UniformSetID RenderingDeviceDriverWebGpu::uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) {} +RenderingDeviceDriver::UniformSetID RenderingDeviceDriverWebGpu::uniform_set_create(VectorView p_uniforms, ShaderID p_shader, uint32_t p_set_index) { + // TODO: impl + print_error("TODO --> uniform_set_create"); + exit(1); +} + void RenderingDeviceDriverWebGpu::uniform_set_free(UniformSetID p_uniform_set) {} // ----- COMMANDS ----- @@ -640,7 +666,11 @@ RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::render_pipeline_c BitField p_dynamic_state, RenderPassID p_render_pass, uint32_t p_render_subpass, - VectorView p_specialization_constants) {} + VectorView p_specialization_constants) { + // TODO: impl + print_error("TODO --> render_pipeline_create"); + exit(1); +} /*****************/ /**** COMPUTE ****/ @@ -658,7 +688,11 @@ void RenderingDeviceDriverWebGpu::command_compute_dispatch_indirect(CommandBuffe // ----- PIPELINE ----- -RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::compute_pipeline_create(ShaderID p_shader, VectorView p_specialization_constants) {} +RenderingDeviceDriver::PipelineID RenderingDeviceDriverWebGpu::compute_pipeline_create(ShaderID p_shader, VectorView p_specialization_constants) { + // TODO: impl + print_error("TODO --> compute_pipeline_create"); + exit(1); +} /*****************/ /**** QUERIES ****/ @@ -735,12 +769,15 @@ String RenderingDeviceDriverWebGpu::get_api_name() const { } String RenderingDeviceDriverWebGpu::get_api_version() const { - // We should compile this in based on the wgpu / dawn version + // TODO: We should compile this in based on the wgpu / dawn version return "v0.19.3.1 (wgpu)"; } String RenderingDeviceDriverWebGpu::get_pipeline_cache_uuid() const {} -const RenderingDeviceDriver::Capabilities &RenderingDeviceDriverWebGpu::get_capabilities() const {} + +const RenderingDeviceDriver::Capabilities &RenderingDeviceDriverWebGpu::get_capabilities() const { + return capabilties; +} RenderingDeviceDriverWebGpu::RenderingDeviceDriverWebGpu(RenderingContextDriverWebGpu *p_context_driver) { DEV_ASSERT(p_context_driver != nullptr); diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index f8f34adbb147..8736962daa34 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -14,6 +14,8 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { RenderingContextDriverWebGpu *context_driver = nullptr; RenderingContextDriver::Device context_device; + RenderingDeviceDriver::Capabilities capabilties; + // NOTE: Indexed by CommandBufferID with offset of 1, so that index 0 => 1. TightLocalVector command_encoders; diff --git a/modules/glslang/config.py b/modules/glslang/config.py index 1169776a739b..a2224a8a234f 100644 --- a/modules/glslang/config.py +++ b/modules/glslang/config.py @@ -1,7 +1,7 @@ def can_build(env, platform): - # glslang is only needed when Vulkan or Direct3D 12-based renderers are available, + # glslang is only needed when Vulkan, Direct3D 12, or WebGpu-based renderers are available, # as OpenGL doesn't use glslang. - return env["vulkan"] or env["d3d12"] + return env["vulkan"] or env["d3d12"] or env["webgpu"] def configure(env): diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp index 09ad1d67773b..51df1f8f1554 100644 --- a/modules/glslang/register_types.cpp +++ b/modules/glslang/register_types.cpp @@ -74,6 +74,10 @@ static Vector _compile_shader_glsl(RenderingDevice::ShaderStage p_stage // - SPIRV-Reflect won't be able to parse the compute workgroup size. // - We want to play it safe with NIR-DXIL. TargetVersion = glslang::EShTargetSpv_1_3; + } else if (capabilities.device_family == RDD::DEVICE_WEBGPU) { + // TODO: This information is not accurate, but we can safely assume that WebGpu == Vulkan. + ClientVersion = glslang::EShTargetVulkan_1_1; + TargetVersion = glslang::EShTargetSpv_1_3; } else { // once we support other backends we'll need to do something here if (r_error) { diff --git a/servers/rendering/rendering_device_driver.h b/servers/rendering/rendering_device_driver.h index 09a041294195..c51b03aabe5c 100644 --- a/servers/rendering/rendering_device_driver.h +++ b/servers/rendering/rendering_device_driver.h @@ -749,6 +749,7 @@ class RenderingDeviceDriver : public RenderingDeviceCommons { DEVICE_OPENGL, DEVICE_VULKAN, DEVICE_DIRECTX, + DEVICE_WEBGPU, }; struct Capabilities { From 1e064277c3ec230054d2aa42ddf9e4c2e71cfad6 Mon Sep 17 00:00:00 2001 From: dav Date: Wed, 10 Apr 2024 14:22:16 -0700 Subject: [PATCH 17/19] Progress with shader creation and reflection --- .../webgpu/rendering_device_driver_webgpu.cpp | 304 +++++++++++++++++- .../webgpu/rendering_device_driver_webgpu.h | 34 ++ drivers/webgpu/webgpu_conv.cpp | 21 ++ drivers/webgpu/webgpu_conv.h | 1 + servers/rendering/rendering_device_commons.h | 9 + servers/rendering/rendering_device_driver.cpp | 170 ++++++++++ 6 files changed, 537 insertions(+), 2 deletions(-) diff --git a/drivers/webgpu/rendering_device_driver_webgpu.cpp b/drivers/webgpu/rendering_device_driver_webgpu.cpp index 6010161cd3dd..a6e05ee7de9b 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.cpp +++ b/drivers/webgpu/rendering_device_driver_webgpu.cpp @@ -1,4 +1,7 @@ #include "rendering_device_driver_webgpu.h" +#include "core/io/marshalls.h" +#include "thirdparty/misc/smolv.h" +#include "webgpu.h" #include "webgpu_conv.h" #include @@ -13,7 +16,8 @@ Error RenderingDeviceDriverWebGpu::initialize(uint32_t p_device_index, uint32_t adapter = context_driver->adapter_get(p_device_index); context_device = context_driver->device_get(p_device_index); - wgpuAdapterRequestDevice(adapter, nullptr, handle_request_device, &this->device); + WGPUDeviceDescriptor device_desc = (WGPUDeviceDescriptor){}; + wgpuAdapterRequestDevice(adapter, &device_desc, handle_request_device, &this->device); ERR_FAIL_COND_V(!this->device, FAILED); queue = wgpuDeviceGetQueue(device); @@ -521,10 +525,306 @@ String RenderingDeviceDriverWebGpu::shader_get_binary_cache_key() { } Vector RenderingDeviceDriverWebGpu::shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) { - return Vector({ 1, 1 }); + // This code is mostly taken from the vulkan device driver. + ShaderReflection shader_refl; + if (_reflect_spirv(p_spirv, shader_refl) != OK) { + return Vector(); + } + + ShaderBinary::Data binary_data; + Vector> uniforms; // Set bindings. + Vector specialization_constants; + { + binary_data.specialization_constants_count = shader_refl.specialization_constants.size(); + binary_data.is_compute = shader_refl.is_compute; + binary_data.compute_local_size[0] = shader_refl.compute_local_size[0]; + binary_data.compute_local_size[1] = shader_refl.compute_local_size[1]; + binary_data.compute_local_size[2] = shader_refl.compute_local_size[2]; + binary_data.set_count = shader_refl.uniform_sets.size(); + // binary_data.push_constant_size = shader_refl.push_constant_size; + for (uint32_t i = 0; i < SHADER_STAGE_MAX; i++) { + if (shader_refl.push_constant_stages.has_flag((ShaderStage)(1 << i))) { + // binary_data.vk_push_constant_stages_mask |= RD_STAGE_TO_VK_SHADER_STAGE_BITS[i]; + } + } + + for (const Vector &set_refl : shader_refl.uniform_sets) { + Vector set_bindings; + for (const ShaderUniform &uniform_refl : set_refl) { + ShaderBinary::DataBinding binding; + binding.type = (uint32_t)uniform_refl.type; + binding.binding = uniform_refl.binding; + binding.stages = (uint32_t)uniform_refl.stages; + binding.length = uniform_refl.length; + binding.writable = (uint32_t)uniform_refl.writable; + set_bindings.push_back(binding); + } + uniforms.push_back(set_bindings); + } + + for (const ShaderSpecializationConstant &refl_sc : shader_refl.specialization_constants) { + ShaderBinary::SpecializationConstant spec_constant; + spec_constant.type = (uint32_t)refl_sc.type; + spec_constant.constant_id = refl_sc.constant_id; + spec_constant.int_value = refl_sc.int_value; + spec_constant.stage_flags = (uint32_t)refl_sc.stages; + specialization_constants.push_back(spec_constant); + } + } + + Vector> compressed_stages; + Vector smolv_size; + Vector zstd_size; + + uint32_t stages_binary_size = 0; + + bool strip_debug = false; + + for (uint32_t i = 0; i < p_spirv.size(); i++) { + smolv::ByteArray smolv; + if (!smolv::Encode(p_spirv[i].spirv.ptr(), p_spirv[i].spirv.size(), smolv, strip_debug ? smolv::kEncodeFlagStripDebugInfo : 0)) { + ERR_FAIL_V_MSG(Vector(), "Error compressing shader stage :" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage])); + } else { + smolv_size.push_back(smolv.size()); + // zstd. + { + Vector zstd; + zstd.resize(Compression::get_max_compressed_buffer_size(smolv.size(), Compression::MODE_ZSTD)); + int dst_size = Compression::compress(zstd.ptrw(), &smolv[0], smolv.size(), Compression::MODE_ZSTD); + + if (dst_size > 0 && (uint32_t)dst_size < smolv.size()) { + zstd_size.push_back(dst_size); + zstd.resize(dst_size); + compressed_stages.push_back(zstd); + } else { + Vector smv; + smv.resize(smolv.size()); + memcpy(smv.ptrw(), &smolv[0], smolv.size()); + // Not using zstd. + zstd_size.push_back(0); + compressed_stages.push_back(smv); + } + } + } + uint32_t s = compressed_stages[i].size(); + stages_binary_size += STEPIFY(s, 4); + } + + binary_data.specialization_constants_count = specialization_constants.size(); + binary_data.set_count = uniforms.size(); + binary_data.stage_count = p_spirv.size(); + + CharString shader_name_utf = p_shader_name.utf8(); + + binary_data.shader_name_len = shader_name_utf.length(); + + // Header + version + main datasize;. + uint32_t total_size = sizeof(uint32_t) * 3; + + total_size += sizeof(ShaderBinary::Data); + + total_size += STEPIFY(binary_data.shader_name_len, 4); + for (int i = 0; i < uniforms.size(); i++) { + total_size += sizeof(uint32_t); + total_size += uniforms[i].size() * sizeof(ShaderBinary::DataBinding); + } + + total_size += sizeof(ShaderBinary::SpecializationConstant) * specialization_constants.size(); + total_size += compressed_stages.size() * sizeof(uint32_t) * 3; // Sizes. + total_size += stages_binary_size; + + Vector ret; + ret.resize(total_size); + { + uint32_t offset = 0; + uint8_t *binptr = ret.ptrw(); + binptr[0] = 'G'; + binptr[1] = 'S'; + binptr[2] = 'B'; + binptr[3] = 'D'; + offset += 4; + encode_uint32(ShaderBinary::VERSION, binptr + offset); + offset += sizeof(uint32_t); + encode_uint32(sizeof(ShaderBinary::Data), binptr + offset); + offset += sizeof(uint32_t); + memcpy(binptr + offset, &binary_data, sizeof(ShaderBinary::Data)); + offset += sizeof(ShaderBinary::Data); + +#define ADVANCE_OFFSET_WITH_ALIGNMENT(m_bytes) \ + { \ + offset += m_bytes; \ + uint32_t padding = STEPIFY(m_bytes, 4) - m_bytes; \ + memset(binptr + offset, 0, padding); /* Avoid garbage data. */ \ + offset += padding; \ + } + + if (binary_data.shader_name_len > 0) { + memcpy(binptr + offset, shader_name_utf.ptr(), binary_data.shader_name_len); + ADVANCE_OFFSET_WITH_ALIGNMENT(binary_data.shader_name_len); + } + + for (int i = 0; i < uniforms.size(); i++) { + int count = uniforms[i].size(); + encode_uint32(count, binptr + offset); + offset += sizeof(uint32_t); + if (count > 0) { + memcpy(binptr + offset, uniforms[i].ptr(), sizeof(ShaderBinary::DataBinding) * count); + offset += sizeof(ShaderBinary::DataBinding) * count; + } + } + + if (specialization_constants.size()) { + memcpy(binptr + offset, specialization_constants.ptr(), sizeof(ShaderBinary::SpecializationConstant) * specialization_constants.size()); + offset += sizeof(ShaderBinary::SpecializationConstant) * specialization_constants.size(); + } + + for (int i = 0; i < compressed_stages.size(); i++) { + encode_uint32(p_spirv[i].shader_stage, binptr + offset); + offset += sizeof(uint32_t); + encode_uint32(smolv_size[i], binptr + offset); + offset += sizeof(uint32_t); + encode_uint32(zstd_size[i], binptr + offset); + offset += sizeof(uint32_t); + memcpy(binptr + offset, compressed_stages[i].ptr(), compressed_stages[i].size()); + ADVANCE_OFFSET_WITH_ALIGNMENT(compressed_stages[i].size()); + } + + DEV_ASSERT(offset == (uint32_t)ret.size()); + } + + return ret; } RenderingDeviceDriver::ShaderID RenderingDeviceDriverWebGpu::shader_create_from_bytecode(const Vector &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) { + r_shader_desc = {}; + + const uint8_t *binptr = p_shader_binary.ptr(); + uint32_t binsize = p_shader_binary.size(); + + uint32_t read_offset = 0; + + // Consistency check. + ERR_FAIL_COND_V(binsize < sizeof(uint32_t) * 3 + sizeof(ShaderBinary::Data), ShaderID()); + ERR_FAIL_COND_V(binptr[0] != 'G' || binptr[1] != 'S' || binptr[2] != 'B' || binptr[3] != 'D', ShaderID()); + uint32_t bin_version = decode_uint32(binptr + 4); + ERR_FAIL_COND_V(bin_version != ShaderBinary::VERSION, ShaderID()); + + uint32_t bin_data_size = decode_uint32(binptr + 8); + const ShaderBinary::Data &binary_data = *(reinterpret_cast(binptr + 12)); + + // r_shader_desc.push_constant_size = binary_data.push_constant_size; + // shader_info.vk_push_constant_stages = binary_data.vk_push_constant_stages_mask; + + // r_shader_desc.vertex_input_mask = binary_data.vertex_input_mask; + // r_shader_desc.fragment_output_mask = binary_data.fragment_output_mask; + + r_shader_desc.is_compute = binary_data.is_compute; + r_shader_desc.compute_local_size[0] = binary_data.compute_local_size[0]; + r_shader_desc.compute_local_size[1] = binary_data.compute_local_size[1]; + r_shader_desc.compute_local_size[2] = binary_data.compute_local_size[2]; + + read_offset += sizeof(uint32_t) * 3 + bin_data_size; + + if (binary_data.shader_name_len) { + r_name.parse_utf8((const char *)(binptr + read_offset), binary_data.shader_name_len); + read_offset += STEPIFY(binary_data.shader_name_len, 4); + } + + Vector> webgpu_layout_entries; + + r_shader_desc.uniform_sets.resize(binary_data.set_count); + webgpu_layout_entries.resize(binary_data.set_count); + + for (uint32_t i = 0; i < binary_data.set_count; i++) { + ERR_FAIL_COND_V(read_offset + sizeof(uint32_t) >= binsize, ShaderID()); + uint32_t binding_count = decode_uint32(binptr + read_offset); + read_offset += sizeof(uint32_t); + const ShaderBinary::DataBinding *set_ptr = reinterpret_cast(binptr + read_offset); + uint32_t binding_size = binding_count * sizeof(ShaderBinary::DataBinding); + ERR_FAIL_COND_V(read_offset + binding_size >= binsize, ShaderID()); + + for (uint32_t j = 0; j < binding_count; j++) { + ShaderUniform info; + info.type = UniformType(set_ptr[j].type); + info.writable = set_ptr[j].writable; + info.length = set_ptr[j].length; + info.binding = set_ptr[j].binding; + info.stages = set_ptr[j].stages; + + WGPUBindGroupLayoutEntry layout_entry = {}; + layout_entry.binding = set_ptr[j].binding; + // layout_binding.descriptorCount = 1; + for (uint32_t k = 0; k < SHADER_STAGE_MAX; k++) { + if ((set_ptr[j].stages & (1 << k))) { + // bind_entry.stageFlags |= RD_STAGE_TO_VK_SHADER_STAGE_BITS[k]; + } + } + + switch (info.type) { + case UNIFORM_TYPE_SAMPLER: { + layout_entry.sampler = (WGPUSamplerBindingLayout){ + .type = WGPUSamplerBindingType_NonFiltering + }; + } break; + case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE: { + // TODO: WebGpu doesn't appear to support combined image samplers? + print_error("WebGpu UNIFORM_TYPE_SAMPLER_WITH_TEXTURE not supported"); + return ShaderID(); + } break; + case UNIFORM_TYPE_TEXTURE: { + layout_entry.texture = (WGPUTextureBindingLayout){ + // TODO + .viewDimension = webgpu_texture_view_dimension_from_rd(info.texture_image_type), + .multisampled = info.texture_is_multisample, + }; + } break; + case UNIFORM_TYPE_IMAGE: { + layout_entry.storageTexture = (WGPUStorageTextureBindingLayout){ + .access = set_ptr[j].writable ? WGPUStorageTextureAccess_ReadWrite : WGPUStorageTextureAccess_ReadOnly, + .format = webgpu_texture_format_from_rd(info.image_format), + .viewDimension = webgpu_texture_view_dimension_from_rd(info.texture_image_type), + }; + } break; + case UNIFORM_TYPE_INPUT_ATTACHMENT: { + layout_entry.texture = (WGPUTextureBindingLayout){ + // TODO + .viewDimension = webgpu_texture_view_dimension_from_rd(info.texture_image_type), + .multisampled = info.texture_is_multisample, + }; + } break; + case UNIFORM_TYPE_UNIFORM_BUFFER: { + layout_entry.buffer = (WGPUBufferBindingLayout){ + .type = WGPUBufferBindingType_Uniform, + // Godot doesn't support dynamic offset + .hasDynamicOffset = false, + }; + } break; + case UNIFORM_TYPE_STORAGE_BUFFER: { + layout_entry.buffer = (WGPUBufferBindingLayout){ + .type = WGPUBufferBindingType_Storage, + // Godot doesn't support dynamic offset + .hasDynamicOffset = false, + }; + } break; + case UNIFORM_TYPE_TEXTURE_BUFFER: + case UNIFORM_TYPE_IMAGE_BUFFER: + print_error("WebGpu UNIFORM_TYPE_TEXTURE_BUFFER and UNIFORM_TYPE_IMAGE_BUFFER not supported."); + return ShaderID(); + break; + default: { + DEV_ASSERT(false); + } + } + + r_shader_desc.uniform_sets.write[i].push_back(info); + webgpu_layout_entries.write[i].push_back(layout_entry); + } + + read_offset += binding_size; + } + + ERR_FAIL_COND_V(read_offset + binary_data.specialization_constants_count * sizeof(ShaderBinary::SpecializationConstant) >= binsize, ShaderID()); + // TODO: impl print_error("TODO --> shader_create_from_bytecode"); exit(1); diff --git a/drivers/webgpu/rendering_device_driver_webgpu.h b/drivers/webgpu/rendering_device_driver_webgpu.h index 8736962daa34..133b57bd8eff 100644 --- a/drivers/webgpu/rendering_device_driver_webgpu.h +++ b/drivers/webgpu/rendering_device_driver_webgpu.h @@ -175,6 +175,40 @@ class RenderingDeviceDriverWebGpu : public RenderingDeviceDriver { /**** SHADER ****/ /****************/ +private: + struct ShaderBinary { + // Version 1: initial. + static const uint32_t VERSION = 1; + + struct DataBinding { + uint32_t type = 0; + uint32_t binding = 0; + uint32_t stages = 0; + uint32_t length = 0; // Size of arrays (in total elements), or UBOs (in bytes * total elements). + uint32_t writable = 0; + }; + + struct SpecializationConstant { + uint32_t type = 0; + uint32_t constant_id = 0; + uint32_t int_value = 0; + uint32_t stage_flags = 0; + }; + + struct Data { + // uint64_t vertex_input_mask = 0; + // uint32_t fragment_output_mask = 0; + uint32_t specialization_constants_count = 0; + uint32_t is_compute = 0; + uint32_t compute_local_size[3] = {}; + uint32_t set_count = 0; + // uint32_t push_constant_size = 0; + // uint32_t vk_push_constant_stages_mask = 0; + uint32_t stage_count = 0; + uint32_t shader_name_len = 0; + }; + }; + public: virtual String shader_get_binary_cache_key() override final; virtual Vector shader_compile_binary_from_spirv(VectorView p_spirv, const String &p_shader_name) override final; diff --git a/drivers/webgpu/webgpu_conv.cpp b/drivers/webgpu/webgpu_conv.cpp index 84d498906ed0..c806fc961588 100644 --- a/drivers/webgpu/webgpu_conv.cpp +++ b/drivers/webgpu/webgpu_conv.cpp @@ -299,6 +299,27 @@ WGPUStoreOp webgpu_store_op_from_rd(RDD::AttachmentStoreOp p_store_op) { } } +WGPUTextureViewDimension webgpu_texture_view_dimension_from_rd(RDD::TextureType p_texture_type) { + switch(p_texture_type) { + case RenderingDeviceCommons::TEXTURE_TYPE_1D: + return WGPUTextureViewDimension_1D; + case RenderingDeviceCommons::TEXTURE_TYPE_2D: + return WGPUTextureViewDimension_2D; + case RenderingDeviceCommons::TEXTURE_TYPE_3D: + return WGPUTextureViewDimension_3D; + case RenderingDeviceCommons::TEXTURE_TYPE_CUBE: + return WGPUTextureViewDimension_Cube; + case RenderingDeviceCommons::TEXTURE_TYPE_1D_ARRAY: + return WGPUTextureViewDimension_Undefined; + case RenderingDeviceCommons::TEXTURE_TYPE_2D_ARRAY: + return WGPUTextureViewDimension_2DArray; + case RenderingDeviceCommons::TEXTURE_TYPE_CUBE_ARRAY: + return WGPUTextureViewDimension_CubeArray; + case RenderingDeviceCommons::TEXTURE_TYPE_MAX: + return WGPUTextureViewDimension_Undefined; + } +} + uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits) { WGPULimits limits = p_limits.limits; // NOTE: For limits that aren't supported, I've put the max uint64 value. This may cause issues. diff --git a/drivers/webgpu/webgpu_conv.h b/drivers/webgpu/webgpu_conv.h index 26fd08303d49..f6bd2810b78a 100644 --- a/drivers/webgpu/webgpu_conv.h +++ b/drivers/webgpu/webgpu_conv.h @@ -13,6 +13,7 @@ WGPUCompareFunction webgpu_compare_mode_from_rd(RDD::CompareOperator p_compare_o WGPUVertexFormat webgpu_vertex_format_from_rd(RDD::DataFormat p_data_format); WGPULoadOp webgpu_load_op_from_rd(RDD::AttachmentLoadOp p_load_op); WGPUStoreOp webgpu_store_op_from_rd(RDD::AttachmentStoreOp p_store_op); +WGPUTextureViewDimension webgpu_texture_view_dimension_from_rd(RDD::TextureType p_texture_type); uint64_t rd_limit_from_webgpu(RDD::Limit p_selected_limit, WGPUSupportedLimits p_limits); diff --git a/servers/rendering/rendering_device_commons.h b/servers/rendering/rendering_device_commons.h index 28d641c879a6..44ee563b6ce6 100644 --- a/servers/rendering/rendering_device_commons.h +++ b/servers/rendering/rendering_device_commons.h @@ -886,6 +886,15 @@ class RenderingDeviceCommons : public Object { BitField stages; uint32_t length = 0; // Size of arrays (in total elements), or ubos (in bytes * total elements). + // Applies for UNIFORM_TYPE_TEXTURE and UNIFORM_TYPE_SAMPLER_WITH_TEXTURE. + bool texture_is_multisample = false; + + // Applies for UNIFORM_TYPE_IMAGE. + DataFormat image_format = DATA_FORMAT_MAX; + + // For texture and image uniform types. + TextureType texture_image_type = TEXTURE_TYPE_2D; + bool operator!=(const ShaderUniform &p_other) const { return binding != p_other.binding || type != p_other.type || writable != p_other.writable || stages != p_other.stages || length != p_other.length; } diff --git a/servers/rendering/rendering_device_driver.cpp b/servers/rendering/rendering_device_driver.cpp index be74467340a6..2ccf476e7d0f 100644 --- a/servers/rendering/rendering_device_driver.cpp +++ b/servers/rendering/rendering_device_driver.cpp @@ -86,6 +86,9 @@ Error RenderingDeviceDriver::_reflect_spirv(VectorView p_s bool need_array_dimensions = false; bool need_block_size = false; bool may_be_writable = false; + bool need_texture_is_multisample = false; + bool need_image_format = false; + bool need_texture_image_type = false; switch (binding.descriptor_type) { case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: { @@ -95,15 +98,21 @@ Error RenderingDeviceDriver::_reflect_spirv(VectorView p_s case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { uniform.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; need_array_dimensions = true; + need_texture_is_multisample = true; + need_texture_image_type = true; } break; case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { uniform.type = UNIFORM_TYPE_TEXTURE; need_array_dimensions = true; + need_texture_is_multisample = true; + need_texture_image_type = true; } break; case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: { uniform.type = UNIFORM_TYPE_IMAGE; need_array_dimensions = true; may_be_writable = true; + need_image_format = true; + need_texture_image_type = true; } break; case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { uniform.type = UNIFORM_TYPE_TEXTURE_BUFFER; @@ -134,6 +143,7 @@ Error RenderingDeviceDriver::_reflect_spirv(VectorView p_s case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: { uniform.type = UNIFORM_TYPE_INPUT_ATTACHMENT; need_array_dimensions = true; + need_texture_is_multisample = true; } break; case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { ERR_PRINT("Acceleration structure not supported."); @@ -166,6 +176,166 @@ Error RenderingDeviceDriver::_reflect_spirv(VectorView p_s uniform.writable = false; } + if (need_texture_is_multisample) { + uniform.texture_is_multisample = binding.image.ms == 1; + } + + if (need_image_format) { + switch (binding.image.image_format) { + case SpvImageFormatRgba32f: + uniform.image_format = DATA_FORMAT_R32G32B32A32_SFLOAT; + break; + case SpvImageFormatRgba16f: + uniform.image_format = DATA_FORMAT_R16G16B16A16_SFLOAT; + break; + case SpvImageFormatR32f: + uniform.image_format = DATA_FORMAT_R32_SFLOAT; + break; + case SpvImageFormatRgba8: + uniform.image_format = DATA_FORMAT_R8G8B8A8_UNORM; + break; + case SpvImageFormatRgba8Snorm: + uniform.image_format = DATA_FORMAT_R8G8B8A8_SNORM; + break; + case SpvImageFormatRg32f: + uniform.image_format = DATA_FORMAT_R32G32_SFLOAT; + break; + case SpvImageFormatRg16f: + uniform.image_format = DATA_FORMAT_R16G16_SFLOAT; + break; + case SpvImageFormatR16f: + uniform.image_format = DATA_FORMAT_R16_SFLOAT; + break; + case SpvImageFormatRgba16: + uniform.image_format = DATA_FORMAT_R16G16B16A16_UNORM; + break; + case SpvImageFormatRg16: + uniform.image_format = DATA_FORMAT_R16G16_UNORM; + break; + case SpvImageFormatRg8: + uniform.image_format = DATA_FORMAT_R8G8_UNORM; + break; + case SpvImageFormatR16: + uniform.image_format = DATA_FORMAT_R16_UNORM; + break; + case SpvImageFormatR8: + uniform.image_format = DATA_FORMAT_R8_UNORM; + break; + case SpvImageFormatRgba16Snorm: + uniform.image_format = DATA_FORMAT_R16G16B16A16_SNORM; + break; + case SpvImageFormatRg16Snorm: + uniform.image_format = DATA_FORMAT_R16G16_SNORM; + break; + case SpvImageFormatRg8Snorm: + uniform.image_format = DATA_FORMAT_R8G8_SNORM; + break; + case SpvImageFormatR16Snorm: + uniform.image_format = DATA_FORMAT_R16_SNORM; + break; + case SpvImageFormatR8Snorm: + uniform.image_format = DATA_FORMAT_R8_SNORM; + break; + case SpvImageFormatRgba32i: + uniform.image_format = DATA_FORMAT_R32G32B32A32_SINT; + break; + case SpvImageFormatRgba16i: + uniform.image_format = DATA_FORMAT_R16G16B16A16_SINT; + break; + case SpvImageFormatRgba8i: + uniform.image_format = DATA_FORMAT_R8G8B8A8_SINT; + break; + case SpvImageFormatR32i: + uniform.image_format = DATA_FORMAT_R32_SINT; + break; + case SpvImageFormatRg32i: + uniform.image_format = DATA_FORMAT_R32G32_SINT; + break; + case SpvImageFormatRg16i: + uniform.image_format = DATA_FORMAT_R16G16_SINT; + break; + case SpvImageFormatRg8i: + uniform.image_format = DATA_FORMAT_R8G8_SINT; + break; + case SpvImageFormatR16i: + uniform.image_format = DATA_FORMAT_R16_SINT; + break; + case SpvImageFormatR8i: + uniform.image_format = DATA_FORMAT_R8_SINT; + break; + case SpvImageFormatRgba32ui: + uniform.image_format = DATA_FORMAT_R32G32B32A32_UINT; + break; + case SpvImageFormatRgba16ui: + uniform.image_format = DATA_FORMAT_R16G16B16A16_UINT; + break; + case SpvImageFormatRgba8ui: + uniform.image_format = DATA_FORMAT_R8G8B8A8_UINT; + break; + case SpvImageFormatR32ui: + uniform.image_format = DATA_FORMAT_R32_UINT; + break; + case SpvImageFormatRg32ui: + uniform.image_format = DATA_FORMAT_R32G32_UINT; + break; + case SpvImageFormatRg16ui: + uniform.image_format = DATA_FORMAT_R16G16_UINT; + break; + case SpvImageFormatRg8ui: + uniform.image_format = DATA_FORMAT_R8G8_UINT; + break; + case SpvImageFormatR16ui: + uniform.image_format = DATA_FORMAT_R16_UINT; + break; + case SpvImageFormatR8ui: + uniform.image_format = DATA_FORMAT_R8_UINT; + break; + case SpvImageFormatR64ui: + uniform.image_format = DATA_FORMAT_R64_UINT; + break; + case SpvImageFormatR64i: + uniform.image_format = DATA_FORMAT_R64_SINT; + break; + case SpvImageFormatUnknown: + print_error("Uniform image Format must be known"); + break; + case SpvImageFormatMax: + case SpvImageFormatR11fG11fB10f: + case SpvImageFormatRgb10A2: + case SpvImageFormatRgb10a2ui: + print_error("Uniform image format not supported"); + break; + } + } + + if (need_texture_image_type) { + switch (binding.image.dim) { + case SpvDim1D: + uniform.texture_image_type = + binding.image.arrayed ? TEXTURE_TYPE_1D_ARRAY : TEXTURE_TYPE_1D; + break; + case SpvDim2D: + uniform.texture_image_type = + binding.image.arrayed ? TEXTURE_TYPE_2D_ARRAY : TEXTURE_TYPE_2D; + break; + case SpvDim3D: + uniform.texture_image_type = + TEXTURE_TYPE_3D; + break; + case SpvDimCube: + uniform.texture_image_type = + binding.image.arrayed ? TEXTURE_TYPE_CUBE_ARRAY : TEXTURE_TYPE_CUBE; + break; + case SpvDimRect: + case SpvDimBuffer: + case SpvDimSubpassData: + case SpvDimTileImageDataEXT: + case SpvDimMax: + print_error("Only 1D, 2D, 3D, Cube images and their array equivalents supported"); + break; + } + } + uniform.binding = binding.binding; uint32_t set = binding.set; From 1eea78bd24fd7850b3a041362cdedcb556968f3c Mon Sep 17 00:00:00 2001 From: Sebastian Hamel Date: Wed, 10 Apr 2024 17:44:22 -0400 Subject: [PATCH 18/19] start platform windows rendering context for webgpu --- platform/windows/SCsub | 4 ++ ...endering_context_driver_webgpu_windows.cpp | 43 +++++++++++++++++++ .../rendering_context_driver_webgpu_windows.h | 27 ++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 platform/windows/rendering_context_driver_webgpu_windows.cpp create mode 100644 platform/windows/rendering_context_driver_webgpu_windows.h diff --git a/platform/windows/SCsub b/platform/windows/SCsub index cf6416b8dad6..320ad7c67f1f 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -24,6 +24,10 @@ common_win = [ "rendering_context_driver_vulkan_windows.cpp", ] +if env["webgpu"]: + common_win.append("rendering_context_driver_webgpu_windows.cpp") + + common_win_wrap = [ "console_wrapper_windows.cpp", ] diff --git a/platform/windows/rendering_context_driver_webgpu_windows.cpp b/platform/windows/rendering_context_driver_webgpu_windows.cpp new file mode 100644 index 000000000000..7638f33e409a --- /dev/null +++ b/platform/windows/rendering_context_driver_webgpu_windows.cpp @@ -0,0 +1,43 @@ +#ifdef WEBGPU_ENABLED + +#include "rendering_context_driver_webgpu_windows.h" + +RenderingContextDriver::SurfaceID RenderingContextDriverWebGpuWindows::surface_create(const void *p_platform_data) { + const WindowPlatformData *wpd = (const WindowPlatformData *)(p_platform_data); + + const WGPUSurfaceDescriptorFromWindowsHWND winHWND_desc = + (const WGPUSurfaceDescriptorFromWindowsHWND){ + .chain = + (const WGPUChainedStruct){ + .sType = WGPUSType_SurfaceDescriptorFromWindowsHWND, + }, + .hinstance = wpd->instance, + .hwnd = wpd->window, + }; + + WGPUSurfaceDescriptor surface_desc = + (WGPUSurfaceDescriptor){ + .nextInChain = + (const WGPUChainedStruct *)&winHWND_desc + }; + + WGPUSurface wgpu_surface = wgpuInstanceCreateSurface( + instance_get(), + &surface_desc); + + ERR_FAIL_COND_V(!wgpu_surface, SurfaceID()); + + Surface *surface = memnew(Surface); + surface->surface = wgpu_surface; + return SurfaceID(surface); +} + +RenderingContextDriverWebGpuWindows::RenderingContextDriverWebGpuWindows() { + // Does nothing. +} + +RenderingContextDriverWebGpuWindows::~RenderingContextDriverWebGpuWindows() { + // Does nothing. +} + +#endif // WEBGPU_ENABLED \ No newline at end of file diff --git a/platform/windows/rendering_context_driver_webgpu_windows.h b/platform/windows/rendering_context_driver_webgpu_windows.h new file mode 100644 index 000000000000..e4cdc48c6f99 --- /dev/null +++ b/platform/windows/rendering_context_driver_webgpu_windows.h @@ -0,0 +1,27 @@ +#ifndef RENDERING_CONTEXT_DRIVER_WEBGPU_WINDOWS_H +#define RENDERING_CONTEXT_DRIVER_WEBGPU_WINDOWS_H + +#ifdef WEBGPU_ENABLED + +#include "drivers/webgpu/rendering_context_driver_webgpu.h" + +#define WIN32_LEAN_AND_MEAN +#include + +class RenderingContextDriverWebGpuWindows : public RenderingContextDriverWebGpu { +protected: + SurfaceID surface_create(const void *p_platform_data) override final; + +public: + struct WindowPlatformData { + HWND window; + HINSTANCE instance; + }; + + RenderingContextDriverWebGpuWindows(); + ~RenderingContextDriverWebGpuWindows(); +}; + +#endif // WEBGPU_ENABLED + +#endif // RENDERING_CONTEXT_DRIVER_WEBGPU_WINDOWS_H \ No newline at end of file From fedffcfd4f7ecb7f4400f1244b2b9df21e36433f Mon Sep 17 00:00:00 2001 From: Sebastian Hamel Date: Wed, 10 Apr 2024 18:36:20 -0400 Subject: [PATCH 19/19] add webgpu rendering driver on windows --- platform/windows/detect.py | 3 +++ platform/windows/display_server_windows.cpp | 20 ++++++++++++++++++++ platform/windows/display_server_windows.h | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 196beb423f47..9da4be7f591b 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -724,6 +724,9 @@ def configure_mingw(env: "SConsEnvironment"): if not env["use_volk"]: env.Append(LIBS=["vulkan"]) + if env["webgpu"]: + env.Append(CPPDEFINES=["WEBGPU_ENABLED", "RD_ENABLED"]) + if env["d3d12"]: # Check whether we have d3d12 dependencies installed. if not os.path.exists(env["mesa_libs"]): diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 074d40bf4bd2..5c9940f271c2 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -42,6 +42,9 @@ #if defined(VULKAN_ENABLED) #include "rendering_context_driver_vulkan_windows.h" #endif +#if defined(WEBGPU_ENABLED) +#include "rendering_context_driver_webgpu_windows.h" +#endif #if defined(D3D12_ENABLED) #include "drivers/d3d12/rendering_context_driver_d3d12.h" #endif @@ -5141,6 +5144,9 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, #ifdef VULKAN_ENABLED RenderingContextDriverVulkanWindows::WindowPlatformData vulkan; #endif +#ifdef WEBGPU_ENABLED + RenderingContextDriverWebGpuWindows::WindowPlatformData webgpu; +#endif #ifdef D3D12_ENABLED RenderingContextDriverD3D12::WindowPlatformData d3d12; #endif @@ -5151,6 +5157,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, wpd.vulkan.instance = hInstance; } #endif +#ifdef WEBGPU_ENABLED + if (rendering_driver == "webgpu") { + wpd.webgpu.window = wd.hWnd; + wpd.webgpu.instance = hInstance; + } +#endif #ifdef D3D12_ENABLED if (rendering_driver == "d3d12") { wpd.d3d12.window = wd.hWnd; @@ -5625,6 +5637,11 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win rendering_context = memnew(RenderingContextDriverVulkanWindows); } #endif +#if defined(WEBGPU_ENABLED) + if (rendering_driver == "webgpu") { + rendering_context = memnew(RenderingContextDriverWebGpuWindows); + } +#endif #if defined(D3D12_ENABLED) if (rendering_driver == "d3d12") { rendering_context = memnew(RenderingContextDriverD3D12); @@ -5796,6 +5813,9 @@ Vector DisplayServerWindows::get_rendering_drivers_func() { #ifdef VULKAN_ENABLED drivers.push_back("vulkan"); #endif +#ifdef WEBGPU_ENABLED + drivers.push_back("webgpu"); +#endif #ifdef D3D12_ENABLED drivers.push_back("d3d12"); #endif diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 1191f2296876..d4c6b5c4fc40 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -56,6 +56,10 @@ #include "servers/rendering/rendering_device.h" #endif +#if defined(WEBGPU_ENABLED) +#include "rendering_context_driver_webgpu_windows.h" +#endif + #if defined(GLES3_ENABLED) #include "gl_manager_windows_angle.h" #include "gl_manager_windows_native.h"