diff --git a/packages/typegpu/src/core/texture/textureWrite.ts b/packages/typegpu/src/core/texture/textureWrite.ts index aa711d1eca..0cfdba180e 100644 --- a/packages/typegpu/src/core/texture/textureWrite.ts +++ b/packages/typegpu/src/core/texture/textureWrite.ts @@ -85,9 +85,9 @@ function imageSize(source: GPUCopyExternalImageSource): [number, number] { return [naturalWidth, naturalHeight]; } - const { codedWidth, codedHeight } = source as VideoFrame; - if (codedWidth && codedHeight) { - return [codedWidth, codedHeight]; + const { displayWidth, displayHeight } = source as VideoFrame; + if (displayWidth && displayHeight) { + return [displayWidth, displayHeight]; } const { width, height } = source as ImageBitmap; diff --git a/packages/typegpu/tests/texture.test.ts b/packages/typegpu/tests/texture.test.ts index c49defc9d6..f96632eb4e 100644 --- a/packages/typegpu/tests/texture.test.ts +++ b/packages/typegpu/tests/texture.test.ts @@ -772,6 +772,36 @@ Overload 3 of 4, '(schema: "(Error) Texture not usable as storage, call $usage(' ); }); + it('uses the display size of a VideoFrame instead of its coded size', ({ root, device }) => { + const texture = root + .createTexture({ + size: [320, 240], + format: 'rgba8unorm', + }) + .$usage('render'); + + const mockFrame = { + codedWidth: 336, + codedHeight: 258, + displayWidth: 320, + displayHeight: 240, + } as VideoFrame; + + texture.write(mockFrame); + + expect(device.mock.queue.copyExternalImageToTexture).toHaveBeenCalledWith( + { source: mockFrame, origin: { x: 0, y: 0 }, flipY: false }, + { + texture: expect.anything(), + mipLevel: 0, + origin: { x: 0, y: 0, z: 0 }, + premultipliedAlpha: false, + colorSpace: 'srgb', + }, + [320, 240], + ); + }); + it('throws when image source writes are missing render usage', ({ root }) => { const texture = root.createTexture({ size: [32, 32],