mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-16 17:02:32 +00:00
Refactor implicit BGLs to support early tracing
This commit is contained in:
parent
f7e1304c38
commit
7c1db12cdc
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -956,7 +956,6 @@ dependencies = [
|
||||
"log",
|
||||
"num-traits",
|
||||
"petgraph",
|
||||
"serde",
|
||||
"spirv_headers",
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -254,10 +254,21 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
|
||||
A::DestroyShaderModule(id) => {
|
||||
self.shader_module_drop::<B>(id);
|
||||
}
|
||||
A::CreateComputePipeline(id, desc) => {
|
||||
A::CreateComputePipeline {
|
||||
id,
|
||||
desc,
|
||||
implicit_context,
|
||||
} => {
|
||||
self.device_maintain_ids::<B>(device).unwrap();
|
||||
let implicit_ids =
|
||||
implicit_context
|
||||
.as_ref()
|
||||
.map(|ic| wgc::device::ImplicitPipelineIds {
|
||||
root_id: ic.root_id,
|
||||
group_ids: &ic.group_ids,
|
||||
});
|
||||
let (_, _, error) =
|
||||
self.device_create_compute_pipeline::<B>(device, &desc, id, None);
|
||||
self.device_create_compute_pipeline::<B>(device, &desc, id, implicit_ids);
|
||||
if let Some(e) = error {
|
||||
panic!("{:?}", e);
|
||||
}
|
||||
@ -265,10 +276,21 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
|
||||
A::DestroyComputePipeline(id) => {
|
||||
self.compute_pipeline_drop::<B>(id);
|
||||
}
|
||||
A::CreateRenderPipeline(id, desc) => {
|
||||
A::CreateRenderPipeline {
|
||||
id,
|
||||
desc,
|
||||
implicit_context,
|
||||
} => {
|
||||
self.device_maintain_ids::<B>(device).unwrap();
|
||||
let implicit_ids =
|
||||
implicit_context
|
||||
.as_ref()
|
||||
.map(|ic| wgc::device::ImplicitPipelineIds {
|
||||
root_id: ic.root_id,
|
||||
group_ids: &ic.group_ids,
|
||||
});
|
||||
let (_, _, error) =
|
||||
self.device_create_render_pipeline::<B>(device, &desc, id, None);
|
||||
self.device_create_render_pipeline::<B>(device, &desc, id, implicit_ids);
|
||||
if let Some(e) = error {
|
||||
panic!("{:?}", e);
|
||||
}
|
||||
|
@ -15,14 +15,17 @@
|
||||
),
|
||||
data: "empty.wgsl",
|
||||
),
|
||||
CreateComputePipeline(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
layout: Some(Id(0, 1, Empty)),
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "main",
|
||||
CreateComputePipeline(
|
||||
id: Id(0, 1, Empty),
|
||||
desc: (
|
||||
label: None,
|
||||
layout: Some(Id(0, 1, Empty)),
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "main",
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
CreateBuffer(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
size: 16,
|
||||
|
@ -1,167 +1,170 @@
|
||||
(
|
||||
features: (bits: 0x0),
|
||||
expectations: [
|
||||
// Ensuring that mapping zero-inits buffers.
|
||||
(
|
||||
name: "mapped_at_creation: false, with MAP_WRITE",
|
||||
buffer: (index: 0, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00]),
|
||||
),
|
||||
(
|
||||
name: "mapped_at_creation: false, without MAP_WRITE",
|
||||
buffer: (index: 1, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00]),
|
||||
),
|
||||
(
|
||||
name: "partially written buffer",
|
||||
buffer: (index: 2, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xBF,
|
||||
0x00, 0x00, 0x80, 0xBF,
|
||||
0x00, 0x00, 0x80, 0x3F,
|
||||
0x00, 0x00, 0x80, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00]),
|
||||
),
|
||||
// Ensuring that binding zero-inits buffers
|
||||
// (by observing correct side effects of compute shader reading & writing values)
|
||||
(
|
||||
name: "buffer has correct values",
|
||||
buffer: (index: 3, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00]),
|
||||
)
|
||||
],
|
||||
actions: [
|
||||
CreateBuffer(
|
||||
Id(0, 1, Empty),
|
||||
(
|
||||
label: Some("mapped_at_creation: false, with MAP_WRITE"),
|
||||
size: 16,
|
||||
usage: (
|
||||
bits: 131, // STORAGE + MAP_READ + MAP_WRITE
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
),
|
||||
),
|
||||
CreateBuffer(
|
||||
Id(1, 1, Empty),
|
||||
(
|
||||
label: Some("mapped_at_creation: false, without MAP_WRITE"),
|
||||
size: 16,
|
||||
usage: (
|
||||
bits: 129, // STORAGE + MAP_READ
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
),
|
||||
),
|
||||
CreateBuffer(
|
||||
Id(2, 1, Empty),
|
||||
(
|
||||
label: Some("partially written"),
|
||||
size: 24,
|
||||
usage: (
|
||||
bits: 9, // MAP_READ + COPY_DST
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
),
|
||||
),
|
||||
WriteBuffer(
|
||||
id: Id(2, 1, Empty),
|
||||
data: "data1.bin",
|
||||
range: (
|
||||
start: 4,
|
||||
end: 20,
|
||||
),
|
||||
queued: true,
|
||||
),
|
||||
CreateShaderModule(
|
||||
id: Id(0, 1, Empty),
|
||||
desc: (
|
||||
label: None,
|
||||
flags: (bits: 3),
|
||||
),
|
||||
data: "buffer-zero-init-for-binding.wgsl",
|
||||
),
|
||||
CreateBuffer(Id(3, 1, Empty), (
|
||||
label: Some("used in binding"),
|
||||
size: 16,
|
||||
usage: (
|
||||
bits: 129, // STORAGE + MAP_READ
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
)),
|
||||
CreateBindGroupLayout(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
entries: [
|
||||
(
|
||||
binding: 0,
|
||||
visibility: (
|
||||
bits: 4,
|
||||
),
|
||||
ty: Buffer(
|
||||
ty: Storage(
|
||||
read_only: false,
|
||||
),
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: Some(16),
|
||||
),
|
||||
count: None,
|
||||
),
|
||||
],
|
||||
)),
|
||||
CreateBindGroup(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
layout: Id(0, 1, Empty),
|
||||
entries: [
|
||||
(
|
||||
binding: 0,
|
||||
resource: Buffer((
|
||||
buffer_id: Id(3, 1, Empty),
|
||||
offset: 0,
|
||||
size: Some(16),
|
||||
)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
CreatePipelineLayout(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
bind_group_layouts: [
|
||||
Id(0, 1, Empty),
|
||||
],
|
||||
push_constant_ranges: [],
|
||||
)),
|
||||
CreateComputePipeline(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
layout: Some(Id(0, 1, Empty)),
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "main",
|
||||
),
|
||||
)),
|
||||
Submit(1, [
|
||||
RunComputePass(
|
||||
base: (
|
||||
label: None,
|
||||
commands: [
|
||||
SetPipeline(Id(0, 1, Empty)),
|
||||
SetBindGroup(
|
||||
index: 0,
|
||||
num_dynamic_offsets: 0,
|
||||
bind_group_id: Id(0, 1, Empty),
|
||||
),
|
||||
Dispatch((4, 1, 1)),
|
||||
],
|
||||
dynamic_offsets: [],
|
||||
string_data: [],
|
||||
push_constant_data: [],
|
||||
),
|
||||
)
|
||||
]),
|
||||
]
|
||||
)
|
||||
(
|
||||
features: (bits: 0x0),
|
||||
expectations: [
|
||||
// Ensuring that mapping zero-inits buffers.
|
||||
(
|
||||
name: "mapped_at_creation: false, with MAP_WRITE",
|
||||
buffer: (index: 0, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00]),
|
||||
),
|
||||
(
|
||||
name: "mapped_at_creation: false, without MAP_WRITE",
|
||||
buffer: (index: 1, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00]),
|
||||
),
|
||||
(
|
||||
name: "partially written buffer",
|
||||
buffer: (index: 2, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xBF,
|
||||
0x00, 0x00, 0x80, 0xBF,
|
||||
0x00, 0x00, 0x80, 0x3F,
|
||||
0x00, 0x00, 0x80, 0x3F,
|
||||
0x00, 0x00, 0x00, 0x00]),
|
||||
),
|
||||
// Ensuring that binding zero-inits buffers
|
||||
// (by observing correct side effects of compute shader reading & writing values)
|
||||
(
|
||||
name: "buffer has correct values",
|
||||
buffer: (index: 3, epoch: 1),
|
||||
offset: 0,
|
||||
data: Raw([0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00]),
|
||||
)
|
||||
],
|
||||
actions: [
|
||||
CreateBuffer(
|
||||
Id(0, 1, Empty),
|
||||
(
|
||||
label: Some("mapped_at_creation: false, with MAP_WRITE"),
|
||||
size: 16,
|
||||
usage: (
|
||||
bits: 131, // STORAGE + MAP_READ + MAP_WRITE
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
),
|
||||
),
|
||||
CreateBuffer(
|
||||
Id(1, 1, Empty),
|
||||
(
|
||||
label: Some("mapped_at_creation: false, without MAP_WRITE"),
|
||||
size: 16,
|
||||
usage: (
|
||||
bits: 129, // STORAGE + MAP_READ
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
),
|
||||
),
|
||||
CreateBuffer(
|
||||
Id(2, 1, Empty),
|
||||
(
|
||||
label: Some("partially written"),
|
||||
size: 24,
|
||||
usage: (
|
||||
bits: 9, // MAP_READ + COPY_DST
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
),
|
||||
),
|
||||
WriteBuffer(
|
||||
id: Id(2, 1, Empty),
|
||||
data: "data1.bin",
|
||||
range: (
|
||||
start: 4,
|
||||
end: 20,
|
||||
),
|
||||
queued: true,
|
||||
),
|
||||
CreateShaderModule(
|
||||
id: Id(0, 1, Empty),
|
||||
desc: (
|
||||
label: None,
|
||||
flags: (bits: 3),
|
||||
),
|
||||
data: "buffer-zero-init-for-binding.wgsl",
|
||||
),
|
||||
CreateBuffer(Id(3, 1, Empty), (
|
||||
label: Some("used in binding"),
|
||||
size: 16,
|
||||
usage: (
|
||||
bits: 129, // STORAGE + MAP_READ
|
||||
),
|
||||
mapped_at_creation: false,
|
||||
)),
|
||||
CreateBindGroupLayout(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
entries: [
|
||||
(
|
||||
binding: 0,
|
||||
visibility: (
|
||||
bits: 4,
|
||||
),
|
||||
ty: Buffer(
|
||||
ty: Storage(
|
||||
read_only: false,
|
||||
),
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: Some(16),
|
||||
),
|
||||
count: None,
|
||||
),
|
||||
],
|
||||
)),
|
||||
CreateBindGroup(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
layout: Id(0, 1, Empty),
|
||||
entries: [
|
||||
(
|
||||
binding: 0,
|
||||
resource: Buffer((
|
||||
buffer_id: Id(3, 1, Empty),
|
||||
offset: 0,
|
||||
size: Some(16),
|
||||
)),
|
||||
),
|
||||
],
|
||||
)),
|
||||
CreatePipelineLayout(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
bind_group_layouts: [
|
||||
Id(0, 1, Empty),
|
||||
],
|
||||
push_constant_ranges: [],
|
||||
)),
|
||||
CreateComputePipeline(
|
||||
id: Id(0, 1, Empty),
|
||||
desc: (
|
||||
label: None,
|
||||
layout: Some(Id(0, 1, Empty)),
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "main",
|
||||
),
|
||||
),
|
||||
),
|
||||
Submit(1, [
|
||||
RunComputePass(
|
||||
base: (
|
||||
label: None,
|
||||
commands: [
|
||||
SetPipeline(Id(0, 1, Empty)),
|
||||
SetBindGroup(
|
||||
index: 0,
|
||||
num_dynamic_offsets: 0,
|
||||
bind_group_id: Id(0, 1, Empty),
|
||||
),
|
||||
Dispatch((4, 1, 1)),
|
||||
],
|
||||
dynamic_offsets: [],
|
||||
string_data: [],
|
||||
push_constant_data: [],
|
||||
),
|
||||
)
|
||||
]),
|
||||
]
|
||||
)
|
||||
|
@ -53,28 +53,31 @@
|
||||
bind_group_layouts: [],
|
||||
push_constant_ranges: [],
|
||||
)),
|
||||
CreateRenderPipeline(Id(0, 1, Empty), (
|
||||
label: None,
|
||||
layout: Some(Id(0, 1, Empty)),
|
||||
vertex: (
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "vs_main",
|
||||
),
|
||||
buffers: [],
|
||||
),
|
||||
fragment: Some((
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "fs_main",
|
||||
),
|
||||
targets: [
|
||||
(
|
||||
format: Rgba8Unorm,
|
||||
CreateRenderPipeline(
|
||||
id: Id(0, 1, Empty),
|
||||
desc: (
|
||||
label: None,
|
||||
layout: Some(Id(0, 1, Empty)),
|
||||
vertex: (
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "vs_main",
|
||||
),
|
||||
],
|
||||
)),
|
||||
)),
|
||||
buffers: [],
|
||||
),
|
||||
fragment: Some((
|
||||
stage: (
|
||||
module: Id(0, 1, Empty),
|
||||
entry_point: "fs_main",
|
||||
),
|
||||
targets: [
|
||||
(
|
||||
format: Rgba8Unorm,
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
Submit(1, [
|
||||
RunRenderPass(
|
||||
base: (
|
||||
|
@ -16,9 +16,9 @@ default = []
|
||||
# Enable SPIRV-Cross
|
||||
cross = ["gfx-backend-metal/cross", "gfx-backend-gl/cross"]
|
||||
# Enable API tracing
|
||||
trace = ["ron", "serde", "wgt/trace", "naga/serialize"]
|
||||
trace = ["ron", "serde", "wgt/trace", "arrayvec/serde"]
|
||||
# Enable API replaying
|
||||
replay = ["serde", "wgt/replay", "naga/deserialize"]
|
||||
replay = ["serde", "wgt/replay", "arrayvec/serde"]
|
||||
# Enable serializable compute/render passes, and bundle encoders.
|
||||
serial-pass = ["serde", "wgt/serde", "arrayvec/serde"]
|
||||
|
||||
|
@ -49,8 +49,6 @@ pub mod queue;
|
||||
pub mod trace;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
#[cfg(feature = "trace")]
|
||||
use trace::{Action, Trace};
|
||||
|
||||
pub const MAX_COLOR_TARGETS: usize = 4;
|
||||
pub const MAX_MIP_LEVELS: u32 = 16;
|
||||
@ -290,7 +288,7 @@ pub struct Device<B: hal::Backend> {
|
||||
// to borrow Device immutably, such as `write_buffer`, `write_texture`, and `buffer_unmap`.
|
||||
pending_writes: queue::PendingWrites<B>,
|
||||
#[cfg(feature = "trace")]
|
||||
pub(crate) trace: Option<Mutex<Trace>>,
|
||||
pub(crate) trace: Option<Mutex<trace::Trace>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
@ -359,9 +357,9 @@ impl<B: GfxBackend> Device<B> {
|
||||
life_tracker: Mutex::new(life::LifetimeTracker::new()),
|
||||
temp_suspected: life::SuspectedResources::default(),
|
||||
#[cfg(feature = "trace")]
|
||||
trace: trace_path.and_then(|path| match Trace::new(path) {
|
||||
trace: trace_path.and_then(|path| match trace::Trace::new(path) {
|
||||
Ok(mut trace) => {
|
||||
trace.add(Action::Init {
|
||||
trace.add(trace::Action::Init {
|
||||
desc: desc.clone(),
|
||||
backend: B::VARIANT,
|
||||
});
|
||||
@ -1787,14 +1785,13 @@ impl<B: GfxBackend> Device<B> {
|
||||
|
||||
//TODO: refactor this. It's the only method of `Device` that registers new objects
|
||||
// (the pipeline layout).
|
||||
fn derive_pipeline_layout<G: GlobalIdentityHandlerFactory>(
|
||||
fn derive_pipeline_layout(
|
||||
&self,
|
||||
self_id: id::DeviceId,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
implicit_context: Option<ImplicitPipelineContext>,
|
||||
mut derived_group_layouts: ArrayVec<[binding_model::BindEntryMap; MAX_BIND_GROUPS]>,
|
||||
bgl_guard: &mut Storage<binding_model::BindGroupLayout<B>, id::BindGroupLayoutId>,
|
||||
pipeline_layout_guard: &mut Storage<binding_model::PipelineLayout<B>, id::PipelineLayoutId>,
|
||||
hub: &Hub<B, G>,
|
||||
) -> Result<
|
||||
(id::PipelineLayoutId, pipeline::ImplicitBindGroupCount),
|
||||
pipeline::ImplicitLayoutError,
|
||||
@ -1808,10 +1805,9 @@ impl<B: GfxBackend> Device<B> {
|
||||
{
|
||||
derived_group_layouts.pop();
|
||||
}
|
||||
let ids = implicit_pipeline_ids
|
||||
.as_ref()
|
||||
.ok_or(pipeline::ImplicitLayoutError::MissingIds(0))?;
|
||||
if ids.group_ids.len() < derived_group_layouts.len() {
|
||||
let mut ids = implicit_context.ok_or(pipeline::ImplicitLayoutError::MissingIds(0))?;
|
||||
let group_count = derived_group_layouts.len();
|
||||
if ids.group_ids.len() < group_count {
|
||||
tracing::error!(
|
||||
"Not enough bind group IDs ({}) specified for the implicit layout ({})",
|
||||
ids.group_ids.len(),
|
||||
@ -1822,66 +1818,33 @@ impl<B: GfxBackend> Device<B> {
|
||||
));
|
||||
}
|
||||
|
||||
let mut derived_group_layout_ids =
|
||||
ArrayVec::<[id::BindGroupLayoutId; MAX_BIND_GROUPS]>::new();
|
||||
for (bgl_id, map) in ids.group_ids.iter().zip(derived_group_layouts) {
|
||||
let processed_id = match Device::deduplicate_bind_group_layout(self_id, &map, bgl_guard)
|
||||
{
|
||||
Some(dedup_id) => dedup_id,
|
||||
for (bgl_id, map) in ids.group_ids.iter_mut().zip(derived_group_layouts) {
|
||||
match Device::deduplicate_bind_group_layout(self_id, &map, bgl_guard) {
|
||||
Some(dedup_id) => {
|
||||
*bgl_id = dedup_id;
|
||||
}
|
||||
None => {
|
||||
#[cfg(feature = "trace")]
|
||||
let bgl_desc = binding_model::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: if self.trace.is_some() {
|
||||
Cow::Owned(map.values().cloned().collect())
|
||||
} else {
|
||||
Cow::Borrowed(&[])
|
||||
},
|
||||
};
|
||||
let bgl = self.create_bind_group_layout(self_id, None, map)?;
|
||||
let out_id = hub.bind_group_layouts.register_identity_locked(
|
||||
bgl_id.clone(),
|
||||
bgl,
|
||||
bgl_guard,
|
||||
);
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref trace) = self.trace {
|
||||
trace
|
||||
.lock()
|
||||
.add(trace::Action::CreateBindGroupLayout(out_id.0, bgl_desc));
|
||||
}
|
||||
out_id.0
|
||||
bgl_guard.insert(*bgl_id, bgl);
|
||||
}
|
||||
};
|
||||
derived_group_layout_ids.push(processed_id);
|
||||
}
|
||||
|
||||
let layout_desc = binding_model::PipelineLayoutDescriptor {
|
||||
label: None,
|
||||
bind_group_layouts: Cow::Borrowed(&derived_group_layout_ids),
|
||||
bind_group_layouts: Cow::Borrowed(&ids.group_ids[..group_count]),
|
||||
push_constant_ranges: Cow::Borrowed(&[]), //TODO?
|
||||
};
|
||||
let layout = self.create_pipeline_layout(self_id, &layout_desc, bgl_guard)?;
|
||||
let layout_id = hub.pipeline_layouts.register_identity_locked(
|
||||
ids.root_id.clone(),
|
||||
layout,
|
||||
pipeline_layout_guard,
|
||||
);
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref trace) = self.trace {
|
||||
trace.lock().add(trace::Action::CreatePipelineLayout(
|
||||
layout_id.0,
|
||||
layout_desc,
|
||||
));
|
||||
}
|
||||
Ok((layout_id.0, derived_bind_group_count))
|
||||
pipeline_layout_guard.insert(ids.root_id, layout);
|
||||
Ok((ids.root_id, derived_bind_group_count))
|
||||
}
|
||||
|
||||
fn create_compute_pipeline<G: GlobalIdentityHandlerFactory>(
|
||||
&self,
|
||||
self_id: id::DeviceId,
|
||||
desc: &pipeline::ComputePipelineDescriptor,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
implicit_context: Option<ImplicitPipelineContext>,
|
||||
hub: &Hub<B, G>,
|
||||
token: &mut Token<Self>,
|
||||
) -> Result<
|
||||
@ -1951,11 +1914,10 @@ impl<B: GfxBackend> Device<B> {
|
||||
Some(id) => (id, 0),
|
||||
None => self.derive_pipeline_layout(
|
||||
self_id,
|
||||
implicit_pipeline_ids,
|
||||
implicit_context,
|
||||
derived_group_layouts,
|
||||
&mut *bgl_guard,
|
||||
&mut *pipeline_layout_guard,
|
||||
&hub,
|
||||
)?,
|
||||
};
|
||||
let layout = pipeline_layout_guard
|
||||
@ -1999,7 +1961,7 @@ impl<B: GfxBackend> Device<B> {
|
||||
&self,
|
||||
self_id: id::DeviceId,
|
||||
desc: &pipeline::RenderPipelineDescriptor,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
implicit_context: Option<ImplicitPipelineContext>,
|
||||
hub: &Hub<B, G>,
|
||||
token: &mut Token<Self>,
|
||||
) -> Result<
|
||||
@ -2367,11 +2329,10 @@ impl<B: GfxBackend> Device<B> {
|
||||
Some(id) => (id, 0),
|
||||
None => self.derive_pipeline_layout(
|
||||
self_id,
|
||||
implicit_pipeline_ids,
|
||||
implicit_context,
|
||||
derived_group_layouts,
|
||||
&mut *bgl_guard,
|
||||
&mut *pipeline_layout_guard,
|
||||
&hub,
|
||||
)?,
|
||||
};
|
||||
let layout = pipeline_layout_guard
|
||||
@ -2582,11 +2543,32 @@ impl DeviceError {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||
pub struct ImplicitPipelineContext {
|
||||
pub root_id: id::PipelineLayoutId,
|
||||
pub group_ids: ArrayVec<[id::BindGroupLayoutId; MAX_BIND_GROUPS]>,
|
||||
}
|
||||
|
||||
pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
|
||||
pub root_id: Input<G, id::PipelineLayoutId>,
|
||||
pub group_ids: &'a [Input<G, id::BindGroupLayoutId>],
|
||||
}
|
||||
|
||||
impl<G: GlobalIdentityHandlerFactory> ImplicitPipelineIds<'_, G> {
|
||||
fn prepare<B: hal::Backend>(self, hub: &Hub<B, G>) -> ImplicitPipelineContext {
|
||||
ImplicitPipelineContext {
|
||||
root_id: hub.pipeline_layouts.prepare(self.root_id).into_id(),
|
||||
group_ids: self
|
||||
.group_ids
|
||||
.iter()
|
||||
.map(|id_in| hub.bind_group_layouts.prepare(id_in.clone()).into_id())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn adapter_get_swap_chain_preferred_format<B: GfxBackend>(
|
||||
&self,
|
||||
@ -3621,11 +3603,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pipeline::ShaderModuleSource::Wgsl(ref code) => {
|
||||
trace.make_binary("wgsl", code.as_bytes())
|
||||
}
|
||||
pipeline::ShaderModuleSource::Naga(ref module) => {
|
||||
let config = ron::ser::PrettyConfig::new();
|
||||
let mut ron = Vec::new();
|
||||
ron::ser::to_writer_pretty(&mut ron, &module, config).unwrap();
|
||||
trace.make_binary("ron", &ron)
|
||||
pipeline::ShaderModuleSource::Naga(_) => {
|
||||
// we don't want to enable Naga serialization just for this alone
|
||||
trace.make_binary("ron", &[])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4019,6 +3999,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut token = Token::root();
|
||||
|
||||
let fid = hub.render_pipelines.prepare(id_in);
|
||||
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(&hub));
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let error = loop {
|
||||
let device = match device_guard.get(device_id) {
|
||||
@ -4027,13 +4009,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref trace) = device.trace {
|
||||
trace
|
||||
.lock()
|
||||
.add(trace::Action::CreateRenderPipeline(fid.id(), desc.clone()));
|
||||
trace.lock().add(trace::Action::CreateRenderPipeline {
|
||||
id: fid.id(),
|
||||
desc: desc.clone(),
|
||||
implicit_context: implicit_context.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let (pipeline, derived_bind_group_count, _layout_id) = match device
|
||||
.create_render_pipeline(device_id, desc, implicit_pipeline_ids, &hub, &mut token)
|
||||
.create_render_pipeline(device_id, desc, implicit_context, &hub, &mut token)
|
||||
{
|
||||
Ok(pair) => pair,
|
||||
Err(e) => break e,
|
||||
@ -4142,6 +4126,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut token = Token::root();
|
||||
|
||||
let fid = hub.compute_pipelines.prepare(id_in);
|
||||
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(&hub));
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
let error = loop {
|
||||
let device = match device_guard.get(device_id) {
|
||||
@ -4150,13 +4136,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref trace) = device.trace {
|
||||
trace
|
||||
.lock()
|
||||
.add(trace::Action::CreateComputePipeline(fid.id(), desc.clone()));
|
||||
trace.lock().add(trace::Action::CreateComputePipeline {
|
||||
id: fid.id(),
|
||||
desc: desc.clone(),
|
||||
implicit_context: implicit_context.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let (pipeline, derived_bind_group_count, _layout_id) = match device
|
||||
.create_compute_pipeline(device_id, desc, implicit_pipeline_ids, &hub, &mut token)
|
||||
.create_compute_pipeline(device_id, desc, implicit_context, &hub, &mut token)
|
||||
{
|
||||
Ok(pair) => pair,
|
||||
Err(e) => break e,
|
||||
@ -4353,7 +4341,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
if let Some(ref trace) = device.trace {
|
||||
trace
|
||||
.lock()
|
||||
.add(Action::CreateSwapChain(sc_id, desc.clone()));
|
||||
.add(trace::Action::CreateSwapChain(sc_id, desc.clone()));
|
||||
}
|
||||
|
||||
let swap_chain = swap_chain::SwapChain {
|
||||
|
@ -75,15 +75,19 @@ pub enum Action<'a> {
|
||||
data: FileName,
|
||||
},
|
||||
DestroyShaderModule(id::ShaderModuleId),
|
||||
CreateComputePipeline(
|
||||
id::ComputePipelineId,
|
||||
crate::pipeline::ComputePipelineDescriptor<'a>,
|
||||
),
|
||||
CreateComputePipeline {
|
||||
id: id::ComputePipelineId,
|
||||
desc: crate::pipeline::ComputePipelineDescriptor<'a>,
|
||||
#[cfg_attr(feature = "replay", serde(default))]
|
||||
implicit_context: Option<super::ImplicitPipelineContext>,
|
||||
},
|
||||
DestroyComputePipeline(id::ComputePipelineId),
|
||||
CreateRenderPipeline(
|
||||
id::RenderPipelineId,
|
||||
crate::pipeline::RenderPipelineDescriptor<'a>,
|
||||
),
|
||||
CreateRenderPipeline {
|
||||
id: id::RenderPipelineId,
|
||||
desc: crate::pipeline::RenderPipelineDescriptor<'a>,
|
||||
#[cfg_attr(feature = "replay", serde(default))]
|
||||
implicit_context: Option<super::ImplicitPipelineContext>,
|
||||
},
|
||||
DestroyRenderPipeline(id::RenderPipelineId),
|
||||
CreateRenderBundle {
|
||||
id: id::RenderBundleId,
|
||||
|
@ -451,6 +451,10 @@ impl<I: TypedId + Copy, T> FutureId<'_, I, T> {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn into_id(self) -> I {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn assign<'a, A: Access<T>>(self, value: T, _: &'a mut Token<A>) -> Valid<I> {
|
||||
self.data.write().insert(self.id, value);
|
||||
Valid(self.id)
|
||||
@ -497,17 +501,6 @@ impl<T: Resource, I: TypedId + Copy, F: IdentityHandlerFactory<I>> Registry<T, I
|
||||
self.prepare(id_in).assign(value, token)
|
||||
}
|
||||
|
||||
pub(crate) fn register_identity_locked(
|
||||
&self,
|
||||
id_in: <F::Filter as IdentityHandler<I>>::Input,
|
||||
value: T,
|
||||
guard: &mut Storage<T, I>,
|
||||
) -> Valid<I> {
|
||||
let id = self.identity.process(id_in, self.backend);
|
||||
guard.insert(id, value);
|
||||
Valid(id)
|
||||
}
|
||||
|
||||
//TODO: consider remove this once everything uses `prepare`
|
||||
pub(crate) fn register_error<A: Access<T>>(
|
||||
&self,
|
||||
|
Loading…
Reference in New Issue
Block a user