diff --git a/vendor/wgpu/.gitignore b/vendor/wgpu/.gitignore index 330d70755a6..80c337a4d4f 100644 --- a/vendor/wgpu/.gitignore +++ b/vendor/wgpu/.gitignore @@ -1,5 +1,5 @@ lib/* -!lib/.gitkeep +!lib/wgpu-windows-x86_64-msvc-release example/web/triangle.wasm example/web/wgpu.js example/web/runtime.js diff --git a/vendor/wgpu/README.md b/vendor/wgpu/README.md index 1022e85419c..8564244be91 100644 --- a/vendor/wgpu/README.md +++ b/vendor/wgpu/README.md @@ -11,8 +11,8 @@ Have a look at the `example/` directory for the rendering of a basic triangle. ## Getting the wgpu-native libraries For native support (not the browser), some libraries are required. Fortunately this is -extremely easy, just download them from the [releases on GitHub](https://github.com/gfx-rs/wgpu-native/releases/tag/v22.1.0.1), -the bindings are for v22.1.0.1 at the moment. +extremely easy, just download them from the [releases on GitHub](https://github.com/gfx-rs/wgpu-native/releases/tag/v24.0.0.2), +the bindings are for v24.0.0.2 at the moment. These are expected in the `lib` folder under the same name as they are released (just unzipped). By default it will look for a static release version (`wgpu-OS-ARCH-release.a|lib`), diff --git a/vendor/wgpu/examples/glfw/main.odin b/vendor/wgpu/examples/glfw/main.odin index b57206371ea..b6438bbc552 100644 --- a/vendor/wgpu/examples/glfw/main.odin +++ b/vendor/wgpu/examples/glfw/main.odin @@ -35,18 +35,18 @@ main :: proc() { } state.surface = os_get_surface(&state.os, state.instance) - wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, on_adapter, nil) + wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, { callback = on_adapter }) - on_adapter :: proc "c" (status: wgpu.RequestAdapterStatus, adapter: wgpu.Adapter, message: cstring, userdata: rawptr) { + on_adapter :: proc "c" (status: wgpu.RequestAdapterStatus, adapter: wgpu.Adapter, message: string, userdata1: rawptr, userdata2: rawptr) { context = state.ctx if status != .Success || adapter == nil { fmt.panicf("request adapter failure: [%v] %s", status, message) } state.adapter = adapter - wgpu.AdapterRequestDevice(adapter, nil, on_device) + wgpu.AdapterRequestDevice(adapter, nil, { callback = on_device }) } - on_device :: proc "c" (status: wgpu.RequestDeviceStatus, device: wgpu.Device, message: cstring, userdata: rawptr) { + on_device :: proc "c" (status: wgpu.RequestDeviceStatus, device: wgpu.Device, message: string, userdata1: rawptr, userdata2: rawptr) { context = state.ctx if status != .Success || device == nil { fmt.panicf("request device failure: [%v] %s", status, message) @@ -82,8 +82,8 @@ main :: proc() { }` state.module = wgpu.DeviceCreateShaderModule(state.device, &{ - nextInChain = &wgpu.ShaderModuleWGSLDescriptor{ - sType = .ShaderModuleWGSLDescriptor, + nextInChain = &wgpu.ShaderSourceWGSL{ + sType = .ShaderSourceWGSL, code = shader, }, }) @@ -130,8 +130,8 @@ frame :: proc "c" (dt: f32) { surface_texture := wgpu.SurfaceGetCurrentTexture(state.surface) switch surface_texture.status { - case .Success: - // All good, could check for `surface_texture.suboptimal` here. + case .SuccessOptimal, .SuccessSuboptimal: + // All good, could handle suboptimal here. case .Timeout, .Outdated, .Lost: // Skip this frame, and re-configure surface. if surface_texture.texture != nil { @@ -139,7 +139,7 @@ frame :: proc "c" (dt: f32) { } resize() return - case .OutOfMemory, .DeviceLost: + case .OutOfMemory, .DeviceLost, .Error: // Fatal error fmt.panicf("[triangle] get_current_texture status=%v", surface_texture.status) } diff --git a/vendor/wgpu/examples/glfw/os_glfw.odin b/vendor/wgpu/examples/glfw/os_glfw.odin index 211b1ce97d5..98407b5e2aa 100644 --- a/vendor/wgpu/examples/glfw/os_glfw.odin +++ b/vendor/wgpu/examples/glfw/os_glfw.odin @@ -23,7 +23,7 @@ os_init :: proc(os: ^OS) { } os_run :: proc(os: ^OS) { - dt: f32 + dt: f32 for !glfw.WindowShouldClose(os.window) { start := time.tick_now() diff --git a/vendor/wgpu/examples/glfw/os_js.odin b/vendor/wgpu/examples/glfw/os_js.odin index 68f9ef6725d..71c3aaeb53f 100644 --- a/vendor/wgpu/examples/glfw/os_js.odin +++ b/vendor/wgpu/examples/glfw/os_js.odin @@ -30,8 +30,8 @@ os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface { return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromCanvasHTMLSelector{ - sType = .SurfaceDescriptorFromCanvasHTMLSelector, + nextInChain = &wgpu.SurfaceSourceCanvasHTMLSelector{ + sType = .SurfaceSourceCanvasHTMLSelector, selector = "#wgpu-canvas", }, }, diff --git a/vendor/wgpu/examples/sdl2/main.odin b/vendor/wgpu/examples/sdl2/main.odin index 58e357f7a6c..2dbfc9903a1 100644 --- a/vendor/wgpu/examples/sdl2/main.odin +++ b/vendor/wgpu/examples/sdl2/main.odin @@ -35,18 +35,18 @@ main :: proc() { } state.surface = os_get_surface(&state.os, state.instance) - wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, on_adapter, nil) + wgpu.InstanceRequestAdapter(state.instance, &{ compatibleSurface = state.surface }, { callback = on_adapter }) - on_adapter :: proc "c" (status: wgpu.RequestAdapterStatus, adapter: wgpu.Adapter, message: cstring, userdata: rawptr) { + on_adapter :: proc "c" (status: wgpu.RequestAdapterStatus, adapter: wgpu.Adapter, message: string, userdata1, userdata2: rawptr) { context = state.ctx if status != .Success || adapter == nil { fmt.panicf("request adapter failure: [%v] %s", status, message) } state.adapter = adapter - wgpu.AdapterRequestDevice(adapter, nil, on_device) + wgpu.AdapterRequestDevice(adapter, nil, { callback = on_device }) } - on_device :: proc "c" (status: wgpu.RequestDeviceStatus, device: wgpu.Device, message: cstring, userdata: rawptr) { + on_device :: proc "c" (status: wgpu.RequestDeviceStatus, device: wgpu.Device, message: string, userdata1, userdata2: rawptr) { context = state.ctx if status != .Success || device == nil { fmt.panicf("request device failure: [%v] %s", status, message) @@ -82,8 +82,8 @@ main :: proc() { }` state.module = wgpu.DeviceCreateShaderModule(state.device, &{ - nextInChain = &wgpu.ShaderModuleWGSLDescriptor{ - sType = .ShaderModuleWGSLDescriptor, + nextInChain = &wgpu.ShaderSourceWGSL{ + sType = .ShaderSourceWGSL, code = shader, }, }) @@ -130,8 +130,8 @@ frame :: proc "c" (dt: f32) { surface_texture := wgpu.SurfaceGetCurrentTexture(state.surface) switch surface_texture.status { - case .Success: - // All good, could check for `surface_texture.suboptimal` here. + case .SuccessOptimal, .SuccessSuboptimal: + // All good, could handle suboptimal here. case .Timeout, .Outdated, .Lost: // Skip this frame, and re-configure surface. if surface_texture.texture != nil { @@ -139,7 +139,7 @@ frame :: proc "c" (dt: f32) { } resize() return - case .OutOfMemory, .DeviceLost: + case .OutOfMemory, .DeviceLost, .Error: // Fatal error fmt.panicf("[triangle] get_current_texture status=%v", surface_texture.status) } diff --git a/vendor/wgpu/examples/sdl2/os_js.odin b/vendor/wgpu/examples/sdl2/os_js.odin index 68f9ef6725d..71c3aaeb53f 100644 --- a/vendor/wgpu/examples/sdl2/os_js.odin +++ b/vendor/wgpu/examples/sdl2/os_js.odin @@ -30,8 +30,8 @@ os_get_surface :: proc(os: ^OS, instance: wgpu.Instance) -> wgpu.Surface { return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromCanvasHTMLSelector{ - sType = .SurfaceDescriptorFromCanvasHTMLSelector, + nextInChain = &wgpu.SurfaceSourceCanvasHTMLSelector{ + sType = .SurfaceSourceCanvasHTMLSelector, selector = "#wgpu-canvas", }, }, diff --git a/vendor/wgpu/glfwglue/glue_darwin.odin b/vendor/wgpu/glfwglue/glue_darwin.odin index c1477f4b002..fbf19e316b1 100644 --- a/vendor/wgpu/glfwglue/glue_darwin.odin +++ b/vendor/wgpu/glfwglue/glue_darwin.odin @@ -12,9 +12,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.S return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{ + nextInChain = &wgpu.SurfaceSourceMetalLayer{ chain = wgpu.ChainedStruct{ - sType = .SurfaceDescriptorFromMetalLayer, + sType = .SurfaceSourceMetalLayer, }, layer = rawptr(metal_layer), }, diff --git a/vendor/wgpu/glfwglue/glue_linux.odin b/vendor/wgpu/glfwglue/glue_linux.odin index 45d29a63875..2b99d79700e 100644 --- a/vendor/wgpu/glfwglue/glue_linux.odin +++ b/vendor/wgpu/glfwglue/glue_linux.odin @@ -11,9 +11,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.S return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{ + nextInChain = &wgpu.SurfaceSourceWaylandSurface{ chain = { - sType = .SurfaceDescriptorFromWaylandSurface, + sType = .SurfaceSourceWaylandSurface, }, display = display, surface = surface, @@ -32,9 +32,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.S return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{ + nextInChain = &wgpu.SurfaceSourceXlibWindow{ chain = { - sType = .SurfaceDescriptorFromXlibWindow, + sType = .SurfaceSourceXlibWindow, }, display = display, window = u64(window), diff --git a/vendor/wgpu/glfwglue/glue_windows.odin b/vendor/wgpu/glfwglue/glue_windows.odin index 73a933f3735..ade5ced6176 100644 --- a/vendor/wgpu/glfwglue/glue_windows.odin +++ b/vendor/wgpu/glfwglue/glue_windows.odin @@ -11,9 +11,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: glfw.WindowHandle) -> wgpu.S return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromWindowsHWND{ + nextInChain = &wgpu.SurfaceSourceWindowsHWND{ chain = wgpu.ChainedStruct{ - sType = .SurfaceDescriptorFromWindowsHWND, + sType = .SurfaceSourceWindowsHWND, }, hinstance = rawptr(hinstance), hwnd = rawptr(hwnd), diff --git a/vendor/wgpu/lib/.gitkeep b/vendor/wgpu/lib/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll new file mode 100644 index 00000000000..7fa1c839871 Binary files /dev/null and b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib new file mode 100644 index 00000000000..072c4b2342f Binary files /dev/null and b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.lib b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib similarity index 72% rename from vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.lib rename to vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib index 7c9f95c33d0..787feaede16 100644 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.lib and b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.dll b/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.dll deleted file mode 100644 index b8f782a2fd8..00000000000 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.dll and /dev/null differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.dll.lib b/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.dll.lib deleted file mode 100644 index 864b7eb5388..00000000000 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.dll.lib and /dev/null differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.pdb b/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.pdb deleted file mode 100644 index 52865e17447..00000000000 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-release/wgpu_native.pdb and /dev/null differ diff --git a/vendor/wgpu/sdl2glue/glue_darwin.odin b/vendor/wgpu/sdl2glue/glue_darwin.odin index c48b8488c79..9878c560220 100644 --- a/vendor/wgpu/sdl2glue/glue_darwin.odin +++ b/vendor/wgpu/sdl2glue/glue_darwin.odin @@ -14,9 +14,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surfac return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer{ + nextInChain = &wgpu.SurfaceSourceMetalLayer{ chain = wgpu.ChainedStruct{ - sType = .SurfaceDescriptorFromMetalLayer, + sType = .SurfaceSourceMetalLayer, }, layer = rawptr(metal_layer), }, diff --git a/vendor/wgpu/sdl2glue/glue_linux.odin b/vendor/wgpu/sdl2glue/glue_linux.odin index 58ec9049937..689d162491b 100644 --- a/vendor/wgpu/sdl2glue/glue_linux.odin +++ b/vendor/wgpu/sdl2glue/glue_linux.odin @@ -14,9 +14,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surfac return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface{ + nextInChain = &wgpu.SurfaceSourceWaylandSurface{ chain = { - sType = .SurfaceDescriptorFromWaylandSurface, + sType = .SurfaceSourceWaylandSurface, }, display = display, surface = surface, @@ -29,9 +29,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surfac return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow{ + nextInChain = &wgpu.SurfaceSourceXlibWindow{ chain = { - sType = .SurfaceDescriptorFromXlibWindow, + sType = .SurfaceSourceXlibWindow, }, display = display, window = u64(window), diff --git a/vendor/wgpu/sdl2glue/glue_windows.odin b/vendor/wgpu/sdl2glue/glue_windows.odin index a2b1437ab81..aaedc27790c 100644 --- a/vendor/wgpu/sdl2glue/glue_windows.odin +++ b/vendor/wgpu/sdl2glue/glue_windows.odin @@ -13,9 +13,9 @@ GetSurface :: proc(instance: wgpu.Instance, window: ^sdl2.Window) -> wgpu.Surfac return wgpu.InstanceCreateSurface( instance, &wgpu.SurfaceDescriptor{ - nextInChain = &wgpu.SurfaceDescriptorFromWindowsHWND{ + nextInChain = &wgpu.SurfaceSourceWindowsHWND{ chain = wgpu.ChainedStruct{ - sType = .SurfaceDescriptorFromWindowsHWND, + sType = .SurfaceSourceWindowsHWND, }, hinstance = rawptr(hinstance), hwnd = rawptr(hwnd), diff --git a/vendor/wgpu/sdl3glue/glue.odin b/vendor/wgpu/sdl3glue/glue.odin index 7d4975fb0a3..4cc59614d33 100644 --- a/vendor/wgpu/sdl3glue/glue.odin +++ b/vendor/wgpu/sdl3glue/glue.odin @@ -1,6 +1,6 @@ -#+build !linux -#+build !windows -#+build !darwin -package wgpu_sdl3_glue - -#panic("package wgpu/sdl3glue is not supported on the current target") +#+build !linux +#+build !windows +#+build !darwin +package wgpu_sdl3_glue + +#panic("package wgpu/sdl3glue is not supported on the current target") diff --git a/vendor/wgpu/sdl3glue/glue_darwin.odin b/vendor/wgpu/sdl3glue/glue_darwin.odin index 4de39b3e39b..b7c9a3b4106 100644 --- a/vendor/wgpu/sdl3glue/glue_darwin.odin +++ b/vendor/wgpu/sdl3glue/glue_darwin.odin @@ -1,18 +1,21 @@ -package wgpu_sdl3_glue - -import "vendor:sdl3" -import "vendor:wgpu" - -GetSurface :: proc(instance: wgpu.Instance, window: ^sdl3.Window) -> wgpu.Surface { - view := sdl3.Metal_CreateView(window) - metal_layer := sdl3.Metal_GetLayer(view) - return wgpu.InstanceCreateSurface( - instance, - &wgpu.SurfaceDescriptor { - nextInChain = &wgpu.SurfaceDescriptorFromMetalLayer { - chain = wgpu.ChainedStruct{sType = .SurfaceDescriptorFromMetalLayer}, - layer = metal_layer, - }, - }, - ) -} +package wgpu_sdl3_glue + +import "vendor:sdl3" +import "vendor:wgpu" + +GetSurface :: proc(instance: wgpu.Instance, window: ^sdl3.Window) -> wgpu.Surface { + view := sdl3.Metal_CreateView(window) + layer := sdl3.Metal_GetLayer(view) + + return wgpu.InstanceCreateSurface( + instance, + &wgpu.SurfaceDescriptor{ + nextInChain = &wgpu.SurfaceSourceMetalLayer{ + chain = wgpu.ChainedStruct{ + sType = .SurfaceSourceMetalLayer, + }, + layer = layer, + }, + }, + ) +} diff --git a/vendor/wgpu/sdl3glue/glue_linux.odin b/vendor/wgpu/sdl3glue/glue_linux.odin index a8dc6f180cc..8068ae7b465 100644 --- a/vendor/wgpu/sdl3glue/glue_linux.odin +++ b/vendor/wgpu/sdl3glue/glue_linux.odin @@ -1,54 +1,37 @@ -package wgpu_sdl3_glue - -import "vendor:sdl3" -import "vendor:wgpu" - - -GetSurface :: proc(instance: wgpu.Instance, window: ^sdl3.Window) -> wgpu.Surface { - switch sdl3.GetCurrentVideoDriver() { - case "x11": - display := sdl3.GetPointerProperty( - sdl3.GetWindowProperties(window), - sdl3.PROP_WINDOW_X11_DISPLAY_POINTER, - nil, - ) - x_window := sdl3.GetNumberProperty( - sdl3.GetWindowProperties(window), - sdl3.PROP_WINDOW_X11_WINDOW_NUMBER, - 0, - ) - return wgpu.InstanceCreateSurface( - instance, - &wgpu.SurfaceDescriptor { - nextInChain = &wgpu.SurfaceDescriptorFromXlibWindow { - chain = {sType = .SurfaceDescriptorFromXlibWindow}, - display = display, - window = u64(x_window), - }, - }, - ) - case "wayland": - display := sdl3.GetPointerProperty( - sdl3.GetWindowProperties(window), - sdl3.PROP_WINDOW_WAYLAND_DISPLAY_POINTER, - nil, - ) - w_surface := sdl3.GetPointerProperty( - sdl3.GetWindowProperties(window), - sdl3.PROP_WINDOW_WAYLAND_SURFACE_POINTER, - nil, - ) - return wgpu.InstanceCreateSurface( - instance, - &wgpu.SurfaceDescriptor { - nextInChain = &wgpu.SurfaceDescriptorFromWaylandSurface { - chain = {sType = .SurfaceDescriptorFromWaylandSurface}, - display = display, - surface = w_surface, - }, - }, - ) - case: - panic("wgpu sdl3 glue: unsupported platform, expected Wayland or X11") - } -} +package wgpu_sdl3_glue + +import "vendor:sdl3" +import "vendor:wgpu" + +GetSurface :: proc(instance: wgpu.Instance, window: ^sdl3.Window) -> wgpu.Surface { + switch sdl3.GetCurrentVideoDriver() { + case "wayland": + return wgpu.InstanceCreateSurface( + instance, + &wgpu.SurfaceDescriptor{ + nextInChain = &wgpu.SurfaceSourceWaylandSurface{ + chain = { + sType = .SurfaceSourceWaylandSurface, + }, + display = sdl3.GetPointerProperty(sdl3.GetWindowProperties(window), sdl3.PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nil), + surface = sdl3.GetPointerProperty(sdl3.GetWindowProperties(window), sdl3.PROP_WINDOW_WAYLAND_SURFACE_POINTER, nil), + }, + }, + ) + case "x11": + return wgpu.InstanceCreateSurface( + instance, + &wgpu.SurfaceDescriptor{ + nextInChain = &wgpu.SurfaceSourceXlibWindow{ + chain = { + sType = .SurfaceSourceXlibWindow, + }, + display = sdl3.GetPointerProperty(sdl3.GetWindowProperties(window), sdl3.PROP_WINDOW_X11_DISPLAY_POINTER, nil), + window = cast(u64)sdl3.GetNumberProperty(sdl3.GetWindowProperties(window), sdl3.PROP_WINDOW_X11_WINDOW_NUMBER, 0), + }, + }, + ) + case: + panic("wgpu sdl3 glue: unsupported video driver, expected Wayland or X11") + } +} diff --git a/vendor/wgpu/sdl3glue/glue_windows.odin b/vendor/wgpu/sdl3glue/glue_windows.odin index c114789f0c2..f5b5fd29771 100644 --- a/vendor/wgpu/sdl3glue/glue_windows.odin +++ b/vendor/wgpu/sdl3glue/glue_windows.odin @@ -1,29 +1,19 @@ -package wgpu_sdl3_glue - -import win "core:sys/windows" - -import "vendor:sdl3" -import "vendor:wgpu" - -GetSurface :: proc(instance: wgpu.Instance, window: ^sdl3.Window) -> wgpu.Surface { - hwnd := sdl3.GetPointerProperty( - sdl3.GetWindowProperties(window), - sdl3.PROP_WINDOW_WIN32_HWND_POINTER, - nil, - ) - hinstance := sdl3.GetPointerProperty( - sdl3.GetWindowProperties(window), - sdl3.PROP_WINDOW_WIN32_INSTANCE_POINTER, - nil, - ) - return wgpu.InstanceCreateSurface( - instance, - &wgpu.SurfaceDescriptor { - nextInChain = &wgpu.SurfaceDescriptorFromWindowsHWND { - chain = wgpu.ChainedStruct{sType = .SurfaceDescriptorFromWindowsHWND}, - hinstance = hinstance, - hwnd = hwnd, - }, - }, - ) -} +package wgpu_sdl3_glue + +import "vendor:sdl3" +import "vendor:wgpu" + +GetSurface :: proc(instance: wgpu.Instance, window: ^sdl3.Window) -> wgpu.Surface { + return wgpu.InstanceCreateSurface( + instance, + &wgpu.SurfaceDescriptor{ + nextInChain = &wgpu.SurfaceSourceWindowsHWND{ + chain = wgpu.ChainedStruct{ + sType = .SurfaceSourceWindowsHWND, + }, + hinstance = sdl3.GetPointerProperty(sdl3.GetWindowProperties(window), sdl3.PROP_WINDOW_WIN32_INSTANCE_POINTER, nil), + hwnd = sdl3.GetPointerProperty(sdl3.GetWindowProperties(window), sdl3.PROP_WINDOW_WIN32_HWND_POINTER, nil), + }, + }, + ) +} diff --git a/vendor/wgpu/wgpu.js b/vendor/wgpu/wgpu.js index 5e0482b6965..4816659f934 100644 --- a/vendor/wgpu/wgpu.js +++ b/vendor/wgpu/wgpu.js @@ -1,5 +1,55 @@ (function() { +const STATUS_SUCCESS = 1; +const STATUS_ERROR = 2; + +const ENUMS = { + FeatureName: [undefined, "depth-clip-control", "depth32float-stencil8", "timestamp-query", "texture-compression-bc", "texture-compression-bc-sliced-3d", "texture-compression-etc2", "texture-compression-astc", "texture-compression-astc-sliced-3d", "indirect-first-instance", "shader-f16", "rg11b10ufloat-renderable", "bgra8unorm-storage", "float32-filterable", "float32-blendable", "clip-distances", "dual-source-blending" ], + StoreOp: [undefined, "store", "discard", ], + LoadOp: [undefined, "load", "clear", ], + BufferBindingType: [null, undefined, "uniform", "storage", "read-only-storage", ], + SamplerBindingType: [null, undefined, "filtering", "non-filtering", "comparison", ], + TextureSampleType: [null, undefined, "float", "unfilterable-float", "depth", "sint", "uint", ], + TextureViewDimension: [undefined, "1d", "2d", "2d-array", "cube", "cube-array", "3d", ], + StorageTextureAccess: [null, undefined, "write-only", "read-only", "read-write", ], + TextureFormat: [undefined, "r8unorm", "r8snorm", "r8uint", "r8sint", "r16uint", "r16sint", "r16float", "rg8unorm", "rg8snorm", "rg8uint", "rg8sint", "r32float", "r32uint", "r32sint", "rg16uint", "rg16sint", "rg16float", "rgba8unorm", "rgba8unorm-srgb", "rgba8snorm", "rgba8uint", "rgba8sint", "bgra8unorm", "bgra8unorm-srgb", "rgb10a2uint", "rgb10a2unorm", "rg11b10ufloat", "rgb9e5ufloat", "rg32float", "rg32uint", "rg32sint", "rgba16uint", "rgba16sint", "rgba16float", "rgba32float", "rgba32uint", "rgba32sint", "stencil8", "depth16unorm", "depth24plus", "depth24plus-stencil8", "depth32float", "depth32float-stencil8", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", "etc2-rgb8unorm", "etc2-rgb8unorm-srgb", "etc2-rgb8a1unorm", "etc2-rgb8a1unorm-srgb", "etc2-rgba8unorm", "etc2-rgba8unorm-srgb", "eac-r11unorm", "eac-r11snorm", "eac-rg11unorm", "eac-rg11snorm", "astc-4x4-unorm", "astc-4x4-unorm-srgb", "astc-5x4-unorm", "astc-5x4-unorm-srgb", "astc-5x5-unorm", "astc-5x5-unorm-srgb", "astc-6x5-unorm", "astc-6x5-unorm-srgb", "astc-6x6-unorm", "astc-6x6-unorm-srgb", "astc-8x5-unorm", "astc-8x5-unorm-srgb", "astc-8x6-unorm", "astc-8x6-unorm-srgb", "astc-8x8-unorm", "astc-8x8-unorm-srgb", "astc-10x5-unorm", "astc-10x5-unorm-srgb", "astc-10x6-unorm", "astc-10x6-unorm-srgb", "astc-10x8-unorm", "astc-10x8-unorm-srgb", "astc-10x10-unorm", "astc-10x10-unorm-srgb", "astc-12x10-unorm", "astc-12x10-unorm-srgb", "astc-12x12-unorm", "astc-12x12-unorm-srgb", ], + QueryType: [undefined, "occlusion", "timestamp", ], + VertexStepMode: [null, undefined, "vertex", "instance", ], + VertexFormat: [undefined, "uint8", "uint8x2", "uint8x4", "sint8", "sint8x2", "sint8x4", "unorm8", "unorm8x2", "unorm8x4", "snorm8", "snorm8x2", "snorm8x4", "uint16", "uint16x2", "uint16x4", "sint16", "sint16x2", "sint16x4", "unorm16", "unorm16x2", "unorm16x4", "snorm16", "snorm16x2", "snorm16x4", "float16", "float16x2", "float16x4", "float32", "float32x2", "float32x3", "float32x4", "uint32", "uint32x2", "uint32x3", "uint32x4", "sint32", "sint32x2", "sint32x3", "sint32x4", "unorm10-10-2", "unorm8x4-bgra" ], + PrimitiveTopology: [undefined, "point-list", "line-list", "line-strip", "triangle-list", "triangle-strip", ], + IndexFormat: [undefined, "uint16", "uint32", ], + FrontFace: [undefined, "ccw", "cw", ], + CullMode: [undefined, "none", "front", "back", ], + AddressMode: [undefined, "clamp-to-edge", "repeat", "mirror-repeat", ], + FilterMode: [undefined, "nearest", "linear", ], + MipmapFilterMode: [undefined, "nearest", "linear", ], + CompareFunction: [undefined, "never", "less", "equal", "less-equal", "greater", "not-equal", "greater-equal", "always", ], + TextureDimension: [undefined, "1d", "2d", "3d", ], + ErrorType: [undefined, "no-error", "validation", "out-of-memory", "internal", "unknown", ], + WGSLLanguageFeatureName: [undefined, "readonly_and_readwrite_storage_textures", "packed_4x8_integer_dot_product", "unrestricted_pointer_parameters", "pointer_composite_access", ], + PowerPreference: [undefined, "low-power", "high-performance", ], + CompositeAlphaMode: ["auto", "opaque", "premultiplied", "unpremultiplied", "inherit", ], + StencilOperation: [undefined, "keep", "zero", "replace", "invert", "increment-clamp", "decrement-clamp", "increment-wrap", "decrement-wrap", ], + BlendOperation: ["add", "subtract", "reverse-subtract", "min", "max", ], + BlendFactor: [undefined, "zero", "one", "src", "one-minus-src", "src-alpha", "one-minus-src-alpha", "dst", "one-minus-dst", "dst-alpha", "one-minus-dst-alpha", "src-alpha-saturated", "constant", "one-minus-constant", "src1", "one-minus-src1", "src1-alpha", "one-minus-src1-alpha" ], + PresentMode: [undefined, "fifo", "fifo-relaxed", "immediate", "mailbox", ], + TextureAspect: [undefined, "all", "stencil-only", "depth-only"], + DeviceLostReason: [undefined, "unknown", "destroyed", "instance-dropped", "failed-creation"], + BufferMapState: [undefined, "unmapped", "pending", "mapped"], + OptionalBool: [false, true, undefined], + + // WARN: used with indexOf to pass to WASM, if we would pass to JS, this needs to use official naming convention (not like Odin enums) like the ones above. + BackendType: [undefined, null, "WebGPU", "D3D11", "D3D12", "Metal", "Vulkan", "OpenGL", "OpenGLES"], + AdapterType: [undefined, "DiscreteGPU", "IntegratedGPU", "CPU", "Unknown"], + RequestDeviceStatus: [undefined, "Success", "InstanceDropped", "Error", "Unknown"], + MapAsyncStatus: [undefined, "Success", "InstanceDropped", "Error", "Aborted", "Unknown"], + CreatePipelineAsyncStatus: [undefined, "Success", "InstanceDropped", "ValidationError", "InternalError", "Unknown"], + PopErrorScopeStatus: [undefined, "Success", "InstanceDropped", "EmptyStack"], + RequestAdapterStatus: [undefined, "Success", "InstanceDropped", "Unavailable", "Error", "Unknown"], + QueueWorkDoneStatus: [undefined, "Success", "InstanceDropped", "Error", "Unknown"], + CompilationInfoRequestStatus: [undefined, "Success", "InstanceDropped", "Error", "Unknown"], +}; + /** * Assumptions: * - Ability to allocate memory, set the context to allocate with using the global `wgpu.g_context` @@ -13,38 +63,33 @@ class WebGPUInterface { constructor(mem) { this.mem = mem; - this.enums = { - FeatureName: [undefined, "depth-clip-control", "depth32float-stencil8", "timestamp-query", "texture-compression-bc", "texture-compression-etc2", "texture-compression-astc", "indirect-first-instance", "shader-f16", "rg11b10ufloat-renderable", "bgra8unorm-storage", "float32-filterable", ], - StoreOp: [undefined, "store", "discard", ], - LoadOp: [undefined, "clear", "load", ], - BufferBindingType: [undefined, "uniform", "storage", "read-only-storage", ], - SamplerBindingType: [undefined, "filtering", "non-filtering", "comparison", ], - TextureSampleType: [undefined, "float", "unfilterable-float", "depth", "sint", "uint", ], - TextureViewDimension: [undefined, "1d", "2d", "2d-array", "cube", "cube-array", "3d", ], - StorageTextureAccess: [undefined, "write-only", "read-only", "read-write", ], - TextureFormat: [undefined, "r8unorm", "r8snorm", "r8uint", "r8sint", "r16uint", "r16sint", "r16float", "rg8unorm", "rg8snorm", "rg8uint", "rg8sint", "r32float", "r32uint", "r32sint", "rg16uint", "rg16sint", "rg16float", "rgba8unorm", "rgba8unorm-srgb", "rgba8snorm", "rgba8uint", "rgba8sint", "bgra8unorm", "bgra8unorm-srgb", "rgb10a2uint", "rgb10a2unorm", "rg11b10ufloat", "rgb9e5ufloat", "rg32float", "rg32uint", "rg32sint", "rgba16uint", "rgba16sint", "rgba16float", "rgba32float", "rgba32uint", "rgba32sint", "stencil8", "depth16unorm", "depth24plus", "depth24plus-stencil8", "depth32float", "depth32float-stencil8", "bc1-rgba-unorm", "bc1-rgba-unorm-srgb", "bc2-rgba-unorm", "bc2-rgba-unorm-srgb", "bc3-rgba-unorm", "bc3-rgba-unorm-srgb", "bc4-r-unorm", "bc4-r-snorm", "bc5-rg-unorm", "bc5-rg-snorm", "bc6h-rgb-ufloat", "bc6h-rgb-float", "bc7-rgba-unorm", "bc7-rgba-unorm-srgb", "etc2-rgb8unorm", "etc2-rgb8unorm-srgb", "etc2-rgb8a1unorm", "etc2-rgb8a1unorm-srgb", "etc2-rgba8unorm", "etc2-rgba8unorm-srgb", "eac-r11unorm", "eac-r11snorm", "eac-rg11unorm", "eac-rg11snorm", "astc-4x4-unorm", "astc-4x4-unorm-srgb", "astc-5x4-unorm", "astc-5x4-unorm-srgb", "astc-5x5-unorm", "astc-5x5-unorm-srgb", "astc-6x5-unorm", "astc-6x5-unorm-srgb", "astc-6x6-unorm", "astc-6x6-unorm-srgb", "astc-8x5-unorm", "astc-8x5-unorm-srgb", "astc-8x6-unorm", "astc-8x6-unorm-srgb", "astc-8x8-unorm", "astc-8x8-unorm-srgb", "astc-10x5-unorm", "astc-10x5-unorm-srgb", "astc-10x6-unorm", "astc-10x6-unorm-srgb", "astc-10x8-unorm", "astc-10x8-unorm-srgb", "astc-10x10-unorm", "astc-10x10-unorm-srgb", "astc-12x10-unorm", "astc-12x10-unorm-srgb", "astc-12x12-unorm", "astc-12x12-unorm-srgb", ], - QueryType: ["occlusion", "timestamp", ], - VertexStepMode: ["vertex", "instance", "vertex-buffer-not-used", ], - VertexFormat: [undefined, "uint8x2", "uint8x4", "sint8x2", "sint8x4", "unorm8x2", "unorm8x4", "snorm8x2", "snorm8x4", "uint16x2", "uint16x4", "sint16x2", "sint16x4", "unorm16x2", "unorm16x4", "snorm16x2", "snorm16x4", "float16x2", "float16x4", "float32", "float32x2", "float32x3", "float32x4", "uint32", "uint32x2", "uint32x3", "uint32x4", "sint32", "sint32x2", "sint32x3", "sint32x4", ], - PrimitiveTopology: ["point-list", "line-list", "line-strip", "triangle-list", "triangle-strip", ], - IndexFormat: [undefined, "uint16", "uint32", ], - FrontFace: ["ccw", "cw", ], - CullMode: ["none", "front", "back", ], - AddressMode: ["repeat", "mirror-repeat", "clamp-to-edge", ], - FilterMode: ["nearest", "linear", ], - MipmapFilterMode: ["nearest", "linear", ], - CompareFunction: [undefined, "never", "less", "less-equal", "greater", "greater-equal", "equal", "not-equal", "always", ], - TextureDimension: ["1d", "2d", "3d", ], - ErrorType: ["no-error", "validation", "out-of-memory", "internal", "unknown", "device-lost", ], - WGSLFeatureName: [undefined, "readonly_and_readwrite_storage_textures", "packed_4x8_integer_dot_product", "unrestricted_pointer_parameters", "pointer_composite_access", ], - PowerPreference: [undefined, "low-power", "high-performance", ], - CompositeAlphaMode: ["auto", "opaque", "premultiplied", "unpremultiplied", "inherit", ], - StencilOperation: ["keep", "zero", "replace", "invert", "increment-clamp", "decrement-clamp", "increment-wrap", "decrement-wrap", ], - BlendOperation: ["add", "subtract", "reverse-subtract", "min", "max", ], - BlendFactor: ["zero", "one", "src", "one-minus-src", "src-alpha", "one-minus-src-alpha", "dst", "one-minus-dst", "dst-alpha", "one-minus-dst-alpha", "src-alpha-saturated", "constant", "one-minus-constant", ], - PresentMode: ["fifo", "fifo-relaxed", "immediate", "mailbox", ], - TextureAspect: ["all", "stencil-only", "depth-only"], - DeviceLostReason: [undefined, "unknown", "destroyed"], + this.sizes = { + Color: [32, 8], + BufferBindingLayout: [24, 8], + SamplerBindingLayout: [8, 4], + TextureBindingLayout: [16, 4], + StorageTextureBindingLayout: [16, 4], + StringView: [2*this.mem.intSize, this.mem.intSize], + ConstantEntry: [this.mem.intSize === 8 ? 32 : 24, 8], + ProgrammableStageDescriptor: [8 + this.mem.intSize*4, this.mem.intSize], + VertexBufferLayout: [16 + this.mem.intSize*2, 8], + VertexAttribute: [24, 8], + VertexState: [8 + this.mem.intSize*6, this.mem.intSize], + PrimitiveState: [24, 4], + MultisampleState: [16, 4], + StencilFaceState: [16, 4], + ColorTargetState: [24, 8], + BlendComponent: [12, 4], + TexelCopyBufferLayout: [16, 8], + Origin3D: [12, 4], + QueueDescriptor: [this.mem.intSize*3, this.mem.intSize], + CallbackInfo: [20, 4], + UncapturedErrorCallbackInfo: [16, 4], + RenderPassColorAttachment: [56, 8], + BindGroupEntry: [40, 8], + BindGroupLayoutEntry: [80, 8], + Extent3D: [12, 4], + CompilationMessage: [this.mem.intSize == 8 ? 64 : 48, 8], }; /** @type {WebGPUObjectManager<{}>} */ @@ -112,6 +157,29 @@ class WebGPUInterface { /** @type {WebGPUObjectManager} */ this.textureViews = new WebGPUObjectManager("TextureView", this.mem); + + this.zeroMessageAddr = 0; + } + + struct(start) { + let offset = start; + + return (size, alignment = null) => { + if (alignment === null) { + if (Array.isArray(size)) { + [size, alignment] = size; + } else { + alignment = size; + } + } + + // Align the offset to the required boundary + offset = Math.ceil(offset / alignment) * alignment; + let currentOffset = offset; + offset += size; + + return currentOffset; + }; } /** @@ -189,18 +257,18 @@ class WebGPUInterface { */ enumeration(name, ptr) { const int = this.mem.loadI32(ptr); - this.assert(this.enums[name], `Unknown enumeration "${name}"`); - return this.enums[name][int]; + return ENUMS[name][int]; } /** * @param {GPUSupportedFeatures} features * @param {number} ptr - * @returns {BigInt|number} */ - genericEnumerateFeatures(features, ptr) { + genericGetFeatures(features, ptr) { + this.assert(ptr != 0); + const availableFeatures = []; - this.enums.FeatureName.forEach((feature, value) => { + ENUMS.FeatureName.forEach((feature, value) => { if (!feature) { return; } @@ -210,57 +278,86 @@ class WebGPUInterface { } }); - if (ptr != 0) { - for (let i = 0; i < availableFeatures.length; i += 1) { - this.mem.storeI32(ptr + (i * 4), availableFeatures[i]); - } + if (availableFeatures.length === 0) { + return; } - return this.uint(availableFeatures.length); + const featuresAddr = this.mem.exports.wgpu_alloc(availableFeatures.length * 4); + this.assert(featuresAddr != 0); + + let off = this.struct(ptr); + this.mem.storeUint(off(this.mem.intSize), availableFeatures.length); + this.mem.storeI32(off(4), featuresAddr); + + off = this.struct(featuresAddr); + for (let i = 0; i < availableFeatures.length; i += 1) { + this.mem.storeI32(off(4), availableFeatures[i]); + } } /** * @param {GPUSupportedLimits} limits * @param {number} ptr + * @returns {number} */ genericGetLimits(limits, supportedLimitsPtr) { this.assert(supportedLimitsPtr != 0); - const limitsPtr = supportedLimitsPtr + 8; - - this.mem.storeU32(limitsPtr + 0, limits.maxTextureDimension1D); - this.mem.storeU32(limitsPtr + 4, limits.maxTextureDimension2D); - this.mem.storeU32(limitsPtr + 8, limits.maxTextureDimension3D); - this.mem.storeU32(limitsPtr + 12, limits.maxTextureArrayLayers); - this.mem.storeU32(limitsPtr + 16, limits.maxBindGroups); - this.mem.storeU32(limitsPtr + 20, limits.maxBindGroupsPlusVertexBuffers); - this.mem.storeU32(limitsPtr + 24, limits.maxBindingsPerBindGroup); - this.mem.storeU32(limitsPtr + 28, limits.maxDynamicUniformBuffersPerPipelineLayout); - this.mem.storeU32(limitsPtr + 32, limits.maxDynamicStorageBuffersPerPipelineLayout); - this.mem.storeU32(limitsPtr + 36, limits.maxSampledTexturesPerShaderStage); - this.mem.storeU32(limitsPtr + 40, limits.maxSamplersPerShaderStage); - this.mem.storeU32(limitsPtr + 44, limits.maxStorageBuffersPerShaderStage); - this.mem.storeU32(limitsPtr + 48, limits.maxStorageTexturesPerShaderStage); - this.mem.storeU32(limitsPtr + 52, limits.maxUniformBuffersPerShaderStage); - this.mem.storeU64(limitsPtr + 56, limits.maxUniformBufferBindingSize); - this.mem.storeU64(limitsPtr + 64, limits.maxStorageBufferBindingSize); - this.mem.storeU32(limitsPtr + 72, limits.minUniformBufferOffsetAlignment); - this.mem.storeU32(limitsPtr + 76, limits.minStorageBufferOffsetAlignment); - this.mem.storeU32(limitsPtr + 80, limits.maxVertexBuffers); - this.mem.storeU64(limitsPtr + 88, limits.maxBufferSize); - this.mem.storeU32(limitsPtr + 96, limits.maxVertexAttributes); - this.mem.storeU32(limitsPtr + 100, limits.maxVertexBufferArrayStride); - this.mem.storeU32(limitsPtr + 104, limits.maxInterStageShaderComponents); - this.mem.storeU32(limitsPtr + 108, limits.maxInterStageShaderVariables); - this.mem.storeU32(limitsPtr + 112, limits.maxColorAttachments); - this.mem.storeU32(limitsPtr + 116, limits.maxColorAttachmentBytesPerSample); - this.mem.storeU32(limitsPtr + 120, limits.maxComputeWorkgroupStorageSize); - this.mem.storeU32(limitsPtr + 124, limits.maxComputeInvocationsPerWorkgroup); - this.mem.storeU32(limitsPtr + 128, limits.maxComputeWorkgroupSizeX); - this.mem.storeU32(limitsPtr + 132, limits.maxComputeWorkgroupSizeY); - this.mem.storeU32(limitsPtr + 136, limits.maxComputeWorkgroupSizeZ); - this.mem.storeU32(limitsPtr + 140, limits.maxComputeWorkgroupsPerDimension); - - return true; + + const off = this.struct(supportedLimitsPtr); + off(4); + + this.mem.storeU32(off(4), limits.maxTextureDimension1D); + this.mem.storeU32(off(4), limits.maxTextureDimension2D); + this.mem.storeU32(off(4), limits.maxTextureDimension3D); + this.mem.storeU32(off(4), limits.maxTextureArrayLayers); + this.mem.storeU32(off(4), limits.maxBindGroups); + this.mem.storeU32(off(4), limits.maxBindGroupsPlusVertexBuffers); + this.mem.storeU32(off(4), limits.maxBindingsPerBindGroup); + this.mem.storeU32(off(4), limits.maxDynamicUniformBuffersPerPipelineLayout); + this.mem.storeU32(off(4), limits.maxDynamicStorageBuffersPerPipelineLayout); + this.mem.storeU32(off(4), limits.maxSampledTexturesPerShaderStage); + this.mem.storeU32(off(4), limits.maxSamplersPerShaderStage); + this.mem.storeU32(off(4), limits.maxStorageBuffersPerShaderStage); + this.mem.storeU32(off(4), limits.maxStorageTexturesPerShaderStage); + this.mem.storeU32(off(4), limits.maxUniformBuffersPerShaderStage); + this.mem.storeU64(off(8), limits.maxUniformBufferBindingSize); + this.mem.storeU64(off(8), limits.maxStorageBufferBindingSize); + this.mem.storeU32(off(4), limits.minUniformBufferOffsetAlignment); + this.mem.storeU32(off(4), limits.minStorageBufferOffsetAlignment); + this.mem.storeU32(off(4), limits.maxVertexBuffers); + this.mem.storeU64(off(8), limits.maxBufferSize); + this.mem.storeU32(off(4), limits.maxVertexAttributes); + this.mem.storeU32(off(4), limits.maxVertexBufferArrayStride); + this.mem.storeU32(off(4), limits.maxInterStageShaderVariables); + this.mem.storeU32(off(4), limits.maxColorAttachments); + this.mem.storeU32(off(4), limits.maxColorAttachmentBytesPerSample); + this.mem.storeU32(off(4), limits.maxComputeWorkgroupStorageSize); + this.mem.storeU32(off(4), limits.maxComputeInvocationsPerWorkgroup); + this.mem.storeU32(off(4), limits.maxComputeWorkgroupSizeX); + this.mem.storeU32(off(4), limits.maxComputeWorkgroupSizeY); + this.mem.storeU32(off(4), limits.maxComputeWorkgroupSizeZ); + this.mem.storeU32(off(4), limits.maxComputeWorkgroupsPerDimension); + + return STATUS_SUCCESS; + } + + genericAdapterInfo(infoPtr) { + this.assert(infoPtr != 0); + + const off = this.struct(infoPtr); + off(4); // nextInChain + off(this.sizes.StringView); // vendor + off(this.sizes.StringView); // architecture + off(this.sizes.StringView); // device + off(this.sizes.StringView); // description + + this.mem.storeI32(off(4), ENUMS.BackendType.indexOf("WebGPU")); + this.mem.storeI32(off(4), ENUMS.AdapterType.indexOf("Unknown")); + + // NOTE: I don't think getting the other fields in this struct is possible. + // `adapter.requestAdapterInfo` is deprecated. + + return STATUS_SUCCESS; } /** @@ -276,7 +373,7 @@ class WebGPUInterface { * @returns {GPUFeatureName} */ FeatureName(featureInt) { - return this.enums.FeatureName[featureInt]; + return ENUMS.FeatureName[featureInt]; } /** @@ -314,39 +411,41 @@ class WebGPUInterface { return undefined; }; + const off = this.struct(start); + off(4); + return { - maxTextureDimension1D: limitU32(start + 0), - maxTextureDimension2D: limitU32(start + 4), - maxTextureDimension3D: limitU32(start + 8), - maxTextureArrayLayers: limitU32(start + 12), - maxBindGroups: limitU32(start + 16), - maxBindGroupsPlusVertexBuffers: limitU32(start + 20), - maxBindingsPerBindGroup: limitU32(start + 24), - maxDynamicUniformBuffersPerPipelineLayout: limitU32(start + 28), - maxDynamicStorageBuffersPerPipelineLayout: limitU32(start + 32), - maxSampledTexturesPerShaderStage: limitU32(start + 36), - maxSamplersPerShaderStage: limitU32(start + 40), - maxStorageBuffersPerShaderStage: limitU32(start + 44), - maxStorageTexturesPerShaderStage: limitU32(start + 48), - maxUniformBuffersPerShaderStage: limitU32(start + 52), - maxUniformBufferBindingSize: limitU64(start + 56), - maxStorageBufferBindingSize: limitU64(start + 64), - minUniformBufferOffsetAlignment: limitU32(start + 72), - minStorageBufferOffsetAlignment: limitU32(start + 76), - maxVertexBuffers: limitU32(start + 80), - maxBufferSize: limitU64(start + 88), - maxVertexAttributes: limitU32(start + 96), - maxVertexBufferArrayStride: limitU32(start + 100), - maxInterStageShaderComponents: limitU32(start + 104), - maxInterStageShaderVariables: limitU32(start + 108), - maxColorAttachments: limitU32(start + 112), - maxColorAttachmentBytesPerSample: limitU32(start + 116), - maxComputeWorkgroupStorageSize: limitU32(start + 120), - maxComputeInvocationsPerWorkgroup: limitU32(start + 124), - maxComputeWorkgroupSizeX: limitU32(start + 128), - maxComputeWorkgroupSizeY: limitU32(start + 132), - maxComputeWorkgroupSizeZ: limitU32(start + 136), - maxComputeWorkgroupsPerDimension: limitU32(start + 140), + maxTextureDimension1D: limitU32(off(4)), + maxTextureDimension2D: limitU32(off(4)), + maxTextureDimension3D: limitU32(off(4)), + maxTextureArrayLayers: limitU32(off(4)), + maxBindGroups: limitU32(off(4)), + maxBindGroupsPlusVertexBuffers: limitU32(off(4)), + maxBindingsPerBindGroup: limitU32(off(4)), + maxDynamicUniformBuffersPerPipelineLayout: limitU32(off(4)), + maxDynamicStorageBuffersPerPipelineLayout: limitU32(off(4)), + maxSampledTexturesPerShaderStage: limitU32(off(4)), + maxSamplersPerShaderStage: limitU32(off(4)), + maxStorageBuffersPerShaderStage: limitU32(off(4)), + maxStorageTexturesPerShaderStage: limitU32(off(4)), + maxUniformBuffersPerShaderStage: limitU32(off(4)), + maxUniformBufferBindingSize: limitU64(off(8)), + maxStorageBufferBindingSize: limitU64(off(8)), + minUniformBufferOffsetAlignment: limitU32(off(4)), + minStorageBufferOffsetAlignment: limitU32(off(4)), + maxVertexBuffers: limitU32(off(4)), + maxBufferSize: limitU64(off(8)), + maxVertexAttributes: limitU32(off(4)), + maxVertexBufferArrayStride: limitU32(off(4)), + maxInterStageShaderVariables: limitU32(off(4)), + maxColorAttachments: limitU32(off(4)), + maxColorAttachmentBytesPerSample: limitU32(off(4)), + maxComputeWorkgroupStorageSize: limitU32(off(4)), + maxComputeInvocationsPerWorkgroup: limitU32(off(4)), + maxComputeWorkgroupSizeX: limitU32(off(4)), + maxComputeWorkgroupSizeY: limitU32(off(4)), + maxComputeWorkgroupSizeZ: limitU32(off(4)), + maxComputeWorkgroupsPerDimension: limitU32(off(4)), }; } @@ -356,7 +455,7 @@ class WebGPUInterface { */ QueueDescriptor(start) { return { - label: this.mem.loadCstring(start + 4), + label: this.StringView(start + 4), }; } @@ -370,10 +469,11 @@ class WebGPUInterface { return undefined; } + const off = this.struct(start); return { - querySet: this.querySets.get(this.mem.loadPtr(start + 0)), - beginningOfPassWriteIndex: this.mem.loadU32(start + 4), - endOfPassWriteIndex: this.mem.loadU32(start + 8), + querySet: this.querySets.get(this.mem.loadPtr(off(4))), + beginningOfPassWriteIndex: this.mem.loadU32(off(4)), + endOfPassWriteIndex: this.mem.loadU32(off(4)), }; } @@ -382,21 +482,25 @@ class WebGPUInterface { * @returns {GPURenderPassColorAttachment} */ RenderPassColorAttachment(start) { - const viewIdx = this.mem.loadPtr(start + 4); - const resolveTargetIdx = this.mem.loadPtr(start + 12); + const off = this.struct(start); + off(4); - let depthSlice = this.mem.loadU32(start + 8); + const viewIdx = this.mem.loadPtr(off(4)); + + let depthSlice = this.mem.loadU32(off(4)); if (depthSlice == 0xFFFFFFFF) { // DEPTH_SLICE_UNDEFINED. depthSlice = undefined; } + const resolveTargetIdx = this.mem.loadPtr(off(4)); + return { view: viewIdx > 0 ? this.textureViews.get(viewIdx) : undefined, resolveTarget: resolveTargetIdx > 0 ? this.textureViews.get(resolveTargetIdx) : undefined, depthSlice: depthSlice, - loadOp: this.enumeration("LoadOp", start + 16), - storeOp: this.enumeration("StoreOp", start + 20), - clearValue: this.Color(start + 24), + loadOp: this.enumeration("LoadOp", off(4)), + storeOp: this.enumeration("StoreOp", off(4)), + clearValue: this.Color(off(this.sizes.Color)), }; } @@ -405,11 +509,12 @@ class WebGPUInterface { * @returns {GPUColor} */ Color(start) { + const off = this.struct(start); return { - r: this.mem.loadF64(start + 0), - g: this.mem.loadF64(start + 8), - b: this.mem.loadF64(start + 16), - a: this.mem.loadF64(start + 24), + r: this.mem.loadF64(off(8)), + g: this.mem.loadF64(off(8)), + b: this.mem.loadF64(off(8)), + a: this.mem.loadF64(off(8)), }; } @@ -423,16 +528,18 @@ class WebGPUInterface { return undefined; } + const off = this.struct(ptr); + return { - view: this.textureViews.get(this.mem.loadPtr(start + 0)), - depthLoadOp: this.enumeration("LoadOp", start + 4), - depthStoreOp: this.enumeration("StoreOp", start + 8), - depthClearValue: this.mem.loadF32(start + 12), - depthReadOnly: this.mem.loadB32(start + 16), - stencilLoadOp: this.enumeration("LoadOp", start + 20), - stencilStoreOp: this.enumeration("StoreOp", start + 24), - stencilClearValue: this.mem.loadF32(start + 28), - stencilReadOnly: this.mem.loadB32(start + 32), + view: this.textureViews.get(this.mem.loadPtr(off(4))), + depthLoadOp: this.enumeration("LoadOp", off(4)), + depthStoreOp: this.enumeration("StoreOp", off(4)), + depthClearValue: this.mem.loadF32(off(4)), + depthReadOnly: this.mem.loadB32(off(4)), + stencilLoadOp: this.enumeration("LoadOp", off(4)), + stencilStoreOp: this.enumeration("StoreOp", off(4)), + stencilClearValue: this.mem.loadF32(off(4)), + stencilReadOnly: this.mem.loadB32(off(4)), }; } @@ -457,42 +564,6 @@ class WebGPUInterface { return this.ComputePassTimestampWritesPtr(ptr); } - /** - * @param {number} start - * @returns {GPUImageDataLayout} - */ - TextureDataLayout(start) { - return { - offset: this.mem.loadU64(start + 8), - bytesPerRow: this.mem.loadU32(start + 16), - rowsPerImage: this.mem.loadU32(start + 20), - }; - } - - /** - * @param {number} start - * @returns {GPUImageCopyBuffer} - */ - ImageCopyBuffer(start) { - return { - ...this.TextureDataLayout(start + 8), - buffer: this.buffers.get(this.mem.loadPtr(start + 32)).buffer, - }; - } - - /** - * @param {number} start - * @returns {GPUImageCopyTexture} - */ - ImageCopyTexture(start) { - return { - texture: this.textures.get(this.mem.loadPtr(start + 4)), - mipLevel: this.mem.loadU32(start + 8), - origin: this.Origin3D(start + 12), - aspect: this.enumeration("TextureAspect", start + 24), - }; - } - /** * @param {number} start * @returns {GPUOrigin3D} @@ -551,13 +622,16 @@ class WebGPUInterface { * @returns {GPUBindGroupLayoutEntry} */ BindGroupLayoutEntry(start) { + const off = this.struct(start); + off(4); + const entry = { - binding: this.mem.loadU32(start + 4), - visibility: this.mem.loadU32(start + 8), - buffer: this.BufferBindingLayout(start + 16), - sampler: this.SamplerBindingLayout(start + 40), - texture: this.TextureBindingLayout(start + 48), - storageTexture: this.StorageTextureBindingLayout(start + 64), + binding: this.mem.loadU32(off(4)), + visibility: this.mem.loadU64(off(8)), + buffer: this.BufferBindingLayout(off(this.sizes.BufferBindingLayout)), + sampler: this.SamplerBindingLayout(off(this.sizes.SamplerBindingLayout)), + texture: this.TextureBindingLayout(off(this.sizes.TextureBindingLayout)), + storageTexture: this.StorageTextureBindingLayout(off(this.sizes.StorageTextureBindingLayout)), }; if (!entry.buffer.type) { entry.buffer = undefined; @@ -625,15 +699,22 @@ class WebGPUInterface { * @returns {GPUProgrammableStage} */ ProgrammableStageDescriptor(start) { + const off = this.struct(start); + off(4); + + const shaderModule = this.shaderModules.get(this.mem.loadPtr(off(4))); + const entryPoint = this.StringView(off(this.sizes.StringView)); + const constantsArray = this.array( - this.mem.loadUint(start + 8 + this.mem.intSize), - this.mem.loadPtr(start + 8 + this.mem.intSize*2), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.ConstantEntry, - 16, + this.sizes.ConstantEntry[0], ); + return { - module: this.shaderModules.get(this.mem.loadPtr(start + 4)), - entryPoint: this.mem.loadCstring(start + 8), + module: shaderModule, + entryPoint: entryPoint, constants: constantsArray.reduce((prev, curr) => { prev[curr.key] = curr.value; return prev; @@ -646,9 +727,12 @@ class WebGPUInterface { * @returns {{ key: string, value: number }} */ ConstantEntry(start) { + const off = this.struct(start); + off(4); + return { - key: this.mem.loadCstring(start + 4), - value: this.mem.loadF64(start + 8), + key: this.StringView(off(this.sizes.StringView)), + value: this.mem.loadF64(off(8)), }; } @@ -657,11 +741,15 @@ class WebGPUInterface { * @returns {GPUComputePipelineDescriptor} */ ComputePipelineDescriptor(start) { - const layoutIdx = this.mem.loadPtr(start + 8) + const off = this.struct(start); + off(4); + + const label = this.StringView(off(this.sizes.StringView)); + const layoutIdx = this.mem.loadPtr(off(4)); return { - label: this.mem.loadCstring(start + 4), - layout: layoutIdx > 0 ? this.pipelineLayouts.get(layoutIdx) : undefined, - compute: this.ProgrammableStageDescriptor(start + 8 + this.mem.intSize), + label: label, + layout: layoutIdx > 0 ? this.pipelineLayouts.get(layoutIdx) : "auto", + compute: this.ProgrammableStageDescriptor(off(this.sizes.ProgrammableStageDescriptor)), }; } @@ -670,28 +758,31 @@ class WebGPUInterface { * @returns {GPUVertexState} */ VertexState(start) { - let off = 8 + this.mem.intSize; + const off = this.struct(start); + off(4); + + const shaderModuleIdx = this.mem.loadPtr(off(4)); + const entryPoint = this.StringView(off(this.sizes.StringView)); + const constantsArray = this.array( - this.mem.loadUint(start + off), - this.mem.loadPtr(start + off + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.ConstantEntry, - 16, + this.sizes.ConstantEntry[0], ); - off += this.mem.intSize * 2; - return { - module: this.shaderModules.get(this.mem.loadPtr(start + 4)), - entryPoint: this.mem.loadCstring(start + 8), + module: this.shaderModules.get(shaderModuleIdx), + entryPoint: entryPoint, constants: constantsArray.reduce((prev, curr) => { prev[curr.key] = curr.value; return prev; }, {}), buffers: this.array( - this.mem.loadUint(start + off), - this.mem.loadPtr(start + off + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.VertexBufferLayout, - this.mem.intSize == 8 ? 32 : 24, + this.sizes.VertexBufferLayout[0], ), }; } @@ -701,18 +792,21 @@ class WebGPUInterface { * @returns {?GPUVertexBufferLayout} */ VertexBufferLayout(start) { - const stepMode = this.enumeration("VertexStepMode", start + 8); - if (stepMode == "vertex-buffer-not-used") { + const off = this.struct(start); + + const stepMode = this.enumeration("VertexStepMode", off(4)); + if (stepMode == null) { return null; } + return { - arrayStride: this.mem.loadU64(start + 0), + arrayStride: this.mem.loadU64(off(8)), stepMode: stepMode, attributes: this.array( - this.mem.loadUint(start + 8 + this.mem.intSize), - this.mem.loadPtr(start + 8 + this.mem.intSize*2), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.VertexAttribute, - 24, + this.sizes.VertexAttribute[0], ), }; } @@ -722,10 +816,11 @@ class WebGPUInterface { * @returns {GPUVertexAttribute} */ VertexAttribute(start) { + const off = this.struct(start); return { - format: this.enumeration("VertexFormat", start + 0), - offset: this.mem.loadU64(start + 8), - shaderLocation: this.mem.loadU32(start + 16), + format: this.enumeration("VertexFormat", off(4)), + offset: this.mem.loadU64(off(8)), + shaderLocation: this.mem.loadU32(off(4)), }; } @@ -734,22 +829,15 @@ class WebGPUInterface { * @returns {GPUPrimitiveState} */ PrimitiveState(start) { - let unclippedDepth = undefined; - const nextInChain = this.mem.loadPtr(start); - if (nextInChain != 0) { - const nextInChainType = this.mem.loadI32(nextInChain + 4); - // PrimitiveDepthClipControl = 0x00000007, - if (nextInChainType == 7) { - unclippedDepth = this.mem.loadB32(nextInChain + 8); - } - } + const off = this.struct(start); + off(4); return { - topology: this.enumeration("PrimitiveTopology", start + 4), - stripIndexFormat: this.enumeration("IndexFormat", start + 8), - frontFace: this.enumeration("FrontFace", start + 12), - cullMode: this.enumeration("CullMode", start + 16), - unclippedDepth: unclippedDepth, + topology: this.enumeration("PrimitiveTopology", off(4)), + stripIndexFormat: this.enumeration("IndexFormat", off(4)), + frontFace: this.enumeration("FrontFace", off(4)), + cullMode: this.enumeration("CullMode", off(4)), + unclippedDepth: this.mem.loadB32(off(4)), }; } @@ -758,27 +846,19 @@ class WebGPUInterface { * @returns {GPURenderPipelineDescriptor} */ RenderPipelineDescriptor(start) { - const layoutIdx = this.mem.loadPtr(start + 8); - const offs = this.mem.intSize == 8 ? [64, 84, 88, 104] : [40, 60, 64, 80]; - return { - label: this.mem.loadCstring(start + 4), - layout: layoutIdx > 0 ? this.pipelineLayouts.get(layoutIdx) : undefined, - vertex: this.VertexState(start + 8 + this.mem.intSize), - primitive: this.PrimitiveState(start + offs[0]), - depthStencil: this.DepthStencilStatePtr(start + offs[1]), - multisample: this.MultisampleState(start + offs[2]), - fragment: this.FragmentStatePtr(start + offs[3]), - }; - } + const off = this.struct(start); + off(4); - /** - * @param {number} start - * @returns {GPUShaderModuleCompilationHint} - */ - ShaderModuleCompilationHint(start) { + const label = this.StringView(off(this.sizes.StringView)); + const layoutIdx = this.mem.loadPtr(off(4)); return { - entryPoint: this.mem.loadCstring(start + 4), - layout: this.pipelineLayouts.get(this.mem.loadPtr(start + 8)), + label: label, + layout: layoutIdx > 0 ? this.pipelineLayouts.get(layoutIdx) : "auto", + vertex: this.VertexState(off(this.sizes.VertexState)), + primitive: this.PrimitiveState(off(this.sizes.PrimitiveState)), + depthStencil: this.DepthStencilStatePtr(off(4)), + multisample: this.MultisampleState(off(this.sizes.MultisampleState)), + fragment: this.FragmentStatePtr(off(4)), }; } @@ -792,17 +872,20 @@ class WebGPUInterface { return undefined; } + const off = this.struct(start); + off(4); + return { - format: this.enumeration("TextureFormat", start + 4), - depthWriteEnabled: this.mem.loadB32(start + 8), - depthCompare: this.enumeration("CompareFunction", start + 12), - stencilFront: this.StencilFaceState(start + 16), - stencilBack: this.StencilFaceState(start + 32), - stencilReadMask: this.mem.loadU32(start + 48), - stencilWriteMask: this.mem.loadU32(start + 52), - depthBias: this.mem.loadI32(start + 56), - depthBiasSlopeScale: this.mem.loadF32(start + 60), - depthBiasClamp: this.mem.loadF32(start + 64), + format: this.enumeration("TextureFormat", off(4)), + depthWriteEnabled: this.enumeration("OptionalBool", off(4)), + depthCompare: this.enumeration("CompareFunction", off(4)), + stencilFront: this.StencilFaceState(off(this.sizes.StencilFaceState)), + stencilBack: this.StencilFaceState(off(this.sizes.StencilFaceState)), + stencilReadMask: this.mem.loadU32(off(4)), + stencilWriteMask: this.mem.loadU32(off(4)), + depthBias: this.mem.loadI32(off(4)), + depthBiasSlopeScale: this.mem.loadF32(off(4)), + depthBiasClamp: this.mem.loadF32(off(4)), }; } @@ -841,29 +924,31 @@ class WebGPUInterface { return undefined; } - let off = 8 + this.mem.intSize; + const off = this.struct(start); + off(4); + + const shaderModule = this.shaderModules.get(this.mem.loadPtr(off(4))); + const entryPoint = this.StringView(off(this.sizes.StringView)); const constantsArray = this.array( - this.mem.loadUint(start + off), - this.mem.loadPtr(start + off + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.ConstantEntry, - 16, + this.sizes.ConstantEntry[0], ); - off += this.mem.intSize * 2; - return { - module: this.shaderModules.get(this.mem.loadPtr(start + 4)), - entryPoint: this.mem.loadCstring(start + 8), + module: shaderModule, + entryPoint: entryPoint, constants: constantsArray.reduce((prev, curr) => { prev[curr.key] = curr.value; return prev; }, {}), targets: this.array( - this.mem.loadUint(start + off), - this.mem.loadPtr(start + off + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.ColorTargetState, - 16, + this.sizes.ColorTargetState[0], ), }; } @@ -873,10 +958,12 @@ class WebGPUInterface { * @returns {GPUColorTargetState} */ ColorTargetState(start) { + const off = this.struct(start); + off(4); return { - format: this.enumeration("TextureFormat", start + 4), - blend: this.BlendStatePtr(start + 8), - writeMask: this.mem.loadU32(start + 12), + format: this.enumeration("TextureFormat", off(4)), + blend: this.BlendStatePtr(off(4)), + writeMask: this.mem.loadU64(off(8)), }; } @@ -890,9 +977,11 @@ class WebGPUInterface { return undefined; } + const off = this.struct(start); + return { - color: this.BlendComponent(start + 0), - alpha: this.BlendComponent(start + 12), + color: this.BlendComponent(off(this.sizes.BlendComponent)), + alpha: this.BlendComponent(off(this.sizes.BlendComponent)), }; } @@ -908,6 +997,108 @@ class WebGPUInterface { }; } + TexelCopyBufferInfo(start) { + const off = this.struct(start); + const layout = this.TexelCopyBufferLayout(off(this.sizes.TexelCopyBufferLayout)); + const bufferIdx = this.mem.loadPtr(off(4)); + return { + buffer: this.buffers.get(bufferIdx).buffer, + offset: layout.offset, + bytesPerRow: layout.bytesPerRow, + rowsPerImage: layout.rowsPerImage, + }; + } + + TexelCopyBufferLayout(start) { + const off = this.struct(start); + return { + offset: this.mem.loadU64(off(8)), + bytesPerRow: this.mem.loadU32(off(4)), + rowsPerImage: this.mem.loadU32(off(4)), + }; + } + + TexelCopyTextureInfo(start) { + const off = this.struct(start); + return { + texture: this.textures.get(this.mem.loadPtr(off(4))), + mipLevel: this.mem.loadU32(off(4)), + origin: this.Origin3D(off(this.sizes.Origin3D)), + aspect: this.enumeration("TextureAspect", off(4)), + }; + } + + StringView(start) { + const data = this.mem.loadPtr(start); + return this.mem.loadString(data, this.mem.loadUint(start + this.mem.intSize)); + } + + CallbackInfoPtr(ptr) { + const start = this.mem.loadPtr(ptr); + if (start === 0) { + return null; + } + + return CallbackInfo(start); + } + + CallbackInfo(start) { + const off = this.struct(start); + off(4); + // TODO: callback mode? + off(4); + return { + callback: this.mem.exports.__indirect_function_table.get(this.mem.loadPtr(off(4))), + userdata1: this.mem.loadPtr(off(4)), + userdata2: this.mem.loadPtr(off(4)), + }; + } + + UncapturedErrorCallbackInfo(start) { + const off = this.struct(start); + off(4); + return { + callback: this.mem.exports.__indirect_function_table.get(this.mem.loadPtr(off(4))), + userdata1: this.mem.loadPtr(off(4)), + userdata2: this.mem.loadPtr(off(4)), + }; + } + + callCallback(callback, args) { + args.push(callback.userdata1); + args.push(callback.userdata2); + callback.callback(...args); + } + + zeroMessageArg() { + if (this.zeroMessageAddr > 0) { + return this.zeroMessageAddr; + } + + this.zeroMessageAddr = this.mem.exports.wgpu_alloc(this.sizes.StringView[0]); + return this.zeroMessageAddr; + } + + makeMessageArg(message) { + if (message.length == 0) { + return this.zeroMessageArg(); + } + + const messageLength = new TextEncoder().encode(message).length; + const stringSize = this.sizes.StringView[0]; + + const addr = this.mem.exports.wgpu_alloc(stringSize + messageLength); + + const messageAddr = addr + stringSize; + + this.mem.storeI32(addr, messageAddr); + this.mem.storeUint(addr + this.mem.intSize, messageLength); + + this.mem.storeString(messageAddr, message); + + return addr; + } + getInterface() { return { /** @@ -920,15 +1111,26 @@ class WebGPUInterface { return 0; } + // TODO: instance capabilities for futures? + return this.instances.create({}); }, /** - * @param {number} deviceIdx + * @param {number} capabilitiesPtr + * @returns {number} + */ + wgpuGetInstanceCapabilities: (capabilitiesPtr) => { + // TODO: implement (futures). + return STATUS_ERROR; + }, + + /** * @param {number} procNamePtr + * @param {number} procNameLen * @returns {number} */ - wgpuGetProcAddress: (deviceIdx, procNamePtr) => { + wgpuGetProcAddress: (procNamePtr, procNameLen) => { console.error(`unimplemented: wgpuGetProcAddress`); return 0; }, @@ -938,44 +1140,29 @@ class WebGPUInterface { /** * @param {number} adapterIdx * @param {number} featuresPtr - * @returns {number|BigInt} */ - wgpuAdapterEnumerateFeatures: (adapterIdx, featuresPtr) => { + wgpuAdapterGetFeatures: (adapterIdx, featuresPtr) => { const adapter = this.adapters.get(adapterIdx); - return this.genericEnumerateFeatures(adapter.features, featuresPtr); - }, - - /** - * @param {number} adapterIdx - * @param {number} supportedLimitsPtr - * @returns {boolean} - */ - wgpuAdapterGetLimits: (adapterIdx, supportedLimitsPtr) => { - const adapter = this.adapters.get(adapterIdx); - return this.genericGetLimits(adapter.limits, supportedLimitsPtr); + this.genericGetFeatures(adapter.features, featuresPtr); }, /** * @param {number} adapterIdx * @param {number} infoPtr + * @returns {number} */ wgpuAdapterGetInfo: (adapterIdx, infoPtr) => { - this.assert(infoPtr != 0); - - // WebGPU backend. - this.mem.storeI32(infoPtr + 20, 2); - // Unknown adapter. - this.mem.storeI32(infoPtr + 24, 3); - - // NOTE: I don't think getting the other fields in this struct is possible. - // `adapter.requestAdapterInfo` is deprecated. + return this.genericGetAdapterInfo(infoPtr); }, /** - * @param {number} infoPtr + * @param {number} adapterIdx + * @param {number} limitsPtr + * @returns {number} */ - wgpuAdapterInfoFreeMembers: (infoPtr) => { - // NOTE: nothing to free. + wgpuAdapterGetLimits: (adapterIdx, limitsPtr) => { + const adapter = this.adapters.get(adapterIdx); + return this.genericGetLimits(adapter.limits, limitsPtr); }, /** @@ -985,105 +1172,96 @@ class WebGPUInterface { */ wgpuAdapterHasFeature: (adapterIdx, featureInt) => { const adapter = this.adapters.get(adapterIdx); - return adapter.features.has(this.enums.FeatureName[featureInt]); + return adapter.features.has(ENUMS.FeatureName[featureInt]); }, /** * @param {number} adapterIdx * @param {0|number} descriptorPtr - * @param {number} callbackPtr - * @param {0|number} userdata + * @param {number} callbackInfoPtr + * @return {number} */ - wgpuAdapterRequestDevice: async (adapterIdx, descriptorPtr, callbackPtr, userdata) => { + wgpuAdapterRequestDevice: (adapterIdx, descriptorPtr, callbackInfoPtr) => { const adapter = this.adapters.get(adapterIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); + + const off = this.struct(descriptorPtr); + off(4); /** @type {GPUDeviceDescriptor} */ let descriptor; if (descriptorPtr != 0) { descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(off(this.sizes.StringView)), requiredFeatures: this.array( - this.mem.loadUint(descriptorPtr + 8), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.FeatureNamePtr, 4, ), - requiredLimits: this.RequiredLimitsPtr(descriptorPtr + 8 + this.mem.intSize + 4), - defaultQueue: this.QueueDescriptor( descriptorPtr + 8 + this.mem.intSize + 4 + 4), + requiredLimits: this.RequiredLimitsPtr(off(4)), + defaultQueue: this.QueueDescriptor(off(this.sizes.QueueDescriptor)), }; } - let device; - let deviceIdx; - try { - device = await adapter.requestDevice(descriptor); - deviceIdx = this.devices.create(device); - // NOTE: don't callback here, any errors that happen later will then be caught by the catch here. - } catch (e) { - const messageLength = new TextEncoder().encode(e.message).length; - const messageAddr = this.mem.exports.wgpu_alloc(messageLength + 1); - this.mem.storeString(messageAddr, e.message); - - callback(1, null, messageAddr, userdata); - - this.mem.exports.wgpu_free(messageAddr); - } - - let callbacksPtr = descriptorPtr + 24 + this.mem.intSize; - - const deviceLostCallbackPtr = this.mem.loadPtr(callbacksPtr); - if (deviceLostCallbackPtr != 0) { - const deviceLostUserData = this.mem.loadPtr(callbacksPtr) + 4; - const deviceLostCallback = this.mem.exports.__indirect_function_table.get(deviceLostCallbackPtr); + const callbackInfo = this.CallbackInfo(callbackInfoPtr); - device.lost.then((info) => { - const reason = this.enums.DeviceLostReason.indexOf(info.reason); - - const messageLength = new TextEncoder().encode(info.message).length; - const messageAddr = this.mem.exports.wgpu_alloc(messageLength + 1); - this.mem.storeString(messageAddr, info.message); - - deviceLostCallback(reason, messageAddr, deviceLostUserData); + const deviceLostCallbackInfo = this.CallbackInfo(off(this.sizes.CallbackInfo)); + const uncapturedErrorCallbackInfo = this.UncapturedErrorCallbackInfo(off(this.sizes.UncapturedErrorCallbackInfo)); + adapter.requestDevice(descriptor) + .catch((e) => { + const messageAddr = this.makeMessageArg(e.message); + this.callCallback(callbackInfo, [ENUMS.RequestDeviceStatus.indexOf("Error"), messageAddr]); this.mem.exports.wgpu_free(messageAddr); - }); - } - callbacksPtr += 8; - - // Skip over `nextInChain`. - callbacksPtr += 4; - - const uncapturedErrorCallbackPtr = this.mem.loadPtr(callbacksPtr); - if (uncapturedErrorCallbackPtr != 0) { - const uncapturedErrorUserData = this.mem.loadPtr(callbacksPtr + 4); - const uncapturedErrorCallback = this.mem.exports.__indirect_function_table.get(uncapturedErrorCallbackPtr); - - device.onuncapturederror = (ev) => { - let status = 4; // Unknown - if (ev.error instanceof GPUValidationError) { - status = 1; // Validation - } else if (ev.error instanceof GPUOutOfMemoryError) { - status = 2; // OutOfMemory - } else if (ev.error instanceof GPUInternalError) { - status = 3; // Internal + }) + .then((device) => { + const deviceIdx = this.devices.create(device); + + const deviceLostCallbackInfo = off(this.sizes.CallbackInfo); + if (descriptorPtr !== 0 && deviceLostCallbackInfo !== null) { + device.lost.then((info) => { + const reason = ENUMS.DeviceLostReason.indexOf(info.reason); + const messageAddr = this.makeMessageArg(info.message); + this.callCallback(deviceLostCallbackInfo, [deviceIdx, reason, messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }); } - const messageLength = new TextEncoder().encode(ev.error.message).length; - const messageAddr = this.mem.exports.wgpu_alloc(messageLength + 1); - this.mem.storeString(messageAddr, ev.error.message); - - uncapturedErrorCallback(status, messageAddr, uncapturedErrorUserData); + if (descriptorPtr !== 0 && uncapturedErrorCallbackInfo !== null) { + device.onuncapturederror = (ev) => { + let status; + if (ev.error instanceof GPUValidationError) { + status = ENUMS.ErrorType.indexOf("validation"); + } else if (ev.error instanceof GPUOutOfMemoryError) { + status = ENUMS.ErrorType.indexOf("out-of-memory"); + } else if (ev.error instanceof GPUInternalError) { + status = ENUMS.ErrorType.indexOf("internal"); + } else { + status = ENUMS.ErrorType.indexOf("unknown"); + } + + const messageAddr = this.makeMessageArg(ev.error.message); + this.callCallback(uncapturedErrorCallbackInfo, [deviceIdx, status, messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }; + } - this.mem.exports.wgpu_free(messageAddr); - }; - } + this.callCallback(callbackInfo, [ENUMS.ErrorType.indexOf("no-error"), deviceIdx, this.zeroMessageArg()]); + }); - callback(0, deviceIdx, null, userdata); + // TODO: returning a future? WARN that requires refactor removing await + return BigInt(0); }, ...this.adapters.interface(), + /** + * @param {number} infoPtr + */ + wgpuAdapterInfoFreeMembers: (infoPtr) => { + // NOTE: nothing to free. + }, + /* ---------------------- BindGroup ---------------------- */ ...this.bindGroups.interface(true), @@ -1100,6 +1278,41 @@ class WebGPUInterface { buffer.buffer.destroy(); }, + /** + * @param {number} bufferIdx + * @param {number|BigInt} offset + * @param {number|BigInt} size + * @returns {number} + */ + wgpuBufferGetConstMappedRange: (bufferIdx, offset, size) => { + const buffer = this.buffers.get(bufferIdx); + offset = this.unwrapBigInt(offset); + size = this.unwrapBigInt(size); + + // TODO: does constMappedRange need to do something else? + + this.assert(!buffer.mapping, "buffer already mapped"); + + const range = buffer.buffer.getMappedRange(offset, size); + + const ptr = this.mem.exports.wgpu_alloc(range.byteLength); + + const mapping = new Uint8Array(this.mem.memory.buffer, ptr, size); + mapping.set(new Uint8Array(range)); + + buffer.mapping = { range: range, ptr: ptr, size: range.byteLength }; + return ptr; + }, + + /** + * @param {number} bufferIdx + * @return {number} + */ + wgpuBufferGetMapState: (bufferIdx) => { + const buffer = this.buffers.get(bufferIdx); + return ENUMS.BufferMapState.indexOf(buffer.mapState); + }, + /** * @param {number} bufferIdx * @param {number|BigInt} offset @@ -1117,6 +1330,9 @@ class WebGPUInterface { const ptr = this.mem.exports.wgpu_alloc(range.byteLength); + const mapping = new Uint8Array(this.mem.memory.buffer, ptr, size); + mapping.set(new Uint8Array(range)); + buffer.mapping = { range: range, ptr: ptr, size: range.byteLength }; return ptr; }, @@ -1144,44 +1360,38 @@ class WebGPUInterface { * @param {number} mode * @param {number|BigInt} offset * @param {number|BigInt} size - * @param {number} callbackPtr - * @param {0|number} userdata + * @param {number} callbackInfo + * @return {number} */ - wgpuBufferMapAsync: async (bufferIdx, mode, offset, size, callbackPtr, userdata) => { + wgpuBufferMapAsync: (bufferIdx, mode, offset, size, callbackInfoPtr) => { const buffer = this.buffers.get(bufferIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); + mode = this.unwrapBigInt(mode); offset = this.unwrapBigInt(offset); size = this.unwrapBigInt(size); - if (buffer.buffer.mapState == "pending") { - callback(this.enums.BufferMapAsyncStatus.MappingAlreadyPending, userdata); - } else { - let result; - try { - await buffer.buffer.mapAsync(mode, offset, size); - result = 0; // Success. - } catch(e) { - console.warn(e); - result = 2; // Unknown error. - - if (e instanceof DomException) { - if (e.name == "OperationError") { - result = 1; // Validation error. - } - } - } + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + buffer.buffer.mapAsync(mode, offset, size) + .catch((e) => { + const messageAddr = this.makeMessageArg(e.message); + this.callCallback(callbackInfo, [ENUMS.MapAsyncStatus.indexOf("Error"), messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }) + .then(() => { + this.callCallback(callbackInfo, [ENUMS.MapAsyncStatus.indexOf("Success"), this.zeroMessageArg()]); + }); - callback(result, userdata); - } + // TODO: returning a future? WARN that requires refactor removing await + return BigInt(0); }, /** * @param {number} bufferIdx * @param {number} labelPtr + * @param {number} labelLen */ - wgpuBufferSetLabel: (bufferIdx, labelPtr) => { + wgpuBufferSetLabel: (bufferIdx, labelPtr, labelLen) => { const buffer = this.buffers.get(bufferIdx); - buffer.buffer.label = this.mem.loadCstringDirect(labelPtr); + buffer.buffer.label = this.mem.loadString(labelPtr, labelLen); }, /** @@ -1219,9 +1429,11 @@ class WebGPUInterface { /** @type {?GPUComputePassDescriptor} */ let descriptor; if (descriptorPtr != 0) { + const off = this.struct(descriptorPtr); + off(4); descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - timestampWrites: this.ComputePassTimestampWritesPtr(descriptorPtr + 8), + label: this.StringView(off(this.sizes.StringView)), + timestampWrites: this.ComputePassTimestampWritesPtr(off(4)), }; } @@ -1238,28 +1450,30 @@ class WebGPUInterface { const commandEncoder = this.commandEncoders.get(commandEncoderIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + let maxDrawCount = undefined; - const nextInChain = this.mem.loadPtr(descriptorPtr); + const nextInChain = this.mem.loadPtr(off(4)); if (nextInChain != 0) { const nextInChainType = this.mem.loadI32(nextInChain + 4); - // RenderPassDescriptorMaxDrawCount = 0x0000000F, - if (nextInChainType == 0x0000000F) { + // RenderPassMaxDrawCount = 0x00000003, + if (nextInChainType == 0x00000003) { maxDrawCount = this.mem.loadU64(nextInChain + 8); } } /** @type {GPURenderPassDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(off(this.sizes.StringView)), colorAttachments: this.array( - this.mem.loadUint(descriptorPtr + 8), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.RenderPassColorAttachment, - 56, + this.sizes.RenderPassColorAttachment[0], ), - depthStencilAttachment: this.RenderPassDepthStencilAttachmentPtr(descriptorPtr + 8 + this.mem.intSize + 4), - occlusionQuerySet: this.QuerySet(descriptorPtr + 8 + this.mem.intSize + 4 + 4), - timestampWrites: this.RenderPassTimestampWritesPtr(descriptorPtr + 8 + this.mem.intSize + 4 + 4), + depthStencilAttachment: this.RenderPassDepthStencilAttachmentPtr(off(4)), + occlusionQuerySet: this.QuerySet(off(4)), + timestampWrites: this.RenderPassTimestampWritesPtr(off(4)), maxDrawCount: maxDrawCount, }; @@ -1308,8 +1522,8 @@ class WebGPUInterface { wgpuCommandEncoderCopyBufferToTexture: (commandEncoderIdx, sourcePtr, destinationPtr, copySizePtr) => { const commandEncoder = this.commandEncoders.get(commandEncoderIdx); commandEncoder.copyBufferToTexture( - this.ImageCopyBuffer(sourcePtr), - this.ImageCopyTexture(destinationPtr), + this.TexelCopyBufferInfo(sourcePtr), + this.TexelCopyTextureInfo(destinationPtr), this.Extent3D(copySizePtr), ); }, @@ -1323,8 +1537,8 @@ class WebGPUInterface { wgpuCommandEncoderCopyTextureToBuffer: (commandEncoderIdx, sourcePtr, destinationPtr, copySizePtr) => { const commandEncoder = this.commandEncoders.get(commandEncoderIdx); commandEncoder.copyTextureToBuffer( - this.ImageCopyTexture(sourcePtr), - this.ImageCopyBuffer(destinationPtr), + this.TexelCopyTextureInfo(sourcePtr), + this.TexelCopyBufferInfo(destinationPtr), this.Extent3D(copySizePtr), ); }, @@ -1338,8 +1552,8 @@ class WebGPUInterface { wgpuCommandEncoderCopyTextureToTexture: (commandEncoderIdx, sourcePtr, destinationPtr, copySizePtr) => { const commandEncoder = this.commandEncoders.get(commandEncoderIdx); commandEncoder.copyTextureToTexture( - this.ImageCopyTexture(sourcePtr), - this.ImageCopyTexture(destinationPtr), + this.TexelCopyTextureInfo(sourcePtr), + this.TexelCopyTextureInfo(destinationPtr), this.Extent3D(copySizePtr), ); }, @@ -1356,7 +1570,7 @@ class WebGPUInterface { let descriptor; if (descriptorPtr != 0) { descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(descriptorPtr + 4), }; } @@ -1367,10 +1581,11 @@ class WebGPUInterface { /** * @param {number} commandEncoderIdx * @param {number} markerLabelPtr + * @param {number} markerLabelLen */ - wgpuCommandEncoderInsertDebugMarker: (commandEncoderIdx, markerLabelPtr) => { + wgpuCommandEncoderInsertDebugMarker: (commandEncoderIdx, markerLabelPtr, markerLabelLen) => { const commandEncoder = this.commandEncoders.get(commandEncoderIdx); - commandEncoder.insertDebugMarker(this.mem.loadCstringDirect(markerLabelPtr)); + commandEncoder.insertDebugMarker(this.mem.loadString(markerLabelPtr, markerLabelLen)); }, /** @@ -1383,11 +1598,12 @@ class WebGPUInterface { /** * @param {number} commandEncoderIdx - * @param {number} markerLabelPtr + * @param {number} groupLabelPtr + * @param {number} groupLabelLen */ - wgpuCommandEncoderPushDebugGroup: (commandEncoderIdx, groupLabelPtr) => { + wgpuCommandEncoderPushDebugGroup: (commandEncoderIdx, groupLabelPtr, groupLabelLen) => { const commandEncoder = this.commandEncoders.get(commandEncoderIdx); - commandEncoder.pushDebugGroup(this.mem.loadCstringDirect(groupLabelPtr)); + commandEncoder.pushDebugGroup(this.mem.loadString(groupLabelPtr, groupLabelLen)); }, /** @@ -1456,10 +1672,11 @@ class WebGPUInterface { /** * @param {number} computePassEncoderIdx * @param {number} markerLabelPtr + * @param {number} markerLabelLen */ - wgpuComputePassEncoderInsertDebugMarker: (computePassEncoderIdx, markerLabelPtr) => { + wgpuComputePassEncoderInsertDebugMarker: (computePassEncoderIdx, markerLabelPtr, markerLabelLen) => { const computePassEncoder = this.computePassEncoders.get(computePassEncoderIdx); - computePassEncoder.insertDebugMarker(this.mem.loadCstringDirect(markerLabelPtr)); + computePassEncoder.insertDebugMarker(this.mem.loadString(markerLabelPtr, markerLabelLen)); }, /** @@ -1472,11 +1689,12 @@ class WebGPUInterface { /** * @param {number} computePassEncoderIdx - * @param {number} markerLabelPtr + * @param {number} groupLabelPtr + * @param {number} groupLabelLen */ - wgpuComputePassEncoderPushDebugGroup: (computePassEncoderIdx, groupLabelPtr) => { + wgpuComputePassEncoderPushDebugGroup: (computePassEncoderIdx, groupLabelPtr, groupLabelLen) => { const computePassEncoder = this.computePassEncoders.get(computePassEncoderIdx); - computePassEncoder.pushDebugGroup(this.mem.loadCstringDirect(groupLabelPtr)); + computePassEncoder.pushDebugGroup(this.mem.loadString(groupLabelPtr, groupLabelLen)); }, /** @@ -1542,15 +1760,18 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPUBindGroupDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - layout: this.bindGroupLayouts.get(this.mem.loadPtr(descriptorPtr + 8)), + label: this.StringView(off(this.sizes.StringView)), + layout: this.bindGroupLayouts.get(this.mem.loadPtr(off(4))), entries: this.array( - this.mem.loadUint(descriptorPtr + 8 + this.mem.intSize), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize * 2), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.BindGroupEntry, - 40, + this.sizes.BindGroupEntry[0], ), }; @@ -1567,14 +1788,17 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPUBindGroupLayoutDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(off(this.sizes.StringView)), entries: this.array( - this.mem.loadUint(descriptorPtr + 8), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.BindGroupLayoutEntry, - 80, + this.sizes.BindGroupLayoutEntry[0], ), }; @@ -1591,12 +1815,15 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPUBufferDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - usage: this.mem.loadU32(descriptorPtr + 8), - size: this.mem.loadU64(descriptorPtr + 16), - mappedAtCreation: this.mem.loadB32(descriptorPtr + 24), + label: this.StringView(off(this.sizes.StringView)), + usage: this.mem.loadU64(off(8)), + size: this.mem.loadU64(off(8)), + mappedAtCreation: this.mem.loadB32(off(4)), }; const buffer = device.createBuffer(descriptor); @@ -1615,7 +1842,7 @@ class WebGPUInterface { let descriptor; if (descriptor != 0) { descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(descriptorPtr + 4), }; } @@ -1638,27 +1865,27 @@ class WebGPUInterface { /** * @param {number} deviceIdx * @param {number} descriptorPtr - * @param {number} callbackPtr - * @param {number} userdata + * @param {number} callbackInfo */ - wgpuDeviceCreateComputePipelineAsync: async (deviceIdx, descriptorPtr, callbackPtr, userdata) => { + wgpuDeviceCreateComputePipelineAsync: (deviceIdx, descriptorPtr, callbackInfoPtr) => { const device = this.devices.get(deviceIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); + this.assert(descriptorPtr != 0); - let result; - let resultIdx; - try { - const computePipeline = await device.createComputePipelineAsync(this.ComputePipelineDescriptor(descriptorPtr)); - resultIdx = this.computePipelines.create(computePipeline); - result = 0; /* Success */ - // NOTE: don't callback here, any errors that happen later will then be caught by the catch here. - } catch (e) { - console.warn(e); - result = 5; /* Unknown error */ - } + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + device.createComputePipelineAsync(this.ComputePipelineDescriptor(descriptorPtr)) + .catch((e) => { + const messageAddr = this.makeMessageArg(e.message); + this.callCallback(callbackInfo, [ENUMS.CreatePipelineAsyncStatus.indexOf("Unknown"), 0, messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }) + .then((computePipeline) => { + const pipelineIdx = this.computePipelines.create(computePipeline); + this.callCallback(callbackInfo, [ENUMS.CreatePipelineAsyncStatus.indexOf("Success"), pipelineIdx, this.zeroMessageArg()]); + }); - callback(result, resultIdx, null, userdata); + // TODO: returning futures? + return BigInt(0); }, /** @@ -1670,12 +1897,15 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPUPipelineLayoutDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(off(this.sizes.StringView)), bindGroupLayouts: this.array( - this.mem.loadUint(descriptorPtr + 8), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), (ptr) => this.bindGroupLayouts.get(this.mem.loadPtr(ptr)), 4, ), @@ -1694,11 +1924,14 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPUQuerySetDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - type: this.QueryType(descriptorPtr + 8), - count: this.mem.loadU32(descriptorPtr + 12), + label: this.StringView(off(this.sizes.StringView)), + type: this.enumeration("QueryType", off(4)), + count: this.mem.loadU32(off(4)), }; const querySet = device.createQuerySet(descriptor); @@ -1714,19 +1947,22 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPURenderBundleEncoderDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(off(this.sizes.StringView)), colorFormats: this.array( - this.mem.loadUint(descriptorPtr + 8), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), this.TextureFormat, 4, ), - depthStencilFormat: this.enumeration("TextureFormat", descriptorPtr + 8 + this.mem.intSize + 4), - sampleCount: this.mem.loadU32(descriptorPtr + 8 + this.mem.intSize + 8), - depthReadOnly: this.mem.loadB32(descriptorPtr + 8 + this.mem.intSize + 12), - stencilReadOnly: this.mem.loadB32(descriptorPtr + 8 + this.mem.intSize + 16), + depthStencilFormat: this.enumeration("TextureFormat", off(4)), + sampleCount: this.mem.loadU32(off(4)), + depthReadOnly: this.mem.loadB32(off(4)), + stencilReadOnly: this.mem.loadB32(off(4)), }; const renderBundleEncoder = device.createRenderBundleEncoder(descriptor); @@ -1750,27 +1986,26 @@ class WebGPUInterface { /** * @param {number} deviceIdx * @param {number} descriptorPtr - * @param {number} callbackPtr - * @param {number} userdata + * @param {number} callbackInfo */ - wgpuDeviceCreateRenderPipelineAsync: async (deviceIdx, descriptorPtr, callbackPtr, userdata) => { + wgpuDeviceCreateRenderPipelineAsync: (deviceIdx, descriptorPtr, callbackInfoPtr) => { const device = this.devices.get(deviceIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); this.assert(descriptorPtr != 0); - let result; - let resultIdx; - try { - const renderPipeline = await device.createRenderPipelineAsync(this.RenderPipelineDescriptor(descriptorPtr)); - resultIdx = this.renderPipelines.create(renderPipeline); - result = 0; /* Success */ - // NOTE: don't callback here, any errors that happen later will then be caught by the catch here. - } catch (e) { - console.warn(e); - result = 5; /* Unknown error */ - } + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + device.createRenderPipelineAsync(this.RenderPipelineDescriptor(descriptorPtr)) + .catch((e) => { + const messageAddr = this.makeMessageArg(e.message); + this.callCallback(callbackInfo, [ENUMS.CreatePipelineAsyncStatus.indexOf("Unknown"), 0, messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }) + .then((renderPipeline) => { + const renderPipelineIdx = this.renderPipelines.create(renderPipeline); + this.callCallback(callbackInfo, [ENUMS.CreatePipelineAsyncStatus.indexOf("Success"), renderPipelineIdx, this.zeroMessageArg()]); + }); - callback(result, resultIdx, null, userdata); + // TODO: returning futures? + return BigInt(0); }, /** @@ -1784,18 +2019,20 @@ class WebGPUInterface { /** @type {?GPUSamplerDescriptor} */ let descriptor; if (descriptorPtr != 0) { + const off = this.struct(descriptorPtr); + off(4); descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - addressModeU: this.enumeration("AddressMode", descriptorPtr + 8), - addressModeV: this.enumeration("AddressMode", descriptorPtr + 12), - addressModeW: this.enumeration("AddressMode", descriptorPtr + 16), - magFilter: this.enumeration("FilterMode", descriptorPtr + 20), - minFilter: this.enumeration("FilterMode", descriptorPtr + 24), - mipMapFilter: this.enumeration("MipmapFilterMode", descriptorPtr + 28), - lodMinClamp: this.mem.loadF32(descriptorPtr + 32), - lodMaxClamp: this.mem.loadF32(descriptorPtr + 36), - compare: this.enumeration("CompareFunction", descriptorPtr + 40), - maxAnisotropy: this.mem.loadU16(descriptorPtr + 44), + label: this.StringView(off(this.sizes.StringView)), + addressModeU: this.enumeration("AddressMode", off(4)), + addressModeV: this.enumeration("AddressMode", off(4)), + addressModeW: this.enumeration("AddressMode", off(4)), + magFilter: this.enumeration("FilterMode", off(4)), + minFilter: this.enumeration("FilterMode", off(4)), + mipMapFilter: this.enumeration("MipmapFilterMode", off(4)), + lodMinClamp: this.mem.loadF32(off(4)), + lodMaxClamp: this.mem.loadF32(off(4)), + compare: this.enumeration("CompareFunction", off(4)), + maxAnisotropy: this.mem.loadU16(off(2)), }; } @@ -1812,24 +2049,24 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); - const nextInChain = this.mem.loadPtr(descriptorPtr); - const nextInChainType = this.mem.loadI32(nextInChain + 4); + const off = this.struct(descriptorPtr); - // ShaderModuleWGSLDescriptor = 0x00000006, - if (nextInChainType != 6) { - throw new TypeError(`Descriptor type should be 'ShaderModuleWGSLDescriptor', got ${nextInChainType}`); + const nextInChain = this.mem.loadPtr(off(4)); + + const chainOff = this.struct(nextInChain); + chainOff(4); + + const nextInChainType = this.mem.loadI32(chainOff(4)); + + // ShaderSourceWGSL = 0x00000002, + if (nextInChainType != 2) { + throw new TypeError(`Descriptor type should be 'ShaderSourceWGSL', got ${nextInChainType}`); } /** @type {GPUShaderModuleDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - code: this.mem.loadCstring(nextInChain + 8), - compilationHints: this.array( - this.mem.loadUint(descriptorPtr + 8), - this.mem.loadPtr(descriptorPtr + 8 + this.mem.intSize), - this.ShaderModuleCompilationHint, - 12, - ), + label: this.StringView(off(this.sizes.StringView)), + code: this.StringView(chainOff(this.sizes.StringView)), }; const shaderModule = device.createShaderModule(descriptor); @@ -1845,18 +2082,21 @@ class WebGPUInterface { const device = this.devices.get(deviceIdx); this.assert(descriptorPtr != 0); + const off = this.struct(descriptorPtr); + off(4); + /** @type {GPUTextureDescriptor} */ const descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - usage: this.mem.loadU32(descriptorPtr + 8), - dimension: this.enumeration("TextureDimension", descriptorPtr + 12), - size: this.Extent3D(descriptorPtr + 16), - format: this.enumeration("TextureFormat", descriptorPtr + 28), - mipLevelCount: this.mem.loadU32(descriptorPtr + 32), - sampleCount: this.mem.loadU32(descriptorPtr + 36), + label: this.StringView(off(this.sizes.StringView)), + usage: this.mem.loadU64(off(8)), + dimension: this.enumeration("TextureDimension", off(4)), + size: this.Extent3D(off(this.sizes.Extent3D)), + format: this.enumeration("TextureFormat", off(4)), + mipLevelCount: this.mem.loadU32(off(4)), + sampleCount: this.mem.loadU32(off(4)), viewFormats: this.array( - this.mem.loadUint(descriptorPtr + 40), - this.mem.loadPtr(descriptorPtr + 40 + this.mem.intSize), + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), (ptr) => this.enumeration("TextureFormat", ptr), 4, ), @@ -1874,26 +2114,43 @@ class WebGPUInterface { device.destroy(); }, + /** + * @param {number} deviceIdx + * @param {number} infoPtr + * @returns {number} + */ + wgpuDeviceGetAdapterInfo: (deviceIdx, infoPtr) => { + return this.genericGetAdapterInfo(infoPtr); + }, + /** * @param {number} deviceIdx * @param {number} featuresPtr - * @returns {number|BigInt} */ - wgpuDeviceEnumerateFeatures: (deviceIdx, featuresPtr) => { + wgpuDeviceGetFeatures: (deviceIdx, featuresPtr) => { const device = this.devices.get(deviceIdx); - return this.genericEnumerateFeatures(device.features, featuresPtr); + return this.genericGetFeatures(device.features, featuresPtr); }, /** * @param {number} deviceIdx * @param {number} limitsPtr - * @returns {boolean} + * @returns {number} */ wgpuDeviceGetLimits: (deviceIdx, limitsPtr) => { const device = this.devices.get(deviceIdx); return this.genericGetLimits(device.limits, limitsPtr); }, + /** + * @param {number} deviceIdx + * @returns {number} + */ + wgpuDeviceGetLostFuture: (deviceIdx) => { + // TODO: futures? + return BigInt(0); + }, + /** * @param {number} deviceIdx * @returns {number} @@ -1910,32 +2167,43 @@ class WebGPUInterface { */ wgpuDeviceHasFeature: (deviceIdx, featureInt) => { const device = this.devices.get(deviceIdx); - return device.features.has(this.enums.FeatureName[featureInt]); + return device.features.has(ENUMS.FeatureName[featureInt]); }, /** * @param {number} deviceIdx - * @param {number} callbackPtr - * @param {number} userdata + * @param {number} callbackInfo + * @returns {number} */ - wgpuDevicePopErrorScope: async (deviceIdx, callbackPtr, userdata) => { + wgpuDevicePopErrorScope: (deviceIdx, callbackInfoPtr) => { const device = this.devices.get(deviceIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); - const error = await device.popErrorScope(); - if (!error) { - callback(0, null, userdata); - return; - } - console.warn(error); - let status = 4; - if (error instanceof GPUValidationError) { - status = 1; - } else if (error instanceof GPUOutOfMemoryError) { - status = 2; - } else if (error instanceof GPUInternalError) { - status = 3; - } - callback(status, null, userdata); + + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + device.popErrorScope() + .then((error) => { + if (!error) { + this.callCallback(callbackInfo, [ENUMS.PopErrorScopeStatus.indexOf("Success"), ENUMS.ErrorType.indexOf("no-error"), this.zeroMessageArg()]); + return; + } + + let status; + if (error instanceof GPUValidationError) { + status = ENUMS.ErrorType.indexOf("validation"); + } else if (error instanceof GPUOutOfMemoryError) { + status = ENUMS.ErrorType.indexOf("out-of-memory"); + } else if (error instanceof GPUInternalError) { + status = ENUMS.ErrorType.indexOf("internal"); + } else { + status = ENUMS.ErrorType.indexOf("unknown"); + } + + const messageAddr = error.message; + this.callCallback(callbackInfo, [ENUMS.PopErrorScopeStatus.indexOf("Success"), status, messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }); + + // TODO: futures? + return BigInt(0); }, /** @@ -1944,7 +2212,7 @@ class WebGPUInterface { */ wgpuDevicePushErrorScope: (deviceIdx, filterInt) => { const device = this.devices.get(deviceIdx); - device.pushErrorScope(this.enums.ErrorFilter[filterInt]); + device.pushErrorScope(ENUMS.ErrorFilter[filterInt]); }, ...this.devices.interface(true), @@ -1959,15 +2227,21 @@ class WebGPUInterface { this.assert(instanceIdx > 0); this.assert(descriptorPtr != 0); - const nextInChain = this.mem.loadPtr(descriptorPtr); - const nextInChainType = this.mem.loadI32(nextInChain + 4); + const off = this.struct(descriptorPtr); + + const nextInChain = this.mem.loadPtr(off(4)); + + const chainOff = this.struct(nextInChain); + chainOff(4); - // SurfaceDescriptorFromCanvasHTMLSelector = 0x00000004, - if (nextInChainType != 4) { - throw new TypeError(`Descriptor type should be 'SurfaceDescriptorFromCanvasHTMLSelector', got ${nextInChainType}`); + const nextInChainType = this.mem.loadI32(chainOff(4)); + + // SurfaceSourceCanvasHTMLSelector = 0x00040001, + if (nextInChainType != 0x00040001) { + throw new TypeError(`Descriptor type should be 'SurfaceSourceCanvasHTMLSelector', got ${nextInChainType}`); } - const selector = this.mem.loadCstring(nextInChain + 8); + const selector = this.StringView(chainOff(this.sizes.StringView)); const surface = document.querySelector(selector); if (!surface) { throw new Error(`Selector '${selector}' did not match any element`); @@ -1979,13 +2253,51 @@ class WebGPUInterface { return this.surfaces.create(surface); }, + /** + * @param {number} instanceIdx + * @param {number} featurePtr + * @returns {number} + */ + wgpuInstanceGetWGSLLanguageFeatures: (instanceIdx, featuresPtr) => { + this.assert(featuresPtr != 0); + + const availableFeatures = []; + ENUMS.WGSLLanguageFeatureName.forEach((feature, value) => { + if (!feature) { + return; + } + + if (navigator.gpu.wgslLanguageFeatures.has(feature)) { + availableFeatures.push(value); + } + }); + + if (availableFeatures.length === 0) { + return; + } + + const featuresAddr = this.mem.exports.wgpu_alloc(availableFeatures.length * 4); + this.assert(featuresAddr != 0); + + let off = this.struct(featuresPtr); + this.mem.storeUint(off(this.mem.intSize), availableFeatures.length); + this.mem.storeI32(off(4), featuresAddr); + + off = this.struct(featuresAddr); + for (let i = 0; i < availableFeatures.length; i += 1) { + this.mem.storeI32(off(4), availableFeatures[i]); + } + + return STATUS_SUCCESS; + }, + /** * @param {number} instanceIdx * @param {number} featureInt * @returns {boolean} */ wgpuInstanceHasWGSLLanguageFeature: (instanceIdx, featureInt) => { - return navigator.gpu.wgslLanguageFeatures.has(this.enums.WGSLFeatureName[featureInt]); + return navigator.gpu.wgslLanguageFeatures.has(ENUMS.WGSLLanguageFeatureName[featureInt]); }, /** @@ -1998,33 +2310,45 @@ class WebGPUInterface { /** * @param {number} instanceIdx * @param {0|number} optionsPtr - * @param {number} callbackPtr - * @param {number} userdata + * @param {number} callbackInfo + * @returns {number} */ - wgpuInstanceRequestAdapter: async (instanceIdx, optionsPtr, callbackPtr, userdata) => { + wgpuInstanceRequestAdapter: (instanceIdx, optionsPtr, callbackInfoPtr) => { this.assert(instanceIdx > 0); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); /** @type {GPURequestAdapterOptions} */ let options; if (optionsPtr != 0) { + const off = this.struct(optionsPtr); + off(4); // nextInChain + off(4); // featureLevel options = { - powerPreference: this.enumeration("PowerPreference", optionsPtr + 8), - forceFallbackAdapter: this.mem.loadB32(optionsPtr + 16), + powerPreference: this.enumeration("PowerPreference", off(4)), + forceFallbackAdapter: this.mem.loadB32(off(4)), }; } - let adapterIdx; - try { - const adapter = await navigator.gpu.requestAdapter(options); - adapterIdx = this.adapters.create(adapter); - // NOTE: don't callback here, any errors that happen later will then be caught by the catch here. - } catch(e) { - console.warn(e); - callback(2, null, null, userdata); - } + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + navigator.gpu.requestAdapter(options) + .catch((e) => { + const messageAddr = this.makeMessageArg(e.message); + this.callCallback(callbackInfo, [ENUMS.RequestAdapterStatus.indexOf("Error"), null, messageAddr]); + this.mem.exports.wgpu_free(messageAddr); + }) + .then((adapter) => { + const adapterIdx = this.adapters.create(adapter); + + this.callCallback(callbackInfo, [ENUMS.RequestAdapterStatus.indexOf("Success"), adapterIdx, this.zeroMessageArg()]); + }); - callback(0, adapterIdx, null, userdata); + // TODO: futures? + return BigInt(0); + }, + + wgpuInstanceWaitAny: (instanceIdx, futureCount, futuresPtr, timeoutNS) => { + // TODO: futures? + console.warn("unimplemented: wgpuInstanceProcessEvents"); + return BigInt(0); }, ...this.instances.interface(false), @@ -2058,7 +2382,7 @@ class WebGPUInterface { */ wgpuQuerySetGetType: (querySetIdx) => { const querySet = this.querySets.get(querySetIdx); - return this.enums.QueryType.indexOf(querySet.type); + return ENUMS.QueryType.indexOf(querySet.type); }, ...this.querySets.interface(true), @@ -2067,21 +2391,23 @@ class WebGPUInterface { /** * @param {number} queueIdx - * @param {number} callbackPtr - * @param {number} userdata + * @param {number} callbackInfo */ - wgpuQueueOnSubmittedWorkDone: async (queueIdx, callbackPtr, userdata) => { + wgpuQueueOnSubmittedWorkDone: (queueIdx, callbackInfoPtr) => { const queue = this.queues.get(queueIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); - let result; - try { - await queue.onSubmittedWorkDone(); - result = 0; - } catch(e) { - console.warn(e); - result = 1; - } - callback(result, userdata); + + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + queue.onSubmittedWorkDone() + .catch((e) => { + console.warn(e); + this.callCallback(callbackInfo, [ENUMS.QueueWorkDoneStatus.indexOf("Error")]); + }) + .then(() => { + this.callCallback(callbackInfo, [ENUMS.QueueWorkDoneStatus.indexOf("Success")]); + }); + + // TODO: futures? + return BigInt(0); }, /** @@ -2125,9 +2451,9 @@ class WebGPUInterface { */ wgpuQueueWriteTexture: (queueIdx, destinationPtr, dataPtr, dataSize, dataLayoutPtr, writeSizePtr) => { const queue = this.queues.get(queueIdx); - const destination = this.ImageCopyTexture(destinationPtr); + const destination = this.TexelCopyTextureInfo(destinationPtr); dataSize = this.unwrapBigInt(dataSize); - const dataLayout = this.TextureDataLayout(dataLayoutPtr); + const dataLayout = this.TexelCopyBufferLayout(dataLayoutPtr); const writeSize = this.Extent3D(writeSizePtr); queue.writeTexture(destination, this.mem.loadBytes(dataPtr, dataSize), dataLayout, writeSize); }, @@ -2201,7 +2527,7 @@ class WebGPUInterface { let descriptor; if (descriptorPtr != 0) { descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), + label: this.StringView(descriptorPtr + 4), }; } @@ -2212,11 +2538,12 @@ class WebGPUInterface { /** * @param {number} renderBundleEncoderIdx * @param {number} markerLabelPtr + * @param {number} markerLabelLen */ - wgpuRenderBundleEncoderInsertDebugMarker: (renderBundleEncoderIdx, markerLabelPtr) => { + wgpuRenderBundleEncoderInsertDebugMarker: (renderBundleEncoderIdx, markerLabelPtr, markerLabelLen) => { const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx); this.assert(markerLabelPtr != 0); - const markerLabel = this.mem.loadCstringDirect(markerLabelPtr); + const markerLabel = this.mem.loadString(markerLabelPtr, markerLabelLen); renderBundleEncoder.insertDebugMarker(markerLabel); }, @@ -2231,11 +2558,12 @@ class WebGPUInterface { /** * @param {number} renderBundleEncoderIdx * @param {number} groupLabelPtr + * @param {number} grouplabelLen */ - wgpuRenderBundleEncoderPushDebugGroup: (renderBundleEncoderIdx, groupLabelPtr) => { + wgpuRenderBundleEncoderPushDebugGroup: (renderBundleEncoderIdx, groupLabelPtr, grouplabelLen) => { const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx); this.assert(groupLabelPtr!= 0); - const groupLabel = this.mem.loadCstringDirect(groupLabelPtr); + const groupLabel = this.mem.loadString(groupLabelPtr, groupLabelLen); renderBundleEncoder.pushDebugGroup(groupLabel); }, @@ -2270,7 +2598,7 @@ class WebGPUInterface { wgpuRenderBundleEncoderSetIndexBuffer: (renderBundleEncoderIdx, bufferIdx, formatInt, offset, size) => { const renderBundleEncoder = this.renderBundleEncoders.get(renderBundleEncoderIdx); const buffer = this.buffers.get(bufferIdx); - const format = this.enums.IndexFormat[formatInt]; + const format = ENUMS.IndexFormat[formatInt]; offset = this.unwrapBigInt(offset); size = this.unwrapBigInt(size); renderBundleEncoder.setIndexBuffer(buffer.buffer, format, offset, size); @@ -2404,10 +2732,11 @@ class WebGPUInterface { /** * @param {number} renderPassEncoderIdx * @param {number} markerLabelPtr + * @param {number} markerLabelLen */ - wgpuRenderPassEncoderInsertDebugMarker: (renderPassEncoderIdx, markerLabelPtr) => { + wgpuRenderPassEncoderInsertDebugMarker: (renderPassEncoderIdx, markerLabelPtr, markerLabelLen) => { const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx); - const markerLabel = this.mem.loadCstringDirect(markerLabelPtr); + const markerLabel = this.mem.loadString(markerLabelPtr, markerLabelLen); renderPassEncoder.insertDebugMarker(markerLabel); }, @@ -2422,10 +2751,11 @@ class WebGPUInterface { /** * @param {number} renderPassEncoderIdx * @param {number} groupLabelPtr + * @param {number} groupLabelLen */ - wgpuRenderPassEncoderPushDebugGroup: (renderPassEncoderIdx, groupLabelPtr) => { + wgpuRenderPassEncoderPushDebugGroup: (renderPassEncoderIdx, groupLabelPtr, groupLabelLen) => { const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx); - const groupLabel = this.mem.loadCstringDirect(groupLabelPtr); + const groupLabel = this.mem.loadString(groupLabelPtr, groupLabelLen); renderPassEncoder.pushDebugGroup(groupLabel); }, @@ -2470,7 +2800,7 @@ class WebGPUInterface { wgpuRenderPassEncoderSetIndexBuffer: (renderPassEncoderIdx, bufferIdx, formatInt, offset, size) => { const renderPassEncoder = this.renderPassEncoders.get(renderPassEncoderIdx); const buffer = this.buffers.get(bufferIdx); - const format = this.enums.IndexFormat[formatInt]; + const format = ENUMS.IndexFormat[formatInt]; offset = this.unwrapBigInt(offset); size = this.unwrapBigInt(size); renderPassEncoder.setIndexBuffer(buffer.buffer, format, offset, size); @@ -2566,60 +2896,76 @@ class WebGPUInterface { /** * @param {number} shaderModuleIdx - * @param {number} callbackPtr - * @param {number} userdata + * @param {number} callbackInfo */ - wgpuShaderModuleGetCompilationInfo: async (shaderModuleIdx, callbackPtr, userdata) => { + wgpuShaderModuleGetCompilationInfo: (shaderModuleIdx, callbackInfoPtr) => { const shaderModule = this.shaderModules.get(shaderModuleIdx); - const callback = this.mem.exports.__indirect_function_table.get(callbackPtr); - let status = 0; - let retAddr = 0; + const callbackInfo = this.CallbackInfo(callbackInfoPtr); + shaderModule.getCompilationInfo() + .catch((e) => { + console.warn(e); + this.callCallback(callbackInfo, [ENUMS.CompilationInfoRequestStatus.indexOf("Error"), null]); + }) + .then((compilationInfo) => { + const ptrsToFree = []; - const ptrsToFree = []; + const compilationMessageSize = this.sizes.CompilationMessage[0]; - try { - const compilationInfo = await shaderModule.getCompilationInfo(); + const size = compilationInfo.messages.length * compilationMessageSize; - const size = compilationInfo.messages.length * 72; - const addr = this.mem.exports.wgpu_alloc(size); - ptrsToFree.push(addr); - compilationInfo.messages.forEach((message, i) => { - const messageLength = new TextEncoder().encode(message.message).length; - const messageAddr = this.mem.exports.wgpu_alloc(messageLength); - ptrsToFree.push(messageAddr); - this.mem.storeString(messageAddr, message.message); - this.mem.storeI32(addr + (i * size) + 4); + const addr = this.mem.exports.wgpu_alloc(size); + ptrsToFree.push(addr); - this.mem.storeI32(addr + (i * size) + 8, this.enums.CompilationMessageType.indexOf(message.type)); + compilationInfo.messages.forEach((message, i) => { + const messageLength = new TextEncoder().encode(message.message).length; + const messageAddr = this.mem.exports.wgpu_alloc(messageLength); + ptrsToFree.push(messageAddr); + this.mem.storeString(messageAddr, message.message); - this.mem.storeU64(addr + (i * size) + 16, message.lineNum); - this.mem.storeU64(addr + (i * size) + 24, message.linePos); - this.mem.storeU64(addr + (i * size) + 32, message.offset); - this.mem.storeU64(addr + (i * size) + 40, message.length); + const off = this.struct(addr + (i * compilationMessageSize)); + off(4); - // TODO: UTF16 units. - this.mem.storeU64(addr + (i * size) + 48, message.linePos); - this.mem.storeU64(addr + (i * size) + 56, message.offset); - this.mem.storeU64(addr + (i * size) + 64, message.length); - }); + const messageStart = off(this.sizes.StringView); + this.mem.storeI32(messageStart, messageAddr); + this.mem.storeUint(messageStart + this.mem.intSize, messageLength); - retAddr = this.mem.exports.wgpu_alloc(3*this.mem.intSize); - ptrsToFree.push(retAddr); - this.mem.storeUint(retAddr + this.mem.intSize, compilationInfo.messages.length); - this.mem.storeI32(retAddr + this.mem.intSize*2, addr); - } catch (e) { - console.warn(e); - status = 1; - } + this.mem.storeI32(off(4), ENUMS.CompilationMessageType.indexOf(message.type)); + + this.mem.storeU64(off(8), message.lineNum); + this.mem.storeU64(off(8), message.linePos); + this.mem.storeU64(off(8), message.offset); + this.mem.storeU64(off(8), message.length); + }); + + const retAddr = this.mem.exports.wgpu_alloc(3*this.mem.intSize); + ptrsToFree.push(retAddr); + this.mem.storeUint(retAddr + this.mem.intSize, compilationInfo.messages.length); + this.mem.storeI32(retAddr + this.mem.intSize*2, addr); + + this.callCallback(callbackInfo, [ENUMS.CompilationInfoRequestStatus.indexOf("Success"), retAddr]); - callback(status, retAddr, userdata); + ptrsToFree.forEach(ptr => this.mem.exports.wgpu_free(ptr)); + }); - ptrsToFree.forEach(ptr => this.mem.exports.wgpu_free(ptr)); + // TODO: futures? + return BigInt(0); }, ...this.shaderModules.interface(true), + /* ---------------------- SupportedFeatures ---------------------- */ + + wgpuSupportedFeaturesFreeMembers: (supportedFeaturesCount, supportedFeaturesPtr) => { + this.mem.exports.wgpu_free(supportedFeaturesPtr); + }, + + /* ---------------------- SupportedWGSLLanguageFeatures ---------------------- */ + + wgpuSupportedWGSLLanguageFeaturesFreeMembers: (supportedFeaturesCount, supportedFeaturesPtr) => { + this.mem.exports.wgpu_free(supportedFeaturesPtr); + }, + /* ---------------------- Surface ---------------------- */ /** @@ -2628,26 +2974,36 @@ class WebGPUInterface { */ wgpuSurfaceConfigure: (surfaceIdx, configPtr) => { const surface = this.surfaces.get(surfaceIdx); - const context = surface.getContext('webgpu'); + const context = surface.getContext("webgpu"); + + const off = this.struct(configPtr); + off(4); + const device = this.devices.get(this.mem.loadPtr(off(4))); + const format = this.enumeration("TextureFormat", off(4)); + const usage = this.mem.loadU64(off(8)); + const width = this.mem.loadU32(off(4)); + const height = this.mem.loadU32(off(4)); + const viewFormats = this.array( + this.mem.loadUint(off(this.mem.intSize)), + this.mem.loadPtr(off(4)), + (ptr) => this.enumeration("TextureFormat", ptr), + 4, + ); + const alphaMode = this.enumeration("CompositeAlphaMode", off(4)); + // NOTE: present mode seems unused. + const presentMode = this.enumeration("PresentMode", off(4)); - const widthOff = 16 + this.mem.intSize + 8; - surface.width = this.mem.loadU32(configPtr + widthOff); - surface.height = this.mem.loadU32(configPtr + widthOff + 4); + surface.width = width; + surface.height = height; /** @type {GPUCanvasConfiguration} */ const config = { - device: this.devices.get(this.mem.loadPtr(configPtr + 4)), - format: this.enumeration("TextureFormat", configPtr + 8), - usage: this.mem.loadU32(configPtr + 12), - viewFormats: this.array( - this.mem.loadUint(configPtr + 16), - this.mem.loadPtr(configPtr + 16 + this.mem.intSize), - (ptr) => this.enumeration("TextureFormat", ptr), - 4, - ), - alphaMode: this.enumeration("CompositeAlphaMode", configPtr + widthOff - 4), - // // NOTE: present mode seems unused. - presentMode: this.enumeration("PresentMode", configPtr + widthOff + 4), + device: device, + format: format, + usage: usage, + viewFormats: viewFormats, + alphaMode: alphaMode, + presentMode: presentMode, }; context.configure(config); @@ -2657,28 +3013,35 @@ class WebGPUInterface { * @param {number} surfaceIdx * @param {number} adapterIdx * @param {number} capabilitiesPtr + * @return {number} */ wgpuSurfaceGetCapabilities: (surfaceIdx, adapterIdx, capabilitiesPtr) => { + const off = this.struct(capabilitiesPtr); + off(4); // nextInChain + off(8); // usages TODO: can we pass this? + const formatStr = navigator.gpu.getPreferredCanvasFormat(); - const format = this.enums.TextureFormat.indexOf(formatStr); + const format = ENUMS.TextureFormat.indexOf(formatStr); - this.mem.storeUint(capabilitiesPtr + 8, 1); + this.mem.storeUint(off(this.mem.intSize), 1); const formatAddr = this.mem.exports.wgpu_alloc(4); this.mem.storeI32(formatAddr, format); - this.mem.storeI32(capabilitiesPtr + 8 + this.mem.intSize, formatAddr); + this.mem.storeI32(off(4), formatAddr); // NOTE: present modes don't seem to actually do anything in JS, we can just give back a default FIFO though. - this.mem.storeUint(capabilitiesPtr + 8 + this.mem.intSize*2, 1); + this.mem.storeUint(off(this.mem.intSize), 1); const presentModesAddr = this.mem.exports.wgpu_alloc(4); - this.mem.storeI32(presentModesAddr, 0); - this.mem.storeI32(capabilitiesPtr + 8 + this.mem.intSize*3, presentModesAddr); + this.mem.storeI32(presentModesAddr, ENUMS.PresentMode.indexOf("fifo")); + this.mem.storeI32(off(4), presentModesAddr); - // Browser seems to support opaque (1) and premultiplied (2). - this.mem.storeUint(capabilitiesPtr + 8 + this.mem.intSize*4, 2); + // Browser seems to support opaque and premultiplied. + this.mem.storeUint(off(this.mem.intSize), 2); const alphaModesAddr = this.mem.exports.wgpu_alloc(8); - this.mem.storeI32(alphaModesAddr + 0, 1); // Opaque. - this.mem.storeI32(alphaModesAddr + 4, 2); // premultiplied. - this.mem.storeI32(capabilitiesPtr + 8 + this.mem.intSize*5, alphaModesAddr); + this.mem.storeI32(alphaModesAddr + 0, ENUMS.CompositeAlphaMode.indexOf("opaque")); + this.mem.storeI32(alphaModesAddr + 4, ENUMS.CompositeAlphaMode.indexOf("premultiplied")); + this.mem.storeI32(off(4), alphaModesAddr); + + return STATUS_SUCCESS; }, /** @@ -2691,7 +3054,7 @@ class WebGPUInterface { const texture = context.getCurrentTexture(); const textureIdx = this.textures.create(texture); - this.mem.storeI32(texturePtr, textureIdx); + this.mem.storeI32(texturePtr + 4, textureIdx); // TODO: determine suboptimal and/or status. }, @@ -2719,13 +3082,22 @@ class WebGPUInterface { * @param {number} surfaceCapabilitiesPtr */ wgpuSurfaceCapabilitiesFreeMembers: (surfaceCapabilitiesPtr) => { - const formatsAddr = this.mem.loadI32(surfaceCapabilitiesPtr + this.mem.intSize*2); + const off = this.struct(capabilitiesPtr); + off(4); // nextInChain + off(8); // usages + off(this.mem.intSize); // formatCount + + const formatsAddr = this.mem.loadPtr(off(4)); this.mem.exports.wgpu_free(formatsAddr); - const presentModesAddr = this.mem.loadI32(surfaceCapabilitiesPtr + this.mem.intSize*4); + off(this.mem.intSize); // presentModeCount + + const presentModesAddr = this.mem.loadPtr(off(4)); this.mem.exports.wgpu_free(presentModesAddr); - const alphaModesAddr = this.mem.loadI32(surfaceCapabilitiesPtr + this.mem.intSize*6); + off(this.mem.intSize); // alphaModeCount + + const alphaModesAddr = this.mem.loadPtr(off(4)); this.mem.exports.wgpu_free(alphaModesAddr); }, @@ -2742,15 +3114,18 @@ class WebGPUInterface { /** @type {?GPUTextureViewDescriptor} */ let descriptor; if (descriptorPtr != 0) { + const off = this.struct(descriptorPtr); + off(4); descriptor = { - label: this.mem.loadCstring(descriptorPtr + 4), - format: this.enumeration("TextureFormat", descriptorPtr + 8), - dimension: this.enumeration("TextureViewDimension", descriptorPtr + 12), - baseMipLevel: this.mem.loadU32(descriptorPtr + 16), - mipLevelCount: this.mem.loadU32(descriptorPtr + 20), - baseArrayLayer: this.mem.loadU32(descriptorPtr + 24), - arrayLayerCount: this.mem.loadU32(descriptorPtr + 28), - aspect: this.enumeration("TextureAspect", descriptorPtr + 32), + label: this.StringView(off(this.sizes.StringView)), + format: this.enumeration("TextureFormat", off(4)), + dimension: this.enumeration("TextureViewDimension", off(4)), + baseMipLevel: this.mem.loadU32(off(4)), + mipLevelCount: this.mem.loadU32(off(4)), + baseArrayLayer: this.mem.loadU32(off(4)), + arrayLayerCount: this.mem.loadU32(off(4)), + aspect: this.enumeration("TextureAspect", off(4)), + usage: this.mem.loadU64(off(8)), }; if (descriptor.arrayLayerCount == 0xFFFFFFFF) { descriptor.arrayLayerCount = undefined; @@ -2787,7 +3162,7 @@ class WebGPUInterface { */ wgpuTextureGetDimension: (textureIdx) => { const texture = this.textures.get(textureIdx); - return this.enums.TextureDimension.indexOf(texture.dimension); + return ENUMS.TextureDimension.indexOf(texture.dimension); }, /** @@ -2796,7 +3171,7 @@ class WebGPUInterface { */ wgpuTextureGetFormat: (textureIdx) => { const texture = this.textures.get(textureIdx); - return this.enums.TextureFormat.indexOf(texture.format); + return ENUMS.TextureFormat.indexOf(texture.format); }, /** @@ -2903,12 +3278,12 @@ class WebGPUObjectManager { interface(withLabelSetter = false) { const inter = {}; - inter[`wgpu${this.name}Reference`] = this.reference.bind(this); + inter[`wgpu${this.name}AddRef`] = this.reference.bind(this); inter[`wgpu${this.name}Release`] = this.release.bind(this); if (withLabelSetter) { - inter[`wgpu${this.name}SetLabel`] = (idx, labelPtr) => { + inter[`wgpu${this.name}SetLabel`] = (idx, labelPtr, labelLen) => { const obj = this.get(idx); - obj.label = this.mem.loadCstringDirect(labelPtr); + obj.label = this.mem.loadString(labelPtr, labelLen); }; } return inter; diff --git a/vendor/wgpu/wgpu.odin b/vendor/wgpu/wgpu.odin index 9854475a922..fa72dc37a90 100644 --- a/vendor/wgpu/wgpu.odin +++ b/vendor/wgpu/wgpu.odin @@ -10,12 +10,13 @@ WGPU_DEBUG :: #config(WGPU_DEBUG, false) when ODIN_OS == .Windows { @(private) ARCH :: "x86_64" when ODIN_ARCH == .amd64 else "x86_64" when ODIN_ARCH == .i386 else #panic("unsupported WGPU Native architecture") @(private) EXT :: ".dll.lib" when WGPU_SHARED else ".lib" - @(private) LIB :: "lib/wgpu-windows-" + ARCH + "-" + TYPE + "/wgpu_native" + EXT + @(private) LIB :: "lib/wgpu-windows-" + ARCH + "-msvc-" + TYPE + "/lib/wgpu_native" + EXT when !#exists(LIB) { - #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v22.1.0.1, make sure to read the README at '" + #directory + "README.md'") + #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v24.0.0.2, make sure to read the README at '" + #directory + "README.md'") } + @(export) foreign import libwgpu { LIB, "system:d3dcompiler.lib", @@ -29,16 +30,19 @@ when ODIN_OS == .Windows { "system:gdi32.lib", "system:ole32.lib", "system:oleaut32.lib", + "system:propsys.lib", + "system:runtimeobject.lib", } } else when ODIN_OS == .Darwin { @(private) ARCH :: "x86_64" when ODIN_ARCH == .amd64 else "aarch64" when ODIN_ARCH == .arm64 else #panic("unsupported WGPU Native architecture") @(private) EXT :: ".dylib" when WGPU_SHARED else ".a" - @(private) LIB :: "lib/wgpu-macos-" + ARCH + "-" + TYPE + "/libwgpu_native" + EXT + @(private) LIB :: "lib/wgpu-macos-" + ARCH + "-" + TYPE + "/lib/libwgpu_native" + EXT when !#exists(LIB) { - #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v22.1.0.1, make sure to read the README at '" + #directory + "README.md'") + #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v24.0.0.2, make sure to read the README at '" + #directory + "README.md'") } + @(export) foreign import libwgpu { LIB, "system:CoreFoundation.framework", @@ -48,18 +52,20 @@ when ODIN_OS == .Windows { } else when ODIN_OS == .Linux { @(private) ARCH :: "x86_64" when ODIN_ARCH == .amd64 else "aarch64" when ODIN_ARCH == .arm64 else #panic("unsupported WGPU Native architecture") @(private) EXT :: ".so" when WGPU_SHARED else ".a" - @(private) LIB :: "lib/wgpu-linux-" + ARCH + "-" + TYPE + "/libwgpu_native" + EXT + @(private) LIB :: "lib/wgpu-linux-" + ARCH + "-" + TYPE + "/lib/libwgpu_native" + EXT when !#exists(LIB) { - #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v22.1.0.1, make sure to read the README at '" + #directory + "README.md'") + #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v24.0.0.2, make sure to read the README at '" + #directory + "README.md'") } + @(export) foreign import libwgpu { LIB, "system:dl", "system:m", } } else when ODIN_OS == .JS { + @(export) foreign import libwgpu "wgpu" } @@ -73,7 +79,11 @@ QUERY_SET_INDEX_UNDEFINED :: max(u32) WHOLE_MAP_SIZE :: max(uint) WHOLE_SIZE :: max(u64) -Flags :: u32 +Flags :: u64 + +StringView :: string + +STRLEN :: transmute(int)(max(uint)) Adapter :: distinct rawptr BindGroup :: distinct rawptr @@ -99,16 +109,17 @@ Texture :: distinct rawptr TextureView :: distinct rawptr AdapterType :: enum i32 { - DiscreteGPU = 0x00000000, - IntegratedGPU = 0x00000001, - CPU = 0x00000002, - Unknown = 0x00000003, + DiscreteGPU = 0x00000001, + IntegratedGPU = 0x00000002, + CPU = 0x00000003, + Unknown = 0x00000004, } AddressMode :: enum i32 { - Repeat = 0x00000000, - MirrorRepeat = 0x00000001, - ClampToEdge = 0x00000002, + Undefined = 0x00000000, + ClampToEdge = 0x00000001, + Repeat = 0x00000002, + MirrorRepeat = 0x00000003, } BackendType :: enum i32 { @@ -124,19 +135,24 @@ BackendType :: enum i32 { } BlendFactor :: enum i32 { - Zero = 0x00000000, - One = 0x00000001, - Src = 0x00000002, - OneMinusSrc = 0x00000003, - SrcAlpha = 0x00000004, - OneMinusSrcAlpha = 0x00000005, - Dst = 0x00000006, - OneMinusDst = 0x00000007, - DstAlpha = 0x00000008, - OneMinusDstAlpha = 0x00000009, - SrcAlphaSaturated = 0x0000000A, - Constant = 0x0000000B, - OneMinusConstant = 0x0000000C, + Undefined = 0x00000000, + Zero = 0x00000001, + One = 0x00000002, + Src = 0x00000003, + OneMinusSrc = 0x00000004, + SrcAlpha = 0x00000005, + OneMinusSrcAlpha = 0x00000006, + Dst = 0x00000007, + OneMinusDst = 0x00000008, + DstAlpha = 0x00000009, + OneMinusDstAlpha = 0x0000000A, + SrcAlphaSaturated = 0x0000000B, + Constant = 0x0000000C, + OneMinusConstant = 0x0000000D, + Src1 = 0x0000000E, + OneMinusSrc1 = 0x0000000F, + Src1Alpha = 0x00000010, + OneMinusSrc1Alpha = 0x00000011, } BlendOperation :: enum i32 { @@ -148,53 +164,48 @@ BlendOperation :: enum i32 { } BufferBindingType :: enum i32 { - Undefined = 0x00000000, - Uniform = 0x00000001, - Storage = 0x00000002, - ReadOnlyStorage = 0x00000003, + BindingNotUsed = 0x00000000, + Undefined = 0x00000001, + Uniform = 0x00000002, + Storage = 0x00000003, + ReadOnlyStorage = 0x00000004, } -BufferMapAsyncStatus :: enum i32 { - Success = 0x00000000, - ValidationError = 0x00000001, - Unknown = 0x00000002, - DeviceLost = 0x00000003, - DestroyedBeforeCallback = 0x00000004, - UnmappedBeforeCallback = 0x00000005, - MappingAlreadyPending = 0x00000006, - OffsetOutOfRange = 0x00000007, - SizeOutOfRange = 0x00000008, +BufferMapState :: enum i32 { + Unmapped = 0x00000001, + Pending = 0x00000002, + Mapped = 0x00000003, } -BufferMapState :: enum i32 { - Unmapped = 0x00000000, - Pending = 0x00000001, - Mapped = 0x00000002, +CallbackMode :: enum i32 { + WaitAnyOnly = 0x00000001, + AllowProcessEvents = 0x00000002, + AllowSpontaneos = 0x00000003, } CompareFunction :: enum i32 { Undefined = 0x00000000, Never = 0x00000001, Less = 0x00000002, - LessEqual = 0x00000003, - Greater = 0x00000004, - GreaterEqual = 0x00000005, - Equal = 0x00000006, - NotEqual = 0x00000007, + Equal = 0x00000003, + LessEqual = 0x00000004, + Greater = 0x00000005, + NotEqual = 0x00000006, + GreaterEqual = 0x00000007, Always = 0x00000008, } CompilationInfoRequestStatus :: enum i32 { - Success = 0x00000000, - Error = 0x00000001, - DeviceLost = 0x00000002, - Unknown = 0x00000003, + Success = 0x00000001, + InstanceDropped = 0x00000002, + Error = 0x00000003, + Unknown = 0x00000004, } CompilationMessageType :: enum i32 { - Error = 0x00000000, - Warning = 0x00000001, - Info = 0x00000002, + Error = 0x00000001, + Warning = 0x00000002, + Info = 0x00000003, } CompositeAlphaMode :: enum i32 { @@ -206,39 +217,45 @@ CompositeAlphaMode :: enum i32 { } CreatePipelineAsyncStatus :: enum i32 { - Success = 0x00000000, - ValidationError = 0x00000001, - InternalError = 0x00000002, - DeviceLost = 0x00000003, - DeviceDestroyed = 0x00000004, + Success = 0x00000001, + InstanceDropped = 0x00000002, + ValidationError = 0x00000003, + InternalError = 0x00000004, Unknown = 0x00000005, } CullMode :: enum i32 { - None = 0x00000000, - Front = 0x00000001, - Back = 0x00000002, + Undefined = 0x00000000, + None = 0x00000001, + Front = 0x00000002, + Back = 0x00000003, } DeviceLostReason :: enum i32 { Undefined = 0x00000000, Unknown = 0x00000001, Destroyed = 0x00000002, + InstanceDropped = 0x00000003, + FailedCreation = 0x00000004, } ErrorFilter :: enum i32 { - Validation = 0x00000000, - OutOfMemory = 0x00000001, - Internal = 0x00000002, -} - -ErrorType :: enum i32 { - NoError = 0x00000000, Validation = 0x00000001, OutOfMemory = 0x00000002, Internal = 0x00000003, - Unknown = 0x00000004, - DeviceLost = 0x00000005, +} + +ErrorType :: enum i32 { + NoError = 0x00000001, + Validation = 0x00000002, + OutOfMemory = 0x00000003, + Internal = 0x00000004, + Unknown = 0x00000005, +} + +FeatureLevel :: enum i32 { + Compatibility = 0x00000001, + Core = 0x00000002, } FeatureName :: enum i32 { @@ -248,13 +265,18 @@ FeatureName :: enum i32 { Depth32FloatStencil8 = 0x00000002, TimestampQuery = 0x00000003, TextureCompressionBC = 0x00000004, - TextureCompressionETC2 = 0x00000005, - TextureCompressionASTC = 0x00000006, - IndirectFirstInstance = 0x00000007, - ShaderF16 = 0x00000008, - RG11B10UfloatRenderable = 0x00000009, - BGRA8UnormStorage = 0x0000000A, - Float32Filterable = 0x0000000B, + TextureCompressionBCSliced3D = 0x00000005, + TextureCompressionETC2 = 0x00000006, + TextureCompressionASTC = 0x00000007, + TextureCompressionASTCSliced3D = 0x00000008, + IndirectFirstInstance = 0x00000009, + ShaderF16 = 0x0000000A, + RG11B10UfloatRenderable = 0x0000000B, + BGRA8UnormStorage = 0x0000000C, + Float32Filterable = 0x0000000D, + Float32Blendable = 0x0000000E, + ClipDistances = 0x0000000F, + DualSourceBlending = 0x00000010, // Native. PushConstants = 0x00030001, @@ -269,8 +291,6 @@ FeatureName :: enum i32 { PartiallyBoundBindingArray, TextureFormat16bitNorm, TextureCompressionAstcHdr, - // TODO: requires wgpu.h api change - // TimestampQueryInsidePasses, MappablePrimaryBuffers = 0x0003000E, BufferBindingArray, UniformBufferAndStorageTextureArrayNonUniformIndexing, @@ -281,7 +301,7 @@ FeatureName :: enum i32 { // PolygonModePoint, // ConservativeRasterization, // ClearTexture, - // SprivShaderPassThrough, + SprivShaderPassThrough = 0x00030017, // MultiView, VertexAttribute64bit = 0x00030019, TextureFormatNv12, @@ -291,16 +311,23 @@ FeatureName :: enum i32 { ShaderI16, ShaderPrimitiveIndex, ShaderEarlyDepthTest, + Subgroup, + SubgroupVertex, + SubgroupBarrier, + TimestampQueryInsideEncoders, + TimestampQueryInsidePasses, } FilterMode :: enum i32 { - Nearest = 0x00000000, - Linear = 0x00000001, + Undefined = 0x00000000, + Nearest = 0x00000001, + Linear = 0x00000002, } FrontFace :: enum i32 { - CCW = 0x00000000, - CW = 0x00000001, + Undefined = 0x00000000, + CCW = 0x00000001, + CW = 0x00000002, } IndexFormat :: enum i32 { @@ -311,13 +338,34 @@ IndexFormat :: enum i32 { LoadOp :: enum i32 { Undefined = 0x00000000, - Clear = 0x00000001, - Load = 0x00000002, + Load = 0x00000001, + Clear = 0x00000002, +} + +MapAsyncStatus :: enum i32 { + Success = 0x00000001, + InstanceDropped = 0x00000002, + Error = 0x00000003, + Aborted = 0x00000004, + Unknown = 0x00000005, } MipmapFilterMode :: enum i32 { - Nearest = 0x00000000, - Linear = 0x00000001, + Undefined = 0x00000000, + Nearest = 0x00000001, + Linear = 0x00000002, +} + +OptionalBool :: enum i32 { + False = 0x00000000, + True = 0x00000001, + Undefined = 0x00000002, +} + +PopErrorScopeStatus :: enum i32 { + Success = 0x00000001, + InstanceDropped = 0x00000002, + EmptyStack = 0x00000003, } PowerPreference :: enum i32 { @@ -327,67 +375,68 @@ PowerPreference :: enum i32 { } PresentMode :: enum i32 { - Fifo = 0x00000000, - FifoRelaxed = 0x00000001, - Immediate = 0x00000002, - Mailbox = 0x00000003, + Undefined = 0x00000000, + Fifo = 0x00000001, + FifoRelaxed = 0x00000002, + Immediate = 0x00000003, + Mailbox = 0x00000004, } PrimitiveTopology :: enum i32 { - PointList = 0x00000000, - LineList = 0x00000001, - LineStrip = 0x00000002, - TriangleList = 0x00000003, - TriangleStrip = 0x00000004, + Undefined = 0x00000000, + PointList = 0x00000001, + LineList = 0x00000002, + LineStrip = 0x00000003, + TriangleList = 0x00000004, + TriangleStrip = 0x00000005, } QueryType :: enum i32 { // WebGPU. - Occlusion = 0x00000000, - Timestamp = 0x00000001, + Occlusion = 0x00000001, + Timestamp = 0x00000002, // Native. PipelineStatistics = 0x00030000, } QueueWorkDoneStatus :: enum i32 { - Success = 0x00000000, - Error = 0x00000001, - Unknown = 0x00000002, - DeviceLost = 0x00000003, + Success = 0x00000001, + InstanceDropped = 0x00000002, + Error = 0x00000003, + Unknown = 0x00000004, } RequestAdapterStatus :: enum i32 { - Success = 0x00000000, - Unavailable = 0x00000001, - Error = 0x00000002, - Unknown = 0x00000003, + Success = 0x00000001, + InstanceDropped = 0x00000002, + Unavailable = 0x00000003, + Error = 0x00000004, + Unknown = 0x00000005, } RequestDeviceStatus :: enum i32 { - Success = 0x00000000, - Error = 0x00000001, - Unknown = 0x00000002, + Success = 0x00000001, + InstanceDropped = 0x00000002, + Error = 0x00000003, + Unknown = 0x00000004, } SType :: enum i32 { // WebGPU. - Invalid = 0x00000000, - SurfaceDescriptorFromMetalLayer = 0x00000001, - SurfaceDescriptorFromWindowsHWND = 0x00000002, - SurfaceDescriptorFromXlibWindow = 0x00000003, - SurfaceDescriptorFromCanvasHTMLSelector = 0x00000004, - ShaderModuleSPIRVDescriptor = 0x00000005, - ShaderModuleWGSLDescriptor = 0x00000006, - PrimitiveDepthClipControl = 0x00000007, - SurfaceDescriptorFromWaylandSurface = 0x00000008, - SurfaceDescriptorFromAndroidNativeWindow = 0x00000009, - SurfaceDescriptorFromXcbWindow = 0x0000000A, - RenderPassDescriptorMaxDrawCount = 0x0000000F, + ShaderSourceSPIRV = 0x00000001, + ShaderSourceWGSL = 0x00000002, + RenderPassMaxDrawCount = 0x00000003, + SurfaceSourceMetalLayer = 0x00000004, + SurfaceSourceWindowsHWND = 0x00000005, + SurfaceSourceXlibWindow = 0x00000006, + SurfaceSourceWaylandSurface = 0x00000007, + SurfaceSourceAndroidNativeWindow = 0x00000008, + SurfaceSourceXCBWindow = 0x00000009, // Native. DeviceExtras = 0x00030001, - RequiredLimitsExtras, + NativeLimits, PipelineLayoutExtras, ShaderModuleGLSLDescriptor, SupportedLimitsExtras, @@ -396,31 +445,42 @@ SType :: enum i32 { BindGroupLayoutEntryExtras, QuerySetDescriptorExtras, SurfaceConfigurationExtras, + + // Odin. + SurfaceSourceCanvasHTMLSelector = 0x00040001, } SamplerBindingType :: enum i32 { - Undefined = 0x00000000, - Filtering = 0x00000001, - NonFiltering = 0x00000002, - Comparison = 0x00000003, + BindingNotUsed = 0x00000000, + Undefined = 0x00000001, + Filtering = 0x00000002, + NonFiltering = 0x00000003, + Comparison = 0x00000004, +} + +Status :: enum i32 { + Success = 0x00000001, + Error = 0x00000002, } StencilOperation :: enum i32 { - Keep = 0x00000000, - Zero = 0x00000001, - Replace = 0x00000002, - Invert = 0x00000003, - IncrementClamp = 0x00000004, - DecrementClamp = 0x00000005, - IncrementWrap = 0x00000006, - DecrementWrap = 0x00000007, + Undefined = 0x00000000, + Keep = 0x00000001, + Zero = 0x00000002, + Replace = 0x00000003, + Invert = 0x00000004, + IncrementClamp = 0x00000005, + DecrementClamp = 0x00000006, + IncrementWrap = 0x00000007, + DecrementWrap = 0x00000008, } StorageTextureAccess :: enum i32 { - Undefined = 0x00000000, - WriteOnly = 0x00000001, - ReadOnly = 0x00000002, - ReadWrite = 0x00000003, + BindingNotUsed = 0x00000000, + Undefined = 0x00000001, + WriteOnly = 0x00000002, + ReadOnly = 0x00000003, + ReadWrite = 0x00000004, } StoreOp :: enum i32 { @@ -430,24 +490,28 @@ StoreOp :: enum i32 { } SurfaceGetCurrentTextureStatus :: enum i32 { - Success = 0x00000000, - Timeout = 0x00000001, - Outdated = 0x00000002, - Lost = 0x00000003, - OutOfMemory = 0x00000004, - DeviceLost = 0x00000005, + SuccessOptimal = 0x00000001, + SuccessSuboptimal = 0x00000002, + Timeout = 0x00000003, + Outdated = 0x00000004, + Lost = 0x00000005, + OutOfMemory = 0x00000006, + DeviceLost = 0x00000007, + Error = 0x00000008, } TextureAspect :: enum i32 { - All = 0x00000000, - StencilOnly = 0x00000001, - DepthOnly = 0x00000002, + Undefined = 0x00000000, + All = 0x00000001, + StencilOnly = 0x00000002, + DepthOnly = 0x00000003, } TextureDimension :: enum i32 { - _1D = 0x00000000, - _2D = 0x00000001, - _3D = 0x00000002, + Undefined = 0x00000000, + _1D = 0x00000001, + _2D = 0x00000002, + _3D = 0x00000003, } TextureFormat :: enum i32 { @@ -562,12 +626,13 @@ TextureFormat :: enum i32 { } TextureSampleType :: enum i32 { - Undefined = 0x00000000, - Float = 0x00000001, - UnfilterableFloat = 0x00000002, - Depth = 0x00000003, - Sint = 0x00000004, - Uint = 0x00000005, + BindingNotUsed = 0x00000000, + Undefined = 0x00000001, + Float = 0x00000002, + UnfilterableFloat = 0x00000003, + Depth = 0x00000004, + Sint = 0x00000005, + Uint = 0x00000006, } TextureViewDimension :: enum i32 { @@ -581,53 +646,71 @@ TextureViewDimension :: enum i32 { } VertexFormat :: enum i32 { - Undefined = 0x00000000, - Uint8x2 = 0x00000001, - Uint8x4 = 0x00000002, - Sint8x2 = 0x00000003, - Sint8x4 = 0x00000004, - Unorm8x2 = 0x00000005, - Unorm8x4 = 0x00000006, - Snorm8x2 = 0x00000007, - Snorm8x4 = 0x00000008, - Uint16x2 = 0x00000009, - Uint16x4 = 0x0000000A, - Sint16x2 = 0x0000000B, - Sint16x4 = 0x0000000C, - Unorm16x2 = 0x0000000D, - Unorm16x4 = 0x0000000E, - Snorm16x2 = 0x0000000F, - Snorm16x4 = 0x00000010, - Float16x2 = 0x00000011, - Float16x4 = 0x00000012, - Float32 = 0x00000013, - Float32x2 = 0x00000014, - Float32x3 = 0x00000015, - Float32x4 = 0x00000016, - Uint32 = 0x00000017, - Uint32x2 = 0x00000018, - Uint32x3 = 0x00000019, - Uint32x4 = 0x0000001A, - Sint32 = 0x0000001B, - Sint32x2 = 0x0000001C, - Sint32x3 = 0x0000001D, - Sint32x4 = 0x0000001E, + Uint8 = 0x00000001, + Uint8x2 = 0x00000002, + Uint8x4 = 0x00000003, + Sint8 = 0x00000004, + Sint8x2 = 0x00000005, + Sint8x4 = 0x00000006, + Unorm8 = 0x00000007, + Unorm8x2 = 0x00000008, + Unorm8x4 = 0x00000009, + Snorm8 = 0x0000000A, + Snorm8x2 = 0x0000000B, + Snorm8x4 = 0x0000000C, + Uint16 = 0x0000000D, + Uint16x2 = 0x0000000E, + Uint16x4 = 0x0000000F, + Sint16 = 0x00000010, + Sint16x2 = 0x00000011, + Sint16x4 = 0x00000012, + Unorm16 = 0x00000013, + Unorm16x2 = 0x00000014, + Unorm16x4 = 0x00000015, + Snorm16 = 0x00000016, + Snorm16x2 = 0x00000017, + Snorm16x4 = 0x00000018, + Float16 = 0x00000019, + Float16x2 = 0x0000001A, + Float16x4 = 0x0000001B, + Float32 = 0x0000001C, + Float32x2 = 0x0000001D, + Float32x3 = 0x0000001E, + Float32x4 = 0x0000001F, + Uint32 = 0x00000020, + Uint32x2 = 0x00000021, + Uint32x3 = 0x00000022, + Uint32x4 = 0x00000023, + Sint32 = 0x00000024, + Sint32x2 = 0x00000025, + Sint32x3 = 0x00000026, + Sint32x4 = 0x00000027, + Unorm10_10_10_2 = 0x00000028, + Unorm8x4BGRA = 0x00000029, } VertexStepMode :: enum i32 { - Vertex = 0x00000000, - Instance = 0x00000001, - VertexBufferNotUsed = 0x00000002, + VertexBufferNotUsed = 0x00000000, + Undefined = 0x00000001, + Vertex = 0x00000002, + Instance = 0x00000003, } -WGSLFeatureName :: enum i32 { - Undefined = 0x00000000, +WGSLLanguageFeatureName :: enum i32 { ReadonlyAndReadwriteStorageTextures = 0x00000001, Packed4x8IntegerDotProduct = 0x00000002, UnrestrictedPointerParameters = 0x00000003, PointerCompositeAccess = 0x00000004, } +WaitStatus :: enum i32 { + Success = 0x00000001, + TimedOut = 0x00000002, + UnsupportedTimeout = 0x00000003, + UnsupportedCount = 0x00000004, + UnsupportedMixedSource = 0x00000005, +} + BufferUsage :: enum i32 { MapRead = 0x00000000, MapWrite = 0x00000001, @@ -675,16 +758,16 @@ TextureUsageFlags :: bit_set[TextureUsage; Flags] Proc :: distinct rawptr -DeviceLostCallback :: #type proc "c" (reason: DeviceLostReason, message: cstring, userdata: rawptr) -ErrorCallback :: #type proc "c" (type: ErrorType, message: cstring, userdata: rawptr) - -AdapterRequestDeviceCallback :: #type proc "c" (status: RequestDeviceStatus, device: Device, message: cstring, /* NULLABLE */ userdata: rawptr) -BufferMapAsyncCallback :: #type proc "c" (status: BufferMapAsyncStatus, /* NULLABLE */ userdata: rawptr) -DeviceCreateComputePipelineAsyncCallback :: #type proc "c" (status: CreatePipelineAsyncStatus, pipeline: ComputePipeline, message: cstring, /* NULLABLE */ userdata: rawptr) -DeviceCreateRenderPipelineAsyncCallback :: #type proc "c" (status: CreatePipelineAsyncStatus, pipeline: RenderPipeline, message: cstring, /* NULLABLE */ userdata: rawptr) -InstanceRequestAdapterCallback :: #type proc "c" (status: RequestAdapterStatus, adapter: Adapter, message: cstring, /* NULLABLE */ userdata: rawptr) -QueueOnSubmittedWorkDoneCallback :: #type proc "c" (status: QueueWorkDoneStatus, /* NULLABLE */ userdata: rawptr) -ShaderModuleGetCompilationInfoCallback :: #type proc "c" (status: CompilationInfoRequestStatus, compilationInfo: ^CompilationInfo, /* NULLABLE */ userdata: rawptr) +BufferMapCallback :: #type proc "c" (status: MapAsyncStatus, message: StringView, userdata1: rawptr, userdata2: rawptr) +CompilationInfoCallback :: #type proc "c" (status: CompilationInfoRequestStatus, compilationInfo: ^CompilationInfo, userdata1: rawptr, userdata2: rawptr) +CreateComputePipelineAsyncCallback :: #type proc "c" (status: CreatePipelineAsyncStatus, pipeline: ComputePipeline, message: StringView, userdata1: rawptr, userdata2: rawptr) +CreateRenderPipelineAsyncCallback :: #type proc "c" (status: CreatePipelineAsyncStatus, pipeline: RenderPipeline, message: StringView, userdata1: rawptr, userdata2: rawptr) +DeviceLostCallback :: #type proc "c" (device: Device, reason: DeviceLostReason, message: StringView, userdata1: rawptr, userdata2: rawptr) +PopErrorScopeCallback :: #type proc "c" (status: PopErrorScopeStatus, type: ErrorType, message: StringView, userdata1: rawptr, userdata2: rawptr) +QueueWorkDoneCallback :: #type proc "c" (status: QueueWorkDoneStatus, userdata1: rawptr, userdata2: rawptr) +RequestAdapterCallback :: #type proc "c" (status: RequestAdapterStatus, adapter: Adapter, message: StringView, userdata1: rawptr, userdata2: rawptr) +RequestDeviceCallback :: #type proc "c" (status: RequestDeviceStatus, adapter: Device, message: StringView, userdata1: rawptr, userdata2: rawptr) +UncapturedErrorCallback :: #type proc "c" (device: Device, type: ErrorType, message: StringView, userdata1: rawptr, userdata2: rawptr) ChainedStruct :: struct { next: ^ChainedStruct, @@ -696,24 +779,96 @@ ChainedStructOut :: struct { sType: SType, } +BufferMapCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: BufferMapCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +CompilationInfoCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: CompilationInfoCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +CreateComputePipelineAsyncCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: CreateComputePipelineAsyncCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +CreateRenderPipelineAsyncCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: CreateRenderPipelineAsyncCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +DeviceLostCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: DeviceLostCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +PopErrorScopeCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: PopErrorScopeCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +QueueWorkDoneCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: QueueWorkDoneCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +RequestAdapterCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: RequestAdapterCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +RequestDeviceCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + mode: CallbackMode, + callback: RequestDeviceCallback, + userdata1: rawptr, + userdata2: rawptr, +} + +UncapturedErrorCallbackInfo :: struct { + nextInChain: ^ChainedStructOut, + callback: UncapturedErrorCallback, + userdata1: rawptr, + userdata2: rawptr, +} + AdapterInfo :: struct { nextInChain: ^ChainedStructOut, - vendor: cstring, - architecture: cstring, - device: cstring, - description: cstring, + vendor: StringView, + architecture: StringView, + device: StringView, + description: StringView, backendType: BackendType, adapterType: AdapterType, vendorID: u32, deviceID: u32, } -when ODIN_OS == .JS { - #assert(int(BackendType.WebGPU) == 2) - #assert(offset_of(AdapterInfo, backendType) == 20) - - #assert(int(AdapterType.Unknown) == 3) - #assert(offset_of(AdapterInfo, adapterType) == 24) -} BindGroupEntry :: struct { nextInChain: ^ChainedStruct, @@ -740,7 +895,7 @@ BufferBindingLayout :: struct { BufferDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, usage: BufferUsageFlags, size: u64, mappedAtCreation: b32, @@ -750,25 +905,22 @@ Color :: [4]f64 CommandBufferDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, } CommandEncoderDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, } CompilationMessage :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ message: cstring, + message: StringView, type: CompilationMessageType, lineNum: u64, linePos: u64, offset: u64, length: u64, - utf16LinePos: u64, - utf16Offset: u64, - utf16Length: u64, } ComputePassTimestampWrites :: struct { @@ -779,7 +931,7 @@ ComputePassTimestampWrites :: struct { ConstantEntry :: struct { nextInChain: ^ChainedStruct, - key: cstring, + key: StringView, value: f64, } @@ -789,11 +941,18 @@ Extent3D :: struct { depthOrArrayLayers: u32, } -InstanceDescriptor :: struct { - nextInChain: ^ChainedStruct, +Future :: struct { + id: u64, +} + +InstanceCapabilities :: struct { + nextInChain: ^ChainedStructOut, + timedWaitAnyEnable: b32, + timedWaitAnyMaxCount: uint, } Limits :: struct { + nextInChain: ^ChainedStructOut, maxTextureDimension1D: u32, maxTextureDimension2D: u32, maxTextureDimension3D: u32, @@ -816,7 +975,6 @@ Limits :: struct { maxBufferSize: u64, maxVertexAttributes: u32, maxVertexBufferArrayStride: u32, - maxInterStageShaderComponents: u32, maxInterStageShaderVariables: u32, maxColorAttachments: u32, maxColorAttachmentBytesPerSample: u32, @@ -843,44 +1001,40 @@ Origin3D :: struct { PipelineLayoutDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, bindGroupLayoutCount: uint, bindGroupLayouts: [^]BindGroupLayout `fmt:"v,bindGroupLayoutCount"`, } -PrimitiveDepthClipControl :: struct { - using chain: ChainedStruct, - unclippedDepth: b32, -} - PrimitiveState :: struct { nextInChain: ^ChainedStruct, topology: PrimitiveTopology, stripIndexFormat: IndexFormat, frontFace: FrontFace, cullMode: CullMode, + unclippedDepth: b32, } QuerySetDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, type: QueryType, count: u32, } QueueDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, } RenderBundleDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, } RenderBundleEncoderDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, colorFormatCount: uint, colorFormats: [^]TextureFormat `fmt:"v,colorFormatCount"`, depthStencilFormat: TextureFormat, @@ -901,7 +1055,7 @@ RenderPassDepthStencilAttachment :: struct { stencilReadOnly: b32, } -RenderPassDescriptorMaxDrawCount :: struct { +RenderPassMaxDrawCount :: struct { using chain: ChainedStruct, maxDrawCount: u64, } @@ -914,10 +1068,11 @@ RenderPassTimestampWrites :: struct { RequestAdapterOptions :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ compatibleSurface: Surface, + featureLevel: FeatureLevel, powerPreference: PowerPreference, - backendType: BackendType, forceFallbackAdapter: b32, + backendType: BackendType, + /* NULLABLE */ compatibleSurface: Surface, } SamplerBindingLayout :: struct { @@ -927,7 +1082,7 @@ SamplerBindingLayout :: struct { SamplerDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, addressModeU: AddressMode, addressModeV: AddressMode, addressModeW: AddressMode, @@ -940,21 +1095,20 @@ SamplerDescriptor :: struct { maxAnisotropy: u16, } -ShaderModuleCompilationHint :: struct { +ShaderModuleDescriptor :: struct { nextInChain: ^ChainedStruct, - entryPoint: cstring, - layout: PipelineLayout, + label: StringView, } -ShaderModuleSPIRVDescriptor :: struct { +ShaderSourceSPIRV :: struct { using chain: ChainedStruct, codeSize: u32, code: /* const */ [^]u32 `fmt:"v,codeSize"`, } -ShaderModuleWGSLDescriptor :: struct { +ShaderSourceWGSL :: struct { using chain: ChainedStruct, - code: cstring, + code: StringView, } StencilFaceState :: struct { @@ -971,6 +1125,16 @@ StorageTextureBindingLayout :: struct { viewDimension: TextureViewDimension, } +SupportedFeatures :: struct { + featureCount: uint, + features: [^]FeatureName `fmt:"v,featureCount"`, +} + +SupportedWGSLLanguageFeatures :: struct { + featureCount: uint, + features: [^]WGSLLanguageFeatureName `fmt:"v,featureCount"`, +} + SurfaceCapabilities :: struct { nextInChain: ^ChainedStructOut, usages: TextureUsageFlags, @@ -981,80 +1145,76 @@ SurfaceCapabilities :: struct { alphaModeCount: uint, alphaModes: /* const */ [^]CompositeAlphaMode `fmt:"v,alphaModeCount"`, } -when ODIN_OS == .JS { - #assert(offset_of(SurfaceCapabilities, formatCount) == 8) - #assert(offset_of(SurfaceCapabilities, formats) == 8 + 1*size_of(int)) - - #assert(offset_of(SurfaceCapabilities, presentModeCount) == 8 + 2*size_of(int)) - #assert(offset_of(SurfaceCapabilities, presentModes) == 8 + 3*size_of(int)) - - #assert(offset_of(SurfaceCapabilities, alphaModeCount) == 8 + 4*size_of(int)) - #assert(offset_of(SurfaceCapabilities, alphaModes) == 8 + 5*size_of(int)) -} SurfaceConfiguration :: struct { nextInChain: ^ChainedStruct, device: Device, format: TextureFormat, usage: TextureUsageFlags, + width: u32, + height: u32, viewFormatCount: uint, viewFormats: [^]TextureFormat `fmt:"v,viewFormatCount"`, alphaMode: CompositeAlphaMode, - width: u32, - height: u32, presentMode: PresentMode, } SurfaceDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, } -SurfaceDescriptorFromAndroidNativeWindow :: struct { +SurfaceSourceAndroidNativeWindow :: struct { using chain: ChainedStruct, window: rawptr, } -SurfaceDescriptorFromCanvasHTMLSelector :: struct { +SurfaceSourceCanvasHTMLSelector :: struct { using chain: ChainedStruct, - selector: cstring, + selector: StringView, } -SurfaceDescriptorFromMetalLayer :: struct { +SurfaceSourceMetalLayer :: struct { using chain: ChainedStruct, layer: rawptr, } -SurfaceDescriptorFromWaylandSurface :: struct { +SurfaceSourceWaylandSurface :: struct { using chain: ChainedStruct, display: rawptr, surface: rawptr, } -SurfaceDescriptorFromWindowsHWND :: struct { +SurfaceSourceWindowsHWND :: struct { using chain: ChainedStruct, hinstance: rawptr, hwnd: rawptr, } -SurfaceDescriptorFromXcbWindow :: struct { +SurfaceSourceXcbWindow :: struct { using chain: ChainedStruct, connection: rawptr, window: u32, } -SurfaceDescriptorFromXlibWindow :: struct { +SurfaceSourceXlibWindow :: struct { using chain: ChainedStruct, display: rawptr, window: u64, } SurfaceTexture :: struct { + nextInChain: ^ChainedStruct, texture: Texture, - suboptimal: b32, status: SurfaceGetCurrentTextureStatus, } +TexelCopyBufferLayout :: struct { + offset: u64, + bytesPerRow: u32, + rowsPerImage: u32, +} + TextureBindingLayout :: struct { nextInChain: ^ChainedStruct, sampleType: TextureSampleType, @@ -1062,16 +1222,9 @@ TextureBindingLayout :: struct { multisampled: b32, } -TextureDataLayout :: struct { - nextInChain: ^ChainedStruct, - offset: u64, - bytesPerRow: u32, - rowsPerImage: u32, -} - TextureViewDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, format: TextureFormat, dimension: TextureViewDimension, baseMipLevel: u32, @@ -1079,12 +1232,7 @@ TextureViewDescriptor :: struct { baseArrayLayer: u32, arrayLayerCount: u32, aspect: TextureAspect, -} - -UncapturedErrorCallbackInfo :: struct { - nextInChain: ^ChainedStruct, - callback: ErrorCallback, - userdata: rawptr, + usage: TextureUsageFlags, } VertexAttribute :: struct { @@ -1095,7 +1243,7 @@ VertexAttribute :: struct { BindGroupDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, layout: BindGroupLayout, entryCount: uint, entries: [^]BindGroupEntry `fmt:"v,entryCount"`, @@ -1124,14 +1272,14 @@ CompilationInfo :: struct { ComputePassDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, /* NULLABLE */ timestampWrites: /* const */ ^ComputePassTimestampWrites, } DepthStencilState :: struct { nextInChain: ^ChainedStruct, format: TextureFormat, - depthWriteEnabled: b32, + depthWriteEnabled: OptionalBool, depthCompare: CompareFunction, stencilFront: StencilFaceState, stencilBack: StencilFaceState, @@ -1142,24 +1290,31 @@ DepthStencilState :: struct { depthBiasClamp: f32, } -ImageCopyBuffer :: struct { +DeviceDescriptor :: struct { nextInChain: ^ChainedStruct, - layout: TextureDataLayout, - buffer: Buffer, + label: StringView, + requiredFeatureCount: uint, + requiredFeatures: [^]FeatureName `fmt:"v,requiredFeatureCount"`, + /* NULLABLE */ requiredLimits: /* const */ ^Limits, + defaultQueue: QueueDescriptor, + deviceLostCallbackInfo: DeviceLostCallbackInfo, + uncapturedErrorCallbackInfo: UncapturedErrorCallbackInfo, +} + +FutureWaitInfo :: struct { + future: Future, + completed: b32, } -ImageCopyTexture :: struct { +InstanceDescriptor :: struct { nextInChain: ^ChainedStruct, - texture: Texture, - mipLevel: u32, - origin: Origin3D, - aspect: TextureAspect, + features: InstanceCapabilities, } ProgrammableStageDescriptor :: struct { nextInChain: ^ChainedStruct, module: ShaderModule, - /* NULLABLE */ entryPoint: cstring, + entryPoint: StringView, constantCount: uint, constants: [^]ConstantEntry `fmt:"v,constantCount"`, } @@ -1173,36 +1328,22 @@ RenderPassColorAttachment :: struct { storeOp: StoreOp, clearValue: Color, } -when ODIN_OS == .JS { - #assert(size_of(RenderPassColorAttachment) == 56) - #assert(offset_of(RenderPassColorAttachment, view) == 4) - #assert(offset_of(RenderPassColorAttachment, depthSlice) == 8) - #assert(offset_of(RenderPassColorAttachment, resolveTarget) == 12) - #assert(offset_of(RenderPassColorAttachment, loadOp) == 16) - #assert(offset_of(RenderPassColorAttachment, storeOp) == 20) - #assert(offset_of(RenderPassColorAttachment, clearValue) == 24) -} -RequiredLimits :: struct { - nextInChain: ^ChainedStruct, - limits: Limits, -} - -ShaderModuleDescriptor :: struct { - nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, - hintCount: uint, - hints: [^]ShaderModuleCompilationHint `fmt:"v,hintCount"`, +TexelCopyBufferInfo :: struct { + layout: TexelCopyBufferLayout, + buffer: Buffer, } -SupportedLimits :: struct { - nextInChain: ^ChainedStructOut, - limits: Limits, +TexelCopyTextureInfo :: struct { + texture: Texture, + mipLevel: u32, + origin: Origin3D, + aspect: TextureAspect, } TextureDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, usage: TextureUsageFlags, dimension: TextureDimension, size: Extent3D, @@ -1214,15 +1355,15 @@ TextureDescriptor :: struct { } VertexBufferLayout :: struct { - arrayStride: u64, stepMode: VertexStepMode, + arrayStride: u64, attributeCount: uint, attributes: [^]VertexAttribute `fmt:"v,attributeCount"`, } BindGroupLayoutDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, entryCount: uint, entries: [^]BindGroupLayoutEntry `fmt:"v,entryCount"`, } @@ -1236,29 +1377,14 @@ ColorTargetState :: struct { ComputePipelineDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, /* NULLABLE */ layout: PipelineLayout, compute: ProgrammableStageDescriptor, } -DeviceDescriptor :: struct { - nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, - requiredFeatureCount: uint, - requiredFeatures: [^]FeatureName `fmt:"v,requiredFeatureCount"`, - /* NULLABLE */ requiredLimits: /* const */ ^RequiredLimits, - defaultQueue: QueueDescriptor, - deviceLostCallback: DeviceLostCallback, - deviceLostUserdata: rawptr, - uncapturedErrorCallbackInfo: UncapturedErrorCallbackInfo, -} -when ODIN_OS == .JS { - #assert(offset_of(DeviceDescriptor, deviceLostCallback) == 24 + size_of(int)) -} - RenderPassDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, colorAttachmentCount: uint, colorAttachments: [^]RenderPassColorAttachment `fmt:"v,colorAttachmentCount"`, /* NULLABLE */ depthStencilAttachment: /* const */ ^RenderPassDepthStencilAttachment, @@ -1269,7 +1395,7 @@ RenderPassDescriptor :: struct { VertexState :: struct { nextInChain: ^ChainedStruct, module: ShaderModule, - /* NULLABLE */ entryPoint: cstring, + entryPoint: StringView, constantCount: uint, constants: [^]ConstantEntry `fmt:"v,constantCount"`, bufferCount: uint, @@ -1279,7 +1405,7 @@ VertexState :: struct { FragmentState :: struct { nextInChain: ^ChainedStruct, module: ShaderModule, - /* NULLABLE */ entryPoint: cstring, + entryPoint: StringView, constantCount: uint, constants: [^]ConstantEntry `fmt:"v,constantCount"`, targetCount: uint, @@ -1288,7 +1414,7 @@ FragmentState :: struct { RenderPipelineDescriptor :: struct { nextInChain: ^ChainedStruct, - /* NULLABLE */ label: cstring, + label: StringView, /* NULLABLE */ layout: PipelineLayout, vertex: VertexState, primitive: PrimitiveState, @@ -1301,26 +1427,28 @@ RenderPipelineDescriptor :: struct { foreign libwgpu { @(link_name="wgpuCreateInstance") RawCreateInstance :: proc(/* NULLABLE */ descriptor: /* const */ ^InstanceDescriptor = nil) -> Instance --- - GetProcAddress :: proc(device: Device, procName: cstring) -> Proc --- + @(link_name="wgpuGetInstanceCapabilities") + RawGetInstanceCapabilities :: proc(capabilities: ^InstanceCapabilities) -> Status --- + GetProcAddress :: proc(procName: StringView) -> Proc --- // Methods of Adapter - @(link_name="wgpuAdapterEnumerateFeatures") - RawAdapterEnumerateFeatures :: proc(adapter: Adapter, features: [^]FeatureName) -> uint --- + @(link_name="wgpuAdapterGetFeatures") + RawAdapterGetFeatures :: proc(adapter: Adapter, features: ^SupportedFeatures) --- @(link_name="wgpuAdapterGetInfo") - RawAdapterGetInfo :: proc(adapter: Adapter, info: ^AdapterInfo) --- + RawAdapterGetInfo :: proc(adapter: Adapter, info: ^AdapterInfo) -> Status --- @(link_name="wgpuAdapterGetLimits") - RawAdapterGetLimits :: proc(adapter: Adapter, limits: ^SupportedLimits) -> b32 --- + RawAdapterGetLimits :: proc(adapter: Adapter, limits: ^Limits) -> Status --- AdapterHasFeature :: proc(adapter: Adapter, feature: FeatureName) -> b32 --- - AdapterRequestDevice :: proc(adapter: Adapter, /* NULLABLE */ descriptor: /* const */ ^DeviceDescriptor, callback: AdapterRequestDeviceCallback, /* NULLABLE */ userdata: rawptr = nil) --- - AdapterReference :: proc(adapter: Adapter) --- + AdapterRequestDevice :: proc(adapter: Adapter, /* NULLABLE */ descriptor: /* const */ ^DeviceDescriptor, callbackInfo: RequestDeviceCallbackInfo) -> Future --- + AdapterAddRef :: proc(adapter: Adapter) --- AdapterRelease :: proc(adapter: Adapter) --- // Procs of AdapterInfo AdapterInfoFreeMembers :: proc(adapterInfo: AdapterInfo) --- // Methods of BindGroup - BindGroupSetLabel :: proc(bindGroup: BindGroup, label: cstring) --- - BindGroupReference :: proc(bindGroup: BindGroup) --- + BindGroupSetLabel :: proc(bindGroup: BindGroup, label: StringView) --- + BindGroupAddRef :: proc(bindGroup: BindGroup) --- BindGroupRelease :: proc(bindGroup: BindGroup) --- // Methods of BindGroupLayout @@ -1337,15 +1465,15 @@ foreign libwgpu { RawBufferGetMappedRange :: proc(buffer: Buffer, offset: uint, size: uint) -> rawptr --- BufferGetSize :: proc(buffer: Buffer) -> u64 --- BufferGetUsage :: proc(buffer: Buffer) -> BufferUsageFlags --- - BufferMapAsync :: proc(buffer: Buffer, mode: MapModeFlags, offset: uint, size: uint, callback: BufferMapAsyncCallback, /* NULLABLE */ userdata: rawptr = nil) --- - BufferSetLabel :: proc(buffer: Buffer, label: cstring) --- + BufferMapAsync :: proc(buffer: Buffer, mode: MapModeFlags, offset: uint, size: uint, callback: BufferMapCallbackInfo) -> Future --- + BufferSetLabel :: proc(buffer: Buffer, label: StringView) --- BufferUnmap :: proc(buffer: Buffer) --- - BufferReference :: proc(buffer: Buffer) --- + BufferAddRef :: proc(buffer: Buffer) --- BufferRelease :: proc(buffer: Buffer) --- // Methods of CommandBuffer - CommandBufferSetLabel :: proc(commandBuffer: CommandBuffer, label: cstring) --- - CommandBufferReference :: proc(commandBuffer: CommandBuffer) --- + CommandBufferSetLabel :: proc(commandBuffer: CommandBuffer, label: StringView) --- + CommandBufferAddRef :: proc(commandBuffer: CommandBuffer) --- CommandBufferRelease :: proc(commandBuffer: CommandBuffer) --- // Methods of CommandEncoder @@ -1353,37 +1481,37 @@ foreign libwgpu { CommandEncoderBeginRenderPass :: proc(commandEncoder: CommandEncoder, descriptor: /* const */ ^RenderPassDescriptor) -> RenderPassEncoder --- CommandEncoderClearBuffer :: proc(commandEncoder: CommandEncoder, buffer: Buffer, offset: u64, size: u64) --- CommandEncoderCopyBufferToBuffer :: proc(commandEncoder: CommandEncoder, source: Buffer, sourceOffset: u64, destination: Buffer, destinationOffset: u64, size: u64) --- - CommandEncoderCopyBufferToTexture :: proc(commandEncoder: CommandEncoder, source: /* const */ ^ImageCopyBuffer, destination: /* const */ ^ImageCopyTexture, copySize: /* const */ ^Extent3D) --- - CommandEncoderCopyTextureToBuffer :: proc(commandEncoder: CommandEncoder, source: /* const */ ^ImageCopyTexture, destination: /* const */ ^ImageCopyBuffer, copySize: /* const */ ^Extent3D) --- - CommandEncoderCopyTextureToTexture :: proc(commandEncoder: CommandEncoder, source: /* const */ ^ImageCopyTexture, destination: /* const */ ^ImageCopyTexture, copySize: /* const */ ^Extent3D) --- + CommandEncoderCopyBufferToTexture :: proc(commandEncoder: CommandEncoder, source: /* const */ ^TexelCopyBufferInfo, destination: /* const */ ^TexelCopyTextureInfo, copySize: /* const */ ^Extent3D) --- + CommandEncoderCopyTextureToBuffer :: proc(commandEncoder: CommandEncoder, source: /* const */ ^TexelCopyTextureInfo, destination: /* const */ ^TexelCopyBufferInfo, copySize: /* const */ ^Extent3D) --- + CommandEncoderCopyTextureToTexture :: proc(commandEncoder: CommandEncoder, source: /* const */ ^TexelCopyTextureInfo, destination: /* const */ ^TexelCopyTextureInfo, copySize: /* const */ ^Extent3D) --- CommandEncoderFinish :: proc(commandEncoder: CommandEncoder, /* NULLABLE */ descriptor: /* const */ ^CommandBufferDescriptor = nil) -> CommandBuffer --- - CommandEncoderInsertDebugMarker :: proc(commandEncoder: CommandEncoder, markerLabel: cstring) --- + CommandEncoderInsertDebugMarker :: proc(commandEncoder: CommandEncoder, markerLabel: StringView) --- CommandEncoderPopDebugGroup :: proc(commandEncoder: CommandEncoder) --- - CommandEncoderPushDebugGroup :: proc(commandEncoder: CommandEncoder, groupLabel: cstring) --- + CommandEncoderPushDebugGroup :: proc(commandEncoder: CommandEncoder, groupLabel: StringView) --- CommandEncoderResolveQuerySet :: proc(commandEncoder: CommandEncoder, querySet: QuerySet, firstQuery: u32, queryCount: u32, destination: Buffer, destinationOffset: u64) --- - CommandEncoderSetLabel :: proc(commandEncoder: CommandEncoder, label: cstring) --- + CommandEncoderSetLabel :: proc(commandEncoder: CommandEncoder, label: StringView) --- CommandEncoderWriteTimestamp :: proc(commandEncoder: CommandEncoder, querySet: QuerySet, queryIndex: u32) --- - CommandEncoderReference :: proc(commandEncoder: CommandEncoder) --- + CommandEncoderAddRef :: proc(commandEncoder: CommandEncoder) --- CommandEncoderRelease :: proc(commandEncoder: CommandEncoder) --- // Methods of ComputePassEncoder ComputePassEncoderDispatchWorkgroups :: proc(computePassEncoder: ComputePassEncoder, workgroupCountX: u32, workgroupCountY: u32, workgroupCountZ: u32) --- ComputePassEncoderDispatchWorkgroupsIndirect :: proc(computePassEncoder: ComputePassEncoder, indirectBuffer: Buffer, indirectOffset: u64) --- ComputePassEncoderEnd :: proc(computePassEncoder: ComputePassEncoder) --- - ComputePassEncoderInsertDebugMarker :: proc(computePassEncoder: ComputePassEncoder, markerLabel: cstring) --- + ComputePassEncoderInsertDebugMarker :: proc(computePassEncoder: ComputePassEncoder, markerLabel: StringView) --- ComputePassEncoderPopDebugGroup :: proc(computePassEncoder: ComputePassEncoder) --- - ComputePassEncoderPushDebugGroup :: proc(computePassEncoder: ComputePassEncoder, groupLabel: cstring) --- + ComputePassEncoderPushDebugGroup :: proc(computePassEncoder: ComputePassEncoder, groupLabel: StringView) --- @(link_name="wgpuComputePassEncoderSetBindGroup") RawComputePassEncoderSetBindGroup :: proc(computePassEncoder: ComputePassEncoder, groupIndex: u32, /* NULLABLE */ group: BindGroup, dynamicOffsetCount: uint, dynamicOffsets: [^]u32) --- - ComputePassEncoderSetLabel :: proc(computePassEncoder: ComputePassEncoder, label: cstring) --- + ComputePassEncoderSetLabel :: proc(computePassEncoder: ComputePassEncoder, label: StringView) --- ComputePassEncoderSetPipeline :: proc(computePassEncoder: ComputePassEncoder, pipeline: ComputePipeline) --- - ComputePassEncoderReference :: proc(computePassEncoder: ComputePassEncoder) --- + ComputePassEncoderAddRef :: proc(computePassEncoder: ComputePassEncoder) --- ComputePassEncoderRelease :: proc(computePassEncoder: ComputePassEncoder) --- // Methods of ComputePipeline ComputePipelineGetBindGroupLayout :: proc(computePipeline: ComputePipeline, groupIndex: u32) -> BindGroupLayout --- - ComputePipelineSetLabel :: proc(computePipeline: ComputePipeline, label: cstring) --- - ComputePipelineReference :: proc(computePipeline: ComputePipeline) --- + ComputePipelineSetLabel :: proc(computePipeline: ComputePipeline, label: StringView) --- + ComputePipelineAddRef :: proc(computePipeline: ComputePipeline) --- ComputePipelineRelease :: proc(computePipeline: ComputePipeline) --- // Methods of Device @@ -1392,62 +1520,68 @@ foreign libwgpu { DeviceCreateBuffer :: proc(device: Device, descriptor: /* const */ ^BufferDescriptor) -> Buffer --- DeviceCreateCommandEncoder :: proc(device: Device, /* NULLABLE */ descriptor: /* const */ ^CommandEncoderDescriptor = nil) -> CommandEncoder --- DeviceCreateComputePipeline :: proc(device: Device, descriptor: /* const */ ^ComputePipelineDescriptor) -> ComputePipeline --- - DeviceCreateComputePipelineAsync :: proc(device: Device, descriptor: /* const */ ^ComputePipelineDescriptor, callback: DeviceCreateComputePipelineAsyncCallback, /* NULLABLE */ userdata: rawptr = nil) --- + DeviceCreateComputePipelineAsync :: proc(device: Device, descriptor: /* const */ ^ComputePipelineDescriptor, callbackInfo: CreateComputePipelineAsyncCallbackInfo) -> Future --- DeviceCreatePipelineLayout :: proc(device: Device, descriptor: /* const */ ^PipelineLayoutDescriptor) -> PipelineLayout --- DeviceCreateQuerySet :: proc(device: Device, descriptor: /* const */ ^QuerySetDescriptor) -> QuerySet --- DeviceCreateRenderBundleEncoder :: proc(device: Device, descriptor: /* const */ ^RenderBundleEncoderDescriptor) -> RenderBundleEncoder --- DeviceCreateRenderPipeline :: proc(device: Device, descriptor: /* const */ ^RenderPipelineDescriptor) -> RenderPipeline --- - DeviceCreateRenderPipelineAsync :: proc(device: Device, descriptor: /* const */ ^RenderPipelineDescriptor, callback: DeviceCreateRenderPipelineAsyncCallback, /* NULLABLE */ userdata: rawptr = nil) --- + DeviceCreateRenderPipelineAsync :: proc(device: Device, descriptor: /* const */ ^RenderPipelineDescriptor, callbackInfo: CreateRenderPipelineAsyncCallbackInfo) -> Future --- DeviceCreateSampler :: proc(device: Device, /* NULLABLE */ descriptor: /* const */ ^SamplerDescriptor = nil) -> Sampler --- DeviceCreateShaderModule :: proc(device: Device, descriptor: /* const */ ^ShaderModuleDescriptor) -> ShaderModule --- DeviceCreateTexture :: proc(device: Device, descriptor: /* const */ ^TextureDescriptor) -> Texture --- DeviceDestroy :: proc(device: Device) --- - @(link_name="wgpuDeviceEnumerateFeatures") - RawDeviceEnumerateFeatures :: proc(device: Device, features: ^FeatureName) -> uint --- + @(link_name="wgpuDeviceGetAdapterInfo") + RawDeviceGetAdapterInfo :: proc(device: Device, info: ^AdapterInfo) -> Status --- + @(link_name="wgpuDeviceGetFeatures") + RawDeviceGetFeatures :: proc(device: Device, features: ^SupportedFeatures) --- @(link_name="wgpuDeviceGetLimits") - RawDeviceGetLimits :: proc(device: Device, limits: ^SupportedLimits) -> b32 --- + RawDeviceGetLimits :: proc(device: Device, limits: ^Limits) -> Status --- + DeviceGetLostFuture :: proc(device: Device) -> Future --- DeviceGetQueue :: proc(device: Device) -> Queue --- DeviceHasFeature :: proc(device: Device, feature: FeatureName) -> b32 --- - DevicePopErrorScope :: proc(device: Device, callback: ErrorCallback, userdata: rawptr) --- + DevicePopErrorScope :: proc(device: Device, callbackInfo: PopErrorScopeCallbackInfo) -> Future --- DevicePushErrorScope :: proc(device: Device, filter: ErrorFilter) --- - DeviceSetLabel :: proc(device: Device, label: cstring) --- - DeviceReference :: proc(device: Device) --- + DeviceSetLabel :: proc(device: Device, label: StringView) --- + DeviceAddRef :: proc(device: Device) --- DeviceRelease :: proc(device: Device) --- // Methods of Instance InstanceCreateSurface :: proc(instance: Instance, descriptor: /* const */ ^SurfaceDescriptor) -> Surface --- - InstanceHasWGSLLanguageFeature :: proc(instance: Instance, feature: WGSLFeatureName) -> b32 --- + @(link_name="wgpuInstanceGetWGSLLanguageFeatures") + RawInstanceGetWGSLLanguageFeatures :: proc(instance: Instance, features: ^SupportedWGSLLanguageFeatures) -> Status --- + InstanceHasWGSLLanguageFeature :: proc(instance: Instance, feature: WGSLLanguageFeatureName) -> b32 --- InstanceProcessEvents :: proc(instance: Instance) --- - InstanceRequestAdapter :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^RequestAdapterOptions, callback: InstanceRequestAdapterCallback, /* NULLABLE */ userdata: rawptr = nil) --- - InstanceReference :: proc(instance: Instance) --- + InstanceRequestAdapter :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^RequestAdapterOptions, callbackInfo: RequestAdapterCallbackInfo) -> Future --- + InstanceWaitAny :: proc(instance: Instance, futureCount: uint, futures: [^]FutureWaitInfo, timeoutNS: u64) -> WaitStatus --- + InstanceAddRef :: proc(instance: Instance) --- InstanceRelease :: proc(instance: Instance) --- // Methods of PipelineLayout - PipelineLayoutSetLabel :: proc(pipelineLayout: PipelineLayout, label: cstring) --- - PipelineLayoutReference :: proc(pipelineLayout: PipelineLayout) --- + PipelineLayoutSetLabel :: proc(pipelineLayout: PipelineLayout, label: StringView) --- + PipelineLayoutAddRef :: proc(pipelineLayout: PipelineLayout) --- PipelineLayoutRelease :: proc(pipelineLayout: PipelineLayout) --- // Methods of QuerySet QuerySetDestroy :: proc(querySet: QuerySet) --- QuerySetGetCount :: proc(querySet: QuerySet) -> u32 --- QuerySetGetType :: proc(querySet: QuerySet) -> QueryType --- - QuerySetSetLabel :: proc(querySet: QuerySet, label: cstring) --- - QuerySetReference :: proc(querySet: QuerySet) --- + QuerySetSetLabel :: proc(querySet: QuerySet, label: StringView) --- + QuerySetAddRef :: proc(querySet: QuerySet) --- QuerySetRelease :: proc(querySet: QuerySet) --- // Methods of Queue - QueueOnSubmittedWorkDone :: proc(queue: Queue, callback: QueueOnSubmittedWorkDoneCallback, /* NULLABLE */ userdata: rawptr = nil) --- - QueueSetLabel :: proc(queue: Queue, label: cstring) --- + QueueOnSubmittedWorkDone :: proc(queue: Queue, callbackInfo: QueueWorkDoneCallbackInfo) -> Future --- + QueueSetLabel :: proc(queue: Queue, label: StringView) --- @(link_name="wgpuQueueSubmit") RawQueueSubmit :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) --- QueueWriteBuffer :: proc(queue: Queue, buffer: Buffer, bufferOffset: u64, data: /* const */ rawptr, size: uint) --- - QueueWriteTexture :: proc(queue: Queue, destination: /* const */ ^ImageCopyTexture, data: /* const */ rawptr, dataSize: uint, dataLayout: /* const */ ^TextureDataLayout, writeSize: /* const */ ^Extent3D) --- - QueueReference :: proc(queue: Queue) --- + QueueWriteTexture :: proc(queue: Queue, destination: /* const */ ^TexelCopyTextureInfo, data: /* const */ rawptr, dataSize: uint, dataLayout: /* const */ ^TexelCopyBufferLayout, writeSize: /* const */ ^Extent3D) --- + QueueAddRef :: proc(queue: Queue) --- QueueRelease :: proc(queue: Queue) --- // Methods of RenderBundle - RenderBundleSetLabel :: proc(renderBundle: RenderBundle, label: cstring) --- - RenderBundleReference :: proc(renderBundle: RenderBundle) --- + RenderBundleSetLabel :: proc(renderBundle: RenderBundle, label: StringView) --- + RenderBundleAddRef :: proc(renderBundle: RenderBundle) --- RenderBundleRelease :: proc(renderBundle: RenderBundle) --- // Methods of RenderBundleEncoder @@ -1456,16 +1590,16 @@ foreign libwgpu { RenderBundleEncoderDrawIndexedIndirect :: proc(renderBundleEncoder: RenderBundleEncoder, indirectBuffer: Buffer, indirectOffset: u64) --- RenderBundleEncoderDrawIndirect :: proc(renderBundleEncoder: RenderBundleEncoder, indirectBuffer: Buffer, indirectOffset: u64) --- RenderBundleEncoderFinish :: proc(renderBundleEncoder: RenderBundleEncoder, /* NULLABLE */ descriptor: /* const */ ^RenderBundleDescriptor = nil) -> RenderBundle --- - RenderBundleEncoderInsertDebugMarker :: proc(renderBundleEncoder: RenderBundleEncoder, markerLabel: cstring) --- + RenderBundleEncoderInsertDebugMarker :: proc(renderBundleEncoder: RenderBundleEncoder, markerLabel: StringView) --- RenderBundleEncoderPopDebugGroup :: proc(renderBundleEncoder: RenderBundleEncoder) --- - RenderBundleEncoderPushDebugGroup :: proc(renderBundleEncoder: RenderBundleEncoder, groupLabel: cstring) --- + RenderBundleEncoderPushDebugGroup :: proc(renderBundleEncoder: RenderBundleEncoder, groupLabel: StringView) --- @(link_name="wgpuRenderBundleEncoderSetBindGroup") RawRenderBundleEncoderSetBindGroup :: proc(renderBundleEncoder: RenderBundleEncoder, groupIndex: u32, /* NULLABLE */ group: BindGroup, dynamicOffsetCount: uint, dynamicOffsets: [^]u32) --- RenderBundleEncoderSetIndexBuffer :: proc(renderBundleEncoder: RenderBundleEncoder, buffer: Buffer, format: IndexFormat, offset: u64, size: u64) --- - RenderBundleEncoderSetLabel :: proc(renderBundleEncoder: RenderBundleEncoder, label: cstring) --- + RenderBundleEncoderSetLabel :: proc(renderBundleEncoder: RenderBundleEncoder, label: StringView) --- RenderBundleEncoderSetPipeline :: proc(renderBundleEncoder: RenderBundleEncoder, pipeline: RenderPipeline) --- RenderBundleEncoderSetVertexBuffer :: proc(renderBundleEncoder: RenderBundleEncoder, slot: u32, /* NULLABLE */ buffer: Buffer, offset: u64, size: u64) --- - RenderBundleEncoderReference :: proc(renderBundleEncoder: RenderBundleEncoder) --- + RenderBundleEncoderAddRef :: proc(renderBundleEncoder: RenderBundleEncoder) --- RenderBundleEncoderRelease :: proc(renderBundleEncoder: RenderBundleEncoder) --- // Methods of RenderPassEncoder @@ -1478,49 +1612,55 @@ foreign libwgpu { RenderPassEncoderEndOcclusionQuery :: proc(renderPassEncoder: RenderPassEncoder) --- @(link_name="wgpuRenderPassEncoderExecuteBundles") RawRenderPassEncoderExecuteBundles :: proc(renderPassEncoder: RenderPassEncoder, bundleCount: uint, bundles: [^]RenderBundle) --- - RenderPassEncoderInsertDebugMarker :: proc(renderPassEncoder: RenderPassEncoder, markerLabel: cstring) --- + RenderPassEncoderInsertDebugMarker :: proc(renderPassEncoder: RenderPassEncoder, markerLabel: StringView) --- RenderPassEncoderPopDebugGroup :: proc(renderPassEncoder: RenderPassEncoder) --- - RenderPassEncoderPushDebugGroup :: proc(renderPassEncoder: RenderPassEncoder, groupLabel: cstring) --- + RenderPassEncoderPushDebugGroup :: proc(renderPassEncoder: RenderPassEncoder, groupLabel: StringView) --- @(link_name="wgpuRenderPassEncoderSetBindGroup") RawRenderPassEncoderSetBindGroup :: proc(renderPassEncoder: RenderPassEncoder, groupIndex: u32, /* NULLABLE */ group: BindGroup, dynamicOffsetCount: uint, dynamicOffsets: [^]u32) --- RenderPassEncoderSetBlendConstant :: proc(renderPassEncoder: RenderPassEncoder, color: /* const */ ^Color) --- RenderPassEncoderSetIndexBuffer :: proc(renderPassEncoder: RenderPassEncoder, buffer: Buffer, format: IndexFormat, offset: u64, size: u64) --- - RenderPassEncoderSetLabel :: proc(renderPassEncoder: RenderPassEncoder, label: cstring) --- + RenderPassEncoderSetLabel :: proc(renderPassEncoder: RenderPassEncoder, label: StringView) --- RenderPassEncoderSetPipeline :: proc(renderPassEncoder: RenderPassEncoder, pipeline: RenderPipeline) --- RenderPassEncoderSetScissorRect :: proc(renderPassEncoder: RenderPassEncoder, x: u32, y: u32, width: u32, height: u32) --- RenderPassEncoderSetStencilReference :: proc(renderPassEncoder: RenderPassEncoder, reference: u32) --- RenderPassEncoderSetVertexBuffer :: proc(renderPassEncoder: RenderPassEncoder, slot: u32, /* NULLABLE */ buffer: Buffer, offset: u64, size: u64) --- RenderPassEncoderSetViewport :: proc(renderPassEncoder: RenderPassEncoder, x: f32, y: f32, width: f32, height: f32, minDepth: f32, maxDepth: f32) --- - RenderPassEncoderReference :: proc(renderPassEncoder: RenderPassEncoder) --- + RenderPassEncoderAddRef :: proc(renderPassEncoder: RenderPassEncoder) --- RenderPassEncoderRelease :: proc(renderPassEncoder: RenderPassEncoder) --- // Methods of RenderPipeline RenderPipelineGetBindGroupLayout :: proc(renderPipeline: RenderPipeline, groupIndex: u32) -> BindGroupLayout --- - RenderPipelineSetLabel :: proc(renderPipeline: RenderPipeline, label: cstring) --- - RenderPipelineReference :: proc(renderPipeline: RenderPipeline) --- + RenderPipelineSetLabel :: proc(renderPipeline: RenderPipeline, label: StringView) --- + RenderPipelineAddRef :: proc(renderPipeline: RenderPipeline) --- RenderPipelineRelease :: proc(renderPipeline: RenderPipeline) --- // Methods of Sampler - SamplerSetLabel :: proc(sampler: Sampler, label: cstring) --- - SamplerReference :: proc(sampler: Sampler) --- + SamplerSetLabel :: proc(sampler: Sampler, label: StringView) --- + SamplerAddRef :: proc(sampler: Sampler) --- SamplerRelease :: proc(sampler: Sampler) --- // Methods of ShaderModule - ShaderModuleGetCompilationInfo :: proc(shaderModule: ShaderModule, callback: ShaderModuleGetCompilationInfoCallback, /* NULLABLE */ userdata: rawptr = nil) --- - ShaderModuleSetLabel :: proc(shaderModule: ShaderModule, label: cstring) --- - ShaderModuleReference :: proc(shaderModule: ShaderModule) --- + ShaderModuleGetCompilationInfo :: proc(shaderModule: ShaderModule, callbackInfo: CompilationInfoCallbackInfo) -> Future --- + ShaderModuleSetLabel :: proc(shaderModule: ShaderModule, label: StringView) --- + ShaderModuleAddRef :: proc(shaderModule: ShaderModule) --- ShaderModuleRelease :: proc(shaderModule: ShaderModule) --- + // Methods of SupportedFeatures + SupportedFeaturesFreeMembers :: proc(supportedFeatures: SupportedFeatures) --- + + // Methods of SupportedWGSLLanguageFeatures + SupportedWGSLLanguageFeaturesFreeMembers :: proc(supportedWGSLLanguageFeatures: SupportedWGSLLanguageFeatures) --- + // Methods of Surface SurfaceConfigure :: proc(surface: Surface, config: /* const */ ^SurfaceConfiguration) --- @(link_name="wgpuSurfaceGetCapabilities") - RawSurfaceGetCapabilities :: proc(surface: Surface, adapter: Adapter, capabilities: ^SurfaceCapabilities) --- + RawSurfaceGetCapabilities :: proc(surface: Surface, adapter: Adapter, capabilities: ^SurfaceCapabilities) -> Status --- @(link_name="wgpuSurfaceGetCurrentTexture") RawSurfaceGetCurrentTexture :: proc(surface: Surface, surfaceTexture: ^SurfaceTexture) --- - SurfacePresent :: proc(surface: Surface) --- - SurfaceSetLabel :: proc(surface: Surface, label: cstring) --- + SurfacePresent :: proc(surface: Surface) -> Status --- + SurfaceSetLabel :: proc(surface: Surface, label: StringView) --- SurfaceUnconfigure :: proc(surface: Surface) --- - SurfaceReference :: proc(surface: Surface) --- + SurfaceAddRef :: proc(surface: Surface) --- SurfaceRelease :: proc(surface: Surface) --- // Methods of SurfaceCapabilities @@ -1537,13 +1677,13 @@ foreign libwgpu { TextureGetSampleCount :: proc(texture: Texture) -> u32 --- TextureGetUsage :: proc(texture: Texture) -> TextureUsageFlags --- TextureGetWidth :: proc(texture: Texture) -> u32 --- - TextureSetLabel :: proc(texture: Texture, label: cstring) --- - TextureReference :: proc(texture: Texture) --- + TextureSetLabel :: proc(texture: Texture, label: StringView) --- + TextureAddRef :: proc(texture: Texture) --- TextureRelease :: proc(texture: Texture) --- // Methods of TextureView - TextureViewSetLabel :: proc(textureView: TextureView, label: cstring) --- - TextureViewReference :: proc(textureView: TextureView) --- + TextureViewSetLabel :: proc(textureView: TextureView, label: StringView) --- + TextureViewAddRef :: proc(textureView: TextureView) --- TextureViewRelease :: proc(textureView: TextureView) --- } @@ -1551,28 +1691,45 @@ foreign libwgpu { CreateInstance :: proc "c" (/* NULLABLE */ descriptor: /* const */ ^InstanceDescriptor = nil) -> Instance { when ODIN_OS != .JS { - wgpu_native_version_check() + v := (transmute([4]u8)GetVersion()).wzyx + + if v.xyz != BINDINGS_VERSION.xyz { + buf: [1024]byte + n := copy(buf[:], "wgpu-native version mismatch: ") + n += copy(buf[n:], "bindings are for version ") + n += copy(buf[n:], BINDINGS_VERSION_STRING) + n += copy(buf[n:], ", but a different version is linked") + panic_contextless(string(buf[:n])) + } } return RawCreateInstance(descriptor) } +GetInstanceCapabilities :: proc "c" () -> (capabilities: InstanceCapabilities, status: Status) { + status = RawGetInstanceCapabilities(&capabilities) + return +} + +InstanceGetWGSLLanguageFeatures :: proc "c" (instance: Instance) -> (features: SupportedWGSLLanguageFeatures, status: Status) { + status = RawInstanceGetWGSLLanguageFeatures(instance, &features) + return +} + // Wrappers of Adapter -AdapterEnumerateFeatures :: proc(adapter: Adapter, allocator := context.allocator) -> []FeatureName { - count := RawAdapterEnumerateFeatures(adapter, nil) - features := make([]FeatureName, count, allocator) - RawAdapterEnumerateFeatures(adapter, raw_data(features)) - return features +AdapterGetLimits :: proc "c" (adapter: Adapter) -> (limits: Limits, status: Status) { + status = RawAdapterGetLimits(adapter, &limits) + return } -AdapterGetLimits :: proc "c" (adapter: Adapter) -> (limits: SupportedLimits, ok: bool) { - ok = bool(RawAdapterGetLimits(adapter, &limits)) +AdapterGetInfo :: proc "c" (adapter: Adapter) -> (info: AdapterInfo, status: Status) { + status = RawAdapterGetInfo(adapter, &info) return } -AdapterGetInfo :: proc "c" (adapter: Adapter) -> (info: AdapterInfo) { - RawAdapterGetInfo(adapter, &info) +AdapterGetFeatures :: proc "c" (adapter: Adapter) -> (features: SupportedFeatures) { + RawAdapterGetFeatures(adapter, &features) return } @@ -1614,20 +1771,23 @@ ComputePassEncoderSetBindGroup :: proc "c" (computePassEncoder: ComputePassEncod // Wrappers of Device -DeviceEnumerateFeatures :: proc(device: Device, allocator := context.allocator) -> []FeatureName { - count := RawDeviceEnumerateFeatures(device, nil) - features := make([]FeatureName, count, allocator) - RawDeviceEnumerateFeatures(device, raw_data(features)) - return features +DeviceGetLimits :: proc "c" (device: Device) -> (limits: Limits, status: Status) { + status = RawDeviceGetLimits(device, &limits) + return +} + +DeviceGetAdapterInfo :: proc "c" (device: Device) -> (info: AdapterInfo, status: Status) { + status = RawDeviceGetAdapterInfo(device, &info) + return } -DeviceGetLimits :: proc "c" (device: Device) -> (limits: SupportedLimits, ok: bool) { - ok = bool(RawDeviceGetLimits(device, &limits)) +DeviceGetFeatures :: proc "c" (device: Device) -> (features: SupportedFeatures) { + RawDeviceGetFeatures(device, &features) return } BufferWithDataDescriptor :: struct { - /* NULLABLE */ label: cstring, + /* NULLABLE */ label: StringView, usage: BufferUsageFlags, } @@ -1702,73 +1862,3 @@ SurfaceGetCurrentTexture :: proc "c" (surface: Surface) -> (surface_texture: Sur RawSurfaceGetCurrentTexture(surface, &surface_texture) return } - -// WGPU Native bindings - -BINDINGS_VERSION :: [4]u8{22, 1, 0, 1} -BINDINGS_VERSION_STRING :: "22.1.0.1" - -when ODIN_OS != .JS { - @(private="file") - wgpu_native_version_check :: proc "c" () { - v := (transmute([4]u8)GetVersion()).wzyx - - if v != BINDINGS_VERSION { - buf: [1024]byte - n := copy(buf[:], "wgpu-native version mismatch: ") - n += copy(buf[n:], "bindings are for version ") - n += copy(buf[n:], BINDINGS_VERSION_STRING) - n += copy(buf[n:], ", but a different version is linked") - panic_contextless(string(buf[:n])) - } - } - - @(link_prefix="wgpu") - foreign libwgpu { - @(link_name="wgpuGenerateReport") - RawGenerateReport :: proc(instance: Instance, report: ^GlobalReport) --- - @(link_name="wgpuInstanceEnumerateAdapters") - RawInstanceEnumerateAdapters :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^InstanceEnumerateAdapterOptions, adapters: [^]Adapter) -> uint --- - - @(link_name="wgpuQueueSubmitForIndex") - RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex --- - - // Returns true if the queue is empty, or false if there are more queue submissions still in flight. - DevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex = nil) -> b32 --- - - SetLogCallback :: proc(callback: LogCallback, userdata: rawptr) --- - - SetLogLevel :: proc(level: LogLevel) --- - - GetVersion :: proc() -> u32 --- - - RenderPassEncoderSetPushConstants :: proc(encoder: RenderPassEncoder, stages: ShaderStageFlags, offset: u32, sizeBytes: u32, data: rawptr) --- - - RenderPassEncoderMultiDrawIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) --- - RenderPassEncoderMultiDrawIndexedIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) --- - - RenderPassEncoderMultiDrawIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) --- - RenderPassEncoderMultiDrawIndexedIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) --- - - ComputePassEncoderBeginPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder, querySet: QuerySet, queryIndex: u32) --- - ComputePassEncoderEndPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder) --- - RenderPassEncoderBeginPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder, querySet: QuerySet, queryIndex: u32) --- - RenderPassEncoderEndPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder) --- - } - - GenerateReport :: proc "c" (instance: Instance) -> (report: GlobalReport) { - RawGenerateReport(instance, &report) - return - } - - InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerateAdapterOptions = nil, allocator := context.allocator) -> (adapters: []Adapter) { - count := RawInstanceEnumerateAdapters(instance, options, nil) - adapters = make([]Adapter, count, allocator) - RawInstanceEnumerateAdapters(instance, options, raw_data(adapters)) - return - } - - QueueSubmitForIndex :: proc "c" (queue: Queue, commands: []CommandBuffer) -> SubmissionIndex { - return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands)) - } -} diff --git a/vendor/wgpu/wgpu_native.odin b/vendor/wgpu/wgpu_native.odin new file mode 100644 index 00000000000..def095e07fc --- /dev/null +++ b/vendor/wgpu/wgpu_native.odin @@ -0,0 +1,57 @@ +#+build !js +package wgpu + +@(link_prefix="wgpu") +foreign libwgpu { + @(link_name="wgpuGenerateReport") + RawGenerateReport :: proc(instance: Instance, report: ^GlobalReport) --- + @(link_name="wgpuInstanceEnumerateAdapters") + RawInstanceEnumerateAdapters :: proc(instance: Instance, /* NULLABLE */ options: /* const */ ^InstanceEnumerateAdapterOptions, adapters: [^]Adapter) -> uint --- + + @(link_name="wgpuQueueSubmitForIndex") + RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex --- + + // Returns true if the queue is empty, or false if there are more queue submissions still in flight. + DevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^SubmissionIndex = nil) -> b32 --- + DeviceCreateShaderModuleSpirV :: proc(device: Device, descriptor: ^ShaderModuleDescriptorSpirV) -> ShaderModule --- + + SetLogCallback :: proc(callback: LogCallback, userdata: rawptr) --- + + SetLogLevel :: proc(level: LogLevel) --- + + GetVersion :: proc() -> u32 --- + + RenderPassEncoderSetPushConstants :: proc(encoder: RenderPassEncoder, stages: ShaderStageFlags, offset: u32, sizeBytes: u32, data: rawptr) --- + ComputePassEncoderSetPushConstants :: proc(encoder: ComputePassEncoder, offset: u32, sizeBytes: u32, data: rawptr) --- + RenderBundleEncoderSetPushConstants :: proc(encoder: RenderBundleEncoder, stages: ShaderStageFlags, offset: u32, sizeBytes: u32, data: rawptr) --- + + RenderPassEncoderMultiDrawIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) --- + RenderPassEncoderMultiDrawIndexedIndirect :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count: u32) --- + + RenderPassEncoderMultiDrawIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) --- + RenderPassEncoderMultiDrawIndexedIndirectCount :: proc(encoder: RenderPassEncoder, buffer: Buffer, offset: u64, count_buffer: Buffer, count_buffer_offset: u64, max_count: u32) --- + + ComputePassEncoderBeginPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder, querySet: QuerySet, queryIndex: u32) --- + ComputePassEncoderEndPipelineStatisticsQuery :: proc(computePassEncoder: ComputePassEncoder) --- + RenderPassEncoderBeginPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder, querySet: QuerySet, queryIndex: u32) --- + RenderPassEncoderEndPipelineStatisticsQuery :: proc(renderPassEncoder: RenderPassEncoder) --- + + ComputePassEncoderWriteTimestamp :: proc(computePassEncoder: ComputePassEncoder, querySet: QuerySet, queryIndex: u32) --- + RenderPassEncoderWriteTimestamp :: proc(renderPassEncoder: RenderPassEncoder, querySet: QuerySet, queryIndex: u32) --- +} + +GenerateReport :: proc "c" (instance: Instance) -> (report: GlobalReport) { + RawGenerateReport(instance, &report) + return +} + +InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerateAdapterOptions = nil, allocator := context.allocator) -> (adapters: []Adapter) { + count := RawInstanceEnumerateAdapters(instance, options, nil) + adapters = make([]Adapter, count, allocator) + RawInstanceEnumerateAdapters(instance, options, raw_data(adapters)) + return +} + +QueueSubmitForIndex :: proc "c" (queue: Queue, commands: []CommandBuffer) -> SubmissionIndex { + return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands)) +} diff --git a/vendor/wgpu/wgpu_native_types.odin b/vendor/wgpu/wgpu_native_types.odin index 2133fdd50eb..378b6591c55 100644 --- a/vendor/wgpu/wgpu_native_types.odin +++ b/vendor/wgpu/wgpu_native_types.odin @@ -2,6 +2,9 @@ package wgpu import "base:runtime" +BINDINGS_VERSION :: [4]u8{24, 0, 0, 2} +BINDINGS_VERSION_STRING :: "24.0.0.2" + LogLevel :: enum i32 { Off, Error, @@ -59,30 +62,21 @@ InstanceExtras :: struct { flags: InstanceFlags, dx12ShaderCompiler: Dx12Compiler, gles3MinorVersion: Gles3MinorVersion, - dxilPath: cstring, - dxcPath: cstring, + dxilPath: StringView, + dxcPath: StringView, } DeviceExtras :: struct { using chain: ChainedStruct, - tracePath: cstring, + tracePath: StringView, } NativeLimits :: struct { + chain: ChainedStructOut, maxPushConstantSize: u32, maxNonSamplerBindings: u32, } -RequiredLimitsExtras :: struct { - using chain: ChainedStruct, - limits: NativeLimits, -} - -SupportedLimitsExtras :: struct { - using chain: ChainedStructOut, - limits: NativeLimits, -} - PushConstantRange :: struct { stages: ShaderStageFlags, start: u32, @@ -97,29 +91,29 @@ PipelineLayoutExtras :: struct { SubmissionIndex :: distinct u64 -WrappedSubmissionIndex :: struct { - queue: Queue, - submissionIndex: SubmissionIndex, -} - ShaderDefine :: struct { - name: cstring, - value: cstring, + name: StringView, + value: StringView, } ShaderModuleGLSLDescriptor :: struct { using chain: ChainedStruct, stage: ShaderStage, - code: cstring, + code: StringView, defineCount: uint, defines: [^]ShaderDefine `fmt:"v,defineCount"`, } +ShaderModuleDescriptorSpirV :: struct { + label: StringView, + sourceSize: u32, + source: [^]u32 `fmt:"v,sourceSize"`, +} + RegistryReport :: struct { numAllocated: uint, numKeptFromUser: uint, numReleasedFromUser: uint, - numErrors: uint, elementSize: uint, } @@ -135,6 +129,7 @@ HubReport :: struct { renderBundles: RegistryReport, renderPipelines: RegistryReport, computePipelines: RegistryReport, + pipelineCaches: RegistryReport, querySets: RegistryReport, buffers: RegistryReport, textures: RegistryReport, @@ -144,11 +139,7 @@ HubReport :: struct { GlobalReport :: struct { surfaces: RegistryReport, - backendType: BackendType, - vulkan: HubReport, - metal: HubReport, - dx12: HubReport, - gl: HubReport, + hub: HubReport, } InstanceEnumerateAdapterOptions :: struct { @@ -182,7 +173,7 @@ SurfaceConfigurationExtras :: struct { desiredMaximumFrameLatency: i32, } -LogCallback :: #type proc "c" (level: LogLevel, message: cstring, userdata: rawptr) +LogCallback :: #type proc "c" (level: LogLevel, message: StringView, userdata: rawptr) // Wrappers @@ -210,3 +201,4 @@ ConvertLogLevel :: proc { ConvertOdinToWGPULogLevel, ConvertWGPUToOdinLogLevel, } +