-
Notifications
You must be signed in to change notification settings - Fork 18
/
matrix-shader-crash.html
101 lines (82 loc) · 3.25 KB
/
matrix-shader-crash.html
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
96
97
98
99
100
101
<!doctype html>
<html>
<head>
<title>WebGPU Shader Matrix crash</title>
</head>
<body>
<canvas id='output'></canvas>
<script type="module">
import glslangModule from 'https://unpkg.com/@webgpu/[email protected]/web/glslang.js';
const outputCanvas = document.getElementById('output');
const context = outputCanvas.getContext('gpupresent');
const vertexShaderGLSL = `#version 450
const vec2 pos[4] = vec2[4](vec2(-1.0f, 1.0f), vec2(1.0f, 1.0f), vec2(-1.0f, -1.0f), vec2(1.0f, -1.0f));
void main() {
// Generate a dummy model view matrix, uninitialized, which causes the crash when you attempt to use
// as part of a pipeline. If you initialize the matrix with valid data here (ie: = mat4(1.0)) then it
// works as expected.
mat4 modelView;
gl_Position = modelView * vec4(pos[gl_VertexIndex], 0.0, 1.0);
}`;
const fragmentShaderGLSL = `#version 450
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(0.0, 1.0, 0.0, 1.0);
}`;
let adapter;
let device;
let glslang;
let swapChain;
let pipeline;
async function initWebGPU(canvas) {
adapter = await navigator.gpu.requestAdapter();
device = await adapter.requestDevice();
glslang = await glslangModule();
const colorFormat = await context.getSwapChainPreferredFormat(device);
swapChain = context.configureSwapChain({ device, format: colorFormat });
pipeline = device.createRenderPipeline({
layout: device.createPipelineLayout({ bindGroupLayouts: [] }),
vertexStage: {
module: device.createShaderModule({
code: glslang.compileGLSL(vertexShaderGLSL, 'vertex')
}),
entryPoint: 'main'
},
fragmentStage: {
module: device.createShaderModule({
code: glslang.compileGLSL(fragmentShaderGLSL, 'fragment')
}),
entryPoint: 'main'
},
primitiveTopology: 'triangle-strip',
colorStates: [{
format: colorFormat,
}]
});
function onResize() {
canvas.width = canvas.offsetWidth * window.devicePixelRatio;
canvas.height = canvas.offsetHeight * window.devicePixelRatio;
}
window.addEventListener('resize', onResize);
onResize();
window.requestAnimationFrame(onFrame);
}
function onFrame() {
window.requestAnimationFrame(onFrame);
const commandEncoder = device.createCommandEncoder({});
const passEncoder = commandEncoder.beginRenderPass({
colorAttachments: [{
// attachment is acquired and set in render loop.
attachment: swapChain.getCurrentTexture().createView(),
loadValue: { r: 1.0, g: 0.5, b: 0.0, a: 1.0 },
}]
});
passEncoder.setPipeline(pipeline);
passEncoder.draw(4, 1, 0, 0);
passEncoder.end();
device.defaultQueue.submit([commandEncoder.finish()]);
}
initWebGPU(outputCanvas);
</script>
</body>
</html>