diff --git a/gpu/src/NativeInstance.zig b/gpu/src/NativeInstance.zig index daa370e1..4634c6d7 100644 --- a/gpu/src/NativeInstance.zig +++ b/gpu/src/NativeInstance.zig @@ -12,14 +12,17 @@ vtable: Interface.VTable, /// Wraps a native WGPUInstance to provide an implementation of the gpu.Interface. pub fn wrap(instance: c.WGPUInstance) NativeInstance { - return .{ .instance = instance }; + return .{ + .instance = instance, + .vtable = undefined, // TODO + }; } /// Returns the gpu.Interface for interacting with this native instance. -pub fn interface(native: *const NativeInstance) Interface { +pub fn interface(native: *NativeInstance) Interface { return .{ .ptr = native, - .vtable = native.vtable, + .vtable = &native.vtable, }; // TODO: implement Interface // WGPU_EXPORT void wgpuInstanceReference(WGPUInstance instance); @@ -37,67 +40,92 @@ pub fn interface(native: *const NativeInstance) Interface { } pub fn createSurface(native: *const NativeInstance, descriptor: *const Surface.Descriptor) Surface { - // typedef enum WGPUSType { - // WGPUSType_Invalid = 0x00000000, - // WGPUSType_SurfaceDescriptorFromMetalLayer = 0x00000001, - // WGPUSType_SurfaceDescriptorFromWindowsHWND = 0x00000002, - // WGPUSType_SurfaceDescriptorFromXlibWindow = 0x00000003, - // WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector = 0x00000004, - // WGPUSType_SurfaceDescriptorFromWindowsCoreWindow = 0x00000008, - // WGPUSType_SurfaceDescriptorFromWindowsSwapChainPanel = 0x0000000B, + const surface = switch (descriptor.*) { + .metal_layer => |src| blk: { + var desc: c.WGPUSurfaceDescriptorFromMetalLayer = undefined; + desc.chain.next = null; + desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromMetalLayer; + desc.layer = src.layer; + break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ + .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), + .label = if (src.label) |l| @ptrCast([*c]const u8, l) else null, + }); + }, + .windows_hwnd => |src| blk: { + var desc: c.WGPUSurfaceDescriptorFromWindowsHWND = undefined; + desc.chain.next = null; + desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsHWND; + desc.hinstance = src.hinstance; + desc.hwnd = src.hwnd; + break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ + .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), + .label = if (src.label) |l| @ptrCast([*c]const u8, l) else null, + }); + }, + .windows_core_window => |src| blk: { + var desc: c.WGPUSurfaceDescriptorFromWindowsCoreWindow = undefined; + desc.chain.next = null; + desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsCoreWindow; + desc.coreWindow = src.core_window; + break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ + .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), + .label = if (src.label) |l| @ptrCast([*c]const u8, l) else null, + }); + }, + .windows_swap_chain_panel => |src| blk: { + var desc: c.WGPUSurfaceDescriptorFromWindowsSwapChainPanel = undefined; + desc.chain.next = null; + desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsSwapChainPanel; + desc.swapChainPanel = src.swap_chain_panel; + break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ + .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), + .label = if (src.label) |l| @ptrCast([*c]const u8, l) else null, + }); + }, + .xlib_window => |src| blk: { + var desc: c.WGPUSurfaceDescriptorFromXlibWindow = undefined; + desc.chain.next = null; + desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromXlibWindow; + desc.display = src.display; + desc.window = src.window; + break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ + .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), + .label = if (src.label) |l| @ptrCast([*c]const u8, l) else null, + }); + }, + .canvas_html_selector => |src| blk: { + var desc: c.WGPUSurfaceDescriptorFromCanvasHTMLSelector = undefined; + desc.chain.next = null; + desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector; + desc.selector = @ptrCast([*c]const u8, src.selector); + break :blk c.wgpuInstanceCreateSurface(native.instance, &c.WGPUSurfaceDescriptor{ + .nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc), + .label = if (src.label) |l| @ptrCast([*c]const u8, l) else null, + }); + }, + }; - // typedef struct WGPUSurfaceDescriptor { - // WGPUChainedStruct const * nextInChain; - // char const * label; - // } WGPUSurfaceDescriptor; - - // typedef struct WGPUSurfaceDescriptorFromCanvasHTMLSelector { - // WGPUChainedStruct chain; - // char const * selector; - // } WGPUSurfaceDescriptorFromCanvasHTMLSelector; - - // typedef struct WGPUSurfaceDescriptorFromMetalLayer { - // WGPUChainedStruct chain; - // void * layer; - // } WGPUSurfaceDescriptorFromMetalLayer; - - // typedef struct WGPUSurfaceDescriptorFromWindowsCoreWindow { - // WGPUChainedStruct chain; - // void * coreWindow; - // } WGPUSurfaceDescriptorFromWindowsCoreWindow; - - // typedef struct WGPUSurfaceDescriptorFromWindowsHWND { - // WGPUChainedStruct chain; - // void * hinstance; - // void * hwnd; - // } WGPUSurfaceDescriptorFromWindowsHWND; - - // typedef struct WGPUSurfaceDescriptorFromWindowsSwapChainPanel { - // WGPUChainedStruct chain; - // void * swapChainPanel; - // } WGPUSurfaceDescriptorFromWindowsSwapChainPanel; - - // typedef struct WGPUSurfaceDescriptorFromXlibWindow { - // WGPUChainedStruct chain; - // void * display; - // uint32_t window; - // } WGPUSurfaceDescriptorFromXlibWindow; - - //c.wgpuInstanceCreateSurface(native.instance, ) - _ = native; - _ = descriptor; - // TODO: - // WGPU_EXPORT WGPUSurface wgpuInstanceCreateSurface(WGPUInstance instance, WGPUSurfaceDescriptor const * descriptor); + return Surface{ + .ptr = surface.?, + .vtable = &surface_vtable, + }; } -// var desc: c.WGPUSurfaceDescriptorFromWindowsHWND = undefined; -// desc.chain.next = null; -// desc.chain.sType = c.WGPUSType_SurfaceDescriptorFromWindowsHWND; +const surface_vtable = Surface.VTable{ + .reference = (struct { + pub fn reference(ptr: *anyopaque) void { + c.wgpuSurfaceReference(@ptrCast(c.WGPUSurface, ptr)); + } + }).reference, + .release = (struct { + pub fn release(ptr: *anyopaque) void { + c.wgpuSurfaceRelease(@ptrCast(c.WGPUSurface, ptr)); + } + }).release, +}; -// desc.hinstance = std.os.windows.kernel32.GetModuleHandleW(null); -// desc.hwnd = glfw_native.getWin32Window(window); - -// var descriptor: c.WGPUSurfaceDescriptor = undefined; -// descriptor.nextInChain = @ptrCast(*c.WGPUChainedStruct, &desc); -// descriptor.label = "basic surface"; -// return c.wgpuInstanceCreateSurface(instance, &descriptor); +test "syntax" { + _ = wrap; + _ = interface; + _ = createSurface; +} diff --git a/gpu/src/Surface.zig b/gpu/src/Surface.zig index 16162e7b..e56b8eb8 100644 --- a/gpu/src/Surface.zig +++ b/gpu/src/Surface.zig @@ -1,5 +1,14 @@ //! A native WebGPU surface +// The type erased pointer to the Surface implementation +ptr: *anyopaque, +vtable: *const VTable, + +pub const VTable = struct { + reference: fn (ptr: *anyopaque) void, + release: fn (ptr: *anyopaque) void, +}; + pub const DescriptorTag = enum { metal_layer, windows_hwnd, @@ -37,3 +46,8 @@ pub const Descriptor = union(DescriptorTag) { selector: []const u8, }, }; + +test "syntax" { + _ = DescriptorTag; + _ = Descriptor; +} diff --git a/gpu/src/TODO b/gpu/src/TODO index b4cafc59..71e74e67 100644 --- a/gpu/src/TODO +++ b/gpu/src/TODO @@ -26,7 +26,6 @@ typedef struct WGPURenderPassEncoderImpl* WGPURenderPassEncoder; typedef struct WGPURenderPipelineImpl* WGPURenderPipeline; typedef struct WGPUSamplerImpl* WGPUSampler; typedef struct WGPUShaderModuleImpl* WGPUShaderModule; -typedef struct WGPUSurfaceImpl* WGPUSurface; typedef struct WGPUSwapChainImpl* WGPUSwapChain; typedef struct WGPUTextureImpl* WGPUTexture; typedef struct WGPUTextureViewImpl* WGPUTextureView; @@ -1275,10 +1274,6 @@ WGPU_EXPORT void wgpuShaderModuleSetLabel(WGPUShaderModule shaderModule, char co WGPU_EXPORT void wgpuShaderModuleReference(WGPUShaderModule shaderModule); WGPU_EXPORT void wgpuShaderModuleRelease(WGPUShaderModule shaderModule); -// Methods of Surface -WGPU_EXPORT void wgpuSurfaceReference(WGPUSurface surface); -WGPU_EXPORT void wgpuSurfaceRelease(WGPUSurface surface); - // Methods of SwapChain WGPU_EXPORT void wgpuSwapChainConfigure(WGPUSwapChain swapChain, WGPUTextureFormat format, WGPUTextureUsageFlags allowedUsage, uint32_t width, uint32_t height); WGPU_EXPORT WGPUTextureView wgpuSwapChainGetCurrentTextureView(WGPUSwapChain swapChain);