@@ -281,4 +281,128 @@ describe("External Textures", () => {
281281 const image = encodeImage ( result ) ;
282282 checkImage ( image , "snapshots/f2.png" ) ;
283283 } ) ;
284+ it ( "flipY: false should not flip (same as omitting flipY)" , async ( ) => {
285+ const result = await client . eval (
286+ ( { gpu, device, ctx, canvas, urls : { fTexture } } ) => {
287+ const module = device . createShaderModule ( {
288+ label : "our hardcoded textured quad shaders" ,
289+ code : /* wgsl */ `
290+ struct OurVertexShaderOutput {
291+ @builtin(position) position: vec4f,
292+ @location(0) texcoord: vec2f,
293+ };
294+
295+ @vertex fn vs(
296+ @builtin(vertex_index) vertexIndex : u32
297+ ) -> OurVertexShaderOutput {
298+ let pos = array(
299+ // 1st triangle
300+ vec2f( 0.0, 0.0), // center
301+ vec2f( 1.0, 0.0), // right, center
302+ vec2f( 0.0, 1.0), // center, top
303+
304+ // 2st triangle
305+ vec2f( 0.0, 1.0), // center, top
306+ vec2f( 1.0, 0.0), // right, center
307+ vec2f( 1.0, 1.0), // right, top
308+ );
309+
310+ var vsOutput: OurVertexShaderOutput;
311+ let xy = pos[vertexIndex];
312+ vsOutput.position = vec4f(xy, 0.0, 1.0);
313+ vsOutput.texcoord = xy;
314+ return vsOutput;
315+ }
316+
317+ @group(0) @binding(0) var ourSampler: sampler;
318+ @group(0) @binding(1) var ourTexture: texture_2d<f32>;
319+
320+ @fragment fn fs(fsInput: OurVertexShaderOutput) -> @location(0) vec4f {
321+ return textureSample(ourTexture, ourSampler, fsInput.texcoord);
322+ }
323+ ` ,
324+ } ) ;
325+
326+ const presentationFormat = gpu . getPreferredCanvasFormat ( ) ;
327+ const pipeline = device . createRenderPipeline ( {
328+ label : "hardcoded textured quad pipeline" ,
329+ layout : "auto" ,
330+ vertex : {
331+ module,
332+ } ,
333+ fragment : {
334+ module,
335+ targets : [ { format : presentationFormat } ] ,
336+ } ,
337+ } ) ;
338+
339+ return fetch ( fTexture ) . then ( ( res ) => {
340+ return res . blob ( ) . then ( ( blob ) => {
341+ return createImageBitmap ( blob , {
342+ colorSpaceConversion : "none" ,
343+ } ) . then ( ( source ) => {
344+ const texture = device . createTexture ( {
345+ label : fTexture ,
346+ format : "rgba8unorm" ,
347+ size : [ source . width , source . height ] ,
348+ usage :
349+ GPUTextureUsage . TEXTURE_BINDING |
350+ GPUTextureUsage . COPY_DST |
351+ GPUTextureUsage . RENDER_ATTACHMENT ,
352+ } ) ;
353+ // Explicitly pass flipY: false - should behave same as omitting it
354+ device . queue . copyExternalImageToTexture (
355+ { source, flipY : false } ,
356+ { texture } ,
357+ { width : source . width , height : source . height } ,
358+ ) ;
359+ const sampler = device . createSampler ( {
360+ addressModeU : "repeat" ,
361+ addressModeV : "repeat" ,
362+ magFilter : "linear" ,
363+ } ) ;
364+
365+ const bindGroup = device . createBindGroup ( {
366+ layout : pipeline . getBindGroupLayout ( 0 ) ,
367+ entries : [
368+ { binding : 0 , resource : sampler } ,
369+ { binding : 1 , resource : texture . createView ( ) } ,
370+ ] ,
371+ } ) ;
372+
373+ const renderPassDescriptor : GPURenderPassDescriptor = {
374+ label : "our basic canvas renderPass" ,
375+ colorAttachments : [
376+ {
377+ view : ctx . getCurrentTexture ( ) . createView ( ) ,
378+ clearValue : [ 0.3 , 0.3 , 0.3 , 1 ] ,
379+ loadOp : "clear" ,
380+ storeOp : "store" ,
381+ } ,
382+ ] ,
383+ } ;
384+
385+ const encoder = device . createCommandEncoder ( {
386+ label : "render quad encoder" ,
387+ } ) ;
388+ const pass = encoder . beginRenderPass ( renderPassDescriptor ) ;
389+ pass . setPipeline ( pipeline ) ;
390+ pass . setBindGroup ( 0 , bindGroup ) ;
391+ pass . draw ( 6 ) ;
392+ pass . end ( ) ;
393+
394+ const commandBuffer = encoder . finish ( ) ;
395+ device . queue . submit ( [ commandBuffer ] ) ;
396+ return canvas . getImageData ( ) ;
397+ } ) ;
398+ } ) ;
399+ } ) ;
400+ } ,
401+ { } ,
402+ ) ;
403+ const image = encodeImage ( result ) ;
404+ // flipY: false should produce the same result as omitting flipY (f2.png)
405+ // This test catches the bug where std::optional<bool> was checked incorrectly
406+ checkImage ( image , "snapshots/f2.png" ) ;
407+ } ) ;
284408} ) ;
0 commit comments