Repository: denoland/deno
Pull request: feat(unstable/webgpu): add `deviceStartCapture` and `deviceStopCapture`

This is achieved by adding a new `Deno.webgpu` namespace which will be used for non-spec functionality, which for now will be marked as unstable

Closes #26766

Changed files:
filename: cli/tsc/dts/lib.deno.unstable.d.ts
patch: @@ -4399,6 +4399,40 @@ declare namespace Deno {
     export {}; // only export exports
   }
 
+  /**
+   * The webgpu namespace provides additional APIs that the WebGPU specification
+   * does not specify.
+   *
+   * @category GPU
+   * @experimental
+   */
+  export namespace webgpu {
+    /**
+     * Starts a frame capture.
+     *
+     * This API is useful for debugging issues related to graphics, and makes
+     * the captured data available to RenderDoc or XCode
+     * (or other software for debugging frames)
+     *
+     * @category GPU
+     * @experimental
+     */
+    export function deviceStartCapture(device: GPUDevice): void;
+    /**
+     * Stops a frame capture.
+     *
+     * This API is useful for debugging issues related to graphics, and makes
+     * the captured data available to RenderDoc or XCode
+     * (or other software for debugging frames)
+     *
+     * @category GPU
+     * @experimental
+     */
+    export function deviceStopCapture(device: GPUDevice): void;
+
+    export {}; // only export exports
+  }
+
   export {}; // only export exports
 }
 

filename: ext/webgpu/01_webgpu.js
patch: @@ -34,6 +34,8 @@ import {
   GPUTexture,
   GPUTextureView,
   op_create_gpu,
+  op_webgpu_device_start_capture,
+  op_webgpu_device_stop_capture,
 } from "ext:core/ops";
 const {
   ObjectDefineProperty,
@@ -821,6 +823,19 @@ webidl.converters["GPUUncapturedErrorEventInit"] = webidl
     dictMembersGPUUncapturedErrorEventInit,
   );
 
+function deviceStartCapture(device) {
+  op_webgpu_device_start_capture(device);
+}
+
+function deviceStopCapture(device) {
+  op_webgpu_device_stop_capture(device);
+}
+
+const denoNsWebGPU = {
+  deviceStartCapture,
+  deviceStopCapture,
+};
+
 let gpu;
 function initGPU() {
   if (!gpu) {
@@ -833,6 +848,7 @@ function initGPU() {
 }
 
 export {
+  denoNsWebGPU,
   GPU,
   gpu,
   GPUAdapter,

filename: ext/webgpu/device.rs
patch: @@ -888,3 +888,13 @@ impl GPUDeviceLostInfo {
     "device was lost"
   }
 }
+
+#[op2(fast)]
+pub fn op_webgpu_device_start_capture(#[cppgc] device: &GPUDevice) {
+  device.instance.device_start_capture(device.id);
+}
+
+#[op2(fast)]
+pub fn op_webgpu_device_stop_capture(#[cppgc] device: &GPUDevice) {
+  device.instance.device_stop_capture(device.id);
+}

filename: ext/webgpu/lib.rs
patch: @@ -64,7 +64,11 @@ pub type Instance = Arc<wgpu_core::global::Global>;
 deno_core::extension!(
   deno_webgpu,
   deps = [deno_webidl, deno_web],
-  ops = [op_create_gpu],
+  ops = [
+    op_create_gpu,
+    device::op_webgpu_device_start_capture,
+    device::op_webgpu_device_stop_capture,
+  ],
   objects = [
     GPU,
     adapter::GPUAdapter,

filename: runtime/js/90_deno_ns.js
patch: @@ -31,6 +31,7 @@ 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";
 import * as telemetry from "ext:deno_telemetry/telemetry.ts";
+import { loadWebGPU } from "ext:deno_webgpu/00_init.js";
 
 const { ObjectDefineProperties } = primordials;
 
@@ -221,6 +222,12 @@ ObjectDefineProperties(denoNsUnstableById[unstableIds.net], {
 denoNsUnstableById[unstableIds.webgpu] = {
   UnsafeWindowSurface: webgpuSurface.UnsafeWindowSurface,
 };
+ObjectDefineProperties(denoNsUnstableById[unstableIds.webgpu], {
+  webgpu: core.propWritableLazyLoaded(
+    (webgpu) => webgpu.denoNsWebGPU,
+    loadWebGPU,
+  ),
+});
 
 // denoNsUnstableById[unstableIds.workerOptions] = { __proto__: null }