All files / webgpu / create_capture.ts

100.00% Branches 0/0
4.55% Lines 1/22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 
 
x1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 





























































































// Copyright 2018-2025 the Deno authors. MIT license.

import { getRowPadding } from "./row_padding.ts";

/** Return value for {@linkcode createCapture}. */
export interface CreateCapture {
  /**
   * Texture to be used as view to render to.
   */
  texture: GPUTexture;

  /**
   * Represents the output buffer of the rendered texture.
   * Can then be used to access and retrieve raw image data.
   */
  outputBuffer: GPUBuffer;
}

/**
 * Creates a texture and buffer to use as a capture.
 *
 * @example Usage
 * ```ts ignore
 * import { createCapture } from "@std/webgpu/create-capture";
 * import { getRowPadding } from "@std/webgpu/row-padding";
 *
 * const adapter = await navigator.gpu.requestAdapter();
 * const device = await adapter?.requestDevice()!;
 *
 * const dimensions = {
 *   width: 200,
 *   height: 200,
 * };
 *
 * const { texture, outputBuffer } = createCapture(device, dimensions.width, dimensions.height);
 *
 * const encoder = device.createCommandEncoder();
 * encoder.beginRenderPass({
 *   colorAttachments: [
 *     {
 *       view: texture.createView(),
 *       storeOp: "store",
 *       loadOp: "clear",
 *       clearValue: [1, 0, 0, 1],
 *     },
 *   ],
 * }).end();
 *
 * const { padded } = getRowPadding(dimensions.width);
 *
 * encoder.copyTextureToBuffer(
 *   {
 *     texture,
 *   },
 *   {
 *     buffer: outputBuffer,
 *     bytesPerRow: padded,
 *   },
 *   dimensions,
 * );
 *
 * device.queue.submit([encoder.finish()]);
 *
 * // outputBuffer contains the raw image data, can then be used
 * // to save as png or other formats.
 * ```
 *
 * @param device The device to use for creating the capture.
 * @param width The width of the capture texture.
 * @param height The height of the capture texture.
 * @returns The texture to render to and buffer to read from.
 */
export function createCapture(
  device: GPUDevice,
  width: number,
  height: number,
): CreateCapture {
  const { padded } = getRowPadding(width);
  const outputBuffer = device.createBuffer({
    label: "Capture",
    size: padded * height,
    usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
  });
  const texture = device.createTexture({
    label: "Capture",
    size: {
      width,
      height,
    },
    format: "rgba8unorm-srgb",
    usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
  });

  return { texture, outputBuffer };
}