mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
native: bind groups for both compute and graphics
This commit is contained in:
parent
6699f4bed1
commit
dee685aa0c
@ -1,12 +1,10 @@
|
|||||||
use crate::registry::{HUB, Items, ConcreteItems};
|
use crate::registry::{HUB, Items};
|
||||||
use crate::{
|
use crate::{
|
||||||
B, Stored, WeaklyStored,
|
B, Stored, WeaklyStored,
|
||||||
BindGroup, PipelineLayout,
|
|
||||||
BindGroupId, BindGroupLayoutId, PipelineLayoutId,
|
BindGroupId, BindGroupLayoutId, PipelineLayoutId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use hal;
|
use hal;
|
||||||
use parking_lot::RwLockReadGuard;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
@ -21,35 +19,20 @@ pub struct Binder {
|
|||||||
entries: Vec<BindGroupEntry>,
|
entries: Vec<BindGroupEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NewBind<'a, B: hal::Backend> {
|
//Note: we can probably make this much better than passing an `FnMut`
|
||||||
pipeline_layout_guard: RwLockReadGuard<'a, ConcreteItems<PipelineLayout<B>>>,
|
|
||||||
pipeline_layout_id: PipelineLayoutId,
|
|
||||||
bind_group_guard: RwLockReadGuard<'a, ConcreteItems<BindGroup<B>>>,
|
|
||||||
bind_group_id: BindGroupId,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, B: hal::Backend> NewBind<'a, B> {
|
|
||||||
pub fn pipeline_layout(&self) -> &B::PipelineLayout {
|
|
||||||
&self.pipeline_layout_guard.get(self.pipeline_layout_id).raw
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn descriptor_set(&self) -> &B::DescriptorSet {
|
|
||||||
&self.bind_group_guard.get(self.bind_group_id).raw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Binder {
|
impl Binder {
|
||||||
//Note: `'a` is need to avoid inheriting the lifetime from `self`
|
pub fn bind_group<F>(&mut self, index: usize, bind_group_id: BindGroupId, mut fun: F)
|
||||||
pub fn bind_group<'a>(
|
where
|
||||||
&mut self, index: u32, bind_group_id: BindGroupId
|
F: FnMut(&<B as hal::Backend>::PipelineLayout, &<B as hal::Backend>::DescriptorSet),
|
||||||
) -> Option<NewBind<'a, B>> {
|
{
|
||||||
let bind_group_guard = HUB.bind_groups.read();
|
let bind_group_guard = HUB.bind_groups.read();
|
||||||
let bind_group = bind_group_guard.get(bind_group_id);
|
let bind_group = bind_group_guard.get(bind_group_id);
|
||||||
|
|
||||||
while self.entries.len() <= index as usize {
|
while self.entries.len() <= index {
|
||||||
self.entries.push(BindGroupEntry::default());
|
self.entries.push(BindGroupEntry::default());
|
||||||
}
|
}
|
||||||
*self.entries.get_mut(index as usize).unwrap() = BindGroupEntry {
|
*self.entries.get_mut(index).unwrap() = BindGroupEntry {
|
||||||
layout: Some(bind_group.layout_id.clone()),
|
layout: Some(bind_group.layout_id.clone()),
|
||||||
data: Some(Stored {
|
data: Some(Stored {
|
||||||
value: bind_group_id,
|
value: bind_group_id,
|
||||||
@ -61,16 +44,41 @@ impl Binder {
|
|||||||
//TODO: we can cache the group layout ids of the current pipeline in `Binder` itself
|
//TODO: we can cache the group layout ids of the current pipeline in `Binder` itself
|
||||||
let pipeline_layout_guard = HUB.pipeline_layouts.read();
|
let pipeline_layout_guard = HUB.pipeline_layouts.read();
|
||||||
let pipeline_layout = pipeline_layout_guard.get(pipeline_layout_id);
|
let pipeline_layout = pipeline_layout_guard.get(pipeline_layout_id);
|
||||||
if pipeline_layout.bind_group_layout_ids[index as usize] == bind_group.layout_id {
|
if pipeline_layout.bind_group_layout_ids[index] == bind_group.layout_id {
|
||||||
return Some(NewBind {
|
fun(&pipeline_layout.raw, &bind_group.raw);
|
||||||
pipeline_layout_guard,
|
|
||||||
pipeline_layout_id,
|
|
||||||
bind_group_guard,
|
|
||||||
bind_group_id,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
None
|
pub fn change_layout<F>(&mut self, pipeline_layout_id: PipelineLayoutId, mut fun: F)
|
||||||
|
where
|
||||||
|
F: FnMut(&<B as hal::Backend>::PipelineLayout, usize, &<B as hal::Backend>::DescriptorSet),
|
||||||
|
{
|
||||||
|
if self.pipeline_layout_id == Some(WeaklyStored(pipeline_layout_id)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pipeline_layout_id = Some(WeaklyStored(pipeline_layout_id));
|
||||||
|
let pipeline_layout_guard = HUB.pipeline_layouts.read();
|
||||||
|
let pipeline_layout = pipeline_layout_guard.get(pipeline_layout_id);
|
||||||
|
let bing_group_guard = HUB.bind_groups.read();
|
||||||
|
|
||||||
|
while self.entries.len() < pipeline_layout.bind_group_layout_ids.len() {
|
||||||
|
self.entries.push(BindGroupEntry::default());
|
||||||
|
}
|
||||||
|
for (index, (entry, bgl_id)) in self.entries
|
||||||
|
.iter_mut()
|
||||||
|
.zip(&pipeline_layout.bind_group_layout_ids)
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
if entry.layout == Some(bgl_id.clone()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
entry.layout = Some(bgl_id.clone());
|
||||||
|
if let Some(ref bg_id) = entry.data {
|
||||||
|
let bind_group = bing_group_guard.get(bg_id.value);
|
||||||
|
fun(&pipeline_layout.raw, index, &bind_group.raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,43 +38,6 @@ pub extern "C" fn wgpu_compute_pass_end_pass(pass_id: ComputePassId) -> CommandB
|
|||||||
pass.cmb_id.value
|
pass.cmb_id.value
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wgpu_compute_pass_set_bind_group(
|
|
||||||
pass_id: ComputePassId,
|
|
||||||
index: u32,
|
|
||||||
bind_group_id: BindGroupId,
|
|
||||||
) {
|
|
||||||
let mut pass_guard = HUB.compute_passes.write();
|
|
||||||
let pass = pass_guard.get_mut(pass_id);
|
|
||||||
if let Some(bind) = pass.binder.bind_group(index, bind_group_id) {
|
|
||||||
unsafe {
|
|
||||||
pass.raw.bind_compute_descriptor_sets(
|
|
||||||
bind.pipeline_layout(),
|
|
||||||
index as usize,
|
|
||||||
iter::once(bind.descriptor_set()),
|
|
||||||
&[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn wgpu_compute_pass_set_pipeline(
|
|
||||||
pass_id: ComputePassId,
|
|
||||||
pipeline_id: ComputePipelineId,
|
|
||||||
) {
|
|
||||||
let pipeline_guard = HUB.compute_pipelines.read();
|
|
||||||
let pipeline = &pipeline_guard.get(pipeline_id).raw;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
HUB.compute_passes
|
|
||||||
.write()
|
|
||||||
.get_mut(pass_id)
|
|
||||||
.raw
|
|
||||||
.bind_compute_pipeline(pipeline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wgpu_compute_pass_dispatch(pass_id: ComputePassId, x: u32, y: u32, z: u32) {
|
pub extern "C" fn wgpu_compute_pass_dispatch(pass_id: ComputePassId, x: u32, y: u32, z: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -85,3 +48,46 @@ pub extern "C" fn wgpu_compute_pass_dispatch(pass_id: ComputePassId, x: u32, y:
|
|||||||
.dispatch([x, y, z]);
|
.dispatch([x, y, z]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wgpu_compute_pass_set_bind_group(
|
||||||
|
pass_id: ComputePassId,
|
||||||
|
index: u32,
|
||||||
|
bind_group_id: BindGroupId,
|
||||||
|
) {
|
||||||
|
let mut pass_guard = HUB.compute_passes.write();
|
||||||
|
let ComputePass { ref mut raw, ref mut binder, .. } = *pass_guard.get_mut(pass_id);
|
||||||
|
|
||||||
|
binder.bind_group(index as usize, bind_group_id, |pipeline_layout, desc_set| unsafe {
|
||||||
|
raw.bind_compute_descriptor_sets(
|
||||||
|
pipeline_layout,
|
||||||
|
index as usize,
|
||||||
|
iter::once(desc_set),
|
||||||
|
&[],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wgpu_compute_pass_set_pipeline(
|
||||||
|
pass_id: ComputePassId,
|
||||||
|
pipeline_id: ComputePipelineId,
|
||||||
|
) {
|
||||||
|
let mut pass_guard = HUB.compute_passes.write();
|
||||||
|
let ComputePass { ref mut raw, ref mut binder, .. } = *pass_guard.get_mut(pass_id);
|
||||||
|
|
||||||
|
let pipeline_guard = HUB.compute_pipelines.read();
|
||||||
|
let pipeline = pipeline_guard.get(pipeline_id);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
raw.bind_compute_pipeline(&pipeline.raw);
|
||||||
|
}
|
||||||
|
binder.change_layout(pipeline.layout_id.0, |pipeline_layout, index, desc_set| unsafe {
|
||||||
|
raw.bind_compute_descriptor_sets(
|
||||||
|
pipeline_layout,
|
||||||
|
index,
|
||||||
|
iter::once(desc_set),
|
||||||
|
&[],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -1,17 +1,21 @@
|
|||||||
|
use crate::command::bind::Binder;
|
||||||
use crate::resource::BufferUsageFlags;
|
use crate::resource::BufferUsageFlags;
|
||||||
use crate::registry::{Items, HUB};
|
use crate::registry::{Items, HUB};
|
||||||
use crate::track::{BufferTracker, TextureTracker, TrackPermit};
|
use crate::track::{BufferTracker, TextureTracker, TrackPermit};
|
||||||
use crate::{
|
use crate::{
|
||||||
CommandBuffer, Stored,
|
CommandBuffer, Stored,
|
||||||
BufferId, CommandBufferId, RenderPassId,
|
BindGroupId, BufferId, CommandBufferId, RenderPassId, RenderPipelineId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use hal::command::RawCommandBuffer;
|
use hal::command::RawCommandBuffer;
|
||||||
|
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
|
|
||||||
pub struct RenderPass<B: hal::Backend> {
|
pub struct RenderPass<B: hal::Backend> {
|
||||||
raw: B::CommandBuffer,
|
raw: B::CommandBuffer,
|
||||||
cmb_id: Stored<CommandBufferId>,
|
cmb_id: Stored<CommandBufferId>,
|
||||||
|
binder: Binder,
|
||||||
buffer_tracker: BufferTracker,
|
buffer_tracker: BufferTracker,
|
||||||
texture_tracker: TextureTracker,
|
texture_tracker: TextureTracker,
|
||||||
}
|
}
|
||||||
@ -21,6 +25,7 @@ impl<B: hal::Backend> RenderPass<B> {
|
|||||||
RenderPass {
|
RenderPass {
|
||||||
raw,
|
raw,
|
||||||
cmb_id,
|
cmb_id,
|
||||||
|
binder: Binder::default(),
|
||||||
buffer_tracker: BufferTracker::new(),
|
buffer_tracker: BufferTracker::new(),
|
||||||
texture_tracker: TextureTracker::new(),
|
texture_tracker: TextureTracker::new(),
|
||||||
}
|
}
|
||||||
@ -152,3 +157,46 @@ pub extern "C" fn wgpu_render_pass_draw_indexed(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wgpu_render_pass_set_bind_group(
|
||||||
|
pass_id: RenderPassId,
|
||||||
|
index: u32,
|
||||||
|
bind_group_id: BindGroupId,
|
||||||
|
) {
|
||||||
|
let mut pass_guard = HUB.render_passes.write();
|
||||||
|
let RenderPass { ref mut raw, ref mut binder, .. } = *pass_guard.get_mut(pass_id);
|
||||||
|
|
||||||
|
binder.bind_group(index as usize, bind_group_id, |pipeline_layout, desc_set| unsafe {
|
||||||
|
raw.bind_compute_descriptor_sets(
|
||||||
|
pipeline_layout,
|
||||||
|
index as usize,
|
||||||
|
iter::once(desc_set),
|
||||||
|
&[],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn wgpu_render_pass_set_pipeline(
|
||||||
|
pass_id: RenderPassId,
|
||||||
|
pipeline_id: RenderPipelineId,
|
||||||
|
) {
|
||||||
|
let mut pass_guard = HUB.render_passes.write();
|
||||||
|
let RenderPass { ref mut raw, ref mut binder, .. } = *pass_guard.get_mut(pass_id);
|
||||||
|
|
||||||
|
let pipeline_guard = HUB.render_pipelines.read();
|
||||||
|
let pipeline = pipeline_guard.get(pipeline_id);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
raw.bind_graphics_pipeline(&pipeline.raw);
|
||||||
|
}
|
||||||
|
binder.change_layout(pipeline.layout_id.0, |pipeline_layout, index, desc_set| unsafe {
|
||||||
|
raw.bind_graphics_descriptor_sets(
|
||||||
|
pipeline_layout,
|
||||||
|
index,
|
||||||
|
iter::once(desc_set),
|
||||||
|
&[],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -986,7 +986,10 @@ pub extern "C" fn wgpu_device_create_render_pipeline(
|
|||||||
|
|
||||||
HUB.render_pipelines
|
HUB.render_pipelines
|
||||||
.write()
|
.write()
|
||||||
.register(pipeline::RenderPipeline { raw: pipeline })
|
.register(pipeline::RenderPipeline {
|
||||||
|
raw: pipeline,
|
||||||
|
layout_id: WeaklyStored(desc.layout),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
use crate::resource;
|
use crate::resource;
|
||||||
use crate::{BlendStateId, ByteArray, DepthStencilStateId, PipelineLayoutId, ShaderModuleId};
|
use crate::{
|
||||||
|
ByteArray, WeaklyStored,
|
||||||
|
BlendStateId, DepthStencilStateId, PipelineLayoutId, ShaderModuleId,
|
||||||
|
};
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
@ -212,6 +215,7 @@ pub struct ComputePipelineDescriptor {
|
|||||||
|
|
||||||
pub(crate) struct ComputePipeline<B: hal::Backend> {
|
pub(crate) struct ComputePipeline<B: hal::Backend> {
|
||||||
pub raw: B::ComputePipeline,
|
pub raw: B::ComputePipeline,
|
||||||
|
pub layout_id: WeaklyStored<PipelineLayoutId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -251,4 +255,5 @@ pub struct RenderPipelineDescriptor {
|
|||||||
|
|
||||||
pub(crate) struct RenderPipeline<B: hal::Backend> {
|
pub(crate) struct RenderPipeline<B: hal::Backend> {
|
||||||
pub raw: B::GraphicsPipeline,
|
pub raw: B::GraphicsPipeline,
|
||||||
|
pub layout_id: WeaklyStored<PipelineLayoutId>,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user