mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
[wgpu-core] make implicit_pipeline_ids
arg optional for users that don't provide IDs
This commit is contained in:
parent
7e112ca4c0
commit
91924fb603
@ -14,8 +14,6 @@ use std::rc::Rc;
|
|||||||
use super::error::WebGpuError;
|
use super::error::WebGpuError;
|
||||||
use super::error::WebGpuResult;
|
use super::error::WebGpuResult;
|
||||||
|
|
||||||
const MAX_BIND_GROUPS: usize = 8;
|
|
||||||
|
|
||||||
pub(crate) struct WebGpuPipelineLayout(
|
pub(crate) struct WebGpuPipelineLayout(
|
||||||
pub(crate) crate::Instance,
|
pub(crate) crate::Instance,
|
||||||
pub(crate) wgpu_core::id::PipelineLayoutId,
|
pub(crate) wgpu_core::id::PipelineLayoutId,
|
||||||
@ -118,21 +116,12 @@ pub fn op_webgpu_create_compute_pipeline(
|
|||||||
},
|
},
|
||||||
cache: None,
|
cache: None,
|
||||||
};
|
};
|
||||||
let implicit_pipelines = match layout {
|
|
||||||
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(_) => None,
|
|
||||||
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => {
|
|
||||||
Some(wgpu_core::device::ImplicitPipelineIds {
|
|
||||||
root_id: None,
|
|
||||||
group_ids: &[None; MAX_BIND_GROUPS],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline(
|
let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline(
|
||||||
device,
|
device,
|
||||||
&descriptor,
|
&descriptor,
|
||||||
None,
|
None,
|
||||||
implicit_pipelines
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
let rid = state
|
let rid = state
|
||||||
@ -397,21 +386,11 @@ pub fn op_webgpu_create_render_pipeline(
|
|||||||
cache: None,
|
cache: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let implicit_pipelines = match args.layout {
|
|
||||||
GPUPipelineLayoutOrGPUAutoLayoutMode::Layout(_) => None,
|
|
||||||
GPUPipelineLayoutOrGPUAutoLayoutMode::Auto(GPUAutoLayoutMode::Auto) => {
|
|
||||||
Some(wgpu_core::device::ImplicitPipelineIds {
|
|
||||||
root_id: None,
|
|
||||||
group_ids: &[None; MAX_BIND_GROUPS],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline(
|
let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline(
|
||||||
device,
|
device,
|
||||||
&descriptor,
|
&descriptor,
|
||||||
None,
|
None,
|
||||||
implicit_pipelines
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
let rid = state
|
let rid = state
|
||||||
|
@ -256,8 +256,8 @@ impl GlobalPlay for wgc::global::Global {
|
|||||||
implicit_context
|
implicit_context
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ic| wgc::device::ImplicitPipelineIds {
|
.map(|ic| wgc::device::ImplicitPipelineIds {
|
||||||
root_id: Some(ic.root_id),
|
root_id: ic.root_id,
|
||||||
group_ids: wgc::id::as_option_slice(&ic.group_ids),
|
group_ids: &ic.group_ids,
|
||||||
});
|
});
|
||||||
let (_, error) =
|
let (_, error) =
|
||||||
self.device_create_compute_pipeline::<A>(device, &desc, Some(id), implicit_ids);
|
self.device_create_compute_pipeline::<A>(device, &desc, Some(id), implicit_ids);
|
||||||
@ -277,8 +277,8 @@ impl GlobalPlay for wgc::global::Global {
|
|||||||
implicit_context
|
implicit_context
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ic| wgc::device::ImplicitPipelineIds {
|
.map(|ic| wgc::device::ImplicitPipelineIds {
|
||||||
root_id: Some(ic.root_id),
|
root_id: ic.root_id,
|
||||||
group_ids: wgc::id::as_option_slice(&ic.group_ids),
|
group_ids: &ic.group_ids,
|
||||||
});
|
});
|
||||||
let (_, error) =
|
let (_, error) =
|
||||||
self.device_create_render_pipeline::<A>(device, &desc, Some(id), implicit_ids);
|
self.device_create_render_pipeline::<A>(device, &desc, Some(id), implicit_ids);
|
||||||
|
@ -1385,12 +1385,18 @@ impl Global {
|
|||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
|
let missing_implicit_pipeline_ids =
|
||||||
|
desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none();
|
||||||
|
|
||||||
let fid = hub.render_pipelines.prepare(id_in);
|
let fid = hub.render_pipelines.prepare(id_in);
|
||||||
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
|
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
|
||||||
|
|
||||||
let is_auto_layout = desc.layout.is_none();
|
|
||||||
|
|
||||||
let error = 'error: {
|
let error = 'error: {
|
||||||
|
if missing_implicit_pipeline_ids {
|
||||||
|
// TODO: categorize this error as API misuse
|
||||||
|
break 'error pipeline::ImplicitLayoutError::MissingImplicitPipelineIds.into();
|
||||||
|
}
|
||||||
|
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
Ok(device) => device,
|
Ok(device) => device,
|
||||||
Err(_) => break 'error DeviceError::InvalidDeviceId.into(),
|
Err(_) => break 'error DeviceError::InvalidDeviceId.into(),
|
||||||
@ -1505,23 +1511,18 @@ impl Global {
|
|||||||
Err(e) => break 'error e,
|
Err(e) => break 'error e,
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_auto_layout {
|
if let Some(ids) = implicit_context.as_ref() {
|
||||||
// TODO: categorize the errors below as API misuse
|
let group_count = pipeline.layout.bind_group_layouts.len();
|
||||||
let ids = if let Some(ids) = implicit_context.as_ref() {
|
if ids.group_ids.len() < group_count {
|
||||||
let group_count = pipeline.layout.bind_group_layouts.len();
|
log::error!(
|
||||||
if ids.group_ids.len() < group_count {
|
"Not enough bind group IDs ({}) specified for the implicit layout ({})",
|
||||||
log::error!(
|
ids.group_ids.len(),
|
||||||
"Not enough bind group IDs ({}) specified for the implicit layout ({})",
|
group_count
|
||||||
ids.group_ids.len(),
|
);
|
||||||
group_count
|
// TODO: categorize this error as API misuse
|
||||||
);
|
break 'error pipeline::ImplicitLayoutError::MissingIds(group_count as _)
|
||||||
break 'error pipeline::ImplicitLayoutError::MissingIds(group_count as _)
|
.into();
|
||||||
.into();
|
}
|
||||||
}
|
|
||||||
ids
|
|
||||||
} else {
|
|
||||||
break 'error pipeline::ImplicitLayoutError::MissingIds(0).into();
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
||||||
let mut bgl_guard = hub.bind_group_layouts.write();
|
let mut bgl_guard = hub.bind_group_layouts.write();
|
||||||
@ -1552,16 +1553,14 @@ impl Global {
|
|||||||
|
|
||||||
let id = fid.assign_error();
|
let id = fid.assign_error();
|
||||||
|
|
||||||
if is_auto_layout {
|
// We also need to assign errors to the implicit pipeline layout and the
|
||||||
// We also need to assign errors to the implicit pipeline layout and the
|
// implicit bind group layouts.
|
||||||
// implicit bind group layouts.
|
if let Some(ids) = implicit_context {
|
||||||
if let Some(ids) = implicit_context {
|
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
||||||
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
let mut bgl_guard = hub.bind_group_layouts.write();
|
||||||
let mut bgl_guard = hub.bind_group_layouts.write();
|
pipeline_layout_guard.insert_error(ids.root_id);
|
||||||
pipeline_layout_guard.insert_error(ids.root_id);
|
for bgl_id in ids.group_ids {
|
||||||
for bgl_id in ids.group_ids {
|
bgl_guard.insert_error(bgl_id);
|
||||||
bgl_guard.insert_error(bgl_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1629,12 +1628,18 @@ impl Global {
|
|||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
|
let missing_implicit_pipeline_ids =
|
||||||
|
desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none();
|
||||||
|
|
||||||
let fid = hub.compute_pipelines.prepare(id_in);
|
let fid = hub.compute_pipelines.prepare(id_in);
|
||||||
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
|
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
|
||||||
|
|
||||||
let is_auto_layout = desc.layout.is_none();
|
|
||||||
|
|
||||||
let error = 'error: {
|
let error = 'error: {
|
||||||
|
if missing_implicit_pipeline_ids {
|
||||||
|
// TODO: categorize this error as API misuse
|
||||||
|
break 'error pipeline::ImplicitLayoutError::MissingImplicitPipelineIds.into();
|
||||||
|
}
|
||||||
|
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
Ok(device) => device,
|
Ok(device) => device,
|
||||||
Err(_) => break 'error DeviceError::InvalidDeviceId.into(),
|
Err(_) => break 'error DeviceError::InvalidDeviceId.into(),
|
||||||
@ -1703,23 +1708,18 @@ impl Global {
|
|||||||
Err(e) => break 'error e,
|
Err(e) => break 'error e,
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_auto_layout {
|
if let Some(ids) = implicit_context.as_ref() {
|
||||||
// TODO: categorize the errors below as API misuse
|
let group_count = pipeline.layout.bind_group_layouts.len();
|
||||||
let ids = if let Some(ids) = implicit_context.as_ref() {
|
if ids.group_ids.len() < group_count {
|
||||||
let group_count = pipeline.layout.bind_group_layouts.len();
|
log::error!(
|
||||||
if ids.group_ids.len() < group_count {
|
"Not enough bind group IDs ({}) specified for the implicit layout ({})",
|
||||||
log::error!(
|
ids.group_ids.len(),
|
||||||
"Not enough bind group IDs ({}) specified for the implicit layout ({})",
|
group_count
|
||||||
ids.group_ids.len(),
|
);
|
||||||
group_count
|
// TODO: categorize this error as API misuse
|
||||||
);
|
break 'error pipeline::ImplicitLayoutError::MissingIds(group_count as _)
|
||||||
break 'error pipeline::ImplicitLayoutError::MissingIds(group_count as _)
|
.into();
|
||||||
.into();
|
}
|
||||||
}
|
|
||||||
ids
|
|
||||||
} else {
|
|
||||||
break 'error pipeline::ImplicitLayoutError::MissingIds(0).into();
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
||||||
let mut bgl_guard = hub.bind_group_layouts.write();
|
let mut bgl_guard = hub.bind_group_layouts.write();
|
||||||
@ -1750,16 +1750,14 @@ impl Global {
|
|||||||
|
|
||||||
let id = fid.assign_error();
|
let id = fid.assign_error();
|
||||||
|
|
||||||
if is_auto_layout {
|
// We also need to assign errors to the implicit pipeline layout and the
|
||||||
// We also need to assign errors to the implicit pipeline layout and the
|
// implicit bind group layouts.
|
||||||
// implicit bind group layouts.
|
if let Some(ids) = implicit_context {
|
||||||
if let Some(ids) = implicit_context {
|
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
||||||
let mut pipeline_layout_guard = hub.pipeline_layouts.write();
|
let mut bgl_guard = hub.bind_group_layouts.write();
|
||||||
let mut bgl_guard = hub.bind_group_layouts.write();
|
pipeline_layout_guard.insert_error(ids.root_id);
|
||||||
pipeline_layout_guard.insert_error(ids.root_id);
|
for bgl_id in ids.group_ids {
|
||||||
for bgl_id in ids.group_ids {
|
bgl_guard.insert_error(bgl_id);
|
||||||
bgl_guard.insert_error(bgl_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,18 +433,18 @@ pub struct ImplicitPipelineContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImplicitPipelineIds<'a> {
|
pub struct ImplicitPipelineIds<'a> {
|
||||||
pub root_id: Option<PipelineLayoutId>,
|
pub root_id: PipelineLayoutId,
|
||||||
pub group_ids: &'a [Option<BindGroupLayoutId>],
|
pub group_ids: &'a [BindGroupLayoutId],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImplicitPipelineIds<'_> {
|
impl ImplicitPipelineIds<'_> {
|
||||||
fn prepare<A: HalApi>(self, hub: &Hub<A>) -> ImplicitPipelineContext {
|
fn prepare<A: HalApi>(self, hub: &Hub<A>) -> ImplicitPipelineContext {
|
||||||
ImplicitPipelineContext {
|
ImplicitPipelineContext {
|
||||||
root_id: hub.pipeline_layouts.prepare(self.root_id).into_id(),
|
root_id: hub.pipeline_layouts.prepare(Some(self.root_id)).into_id(),
|
||||||
group_ids: self
|
group_ids: self
|
||||||
.group_ids
|
.group_ids
|
||||||
.iter()
|
.iter()
|
||||||
.map(|id_in| hub.bind_group_layouts.prepare(*id_in).into_id())
|
.map(|id_in| hub.bind_group_layouts.prepare(Some(*id_in)).into_id())
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,18 +77,6 @@ impl RawId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Coerce a slice of identifiers into a slice of optional raw identifiers.
|
|
||||||
///
|
|
||||||
/// There's two reasons why we know this is correct:
|
|
||||||
/// * `Option<T>` is guaranteed to be niche-filled to 0's.
|
|
||||||
/// * The `T` in `Option<T>` can inhabit any representation except 0's, since
|
|
||||||
/// its underlying representation is `NonZero*`.
|
|
||||||
pub fn as_option_slice<T: Marker>(ids: &[Id<T>]) -> &[Option<Id<T>>] {
|
|
||||||
// SAFETY: Any Id<T> is repr(transparent) over `Option<RawId>`, since both
|
|
||||||
// are backed by non-zero types.
|
|
||||||
unsafe { std::slice::from_raw_parts(ids.as_ptr().cast(), ids.len()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An identifier for a wgpu object.
|
/// An identifier for a wgpu object.
|
||||||
///
|
///
|
||||||
/// An `Id<T>` value identifies a value stored in a [`Global`]'s [`Hub`].
|
/// An `Id<T>` value identifies a value stored in a [`Global`]'s [`Hub`].
|
||||||
|
@ -186,6 +186,8 @@ pub type ImplicitBindGroupCount = u8;
|
|||||||
#[derive(Clone, Debug, Error)]
|
#[derive(Clone, Debug, Error)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum ImplicitLayoutError {
|
pub enum ImplicitLayoutError {
|
||||||
|
#[error("The implicit_pipeline_ids arg is required")]
|
||||||
|
MissingImplicitPipelineIds,
|
||||||
#[error("Missing IDs for deriving {0} bind groups")]
|
#[error("Missing IDs for deriving {0} bind groups")]
|
||||||
MissingIds(ImplicitBindGroupCount),
|
MissingIds(ImplicitBindGroupCount),
|
||||||
#[error("Unable to reflect the shader {0:?} interface")]
|
#[error("Unable to reflect the shader {0:?} interface")]
|
||||||
|
@ -1162,13 +1162,6 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let implicit_pipeline_ids = match desc.layout {
|
|
||||||
Some(_) => None,
|
|
||||||
None => Some(wgc::device::ImplicitPipelineIds {
|
|
||||||
root_id: None,
|
|
||||||
group_ids: &[None; wgc::MAX_BIND_GROUPS],
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
let descriptor = pipe::RenderPipelineDescriptor {
|
let descriptor = pipe::RenderPipelineDescriptor {
|
||||||
label: desc.label.map(Borrowed),
|
label: desc.label.map(Borrowed),
|
||||||
layout: desc.layout.map(|l| l.id.into()),
|
layout: desc.layout.map(|l| l.id.into()),
|
||||||
@ -1211,7 +1204,7 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
*device,
|
*device,
|
||||||
&descriptor,
|
&descriptor,
|
||||||
None,
|
None,
|
||||||
implicit_pipeline_ids
|
None,
|
||||||
));
|
));
|
||||||
if let Some(cause) = error {
|
if let Some(cause) = error {
|
||||||
if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause {
|
if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause {
|
||||||
@ -1235,13 +1228,6 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
) -> (Self::ComputePipelineId, Self::ComputePipelineData) {
|
) -> (Self::ComputePipelineId, Self::ComputePipelineData) {
|
||||||
use wgc::pipeline as pipe;
|
use wgc::pipeline as pipe;
|
||||||
|
|
||||||
let implicit_pipeline_ids = match desc.layout {
|
|
||||||
Some(_) => None,
|
|
||||||
None => Some(wgc::device::ImplicitPipelineIds {
|
|
||||||
root_id: None,
|
|
||||||
group_ids: &[None; wgc::MAX_BIND_GROUPS],
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
let descriptor = pipe::ComputePipelineDescriptor {
|
let descriptor = pipe::ComputePipelineDescriptor {
|
||||||
label: desc.label.map(Borrowed),
|
label: desc.label.map(Borrowed),
|
||||||
layout: desc.layout.map(|l| l.id.into()),
|
layout: desc.layout.map(|l| l.id.into()),
|
||||||
@ -1261,7 +1247,7 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
*device,
|
*device,
|
||||||
&descriptor,
|
&descriptor,
|
||||||
None,
|
None,
|
||||||
implicit_pipeline_ids
|
None,
|
||||||
));
|
));
|
||||||
if let Some(cause) = error {
|
if let Some(cause) = error {
|
||||||
if let wgc::pipeline::CreateComputePipelineError::Internal(ref error) = cause {
|
if let wgc::pipeline::CreateComputePipelineError::Internal(ref error) = cause {
|
||||||
|
Loading…
Reference in New Issue
Block a user