From 6968d6f84e9875ee67cb241592d6b6e0cabe48ed Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Tue, 25 Feb 2025 22:22:07 +0100 Subject: [PATCH] adding base webgpu compute pass and compute pipeline --- Sources/Backends/Vulkan/VulkanComputePass.c | 9 +--- Sources/Backends/WebGPU/WebGPUComputePass.c | 25 ++++++++++ Sources/Backends/WebGPU/WebGPUComputePass.h | 1 + .../Backends/WebGPU/WebGPUComputePipeline.c | 47 +++++++++++++++++++ .../Backends/WebGPU/WebGPUComputePipeline.h | 2 + 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/Sources/Backends/Vulkan/VulkanComputePass.c b/Sources/Backends/Vulkan/VulkanComputePass.c index b539279..695cdab 100644 --- a/Sources/Backends/Vulkan/VulkanComputePass.c +++ b/Sources/Backends/Vulkan/VulkanComputePass.c @@ -9,18 +9,13 @@ PulseComputePass VulkanCreateComputePass(PulseDevice device, PulseCommandList cmd) { + PULSE_UNUSED(device); PulseComputePass pass = (PulseComputePass)calloc(1, sizeof(PulseComputePassHandler)); PULSE_CHECK_ALLOCATION_RETVAL(pass, PULSE_NULL_HANDLE); VulkanComputePass* vulkan_pass = (VulkanComputePass*)calloc(1, sizeof(VulkanComputePass)); PULSE_CHECK_ALLOCATION_RETVAL(vulkan_pass, PULSE_NULL_HANDLE); - VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*); - -// vulkan_pass->read_only_descriptor_set = VulkanRequestDescriptorSetFromPool( -// VulkanGetAvailableDescriptorSetPool(&vulkan_device->descriptor_set_pool_manager), -// VulkanGetDescriptorSetLayout(&vulkan_device->descriptor_set_layout_manager, )); - pass->cmd = cmd; pass->driver_data = vulkan_pass; @@ -29,7 +24,7 @@ PulseComputePass VulkanCreateComputePass(PulseDevice device, PulseCommandList cm void VulkanDestroyComputePass(PulseDevice device, PulseComputePass pass) { - (void)device; // Maybe reserved for future use + PULSE_UNUSED(device); free(pass->driver_data); free(pass); } diff --git a/Sources/Backends/WebGPU/WebGPUComputePass.c b/Sources/Backends/WebGPU/WebGPUComputePass.c index 5cb04fe..2a1ea79 100644 --- a/Sources/Backends/WebGPU/WebGPUComputePass.c +++ b/Sources/Backends/WebGPU/WebGPUComputePass.c @@ -4,21 +4,44 @@ #include #include "WebGPU.h" +#include "WebGPUDevice.h" +#include "WebGPUComputePass.h" PulseComputePass WebGPUCreateComputePass(PulseDevice device, PulseCommandList cmd) { + PULSE_UNUSED(device); + PulseComputePass pass = (PulseComputePass)calloc(1, sizeof(PulseComputePassHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(pass, PULSE_NULL_HANDLE); + + WebGPUComputePass* webgpu_pass = (WebGPUComputePass*)calloc(1, sizeof(WebGPUComputePass)); + PULSE_CHECK_ALLOCATION_RETVAL(webgpu_pass, PULSE_NULL_HANDLE); + + pass->cmd = cmd; + pass->driver_data = webgpu_pass; + + return pass; } void WebGPUDestroyComputePass(PulseDevice device, PulseComputePass pass) { + PULSE_UNUSED(device); + free(pass->driver_data); + free(pass); } PulseComputePass WebGPUBeginComputePass(PulseCommandList cmd) { + WebGPUCommandList* webgpu_cmd = WEBGPU_RETRIEVE_DRIVER_DATA_AS(cmd, WebGPUCommandList*); + WebGPUComputePass* webgpu_pass = WEBGPU_RETRIEVE_DRIVER_DATA_AS(cmd->pass, WebGPUComputePass*); + WGPUComputePassDescriptor descriptor = { 0 }; + webgpu_pass->encoder = wgpuCommandEncoderBeginComputePass(webgpu_cmd->encoder, &descriptor); + return cmd->pass; } void WebGPUEndComputePass(PulseComputePass pass) { + WebGPUComputePass* webgpu_pass = WEBGPU_RETRIEVE_DRIVER_DATA_AS(pass, WebGPUComputePass*); + wgpuComputePassEncoderEnd(webgpu_pass->encoder); } void WebGPUBindStorageBuffers(PulseComputePass pass, const PulseBuffer* buffers, uint32_t num_buffers) @@ -39,4 +62,6 @@ void WebGPUBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipel void WebGPUDispatchComputations(PulseComputePass pass, uint32_t groupcount_x, uint32_t groupcount_y, uint32_t groupcount_z) { + WebGPUComputePass* webgpu_pass = WEBGPU_RETRIEVE_DRIVER_DATA_AS(pass, WebGPUComputePass*); + wgpuComputePassEncoderDispatchWorkgroups(webgpu_pass->encoder, groupcount_x, groupcount_y, groupcount_z); } diff --git a/Sources/Backends/WebGPU/WebGPUComputePass.h b/Sources/Backends/WebGPU/WebGPUComputePass.h index 347842d..20c2512 100644 --- a/Sources/Backends/WebGPU/WebGPUComputePass.h +++ b/Sources/Backends/WebGPU/WebGPUComputePass.h @@ -15,6 +15,7 @@ typedef struct WebGPUComputePass { + WGPUComputePassEncoder encoder; } WebGPUComputePass; PulseComputePass WebGPUCreateComputePass(PulseDevice device, PulseCommandList cmd); diff --git a/Sources/Backends/WebGPU/WebGPUComputePipeline.c b/Sources/Backends/WebGPU/WebGPUComputePipeline.c index e152221..cd351a3 100644 --- a/Sources/Backends/WebGPU/WebGPUComputePipeline.c +++ b/Sources/Backends/WebGPU/WebGPUComputePipeline.c @@ -3,10 +3,57 @@ // For conditions of distribution and use, see copyright notice in LICENSE #include +#include "../../PulseInternal.h" #include "WebGPU.h" +#include "WebGPUDevice.h" +#include "WebGPUComputePipeline.h" PulseComputePipeline WebGPUCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info) { + WebGPUDevice* webgpu_device = WEBGPU_RETRIEVE_DRIVER_DATA_AS(device, WebGPUDevice*); + + PulseComputePipelineHandler* pipeline = (PulseComputePipelineHandler*)calloc(1, sizeof(PulseComputePipelineHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(pipeline, PULSE_NULL_HANDLE); + + WebGPUComputePipeline* webgpu_pipeline = (WebGPUComputePipeline*)calloc(1, sizeof(WebGPUComputePipeline)); + PULSE_CHECK_ALLOCATION_RETVAL(webgpu_pipeline, PULSE_NULL_HANDLE); + + pipeline->driver_data = webgpu_pipeline; + + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + { + if(info->code == PULSE_NULLPTR) + PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo"); + if(info->entrypoint == PULSE_NULLPTR) + PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo"); + if(info->format == PULSE_SHADER_FORMAT_WGSL_BIT && (device->backend->supported_shader_formats & PULSE_SHADER_FORMAT_WGSL_BIT) == 0) + PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo"); + } + + WGPUStringView code = { 0 }; + code.length = info->code_size; + code.data = (const char*)info->code; + WGPUChainedStruct chain = { 0 }; + chain.next = PULSE_NULLPTR; + chain.sType = WGPUSType_ShaderSourceWGSL; + WGPUShaderSourceWGSL source = { 0 }; + source.chain = chain; + source.code = code; + WGPUShaderModuleDescriptor shader_descriptor = { 0 }; + shader_descriptor.nextInChain = (const WGPUChainedStruct*)&source; + webgpu_pipeline->shader = wgpuDeviceCreateShaderModule(webgpu_device->device, &shader_descriptor); + + WGPUStringView entrypoint = { 0 }; + code.length = WGPU_STRLEN; + code.data = info->entrypoint; + WGPUProgrammableStageDescriptor state = { 0 }; + state.module = webgpu_pipeline->shader; + state.entryPoint = entrypoint; + WGPUComputePipelineDescriptor pipeline_descriptor = { 0 }; + pipeline_descriptor.compute = state; + webgpu_pipeline->pipeline = wgpuDeviceCreateComputePipeline(webgpu_device->device, &pipeline_descriptor); + + return pipeline; } void WebGPUDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline) diff --git a/Sources/Backends/WebGPU/WebGPUComputePipeline.h b/Sources/Backends/WebGPU/WebGPUComputePipeline.h index 8dd08e4..85cc295 100644 --- a/Sources/Backends/WebGPU/WebGPUComputePipeline.h +++ b/Sources/Backends/WebGPU/WebGPUComputePipeline.h @@ -13,6 +13,8 @@ typedef struct WebGPUComputePipeline { + WGPUComputePipeline pipeline; + WGPUShaderModule shader; } WebGPUComputePipeline; PulseComputePipeline WebGPUCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);