REGRESSION: ( r246394 ) webgpu/whlsl-buffer-fragment.html and webgpu/whlsl-buffer...
[WebKit-https.git] / LayoutTests / webgpu / js / webgpu-functions.js
1 async function getBasicDevice() {
2     const adapter = await navigator.gpu.requestAdapter({ powerPreference: "low-power" });
3     const device = await adapter.requestDevice();
4     return device;
5 }
6
7 function drawWhiteSquareOnBlueBackgroundInSoftware(canvas) {
8     const context = canvas.getContext("2d");
9     context.fillStyle = "blue";
10     context.fillRect(0, 0, 400, 400);
11     context.fillStyle = "white";
12     context.fillRect(100, 100, 200, 200);
13 }
14
15 function drawBlackSquareOnBlueBackgroundInSoftware(canvas) {
16     const context = canvas.getContext("2d");
17     context.fillStyle = "blue";
18     context.fillRect(0, 0, 400, 400);
19     context.fillStyle = "black";
20     context.fillRect(100, 100, 200, 200);
21 }
22
23 function drawGreenSquareInSoftware(canvas) {
24     const context = canvas.getContext('2d');
25     context.fillStyle = 'rgb(0, 255, 0)';
26     context.fillRect(0, 0, canvas.width, canvas.height);
27 }
28
29 function drawGreenAndBlueCheckerboardInSoftware(canvas) {
30     const context = canvas.getContext('2d');
31
32     context.fillStyle = 'rgb(0, 255, 0)';
33     context.fillRect(0, 0, canvas.width, canvas.height);
34
35     const numColumns = 4;
36     const numRows = 4;
37     context.beginPath();
38     context.fillStyle = 'rgb(0, 0, 255)';
39     for (let x = 0; x < numColumns; ++x) {
40         for (let y = 0; y < numRows; ++y) {
41             if (x % 2 == 0 && y % 2 == 0 || x % 2 == 1 && y % 2 == 1)
42                 context.rect(
43                     x * canvas.width / numColumns,
44                     y * canvas.height / numRows,
45                     canvas.width / numColumns,
46                     canvas.height / numRows
47                     );
48         }
49     }
50     context.fill();
51 }
52
53 function createBasicSwapChain(canvas, device) {
54     const context = canvas.getContext("gpu");
55     return context.configureSwapChain({ device: device, format: "bgra8unorm" });
56 }
57
58 function createBasicDepthStateDescriptor() {
59     return {
60         depthWriteEnabled: true,
61         depthCompare: "less"
62     };
63 }
64
65 function createBasicDepthTexture(canvas, device) {
66     const depthSize = {
67         width: canvas.width,
68         height: canvas.height,
69         depth: 1
70     };
71
72     return device.createTexture({
73         size: depthSize,
74         format: "depth32float-stencil8",
75         usage: GPUTextureUsage.OUTPUT_ATTACHMENT
76     });
77 }
78
79 function createBasicPipeline(shaderModule, device, colorStates, pipelineLayout, vertexInputDescriptor, depthStateDescriptor, primitiveTopology = "triangle-strip") {
80     const vertexStageDescriptor = {
81         module: shaderModule,
82         entryPoint: "vertex_main" 
83     };
84
85     const fragmentStageDescriptor = {
86         module: shaderModule,
87         entryPoint: "fragment_main"
88     };
89
90     if (!colorStates) {
91         colorStates = [{ 
92             format: "bgra8unorm",
93             alphaBlend: {},
94             colorBlend: {}
95         }];
96     }
97
98     if (!vertexInputDescriptor)
99         vertexInputDescriptor = { vertexBuffers: [] };
100
101     const pipelineDescriptor = {
102         vertexStage: vertexStageDescriptor,
103         fragmentStage: fragmentStageDescriptor,
104         primitiveTopology: primitiveTopology,
105         colorStates: colorStates,
106         vertexInput: vertexInputDescriptor
107     };
108
109     if (pipelineLayout)
110         pipelineDescriptor.layout = pipelineLayout;
111
112     if (depthStateDescriptor)
113         pipelineDescriptor.depthStencilState = depthStateDescriptor;
114
115     return device.createRenderPipeline(pipelineDescriptor);
116 }
117
118 function beginBasicRenderPass(swapChain, commandEncoder) {
119     const basicAttachment = {
120         attachment: swapChain.getCurrentTexture().createDefaultView(),
121         loadOp: "clear",
122         storeOp: "store",
123         clearColor: { r: 1.0, g: 0, b: 0, a: 1.0 }
124     };
125
126     // FIXME: Flesh out the rest of GPURenderPassDescriptor. 
127     return commandEncoder.beginRenderPass({ colorAttachments : [basicAttachment] });
128 }
129
130 function encodeBasicCommands(renderPassEncoder, renderPipeline, vertexBuffer) {
131     if (vertexBuffer)
132         renderPassEncoder.setVertexBuffers(0, [vertexBuffer], [0]);
133     renderPassEncoder.setPipeline(renderPipeline);
134     renderPassEncoder.draw(4, 1, 0, 0);
135     renderPassEncoder.endPass();
136 }
137
138 function createBufferWithData(device, descriptor, data, offset = 0) {
139     const mappedBuffer = device.createBufferMapped(descriptor);
140     const dataArray = new Uint8Array(mappedBuffer[1]);
141     dataArray.set(new Uint8Array(data), offset);
142     mappedBuffer[0].unmap();
143     return mappedBuffer[0];
144 }
145
146 async function mapWriteDataToBuffer(buffer, data, offset = 0) {
147     const arrayBuffer = await buffer.mapWriteAsync();
148     const writeArray = new Uint8Array(arrayBuffer);
149     writeArray.set(new Uint8Array(data), offset);
150     buffer.unmap();
151 }