in src/webgpu/web_platform/reftests/canvas_complex.html.ts [499:595]
function FragmentTextureStore(ctx: GPUCanvasContext) {
const halfCanvasWidthStr = (ctx.canvas.width / 2).toFixed();
const halfCanvasHeightStr = (ctx.canvas.height / 2).toFixed();
const pipeline = t.device.createRenderPipeline({
layout: 'auto',
vertex: {
module: t.device.createShaderModule({
code: `
struct VertexOutput {
@builtin(position) Position : vec4<f32>
}
@vertex
fn main(@builtin(vertex_index) VertexIndex : u32) -> VertexOutput {
var pos = array<vec2<f32>, 6>(
vec2<f32>( 1.0, 1.0),
vec2<f32>( 1.0, -1.0),
vec2<f32>(-1.0, -1.0),
vec2<f32>( 1.0, 1.0),
vec2<f32>(-1.0, -1.0),
vec2<f32>(-1.0, 1.0));
var output : VertexOutput;
output.Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
return output;
}
`,
}),
entryPoint: 'main',
},
fragment: {
module: t.device.createShaderModule({
code: `
@group(0) @binding(0) var outImage : texture_storage_2d<${format}, write>;
@fragment
fn main(@builtin(position) fragcoord: vec4<f32>) -> @location(0) vec4<f32> {
var coord = vec2<u32>(floor(fragcoord.xy));
var color = vec4<f32>(0.0, 0.0, 0.0, 1.0);
if (coord.x < ${halfCanvasWidthStr}u) {
if (coord.y < ${halfCanvasHeightStr}u) {
color.r = ${shaderValueStr};
} else {
color.b = ${shaderValueStr};
}
} else {
if (coord.y < ${halfCanvasHeightStr}u) {
color.g = ${shaderValueStr};
} else {
color.r = ${shaderValueStr};
color.g = ${shaderValueStr};
}
}
textureStore(outImage, vec2<i32>(coord), color);
return color;
}
`,
}),
entryPoint: 'main',
targets: [{ format }],
},
primitive: {
topology: 'triangle-list',
},
});
const bg = t.device.createBindGroup({
entries: [{ binding: 0, resource: ctx.getCurrentTexture().createView() }],
layout: pipeline.getBindGroupLayout(0),
});
const outputTexture = t.device.createTexture({
format,
size: [ctx.canvas.width, ctx.canvas.height, 1],
usage: GPUTextureUsage.RENDER_ATTACHMENT,
});
const renderPassDescriptor: GPURenderPassDescriptor = {
colorAttachments: [
{
view: outputTexture.createView(),
clearValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },
loadOp: 'clear',
storeOp: 'store',
},
],
};
const commandEncoder = t.device.createCommandEncoder({ label: 'FragmentTextureStore' });
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, bg);
passEncoder.draw(6, 1, 0, 0);
passEncoder.end();
t.device.queue.submit([commandEncoder.finish()]);
}