Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 2 additions & 0 deletions drivers/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -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"]:
Expand Down
5 changes: 5 additions & 0 deletions drivers/vulkan/rendering_device_driver_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -4960,3 +4962,6 @@ RenderingDeviceDriverVulkan::~RenderingDeviceDriverVulkan() {
vkDestroyDevice(vk_device, nullptr);
}
}

#endif // VULKAN_ENABLED

4 changes: 4 additions & 0 deletions drivers/vulkan/rendering_device_driver_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -646,4 +648,6 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
virtual ~RenderingDeviceDriverVulkan();
};

#endif // VULKAN_ENABLED

#endif // RENDERING_DEVICE_DRIVER_VULKAN_H
24 changes: 24 additions & 0 deletions drivers/webgpu/SCsub
Original file line number Diff line number Diff line change
@@ -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])
160 changes: 160 additions & 0 deletions drivers/webgpu/rendering_context_driver_webgpu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#include "webgpu.h"

#ifdef WEBGPU_ENABLED

#include "rendering_context_driver_webgpu.h"

#include "core/error/error_macros.h"

#include "rendering_device_driver_webgpu.h"

static void handle_request_adapter(WGPURequestAdapterStatus status,
WGPUAdapter adapter, char const *message,
void *userdata) {
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,
handle_request_adapter, this);

adapter_options.powerPreference = WGPUPowerPreference::WGPUPowerPreference_LowPower;
wgpuInstanceRequestAdapter(instance,
&adapter_options,
handle_request_adapter, this);

return OK;
}

const RenderingContextDriver::Device &RenderingContextDriverWebGpu::device_get(uint32_t p_device_index) const {
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 {
return adapters.size();
}

bool RenderingContextDriverWebGpu::device_supports_present(uint32_t p_device_index, SurfaceID p_surface) const {
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() {
return memnew(RenderingDeviceDriverWebGpu(this));
}

void RenderingContextDriverWebGpu::driver_free(RenderingDeviceDriver *p_driver) {
memdelete(p_driver);
}

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) {
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) {
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 {
Surface *surface = (Surface *)(p_surface);
return surface->vsync_mode;
}

uint32_t RenderingContextDriverWebGpu::surface_get_width(SurfaceID p_surface) const {
Surface *surface = (Surface *)(p_surface);
return surface->width;
}

uint32_t RenderingContextDriverWebGpu::surface_get_height(SurfaceID p_surface) const {
Surface *surface = (Surface *)(p_surface);
return surface->height;
}

void RenderingContextDriverWebGpu::surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) {
Surface *surface = (Surface *)(p_surface);
surface->needs_resize = p_needs_resize;
}

bool RenderingContextDriverWebGpu::surface_get_needs_resize(SurfaceID p_surface) const {
Surface *surface = (Surface *)(p_surface);
return surface->needs_resize;
}

void RenderingContextDriverWebGpu::surface_destroy(SurfaceID p_surface) {
Surface *surface = (Surface *)(p_surface);
wgpuSurfaceRelease(surface->surface);
memdelete(surface);
}
bool RenderingContextDriverWebGpu::is_debug_utils_enabled() const {
// 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;
}

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);
}

#endif // WEBGPU_ENABLED
49 changes: 49 additions & 0 deletions drivers/webgpu/rendering_context_driver_webgpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#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 <webgpu.h>

class RenderingContextDriverWebGpu : public RenderingContextDriver {
private:
WGPUInstance instance = nullptr;
TightLocalVector<WGPUAdapter> adapters;
TightLocalVector<Device> driver_devices;

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;

struct Surface {
WGPUSurface surface = nullptr;
uint32_t width = 0;
uint32_t height = 0;
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
bool needs_resize = false;
};

WGPUInstance instance_get() const;
WGPUAdapter adapter_get(uint32_t p_adapter_index) const;
void adapter_push_back(WGPUAdapter p_adapter, Device p_device);
};

#endif // RENDERING_CONTEXT_DRIVER_WEBGPU_H
Loading