From 40febd9dd1224a15a3bc877e2fdf010c4c893e0e Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Fri, 19 Jan 2024 22:49:14 +0530 Subject: feat:: External webgpu surfaces / BYOW (#21835) This PR contains the implementation of the External webgpu surfaces / BYOW proposal. BYOW stands for "Bring your own window". Closes #21713 Adds `Deno.UnsafeWindowSurface` ( `--unstable-webgpu` API) to the `Deno` namespace: ```typescript class UnsafeWindowSurface { constructor( system: "cocoa" | "x11" | "win32", winHandle: Deno.PointerValue, displayHandle: Deno.PointerValue | null ); getContext(type: "webgpu"): GPUCanvasContext; present(): void; } ``` For the initial pass, I've opted to support the three major windowing systems. The parameters correspond to the table below: | system | winHandle | displayHandle | | ----------------- | ---------- | ------- | | "cocoa" (macOS) | `NSView*` | - | | "win32" (Windows) | `HWND` | `HINSTANCE` | | "x11" (Linux) | Xlib `Window` | Xlib `Display*` | Ecosystem support: - [x] deno_sdl2 (sdl2) - [mod.ts#L1209](https://github.com/littledivy/deno_sdl2/blob/7e177bc6524750a8849c25ce421798b2e71ec943/mod.ts#L1209) - [x] dwm (glfw) - https://github.com/deno-windowing/dwm/issues/29 - [ ] pane (winit)
Example ```typescript // A simple clear screen pass, colors based on mouse position. import { EventType, WindowBuilder } from "https://deno.land/x/sdl2@0.7.0/mod.ts"; const window = new WindowBuilder("sdl2 + deno + webgpu", 640, 480).build(); const [system, windowHandle, displayHandle] = window.rawHandle(); const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const context = Deno.createWindowSurface(system, windowHandle, displayHandle); context.configure({ device: device, format: "bgra8unorm", height: 480, width: 640, }); let r = 0.0; let g = 0.0; let b = 0.0; for (const event of window.events()) { if (event.type === EventType.Quit) { break; } else if (event.type === EventType.Draw) { const textureView = context.getCurrentTexture().createView(); const renderPassDescriptor: GPURenderPassDescriptor = { colorAttachments: [ { view: textureView, clearValue: { r, g, b, a: 1.0 }, loadOp: "clear", storeOp: "store", }, ], }; const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); passEncoder.end(); device.queue.submit([commandEncoder.finish()]); Deno.presentGPUCanvasContext(context); } if (event.type === EventType.MouseMotion) { r = event.x / 640; g = event.y / 480; b = 1.0 - r - g; } } ``` You can find more examples in the linked tracking issue.
--------- Signed-off-by: Divy Srivastava --- runtime/js/90_deno_ns.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index 97b4a9531..058985fbf 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -29,6 +29,7 @@ import * as tty from "ext:runtime/40_tty.js"; import * as httpRuntime from "ext:runtime/40_http.js"; import * as kv from "ext:deno_kv/01_db.ts"; import * as cron from "ext:deno_cron/01_cron.ts"; +import * as webgpuSurface from "ext:deno_webgpu/02_surface.js"; const denoNs = { metrics: core.metrics, @@ -222,7 +223,9 @@ denoNsUnstableById[unstableIds.net] = { // denoNsUnstableById[unstableIds.unsafeProto] = {} -// denoNsUnstableById[unstableIds.webgpu] = {} +denoNsUnstableById[unstableIds.webgpu] = { + UnsafeWindowSurface: webgpuSurface.UnsafeWindowSurface, +}; // denoNsUnstableById[unstableIds.workerOptions] = {} @@ -242,6 +245,7 @@ const denoNsUnstable = { UnsafePointer: ffi.UnsafePointer, UnsafePointerView: ffi.UnsafePointerView, UnsafeFnPointer: ffi.UnsafeFnPointer, + UnsafeWindowSurface: webgpuSurface.UnsafeWindowSurface, flock: fs.flock, flockSync: fs.flockSync, funlock: fs.funlock, -- cgit v1.2.3