Skip to content

Commit

Permalink
move out ID to resource mapping code from Device.create_bind_group
Browse files Browse the repository at this point in the history
  • Loading branch information
teoxoy committed Jul 2, 2024
1 parent c6ca0c5 commit 1bbaf38
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 92 deletions.
46 changes: 44 additions & 2 deletions wgpu-core/src/binding_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::{
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
pipeline::{ComputePipeline, RenderPipeline},
resource::{
DestroyedResourceError, Labeled, MissingBufferUsageError, MissingTextureUsageError,
ResourceErrorIdent, TrackingData,
Buffer, DestroyedResourceError, Labeled, MissingBufferUsageError, MissingTextureUsageError,
ResourceErrorIdent, Sampler, TextureView, TrackingData,
},
resource_log,
snatch::{SnatchGuard, Snatchable},
Expand Down Expand Up @@ -414,6 +414,16 @@ pub struct BindGroupEntry<'a> {
pub resource: BindingResource<'a>,
}

/// Bindable resource and the slot to bind it to.
#[derive(Clone, Debug)]
pub struct ResolvedBindGroupEntry<'a, A: HalApi> {
/// Slot for which binding provides resource. Corresponds to an entry of the same
/// binding index in the [`BindGroupLayoutDescriptor`].
pub binding: u32,
/// Resource to attach to the binding
pub resource: ResolvedBindingResource<'a, A>,
}

/// Describes a group of bindings and the resources to be bound.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
Expand All @@ -428,6 +438,19 @@ pub struct BindGroupDescriptor<'a> {
pub entries: Cow<'a, [BindGroupEntry<'a>]>,
}

/// Describes a group of bindings and the resources to be bound.
#[derive(Clone, Debug)]
pub struct ResolvedBindGroupDescriptor<'a, A: HalApi> {
/// Debug label of the bind group.
///
/// This will show up in graphics debuggers for easy identification.
pub label: Label<'a>,
/// The [`BindGroupLayout`] that corresponds to this bind group.
pub layout: Arc<BindGroupLayout<A>>,
/// The resources to bind to this bind group.
pub entries: Cow<'a, [ResolvedBindGroupEntry<'a, A>]>,
}

/// Describes a [`BindGroupLayout`].
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Expand Down Expand Up @@ -754,6 +777,13 @@ pub struct BufferBinding {
pub size: Option<wgt::BufferSize>,
}

#[derive(Clone, Debug)]
pub struct ResolvedBufferBinding<A: HalApi> {
pub buffer: Arc<Buffer<A>>,
pub offset: wgt::BufferAddress,
pub size: Option<wgt::BufferSize>,
}

// Note: Duplicated in `wgpu-rs` as `BindingResource`
// They're different enough that it doesn't make sense to share a common type
#[derive(Debug, Clone)]
Expand All @@ -767,6 +797,18 @@ pub enum BindingResource<'a> {
TextureViewArray(Cow<'a, [TextureViewId]>),
}

// Note: Duplicated in `wgpu-rs` as `BindingResource`
// They're different enough that it doesn't make sense to share a common type
#[derive(Debug, Clone)]
pub enum ResolvedBindingResource<'a, A: HalApi> {
Buffer(ResolvedBufferBinding<A>),
BufferArray(Cow<'a, [ResolvedBufferBinding<A>]>),
Sampler(Arc<Sampler<A>>),
SamplerArray(Cow<'a, [Arc<Sampler<A>>]>),
TextureView(Arc<TextureView<A>>),
TextureViewArray(Cow<'a, [Arc<TextureView<A>>]>),
}

#[derive(Clone, Debug, Error)]
#[non_exhaustive]
pub enum BindError {
Expand Down
96 changes: 93 additions & 3 deletions wgpu-core/src/device/global.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#[cfg(feature = "trace")]
use crate::device::trace;
use crate::{
api_log, binding_model, command, conv,
api_log,
binding_model::{
self, BindGroupEntry, BindingResource, BufferBinding, ResolvedBindGroupDescriptor,
ResolvedBindGroupEntry, ResolvedBindingResource, ResolvedBufferBinding,
},
command, conv,
device::{
bgl, life::WaitIdleError, map_buffer, queue, DeviceError, DeviceLostClosure,
DeviceLostReason, HostMap,
Expand All @@ -21,6 +26,7 @@ use crate::{
self, BufferAccessError, BufferAccessResult, BufferMapOperation, CreateBufferError,
Trackable,
},
storage::Storage,
Label,
};

Expand Down Expand Up @@ -1157,12 +1163,96 @@ impl Global {
trace.add(trace::Action::CreateBindGroup(fid.id(), desc.clone()));
}

let bind_group_layout = match hub.bind_group_layouts.get(desc.layout) {
let layout = match hub.bind_group_layouts.get(desc.layout) {
Ok(layout) => layout,
Err(..) => break 'error binding_model::CreateBindGroupError::InvalidLayout,
};

let bind_group = match device.create_bind_group(&bind_group_layout, desc, hub) {
fn map_entry<'a, A: HalApi>(
e: &BindGroupEntry<'a>,
buffer_storage: &Storage<resource::Buffer<A>>,
sampler_storage: &Storage<resource::Sampler<A>>,
texture_view_storage: &Storage<resource::TextureView<A>>,
) -> Result<ResolvedBindGroupEntry<'a, A>, binding_model::CreateBindGroupError>
{
let map_buffer = |bb: &BufferBinding| {
buffer_storage
.get_owned(bb.buffer_id)
.map(|buffer| ResolvedBufferBinding {
buffer,
offset: bb.offset,
size: bb.size,
})
.map_err(|_| {
binding_model::CreateBindGroupError::InvalidBufferId(bb.buffer_id)
})
};
let map_sampler = |id: &id::SamplerId| {
sampler_storage
.get_owned(*id)
.map_err(|_| binding_model::CreateBindGroupError::InvalidSamplerId(*id))
};
let map_view = |id: &id::TextureViewId| {
texture_view_storage
.get_owned(*id)
.map_err(|_| binding_model::CreateBindGroupError::InvalidTextureViewId(*id))
};
let resource = match e.resource {
BindingResource::Buffer(ref buffer) => {
ResolvedBindingResource::Buffer(map_buffer(buffer)?)
}
BindingResource::BufferArray(ref buffers) => {
let buffers = buffers
.iter()
.map(map_buffer)
.collect::<Result<Vec<_>, _>>()?;
ResolvedBindingResource::BufferArray(Cow::Owned(buffers))
}
BindingResource::Sampler(ref sampler) => {
ResolvedBindingResource::Sampler(map_sampler(sampler)?)
}
BindingResource::SamplerArray(ref samplers) => {
let samplers = samplers
.iter()
.map(map_sampler)
.collect::<Result<Vec<_>, _>>()?;
ResolvedBindingResource::SamplerArray(Cow::Owned(samplers))
}
BindingResource::TextureView(ref view) => {
ResolvedBindingResource::TextureView(map_view(view)?)
}
BindingResource::TextureViewArray(ref views) => {
let views = views.iter().map(map_view).collect::<Result<Vec<_>, _>>()?;
ResolvedBindingResource::TextureViewArray(Cow::Owned(views))
}
};
Ok(ResolvedBindGroupEntry {
binding: e.binding,
resource,
})
}

let entries = {
let buffer_guard = hub.buffers.read();
let texture_view_guard = hub.texture_views.read();
let sampler_guard = hub.samplers.read();
desc.entries
.iter()
.map(|e| map_entry(e, &buffer_guard, &sampler_guard, &texture_view_guard))
.collect::<Result<Vec<_>, _>>()
};
let entries = match entries {
Ok(entries) => Cow::Owned(entries),
Err(e) => break 'error e,
};

let desc = ResolvedBindGroupDescriptor {
label: desc.label.clone(),
layout,
entries,
};

let bind_group = match device.create_bind_group(desc) {
Ok(bind_group) => bind_group,
Err(e) => break 'error e,
};
Expand Down
Loading

0 comments on commit 1bbaf38

Please sign in to comment.