1 async function helloTriangle() {
3 document.body.className = 'error';
7 const adapter = await navigator.gpu.requestAdapter();
8 const device = await adapter.requestDevice();
10 /*** Shader Setup ***/
13 const positionLocation = 0;
14 const colorLocation = 1;
18 float4 position : SV_Position;
19 float4 color : attribute(${colorLocation});
22 vertex FragmentData vertexMain(float4 position : attribute(${positionLocation}), float4 color : attribute(${colorLocation}))
26 out.position = position;
32 fragment float4 fragmentMain(float4 color : attribute(${colorLocation})) : SV_Target 0
37 const shaderModule = device.createShaderModule({ code: whlslSource, isWHLSL: true });
39 /* GPUPipelineStageDescriptors */
40 const vertexStageDescriptor = { module: shaderModule, entryPoint: "vertexMain" };
41 const fragmentStageDescriptor = { module: shaderModule, entryPoint: "fragmentMain" };
43 /*** Vertex Buffer Setup ***/
46 const colorOffset = 4 * 4; // 4 floats of 4 bytes each.
47 const vertexStride = 8 * 4;
48 const vertexDataSize = vertexStride * 3;
50 /* GPUBufferDescriptor */
51 const vertexDataBufferDescriptor = {
53 usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.VERTEX
56 const vertexBuffer = device.createBuffer(vertexDataBufferDescriptor);
58 /*** Write Data To GPU ***/
60 const vertexArrayBuffer = await vertexBuffer.mapWriteAsync();
61 const vertexWriteArray = new Float32Array(vertexArrayBuffer);
62 vertexWriteArray.set([
63 // x, y, z, w, r, g, b, a
64 0, 0.8, 0, 1, 0, 1, 1, 1,
65 -0.8, -0.8, 0, 1, 1, 1, 0, 1,
66 0.8, -0.8, 0, 1, 1, 0, 1, 1
70 /*** Describe Vertex Data For Pipeline ***/
72 const vertexBufferSlot = 0;
74 /* GPUVertexAttributeDescriptors */
75 const positionAttribute = {
76 shaderLocation: positionLocation,
80 const colorAttribute = {
81 shaderLocation: colorLocation,
86 /* GPUVertexBufferDescriptor */
87 const vertexBufferDescriptor = {
89 attributeSet: [positionAttribute, colorAttribute]
92 /* GPUVertexInputDescriptor */
93 const vertexInputDescriptor = {
94 vertexBuffers: [vertexBufferDescriptor]
97 /*** Finish Pipeline State ***/
99 /* GPUBlendDescriptors */
100 const alphaBlendDescriptor = { srcFactor: "one", dstFactor: "zero", operation: "add" };
101 const colorBlendDescriptor = { srcFactor: "one", dstFactor: "zero", operation: "add" };
103 /* GPUColorStateDescriptor */
104 const colorStateDescriptor = {
105 format: "bgra8unorm",
106 alphaBlend: alphaBlendDescriptor,
107 colorBlend: colorBlendDescriptor,
108 writeMask: GPUColorWriteBits.ALL
111 /* GPURenderPipelineDescriptor */
112 const renderPipelineDescriptor = {
113 vertexStage: vertexStageDescriptor,
114 fragmentStage: fragmentStageDescriptor,
115 primitiveTopology: "triangle-list",
116 colorStates: [colorStateDescriptor],
117 vertexInput: vertexInputDescriptor
119 /* GPURenderPipeline */
120 const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
122 /*** Swap Chain Setup ***/
124 const canvas = document.querySelector("canvas");
128 const gpuContext = canvas.getContext("gpu");
130 /* GPUSwapChainDescriptor */
131 const swapChainDescriptor = { device: device, format: "bgra8unorm" };
133 const swapChain = gpuContext.configureSwapChain(swapChainDescriptor);
135 /*** Render Pass Setup ***/
137 /* Acquire Texture To Render To */
140 const swapChainTexture = swapChain.getCurrentTexture();
142 const renderAttachment = swapChainTexture.createDefaultView();
145 const darkBlue = { r: 0.15, g: 0.15, b: 0.5, a: 1 };
147 /* GPURenderPassColorATtachmentDescriptor */
148 const colorAttachmentDescriptor = {
149 attachment: renderAttachment,
155 /* GPURenderPassDescriptor */
156 const renderPassDescriptor = { colorAttachments: [colorAttachmentDescriptor] };
160 /* GPUCommandEncoder */
161 const commandEncoder = device.createCommandEncoder();
162 /* GPURenderPassEncoder */
163 const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
165 renderPassEncoder.setPipeline(renderPipeline);
166 renderPassEncoder.setVertexBuffers(vertexBufferSlot, [vertexBuffer], [0]);
167 renderPassEncoder.draw(3, 1, 0, 0); // 3 vertices, 1 instance, 0th vertex, 0th instance.
168 renderPassEncoder.endPass();
170 /* GPUComamndBuffer */
171 const commandBuffer = commandEncoder.finish();
174 const queue = device.getQueue();
175 queue.submit([commandBuffer]);
178 window.addEventListener("DOMContentLoaded", helloTriangle);