From a4def517dd11eadc56312ad8b64cd082a40d0e23 Mon Sep 17 00:00:00 2001 From: Oliver Bestmann Date: Wed, 27 May 2026 07:08:18 +0200 Subject: [PATCH 1/5] cgo: automatically generate wgpu wrapper functions and add #cgo annotations to reduce memory allocation & cgo overhead --- cmd/cgohints/main.go | 239 +++ examples/triangle/main.go | 8 + wgpu/buffer.go | 46 +- wgpu/cgo_test.go | 46 + wgpu/cgohints.go | 277 ++++ wgpu/command_encoder.go | 249 +-- wgpu/common.go | 5 +- wgpu/compute_pass_encoder.go | 41 +- wgpu/device.go | 271 +--- wgpu/error-callback.go | 48 +- wgpu/gen_wrappers.go | 6 +- wgpu/queue.go | 63 +- wgpu/render_pass_encoder.go | 25 +- wgpu/surface.go | 31 +- wgpu/texture.go | 40 +- wgpu/wgpu_c_cb.go | 9 - wgpu/wgpu_go_wrappers.h | 2864 ++++++++++++++++++++++++++++++++++ 17 files changed, 3638 insertions(+), 630 deletions(-) create mode 100644 cmd/cgohints/main.go create mode 100644 wgpu/cgo_test.go create mode 100644 wgpu/cgohints.go create mode 100644 wgpu/wgpu_go_wrappers.h diff --git a/cmd/cgohints/main.go b/cmd/cgohints/main.go new file mode 100644 index 0000000..c19824f --- /dev/null +++ b/cmd/cgohints/main.go @@ -0,0 +1,239 @@ +package main + +import ( + "flag" + "fmt" + "go/format" + "io" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "slices" + "strings" +) + +var ( + path string +) + +func init() { + flag.StringVar(&path, "i", "", "Path that contains the wgpu source files") +} + +func listUsed() []string { + re := regexp.MustCompile(`\bC.((?:go_)?wgpu[A-Z][A-Za-z]+)`) + + seen := map[string]bool{} + var names []string + + files := mustv(filepath.Glob(path + "/*.go")) + for _, file := range files { + source := string(mustv(os.ReadFile(file))) + for _, match := range re.FindAllStringSubmatch(source, -1) { + fn := match[1] + + if !seen[fn] { + seen[fn] = true + names = append(names, fn) + } + } + } + + slices.Sort(names) + + return names +} + +func main() { + flag.Parse() + + { + code := generateHints() + writeTo(path+"/cgohints.go", fmtGo(code)) + } + + { + code := generateWrappers() + writeTo(path+"/wgpu_go_wrappers.h", fmtC(code)) + } +} + +func generateHints() string { + withCallback := map[string]bool{} + for _, fn := range FindFunctions() { + if strings.Contains(fn.Params, "Callback") { + withCallback[fn.Name] = true + } + + if fn.RetType == "WGPUFuture" { + withCallback[fn.Name] = true + } + } + + var code []string + code = append(code, "// Code generated by cmd/refcount: DO NOT EDIT.\n") + code = append(code, "//go:build !js") + code = append(code, "package wgpu") + + code = append(code, "/*") + + for _, fn := range listUsed() { + fnWGPU := strings.TrimPrefix(fn, "go_") + if withCallback[fnWGPU] { + fmt.Println("Skipping function with callback:", fn) + continue + } + + if fnWGPU == "wgpuDevicePoll" || fnWGPU == "wgpuQueuesubmit" { + // if i understood correctly, + // those methods can run previously scheduled callbacks + continue + } + + code = append(code, "#cgo noescape "+fn) + code = append(code, "#cgo nocallback "+fn) + } + + code = append(code, "*/") + code = append(code, `import "C"`) + + return strings.Join(code, "\n") +} + +func writeTo(path string, content string) { + out, err := os.Create(path) + if err != nil { + panic(err) + } + + defer doClose(out) + + mustv(out.WriteString(content)) +} + +func doClose(out io.Closer) { + _ = out.Close() +} + +type Function struct { + RetType string + Name string + Params string +} + +func FindFunctions() (funcs []Function) { + webgpuH := string(mustv(os.ReadFile(path + "/lib/linux/arm64/webgpu.h"))) + + re := regexp.MustCompile(`(?m)^WGPU_EXPORT(?: WGPU_NULLABLE)? (\S+) (wgpu[^(]+)\((.*)\)`) + + for _, match := range re.FindAllStringSubmatch(webgpuH, -1) { + funcs = append(funcs, Function{ + RetType: match[1], + Name: match[2], + Params: match[3], + }) + } + + return +} + +func generateWrappers() string { + var lines []string + lines = append(lines, "// Code generated by cmd/refcount: DO NOT EDIT.\n") + + lines = append(lines, ` + #pragma once + + #include + #include + #include + + static inline void webgpu_error_callback(WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, WGPU_NULLABLE void* userdata1, WGPU_NULLABLE void* userdata2) { + char* err = (char *)userdata1; + if (type == WGPUErrorType_NoError) { + return; + } + + strncpy(err, message.data, 1024-1); + } + `) + + for _, fn := range FindFunctions() { + var paramValues []string + + reValue := regexp.MustCompile(`([a-zA-Z0-9]+)(,|$)`) + for _, match := range reValue.FindAllStringSubmatch(fn.Params, -1) { + paramValues = append(paramValues, match[1]) + } + + var returnVar, returnStmt string + if fn.RetType != "void" { + returnVar = fn.RetType + " ret = " + returnStmt = "return ret;" + } + + lines = append(lines, fmt.Sprintf(` + static inline %[6]s go_%[1]s(WGPUDevice _dev, char *err, %[2]s) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + %[4]s %[1]s(%[3]s); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void*) err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + %[5]s + } + `, + fn.Name, + fn.Params, + strings.Join(paramValues, ", "), + returnVar, + returnStmt, + fn.RetType, + )) + + lines = append(lines, "") + } + + return strings.Join(lines, "\n") +} + +func fmtGo(input string) string { + b, err := format.Source([]byte(input)) + if err != nil { + fmt.Println() + fmt.Println(input) + fmt.Println() + log.Fatalf("cannot run 'go fmt' on file: %v", err) + } + + return string(b) +} + +func fmtC(input string) string { + var w strings.Builder + + cmd := exec.Command("clang-format") + cmd.Stdin = strings.NewReader(input) + cmd.Stdout = &w + must(cmd.Run()) + + return w.String() +} + +func must(err error) { + if err != nil { + panic(err) + } +} + +func mustv[T any](v T, err error) T { + if err != nil { + panic(err) + } + return v +} diff --git a/examples/triangle/main.go b/examples/triangle/main.go index 64ef4f7..85c30da 100644 --- a/examples/triangle/main.go +++ b/examples/triangle/main.go @@ -153,6 +153,12 @@ func (s *State) Render() error { return nil } + defer func() { + if nextTexture != nil { + nextTexture.Release() + } + }() + view, err := nextTexture.TryCreateView(nil) if err != nil { return err @@ -191,6 +197,8 @@ func (s *State) Render() error { s.queue.Submit(cmdBuffer) s.surface.Present() + nextTexture = nil + return nil } diff --git a/wgpu/buffer.go b/wgpu/buffer.go index a190ed5..b54f696 100644 --- a/wgpu/buffer.go +++ b/wgpu/buffer.go @@ -3,38 +3,8 @@ package wgpu /* - -#include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); - +#include "wgpu_go_wrappers.h" extern void gowebgpu_buffer_map_callback_c(WGPUMapAsyncStatus status, WGPUStringView message, void *userdata, void *userdata2); - -static inline void gowebgpu_buffer_map_async(WGPUBuffer buffer, WGPUMapMode mode, size_t offset, size_t size, WGPUBufferMapCallbackInfo callback, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuBufferMapAsync(buffer, mode, offset, size, callback); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_buffer_unmap(WGPUBuffer buffer, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuBufferUnmap(buffer); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - */ import "C" import ( @@ -75,7 +45,9 @@ func (p *Buffer) TryMapAsync(mode MapMode, offset uint64, size uint64, callback errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_buffer_map_async( + C.go_wgpuBufferMapAsync( + p.device, + errh.ToPointer(), p.ref, C.WGPUMapMode(mode), C.size_t(offset), @@ -84,22 +56,20 @@ func (p *Buffer) TryMapAsync(mode MapMode, offset uint64, size uint64, callback callback: C.WGPUBufferMapCallback(C.gowebgpu_buffer_map_callback_c), userdata1: callbackHandle.ToPointer(), }, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *Buffer) TryUnmap() error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_buffer_unmap( - p.ref, + C.go_wgpuBufferUnmap( p.device, errh.ToPointer(), + p.ref, ) - return errh.err + return errh.ToError() } diff --git a/wgpu/cgo_test.go b/wgpu/cgo_test.go new file mode 100644 index 0000000..9a20475 --- /dev/null +++ b/wgpu/cgo_test.go @@ -0,0 +1,46 @@ +package wgpu + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func BenchmarkCGoOverhead(b *testing.B) { + instance := CreateInstance(nil) + + adapter, err := instance.RequestAdapter(&RequestAdapterOptions{ + ForceFallbackAdapter: true, + }) + require.NoError(b, err) + defer adapter.Release() + + device, err := adapter.RequestDevice(nil) + require.NoError(b, err) + defer device.Release() + + queue := device.GetQueue() + defer queue.Release() + + b.ReportAllocs() + + texture := device.CreateTexture(&TextureDescriptor{ + Label: "test", + Usage: TextureUsageCopyDst, + Dimension: TextureDimension2D, + Size: Extent3D{Width: 16, Height: 16, DepthOrArrayLayers: 1}, + Format: TextureFormatRGBA8Unorm, + MipLevelCount: 1, + SampleCount: 1, + }) + + for range b.N { + view := texture.CreateView(&TextureViewDescriptor{ + Label: "test label", + MipLevelCount: 1, + ArrayLayerCount: 1, + }) + + view.Release() + } +} diff --git a/wgpu/cgohints.go b/wgpu/cgohints.go new file mode 100644 index 0000000..77d67cd --- /dev/null +++ b/wgpu/cgohints.go @@ -0,0 +1,277 @@ +// Code generated by cmd/refcount: DO NOT EDIT. + +//go:build !js + +package wgpu + +/* +#cgo noescape go_wgpuBufferUnmap +#cgo nocallback go_wgpuBufferUnmap +#cgo noescape go_wgpuCommandEncoderBeginRenderPass +#cgo nocallback go_wgpuCommandEncoderBeginRenderPass +#cgo noescape go_wgpuCommandEncoderClearBuffer +#cgo nocallback go_wgpuCommandEncoderClearBuffer +#cgo noescape go_wgpuCommandEncoderCopyBufferToBuffer +#cgo nocallback go_wgpuCommandEncoderCopyBufferToBuffer +#cgo noescape go_wgpuCommandEncoderCopyBufferToTexture +#cgo nocallback go_wgpuCommandEncoderCopyBufferToTexture +#cgo noescape go_wgpuCommandEncoderCopyTextureToBuffer +#cgo nocallback go_wgpuCommandEncoderCopyTextureToBuffer +#cgo noescape go_wgpuCommandEncoderCopyTextureToTexture +#cgo nocallback go_wgpuCommandEncoderCopyTextureToTexture +#cgo noescape go_wgpuCommandEncoderFinish +#cgo nocallback go_wgpuCommandEncoderFinish +#cgo noescape go_wgpuCommandEncoderInsertDebugMarker +#cgo nocallback go_wgpuCommandEncoderInsertDebugMarker +#cgo noescape go_wgpuCommandEncoderPopDebugGroup +#cgo nocallback go_wgpuCommandEncoderPopDebugGroup +#cgo noescape go_wgpuCommandEncoderPushDebugGroup +#cgo nocallback go_wgpuCommandEncoderPushDebugGroup +#cgo noescape go_wgpuCommandEncoderResolveQuerySet +#cgo nocallback go_wgpuCommandEncoderResolveQuerySet +#cgo noescape go_wgpuComputePassEncoderEnd +#cgo nocallback go_wgpuComputePassEncoderEnd +#cgo noescape go_wgpuDeviceCreateBindGroup +#cgo nocallback go_wgpuDeviceCreateBindGroup +#cgo noescape go_wgpuDeviceCreateBindGroupLayout +#cgo nocallback go_wgpuDeviceCreateBindGroupLayout +#cgo noescape go_wgpuDeviceCreateBuffer +#cgo nocallback go_wgpuDeviceCreateBuffer +#cgo noescape go_wgpuDeviceCreateCommandEncoder +#cgo nocallback go_wgpuDeviceCreateCommandEncoder +#cgo noescape go_wgpuDeviceCreateComputePipeline +#cgo nocallback go_wgpuDeviceCreateComputePipeline +#cgo noescape go_wgpuDeviceCreatePipelineLayout +#cgo nocallback go_wgpuDeviceCreatePipelineLayout +#cgo noescape go_wgpuDeviceCreateQuerySet +#cgo nocallback go_wgpuDeviceCreateQuerySet +#cgo noescape go_wgpuDeviceCreateRenderPipeline +#cgo nocallback go_wgpuDeviceCreateRenderPipeline +#cgo noescape go_wgpuDeviceCreateSampler +#cgo nocallback go_wgpuDeviceCreateSampler +#cgo noescape go_wgpuDeviceCreateShaderModule +#cgo nocallback go_wgpuDeviceCreateShaderModule +#cgo noescape go_wgpuDeviceCreateTexture +#cgo nocallback go_wgpuDeviceCreateTexture +#cgo noescape go_wgpuQueueWriteBuffer +#cgo nocallback go_wgpuQueueWriteBuffer +#cgo noescape go_wgpuQueueWriteTexture +#cgo nocallback go_wgpuQueueWriteTexture +#cgo noescape go_wgpuRenderPassEncoderEnd +#cgo nocallback go_wgpuRenderPassEncoderEnd +#cgo noescape go_wgpuSurfaceGetCurrentTexture +#cgo nocallback go_wgpuSurfaceGetCurrentTexture +#cgo noescape go_wgpuTextureCreateView +#cgo nocallback go_wgpuTextureCreateView +#cgo noescape wgpuAdapterGetFeatures +#cgo nocallback wgpuAdapterGetFeatures +#cgo noescape wgpuAdapterGetInfo +#cgo nocallback wgpuAdapterGetInfo +#cgo noescape wgpuAdapterGetLimits +#cgo nocallback wgpuAdapterGetLimits +#cgo noescape wgpuAdapterHasFeature +#cgo nocallback wgpuAdapterHasFeature +#cgo noescape wgpuAdapterRelease +#cgo nocallback wgpuAdapterRelease +#cgo noescape wgpuBindGroupLayoutRelease +#cgo nocallback wgpuBindGroupLayoutRelease +#cgo noescape wgpuBindGroupRelease +#cgo nocallback wgpuBindGroupRelease +#cgo noescape wgpuBufferDestroy +#cgo nocallback wgpuBufferDestroy +#cgo noescape wgpuBufferGetMappedRange +#cgo nocallback wgpuBufferGetMappedRange +#cgo noescape wgpuBufferGetSize +#cgo nocallback wgpuBufferGetSize +#cgo noescape wgpuBufferGetUsage +#cgo nocallback wgpuBufferGetUsage +#cgo noescape wgpuBufferRelease +#cgo nocallback wgpuBufferRelease +#cgo noescape wgpuCommandBufferRelease +#cgo nocallback wgpuCommandBufferRelease +#cgo noescape wgpuCommandEncoderBeginComputePass +#cgo nocallback wgpuCommandEncoderBeginComputePass +#cgo noescape wgpuCommandEncoderRelease +#cgo nocallback wgpuCommandEncoderRelease +#cgo noescape wgpuComputePassEncoderBeginPipelineStatisticsQuery +#cgo nocallback wgpuComputePassEncoderBeginPipelineStatisticsQuery +#cgo noescape wgpuComputePassEncoderDispatchWorkgroups +#cgo nocallback wgpuComputePassEncoderDispatchWorkgroups +#cgo noescape wgpuComputePassEncoderDispatchWorkgroupsIndirect +#cgo nocallback wgpuComputePassEncoderDispatchWorkgroupsIndirect +#cgo noescape wgpuComputePassEncoderEndPipelineStatisticsQuery +#cgo nocallback wgpuComputePassEncoderEndPipelineStatisticsQuery +#cgo noescape wgpuComputePassEncoderInsertDebugMarker +#cgo nocallback wgpuComputePassEncoderInsertDebugMarker +#cgo noescape wgpuComputePassEncoderPopDebugGroup +#cgo nocallback wgpuComputePassEncoderPopDebugGroup +#cgo noescape wgpuComputePassEncoderPushDebugGroup +#cgo nocallback wgpuComputePassEncoderPushDebugGroup +#cgo noescape wgpuComputePassEncoderRelease +#cgo nocallback wgpuComputePassEncoderRelease +#cgo noescape wgpuComputePassEncoderSetBindGroup +#cgo nocallback wgpuComputePassEncoderSetBindGroup +#cgo noescape wgpuComputePassEncoderSetPipeline +#cgo nocallback wgpuComputePassEncoderSetPipeline +#cgo noescape wgpuComputePipelineGetBindGroupLayout +#cgo nocallback wgpuComputePipelineGetBindGroupLayout +#cgo noescape wgpuComputePipelineRelease +#cgo nocallback wgpuComputePipelineRelease +#cgo noescape wgpuCreateInstance +#cgo nocallback wgpuCreateInstance +#cgo noescape wgpuDeviceAddRef +#cgo nocallback wgpuDeviceAddRef +#cgo noescape wgpuDeviceCreateRenderBundleEncoder +#cgo nocallback wgpuDeviceCreateRenderBundleEncoder +#cgo noescape wgpuDeviceGetFeatures +#cgo nocallback wgpuDeviceGetFeatures +#cgo noescape wgpuDeviceGetLimits +#cgo nocallback wgpuDeviceGetLimits +#cgo noescape wgpuDeviceGetQueue +#cgo nocallback wgpuDeviceGetQueue +#cgo noescape wgpuDeviceHasFeature +#cgo nocallback wgpuDeviceHasFeature +#cgo noescape wgpuDeviceRelease +#cgo nocallback wgpuDeviceRelease +#cgo noescape wgpuGenerateReport +#cgo nocallback wgpuGenerateReport +#cgo noescape wgpuGetVersion +#cgo nocallback wgpuGetVersion +#cgo noescape wgpuInstanceCreateSurface +#cgo nocallback wgpuInstanceCreateSurface +#cgo noescape wgpuInstanceEnumerateAdapters +#cgo nocallback wgpuInstanceEnumerateAdapters +#cgo noescape wgpuInstanceRelease +#cgo nocallback wgpuInstanceRelease +#cgo noescape wgpuPipelineLayoutRelease +#cgo nocallback wgpuPipelineLayoutRelease +#cgo noescape wgpuQuerySetRelease +#cgo nocallback wgpuQuerySetRelease +#cgo noescape wgpuQueueRelease +#cgo nocallback wgpuQueueRelease +#cgo noescape wgpuQueueSubmitForIndex +#cgo nocallback wgpuQueueSubmitForIndex +#cgo noescape wgpuRenderBundleEncoderDraw +#cgo nocallback wgpuRenderBundleEncoderDraw +#cgo noescape wgpuRenderBundleEncoderDrawIndexed +#cgo nocallback wgpuRenderBundleEncoderDrawIndexed +#cgo noescape wgpuRenderBundleEncoderDrawIndexedIndirect +#cgo nocallback wgpuRenderBundleEncoderDrawIndexedIndirect +#cgo noescape wgpuRenderBundleEncoderDrawIndirect +#cgo nocallback wgpuRenderBundleEncoderDrawIndirect +#cgo noescape wgpuRenderBundleEncoderFinish +#cgo nocallback wgpuRenderBundleEncoderFinish +#cgo noescape wgpuRenderBundleEncoderInsertDebugMarker +#cgo nocallback wgpuRenderBundleEncoderInsertDebugMarker +#cgo noescape wgpuRenderBundleEncoderPopDebugGroup +#cgo nocallback wgpuRenderBundleEncoderPopDebugGroup +#cgo noescape wgpuRenderBundleEncoderPushDebugGroup +#cgo nocallback wgpuRenderBundleEncoderPushDebugGroup +#cgo noescape wgpuRenderBundleEncoderRelease +#cgo nocallback wgpuRenderBundleEncoderRelease +#cgo noescape wgpuRenderBundleEncoderSetBindGroup +#cgo nocallback wgpuRenderBundleEncoderSetBindGroup +#cgo noescape wgpuRenderBundleEncoderSetIndexBuffer +#cgo nocallback wgpuRenderBundleEncoderSetIndexBuffer +#cgo noescape wgpuRenderBundleEncoderSetPipeline +#cgo nocallback wgpuRenderBundleEncoderSetPipeline +#cgo noescape wgpuRenderBundleEncoderSetVertexBuffer +#cgo nocallback wgpuRenderBundleEncoderSetVertexBuffer +#cgo noescape wgpuRenderBundleRelease +#cgo nocallback wgpuRenderBundleRelease +#cgo noescape wgpuRenderPassEncoderBeginOcclusionQuery +#cgo nocallback wgpuRenderPassEncoderBeginOcclusionQuery +#cgo noescape wgpuRenderPassEncoderBeginPipelineStatisticsQuery +#cgo nocallback wgpuRenderPassEncoderBeginPipelineStatisticsQuery +#cgo noescape wgpuRenderPassEncoderDraw +#cgo nocallback wgpuRenderPassEncoderDraw +#cgo noescape wgpuRenderPassEncoderDrawIndexed +#cgo nocallback wgpuRenderPassEncoderDrawIndexed +#cgo noescape wgpuRenderPassEncoderDrawIndexedIndirect +#cgo nocallback wgpuRenderPassEncoderDrawIndexedIndirect +#cgo noescape wgpuRenderPassEncoderDrawIndirect +#cgo nocallback wgpuRenderPassEncoderDrawIndirect +#cgo noescape wgpuRenderPassEncoderEndOcclusionQuery +#cgo nocallback wgpuRenderPassEncoderEndOcclusionQuery +#cgo noescape wgpuRenderPassEncoderEndPipelineStatisticsQuery +#cgo nocallback wgpuRenderPassEncoderEndPipelineStatisticsQuery +#cgo noescape wgpuRenderPassEncoderExecuteBundles +#cgo nocallback wgpuRenderPassEncoderExecuteBundles +#cgo noescape wgpuRenderPassEncoderInsertDebugMarker +#cgo nocallback wgpuRenderPassEncoderInsertDebugMarker +#cgo noescape wgpuRenderPassEncoderMultiDrawIndexedIndirect +#cgo nocallback wgpuRenderPassEncoderMultiDrawIndexedIndirect +#cgo noescape wgpuRenderPassEncoderMultiDrawIndexedIndirectCount +#cgo nocallback wgpuRenderPassEncoderMultiDrawIndexedIndirectCount +#cgo noescape wgpuRenderPassEncoderMultiDrawIndirect +#cgo nocallback wgpuRenderPassEncoderMultiDrawIndirect +#cgo noescape wgpuRenderPassEncoderMultiDrawIndirectCount +#cgo nocallback wgpuRenderPassEncoderMultiDrawIndirectCount +#cgo noescape wgpuRenderPassEncoderPopDebugGroup +#cgo nocallback wgpuRenderPassEncoderPopDebugGroup +#cgo noescape wgpuRenderPassEncoderPushDebugGroup +#cgo nocallback wgpuRenderPassEncoderPushDebugGroup +#cgo noescape wgpuRenderPassEncoderRelease +#cgo nocallback wgpuRenderPassEncoderRelease +#cgo noescape wgpuRenderPassEncoderSetBindGroup +#cgo nocallback wgpuRenderPassEncoderSetBindGroup +#cgo noescape wgpuRenderPassEncoderSetBlendConstant +#cgo nocallback wgpuRenderPassEncoderSetBlendConstant +#cgo noescape wgpuRenderPassEncoderSetImmediates +#cgo nocallback wgpuRenderPassEncoderSetImmediates +#cgo noescape wgpuRenderPassEncoderSetIndexBuffer +#cgo nocallback wgpuRenderPassEncoderSetIndexBuffer +#cgo noescape wgpuRenderPassEncoderSetPipeline +#cgo nocallback wgpuRenderPassEncoderSetPipeline +#cgo noescape wgpuRenderPassEncoderSetScissorRect +#cgo nocallback wgpuRenderPassEncoderSetScissorRect +#cgo noescape wgpuRenderPassEncoderSetStencilReference +#cgo nocallback wgpuRenderPassEncoderSetStencilReference +#cgo noescape wgpuRenderPassEncoderSetVertexBuffer +#cgo nocallback wgpuRenderPassEncoderSetVertexBuffer +#cgo noescape wgpuRenderPassEncoderSetViewport +#cgo nocallback wgpuRenderPassEncoderSetViewport +#cgo noescape wgpuRenderPipelineGetBindGroupLayout +#cgo nocallback wgpuRenderPipelineGetBindGroupLayout +#cgo noescape wgpuRenderPipelineRelease +#cgo nocallback wgpuRenderPipelineRelease +#cgo noescape wgpuSamplerRelease +#cgo nocallback wgpuSamplerRelease +#cgo noescape wgpuSetLogCallback +#cgo nocallback wgpuSetLogCallback +#cgo noescape wgpuSetLogLevel +#cgo nocallback wgpuSetLogLevel +#cgo noescape wgpuShaderModuleRelease +#cgo nocallback wgpuShaderModuleRelease +#cgo noescape wgpuSurfaceConfigure +#cgo nocallback wgpuSurfaceConfigure +#cgo noescape wgpuSurfaceGetCapabilities +#cgo nocallback wgpuSurfaceGetCapabilities +#cgo noescape wgpuSurfacePresent +#cgo nocallback wgpuSurfacePresent +#cgo noescape wgpuSurfaceRelease +#cgo nocallback wgpuSurfaceRelease +#cgo noescape wgpuTextureDestroy +#cgo nocallback wgpuTextureDestroy +#cgo noescape wgpuTextureGetDepthOrArrayLayers +#cgo nocallback wgpuTextureGetDepthOrArrayLayers +#cgo noescape wgpuTextureGetDimension +#cgo nocallback wgpuTextureGetDimension +#cgo noescape wgpuTextureGetFormat +#cgo nocallback wgpuTextureGetFormat +#cgo noescape wgpuTextureGetHeight +#cgo nocallback wgpuTextureGetHeight +#cgo noescape wgpuTextureGetMipLevelCount +#cgo nocallback wgpuTextureGetMipLevelCount +#cgo noescape wgpuTextureGetSampleCount +#cgo nocallback wgpuTextureGetSampleCount +#cgo noescape wgpuTextureGetUsage +#cgo nocallback wgpuTextureGetUsage +#cgo noescape wgpuTextureGetWidth +#cgo nocallback wgpuTextureGetWidth +#cgo noescape wgpuTextureRelease +#cgo nocallback wgpuTextureRelease +#cgo noescape wgpuTextureViewRelease +#cgo nocallback wgpuTextureViewRelease +*/ +import "C" diff --git a/wgpu/command_encoder.go b/wgpu/command_encoder.go index 97ac80f..9ab4b40 100644 --- a/wgpu/command_encoder.go +++ b/wgpu/command_encoder.go @@ -3,147 +3,7 @@ package wgpu /* - -#include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); - -static inline void gowebgpu_command_encoder_clear_buffer(WGPUCommandEncoder commandEncoder, WGPUBuffer buffer, uint64_t offset, uint64_t size, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderClearBuffer(commandEncoder, buffer, offset, size); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_copy_buffer_to_buffer(WGPUCommandEncoder commandEncoder, WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, uint64_t destinationOffset, uint64_t size, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderCopyBufferToBuffer(commandEncoder, source, sourceOffset, destination, destinationOffset, size); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_copy_buffer_to_texture(WGPUCommandEncoder commandEncoder, WGPUTexelCopyBufferInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderCopyBufferToTexture(commandEncoder, source, destination, copySize); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_copy_texture_to_buffer(WGPUCommandEncoder commandEncoder, WGPUTexelCopyTextureInfo const * source, WGPUTexelCopyBufferInfo const * destination, WGPUExtent3D const * copySize, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderCopyTextureToBuffer(commandEncoder, source, destination, copySize); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_copy_texture_to_texture(WGPUCommandEncoder commandEncoder, WGPUTexelCopyTextureInfo const * source, WGPUTexelCopyTextureInfo const * destination, WGPUExtent3D const * copySize, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderCopyTextureToTexture(commandEncoder, source, destination, copySize); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline WGPUCommandBuffer gowebgpu_command_encoder_finish(WGPUCommandEncoder commandEncoder, WGPUCommandBufferDescriptor const * descriptor, WGPUDevice device, void * error_userdata) { - WGPUCommandBuffer ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuCommandEncoderFinish(commandEncoder, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline void gowebgpu_command_encoder_insert_debug_marker(WGPUCommandEncoder commandEncoder, char const * markerLabel, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderInsertDebugMarker(commandEncoder, (WGPUStringView) {markerLabel, WGPU_STRLEN}); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_pop_debug_group(WGPUCommandEncoder commandEncoder, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderPopDebugGroup(commandEncoder); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_push_debug_group(WGPUCommandEncoder commandEncoder, char const * groupLabel, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderPushDebugGroup(commandEncoder, (WGPUStringView) {groupLabel, WGPU_STRLEN}); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_resolve_query_set(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, WGPUBuffer destination, uint64_t destinationOffset, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderResolveQuerySet(commandEncoder, querySet, firstQuery, queryCount, destination, destinationOffset); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_command_encoder_write_timestamp(WGPUCommandEncoder commandEncoder, WGPUQuerySet querySet, uint32_t queryIndex, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuCommandEncoderWriteTimestamp(commandEncoder, querySet, queryIndex); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - +#include "wgpu_go_wrappers.h" */ import "C" import ( @@ -181,7 +41,7 @@ func (p *CommandEncoder) BeginComputePass(descriptor *ComputePassDescriptor) *Co return releaseOnGC(&ComputePassEncoder{device: p.device, ref: ref}) } -func (p *CommandEncoder) BeginRenderPass(descriptor *RenderPassDescriptor) *RenderPassEncoder { +func (p *CommandEncoder) TryBeginRenderPass(descriptor *RenderPassDescriptor) (*RenderPassEncoder, error) { var desc *C.WGPURenderPassDescriptor = allocWGPURenderPassDescriptor.GetZeroed() defer allocWGPURenderPassDescriptor.Put(desc) @@ -247,48 +107,50 @@ func (p *CommandEncoder) BeginRenderPass(descriptor *RenderPassDescriptor) *Rend } } - ref := C.wgpuCommandEncoderBeginRenderPass(p.ref, desc) - if ref == nil { - err := errors.New("failed to acquire RenderPassEncoder") - panic(wrap(err, "")) + errh := acquireErrorCallback() + defer errh.Done() + + ref := C.go_wgpuCommandEncoderBeginRenderPass(p.device, errh.ToPointer(), p.ref, desc) + if err := errh.ToError(); err != nil { + return nil, err } C.wgpuDeviceAddRef(p.device) - return releaseOnGC(&RenderPassEncoder{device: p.device, ref: ref}) + return releaseOnGC(&RenderPassEncoder{device: p.device, ref: ref}), nil } func (p *CommandEncoder) TryClearBuffer(buffer *Buffer, offset uint64, size uint64) error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_clear_buffer( + C.go_wgpuCommandEncoderClearBuffer( + p.device, + errh.errStr, p.ref, buffer.ref, C.uint64_t(offset), C.uint64_t(size), - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryCopyBufferToBuffer(source *Buffer, sourceOffset uint64, destination *Buffer, destinationOffset uint64, size uint64) error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_copy_buffer_to_buffer( + C.go_wgpuCommandEncoderCopyBufferToBuffer( + p.device, + errh.ToPointer(), p.ref, source.ref, C.uint64_t(sourceOffset), destination.ref, C.uint64_t(destinationOffset), C.uint64_t(size), - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryCopyBufferToTexture(source *TexelCopyBufferInfo, destination *TexelCopyTextureInfo, copySize *Extent3D) error { @@ -332,16 +194,16 @@ func (p *CommandEncoder) TryCopyBufferToTexture(source *TexelCopyBufferInfo, des errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_copy_buffer_to_texture( + C.go_wgpuCommandEncoderCopyBufferToTexture( + p.device, + errh.ToPointer(), p.ref, &src, &dst, &cpySize, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryCopyTextureToBuffer(source *TexelCopyTextureInfo, destination *TexelCopyBufferInfo, copySize *Extent3D) error { @@ -385,16 +247,16 @@ func (p *CommandEncoder) TryCopyTextureToBuffer(source *TexelCopyTextureInfo, de errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_copy_texture_to_buffer( + C.go_wgpuCommandEncoderCopyTextureToBuffer( + p.device, + errh.ToPointer(), p.ref, &src, &dst, &cpySize, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryCopyTextureToTexture(source *TexelCopyTextureInfo, destination *TexelCopyTextureInfo, copySize *Extent3D) error { @@ -442,16 +304,16 @@ func (p *CommandEncoder) TryCopyTextureToTexture(source *TexelCopyTextureInfo, d errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_copy_texture_to_texture( + C.go_wgpuCommandEncoderCopyTextureToTexture( + p.device, + errh.ToPointer(), p.ref, &src, &dst, &cpySize, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryFinish(descriptor *CommandBufferDescriptor) (*CommandBuffer, error) { @@ -469,81 +331,82 @@ func (p *CommandEncoder) TryFinish(descriptor *CommandBufferDescriptor) (*Comman errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_command_encoder_finish( + ref := C.go_wgpuCommandEncoderFinish( + p.device, + errh.errStr, p.ref, desc, - p.device, - errh.ToPointer(), ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuCommandBufferRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&CommandBuffer{ref: ref}), nil } func (p *CommandEncoder) TryInsertDebugMarker(markerLabel string) error { - markerLabelStr := C.CString(markerLabel) - defer C.free(unsafe.Pointer(markerLabelStr)) - errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_insert_debug_marker( - p.ref, - markerLabelStr, + C.go_wgpuCommandEncoderInsertDebugMarker( p.device, errh.ToPointer(), + p.ref, + toStringView(markerLabel), ) - return errh.err + return errh.ToError() +} + +func toStringView(str string) C.WGPUStringView { + return C.WGPUStringView{ + data: (*C.char)(unsafe.Pointer(unsafe.StringData(str))), + length: C.size_t(len(str)), + } } func (p *CommandEncoder) TryPopDebugGroup() error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_pop_debug_group( - p.ref, + C.go_wgpuCommandEncoderPopDebugGroup( p.device, errh.ToPointer(), + p.ref, ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryPushDebugGroup(groupLabel string) error { - groupLabelStr := C.CString(groupLabel) - defer C.free(unsafe.Pointer(groupLabelStr)) - errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_push_debug_group( - p.ref, - groupLabelStr, + C.go_wgpuCommandEncoderPushDebugGroup( p.device, errh.ToPointer(), + p.ref, + toStringView(groupLabel), ) - return errh.err + return errh.ToError() } func (p *CommandEncoder) TryResolveQuerySet(querySet *QuerySet, firstQuery uint32, queryCount uint32, destination *Buffer, destinationOffset uint64) error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_command_encoder_resolve_query_set( + C.go_wgpuCommandEncoderResolveQuerySet( + p.device, + errh.ToPointer(), p.ref, querySet.ref, C.uint32_t(firstQuery), C.uint32_t(queryCount), destination.ref, C.uint64_t(destinationOffset), - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } diff --git a/wgpu/common.go b/wgpu/common.go index bfb1839..c44a05f 100644 --- a/wgpu/common.go +++ b/wgpu/common.go @@ -4,9 +4,10 @@ import ( "strconv" ) -//go:generate sh -c "cd ../cmd/enums && go run . -i ../../wgpu/lib/linux/arm64/ -o ../../wgpu/gen_enums.go -pkg wgpu" +//go:generate sh -ec "cd ../cmd/enums && go run . -i ../../wgpu/lib/linux/arm64/ -o ../../wgpu/gen_enums.go -pkg wgpu" //go:generate go run ../cmd/refcount Adapter BindGroup BindGroupLayout CommandBuffer ComputePipeline Device Instance PipelineLayout QuerySet RenderBundle RenderBundleEncoder RenderPipeline Sampler ShaderModule TextureView +Queue +Buffer +CommandEncoder +Texture +ComputePassEncoder +RenderPassEncoder +Surface -//go:generate sh -c "cd .. && go run ./cmd/wrappers" +//go:generate sh -ec "cd .. && go run ./cmd/wrappers" +//go:generate sh -ec "cd .. && go run ./cmd/cgohints -i wgpu" // This file contains common types and constants diff --git a/wgpu/compute_pass_encoder.go b/wgpu/compute_pass_encoder.go index 6ca1415..35f0cfb 100644 --- a/wgpu/compute_pass_encoder.go +++ b/wgpu/compute_pass_encoder.go @@ -2,26 +2,7 @@ package wgpu -/* - -#include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); - -static inline void gowebgpu_compute_pass_encoder_end(WGPUComputePassEncoder computePassEncoder, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuComputePassEncoderEnd(computePassEncoder); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -*/ +// #include "wgpu_go_wrappers.h" import "C" import ( "unsafe" @@ -43,8 +24,8 @@ func (p *ComputePassEncoder) TryEnd() error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_compute_pass_encoder_end(p.ref, p.device, errh.ToPointer()) - return errh.err + C.go_wgpuComputePassEncoderEnd(p.device, errh.ToPointer(), p.ref) + return errh.ToError() } func (p *ComputePassEncoder) EndPipelineStatisticsQuery() { @@ -52,13 +33,7 @@ func (p *ComputePassEncoder) EndPipelineStatisticsQuery() { } func (p *ComputePassEncoder) InsertDebugMarker(markerLabel string) { - markerLabelStr := C.CString(markerLabel) - defer C.free(unsafe.Pointer(markerLabelStr)) - - C.wgpuComputePassEncoderInsertDebugMarker(p.ref, C.WGPUStringView{ - data: markerLabelStr, - length: C.WGPU_STRLEN, - }) + C.wgpuComputePassEncoderInsertDebugMarker(p.ref, toStringView(markerLabel)) } func (p *ComputePassEncoder) PopDebugGroup() { @@ -66,13 +41,7 @@ func (p *ComputePassEncoder) PopDebugGroup() { } func (p *ComputePassEncoder) PushDebugGroup(groupLabel string) { - groupLabelStr := C.CString(groupLabel) - defer C.free(unsafe.Pointer(groupLabelStr)) - - C.wgpuComputePassEncoderPushDebugGroup(p.ref, C.WGPUStringView{ - data: groupLabelStr, - length: C.WGPU_STRLEN, - }) + C.wgpuComputePassEncoderPushDebugGroup(p.ref, toStringView(groupLabel)) } func (p *ComputePassEncoder) SetBindGroup(groupIndex uint32, group *BindGroup, dynamicOffsets []uint32) { diff --git a/wgpu/device.go b/wgpu/device.go index b2f361f..32b3040 100644 --- a/wgpu/device.go +++ b/wgpu/device.go @@ -3,177 +3,7 @@ package wgpu /* - -#include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); - -static inline WGPUBindGroup gowebgpu_device_create_bind_group(WGPUDevice device, WGPUBindGroupDescriptor const * descriptor, void * error_userdata) { - WGPUBindGroup ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateBindGroup(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUBindGroupLayout gowebgpu_device_create_bind_group_layout(WGPUDevice device, WGPUBindGroupLayoutDescriptor const * descriptor, void * error_userdata) { - WGPUBindGroupLayout ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateBindGroupLayout(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUBuffer gowebgpu_device_create_buffer(WGPUDevice device, WGPUBufferDescriptor const * descriptor, void * error_userdata) { - WGPUBuffer ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateBuffer(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUCommandEncoder gowebgpu_device_create_command_encoder(WGPUDevice device, WGPUCommandEncoderDescriptor const * descriptor, void * error_userdata) { - WGPUCommandEncoder ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateCommandEncoder(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUComputePipeline gowebgpu_device_create_compute_pipeline(WGPUDevice device, WGPUComputePipelineDescriptor const * descriptor, void * error_userdata) { - WGPUComputePipeline ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateComputePipeline(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUPipelineLayout gowebgpu_device_create_pipeline_layout(WGPUDevice device, WGPUPipelineLayoutDescriptor const * descriptor, void * error_userdata) { - WGPUPipelineLayout ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreatePipelineLayout(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUQuerySet gowebgpu_device_create_query_set(WGPUDevice device, WGPUQuerySetDescriptor const * descriptor, void * error_userdata) { - WGPUQuerySet ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateQuerySet(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPURenderPipeline gowebgpu_device_create_render_pipeline(WGPUDevice device, WGPURenderPipelineDescriptor const * descriptor, void * error_userdata) { - WGPURenderPipeline ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateRenderPipeline(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUSampler gowebgpu_device_create_sampler(WGPUDevice device, WGPUSamplerDescriptor const * descriptor, void * error_userdata) { - WGPUSampler ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateSampler(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUShaderModule gowebgpu_device_create_shader_module(WGPUDevice device, WGPUShaderModuleDescriptor const * descriptor, void * error_userdata) { - WGPUShaderModule ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateShaderModule(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - -static inline WGPUTexture gowebgpu_device_create_texture(WGPUDevice device, WGPUTextureDescriptor const * descriptor, void * error_userdata) { - WGPUTexture ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuDeviceCreateTexture(device, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - +#include "wgpu_go_wrappers.h" */ import "C" import ( @@ -232,14 +62,15 @@ func (g *Device) TryCreateBindGroup(descriptor *BindGroupDescriptor) (*BindGroup errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_bind_group( + ref := C.go_wgpuDeviceCreateBindGroup( g.ref, - desc, errh.ToPointer(), + g.ref, + desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuBindGroupRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&BindGroup{ref: ref}), nil @@ -333,14 +164,15 @@ func (g *Device) TryCreateBindGroupLayout(descriptor *BindGroupLayoutDescriptor) errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_bind_group_layout( + ref := C.go_wgpuDeviceCreateBindGroupLayout( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuBindGroupLayoutRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&BindGroupLayout{ref: ref}), nil @@ -366,14 +198,15 @@ func (g *Device) TryCreateBuffer(descriptor *BufferDescriptor) (*Buffer, error) errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_buffer( + ref := C.go_wgpuDeviceCreateBuffer( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuBufferRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&Buffer{device: g.addRef(), ref: ref}), nil @@ -398,14 +231,15 @@ func (g *Device) TryCreateCommandEncoder(descriptor *CommandEncoderDescriptor) ( errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_command_encoder( + ref := C.go_wgpuDeviceCreateCommandEncoder( g.ref, - desc, errh.ToPointer(), + g.ref, + desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuCommandEncoderRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&CommandEncoder{device: g.addRef(), ref: ref}), nil @@ -455,14 +289,15 @@ func (g *Device) TryCreateComputePipeline(descriptor *ComputePipelineDescriptor) errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_compute_pipeline( + ref := C.go_wgpuDeviceCreateComputePipeline( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuComputePipelineRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&ComputePipeline{ref: ref}), nil @@ -527,14 +362,15 @@ func (g *Device) TryCreatePipelineLayout(descriptor *PipelineLayoutDescriptor) ( errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_pipeline_layout( + ref := C.go_wgpuDeviceCreatePipelineLayout( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuPipelineLayoutRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&PipelineLayout{ref: ref}), nil @@ -559,14 +395,15 @@ func (g *Device) TryCreateQuerySet(descriptor *QuerySetDescriptor) (*QuerySet, e errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_query_set( + ref := C.go_wgpuDeviceCreateQuerySet( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuQuerySetRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&QuerySet{ref: ref}), nil @@ -876,14 +713,15 @@ func (g *Device) TryCreateRenderPipeline(descriptor *RenderPipelineDescriptor) ( errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_render_pipeline( + ref := C.go_wgpuDeviceCreateRenderPipeline( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuRenderPipelineRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&RenderPipeline{ref: ref}), nil @@ -918,14 +756,15 @@ func (g *Device) TryCreateSampler(descriptor *SamplerDescriptor) (*Sampler, erro errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_sampler( + ref := C.go_wgpuDeviceCreateSampler( g.ref, - desc, errh.ToPointer(), + g.ref, + desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuSamplerRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&Sampler{ref: ref}), nil @@ -1052,14 +891,15 @@ func (g *Device) TryCreateShaderModule(descriptor *ShaderModuleDescriptor) (*Sha errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_shader_module( + ref := C.go_wgpuDeviceCreateShaderModule( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuShaderModuleRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&ShaderModule{ref: ref}), nil @@ -1094,14 +934,15 @@ func (g *Device) TryCreateTexture(descriptor *TextureDescriptor) (*Texture, erro errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_device_create_texture( + ref := C.go_wgpuDeviceCreateTexture( g.ref, - &desc, errh.ToPointer(), + g.ref, + &desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuTextureRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&Texture{device: g.addRef(), ref: ref}), nil diff --git a/wgpu/error-callback.go b/wgpu/error-callback.go index a1688e5..8601f36 100644 --- a/wgpu/error-callback.go +++ b/wgpu/error-callback.go @@ -7,6 +7,9 @@ import ( "strings" ) +// #include +import "C" + /* #include */ @@ -17,9 +20,8 @@ import ( ) type errorCallback struct { - handle callers [1]uintptr - err error + errStr *C.char } func acquireErrorCallback() *errorCallback { @@ -34,19 +36,24 @@ func acquireErrorCallback() *errorCallback { // get the location of the caller for error reporting runtime.Callers(2, cb.callers[:]) - if cb.handle == (handle{}) { - // create a stable handle we can use to identify the callback - // in c-land. - cb.handle = newHandle(cb) + if cb.errStr == nil { + cb.errStr = (*C.char)(C.malloc(16 * 1024)) - // if the error callback gets cleaned up, we need to release - // the c-handle too - runtime.AddCleanup(cb, handle.Delete, cb.handle) + // if this instance gets cleaned up, we need to release + // the error memory too + runtime.AddCleanup(cb, cfree, cb.errStr) } + // clear string by setting the first byte to zero + *cb.errStr = 0 + return cb } +func cfree(ch *C.char) { + C.free(unsafe.Pointer(ch)) +} + func (v *errorCallback) Done() { if v.callers[0] == 0 { // someone else called done on this instance. @@ -61,7 +68,15 @@ func (v *errorCallback) Done() { allocErrorCallbackValue.Put(v) } -func (v *errorCallback) Handle(_ ErrorType, message string) { +func (v *errorCallback) ToPointer() *C.char { + return v.errStr +} + +func (v *errorCallback) ToError() error { + if *v.errStr == 0 { + return nil + } + frames := runtime.CallersFrames(v.callers[:]) frame, _ := frames.Next() @@ -72,14 +87,15 @@ func (v *errorCallback) Handle(_ ErrorType, message string) { context = context[idx+1:] } - v.err = Error{Context: context, Wrapped: errors.New(message)} + // convert the message to a string + message := C.GoString(v.errStr) + + return Error{ + Context: context, + Wrapped: errors.New(message), + } } //export gowebgpu_error_callback_go func gowebgpu_error_callback_go(_type C.WGPUErrorType, message C.WGPUStringView, userdata unsafe.Pointer) { - handle := lookupHandle(userdata) - ec, ok := handle.Value().(*errorCallback) - if ok { - ec.Handle(ErrorType(_type), C.GoStringN(message.data, C.int(message.length))) - } } diff --git a/wgpu/gen_wrappers.go b/wgpu/gen_wrappers.go index 01b66b9..609e41c 100644 --- a/wgpu/gen_wrappers.go +++ b/wgpu/gen_wrappers.go @@ -7,6 +7,11 @@ func (p *Buffer) MapAsync(mode MapMode, offset uint64, size uint64, callback Buf } func (p *Buffer) Unmap() { err := p.TryUnmap(); panicIf(err, "Buffer.Unmap failed") } +func (p *CommandEncoder) BeginRenderPass(descriptor *RenderPassDescriptor) *RenderPassEncoder { + r0, err := p.TryBeginRenderPass(descriptor) + panicIf(err, "CommandEncoder.BeginRenderPass failed") + return r0 +} func (p *CommandEncoder) ClearBuffer(buffer *Buffer, offset uint64, size uint64) { err := p.TryClearBuffer(buffer, offset, size) @@ -59,7 +64,6 @@ func (p *CommandEncoder) ResolveQuerySet(querySet *QuerySet, firstQuery uint32, panicIf(err, "CommandEncoder.ResolveQuerySet failed") } func (p *ComputePassEncoder) End() { err := p.TryEnd(); panicIf(err, "ComputePassEncoder.End failed") } - func (g *Device) CreateBindGroup(descriptor *BindGroupDescriptor) *BindGroup { r0, err := g.TryCreateBindGroup(descriptor) panicIf(err, "Device.CreateBindGroup failed") diff --git a/wgpu/queue.go b/wgpu/queue.go index 939301a..d80cc2c 100644 --- a/wgpu/queue.go +++ b/wgpu/queue.go @@ -3,37 +3,8 @@ package wgpu /* - -#include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); +#include "wgpu_go_wrappers.h" extern void gowebgpu_queue_work_done_callback_c(WGPUQueueWorkDoneStatus status, void * userdata); - -static inline void gowebgpu_queue_write_buffer(WGPUQueue queue, WGPUBuffer buffer, uint64_t bufferOffset, void const * data, size_t size, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuQueueWriteBuffer(queue, buffer, bufferOffset, data, size); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - -static inline void gowebgpu_queue_write_texture(WGPUQueue queue, WGPUTexelCopyTextureInfo const * destination, void const * data, size_t dataSize, WGPUTexelCopyBufferLayout const * dataLayout, WGPUExtent3D const * writeSize, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuQueueWriteTexture(queue, destination, data, dataSize, dataLayout, writeSize); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - */ import "C" import ( @@ -89,30 +60,30 @@ func (p *Queue) TryWriteBuffer(buffer *Buffer, bufferOffset uint64, data []byte) size := len(data) if size == 0 { - C.gowebgpu_queue_write_buffer( + C.go_wgpuQueueWriteBuffer( + p.device, + errh.ToPointer(), p.ref, buffer.ref, C.uint64_t(bufferOffset), nil, 0, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } - C.gowebgpu_queue_write_buffer( + C.go_wgpuQueueWriteBuffer( + p.device, + errh.ToPointer(), p.ref, buffer.ref, C.uint64_t(bufferOffset), unsafe.Pointer(&data[0]), C.size_t(size), - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } func (p *Queue) TryWriteTexture(destination *TexelCopyTextureInfo, data []byte, dataLayout *TexelCopyBufferLayout, writeSize *Extent3D) error { @@ -155,30 +126,30 @@ func (p *Queue) TryWriteTexture(destination *TexelCopyTextureInfo, data []byte, size := len(data) if size == 0 { - C.gowebgpu_queue_write_texture( + C.go_wgpuQueueWriteTexture( + p.device, + errh.ToPointer(), p.ref, &dst, nil, 0, &layout, &writeExtent, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } - C.gowebgpu_queue_write_texture( + C.go_wgpuQueueWriteTexture( + p.device, + errh.ToPointer(), p.ref, &dst, unsafe.Pointer(&data[0]), C.size_t(size), &layout, &writeExtent, - p.device, - errh.ToPointer(), ) - return errh.err + return errh.ToError() } diff --git a/wgpu/render_pass_encoder.go b/wgpu/render_pass_encoder.go index 107f3be..a410d41 100644 --- a/wgpu/render_pass_encoder.go +++ b/wgpu/render_pass_encoder.go @@ -3,24 +3,7 @@ package wgpu /* - -#include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); - -static inline void gowebgpu_render_pass_encoder_end(WGPURenderPassEncoder renderPassEncoder, WGPUDevice device, void * error_userdata) { - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuRenderPassEncoderEnd(renderPassEncoder); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); -} - +#include "wgpu_go_wrappers.h" */ import "C" import ( @@ -68,16 +51,16 @@ func (p *RenderPassEncoder) TryEnd() error { errh := acquireErrorCallback() defer errh.Done() - C.gowebgpu_render_pass_encoder_end( - p.ref, + C.go_wgpuRenderPassEncoderEnd( p.device, errh.ToPointer(), + p.ref, ) // also release the render pass at this point p.Release() - return errh.err + return errh.ToError() } func (p *RenderPassEncoder) EndOcclusionQuery() { diff --git a/wgpu/surface.go b/wgpu/surface.go index 52f3a54..d3cd101 100644 --- a/wgpu/surface.go +++ b/wgpu/surface.go @@ -3,27 +3,8 @@ package wgpu /* - #include -#include - -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); - -static inline WGPUSurfaceTexture gowebgpu_surface_get_current_texture(WGPUSurface surface, WGPUDevice device, void * error_userdata) { - WGPUSurfaceTexture ref; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - wgpuSurfaceGetCurrentTexture(surface, &ref); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} - +#include "wgpu_go_wrappers.h" */ import "C" import ( @@ -133,17 +114,19 @@ func (g *Surface) TryGetCurrentTexture() (SurfaceTexture, error) { errh := acquireErrorCallback() defer errh.Done() - surfaceTexture := C.gowebgpu_surface_get_current_texture( - g.ref, + var surfaceTexture C.WGPUSurfaceTexture + C.go_wgpuSurfaceGetCurrentTexture( g.device, errh.ToPointer(), + g.ref, + &surfaceTexture, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { if surfaceTexture.texture != nil { C.wgpuTextureRelease(surfaceTexture.texture) } - return SurfaceTexture{}, errh.err + return SurfaceTexture{}, err } status := SurfaceGetCurrentTextureStatus(surfaceTexture.status) diff --git a/wgpu/texture.go b/wgpu/texture.go index 434369b..74964c9 100644 --- a/wgpu/texture.go +++ b/wgpu/texture.go @@ -5,30 +5,16 @@ package wgpu /* #include -#include +#include "wgpu_go_wrappers.h" -extern void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2); +#cgo noescape wgpuTextureViewRelease +#cgo nocallback wgpuTextureViewRelease -static inline WGPUTextureView gowebgpu_texture_create_view(WGPUTexture texture, WGPUTextureViewDescriptor const * descriptor, WGPUDevice device, void * error_userdata) { - WGPUTextureView ref = NULL; - wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation); - ref = wgpuTextureCreateView(texture, descriptor); - - WGPUPopErrorScopeCallbackInfo const err_cb = { - .callback = gowebgpu_error_callback_c, - .userdata1 = error_userdata, - }; - - wgpuDevicePopErrorScope(device, err_cb); - - return ref; -} +#cgo noescape go_wgpuTextureCreateView +#cgo nocallback go_wgpuTextureCreateView */ import "C" -import ( - "unsafe" -) func (g *Texture) TryCreateView(descriptor *TextureViewDescriptor) (*TextureView, error) { var desc *C.WGPUTextureViewDescriptor @@ -45,26 +31,22 @@ func (g *Texture) TryCreateView(descriptor *TextureViewDescriptor) (*TextureView } if descriptor.Label != "" { - label := C.CString(descriptor.Label) - defer C.free(unsafe.Pointer(label)) - - desc.label.data = label - desc.label.length = C.WGPU_STRLEN + desc.label = toStringView(descriptor.Label) } } errh := acquireErrorCallback() defer errh.Done() - ref := C.gowebgpu_texture_create_view( - g.ref, - desc, + ref := C.go_wgpuTextureCreateView( g.device, errh.ToPointer(), + g.ref, + desc, ) - if errh.err != nil { + if err := errh.ToError(); err != nil { C.wgpuTextureViewRelease(ref) - return nil, errh.err + return nil, err } return releaseOnGC(&TextureView{ref: ref}), nil diff --git a/wgpu/wgpu_c_cb.go b/wgpu/wgpu_c_cb.go index fe4e6b8..2a97ea0 100644 --- a/wgpu/wgpu_c_cb.go +++ b/wgpu/wgpu_c_cb.go @@ -26,15 +26,6 @@ void gowebgpu_device_lost_callback_c(WGPUDeviceLostReason reason, char const * m gowebgpu_device_lost_callback_go(reason, message, userdata); } -void gowebgpu_error_callback_c(enum WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message, void * userdata, void * userdata2) { - if (type == WGPUErrorType_NoError) { - return; - } - - extern void gowebgpu_error_callback_go(WGPUErrorType type, WGPUStringView message, void * userdata); - gowebgpu_error_callback_go(type, message, userdata); -} - void gowebgpu_queue_work_done_callback_c(WGPUQueueWorkDoneStatus status, void * userdata) { extern void gowebgpu_queue_work_done_callback_go(WGPUQueueWorkDoneStatus status, void * userdata); gowebgpu_queue_work_done_callback_go(status, userdata); diff --git a/wgpu/wgpu_go_wrappers.h b/wgpu/wgpu_go_wrappers.h new file mode 100644 index 0000000..af1656c --- /dev/null +++ b/wgpu/wgpu_go_wrappers.h @@ -0,0 +1,2864 @@ +// Code generated by cmd/refcount: DO NOT EDIT. + +#pragma once + +#include +#include +#include + +static inline void webgpu_error_callback(WGPUPopErrorScopeStatus status, + WGPUErrorType type, + WGPUStringView message, + WGPU_NULLABLE void *userdata1, + WGPU_NULLABLE void *userdata2) { + char *err = (char *)userdata1; + if (type == WGPUErrorType_NoError) { + return; + } + + strncpy(err, message.data, 1024 - 1); +} + +static inline WGPUInstance +go_wgpuCreateInstance(WGPUDevice _dev, char *err, + WGPU_NULLABLE WGPUInstanceDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUInstance ret = wgpuCreateInstance(descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void +go_wgpuGetInstanceFeatures(WGPUDevice _dev, char *err, + WGPUSupportedInstanceFeatures *features) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuGetInstanceFeatures(features); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus go_wgpuGetInstanceLimits(WGPUDevice _dev, char *err, + WGPUInstanceLimits *limits) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuGetInstanceLimits(limits); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUBool +go_wgpuHasInstanceFeature(WGPUDevice _dev, char *err, + WGPUInstanceFeatureName feature) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBool ret = wgpuHasInstanceFeature(feature); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUProc go_wgpuGetProcAddress(WGPUDevice _dev, char *err, + WGPUStringView procName) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUProc ret = wgpuGetProcAddress(procName); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuAdapterGetFeatures(WGPUDevice _dev, char *err, + WGPUAdapter adapter, + WGPUSupportedFeatures *features) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuAdapterGetFeatures(adapter, features); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus go_wgpuAdapterGetInfo(WGPUDevice _dev, char *err, + WGPUAdapter adapter, + WGPUAdapterInfo *info) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuAdapterGetInfo(adapter, info); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUStatus go_wgpuAdapterGetLimits(WGPUDevice _dev, char *err, + WGPUAdapter adapter, + WGPULimits *limits) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuAdapterGetLimits(adapter, limits); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUBool go_wgpuAdapterHasFeature(WGPUDevice _dev, char *err, + WGPUAdapter adapter, + WGPUFeatureName feature) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBool ret = wgpuAdapterHasFeature(adapter, feature); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUFuture go_wgpuAdapterRequestDevice( + WGPUDevice _dev, char *err, WGPUAdapter adapter, + WGPU_NULLABLE WGPUDeviceDescriptor const *descriptor, + WGPURequestDeviceCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = wgpuAdapterRequestDevice(adapter, descriptor, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuAdapterAddRef(WGPUDevice _dev, char *err, + WGPUAdapter adapter) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuAdapterAddRef(adapter); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuAdapterRelease(WGPUDevice _dev, char *err, + WGPUAdapter adapter) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuAdapterRelease(adapter); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuAdapterInfoFreeMembers(WGPUDevice _dev, char *err, + WGPUAdapterInfo adapterInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuAdapterInfoFreeMembers(adapterInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuBindGroupSetLabel(WGPUDevice _dev, char *err, + WGPUBindGroup bindGroup, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBindGroupSetLabel(bindGroup, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuBindGroupAddRef(WGPUDevice _dev, char *err, + WGPUBindGroup bindGroup) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBindGroupAddRef(bindGroup); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuBindGroupRelease(WGPUDevice _dev, char *err, + WGPUBindGroup bindGroup) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBindGroupRelease(bindGroup); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuBindGroupLayoutSetLabel(WGPUDevice _dev, char *err, + WGPUBindGroupLayout bindGroupLayout, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBindGroupLayoutSetLabel(bindGroupLayout, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuBindGroupLayoutAddRef(WGPUDevice _dev, char *err, + WGPUBindGroupLayout bindGroupLayout) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBindGroupLayoutAddRef(bindGroupLayout); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuBindGroupLayoutRelease(WGPUDevice _dev, char *err, + WGPUBindGroupLayout bindGroupLayout) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBindGroupLayoutRelease(bindGroupLayout); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuBufferDestroy(WGPUDevice _dev, char *err, + WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBufferDestroy(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUBufferMapState +go_wgpuBufferGetMapState(WGPUDevice _dev, char *err, WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBufferMapState ret = wgpuBufferGetMapState(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline uint64_t go_wgpuBufferGetSize(WGPUDevice _dev, char *err, + WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint64_t ret = wgpuBufferGetSize(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUBufferUsage go_wgpuBufferGetUsage(WGPUDevice _dev, char *err, + WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBufferUsage ret = wgpuBufferGetUsage(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUFuture +go_wgpuBufferMapAsync(WGPUDevice _dev, char *err, WGPUBuffer buffer, + WGPUMapMode mode, size_t offset, size_t size, + WGPUBufferMapCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = wgpuBufferMapAsync(buffer, mode, offset, size, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUStatus +go_wgpuBufferReadMappedRange(WGPUDevice _dev, char *err, WGPUBuffer buffer, + size_t offset, void *data, size_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuBufferReadMappedRange(buffer, offset, data, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuBufferSetLabel(WGPUDevice _dev, char *err, + WGPUBuffer buffer, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBufferSetLabel(buffer, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuBufferUnmap(WGPUDevice _dev, char *err, + WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBufferUnmap(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus +go_wgpuBufferWriteMappedRange(WGPUDevice _dev, char *err, WGPUBuffer buffer, + size_t offset, void const *data, size_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuBufferWriteMappedRange(buffer, offset, data, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuBufferAddRef(WGPUDevice _dev, char *err, + WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBufferAddRef(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuBufferRelease(WGPUDevice _dev, char *err, + WGPUBuffer buffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuBufferRelease(buffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandBufferSetLabel(WGPUDevice _dev, char *err, + WGPUCommandBuffer commandBuffer, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandBufferSetLabel(commandBuffer, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandBufferAddRef(WGPUDevice _dev, char *err, + WGPUCommandBuffer commandBuffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandBufferAddRef(commandBuffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuCommandBufferRelease(WGPUDevice _dev, char *err, + WGPUCommandBuffer commandBuffer) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandBufferRelease(commandBuffer); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUComputePassEncoder go_wgpuCommandEncoderBeginComputePass( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPU_NULLABLE WGPUComputePassDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUComputePassEncoder ret = + wgpuCommandEncoderBeginComputePass(commandEncoder, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPURenderPassEncoder go_wgpuCommandEncoderBeginRenderPass( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPURenderPassDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPURenderPassEncoder ret = + wgpuCommandEncoderBeginRenderPass(commandEncoder, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuCommandEncoderClearBuffer( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUBuffer buffer, uint64_t offset, uint64_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderClearBuffer(commandEncoder, buffer, offset, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandEncoderCopyBufferToBuffer( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUBuffer source, uint64_t sourceOffset, WGPUBuffer destination, + uint64_t destinationOffset, uint64_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderCopyBufferToBuffer(commandEncoder, source, sourceOffset, + destination, destinationOffset, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandEncoderCopyBufferToTexture( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUTexelCopyBufferInfo const *source, + WGPUTexelCopyTextureInfo const *destination, WGPUExtent3D const *copySize) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderCopyBufferToTexture(commandEncoder, source, destination, + copySize); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandEncoderCopyTextureToBuffer( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUTexelCopyTextureInfo const *source, + WGPUTexelCopyBufferInfo const *destination, WGPUExtent3D const *copySize) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderCopyTextureToBuffer(commandEncoder, source, destination, + copySize); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandEncoderCopyTextureToTexture( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUTexelCopyTextureInfo const *source, + WGPUTexelCopyTextureInfo const *destination, WGPUExtent3D const *copySize) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderCopyTextureToTexture(commandEncoder, source, destination, + copySize); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUCommandBuffer go_wgpuCommandEncoderFinish( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPU_NULLABLE WGPUCommandBufferDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUCommandBuffer ret = wgpuCommandEncoderFinish(commandEncoder, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void +go_wgpuCommandEncoderInsertDebugMarker(WGPUDevice _dev, char *err, + WGPUCommandEncoder commandEncoder, + WGPUStringView markerLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderInsertDebugMarker(commandEncoder, markerLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuCommandEncoderPopDebugGroup(WGPUDevice _dev, char *err, + WGPUCommandEncoder commandEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderPopDebugGroup(commandEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuCommandEncoderPushDebugGroup(WGPUDevice _dev, char *err, + WGPUCommandEncoder commandEncoder, + WGPUStringView groupLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderPushDebugGroup(commandEncoder, groupLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandEncoderResolveQuerySet( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUQuerySet querySet, uint32_t firstQuery, uint32_t queryCount, + WGPUBuffer destination, uint64_t destinationOffset) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderResolveQuerySet(commandEncoder, querySet, firstQuery, + queryCount, destination, destinationOffset); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuCommandEncoderSetLabel(WGPUDevice _dev, char *err, + WGPUCommandEncoder commandEncoder, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderSetLabel(commandEncoder, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuCommandEncoderWriteTimestamp( + WGPUDevice _dev, char *err, WGPUCommandEncoder commandEncoder, + WGPUQuerySet querySet, uint32_t queryIndex) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderWriteTimestamp(commandEncoder, querySet, queryIndex); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuCommandEncoderAddRef(WGPUDevice _dev, char *err, + WGPUCommandEncoder commandEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderAddRef(commandEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuCommandEncoderRelease(WGPUDevice _dev, char *err, + WGPUCommandEncoder commandEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuCommandEncoderRelease(commandEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuComputePassEncoderDispatchWorkgroups( + WGPUDevice _dev, char *err, WGPUComputePassEncoder computePassEncoder, + uint32_t workgroupCountX, uint32_t workgroupCountY, + uint32_t workgroupCountZ) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderDispatchWorkgroups(computePassEncoder, workgroupCountX, + workgroupCountY, workgroupCountZ); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuComputePassEncoderDispatchWorkgroupsIndirect( + WGPUDevice _dev, char *err, WGPUComputePassEncoder computePassEncoder, + WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderDispatchWorkgroupsIndirect( + computePassEncoder, indirectBuffer, indirectOffset); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePassEncoderEnd(WGPUDevice _dev, char *err, + WGPUComputePassEncoder computePassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderEnd(computePassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuComputePassEncoderInsertDebugMarker( + WGPUDevice _dev, char *err, WGPUComputePassEncoder computePassEncoder, + WGPUStringView markerLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderInsertDebugMarker(computePassEncoder, markerLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuComputePassEncoderPopDebugGroup( + WGPUDevice _dev, char *err, WGPUComputePassEncoder computePassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderPopDebugGroup(computePassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuComputePassEncoderPushDebugGroup( + WGPUDevice _dev, char *err, WGPUComputePassEncoder computePassEncoder, + WGPUStringView groupLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderPushDebugGroup(computePassEncoder, groupLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuComputePassEncoderSetBindGroup( + WGPUDevice _dev, char *err, WGPUComputePassEncoder computePassEncoder, + uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, + size_t dynamicOffsetCount, uint32_t const *dynamicOffsets) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderSetBindGroup(computePassEncoder, groupIndex, group, + dynamicOffsetCount, dynamicOffsets); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePassEncoderSetLabel(WGPUDevice _dev, char *err, + WGPUComputePassEncoder computePassEncoder, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderSetLabel(computePassEncoder, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePassEncoderSetPipeline(WGPUDevice _dev, char *err, + WGPUComputePassEncoder computePassEncoder, + WGPUComputePipeline pipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderSetPipeline(computePassEncoder, pipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePassEncoderAddRef(WGPUDevice _dev, char *err, + WGPUComputePassEncoder computePassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderAddRef(computePassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePassEncoderRelease(WGPUDevice _dev, char *err, + WGPUComputePassEncoder computePassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePassEncoderRelease(computePassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUBindGroupLayout +go_wgpuComputePipelineGetBindGroupLayout(WGPUDevice _dev, char *err, + WGPUComputePipeline computePipeline, + uint32_t groupIndex) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBindGroupLayout ret = + wgpuComputePipelineGetBindGroupLayout(computePipeline, groupIndex); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void +go_wgpuComputePipelineSetLabel(WGPUDevice _dev, char *err, + WGPUComputePipeline computePipeline, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePipelineSetLabel(computePipeline, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePipelineAddRef(WGPUDevice _dev, char *err, + WGPUComputePipeline computePipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePipelineAddRef(computePipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuComputePipelineRelease(WGPUDevice _dev, char *err, + WGPUComputePipeline computePipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuComputePipelineRelease(computePipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUBindGroup +go_wgpuDeviceCreateBindGroup(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUBindGroupDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBindGroup ret = wgpuDeviceCreateBindGroup(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUBindGroupLayout go_wgpuDeviceCreateBindGroupLayout( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPUBindGroupLayoutDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBindGroupLayout ret = wgpuDeviceCreateBindGroupLayout(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUBuffer +go_wgpuDeviceCreateBuffer(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUBufferDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBuffer ret = wgpuDeviceCreateBuffer(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUCommandEncoder go_wgpuDeviceCreateCommandEncoder( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPU_NULLABLE WGPUCommandEncoderDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUCommandEncoder ret = wgpuDeviceCreateCommandEncoder(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUComputePipeline go_wgpuDeviceCreateComputePipeline( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPUComputePipelineDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUComputePipeline ret = wgpuDeviceCreateComputePipeline(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUFuture go_wgpuDeviceCreateComputePipelineAsync( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPUComputePipelineDescriptor const *descriptor, + WGPUCreateComputePipelineAsyncCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = + wgpuDeviceCreateComputePipelineAsync(device, descriptor, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUPipelineLayout go_wgpuDeviceCreatePipelineLayout( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPUPipelineLayoutDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUPipelineLayout ret = wgpuDeviceCreatePipelineLayout(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUQuerySet +go_wgpuDeviceCreateQuerySet(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUQuerySetDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUQuerySet ret = wgpuDeviceCreateQuerySet(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPURenderBundleEncoder go_wgpuDeviceCreateRenderBundleEncoder( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPURenderBundleEncoderDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPURenderBundleEncoder ret = + wgpuDeviceCreateRenderBundleEncoder(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPURenderPipeline go_wgpuDeviceCreateRenderPipeline( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPURenderPipelineDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPURenderPipeline ret = wgpuDeviceCreateRenderPipeline(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUFuture go_wgpuDeviceCreateRenderPipelineAsync( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPURenderPipelineDescriptor const *descriptor, + WGPUCreateRenderPipelineAsyncCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = + wgpuDeviceCreateRenderPipelineAsync(device, descriptor, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUSampler go_wgpuDeviceCreateSampler( + WGPUDevice _dev, char *err, WGPUDevice device, + WGPU_NULLABLE WGPUSamplerDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUSampler ret = wgpuDeviceCreateSampler(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUShaderModule +go_wgpuDeviceCreateShaderModule(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUShaderModuleDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUShaderModule ret = wgpuDeviceCreateShaderModule(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUTexture +go_wgpuDeviceCreateTexture(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUTextureDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUTexture ret = wgpuDeviceCreateTexture(device, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuDeviceDestroy(WGPUDevice _dev, char *err, + WGPUDevice device) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuDeviceDestroy(device); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus +go_wgpuDeviceGetAdapterInfo(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUAdapterInfo *adapterInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuDeviceGetAdapterInfo(device, adapterInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuDeviceGetFeatures(WGPUDevice _dev, char *err, + WGPUDevice device, + WGPUSupportedFeatures *features) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuDeviceGetFeatures(device, features); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus go_wgpuDeviceGetLimits(WGPUDevice _dev, char *err, + WGPUDevice device, + WGPULimits *limits) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuDeviceGetLimits(device, limits); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUFuture go_wgpuDeviceGetLostFuture(WGPUDevice _dev, char *err, + WGPUDevice device) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = wgpuDeviceGetLostFuture(device); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUQueue go_wgpuDeviceGetQueue(WGPUDevice _dev, char *err, + WGPUDevice device) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUQueue ret = wgpuDeviceGetQueue(device); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUBool go_wgpuDeviceHasFeature(WGPUDevice _dev, char *err, + WGPUDevice device, + WGPUFeatureName feature) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBool ret = wgpuDeviceHasFeature(device, feature); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUFuture +go_wgpuDevicePopErrorScope(WGPUDevice _dev, char *err, WGPUDevice device, + WGPUPopErrorScopeCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = wgpuDevicePopErrorScope(device, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuDevicePushErrorScope(WGPUDevice _dev, char *err, + WGPUDevice device, + WGPUErrorFilter filter) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuDevicePushErrorScope(device, filter); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuDeviceSetLabel(WGPUDevice _dev, char *err, + WGPUDevice device, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuDeviceSetLabel(device, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuDeviceAddRef(WGPUDevice _dev, char *err, + WGPUDevice device) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuDeviceAddRef(device); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuDeviceRelease(WGPUDevice _dev, char *err, + WGPUDevice device) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuDeviceRelease(device); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuExternalTextureSetLabel(WGPUDevice _dev, char *err, + WGPUExternalTexture externalTexture, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuExternalTextureSetLabel(externalTexture, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuExternalTextureAddRef(WGPUDevice _dev, char *err, + WGPUExternalTexture externalTexture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuExternalTextureAddRef(externalTexture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuExternalTextureRelease(WGPUDevice _dev, char *err, + WGPUExternalTexture externalTexture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuExternalTextureRelease(externalTexture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUSurface +go_wgpuInstanceCreateSurface(WGPUDevice _dev, char *err, WGPUInstance instance, + WGPUSurfaceDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUSurface ret = wgpuInstanceCreateSurface(instance, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuInstanceGetWGSLLanguageFeatures( + WGPUDevice _dev, char *err, WGPUInstance instance, + WGPUSupportedWGSLLanguageFeatures *features) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuInstanceGetWGSLLanguageFeatures(instance, features); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUBool +go_wgpuInstanceHasWGSLLanguageFeature(WGPUDevice _dev, char *err, + WGPUInstance instance, + WGPUWGSLLanguageFeatureName feature) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBool ret = wgpuInstanceHasWGSLLanguageFeature(instance, feature); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuInstanceProcessEvents(WGPUDevice _dev, char *err, + WGPUInstance instance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuInstanceProcessEvents(instance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUFuture go_wgpuInstanceRequestAdapter( + WGPUDevice _dev, char *err, WGPUInstance instance, + WGPU_NULLABLE WGPURequestAdapterOptions const *options, + WGPURequestAdapterCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = wgpuInstanceRequestAdapter(instance, options, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUWaitStatus go_wgpuInstanceWaitAny( + WGPUDevice _dev, char *err, WGPUInstance instance, size_t futureCount, + WGPU_NULLABLE WGPUFutureWaitInfo *futures, uint64_t timeoutNS) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUWaitStatus ret = + wgpuInstanceWaitAny(instance, futureCount, futures, timeoutNS); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuInstanceAddRef(WGPUDevice _dev, char *err, + WGPUInstance instance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuInstanceAddRef(instance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuInstanceRelease(WGPUDevice _dev, char *err, + WGPUInstance instance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuInstanceRelease(instance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuPipelineLayoutSetLabel(WGPUDevice _dev, char *err, + WGPUPipelineLayout pipelineLayout, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuPipelineLayoutSetLabel(pipelineLayout, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuPipelineLayoutAddRef(WGPUDevice _dev, char *err, + WGPUPipelineLayout pipelineLayout) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuPipelineLayoutAddRef(pipelineLayout); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuPipelineLayoutRelease(WGPUDevice _dev, char *err, + WGPUPipelineLayout pipelineLayout) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuPipelineLayoutRelease(pipelineLayout); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQuerySetDestroy(WGPUDevice _dev, char *err, + WGPUQuerySet querySet) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQuerySetDestroy(querySet); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline uint32_t go_wgpuQuerySetGetCount(WGPUDevice _dev, char *err, + WGPUQuerySet querySet) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint32_t ret = wgpuQuerySetGetCount(querySet); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUQueryType go_wgpuQuerySetGetType(WGPUDevice _dev, char *err, + WGPUQuerySet querySet) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUQueryType ret = wgpuQuerySetGetType(querySet); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuQuerySetSetLabel(WGPUDevice _dev, char *err, + WGPUQuerySet querySet, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQuerySetSetLabel(querySet, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQuerySetAddRef(WGPUDevice _dev, char *err, + WGPUQuerySet querySet) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQuerySetAddRef(querySet); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQuerySetRelease(WGPUDevice _dev, char *err, + WGPUQuerySet querySet) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQuerySetRelease(querySet); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUFuture +go_wgpuQueueOnSubmittedWorkDone(WGPUDevice _dev, char *err, WGPUQueue queue, + WGPUQueueWorkDoneCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = wgpuQueueOnSubmittedWorkDone(queue, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuQueueSetLabel(WGPUDevice _dev, char *err, + WGPUQueue queue, WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQueueSetLabel(queue, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQueueSubmit(WGPUDevice _dev, char *err, + WGPUQueue queue, size_t commandCount, + WGPUCommandBuffer const *commands) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQueueSubmit(queue, commandCount, commands); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQueueWriteBuffer(WGPUDevice _dev, char *err, + WGPUQueue queue, WGPUBuffer buffer, + uint64_t bufferOffset, + void const *data, size_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQueueWriteBuffer(queue, buffer, bufferOffset, data, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuQueueWriteTexture(WGPUDevice _dev, char *err, WGPUQueue queue, + WGPUTexelCopyTextureInfo const *destination, + void const *data, size_t dataSize, + WGPUTexelCopyBufferLayout const *dataLayout, + WGPUExtent3D const *writeSize) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQueueWriteTexture(queue, destination, data, dataSize, dataLayout, + writeSize); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQueueAddRef(WGPUDevice _dev, char *err, + WGPUQueue queue) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQueueAddRef(queue); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuQueueRelease(WGPUDevice _dev, char *err, + WGPUQueue queue) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuQueueRelease(queue); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleSetLabel(WGPUDevice _dev, char *err, + WGPURenderBundle renderBundle, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleSetLabel(renderBundle, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleAddRef(WGPUDevice _dev, char *err, + WGPURenderBundle renderBundle) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleAddRef(renderBundle); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleRelease(WGPUDevice _dev, char *err, + WGPURenderBundle renderBundle) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleRelease(renderBundle); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderBundleEncoderDraw(WGPUDevice _dev, char *err, + WGPURenderBundleEncoder renderBundleEncoder, + uint32_t vertexCount, uint32_t instanceCount, + uint32_t firstVertex, uint32_t firstInstance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderDraw(renderBundleEncoder, vertexCount, instanceCount, + firstVertex, firstInstance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderDrawIndexed( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, + int32_t baseVertex, uint32_t firstInstance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderDrawIndexed(renderBundleEncoder, indexCount, + instanceCount, firstIndex, baseVertex, + firstInstance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderDrawIndexedIndirect( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderDrawIndexedIndirect(renderBundleEncoder, + indirectBuffer, indirectOffset); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderDrawIndirect( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderDrawIndirect(renderBundleEncoder, indirectBuffer, + indirectOffset); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPURenderBundle go_wgpuRenderBundleEncoderFinish( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPU_NULLABLE WGPURenderBundleDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPURenderBundle ret = + wgpuRenderBundleEncoderFinish(renderBundleEncoder, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuRenderBundleEncoderInsertDebugMarker( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPUStringView markerLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderInsertDebugMarker(renderBundleEncoder, markerLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderPopDebugGroup( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderPopDebugGroup(renderBundleEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderPushDebugGroup( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPUStringView groupLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderPushDebugGroup(renderBundleEncoder, groupLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderSetBindGroup( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, + size_t dynamicOffsetCount, uint32_t const *dynamicOffsets) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderSetBindGroup(renderBundleEncoder, groupIndex, group, + dynamicOffsetCount, dynamicOffsets); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderSetIndexBuffer( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderSetIndexBuffer(renderBundleEncoder, buffer, format, + offset, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderBundleEncoderSetLabel(WGPUDevice _dev, char *err, + WGPURenderBundleEncoder renderBundleEncoder, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderSetLabel(renderBundleEncoder, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderSetPipeline( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + WGPURenderPipeline pipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderSetPipeline(renderBundleEncoder, pipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderBundleEncoderSetVertexBuffer( + WGPUDevice _dev, char *err, WGPURenderBundleEncoder renderBundleEncoder, + uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, + uint64_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderSetVertexBuffer(renderBundleEncoder, slot, buffer, + offset, size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderBundleEncoderAddRef(WGPUDevice _dev, char *err, + WGPURenderBundleEncoder renderBundleEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderAddRef(renderBundleEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderBundleEncoderRelease(WGPUDevice _dev, char *err, + WGPURenderBundleEncoder renderBundleEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderBundleEncoderRelease(renderBundleEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderBeginOcclusionQuery( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + uint32_t queryIndex) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderBeginOcclusionQuery(renderPassEncoder, queryIndex); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderDraw(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder, + uint32_t vertexCount, uint32_t instanceCount, + uint32_t firstVertex, uint32_t firstInstance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderDraw(renderPassEncoder, vertexCount, instanceCount, + firstVertex, firstInstance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderDrawIndexed( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, + int32_t baseVertex, uint32_t firstInstance) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderDrawIndexed(renderPassEncoder, indexCount, instanceCount, + firstIndex, baseVertex, firstInstance); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderDrawIndexedIndirect( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderDrawIndexedIndirect(renderPassEncoder, indirectBuffer, + indirectOffset); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderDrawIndirect( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + WGPUBuffer indirectBuffer, uint64_t indirectOffset) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderDrawIndirect(renderPassEncoder, indirectBuffer, + indirectOffset); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderEnd(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderEnd(renderPassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderEndOcclusionQuery( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderEndOcclusionQuery(renderPassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderExecuteBundles( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + size_t bundleCount, WGPURenderBundle const *bundles) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderExecuteBundles(renderPassEncoder, bundleCount, bundles); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderInsertDebugMarker( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + WGPUStringView markerLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderInsertDebugMarker(renderPassEncoder, markerLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderPopDebugGroup(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderPopDebugGroup(renderPassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderPushDebugGroup(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder, + WGPUStringView groupLabel) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderPushDebugGroup(renderPassEncoder, groupLabel); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderSetBindGroup( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + uint32_t groupIndex, WGPU_NULLABLE WGPUBindGroup group, + size_t dynamicOffsetCount, uint32_t const *dynamicOffsets) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetBindGroup(renderPassEncoder, groupIndex, group, + dynamicOffsetCount, dynamicOffsets); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderSetBlendConstant( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + WGPUColor const *color) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetBlendConstant(renderPassEncoder, color); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderSetIndexBuffer( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + WGPUBuffer buffer, WGPUIndexFormat format, uint64_t offset, uint64_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetIndexBuffer(renderPassEncoder, buffer, format, offset, + size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderSetLabel(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetLabel(renderPassEncoder, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderSetPipeline(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder, + WGPURenderPipeline pipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetPipeline(renderPassEncoder, pipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderSetScissorRect( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetScissorRect(renderPassEncoder, x, y, width, height); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderSetStencilReference( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + uint32_t reference) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetStencilReference(renderPassEncoder, reference); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuRenderPassEncoderSetVertexBuffer( + WGPUDevice _dev, char *err, WGPURenderPassEncoder renderPassEncoder, + uint32_t slot, WGPU_NULLABLE WGPUBuffer buffer, uint64_t offset, + uint64_t size) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetVertexBuffer(renderPassEncoder, slot, buffer, offset, + size); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderSetViewport(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder, + float x, float y, float width, float height, + float minDepth, float maxDepth) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderSetViewport(renderPassEncoder, x, y, width, height, + minDepth, maxDepth); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderAddRef(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderAddRef(renderPassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPassEncoderRelease(WGPUDevice _dev, char *err, + WGPURenderPassEncoder renderPassEncoder) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPassEncoderRelease(renderPassEncoder); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUBindGroupLayout +go_wgpuRenderPipelineGetBindGroupLayout(WGPUDevice _dev, char *err, + WGPURenderPipeline renderPipeline, + uint32_t groupIndex) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUBindGroupLayout ret = + wgpuRenderPipelineGetBindGroupLayout(renderPipeline, groupIndex); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void +go_wgpuRenderPipelineSetLabel(WGPUDevice _dev, char *err, + WGPURenderPipeline renderPipeline, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPipelineSetLabel(renderPipeline, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPipelineAddRef(WGPUDevice _dev, char *err, + WGPURenderPipeline renderPipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPipelineAddRef(renderPipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuRenderPipelineRelease(WGPUDevice _dev, char *err, + WGPURenderPipeline renderPipeline) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuRenderPipelineRelease(renderPipeline); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSamplerSetLabel(WGPUDevice _dev, char *err, + WGPUSampler sampler, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSamplerSetLabel(sampler, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSamplerAddRef(WGPUDevice _dev, char *err, + WGPUSampler sampler) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSamplerAddRef(sampler); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSamplerRelease(WGPUDevice _dev, char *err, + WGPUSampler sampler) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSamplerRelease(sampler); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUFuture go_wgpuShaderModuleGetCompilationInfo( + WGPUDevice _dev, char *err, WGPUShaderModule shaderModule, + WGPUCompilationInfoCallbackInfo callbackInfo) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUFuture ret = + wgpuShaderModuleGetCompilationInfo(shaderModule, callbackInfo); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuShaderModuleSetLabel(WGPUDevice _dev, char *err, + WGPUShaderModule shaderModule, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuShaderModuleSetLabel(shaderModule, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuShaderModuleAddRef(WGPUDevice _dev, char *err, + WGPUShaderModule shaderModule) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuShaderModuleAddRef(shaderModule); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuShaderModuleRelease(WGPUDevice _dev, char *err, + WGPUShaderModule shaderModule) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuShaderModuleRelease(shaderModule); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuSupportedFeaturesFreeMembers(WGPUDevice _dev, char *err, + WGPUSupportedFeatures supportedFeatures) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSupportedFeaturesFreeMembers(supportedFeatures); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSupportedInstanceFeaturesFreeMembers( + WGPUDevice _dev, char *err, + WGPUSupportedInstanceFeatures supportedInstanceFeatures) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSupportedInstanceFeaturesFreeMembers(supportedInstanceFeatures); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSupportedWGSLLanguageFeaturesFreeMembers( + WGPUDevice _dev, char *err, + WGPUSupportedWGSLLanguageFeatures supportedWGSLLanguageFeatures) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSupportedWGSLLanguageFeaturesFreeMembers(supportedWGSLLanguageFeatures); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void +go_wgpuSurfaceConfigure(WGPUDevice _dev, char *err, WGPUSurface surface, + WGPUSurfaceConfiguration const *config) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceConfigure(surface, config); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus +go_wgpuSurfaceGetCapabilities(WGPUDevice _dev, char *err, WGPUSurface surface, + WGPUAdapter adapter, + WGPUSurfaceCapabilities *capabilities) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuSurfaceGetCapabilities(surface, adapter, capabilities); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void +go_wgpuSurfaceGetCurrentTexture(WGPUDevice _dev, char *err, WGPUSurface surface, + WGPUSurfaceTexture *surfaceTexture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceGetCurrentTexture(surface, surfaceTexture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUStatus go_wgpuSurfacePresent(WGPUDevice _dev, char *err, + WGPUSurface surface) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUStatus ret = wgpuSurfacePresent(surface); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuSurfaceSetLabel(WGPUDevice _dev, char *err, + WGPUSurface surface, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceSetLabel(surface, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSurfaceUnconfigure(WGPUDevice _dev, char *err, + WGPUSurface surface) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceUnconfigure(surface); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSurfaceAddRef(WGPUDevice _dev, char *err, + WGPUSurface surface) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceAddRef(surface); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSurfaceRelease(WGPUDevice _dev, char *err, + WGPUSurface surface) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceRelease(surface); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuSurfaceCapabilitiesFreeMembers( + WGPUDevice _dev, char *err, WGPUSurfaceCapabilities surfaceCapabilities) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuSurfaceCapabilitiesFreeMembers(surfaceCapabilities); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline WGPUTextureView go_wgpuTextureCreateView( + WGPUDevice _dev, char *err, WGPUTexture texture, + WGPU_NULLABLE WGPUTextureViewDescriptor const *descriptor) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUTextureView ret = wgpuTextureCreateView(texture, descriptor); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuTextureDestroy(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureDestroy(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline uint32_t +go_wgpuTextureGetDepthOrArrayLayers(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint32_t ret = wgpuTextureGetDepthOrArrayLayers(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUTextureDimension +go_wgpuTextureGetDimension(WGPUDevice _dev, char *err, WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUTextureDimension ret = wgpuTextureGetDimension(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUTextureFormat +go_wgpuTextureGetFormat(WGPUDevice _dev, char *err, WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUTextureFormat ret = wgpuTextureGetFormat(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline uint32_t go_wgpuTextureGetHeight(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint32_t ret = wgpuTextureGetHeight(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline uint32_t go_wgpuTextureGetMipLevelCount(WGPUDevice _dev, + char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint32_t ret = wgpuTextureGetMipLevelCount(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline uint32_t go_wgpuTextureGetSampleCount(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint32_t ret = wgpuTextureGetSampleCount(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUTextureViewDimension +go_wgpuTextureGetTextureBindingViewDimension(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUTextureViewDimension ret = + wgpuTextureGetTextureBindingViewDimension(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline WGPUTextureUsage +go_wgpuTextureGetUsage(WGPUDevice _dev, char *err, WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + WGPUTextureUsage ret = wgpuTextureGetUsage(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline uint32_t go_wgpuTextureGetWidth(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + uint32_t ret = wgpuTextureGetWidth(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); + return ret; +} + +static inline void go_wgpuTextureSetLabel(WGPUDevice _dev, char *err, + WGPUTexture texture, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureSetLabel(texture, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuTextureAddRef(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureAddRef(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuTextureRelease(WGPUDevice _dev, char *err, + WGPUTexture texture) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureRelease(texture); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuTextureViewSetLabel(WGPUDevice _dev, char *err, + WGPUTextureView textureView, + WGPUStringView label) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureViewSetLabel(textureView, label); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuTextureViewAddRef(WGPUDevice _dev, char *err, + WGPUTextureView textureView) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureViewAddRef(textureView); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} + +static inline void go_wgpuTextureViewRelease(WGPUDevice _dev, char *err, + WGPUTextureView textureView) { + wgpuDevicePushErrorScope(_dev, WGPUErrorFilter_Validation); + wgpuTextureViewRelease(textureView); + + WGPUPopErrorScopeCallbackInfo const err_cb = { + .callback = webgpu_error_callback, + .userdata1 = (void *)err, + }; + + wgpuDevicePopErrorScope(_dev, err_cb); +} From f2177b698d6bac8af01ec2bc165bc3d9da6cce4b Mon Sep 17 00:00:00 2001 From: Oliver Bestmann Date: Thu, 28 May 2026 21:48:41 +0200 Subject: [PATCH 2/5] mem: reduce allocation by using an interface for releaseNow. The previous implementation was capturing the generic runtime info when creating the closure passed to SetFinalizer. This is not necessary if we use an interface. --- wgpu/cgo_test.go | 140 ++++++++++++++++++++++++++++++++++- wgpu/command_encoder.go | 53 ++++++------- wgpu/compute_pass_encoder.go | 10 ++- wgpu/compute_pipeline.go | 7 +- wgpu/compute_pipeline_js.go | 2 +- wgpu/device.go | 35 +++------ wgpu/error-callback.go | 8 +- wgpu/pools.go | 7 -- wgpu/string-view.go | 26 +++++++ wgpu/texture.go | 6 +- wgpu/wgpu.go | 10 +-- 11 files changed, 214 insertions(+), 90 deletions(-) create mode 100644 wgpu/string-view.go diff --git a/wgpu/cgo_test.go b/wgpu/cgo_test.go index 9a20475..0c5059a 100644 --- a/wgpu/cgo_test.go +++ b/wgpu/cgo_test.go @@ -1,12 +1,13 @@ package wgpu import ( + "fmt" "testing" "github.com/stretchr/testify/require" ) -func BenchmarkCGoOverhead(b *testing.B) { +func BenchmarkCreateView(b *testing.B) { instance := CreateInstance(nil) adapter, err := instance.RequestAdapter(&RequestAdapterOptions{ @@ -22,8 +23,6 @@ func BenchmarkCGoOverhead(b *testing.B) { queue := device.GetQueue() defer queue.Release() - b.ReportAllocs() - texture := device.CreateTexture(&TextureDescriptor{ Label: "test", Usage: TextureUsageCopyDst, @@ -34,6 +33,10 @@ func BenchmarkCGoOverhead(b *testing.B) { SampleCount: 1, }) + defer texture.Release() + + b.ReportAllocs() + for range b.N { view := texture.CreateView(&TextureViewDescriptor{ Label: "test label", @@ -44,3 +47,134 @@ func BenchmarkCGoOverhead(b *testing.B) { view.Release() } } + +func BenchmarkCreateBindGroup(b *testing.B) { + instance := CreateInstance(nil) + + adapter, err := instance.RequestAdapter(&RequestAdapterOptions{ + ForceFallbackAdapter: true, + }) + require.NoError(b, err) + defer adapter.Release() + + device, err := adapter.RequestDevice(nil) + require.NoError(b, err) + defer device.Release() + + queue := device.GetQueue() + defer queue.Release() + + texture := device.CreateTexture(&TextureDescriptor{ + Label: "test", + Usage: TextureUsageTextureBinding, + Dimension: TextureDimension2D, + Size: Extent3D{Width: 16, Height: 16, DepthOrArrayLayers: 1}, + Format: TextureFormatRGBA8Unorm, + MipLevelCount: 1, + SampleCount: 1, + }) + defer texture.Release() + + view := texture.CreateView(&TextureViewDescriptor{ + Label: "test label", + MipLevelCount: 1, + ArrayLayerCount: 1, + }) + defer view.Release() + + bindGroupLayout := device.CreateBindGroupLayout(&BindGroupLayoutDescriptor{ + Label: "BindGroupLayout", + Entries: []BindGroupLayoutEntry{ + { + Binding: 0, + Visibility: ShaderStageFragment, + Texture: TextureBindingLayout{ + SampleType: TextureSampleTypeFloat, + ViewDimension: TextureViewDimension2D, + Multisampled: false, + }, + }, + }, + }) + defer bindGroupLayout.Release() + + b.ReportAllocs() + + label := fmt.Sprintf("BindGroup %T", device) + + for range b.N { + bindGroup := device.CreateBindGroup(&BindGroupDescriptor{ + Label: label, + Layout: bindGroupLayout, + Entries: []BindGroupEntry{ + { + TextureView: view, + }, + }, + }) + + bindGroup.Release() + } +} + +func BenchmarkBeginRenderPass(b *testing.B) { + instance := CreateInstance(nil) + + adapter, err := instance.RequestAdapter(&RequestAdapterOptions{ + ForceFallbackAdapter: true, + }) + require.NoError(b, err) + defer adapter.Release() + + device, err := adapter.RequestDevice(nil) + require.NoError(b, err) + defer device.Release() + + queue := device.GetQueue() + defer queue.Release() + + b.ReportAllocs() + + texture := device.CreateTexture(&TextureDescriptor{ + Label: "test", + Usage: TextureUsageRenderAttachment, + Dimension: TextureDimension2D, + Size: Extent3D{Width: 16, Height: 16, DepthOrArrayLayers: 1}, + Format: TextureFormatRGBA8Unorm, + MipLevelCount: 1, + SampleCount: 1, + }) + + defer texture.Release() + + view := texture.CreateView(&TextureViewDescriptor{ + Label: "test label", + MipLevelCount: 1, + ArrayLayerCount: 1, + }) + + defer view.Release() + + for range b.N { + enc := device.CreateCommandEncoder(nil) + + pass := enc.BeginRenderPass(&RenderPassDescriptor{ + Label: "RenderPass", + ColorAttachments: []RenderPassColorAttachment{ + { + View: view, + LoadOp: LoadOpClear, + StoreOp: StoreOpStore, + }, + }, + }) + + pass.End() + pass.Release() + + buf := enc.Finish(nil) + buf.Release() + + enc.Release() + } +} diff --git a/wgpu/command_encoder.go b/wgpu/command_encoder.go index 9ab4b40..67b2986 100644 --- a/wgpu/command_encoder.go +++ b/wgpu/command_encoder.go @@ -2,9 +2,7 @@ package wgpu -/* -#include "wgpu_go_wrappers.h" -*/ +// #include "wgpu_go_wrappers.h" import "C" import ( "errors" @@ -19,19 +17,15 @@ type ComputePassDescriptor struct { } func (p *CommandEncoder) BeginComputePass(descriptor *ComputePassDescriptor) *ComputePassEncoder { - var desc *C.WGPUComputePassDescriptor + var desc C.WGPUComputePassDescriptor - if descriptor != nil && descriptor.Label != "" { - label := C.CString(descriptor.Label) - defer C.free(unsafe.Pointer(label)) - - desc = allocWGPUComputePassDescriptor.GetZeroed() - defer allocWGPUComputePassDescriptor.Put(desc) - - desc.label = C.WGPUStringView{data: label, length: C.WGPU_STRLEN} + if descriptor != nil { + label := stringViewOf(descriptor.Label) + defer label.Release() + desc.label = label.ToC() } - ref := C.wgpuCommandEncoderBeginComputePass(p.ref, desc) + ref := C.wgpuCommandEncoderBeginComputePass(p.ref, &desc) if ref == nil { err := errors.New("failed to acquire ComputePassEncoder") panic(wrap(err, "")) @@ -42,17 +36,12 @@ func (p *CommandEncoder) BeginComputePass(descriptor *ComputePassDescriptor) *Co } func (p *CommandEncoder) TryBeginRenderPass(descriptor *RenderPassDescriptor) (*RenderPassEncoder, error) { - var desc *C.WGPURenderPassDescriptor = allocWGPURenderPassDescriptor.GetZeroed() - defer allocWGPURenderPassDescriptor.Put(desc) + var desc C.WGPURenderPassDescriptor if descriptor != nil { - if descriptor.Label != "" { - label := C.CString(descriptor.Label) - defer C.free(unsafe.Pointer(label)) - - desc.label.data = label - desc.label.length = C.WGPU_STRLEN - } + label := stringViewOf(descriptor.Label) + defer label.Release() + desc.label = label.ToC() colorAttachmentCount := len(descriptor.ColorAttachments) if colorAttachmentCount > 0 { @@ -110,7 +99,7 @@ func (p *CommandEncoder) TryBeginRenderPass(descriptor *RenderPassDescriptor) (* errh := acquireErrorCallback() defer errh.Done() - ref := C.go_wgpuCommandEncoderBeginRenderPass(p.device, errh.ToPointer(), p.ref, desc) + ref := C.go_wgpuCommandEncoderBeginRenderPass(p.device, errh.ToPointer(), p.ref, &desc) if err := errh.ToError(); err != nil { return nil, err } @@ -346,6 +335,9 @@ func (p *CommandEncoder) TryFinish(descriptor *CommandBufferDescriptor) (*Comman } func (p *CommandEncoder) TryInsertDebugMarker(markerLabel string) error { + label := stringViewOf(markerLabel) + defer label.Release() + errh := acquireErrorCallback() defer errh.Done() @@ -353,19 +345,12 @@ func (p *CommandEncoder) TryInsertDebugMarker(markerLabel string) error { p.device, errh.ToPointer(), p.ref, - toStringView(markerLabel), + label.ToC(), ) return errh.ToError() } -func toStringView(str string) C.WGPUStringView { - return C.WGPUStringView{ - data: (*C.char)(unsafe.Pointer(unsafe.StringData(str))), - length: C.size_t(len(str)), - } -} - func (p *CommandEncoder) TryPopDebugGroup() error { errh := acquireErrorCallback() defer errh.Done() @@ -383,11 +368,15 @@ func (p *CommandEncoder) TryPushDebugGroup(groupLabel string) error { errh := acquireErrorCallback() defer errh.Done() + label := stringViewOf(groupLabel) + defer label.Release() + labelC := label.ToC() + C.go_wgpuCommandEncoderPushDebugGroup( p.device, errh.ToPointer(), p.ref, - toStringView(groupLabel), + labelC, ) return errh.ToError() diff --git a/wgpu/compute_pass_encoder.go b/wgpu/compute_pass_encoder.go index 35f0cfb..adec3f4 100644 --- a/wgpu/compute_pass_encoder.go +++ b/wgpu/compute_pass_encoder.go @@ -33,7 +33,10 @@ func (p *ComputePassEncoder) EndPipelineStatisticsQuery() { } func (p *ComputePassEncoder) InsertDebugMarker(markerLabel string) { - C.wgpuComputePassEncoderInsertDebugMarker(p.ref, toStringView(markerLabel)) + label := stringViewOf(markerLabel) + defer label.Release() + + C.wgpuComputePassEncoderInsertDebugMarker(p.ref, label.ToC()) } func (p *ComputePassEncoder) PopDebugGroup() { @@ -41,7 +44,10 @@ func (p *ComputePassEncoder) PopDebugGroup() { } func (p *ComputePassEncoder) PushDebugGroup(groupLabel string) { - C.wgpuComputePassEncoderPushDebugGroup(p.ref, toStringView(groupLabel)) + label := stringViewOf(groupLabel) + defer label.Release() + + C.wgpuComputePassEncoderPushDebugGroup(p.ref, label.ToC()) } func (p *ComputePassEncoder) SetBindGroup(groupIndex uint32, group *BindGroup, dynamicOffsets []uint32) { diff --git a/wgpu/compute_pipeline.go b/wgpu/compute_pipeline.go index 5938dbe..0dbc859 100644 --- a/wgpu/compute_pipeline.go +++ b/wgpu/compute_pipeline.go @@ -2,12 +2,7 @@ package wgpu -/* - -#include -#include - -*/ +// #include "wgpu_go_wrappers.h" import "C" func (g *ComputePipeline) GetBindGroupLayout(groupIndex uint32) *BindGroupLayout { diff --git a/wgpu/compute_pipeline_js.go b/wgpu/compute_pipeline_js.go index 90239a7..189c4d1 100644 --- a/wgpu/compute_pipeline_js.go +++ b/wgpu/compute_pipeline_js.go @@ -2,7 +2,7 @@ package wgpu -// ComputePipelineDescriptor as described: +// ComputePipeline Descriptor as described: // https://gpuweb.github.io/gpuweb/#dictdef-gpucomputepipelinedescriptor type ComputePipelineDescriptor struct { Layout *PipelineLayout diff --git a/wgpu/device.go b/wgpu/device.go index 32b3040..ff5a739 100644 --- a/wgpu/device.go +++ b/wgpu/device.go @@ -2,26 +2,20 @@ package wgpu -/* -#include "wgpu_go_wrappers.h" -*/ +// #include "wgpu_go_wrappers.h" import "C" import ( "unsafe" ) func (g *Device) TryCreateBindGroup(descriptor *BindGroupDescriptor) (*BindGroup, error) { - var desc *C.WGPUBindGroupDescriptor = allocWGPUBindGroupDescriptor.GetZeroed() - defer allocWGPUBindGroupDescriptor.Put(desc) + var desc C.WGPUBindGroupDescriptor if descriptor != nil { - if descriptor.Label != "" { - label := C.CString(descriptor.Label) - defer C.free(unsafe.Pointer(label)) - desc.label.data = label - desc.label.length = C.WGPU_STRLEN - } + label := stringViewOf(descriptor.Label) + defer label.Release() + desc.label = label.ToC() if descriptor.Layout != nil { desc.layout = descriptor.Layout.ref @@ -66,7 +60,7 @@ func (g *Device) TryCreateBindGroup(descriptor *BindGroupDescriptor) (*BindGroup g.ref, errh.ToPointer(), g.ref, - desc, + &desc, ) if err := errh.ToError(); err != nil { C.wgpuBindGroupRelease(ref) @@ -213,19 +207,12 @@ func (g *Device) TryCreateBuffer(descriptor *BufferDescriptor) (*Buffer, error) } func (g *Device) TryCreateCommandEncoder(descriptor *CommandEncoderDescriptor) (*CommandEncoder, error) { - var desc *C.WGPUCommandEncoderDescriptor + var desc C.WGPUCommandEncoderDescriptor if descriptor != nil && descriptor.Label != "" { - label := C.CString(descriptor.Label) - defer C.free(unsafe.Pointer(label)) - - desc = allocWGPUCommandEncoderDescriptor.GetZeroed() - defer allocWGPUCommandEncoderDescriptor.Put(desc) - - desc.label = C.WGPUStringView{ - data: label, - length: C.WGPU_STRLEN, - } + label := stringViewOf(descriptor.Label) + defer label.Release() + desc.label = label.ToC() } errh := acquireErrorCallback() @@ -235,7 +222,7 @@ func (g *Device) TryCreateCommandEncoder(descriptor *CommandEncoderDescriptor) ( g.ref, errh.ToPointer(), g.ref, - desc, + &desc, ) if err := errh.ToError(); err != nil { C.wgpuCommandEncoderRelease(ref) diff --git a/wgpu/error-callback.go b/wgpu/error-callback.go index 8601f36..cd81d3f 100644 --- a/wgpu/error-callback.go +++ b/wgpu/error-callback.go @@ -1,18 +1,12 @@ package wgpu -import "C" import ( "errors" "runtime" "strings" ) -// #include -import "C" - -/* -#include -*/ +// #include "wgpu_go_wrappers.h" import "C" import ( diff --git a/wgpu/pools.go b/wgpu/pools.go index c970e7d..97b9233 100644 --- a/wgpu/pools.go +++ b/wgpu/pools.go @@ -1,7 +1,5 @@ package wgpu -import "C" - /* #include */ @@ -10,11 +8,6 @@ import "sync" var allocErrorCallbackValue = makeTypedPool[errorCallback]() -var allocWGPUBindGroupDescriptor = makeTypedPool[C.WGPUBindGroupDescriptor]() -var allocWGPUCommandEncoderDescriptor = makeTypedPool[C.WGPUCommandEncoderDescriptor]() -var allocWGPURenderPassDescriptor = makeTypedPool[C.WGPURenderPassDescriptor]() -var allocWGPUComputePassDescriptor = makeTypedPool[C.WGPUComputePassDescriptor]() - type typedPool[T any] sync.Pool func makeTypedPool[T any]() typedPool[T] { diff --git a/wgpu/string-view.go b/wgpu/string-view.go new file mode 100644 index 0000000..04523e0 --- /dev/null +++ b/wgpu/string-view.go @@ -0,0 +1,26 @@ +package wgpu + +// #include "wgpu_go_wrappers.h" +import "C" +import "unsafe" + +type stringView struct { + view C.WGPUStringView +} + +func stringViewOf(value string) stringView { + return stringView{ + view: C.WGPUStringView{ + data: C.CString(value), + length: C.size_t(len(value)), + }, + } +} + +func (v stringView) ToC() C.WGPUStringView { + return v.view +} + +func (v stringView) Release() { + C.free(unsafe.Pointer(v.view.data)) +} diff --git a/wgpu/texture.go b/wgpu/texture.go index 74964c9..9220e63 100644 --- a/wgpu/texture.go +++ b/wgpu/texture.go @@ -30,9 +30,9 @@ func (g *Texture) TryCreateView(descriptor *TextureViewDescriptor) (*TextureView aspect: C.WGPUTextureAspect(descriptor.Aspect), } - if descriptor.Label != "" { - desc.label = toStringView(descriptor.Label) - } + label := stringViewOf(descriptor.Label) + defer label.Release() + desc.label = label.ToC() } errh := acquireErrorCallback() diff --git a/wgpu/wgpu.go b/wgpu/wgpu.go index 3c55965..f613dbc 100644 --- a/wgpu/wgpu.go +++ b/wgpu/wgpu.go @@ -112,15 +112,15 @@ func (g *Device) addRef() C.WGPUDevice { type releaser interface{ release() } -func releaseNow[T releaser](value T) { - value.release() -} - func releaseOnGC[T releaser](value T) T { - runtime.SetFinalizer(value, releaseNow[T]) + runtime.SetFinalizer(value, releaseNow) return value } +func releaseNow(value releaser) { + value.release() +} + // cBool converts the given Go bool to a C.WGPUBool. func cBool(b bool) C.WGPUBool { if b { From c963383f85cacb44c42f4471be35e09071afd0ff Mon Sep 17 00:00:00 2001 From: Oliver Bestmann Date: Fri, 29 May 2026 07:31:07 +0200 Subject: [PATCH 3/5] wgpu: only allocate in stringView if value is not empty --- wgpu/string-view.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/wgpu/string-view.go b/wgpu/string-view.go index 04523e0..7c46899 100644 --- a/wgpu/string-view.go +++ b/wgpu/string-view.go @@ -9,6 +9,10 @@ type stringView struct { } func stringViewOf(value string) stringView { + if value == "" { + return stringView{} + } + return stringView{ view: C.WGPUStringView{ data: C.CString(value), @@ -22,5 +26,7 @@ func (v stringView) ToC() C.WGPUStringView { } func (v stringView) Release() { - C.free(unsafe.Pointer(v.view.data)) + if v.view.data { + C.free(unsafe.Pointer(v.view.data)) + } } From 69f45754606b1f8d9a557b4c5060859df7ff3585 Mon Sep 17 00:00:00 2001 From: Oliver Bestmann Date: Fri, 29 May 2026 07:32:15 +0200 Subject: [PATCH 4/5] go mod tidy --- go.mod | 7 +++++++ go.sum | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/go.mod b/go.mod index f8380b4..0e3e4d9 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,13 @@ require ( github.com/oliverbestmann/webgpu/libs-ios v0.0.0-20260509160803-765e39d2a48b github.com/oliverbestmann/webgpu/libs-linux v0.0.0-20260509160809-2fefaf7c9ead github.com/oliverbestmann/webgpu/libs-windows v0.0.0-20260509160807-0bc32b12c7bc + github.com/stretchr/testify v1.11.1 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) retract v1.27.0 // published before deciding on a version scheme. we start at v1.0.0 diff --git a/go.sum b/go.sum index 50d3c79..7dfd726 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-gl/glfw/v3.4/glfw v0.1.0-pre.1.0.20260406072232-3ac4aa2bb164 h1:c87Nyz3ox3QbCl0yozQPeVPW4mmgFOSKY4yyc1TrS0w= github.com/go-gl/glfw/v3.4/glfw v0.1.0-pre.1.0.20260406072232-3ac4aa2bb164/go.mod h1:T5Dn0JwIJOX1euPZ/iT4tq6nFYtmukjcYa7937HuYK8= github.com/oliverbestmann/webgpu/libs-android v0.0.0-20260509160813-48db59792a15 h1:HPxVSV8C8JaxGfa9hjDhzNmryoqPF3EwESBTFWpxNBo= @@ -10,3 +12,11 @@ github.com/oliverbestmann/webgpu/libs-linux v0.0.0-20260509160809-2fefaf7c9ead h github.com/oliverbestmann/webgpu/libs-linux v0.0.0-20260509160809-2fefaf7c9ead/go.mod h1:SOeo2YWe2UxWxOeAHyZtwaSXkBbP78cGnm7I+6lIWV0= github.com/oliverbestmann/webgpu/libs-windows v0.0.0-20260509160807-0bc32b12c7bc h1:YVCfgeByW1ibKniigozHCwF2wC26TDmAIJwQG40bCBM= github.com/oliverbestmann/webgpu/libs-windows v0.0.0-20260509160807-0bc32b12c7bc/go.mod h1:58qRJHG2+mjEu/AKJFh026bz3xE1zEHYt41i4TBM8NE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 39085e8fdde85a2696f83ccafb9cf3ecd85dd08e Mon Sep 17 00:00:00 2001 From: Oliver Bestmann Date: Fri, 29 May 2026 08:38:49 +0200 Subject: [PATCH 5/5] string-view: fix typo --- wgpu/string-view.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/string-view.go b/wgpu/string-view.go index 7c46899..3539a8a 100644 --- a/wgpu/string-view.go +++ b/wgpu/string-view.go @@ -26,7 +26,7 @@ func (v stringView) ToC() C.WGPUStringView { } func (v stringView) Release() { - if v.view.data { + if v.view.data != nil { C.free(unsafe.Pointer(v.view.data)) } }