From b086b4f88aba7b8dee4691686e1390c6bb489a5c Mon Sep 17 00:00:00 2001 From: dhannyell Date: Tue, 21 Jul 2026 17:30:43 -0300 Subject: [PATCH] fix(wgpu): C-allocate device descriptor to allow DeviceLostCallback RequestDevice Go-allocated the descriptor with &C.WGPUDeviceDescriptor{} and then embedded the DeviceLostCallback handle (a Go pointer, &pointers[0] from newHandle) in desc.deviceLostCallbackInfo.userdata1. Passing desc (a Go pointer to Go memory now containing a Go pointer) to C violates the cgo pointer rule and panics with 'Go pointer to unpinned Go pointer'. C-allocate desc with calloc instead, matching the pattern already used for requiredFeatures/requiredLimits/deviceExtras in the same function. The checker does not scan C memory, so the embedded Go pointer is allowed; &pointers[0] points to byte storage with no nested pointers. wgpuAdapterRequestDevice is synchronous, so freeing at function exit is safe. The nil-descriptor path is unchanged. Verified: RequestDevice with a DeviceLostCallback now succeeds instead of panicking; RequestDevice(nil) still works; three devices created/released in sequence (nil, label+callback, label+RequiredLimits+callback) all succeed; go run -race clean; go build ./wgpu/ and go vet ./wgpu/ pass. --- wgpu/adapter.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wgpu/adapter.go b/wgpu/adapter.go index 716e351..f1fd33b 100644 --- a/wgpu/adapter.go +++ b/wgpu/adapter.go @@ -129,7 +129,8 @@ func (g *Adapter) RequestDevice(descriptor *DeviceDescriptor) (*Device, error) { var desc *C.WGPUDeviceDescriptor = nil if descriptor != nil { - desc = &C.WGPUDeviceDescriptor{} + desc = (*C.WGPUDeviceDescriptor)(C.calloc(1, C.size_t(unsafe.Sizeof(C.WGPUDeviceDescriptor{})))) + defer C.free(unsafe.Pointer(desc)) if descriptor.Label != "" { label := C.CString(descriptor.Label)