3

I'm trying to use an external_texture in WebGpu, but am running into an error.

localhost/:1 Destroyed texture [Texture] used in a submit.
    at ValidateCanUseInSubmitNow (../../third_party/dawn/src/dawn_native/Texture.cpp:605)
    at ValidateSubmit (../../third_party/dawn/src/dawn_native/Queue.cpp:395)

I've created a video element and created an external texture:

const video = document.createElement('video');
video.loop = true;
video.autoplay = true;
video.muted = true;
video.src = '/videos/sample.webm';
await video.play();

const videoTexture = device.importExternalTexture({
    source: video,
  });

I'm binding it like so:

{
    binding: 2,
    resource: videoTexture,
},

and am referencing it in my shader like the following:

[[binding(2), group(0)]] var diffuseTexture: texture_external;

...
var diffuse = textureSampleLevel(diffuseTexture, textureSampler, in.uv).xyz

I've stored both the video element and videoTexture to a variable just in case it was something to do with garbage collection, but it has not helped. I seem to be doing everything the same as in the video uploading sample (https://austin-eng.com/webgpu-samples/samples/videoUploading) except there's a lot more going on in my program.

Axiverse
  • 1,589
  • 3
  • 14
  • 30

1 Answers1

3

It turns out that the lifetime of an video external texture is very limited. When your code returns control to the browser, the external texture will be destroyed. For most 3d applications, this would most likely be when the requestAnimationFrame finishes.

In order to alleviate this you have to create both the bind group and the external texture in the same frame as you render. It may be helpful to put your external texture(s) in a separate bind group since you will have to recreate it.

e.g.

function frame() {

    var externalTextureBindGroup = device.createBindGroup({
        layout: pipeline.getBindGroupLayout(1),
        entries: [
            {
                binding: 0,
                resource: device.importExternalTexture({
                    source: video,
                    }),
            },
        ],
    }); 

    // additional setup.

    passEncoder.setBindGroup(1, externalTextureBindGroup);
    passEncoder.drawIndexed(group.count, 1, group.start, 0);

    // additional draws

    requestAnimationFrame(frame);

}

References:

Axiverse
  • 1,589
  • 3
  • 14
  • 30