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

fsi0uk1n  于 2023-01-30  发布在  其他
关注(0)|答案(1)|浏览(134)

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

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,
});

并且如期望的那样工作。
上下文:我在渲染过程中使用这些来进行后期处理。
现在我还需要一个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()
});

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

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,
});

然而,当我现在运行代码时,会得到一个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

我注意到在MetalDirectX 12上有相同的行为。我还注意到,当我只添加一个采样器或添加两个纹理绑定时,我会得到相同的错误,如下所示:

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::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),
        },
        wgpu::BindGroupEntry {
            binding: 1,
            resource: wgpu::BindingResource::TextureView(&target),
        },
    ],
    layout: &bind_group_layout,
});

所以我发现唯一有效的配置是绑定组和布局只包含一个纹理绑定。
有人知道为什么会这样吗?
完整的代码可以在here中找到。失败的代码在src/fxaa/中,可以使用cargo run --example triangle测试,原始工作代码在src/grayscale/中,可以使用cargo run --example text运行。为了简洁起见,我省略了着色器,因为它们的内容似乎并不重要,但它们也可以在上面链接的repo中找到。

ni65a41a

ni65a41a1#

因为在fn resize(&mut self, device: &wgpu::Device, size: &wgpu::Extent3d)中,您创建了一个与已经绑定的bind_group_layout不兼容的新bind_group
如果重新创建新的bind_group_layout,还需要重新创建新的管道和pipeline_layout

相关问题