gpu: implement NativeInstance.createSurface

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2022-03-06 21:27:37 -07:00 committed by Stephen Gutekanst
parent 89b1f31de8
commit 368f53ece1
3 changed files with 105 additions and 68 deletions

View file

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

View file

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

View file

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