in src/webgpu/web_platform/reftests/canvas_complex.html.ts [212:332]
async function DrawTextureSample(ctx: GPUCanvasContext) {
const imageBitmap = await getImageBitmap(ctx);
const srcTexture = setupSrcTexture(imageBitmap);
const pipeline = t.device.createRenderPipeline({
layout: 'auto',
vertex: {
module: t.device.createShaderModule({
code: `
struct VertexOutput {
@builtin(position) Position : vec4<f32>,
@location(0) fragUV : vec2<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 uv = array<vec2<f32>, 6>(
vec2<f32>(1.0, 0.0),
vec2<f32>(1.0, 1.0),
vec2<f32>(0.0, 1.0),
vec2<f32>(1.0, 0.0),
vec2<f32>(0.0, 1.0),
vec2<f32>(0.0, 0.0));
var output : VertexOutput;
output.Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);
output.fragUV = uv[VertexIndex];
return output;
}
`,
}),
entryPoint: 'main',
},
fragment: {
module: t.device.createShaderModule({
// NOTE: "-srgb" cases haven't been tested (there aren't any .html files that use them).
code: `
@group(0) @binding(0) var mySampler: sampler;
@group(0) @binding(1) var myTexture: texture_2d<f32>;
fn gammaDecompress(n: f32) -> f32 {
var r = n;
if (r <= 0.04045) {
r = r * 25.0 / 323.0;
} else {
r = pow((200.0 * r + 11.0) / 121.0, 12.0 / 5.0);
}
r = clamp(r, 0.0, 1.0);
return r;
}
@fragment
fn srgbMain(@location(0) fragUV: vec2<f32>) -> @location(0) vec4<f32> {
var result = textureSample(myTexture, mySampler, fragUV);
result.r = gammaDecompress(result.r);
result.g = gammaDecompress(result.g);
result.b = gammaDecompress(result.b);
return result;
}
@fragment
fn linearMain(@location(0) fragUV: vec2<f32>) -> @location(0) vec4<f32> {
return textureSample(myTexture, mySampler, fragUV);
}
`,
}),
entryPoint: isOutputSrgb ? 'srgbMain' : 'linearMain',
targets: [{ format }],
},
primitive: {
topology: 'triangle-list',
},
});
const sampler = t.device.createSampler({
magFilter: 'nearest',
minFilter: 'nearest',
});
const uniformBindGroup = t.device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [
{
binding: 0,
resource: sampler,
},
{
binding: 1,
resource: srcTexture.createView(),
},
],
});
const renderPassDescriptor: GPURenderPassDescriptor = {
colorAttachments: [
{
view: ctx.getCurrentTexture().createView(),
clearValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },
loadOp: 'clear',
storeOp: 'store',
},
],
};
const commandEncoder = t.device.createCommandEncoder({ label: 'DrawTextureSample' });
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, uniformBindGroup);
passEncoder.draw(6, 1, 0, 0);
passEncoder.end();
t.device.queue.submit([commandEncoder.finish()]);
}