为什么我的 wgpu 绑定组中只能有一个纹理绑定?

fra*_*pps 3 graphics rust webgpu wgpu-rs

我目前有一个BindGroupandBindGroupLayout看起来像这样:

let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
    label: None,
    entries: &[wgpu::BindGroupLayoutEntry {
        binding: 0,
        visibility: wgpu::ShaderStages::FRAGMENT,
        ty: wgpu::BindingType::Texture {
            sample_type: wgpu::TextureSampleType::Float { filterable: true },
            view_dimension: wgpu::TextureViewDimension::D2,
            multisampled: false,
        },
        count: None,
    }],
});

let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
    label: None,
    entries: &[wgpu::BindGroupEntry {
        binding: 0,
        resource: wgpu::BindingResource::TextureView(&target),
    }],
    layout: &bind_group_layout,
});
Run Code Online (Sandbox Code Playgroud)

并按预期工作。

对于上下文:我在渲染通道中使用它们来进行后处理。

现在我的着色器中还需要一个Sampler。首先我创建了Sampler

let linear_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
    mag_filter: wgpu::FilterMode::Nearest,
    min_filter: wgpu::FilterMode::Nearest,
    mipmap_filter: wgpu::FilterMode::Nearest,
    ..Default::default()
});
Run Code Online (Sandbox Code Playgroud)

并将其添加到布局和绑定组中,如下所示:

let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
    label: None,
    entries: &[
        wgpu::BindGroupLayoutEntry {
            binding: 0,
            visibility: wgpu::ShaderStages::FRAGMENT,
            ty: wgpu::BindingType::Texture {
                sample_type: wgpu::TextureSampleType::Float { filterable: true },
                view_dimension: wgpu::TextureViewDimension::D2,
                multisampled: false,
            },
            count: None,
        },
        wgpu::BindGroupLayoutEntry {
            binding: 1,
            visibility: wgpu::ShaderStages::FRAGMENT,
            ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::NonFiltering),
            count: None,
        },
    ],
});

let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
    label: None,
    entries: &[
        wgpu::BindGroupEntry {
            binding: 0,
            resource: wgpu::BindingResource::TextureView(&target),
        },
        wgpu::BindGroupEntry {
            binding: 1,
            resource: wgpu::BindingResource::Sampler(&linear_sampler),
        },
    ],
    layout: &bind_group_layout,
});
Run Code Online (Sandbox Code Playgroud)

然而,当我现在运行我的代码时,会收到一个ValidationError消息:

thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 2, Metal)>`
    In a draw command, indexed:false indirect:false
      note: render pipeline = `<RenderPipeline-(1, 1, Metal)>`
    the pipeline layout, associated with the current render pipeline, contains a bind group layout at index 0 which is incompatible with the bind group layout associated with the bind group at 0
Run Code Online (Sandbox Code Playgroud)

Metal我注意到和上也有同样的行为DirectX 12。我还注意到,当我仅添加一个采样器或添加两个纹理绑定时,会出现相同的错误,如下所示:

thread 'main' panicked at 'wgpu error: Validation Error

Caused by:
    In a RenderPass
      note: encoder = `<CommandBuffer-(0, 2, Metal)>`
    In a draw command, indexed:false indirect:false
      note: render pipeline = `<RenderPipeline-(1, 1, Metal)>`
    the pipeline layout, associated with the current render pipeline, contains a bind group layout at index 0 which is incompatible with the bind group layout associated with the bind group at 0
Run Code Online (Sandbox Code Playgroud)

因此,我发现唯一有效的配置是当绑定组和布局恰好包含一个纹理绑定时。

有人知道为什么会出现这种情况吗?

完整的代码可以在这里找到。失败的代码位于src/fxaa/并且可以使用进行测试cargo run --example triangle,原始工作代码位于src/grayscale/并且可以使用来运行cargo run --example text。为了简洁起见,我省略了着色器,因为它们的内容似乎并不重要,但它们也可以在上面链接的存储库中找到。

Jin*_* Li 5

因为在 中fn resize(&mut self, device: &wgpu::Device, size: &wgpu::Extent3d),您创建了一个bind_group与已绑定的不兼容的新对象bind_group_layout

如果重新创建新的bind_group_layout,还需要重新创建新的管道和pipeline_layout