mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Improve the consistency of identifiers (#5108)
This commit is contained in:
parent
4face1c2ba
commit
dec6ea5ea4
@ -32,7 +32,7 @@ pub fn op_webgpu_queue_submit(
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, AnyError>>()?;
|
.collect::<Result<Vec<_>, AnyError>>()?;
|
||||||
|
|
||||||
let maybe_err = gfx_select!(queue => instance.queue_submit(queue, &ids)).err();
|
let maybe_err = gfx_select!(queue => instance.queue_submit(queue.transmute(), &ids)).err();
|
||||||
|
|
||||||
for rid in command_buffers {
|
for rid in command_buffers {
|
||||||
let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?;
|
let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?;
|
||||||
@ -84,7 +84,7 @@ pub fn op_webgpu_write_buffer(
|
|||||||
None => &buf[data_offset..],
|
None => &buf[data_offset..],
|
||||||
};
|
};
|
||||||
let maybe_err = gfx_select!(queue => instance.queue_write_buffer(
|
let maybe_err = gfx_select!(queue => instance.queue_write_buffer(
|
||||||
queue,
|
queue.transmute(),
|
||||||
buffer,
|
buffer,
|
||||||
buffer_offset,
|
buffer_offset,
|
||||||
data
|
data
|
||||||
@ -120,7 +120,7 @@ pub fn op_webgpu_write_texture(
|
|||||||
let data_layout = data_layout.into();
|
let data_layout = data_layout.into();
|
||||||
|
|
||||||
gfx_ok!(queue => instance.queue_write_texture(
|
gfx_ok!(queue => instance.queue_write_texture(
|
||||||
queue,
|
queue.transmute(),
|
||||||
&destination,
|
&destination,
|
||||||
buf,
|
buf,
|
||||||
&data_layout,
|
&data_layout,
|
||||||
|
@ -61,7 +61,7 @@ fn main() {
|
|||||||
global.instance_create_surface(
|
global.instance_create_surface(
|
||||||
window.display_handle().unwrap().into(),
|
window.display_handle().unwrap().into(),
|
||||||
window.window_handle().unwrap().into(),
|
window.window_handle().unwrap().into(),
|
||||||
wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty),
|
wgc::id::Id::zip(0, 1, wgt::Backend::Empty),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -79,22 +79,21 @@ fn main() {
|
|||||||
#[cfg(not(feature = "winit"))]
|
#[cfg(not(feature = "winit"))]
|
||||||
compatible_surface: None,
|
compatible_surface: None,
|
||||||
},
|
},
|
||||||
wgc::instance::AdapterInputs::IdSet(
|
wgc::instance::AdapterInputs::IdSet(&[wgc::id::Id::zip(0, 0, backend)], |id| {
|
||||||
&[wgc::id::TypedId::zip(0, 0, backend)],
|
id.backend()
|
||||||
|id| id.backend(),
|
}),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.expect("Unable to find an adapter for selected backend");
|
.expect("Unable to find an adapter for selected backend");
|
||||||
|
|
||||||
let info = gfx_select!(adapter => global.adapter_get_info(adapter)).unwrap();
|
let info = gfx_select!(adapter => global.adapter_get_info(adapter)).unwrap();
|
||||||
log::info!("Picked '{}'", info.name);
|
log::info!("Picked '{}'", info.name);
|
||||||
let id = wgc::id::TypedId::zip(1, 0, backend);
|
let id = wgc::id::Id::zip(1, 0, backend);
|
||||||
let (_, _, error) = gfx_select!(adapter => global.adapter_request_device(
|
let (_, _, error) = gfx_select!(adapter => global.adapter_request_device(
|
||||||
adapter,
|
adapter,
|
||||||
&desc,
|
&desc,
|
||||||
None,
|
None,
|
||||||
id,
|
id,
|
||||||
id
|
id.transmute()
|
||||||
));
|
));
|
||||||
if let Some(e) = error {
|
if let Some(e) = error {
|
||||||
panic!("{:?}", e);
|
panic!("{:?}", e);
|
||||||
|
@ -14,10 +14,10 @@ use std::{borrow::Cow, fs, path::Path};
|
|||||||
|
|
||||||
pub struct IdentityPassThroughFactory;
|
pub struct IdentityPassThroughFactory;
|
||||||
|
|
||||||
impl<I: wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I> for IdentityPassThroughFactory {
|
impl<T: wgc::id::Marker> wgc::identity::IdentityHandlerFactory<T> for IdentityPassThroughFactory {
|
||||||
type Input = I;
|
type Input = wgc::id::Id<T>;
|
||||||
|
|
||||||
fn input_to_id(id_in: Self::Input) -> I {
|
fn input_to_id(id_in: Self::Input) -> wgc::id::Id<T> {
|
||||||
id_in
|
id_in
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ pub trait GlobalPlay {
|
|||||||
device: wgc::id::DeviceId,
|
device: wgc::id::DeviceId,
|
||||||
action: trace::Action,
|
action: trace::Action,
|
||||||
dir: &Path,
|
dir: &Path,
|
||||||
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::CommandBufferId>,
|
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::markers::CommandBuffer>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
|
|||||||
device: wgc::id::DeviceId,
|
device: wgc::id::DeviceId,
|
||||||
action: trace::Action,
|
action: trace::Action,
|
||||||
dir: &Path,
|
dir: &Path,
|
||||||
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::CommandBufferId>,
|
comb_manager: &mut wgc::identity::IdentityManager<wgc::id::markers::CommandBuffer>,
|
||||||
) {
|
) {
|
||||||
use wgc::device::trace::Action;
|
use wgc::device::trace::Action;
|
||||||
log::debug!("action {:?}", action);
|
log::debug!("action {:?}", action);
|
||||||
@ -350,7 +350,7 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
|
|||||||
let bin = std::fs::read(dir.join(data)).unwrap();
|
let bin = std::fs::read(dir.join(data)).unwrap();
|
||||||
let size = (range.end - range.start) as usize;
|
let size = (range.end - range.start) as usize;
|
||||||
if queued {
|
if queued {
|
||||||
self.queue_write_buffer::<A>(device, id, range.start, &bin)
|
self.queue_write_buffer::<A>(device.transmute(), id, range.start, &bin)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
} else {
|
} else {
|
||||||
self.device_wait_for_buffer::<A>(device, id).unwrap();
|
self.device_wait_for_buffer::<A>(device, id).unwrap();
|
||||||
@ -365,23 +365,24 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
|
|||||||
size,
|
size,
|
||||||
} => {
|
} => {
|
||||||
let bin = std::fs::read(dir.join(data)).unwrap();
|
let bin = std::fs::read(dir.join(data)).unwrap();
|
||||||
self.queue_write_texture::<A>(device, &to, &bin, &layout, &size)
|
self.queue_write_texture::<A>(device.transmute(), &to, &bin, &layout, &size)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
Action::Submit(_index, ref commands) if commands.is_empty() => {
|
Action::Submit(_index, ref commands) if commands.is_empty() => {
|
||||||
self.queue_submit::<A>(device, &[]).unwrap();
|
self.queue_submit::<A>(device.transmute(), &[]).unwrap();
|
||||||
}
|
}
|
||||||
Action::Submit(_index, commands) => {
|
Action::Submit(_index, commands) => {
|
||||||
let (encoder, error) = self.device_create_command_encoder::<A>(
|
let (encoder, error) = self.device_create_command_encoder::<A>(
|
||||||
device,
|
device,
|
||||||
&wgt::CommandEncoderDescriptor { label: None },
|
&wgt::CommandEncoderDescriptor { label: None },
|
||||||
comb_manager.process(device.backend()),
|
comb_manager.process(device.backend()).transmute(),
|
||||||
);
|
);
|
||||||
if let Some(e) = error {
|
if let Some(e) = error {
|
||||||
panic!("{e}");
|
panic!("{e}");
|
||||||
}
|
}
|
||||||
let cmdbuf = self.encode_commands::<A>(encoder, commands);
|
let cmdbuf = self.encode_commands::<A>(encoder, commands);
|
||||||
self.queue_submit::<A>(device, &[cmdbuf]).unwrap();
|
self.queue_submit::<A>(device.transmute(), &[cmdbuf])
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ impl Test<'_> {
|
|||||||
test_num: u32,
|
test_num: u32,
|
||||||
) {
|
) {
|
||||||
let backend = adapter.backend();
|
let backend = adapter.backend();
|
||||||
let device_id = wgc::id::TypedId::zip(test_num, 0, backend);
|
let device_id = wgc::id::Id::zip(test_num, 0, backend);
|
||||||
let (_, _, error) = wgc::gfx_select!(adapter => global.adapter_request_device(
|
let (_, _, error) = wgc::gfx_select!(adapter => global.adapter_request_device(
|
||||||
adapter,
|
adapter,
|
||||||
&wgt::DeviceDescriptor {
|
&wgt::DeviceDescriptor {
|
||||||
@ -115,7 +115,7 @@ impl Test<'_> {
|
|||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
device_id,
|
device_id,
|
||||||
device_id
|
device_id.transmute()
|
||||||
));
|
));
|
||||||
if let Some(e) = error {
|
if let Some(e) = error {
|
||||||
panic!("{:?}", e);
|
panic!("{:?}", e);
|
||||||
@ -128,7 +128,7 @@ impl Test<'_> {
|
|||||||
}
|
}
|
||||||
println!("\t\t\tMapping...");
|
println!("\t\t\tMapping...");
|
||||||
for expect in &self.expectations {
|
for expect in &self.expectations {
|
||||||
let buffer = wgc::id::TypedId::zip(expect.buffer.index, expect.buffer.epoch, backend);
|
let buffer = wgc::id::Id::zip(expect.buffer.index, expect.buffer.epoch, backend);
|
||||||
wgc::gfx_select!(device_id => global.buffer_map_async(
|
wgc::gfx_select!(device_id => global.buffer_map_async(
|
||||||
buffer,
|
buffer,
|
||||||
expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress,
|
expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress,
|
||||||
@ -148,7 +148,7 @@ impl Test<'_> {
|
|||||||
|
|
||||||
for expect in self.expectations {
|
for expect in self.expectations {
|
||||||
println!("\t\t\tChecking {}", expect.name);
|
println!("\t\t\tChecking {}", expect.name);
|
||||||
let buffer = wgc::id::TypedId::zip(expect.buffer.index, expect.buffer.epoch, backend);
|
let buffer = wgc::id::Id::zip(expect.buffer.index, expect.buffer.epoch, backend);
|
||||||
let (ptr, size) =
|
let (ptr, size) =
|
||||||
wgc::gfx_select!(device_id => global.buffer_get_mapped_range(buffer, expect.offset, Some(expect.data.len() as wgt::BufferAddress)))
|
wgc::gfx_select!(device_id => global.buffer_get_mapped_range(buffer, expect.offset, Some(expect.data.len() as wgt::BufferAddress)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -221,10 +221,9 @@ impl Corpus {
|
|||||||
force_fallback_adapter: false,
|
force_fallback_adapter: false,
|
||||||
compatible_surface: None,
|
compatible_surface: None,
|
||||||
},
|
},
|
||||||
wgc::instance::AdapterInputs::IdSet(
|
wgc::instance::AdapterInputs::IdSet(&[wgc::id::Id::zip(0, 0, backend)], |id| {
|
||||||
&[wgc::id::TypedId::zip(0, 0, backend)],
|
id.backend()
|
||||||
|id| id.backend(),
|
}),
|
||||||
),
|
|
||||||
) {
|
) {
|
||||||
Ok(adapter) => adapter,
|
Ok(adapter) => adapter,
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
|
@ -6,10 +6,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
error::{ErrorFormatter, PrettyError},
|
error::{ErrorFormatter, PrettyError},
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{
|
id::{BindGroupLayoutId, BufferId, SamplerId, TextureId, TextureViewId},
|
||||||
BindGroupId, BindGroupLayoutId, BufferId, PipelineLayoutId, SamplerId, TextureId,
|
|
||||||
TextureViewId,
|
|
||||||
},
|
|
||||||
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
||||||
resource::{Resource, ResourceInfo, ResourceType},
|
resource::{Resource, ResourceInfo, ResourceType},
|
||||||
resource_log,
|
resource_log,
|
||||||
@ -441,7 +438,7 @@ pub struct BindGroupLayoutDescriptor<'a> {
|
|||||||
pub entries: Cow<'a, [wgt::BindGroupLayoutEntry]>,
|
pub entries: Cow<'a, [wgt::BindGroupLayoutEntry]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BindGroupLayouts<A> = crate::storage::Storage<BindGroupLayout<A>, BindGroupLayoutId>;
|
pub type BindGroupLayouts<A> = crate::storage::Storage<BindGroupLayout<A>>;
|
||||||
|
|
||||||
/// Bind group layout.
|
/// Bind group layout.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -458,7 +455,7 @@ pub struct BindGroupLayout<A: HalApi> {
|
|||||||
pub(crate) origin: bgl::Origin,
|
pub(crate) origin: bgl::Origin,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) binding_count_validator: BindingTypeMaxCountValidator,
|
pub(crate) binding_count_validator: BindingTypeMaxCountValidator,
|
||||||
pub(crate) info: ResourceInfo<BindGroupLayoutId>,
|
pub(crate) info: ResourceInfo<BindGroupLayout<A>>,
|
||||||
pub(crate) label: String,
|
pub(crate) label: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,14 +479,16 @@ impl<A: HalApi> Drop for BindGroupLayout<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<BindGroupLayoutId> for BindGroupLayout<A> {
|
impl<A: HalApi> Resource for BindGroupLayout<A> {
|
||||||
const TYPE: ResourceType = "BindGroupLayout";
|
const TYPE: ResourceType = "BindGroupLayout";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<BindGroupLayoutId> {
|
type Marker = crate::id::markers::BindGroupLayout;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BindGroupLayoutId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +601,7 @@ pub struct PipelineLayoutDescriptor<'a> {
|
|||||||
pub struct PipelineLayout<A: HalApi> {
|
pub struct PipelineLayout<A: HalApi> {
|
||||||
pub(crate) raw: Option<A::PipelineLayout>,
|
pub(crate) raw: Option<A::PipelineLayout>,
|
||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) info: ResourceInfo<PipelineLayoutId>,
|
pub(crate) info: ResourceInfo<PipelineLayout<A>>,
|
||||||
pub(crate) bind_group_layouts: ArrayVec<Arc<BindGroupLayout<A>>, { hal::MAX_BIND_GROUPS }>,
|
pub(crate) bind_group_layouts: ArrayVec<Arc<BindGroupLayout<A>>, { hal::MAX_BIND_GROUPS }>,
|
||||||
pub(crate) push_constant_ranges: ArrayVec<wgt::PushConstantRange, { SHADER_STAGE_COUNT }>,
|
pub(crate) push_constant_ranges: ArrayVec<wgt::PushConstantRange, { SHADER_STAGE_COUNT }>,
|
||||||
}
|
}
|
||||||
@ -716,14 +715,16 @@ impl<A: HalApi> PipelineLayout<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<PipelineLayoutId> for PipelineLayout<A> {
|
impl<A: HalApi> Resource for PipelineLayout<A> {
|
||||||
const TYPE: ResourceType = "PipelineLayout";
|
const TYPE: ResourceType = "PipelineLayout";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<PipelineLayoutId> {
|
type Marker = crate::id::markers::PipelineLayout;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<PipelineLayoutId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -830,7 +831,7 @@ pub struct BindGroup<A: HalApi> {
|
|||||||
pub(crate) raw: Snatchable<A::BindGroup>,
|
pub(crate) raw: Snatchable<A::BindGroup>,
|
||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) layout: Arc<BindGroupLayout<A>>,
|
pub(crate) layout: Arc<BindGroupLayout<A>>,
|
||||||
pub(crate) info: ResourceInfo<BindGroupId>,
|
pub(crate) info: ResourceInfo<BindGroup<A>>,
|
||||||
pub(crate) used: BindGroupStates<A>,
|
pub(crate) used: BindGroupStates<A>,
|
||||||
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction<A>>,
|
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction<A>>,
|
||||||
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction<A>>,
|
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction<A>>,
|
||||||
@ -919,14 +920,16 @@ impl<A: HalApi> BindGroup<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<BindGroupId> for BindGroup<A> {
|
impl<A: HalApi> Resource for BindGroup<A> {
|
||||||
const TYPE: ResourceType = "BindGroup";
|
const TYPE: ResourceType = "BindGroup";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<BindGroupId> {
|
type Marker = crate::id::markers::BindGroup;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BindGroupId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ use crate::{
|
|||||||
error::{ErrorFormatter, PrettyError},
|
error::{ErrorFormatter, PrettyError},
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hub::Hub,
|
hub::Hub,
|
||||||
id::{self, RenderBundleId},
|
id,
|
||||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
||||||
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
||||||
resource::{Resource, ResourceInfo, ResourceType},
|
resource::{Resource, ResourceInfo, ResourceType},
|
||||||
@ -832,7 +832,7 @@ pub struct RenderBundle<A: HalApi> {
|
|||||||
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
|
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
|
||||||
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction<A>>,
|
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction<A>>,
|
||||||
pub(super) context: RenderPassContext,
|
pub(super) context: RenderPassContext,
|
||||||
pub(crate) info: ResourceInfo<RenderBundleId>,
|
pub(crate) info: ResourceInfo<RenderBundle<A>>,
|
||||||
discard_hal_labels: bool,
|
discard_hal_labels: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1067,14 +1067,16 @@ impl<A: HalApi> RenderBundle<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<RenderBundleId> for RenderBundle<A> {
|
impl<A: HalApi> Resource for RenderBundle<A> {
|
||||||
const TYPE: ResourceType = "RenderBundle";
|
const TYPE: ResourceType = "RenderBundle";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<RenderBundleId> {
|
type Marker = crate::id::markers::RenderBundle;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<RenderBundleId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ impl<A: HalApi> State<A> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
raw_encoder: &mut A::CommandEncoder,
|
raw_encoder: &mut A::CommandEncoder,
|
||||||
base_trackers: &mut Tracker<A>,
|
base_trackers: &mut Tracker<A>,
|
||||||
bind_group_guard: &Storage<BindGroup<A>, id::BindGroupId>,
|
bind_group_guard: &Storage<BindGroup<A>>,
|
||||||
indirect_buffer: Option<id::BufferId>,
|
indirect_buffer: Option<id::BufferId>,
|
||||||
snatch_guard: &SnatchGuard,
|
snatch_guard: &SnatchGuard,
|
||||||
) -> Result<(), UsageConflict> {
|
) -> Result<(), UsageConflict> {
|
||||||
|
@ -140,7 +140,7 @@ pub struct CommandBuffer<A: HalApi> {
|
|||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
limits: wgt::Limits,
|
limits: wgt::Limits,
|
||||||
support_clear_texture: bool,
|
support_clear_texture: bool,
|
||||||
pub(crate) info: ResourceInfo<CommandBufferId>,
|
pub(crate) info: ResourceInfo<CommandBuffer<A>>,
|
||||||
pub(crate) data: Mutex<Option<CommandBufferMutable<A>>>,
|
pub(crate) data: Mutex<Option<CommandBufferMutable<A>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ impl<A: HalApi> CommandBuffer<A> {
|
|||||||
id: id::CommandEncoderId,
|
id: id::CommandEncoderId,
|
||||||
) -> Result<Arc<Self>, CommandEncoderError> {
|
) -> Result<Arc<Self>, CommandEncoderError> {
|
||||||
let storage = hub.command_buffers.read();
|
let storage = hub.command_buffers.read();
|
||||||
match storage.get(id) {
|
match storage.get(id.transmute()) {
|
||||||
Ok(cmd_buf) => match cmd_buf.data.lock().as_ref().unwrap().status {
|
Ok(cmd_buf) => match cmd_buf.data.lock().as_ref().unwrap().status {
|
||||||
CommandEncoderStatus::Recording => Ok(cmd_buf.clone()),
|
CommandEncoderStatus::Recording => Ok(cmd_buf.clone()),
|
||||||
CommandEncoderStatus::Finished => Err(CommandEncoderError::NotRecording),
|
CommandEncoderStatus::Finished => Err(CommandEncoderError::NotRecording),
|
||||||
@ -296,14 +296,16 @@ impl<A: HalApi> CommandBuffer<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<CommandBufferId> for CommandBuffer<A> {
|
impl<A: HalApi> Resource for CommandBuffer<A> {
|
||||||
const TYPE: ResourceType = "CommandBuffer";
|
const TYPE: ResourceType = "CommandBuffer";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<CommandBufferId> {
|
type Marker = crate::id::markers::CommandBuffer;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<CommandBufferId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +420,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let error = match hub.command_buffers.get(encoder_id) {
|
let error = match hub.command_buffers.get(encoder_id.transmute()) {
|
||||||
Ok(cmd_buf) => {
|
Ok(cmd_buf) => {
|
||||||
let mut cmd_buf_data = cmd_buf.data.lock();
|
let mut cmd_buf_data = cmd_buf.data.lock();
|
||||||
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
||||||
@ -444,7 +446,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
Err(_) => Some(CommandEncoderError::Invalid),
|
Err(_) => Some(CommandEncoderError::Invalid),
|
||||||
};
|
};
|
||||||
|
|
||||||
(encoder_id, error)
|
(encoder_id.transmute(), error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command_encoder_push_debug_group<A: HalApi>(
|
pub fn command_encoder_push_debug_group<A: HalApi>(
|
||||||
@ -700,7 +702,7 @@ impl PrettyError for PassErrorScope {
|
|||||||
// This error is not in the error chain, only notes are needed
|
// This error is not in the error chain, only notes are needed
|
||||||
match *self {
|
match *self {
|
||||||
Self::Pass(id) => {
|
Self::Pass(id) => {
|
||||||
fmt.command_buffer_label(&id);
|
fmt.command_buffer_label(&id.transmute());
|
||||||
}
|
}
|
||||||
Self::SetBindGroup(id) => {
|
Self::SetBindGroup(id) => {
|
||||||
fmt.bind_group_label(&id);
|
fmt.bind_group_label(&id);
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
device::DeviceError,
|
device::DeviceError,
|
||||||
global::Global,
|
global::Global,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{self, Id, TypedId},
|
id::{self, Id},
|
||||||
identity::GlobalIdentityHandlerFactory,
|
identity::GlobalIdentityHandlerFactory,
|
||||||
init_tracker::MemoryInitKind,
|
init_tracker::MemoryInitKind,
|
||||||
resource::QuerySet,
|
resource::QuerySet,
|
||||||
@ -49,7 +49,7 @@ impl<A: HalApi> QueryResetMap<A> {
|
|||||||
pub fn reset_queries(
|
pub fn reset_queries(
|
||||||
&mut self,
|
&mut self,
|
||||||
raw_encoder: &mut A::CommandEncoder,
|
raw_encoder: &mut A::CommandEncoder,
|
||||||
query_set_storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
query_set_storage: &Storage<QuerySet<A>>,
|
||||||
backend: wgt::Backend,
|
backend: wgt::Backend,
|
||||||
) -> Result<(), id::QuerySetId> {
|
) -> Result<(), id::QuerySetId> {
|
||||||
for (query_set_id, (state, epoch)) in self.map.drain() {
|
for (query_set_id, (state, epoch)) in self.map.drain() {
|
||||||
@ -314,7 +314,7 @@ impl<A: HalApi> QuerySet<A> {
|
|||||||
|
|
||||||
pub(super) fn end_occlusion_query<A: HalApi>(
|
pub(super) fn end_occlusion_query<A: HalApi>(
|
||||||
raw_encoder: &mut A::CommandEncoder,
|
raw_encoder: &mut A::CommandEncoder,
|
||||||
storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
storage: &Storage<QuerySet<A>>,
|
||||||
active_query: &mut Option<(id::QuerySetId, u32)>,
|
active_query: &mut Option<(id::QuerySetId, u32)>,
|
||||||
) -> Result<(), QueryUseError> {
|
) -> Result<(), QueryUseError> {
|
||||||
if let Some((query_set_id, query_index)) = active_query.take() {
|
if let Some((query_set_id, query_index)) = active_query.take() {
|
||||||
@ -331,7 +331,7 @@ pub(super) fn end_occlusion_query<A: HalApi>(
|
|||||||
|
|
||||||
pub(super) fn end_pipeline_statistics_query<A: HalApi>(
|
pub(super) fn end_pipeline_statistics_query<A: HalApi>(
|
||||||
raw_encoder: &mut A::CommandEncoder,
|
raw_encoder: &mut A::CommandEncoder,
|
||||||
storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
storage: &Storage<QuerySet<A>>,
|
||||||
active_query: &mut Option<(id::QuerySetId, u32)>,
|
active_query: &mut Option<(id::QuerySetId, u32)>,
|
||||||
) -> Result<(), QueryUseError> {
|
) -> Result<(), QueryUseError> {
|
||||||
if let Some((query_set_id, query_index)) = active_query.take() {
|
if let Some((query_set_id, query_index)) = active_query.take() {
|
||||||
|
@ -784,10 +784,10 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
|||||||
trackers: &mut Tracker<A>,
|
trackers: &mut Tracker<A>,
|
||||||
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
|
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
|
||||||
pending_query_resets: &mut QueryResetMap<A>,
|
pending_query_resets: &mut QueryResetMap<A>,
|
||||||
view_guard: &'a Storage<TextureView<A>, id::TextureViewId>,
|
view_guard: &'a Storage<TextureView<A>>,
|
||||||
buffer_guard: &'a Storage<Buffer<A>, id::BufferId>,
|
buffer_guard: &'a Storage<Buffer<A>>,
|
||||||
texture_guard: &'a Storage<Texture<A>, id::TextureId>,
|
texture_guard: &'a Storage<Texture<A>>,
|
||||||
query_set_guard: &'a Storage<QuerySet<A>, id::QuerySetId>,
|
query_set_guard: &'a Storage<QuerySet<A>>,
|
||||||
snatch_guard: &SnatchGuard<'a>,
|
snatch_guard: &SnatchGuard<'a>,
|
||||||
) -> Result<Self, RenderPassErrorInner> {
|
) -> Result<Self, RenderPassErrorInner> {
|
||||||
profiling::scope!("RenderPassInfo::start");
|
profiling::scope!("RenderPassInfo::start");
|
||||||
@ -2391,7 +2391,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
(trackers, pending_discard_init_fixups)
|
(trackers, pending_discard_init_fixups)
|
||||||
};
|
};
|
||||||
|
|
||||||
let cmd_buf = hub.command_buffers.get(encoder_id).unwrap();
|
let cmd_buf = hub.command_buffers.get(encoder_id.transmute()).unwrap();
|
||||||
let mut cmd_buf_data = cmd_buf.data.lock();
|
let mut cmd_buf_data = cmd_buf.data.lock();
|
||||||
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
global::Global,
|
global::Global,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
|
id::markers,
|
||||||
id::{self, AdapterId, DeviceId, QueueId, SurfaceId},
|
id::{self, AdapterId, DeviceId, QueueId, SurfaceId},
|
||||||
identity::{GlobalIdentityHandlerFactory, Input},
|
identity::{GlobalIdentityHandlerFactory, Input},
|
||||||
init_tracker::TextureInitTracker,
|
init_tracker::TextureInitTracker,
|
||||||
@ -146,12 +147,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &resource::BufferDescriptor,
|
desc: &resource::BufferDescriptor,
|
||||||
id_in: Input<G, id::BufferId>,
|
id_in: Input<G, markers::Buffer>,
|
||||||
) -> (id::BufferId, Option<CreateBufferError>) {
|
) -> (id::BufferId, Option<CreateBufferError>) {
|
||||||
profiling::scope!("Device::create_buffer");
|
profiling::scope!("Device::create_buffer");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.buffers.prepare::<G>(id_in);
|
let fid = hub.buffers.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let mut to_destroy: ArrayVec<resource::Buffer<A>, 2> = ArrayVec::new();
|
let mut to_destroy: ArrayVec<resource::Buffer<A>, 2> = ArrayVec::new();
|
||||||
let error = loop {
|
let error = loop {
|
||||||
@ -309,20 +310,20 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
/// [`device_create_buffer`]: Global::device_create_buffer
|
/// [`device_create_buffer`]: Global::device_create_buffer
|
||||||
/// [`usage`]: https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-usage
|
/// [`usage`]: https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-usage
|
||||||
/// [`wgpu_types::BufferUsages`]: wgt::BufferUsages
|
/// [`wgpu_types::BufferUsages`]: wgt::BufferUsages
|
||||||
pub fn create_buffer_error<A: HalApi>(&self, id_in: Input<G, id::BufferId>, label: Label) {
|
pub fn create_buffer_error<A: HalApi>(&self, id_in: Input<G, markers::Buffer>, label: Label) {
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.buffers.prepare::<G>(id_in);
|
let fid = hub.buffers.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
fid.assign_error(label.borrow_or_default());
|
fid.assign_error(label.borrow_or_default());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_bundle_error<A: HalApi>(
|
pub fn create_render_bundle_error<A: HalApi>(
|
||||||
&self,
|
&self,
|
||||||
id_in: Input<G, id::RenderBundleId>,
|
id_in: Input<G, markers::RenderBundle>,
|
||||||
label: Label,
|
label: Label,
|
||||||
) {
|
) {
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.render_bundles.prepare::<G>(id_in);
|
let fid = hub.render_bundles.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
fid.assign_error(label.borrow_or_default());
|
fid.assign_error(label.borrow_or_default());
|
||||||
}
|
}
|
||||||
@ -330,9 +331,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
/// Assign `id_in` an error with the given `label`.
|
/// Assign `id_in` an error with the given `label`.
|
||||||
///
|
///
|
||||||
/// See `create_buffer_error` for more context and explaination.
|
/// See `create_buffer_error` for more context and explaination.
|
||||||
pub fn create_texture_error<A: HalApi>(&self, id_in: Input<G, id::TextureId>, label: Label) {
|
pub fn create_texture_error<A: HalApi>(&self, id_in: Input<G, markers::Texture>, label: Label) {
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.textures.prepare::<G>(id_in);
|
let fid = hub.textures.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
fid.assign_error(label.borrow_or_default());
|
fid.assign_error(label.borrow_or_default());
|
||||||
}
|
}
|
||||||
@ -545,13 +546,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &resource::TextureDescriptor,
|
desc: &resource::TextureDescriptor,
|
||||||
id_in: Input<G, id::TextureId>,
|
id_in: Input<G, markers::Texture>,
|
||||||
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
||||||
profiling::scope!("Device::create_texture");
|
profiling::scope!("Device::create_texture");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.textures.prepare::<G>(id_in);
|
let fid = hub.textures.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -599,13 +600,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
hal_texture: A::Texture,
|
hal_texture: A::Texture,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &resource::TextureDescriptor,
|
desc: &resource::TextureDescriptor,
|
||||||
id_in: Input<G, id::TextureId>,
|
id_in: Input<G, markers::Texture>,
|
||||||
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
||||||
profiling::scope!("Device::create_texture_from_hal");
|
profiling::scope!("Device::create_texture_from_hal");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.textures.prepare::<G>(id_in);
|
let fid = hub.textures.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -673,12 +674,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
hal_buffer: A::Buffer,
|
hal_buffer: A::Buffer,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &resource::BufferDescriptor,
|
desc: &resource::BufferDescriptor,
|
||||||
id_in: Input<G, id::BufferId>,
|
id_in: Input<G, markers::Buffer>,
|
||||||
) -> (id::BufferId, Option<CreateBufferError>) {
|
) -> (id::BufferId, Option<CreateBufferError>) {
|
||||||
profiling::scope!("Device::create_buffer");
|
profiling::scope!("Device::create_buffer");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.buffers.prepare::<G>(id_in);
|
let fid = hub.buffers.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -783,13 +784,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
texture_id: id::TextureId,
|
texture_id: id::TextureId,
|
||||||
desc: &resource::TextureViewDescriptor,
|
desc: &resource::TextureViewDescriptor,
|
||||||
id_in: Input<G, id::TextureViewId>,
|
id_in: Input<G, markers::TextureView>,
|
||||||
) -> (id::TextureViewId, Option<resource::CreateTextureViewError>) {
|
) -> (id::TextureViewId, Option<resource::CreateTextureViewError>) {
|
||||||
profiling::scope!("Texture::create_view");
|
profiling::scope!("Texture::create_view");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.texture_views.prepare::<G>(id_in);
|
let fid = hub.texture_views.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let texture = match hub.textures.get(texture_id) {
|
let texture = match hub.textures.get(texture_id) {
|
||||||
@ -873,12 +874,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &resource::SamplerDescriptor,
|
desc: &resource::SamplerDescriptor,
|
||||||
id_in: Input<G, id::SamplerId>,
|
id_in: Input<G, markers::Sampler>,
|
||||||
) -> (id::SamplerId, Option<resource::CreateSamplerError>) {
|
) -> (id::SamplerId, Option<resource::CreateSamplerError>) {
|
||||||
profiling::scope!("Device::create_sampler");
|
profiling::scope!("Device::create_sampler");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.samplers.prepare::<G>(id_in);
|
let fid = hub.samplers.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -934,7 +935,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &binding_model::BindGroupLayoutDescriptor,
|
desc: &binding_model::BindGroupLayoutDescriptor,
|
||||||
id_in: Input<G, id::BindGroupLayoutId>,
|
id_in: Input<G, markers::BindGroupLayout>,
|
||||||
) -> (
|
) -> (
|
||||||
id::BindGroupLayoutId,
|
id::BindGroupLayoutId,
|
||||||
Option<binding_model::CreateBindGroupLayoutError>,
|
Option<binding_model::CreateBindGroupLayoutError>,
|
||||||
@ -942,7 +943,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
profiling::scope!("Device::create_bind_group_layout");
|
profiling::scope!("Device::create_bind_group_layout");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.bind_group_layouts.prepare::<G>(id_in);
|
let fid = hub.bind_group_layouts.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1004,7 +1005,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
return (id.unwrap(), None);
|
return (id.unwrap(), None);
|
||||||
};
|
};
|
||||||
|
|
||||||
let fid = hub.bind_group_layouts.prepare::<G>(id_in);
|
let fid = hub.bind_group_layouts.prepare::<G, _>(id_in);
|
||||||
let id = fid.assign_error(desc.label.borrow_or_default());
|
let id = fid.assign_error(desc.label.borrow_or_default());
|
||||||
(id, Some(error))
|
(id, Some(error))
|
||||||
}
|
}
|
||||||
@ -1033,7 +1034,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &binding_model::PipelineLayoutDescriptor,
|
desc: &binding_model::PipelineLayoutDescriptor,
|
||||||
id_in: Input<G, id::PipelineLayoutId>,
|
id_in: Input<G, markers::PipelineLayout>,
|
||||||
) -> (
|
) -> (
|
||||||
id::PipelineLayoutId,
|
id::PipelineLayoutId,
|
||||||
Option<binding_model::CreatePipelineLayoutError>,
|
Option<binding_model::CreatePipelineLayoutError>,
|
||||||
@ -1041,7 +1042,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
profiling::scope!("Device::create_pipeline_layout");
|
profiling::scope!("Device::create_pipeline_layout");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.pipeline_layouts.prepare::<G>(id_in);
|
let fid = hub.pipeline_layouts.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1094,12 +1095,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &binding_model::BindGroupDescriptor,
|
desc: &binding_model::BindGroupDescriptor,
|
||||||
id_in: Input<G, id::BindGroupId>,
|
id_in: Input<G, markers::BindGroup>,
|
||||||
) -> (id::BindGroupId, Option<binding_model::CreateBindGroupError>) {
|
) -> (id::BindGroupId, Option<binding_model::CreateBindGroupError>) {
|
||||||
profiling::scope!("Device::create_bind_group");
|
profiling::scope!("Device::create_bind_group");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.bind_groups.prepare::<G>(id_in);
|
let fid = hub.bind_groups.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1178,7 +1179,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &pipeline::ShaderModuleDescriptor,
|
desc: &pipeline::ShaderModuleDescriptor,
|
||||||
source: pipeline::ShaderModuleSource,
|
source: pipeline::ShaderModuleSource,
|
||||||
id_in: Input<G, id::ShaderModuleId>,
|
id_in: Input<G, markers::ShaderModule>,
|
||||||
) -> (
|
) -> (
|
||||||
id::ShaderModuleId,
|
id::ShaderModuleId,
|
||||||
Option<pipeline::CreateShaderModuleError>,
|
Option<pipeline::CreateShaderModuleError>,
|
||||||
@ -1186,7 +1187,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
profiling::scope!("Device::create_shader_module");
|
profiling::scope!("Device::create_shader_module");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.shader_modules.prepare::<G>(id_in);
|
let fid = hub.shader_modules.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1256,7 +1257,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &pipeline::ShaderModuleDescriptor,
|
desc: &pipeline::ShaderModuleDescriptor,
|
||||||
source: Cow<[u32]>,
|
source: Cow<[u32]>,
|
||||||
id_in: Input<G, id::ShaderModuleId>,
|
id_in: Input<G, markers::ShaderModule>,
|
||||||
) -> (
|
) -> (
|
||||||
id::ShaderModuleId,
|
id::ShaderModuleId,
|
||||||
Option<pipeline::CreateShaderModuleError>,
|
Option<pipeline::CreateShaderModuleError>,
|
||||||
@ -1264,7 +1265,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
profiling::scope!("Device::create_shader_module");
|
profiling::scope!("Device::create_shader_module");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.shader_modules.prepare::<G>(id_in);
|
let fid = hub.shader_modules.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1318,12 +1319,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &wgt::CommandEncoderDescriptor<Label>,
|
desc: &wgt::CommandEncoderDescriptor<Label>,
|
||||||
id_in: Input<G, id::CommandEncoderId>,
|
id_in: Input<G, markers::CommandEncoder>,
|
||||||
) -> (id::CommandEncoderId, Option<DeviceError>) {
|
) -> (id::CommandEncoderId, Option<DeviceError>) {
|
||||||
profiling::scope!("Device::create_command_encoder");
|
profiling::scope!("Device::create_command_encoder");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.command_buffers.prepare::<G>(id_in);
|
let fid = hub
|
||||||
|
.command_buffers
|
||||||
|
.prepare::<G, markers::CommandEncoder>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1359,11 +1362,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let (id, _) = fid.assign(command_buffer);
|
let (id, _) = fid.assign(command_buffer);
|
||||||
api_log!("Device::create_command_encoder -> {id:?}");
|
api_log!("Device::create_command_encoder -> {id:?}");
|
||||||
return (id, None);
|
return (id.transmute(), None);
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = fid.assign_error(desc.label.borrow_or_default());
|
let id = fid.assign_error(desc.label.borrow_or_default());
|
||||||
(id, Some(error))
|
(id.transmute(), Some(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command_buffer_label<A: HalApi>(&self, id: id::CommandBufferId) -> String {
|
pub fn command_buffer_label<A: HalApi>(&self, id: id::CommandBufferId) -> String {
|
||||||
@ -1376,7 +1379,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
if let Some(cmd_buf) = hub.command_buffers.unregister(command_encoder_id) {
|
if let Some(cmd_buf) = hub
|
||||||
|
.command_buffers
|
||||||
|
.unregister(command_encoder_id.transmute())
|
||||||
|
{
|
||||||
cmd_buf
|
cmd_buf
|
||||||
.device
|
.device
|
||||||
.untrack(&cmd_buf.data.lock().as_ref().unwrap().trackers);
|
.untrack(&cmd_buf.data.lock().as_ref().unwrap().trackers);
|
||||||
@ -1386,7 +1392,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub fn command_buffer_drop<A: HalApi>(&self, command_buffer_id: id::CommandBufferId) {
|
pub fn command_buffer_drop<A: HalApi>(&self, command_buffer_id: id::CommandBufferId) {
|
||||||
profiling::scope!("CommandBuffer::drop");
|
profiling::scope!("CommandBuffer::drop");
|
||||||
api_log!("CommandBuffer::drop {command_buffer_id:?}");
|
api_log!("CommandBuffer::drop {command_buffer_id:?}");
|
||||||
self.command_encoder_drop::<A>(command_buffer_id)
|
self.command_encoder_drop::<A>(command_buffer_id.transmute())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn device_create_render_bundle_encoder(
|
pub fn device_create_render_bundle_encoder(
|
||||||
@ -1394,7 +1400,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &command::RenderBundleEncoderDescriptor,
|
desc: &command::RenderBundleEncoderDescriptor,
|
||||||
) -> (
|
) -> (
|
||||||
id::RenderBundleEncoderId,
|
*mut command::RenderBundleEncoder,
|
||||||
Option<command::CreateRenderBundleError>,
|
Option<command::CreateRenderBundleError>,
|
||||||
) {
|
) {
|
||||||
profiling::scope!("Device::create_render_bundle_encoder");
|
profiling::scope!("Device::create_render_bundle_encoder");
|
||||||
@ -1410,13 +1416,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
bundle_encoder: command::RenderBundleEncoder,
|
bundle_encoder: command::RenderBundleEncoder,
|
||||||
desc: &command::RenderBundleDescriptor,
|
desc: &command::RenderBundleDescriptor,
|
||||||
id_in: Input<G, id::RenderBundleId>,
|
id_in: Input<G, markers::RenderBundle>,
|
||||||
) -> (id::RenderBundleId, Option<command::RenderBundleError>) {
|
) -> (id::RenderBundleId, Option<command::RenderBundleError>) {
|
||||||
profiling::scope!("RenderBundleEncoder::finish");
|
profiling::scope!("RenderBundleEncoder::finish");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.render_bundles.prepare::<G>(id_in);
|
let fid = hub.render_bundles.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(bundle_encoder.parent()) {
|
let device = match hub.devices.get(bundle_encoder.parent()) {
|
||||||
@ -1480,12 +1486,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &resource::QuerySetDescriptor,
|
desc: &resource::QuerySetDescriptor,
|
||||||
id_in: Input<G, id::QuerySetId>,
|
id_in: Input<G, markers::QuerySet>,
|
||||||
) -> (id::QuerySetId, Option<resource::CreateQuerySetError>) {
|
) -> (id::QuerySetId, Option<resource::CreateQuerySetError>) {
|
||||||
profiling::scope!("Device::create_query_set");
|
profiling::scope!("Device::create_query_set");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let fid = hub.query_sets.prepare::<G>(id_in);
|
let fid = hub.query_sets.prepare::<G, _>(id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let device = match hub.devices.get(device_id) {
|
let device = match hub.devices.get(device_id) {
|
||||||
@ -1554,7 +1560,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &pipeline::RenderPipelineDescriptor,
|
desc: &pipeline::RenderPipelineDescriptor,
|
||||||
id_in: Input<G, id::RenderPipelineId>,
|
id_in: Input<G, markers::RenderPipeline>,
|
||||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||||
) -> (
|
) -> (
|
||||||
id::RenderPipelineId,
|
id::RenderPipelineId,
|
||||||
@ -1564,7 +1570,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.render_pipelines.prepare::<G>(id_in);
|
let fid = hub.render_pipelines.prepare::<G, _>(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 implicit_error_context = implicit_context.clone();
|
let implicit_error_context = implicit_context.clone();
|
||||||
|
|
||||||
@ -1633,7 +1639,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
pipeline_id: id::RenderPipelineId,
|
pipeline_id: id::RenderPipelineId,
|
||||||
index: u32,
|
index: u32,
|
||||||
id_in: Input<G, id::BindGroupLayoutId>,
|
id_in: Input<G, markers::BindGroupLayout>,
|
||||||
) -> (
|
) -> (
|
||||||
id::BindGroupLayoutId,
|
id::BindGroupLayoutId,
|
||||||
Option<binding_model::GetBindGroupLayoutError>,
|
Option<binding_model::GetBindGroupLayoutError>,
|
||||||
@ -1648,7 +1654,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
let id = match pipeline.layout.bind_group_layouts.get(index as usize) {
|
let id = match pipeline.layout.bind_group_layouts.get(index as usize) {
|
||||||
Some(bg) => hub
|
Some(bg) => hub
|
||||||
.bind_group_layouts
|
.bind_group_layouts
|
||||||
.prepare::<G>(id_in)
|
.prepare::<G, _>(id_in)
|
||||||
.assign_existing(bg),
|
.assign_existing(bg),
|
||||||
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
||||||
};
|
};
|
||||||
@ -1657,7 +1663,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let id = hub
|
let id = hub
|
||||||
.bind_group_layouts
|
.bind_group_layouts
|
||||||
.prepare::<G>(id_in)
|
.prepare::<G, _>(id_in)
|
||||||
.assign_error("<derived>");
|
.assign_error("<derived>");
|
||||||
(id, Some(error))
|
(id, Some(error))
|
||||||
}
|
}
|
||||||
@ -1692,7 +1698,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: DeviceId,
|
device_id: DeviceId,
|
||||||
desc: &pipeline::ComputePipelineDescriptor,
|
desc: &pipeline::ComputePipelineDescriptor,
|
||||||
id_in: Input<G, id::ComputePipelineId>,
|
id_in: Input<G, markers::ComputePipeline>,
|
||||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||||
) -> (
|
) -> (
|
||||||
id::ComputePipelineId,
|
id::ComputePipelineId,
|
||||||
@ -1702,7 +1708,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.compute_pipelines.prepare::<G>(id_in);
|
let fid = hub.compute_pipelines.prepare::<G, _>(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 implicit_error_context = implicit_context.clone();
|
let implicit_error_context = implicit_context.clone();
|
||||||
|
|
||||||
@ -1766,7 +1772,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
pipeline_id: id::ComputePipelineId,
|
pipeline_id: id::ComputePipelineId,
|
||||||
index: u32,
|
index: u32,
|
||||||
id_in: Input<G, id::BindGroupLayoutId>,
|
id_in: Input<G, markers::BindGroupLayout>,
|
||||||
) -> (
|
) -> (
|
||||||
id::BindGroupLayoutId,
|
id::BindGroupLayoutId,
|
||||||
Option<binding_model::GetBindGroupLayoutError>,
|
Option<binding_model::GetBindGroupLayoutError>,
|
||||||
@ -1782,7 +1788,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
let id = match pipeline.layout.bind_group_layouts.get(index as usize) {
|
let id = match pipeline.layout.bind_group_layouts.get(index as usize) {
|
||||||
Some(bg) => hub
|
Some(bg) => hub
|
||||||
.bind_group_layouts
|
.bind_group_layouts
|
||||||
.prepare::<G>(id_in)
|
.prepare::<G, _>(id_in)
|
||||||
.assign_existing(bg),
|
.assign_existing(bg),
|
||||||
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
||||||
};
|
};
|
||||||
@ -1792,7 +1798,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let id = hub
|
let id = hub
|
||||||
.bind_group_layouts
|
.bind_group_layouts
|
||||||
.prepare::<G>(id_in)
|
.prepare::<G, _>(id_in)
|
||||||
.assign_error("<derived>");
|
.assign_error("<derived>");
|
||||||
(id, Some(error))
|
(id, Some(error))
|
||||||
}
|
}
|
||||||
@ -2118,7 +2124,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let (closures, queue_empty) = {
|
let (closures, queue_empty) = {
|
||||||
if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain {
|
if let wgt::Maintain::WaitForSubmissionIndex(submission_index) = maintain {
|
||||||
if submission_index.queue_id != device_id {
|
if submission_index.queue_id != device_id.transmute() {
|
||||||
return Err(WaitIdleError::WrongSubmissionIndex(
|
return Err(WaitIdleError::WrongSubmissionIndex(
|
||||||
submission_index.queue_id,
|
submission_index.queue_id,
|
||||||
device_id,
|
device_id,
|
||||||
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{
|
id::{
|
||||||
self, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, PipelineLayoutId,
|
self, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, Id, PipelineLayoutId,
|
||||||
QuerySetId, RenderBundleId, RenderPipelineId, SamplerId, StagingBufferId, TextureId,
|
QuerySetId, RenderBundleId, RenderPipelineId, SamplerId, StagingBufferId, TextureId,
|
||||||
TextureViewId,
|
TextureViewId,
|
||||||
},
|
},
|
||||||
@ -419,15 +419,14 @@ impl<A: HalApi> LifetimeTracker<A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> LifetimeTracker<A> {
|
impl<A: HalApi> LifetimeTracker<A> {
|
||||||
fn triage_resources<Id, R>(
|
fn triage_resources<R>(
|
||||||
resources_map: &mut FastHashMap<Id, Arc<R>>,
|
resources_map: &mut FastHashMap<Id<R::Marker>, Arc<R>>,
|
||||||
active: &mut [ActiveSubmission<A>],
|
active: &mut [ActiveSubmission<A>],
|
||||||
trackers: &mut impl ResourceTracker<Id, R>,
|
trackers: &mut impl ResourceTracker<R>,
|
||||||
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<Id, Arc<R>>,
|
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<Id<R::Marker>, Arc<R>>,
|
||||||
) -> Vec<Arc<R>>
|
) -> Vec<Arc<R>>
|
||||||
where
|
where
|
||||||
Id: id::TypedId,
|
R: Resource,
|
||||||
R: Resource<Id>,
|
|
||||||
{
|
{
|
||||||
let mut removed_resources = Vec::new();
|
let mut removed_resources = Vec::new();
|
||||||
resources_map.retain(|&id, resource| {
|
resources_map.retain(|&id, resource| {
|
||||||
|
@ -2,7 +2,8 @@ use crate::{
|
|||||||
binding_model,
|
binding_model,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hub::Hub,
|
hub::Hub,
|
||||||
id::{self},
|
id,
|
||||||
|
id::markers,
|
||||||
identity::{GlobalIdentityHandlerFactory, Input},
|
identity::{GlobalIdentityHandlerFactory, Input},
|
||||||
resource::{Buffer, BufferAccessResult},
|
resource::{Buffer, BufferAccessResult},
|
||||||
resource::{BufferAccessError, BufferMapOperation},
|
resource::{BufferAccessError, BufferMapOperation},
|
||||||
@ -463,18 +464,18 @@ pub struct ImplicitPipelineContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
|
pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
|
||||||
pub root_id: Input<G, id::PipelineLayoutId>,
|
pub root_id: Input<G, markers::PipelineLayout>,
|
||||||
pub group_ids: &'a [Input<G, id::BindGroupLayoutId>],
|
pub group_ids: &'a [Input<G, markers::BindGroupLayout>],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G: GlobalIdentityHandlerFactory> ImplicitPipelineIds<'_, G> {
|
impl<G: GlobalIdentityHandlerFactory> ImplicitPipelineIds<'_, G> {
|
||||||
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::<G>(self.root_id).into_id(),
|
root_id: hub.pipeline_layouts.prepare::<G, _>(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::<G>(*id_in).into_id())
|
.map(|id_in| hub.bind_group_layouts.prepare::<G, _>(*id_in).into_id())
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use crate::{
|
|||||||
global::Global,
|
global::Global,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hal_label,
|
hal_label,
|
||||||
|
id::markers,
|
||||||
id::{self, QueueId},
|
id::{self, QueueId},
|
||||||
identity::{GlobalIdentityHandlerFactory, Input},
|
identity::{GlobalIdentityHandlerFactory, Input},
|
||||||
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
|
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
|
||||||
@ -37,17 +38,19 @@ use super::Device;
|
|||||||
pub struct Queue<A: HalApi> {
|
pub struct Queue<A: HalApi> {
|
||||||
pub device: Option<Arc<Device<A>>>,
|
pub device: Option<Arc<Device<A>>>,
|
||||||
pub raw: Option<A::Queue>,
|
pub raw: Option<A::Queue>,
|
||||||
pub info: ResourceInfo<QueueId>,
|
pub info: ResourceInfo<Queue<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<QueueId> for Queue<A> {
|
impl<A: HalApi> Resource for Queue<A> {
|
||||||
const TYPE: ResourceType = "Queue";
|
const TYPE: ResourceType = "Queue";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<QueueId> {
|
type Marker = crate::id::markers::Queue;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<QueueId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,7 +439,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
queue_id: QueueId,
|
queue_id: QueueId,
|
||||||
buffer_size: wgt::BufferSize,
|
buffer_size: wgt::BufferSize,
|
||||||
id_in: Input<G, id::StagingBufferId>,
|
id_in: Input<G, markers::StagingBuffer>,
|
||||||
) -> Result<(id::StagingBufferId, *mut u8), QueueWriteError> {
|
) -> Result<(id::StagingBufferId, *mut u8), QueueWriteError> {
|
||||||
profiling::scope!("Queue::create_staging_buffer");
|
profiling::scope!("Queue::create_staging_buffer");
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
@ -451,7 +454,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
let (staging_buffer, staging_buffer_ptr) =
|
let (staging_buffer, staging_buffer_ptr) =
|
||||||
prepare_staging_buffer(device, buffer_size.get(), device.instance_flags)?;
|
prepare_staging_buffer(device, buffer_size.get(), device.instance_flags)?;
|
||||||
|
|
||||||
let fid = hub.staging_buffers.prepare::<G>(id_in);
|
let fid = hub.staging_buffers.prepare::<G, _>(id_in);
|
||||||
let (id, _) = fid.assign(staging_buffer);
|
let (id, _) = fid.assign(staging_buffer);
|
||||||
resource_log!("Queue::create_staging_buffer {id:?}");
|
resource_log!("Queue::create_staging_buffer {id:?}");
|
||||||
|
|
||||||
@ -669,7 +672,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
.get(destination.texture)
|
.get(destination.texture)
|
||||||
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
.map_err(|_| TransferError::InvalidTexture(destination.texture))?;
|
||||||
|
|
||||||
if dst.device.as_info().id() != queue_id {
|
if dst.device.as_info().id() != queue_id.transmute() {
|
||||||
return Err(DeviceError::WrongDevice.into());
|
return Err(DeviceError::WrongDevice.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1150,7 +1153,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
if cmdbuf.device.as_info().id() != queue_id {
|
if cmdbuf.device.as_info().id() != queue_id.transmute() {
|
||||||
return Err(DeviceError::WrongDevice.into());
|
return Err(DeviceError::WrongDevice.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hal_label,
|
hal_label,
|
||||||
hub::Hub,
|
hub::Hub,
|
||||||
id::{self, DeviceId, QueueId},
|
id::QueueId,
|
||||||
init_tracker::{
|
init_tracker::{
|
||||||
BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange,
|
BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange,
|
||||||
TextureInitTracker, TextureInitTrackerAction,
|
TextureInitTracker, TextureInitTrackerAction,
|
||||||
@ -90,7 +90,7 @@ pub struct Device<A: HalApi> {
|
|||||||
pub(crate) queue_id: RwLock<Option<QueueId>>,
|
pub(crate) queue_id: RwLock<Option<QueueId>>,
|
||||||
queue_to_drop: RwLock<Option<A::Queue>>,
|
queue_to_drop: RwLock<Option<A::Queue>>,
|
||||||
pub(crate) zero_buffer: Option<A::Buffer>,
|
pub(crate) zero_buffer: Option<A::Buffer>,
|
||||||
pub(crate) info: ResourceInfo<DeviceId>,
|
pub(crate) info: ResourceInfo<Device<A>>,
|
||||||
|
|
||||||
pub(crate) command_allocator: Mutex<Option<CommandAllocator<A>>>,
|
pub(crate) command_allocator: Mutex<Option<CommandAllocator<A>>>,
|
||||||
//Note: The submission index here corresponds to the last submission that is done.
|
//Note: The submission index here corresponds to the last submission that is done.
|
||||||
@ -1785,7 +1785,7 @@ impl<A: HalApi> Device<A> {
|
|||||||
dynamic_binding_info: &mut Vec<binding_model::BindGroupDynamicBindingData>,
|
dynamic_binding_info: &mut Vec<binding_model::BindGroupDynamicBindingData>,
|
||||||
late_buffer_binding_sizes: &mut FastHashMap<u32, wgt::BufferSize>,
|
late_buffer_binding_sizes: &mut FastHashMap<u32, wgt::BufferSize>,
|
||||||
used: &mut BindGroupStates<A>,
|
used: &mut BindGroupStates<A>,
|
||||||
storage: &'a Storage<Buffer<A>, id::BufferId>,
|
storage: &'a Storage<Buffer<A>>,
|
||||||
limits: &wgt::Limits,
|
limits: &wgt::Limits,
|
||||||
snatch_guard: &'a SnatchGuard<'a>,
|
snatch_guard: &'a SnatchGuard<'a>,
|
||||||
) -> Result<hal::BufferBinding<'a, A>, binding_model::CreateBindGroupError> {
|
) -> Result<hal::BufferBinding<'a, A>, binding_model::CreateBindGroupError> {
|
||||||
@ -2386,7 +2386,7 @@ impl<A: HalApi> Device<A> {
|
|||||||
pub(crate) fn create_pipeline_layout(
|
pub(crate) fn create_pipeline_layout(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
desc: &binding_model::PipelineLayoutDescriptor,
|
desc: &binding_model::PipelineLayoutDescriptor,
|
||||||
bgl_registry: &Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
bgl_registry: &Registry<BindGroupLayout<A>>,
|
||||||
) -> Result<binding_model::PipelineLayout<A>, binding_model::CreatePipelineLayoutError> {
|
) -> Result<binding_model::PipelineLayout<A>, binding_model::CreatePipelineLayoutError> {
|
||||||
use crate::binding_model::CreatePipelineLayoutError as Error;
|
use crate::binding_model::CreatePipelineLayoutError as Error;
|
||||||
|
|
||||||
@ -2499,8 +2499,8 @@ impl<A: HalApi> Device<A> {
|
|||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
implicit_context: Option<ImplicitPipelineContext>,
|
implicit_context: Option<ImplicitPipelineContext>,
|
||||||
mut derived_group_layouts: ArrayVec<bgl::EntryMap, { hal::MAX_BIND_GROUPS }>,
|
mut derived_group_layouts: ArrayVec<bgl::EntryMap, { hal::MAX_BIND_GROUPS }>,
|
||||||
bgl_registry: &Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
bgl_registry: &Registry<BindGroupLayout<A>>,
|
||||||
pipeline_layout_registry: &Registry<id::PipelineLayoutId, binding_model::PipelineLayout<A>>,
|
pipeline_layout_registry: &Registry<binding_model::PipelineLayout<A>>,
|
||||||
) -> Result<Arc<binding_model::PipelineLayout<A>>, pipeline::ImplicitLayoutError> {
|
) -> Result<Arc<binding_model::PipelineLayout<A>>, pipeline::ImplicitLayoutError> {
|
||||||
while derived_group_layouts
|
while derived_group_layouts
|
||||||
.last()
|
.last()
|
||||||
@ -3440,14 +3440,16 @@ impl<A: HalApi> Device<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<DeviceId> for Device<A> {
|
impl<A: HalApi> Resource for Device<A> {
|
||||||
const TYPE: ResourceType = "Device";
|
const TYPE: ResourceType = "Device";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<DeviceId> {
|
type Marker = crate::id::markers::Device;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<DeviceId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ use wgt::Backend;
|
|||||||
use crate::{
|
use crate::{
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hub::{HubReport, Hubs},
|
hub::{HubReport, Hubs},
|
||||||
id::SurfaceId,
|
|
||||||
identity::GlobalIdentityHandlerFactory,
|
identity::GlobalIdentityHandlerFactory,
|
||||||
instance::{Instance, Surface},
|
instance::{Instance, Surface},
|
||||||
registry::{Registry, RegistryReport},
|
registry::{Registry, RegistryReport},
|
||||||
@ -47,7 +46,7 @@ impl GlobalReport {
|
|||||||
|
|
||||||
pub struct Global<G: GlobalIdentityHandlerFactory> {
|
pub struct Global<G: GlobalIdentityHandlerFactory> {
|
||||||
pub instance: Instance,
|
pub instance: Instance,
|
||||||
pub surfaces: Registry<SurfaceId, Surface>,
|
pub surfaces: Registry<Surface>,
|
||||||
pub(crate) hubs: Hubs,
|
pub(crate) hubs: Hubs,
|
||||||
_phantom: PhantomData<G>,
|
_phantom: PhantomData<G>,
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
The `wgpu_core` API uses identifiers of type [`Id<R>`] to refer to
|
The `wgpu_core` API uses identifiers of type [`Id<R>`] to refer to
|
||||||
resources of type `R`. For example, [`id::DeviceId`] is an alias for
|
resources of type `R`. For example, [`id::DeviceId`] is an alias for
|
||||||
`Id<Device<Empty>>`, and [`id::BufferId`] is an alias for
|
`Id<markers::Device>`, and [`id::BufferId`] is an alias for
|
||||||
`Id<Buffer<Empty>>`. `Id` implements `Copy`, `Hash`, `Eq`, `Ord`, and
|
`Id<markers::Buffer>`. `Id` implements `Copy`, `Hash`, `Eq`, `Ord`, and
|
||||||
of course `Debug`.
|
of course `Debug`.
|
||||||
|
|
||||||
|
[`id::DeviceId`]: crate::id::DeviceId
|
||||||
|
[`id::BufferId`]: crate::id::BufferId
|
||||||
|
|
||||||
Each `Id` contains not only an index for the resource it denotes but
|
Each `Id` contains not only an index for the resource it denotes but
|
||||||
also a Backend indicating which `wgpu` backend it belongs to. You
|
also a Backend indicating which `wgpu` backend it belongs to. You
|
||||||
can use the [`gfx_select`] macro to dynamically dispatch on an id's
|
can use the [`gfx_select`] macro to dynamically dispatch on an id's
|
||||||
@ -43,7 +46,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
device_id: id::DeviceId,
|
device_id: id::DeviceId,
|
||||||
desc: &resource::BufferDescriptor,
|
desc: &resource::BufferDescriptor,
|
||||||
id_in: Input<G, id::BufferId>,
|
id_in: Input<G>,
|
||||||
) -> (id::BufferId, Option<resource::CreateBufferError>) {
|
) -> (id::BufferId, Option<resource::CreateBufferError>) {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
@ -115,7 +118,6 @@ use crate::{
|
|||||||
command::{CommandBuffer, RenderBundle},
|
command::{CommandBuffer, RenderBundle},
|
||||||
device::{queue::Queue, Device},
|
device::{queue::Queue, Device},
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id,
|
|
||||||
identity::GlobalIdentityHandlerFactory,
|
identity::GlobalIdentityHandlerFactory,
|
||||||
instance::{Adapter, HalSurface, Surface},
|
instance::{Adapter, HalSurface, Surface},
|
||||||
pipeline::{ComputePipeline, RenderPipeline, ShaderModule},
|
pipeline::{ComputePipeline, RenderPipeline, ShaderModule},
|
||||||
@ -177,23 +179,23 @@ impl HubReport {
|
|||||||
///
|
///
|
||||||
/// [`A::hub(global)`]: HalApi::hub
|
/// [`A::hub(global)`]: HalApi::hub
|
||||||
pub struct Hub<A: HalApi> {
|
pub struct Hub<A: HalApi> {
|
||||||
pub adapters: Registry<id::AdapterId, Adapter<A>>,
|
pub adapters: Registry<Adapter<A>>,
|
||||||
pub devices: Registry<id::DeviceId, Device<A>>,
|
pub devices: Registry<Device<A>>,
|
||||||
pub queues: Registry<id::QueueId, Queue<A>>,
|
pub queues: Registry<Queue<A>>,
|
||||||
pub pipeline_layouts: Registry<id::PipelineLayoutId, PipelineLayout<A>>,
|
pub pipeline_layouts: Registry<PipelineLayout<A>>,
|
||||||
pub shader_modules: Registry<id::ShaderModuleId, ShaderModule<A>>,
|
pub shader_modules: Registry<ShaderModule<A>>,
|
||||||
pub bind_group_layouts: Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
pub bind_group_layouts: Registry<BindGroupLayout<A>>,
|
||||||
pub bind_groups: Registry<id::BindGroupId, BindGroup<A>>,
|
pub bind_groups: Registry<BindGroup<A>>,
|
||||||
pub command_buffers: Registry<id::CommandBufferId, CommandBuffer<A>>,
|
pub command_buffers: Registry<CommandBuffer<A>>,
|
||||||
pub render_bundles: Registry<id::RenderBundleId, RenderBundle<A>>,
|
pub render_bundles: Registry<RenderBundle<A>>,
|
||||||
pub render_pipelines: Registry<id::RenderPipelineId, RenderPipeline<A>>,
|
pub render_pipelines: Registry<RenderPipeline<A>>,
|
||||||
pub compute_pipelines: Registry<id::ComputePipelineId, ComputePipeline<A>>,
|
pub compute_pipelines: Registry<ComputePipeline<A>>,
|
||||||
pub query_sets: Registry<id::QuerySetId, QuerySet<A>>,
|
pub query_sets: Registry<QuerySet<A>>,
|
||||||
pub buffers: Registry<id::BufferId, Buffer<A>>,
|
pub buffers: Registry<Buffer<A>>,
|
||||||
pub staging_buffers: Registry<id::StagingBufferId, StagingBuffer<A>>,
|
pub staging_buffers: Registry<StagingBuffer<A>>,
|
||||||
pub textures: Registry<id::TextureId, Texture<A>>,
|
pub textures: Registry<Texture<A>>,
|
||||||
pub texture_views: Registry<id::TextureViewId, TextureView<A>>,
|
pub texture_views: Registry<TextureView<A>>,
|
||||||
pub samplers: Registry<id::SamplerId, Sampler<A>>,
|
pub samplers: Registry<Sampler<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Hub<A> {
|
impl<A: HalApi> Hub<A> {
|
||||||
@ -222,11 +224,7 @@ impl<A: HalApi> Hub<A> {
|
|||||||
//TODO: instead of having a hacky `with_adapters` parameter,
|
//TODO: instead of having a hacky `with_adapters` parameter,
|
||||||
// we should have `clear_device(device_id)` that specifically destroys
|
// we should have `clear_device(device_id)` that specifically destroys
|
||||||
// everything related to a logical device.
|
// everything related to a logical device.
|
||||||
pub(crate) fn clear(
|
pub(crate) fn clear(&self, surface_guard: &Storage<Surface>, with_adapters: bool) {
|
||||||
&self,
|
|
||||||
surface_guard: &Storage<Surface, id::SurfaceId>,
|
|
||||||
with_adapters: bool,
|
|
||||||
) {
|
|
||||||
use hal::Surface;
|
use hal::Surface;
|
||||||
|
|
||||||
let mut devices = self.devices.write();
|
let mut devices = self.devices.write();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::{Epoch, Index};
|
use crate::{Epoch, Index};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
fmt::{self, Debug},
|
fmt::{self, Debug},
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
@ -9,15 +8,74 @@ use std::{
|
|||||||
use wgt::{Backend, WasmNotSendSync};
|
use wgt::{Backend, WasmNotSendSync};
|
||||||
|
|
||||||
type IdType = u64;
|
type IdType = u64;
|
||||||
type NonZeroId = std::num::NonZeroU64;
|
|
||||||
type ZippedIndex = Index;
|
type ZippedIndex = Index;
|
||||||
|
type NonZeroId = std::num::NonZeroU64;
|
||||||
|
|
||||||
const INDEX_BITS: usize = std::mem::size_of::<ZippedIndex>() * 8;
|
const INDEX_BITS: usize = std::mem::size_of::<ZippedIndex>() * 8;
|
||||||
const EPOCH_BITS: usize = INDEX_BITS - BACKEND_BITS;
|
const EPOCH_BITS: usize = INDEX_BITS - BACKEND_BITS;
|
||||||
const BACKEND_BITS: usize = 3;
|
const BACKEND_BITS: usize = 3;
|
||||||
const BACKEND_SHIFT: usize = INDEX_BITS * 2 - BACKEND_BITS;
|
const BACKEND_SHIFT: usize = INDEX_BITS * 2 - BACKEND_BITS;
|
||||||
pub const EPOCH_MASK: u32 = (1 << (EPOCH_BITS)) - 1;
|
pub const EPOCH_MASK: u32 = (1 << (EPOCH_BITS)) - 1;
|
||||||
type Dummy = hal::api::Empty;
|
|
||||||
|
/// The raw underlying representation of an identifier.
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(any(feature = "serde", feature = "replay"), derive(serde::Deserialize))]
|
||||||
|
#[cfg_attr(feature = "trace", serde(into = "SerialId"))]
|
||||||
|
#[cfg_attr(feature = "replay", serde(from = "SerialId"))]
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct RawId(NonZeroId);
|
||||||
|
|
||||||
|
impl RawId {
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[inline]
|
||||||
|
pub fn from_non_zero(non_zero: NonZeroId) -> Self {
|
||||||
|
Self(non_zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[inline]
|
||||||
|
pub fn into_non_zero(self) -> NonZeroId {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Zip together an identifier and return its raw underlying representation.
|
||||||
|
pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> RawId {
|
||||||
|
assert_eq!(0, epoch >> EPOCH_BITS);
|
||||||
|
assert_eq!(0, (index as IdType) >> INDEX_BITS);
|
||||||
|
let v = index as IdType
|
||||||
|
| ((epoch as IdType) << INDEX_BITS)
|
||||||
|
| ((backend as IdType) << BACKEND_SHIFT);
|
||||||
|
Self(NonZeroId::new(v).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unzip a raw identifier into its components.
|
||||||
|
#[allow(trivial_numeric_casts)]
|
||||||
|
pub fn unzip(self) -> (Index, Epoch, Backend) {
|
||||||
|
(
|
||||||
|
(self.0.get() as ZippedIndex) as Index,
|
||||||
|
(((self.0.get() >> INDEX_BITS) as ZippedIndex) & (EPOCH_MASK as ZippedIndex)) as Index,
|
||||||
|
self.backend(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn backend(self) -> Backend {
|
||||||
|
match self.0.get() >> (BACKEND_SHIFT) as u8 {
|
||||||
|
0 => Backend::Empty,
|
||||||
|
1 => Backend::Vulkan,
|
||||||
|
2 => Backend::Metal,
|
||||||
|
3 => Backend::Dx12,
|
||||||
|
4 => Backend::Gl,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Coerce a slice of identifiers into a slice of raw identifiers.
|
||||||
|
pub fn into_raw_slice<T: Marker>(ids: &[Id<T>]) -> &[RawId] {
|
||||||
|
// SAFETY: Any Id<T> is repr(transparent) over `RawId`.
|
||||||
|
unsafe { std::slice::from_raw_parts(ids.as_ptr().cast(), ids.len()) }
|
||||||
|
}
|
||||||
|
|
||||||
/// An identifier for a wgpu object.
|
/// An identifier for a wgpu object.
|
||||||
///
|
///
|
||||||
@ -49,21 +107,13 @@ type Dummy = hal::api::Empty;
|
|||||||
/// [`Registry`]: crate::hub::Registry
|
/// [`Registry`]: crate::hub::Registry
|
||||||
/// [`Empty`]: hal::api::Empty
|
/// [`Empty`]: hal::api::Empty
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[cfg_attr(feature = "trace", derive(serde::Serialize), serde(into = "SerialId"))]
|
#[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))]
|
||||||
|
#[cfg_attr(any(feature = "serde", feature = "replay"), derive(serde::Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "replay",
|
any(feature = "serde", feature = "trace", feature = "replay"),
|
||||||
derive(serde::Deserialize),
|
serde(transparent)
|
||||||
serde(from = "SerialId")
|
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
pub struct Id<T: Marker>(RawId, PhantomData<T>);
|
||||||
all(feature = "serde", not(feature = "trace")),
|
|
||||||
derive(serde::Serialize)
|
|
||||||
)]
|
|
||||||
#[cfg_attr(
|
|
||||||
all(feature = "serde", not(feature = "replay")),
|
|
||||||
derive(serde::Deserialize)
|
|
||||||
)]
|
|
||||||
pub struct Id<T: 'static + WasmNotSendSync>(NonZeroId, PhantomData<T>);
|
|
||||||
|
|
||||||
// This type represents Id in a more readable (and editable) way.
|
// This type represents Id in a more readable (and editable) way.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -72,39 +122,40 @@ enum SerialId {
|
|||||||
// The only variant forces RON to not ignore "Id"
|
// The only variant forces RON to not ignore "Id"
|
||||||
Id(Index, Epoch, Backend),
|
Id(Index, Epoch, Backend),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
impl<T> From<Id<T>> for SerialId
|
impl From<RawId> for SerialId {
|
||||||
where
|
fn from(id: RawId) -> Self {
|
||||||
T: 'static + WasmNotSendSync,
|
|
||||||
{
|
|
||||||
fn from(id: Id<T>) -> Self {
|
|
||||||
let (index, epoch, backend) = id.unzip();
|
let (index, epoch, backend) = id.unzip();
|
||||||
Self::Id(index, epoch, backend)
|
Self::Id(index, epoch, backend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "replay")]
|
#[cfg(feature = "replay")]
|
||||||
impl<T> From<SerialId> for Id<T>
|
impl From<SerialId> for RawId {
|
||||||
where
|
|
||||||
T: 'static + WasmNotSendSync,
|
|
||||||
{
|
|
||||||
fn from(id: SerialId) -> Self {
|
fn from(id: SerialId) -> Self {
|
||||||
match id {
|
match id {
|
||||||
SerialId::Id(index, epoch, backend) => TypedId::zip(index, epoch, backend),
|
SerialId::Id(index, epoch, backend) => RawId::zip(index, epoch, backend),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Id<T>
|
impl<T> Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The raw id must be valid for the type.
|
/// The raw id must be valid for the type.
|
||||||
pub unsafe fn from_raw(raw: NonZeroId) -> Self {
|
pub unsafe fn from_raw(raw: RawId) -> Self {
|
||||||
Self(raw, PhantomData)
|
Self(raw, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Coerce the identifiers into its raw underlying representation.
|
||||||
|
pub fn into_raw(self) -> RawId {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn dummy(index: u32) -> Self {
|
pub(crate) fn dummy(index: u32) -> Self {
|
||||||
Id::zip(index, 1, Backend::Empty)
|
Id::zip(index, 1, Backend::Empty)
|
||||||
@ -115,24 +166,53 @@ where
|
|||||||
self.backend() != Backend::Empty
|
self.backend() != Backend::Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the backend this identifier corresponds to.
|
||||||
|
#[inline]
|
||||||
pub fn backend(self) -> Backend {
|
pub fn backend(self) -> Backend {
|
||||||
match self.0.get() >> (BACKEND_SHIFT) as u8 {
|
self.0.backend()
|
||||||
0 => Backend::Empty,
|
}
|
||||||
1 => Backend::Vulkan,
|
|
||||||
2 => Backend::Metal,
|
/// Transmute this identifier to one with a different marker trait.
|
||||||
3 => Backend::Dx12,
|
///
|
||||||
4 => Backend::Gl,
|
/// Legal use is governed through a sealed trait, however it's correctness
|
||||||
_ => unreachable!(),
|
/// depends on the current implementation of `wgpu-core`.
|
||||||
}
|
#[inline]
|
||||||
|
pub const fn transmute<U: self::transmute::Transmute<T>>(self) -> Id<U> {
|
||||||
|
Id(self.0, PhantomData)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
||||||
|
Id(RawId::zip(index, epoch, backend), PhantomData)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn unzip(self) -> (Index, Epoch, Backend) {
|
||||||
|
self.0.unzip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Copy for Id<T> where T: 'static + WasmNotSendSync {}
|
pub(crate) mod transmute {
|
||||||
|
// This trait is effectively sealed to prevent illegal transmutes.
|
||||||
|
pub trait Transmute<U>: super::Marker {}
|
||||||
|
|
||||||
|
// Self-transmute is always legal.
|
||||||
|
impl<T> Transmute<T> for T where T: super::Marker {}
|
||||||
|
|
||||||
|
// TODO: Remove these once queues have their own identifiers.
|
||||||
|
impl Transmute<super::markers::Queue> for super::markers::Device {}
|
||||||
|
impl Transmute<super::markers::Device> for super::markers::Queue {}
|
||||||
|
impl Transmute<super::markers::CommandBuffer> for super::markers::CommandEncoder {}
|
||||||
|
impl Transmute<super::markers::CommandEncoder> for super::markers::CommandBuffer {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Copy for Id<T> where T: Marker {}
|
||||||
|
|
||||||
impl<T> Clone for Id<T>
|
impl<T> Clone for Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
@ -140,7 +220,7 @@ where
|
|||||||
|
|
||||||
impl<T> Debug for Id<T>
|
impl<T> Debug for Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let (index, epoch, backend) = self.unzip();
|
let (index, epoch, backend) = self.unzip();
|
||||||
@ -159,8 +239,9 @@ where
|
|||||||
|
|
||||||
impl<T> Hash for Id<T>
|
impl<T> Hash for Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.0.hash(state);
|
self.0.hash(state);
|
||||||
}
|
}
|
||||||
@ -168,19 +249,21 @@ where
|
|||||||
|
|
||||||
impl<T> PartialEq for Id<T>
|
impl<T> PartialEq for Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.0 == other.0
|
self.0 == other.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Eq for Id<T> where T: 'static + WasmNotSendSync {}
|
impl<T> Eq for Id<T> where T: Marker {}
|
||||||
|
|
||||||
impl<T> PartialOrd for Id<T>
|
impl<T> PartialOrd for Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
self.0.partial_cmp(&other.0)
|
self.0.partial_cmp(&other.0)
|
||||||
}
|
}
|
||||||
@ -188,78 +271,73 @@ where
|
|||||||
|
|
||||||
impl<T> Ord for Id<T>
|
impl<T> Ord for Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: Marker,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
self.0.cmp(&other.0)
|
self.0.cmp(&other.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait carrying methods for direct `Id` access.
|
/// Marker trait used to determine which types uniquely identify a resource.
|
||||||
///
|
///
|
||||||
/// Most `wgpu-core` clients should not use this trait. Unusual clients that
|
/// For example, `Device<A>` will have the same type of identifier as
|
||||||
/// need to construct `Id` values directly, or access their components, like the
|
/// `Device<B>` because `Device<T>` for any `T` defines the same maker type.
|
||||||
/// WGPU recording player, may use this trait to do so.
|
pub trait Marker: 'static + WasmNotSendSync {}
|
||||||
pub trait TypedId: Copy + Debug + Any + 'static + WasmNotSendSync + Eq + Hash {
|
|
||||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self;
|
|
||||||
fn unzip(self) -> (Index, Epoch, Backend);
|
|
||||||
fn into_raw(self) -> NonZeroId;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(trivial_numeric_casts)]
|
// This allows `()` to be used as a marker type for tests.
|
||||||
impl<T> TypedId for Id<T>
|
//
|
||||||
where
|
// We don't want these in production code, since they essentially remove type
|
||||||
T: 'static + WasmNotSendSync,
|
// safety, like how identifiers across different types can be compared.
|
||||||
{
|
#[cfg(test)]
|
||||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
impl Marker for () {}
|
||||||
assert_eq!(0, epoch >> EPOCH_BITS);
|
|
||||||
assert_eq!(0, (index as IdType) >> INDEX_BITS);
|
|
||||||
let v = index as IdType
|
|
||||||
| ((epoch as IdType) << INDEX_BITS)
|
|
||||||
| ((backend as IdType) << BACKEND_SHIFT);
|
|
||||||
Id(NonZeroId::new(v).unwrap(), PhantomData)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unzip(self) -> (Index, Epoch, Backend) {
|
/// Define identifiers for each resource.
|
||||||
(
|
macro_rules! ids {
|
||||||
(self.0.get() as ZippedIndex) as Index,
|
($(
|
||||||
(((self.0.get() >> INDEX_BITS) as ZippedIndex) & (EPOCH_MASK as ZippedIndex)) as Index,
|
$(#[$($meta:meta)*])*
|
||||||
self.backend(),
|
pub type $name:ident $marker:ident;
|
||||||
)
|
)*) => {
|
||||||
}
|
/// Marker types for each resource.
|
||||||
|
pub mod markers {
|
||||||
|
$(
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum $marker {}
|
||||||
|
impl super::Marker for $marker {}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
fn into_raw(self) -> NonZeroId {
|
$(
|
||||||
self.0
|
$(#[$($meta)*])*
|
||||||
|
pub type $name = Id<self::markers::$marker>;
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type AdapterId = Id<crate::instance::Adapter<Dummy>>;
|
ids! {
|
||||||
pub type SurfaceId = Id<crate::instance::Surface>;
|
pub type AdapterId Adapter;
|
||||||
// Device
|
pub type SurfaceId Surface;
|
||||||
pub type DeviceId = Id<crate::device::Device<Dummy>>;
|
pub type DeviceId Device;
|
||||||
pub type QueueId = DeviceId;
|
pub type QueueId Queue;
|
||||||
// Resource
|
pub type BufferId Buffer;
|
||||||
pub type BufferId = Id<crate::resource::Buffer<Dummy>>;
|
pub type StagingBufferId StagingBuffer;
|
||||||
pub type StagingBufferId = Id<crate::resource::StagingBuffer<Dummy>>;
|
pub type TextureViewId TextureView;
|
||||||
pub type TextureViewId = Id<crate::resource::TextureView<Dummy>>;
|
pub type TextureId Texture;
|
||||||
pub type TextureId = Id<crate::resource::Texture<Dummy>>;
|
pub type SamplerId Sampler;
|
||||||
pub type SamplerId = Id<crate::resource::Sampler<Dummy>>;
|
pub type BindGroupLayoutId BindGroupLayout;
|
||||||
// Binding model
|
pub type PipelineLayoutId PipelineLayout;
|
||||||
pub type BindGroupLayoutId = Id<crate::binding_model::BindGroupLayout<Dummy>>;
|
pub type BindGroupId BindGroup;
|
||||||
pub type PipelineLayoutId = Id<crate::binding_model::PipelineLayout<Dummy>>;
|
pub type ShaderModuleId ShaderModule;
|
||||||
pub type BindGroupId = Id<crate::binding_model::BindGroup<Dummy>>;
|
pub type RenderPipelineId RenderPipeline;
|
||||||
// Pipeline
|
pub type ComputePipelineId ComputePipeline;
|
||||||
pub type ShaderModuleId = Id<crate::pipeline::ShaderModule<Dummy>>;
|
pub type CommandEncoderId CommandEncoder;
|
||||||
pub type RenderPipelineId = Id<crate::pipeline::RenderPipeline<Dummy>>;
|
pub type CommandBufferId CommandBuffer;
|
||||||
pub type ComputePipelineId = Id<crate::pipeline::ComputePipeline<Dummy>>;
|
pub type RenderPassEncoderId RenderPassEncoder;
|
||||||
// Command
|
pub type ComputePassEncoderId ComputePassEncoder;
|
||||||
pub type CommandEncoderId = CommandBufferId;
|
pub type RenderBundleEncoderId RenderBundleEncoder;
|
||||||
pub type CommandBufferId = Id<crate::command::CommandBuffer<Dummy>>;
|
pub type RenderBundleId RenderBundle;
|
||||||
pub type RenderPassEncoderId = *mut crate::command::RenderPass;
|
pub type QuerySetId QuerySet;
|
||||||
pub type ComputePassEncoderId = *mut crate::command::ComputePass;
|
}
|
||||||
pub type RenderBundleEncoderId = *mut crate::command::RenderBundleEncoder;
|
|
||||||
pub type RenderBundleId = Id<crate::command::RenderBundle<Dummy>>;
|
|
||||||
pub type QuerySetId = Id<crate::resource::QuerySet<Dummy>>;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_id_backend() {
|
fn test_id_backend() {
|
||||||
@ -270,7 +348,7 @@ fn test_id_backend() {
|
|||||||
Backend::Dx12,
|
Backend::Dx12,
|
||||||
Backend::Gl,
|
Backend::Gl,
|
||||||
] {
|
] {
|
||||||
let id: Id<()> = Id::zip(1, 0, b);
|
let id = crate::id::Id::<()>::zip(1, 0, b);
|
||||||
let (_id, _epoch, backend) = id.unzip();
|
let (_id, _epoch, backend) = id.unzip();
|
||||||
assert_eq!(id.backend(), b);
|
assert_eq!(id.backend(), b);
|
||||||
assert_eq!(backend, b);
|
assert_eq!(backend, b);
|
||||||
@ -292,7 +370,7 @@ fn test_id() {
|
|||||||
for &i in &indexes {
|
for &i in &indexes {
|
||||||
for &e in &epochs {
|
for &e in &epochs {
|
||||||
for &b in &backends {
|
for &b in &backends {
|
||||||
let id: Id<()> = Id::zip(i, e, b);
|
let id = crate::id::Id::<()>::zip(i, e, b);
|
||||||
let (index, epoch, backend) = id.unzip();
|
let (index, epoch, backend) = id.unzip();
|
||||||
assert_eq!(index, i);
|
assert_eq!(index, i);
|
||||||
assert_eq!(epoch, e);
|
assert_eq!(epoch, e);
|
||||||
|
@ -2,7 +2,7 @@ use parking_lot::Mutex;
|
|||||||
use wgt::Backend;
|
use wgt::Backend;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
id::{self},
|
id::{self, Id, Marker},
|
||||||
Epoch, FastHashMap, Index,
|
Epoch, FastHashMap, Index,
|
||||||
};
|
};
|
||||||
use std::{fmt::Debug, marker::PhantomData, sync::Arc};
|
use std::{fmt::Debug, marker::PhantomData, sync::Arc};
|
||||||
@ -47,10 +47,10 @@ impl IdentityValues {
|
|||||||
///
|
///
|
||||||
/// The backend is incorporated into the id, so that ids allocated with
|
/// The backend is incorporated into the id, so that ids allocated with
|
||||||
/// different `backend` values are always distinct.
|
/// different `backend` values are always distinct.
|
||||||
pub fn alloc<I: id::TypedId>(&mut self, backend: Backend) -> I {
|
pub fn alloc<T: Marker>(&mut self, backend: Backend) -> Id<T> {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
match self.free.pop() {
|
match self.free.pop() {
|
||||||
Some((index, epoch)) => I::zip(index, epoch + 1, backend),
|
Some((index, epoch)) => Id::zip(index, epoch + 1, backend),
|
||||||
None => {
|
None => {
|
||||||
let epoch = 1;
|
let epoch = 1;
|
||||||
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
||||||
@ -60,12 +60,12 @@ impl IdentityValues {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
used.push(index);
|
used.push(index);
|
||||||
I::zip(index, epoch, backend)
|
Id::zip(index, epoch, backend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_as_used<I: id::TypedId>(&mut self, id: I) -> I {
|
pub fn mark_as_used<T: Marker>(&mut self, id: Id<T>) -> Id<T> {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
let (index, epoch, _backend) = id.unzip();
|
let (index, epoch, _backend) = id.unzip();
|
||||||
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
||||||
@ -74,7 +74,7 @@ impl IdentityValues {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Free `id`. It will never be returned from `alloc` again.
|
/// Free `id`. It will never be returned from `alloc` again.
|
||||||
pub fn release<I: id::TypedId>(&mut self, id: I) {
|
pub fn release<T: Marker>(&mut self, id: Id<T>) {
|
||||||
let (index, epoch, _backend) = id.unzip();
|
let (index, epoch, _backend) = id.unzip();
|
||||||
self.free.push((index, epoch));
|
self.free.push((index, epoch));
|
||||||
self.count -= 1;
|
self.count -= 1;
|
||||||
@ -86,24 +86,24 @@ impl IdentityValues {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IdentityManager<I: id::TypedId> {
|
pub struct IdentityManager<T: Marker> {
|
||||||
pub(super) values: Mutex<IdentityValues>,
|
pub(super) values: Mutex<IdentityValues>,
|
||||||
_phantom: PhantomData<I>,
|
_phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: id::TypedId> IdentityManager<I> {
|
impl<T: Marker> IdentityManager<T> {
|
||||||
pub fn process(&self, backend: Backend) -> I {
|
pub fn process(&self, backend: Backend) -> Id<T> {
|
||||||
self.values.lock().alloc(backend)
|
self.values.lock().alloc(backend)
|
||||||
}
|
}
|
||||||
pub fn mark_as_used(&self, id: I) -> I {
|
pub fn mark_as_used(&self, id: Id<T>) -> Id<T> {
|
||||||
self.values.lock().mark_as_used(id)
|
self.values.lock().mark_as_used(id)
|
||||||
}
|
}
|
||||||
pub fn free(&self, id: I) {
|
pub fn free(&self, id: Id<T>) {
|
||||||
self.values.lock().release(id)
|
self.values.lock().release(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: id::TypedId> IdentityManager<I> {
|
impl<T: Marker> IdentityManager<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
values: Mutex::new(IdentityValues::default()),
|
values: Mutex::new(IdentityValues::default()),
|
||||||
@ -115,7 +115,7 @@ impl<I: id::TypedId> IdentityManager<I> {
|
|||||||
/// A type that can produce [`IdentityManager`] filters for ids of type `I`.
|
/// A type that can produce [`IdentityManager`] filters for ids of type `I`.
|
||||||
///
|
///
|
||||||
/// See the module-level documentation for details.
|
/// See the module-level documentation for details.
|
||||||
pub trait IdentityHandlerFactory<I: id::TypedId> {
|
pub trait IdentityHandlerFactory<T: Marker> {
|
||||||
type Input: Copy;
|
type Input: Copy;
|
||||||
/// Create an [`IdentityManager<I>`] implementation that can
|
/// Create an [`IdentityManager<I>`] implementation that can
|
||||||
/// transform proto-ids into ids of type `I`.
|
/// transform proto-ids into ids of type `I`.
|
||||||
@ -123,11 +123,11 @@ pub trait IdentityHandlerFactory<I: id::TypedId> {
|
|||||||
/// and are not generated by wgpu
|
/// and are not generated by wgpu
|
||||||
///
|
///
|
||||||
/// [`IdentityManager<I>`]: IdentityManager
|
/// [`IdentityManager<I>`]: IdentityManager
|
||||||
fn spawn(&self) -> Arc<IdentityManager<I>> {
|
fn spawn(&self) -> Arc<IdentityManager<T>> {
|
||||||
Arc::new(IdentityManager::new())
|
Arc::new(IdentityManager::new())
|
||||||
}
|
}
|
||||||
fn autogenerate_ids() -> bool;
|
fn autogenerate_ids() -> bool;
|
||||||
fn input_to_id(id_in: Self::Input) -> I;
|
fn input_to_id(id_in: Self::Input) -> Id<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A global identity handler factory based on [`IdentityManager`].
|
/// A global identity handler factory based on [`IdentityManager`].
|
||||||
@ -138,13 +138,13 @@ pub trait IdentityHandlerFactory<I: id::TypedId> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IdentityManagerFactory;
|
pub struct IdentityManagerFactory;
|
||||||
|
|
||||||
impl<I: id::TypedId> IdentityHandlerFactory<I> for IdentityManagerFactory {
|
impl<T: Marker> IdentityHandlerFactory<T> for IdentityManagerFactory {
|
||||||
type Input = ();
|
type Input = ();
|
||||||
fn autogenerate_ids() -> bool {
|
fn autogenerate_ids() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input_to_id(_id_in: Self::Input) -> I {
|
fn input_to_id(_id_in: Self::Input) -> Id<T> {
|
||||||
unreachable!("It should not be called")
|
unreachable!("It should not be called")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,23 +152,25 @@ impl<I: id::TypedId> IdentityHandlerFactory<I> for IdentityManagerFactory {
|
|||||||
/// A factory that can build [`IdentityManager`]s for all resource
|
/// A factory that can build [`IdentityManager`]s for all resource
|
||||||
/// types.
|
/// types.
|
||||||
pub trait GlobalIdentityHandlerFactory:
|
pub trait GlobalIdentityHandlerFactory:
|
||||||
IdentityHandlerFactory<id::AdapterId>
|
IdentityHandlerFactory<id::markers::Adapter>
|
||||||
+ IdentityHandlerFactory<id::DeviceId>
|
+ IdentityHandlerFactory<id::markers::Device>
|
||||||
+ IdentityHandlerFactory<id::PipelineLayoutId>
|
+ IdentityHandlerFactory<id::markers::PipelineLayout>
|
||||||
+ IdentityHandlerFactory<id::ShaderModuleId>
|
+ IdentityHandlerFactory<id::markers::ShaderModule>
|
||||||
+ IdentityHandlerFactory<id::BindGroupLayoutId>
|
+ IdentityHandlerFactory<id::markers::BindGroupLayout>
|
||||||
+ IdentityHandlerFactory<id::BindGroupId>
|
+ IdentityHandlerFactory<id::markers::BindGroup>
|
||||||
+ IdentityHandlerFactory<id::CommandBufferId>
|
+ IdentityHandlerFactory<id::markers::CommandBuffer>
|
||||||
+ IdentityHandlerFactory<id::RenderBundleId>
|
+ IdentityHandlerFactory<id::markers::RenderBundle>
|
||||||
+ IdentityHandlerFactory<id::RenderPipelineId>
|
+ IdentityHandlerFactory<id::markers::RenderPipeline>
|
||||||
+ IdentityHandlerFactory<id::ComputePipelineId>
|
+ IdentityHandlerFactory<id::markers::ComputePipeline>
|
||||||
+ IdentityHandlerFactory<id::QuerySetId>
|
+ IdentityHandlerFactory<id::markers::QuerySet>
|
||||||
+ IdentityHandlerFactory<id::BufferId>
|
+ IdentityHandlerFactory<id::markers::Buffer>
|
||||||
+ IdentityHandlerFactory<id::StagingBufferId>
|
+ IdentityHandlerFactory<id::markers::StagingBuffer>
|
||||||
+ IdentityHandlerFactory<id::TextureId>
|
+ IdentityHandlerFactory<id::markers::Texture>
|
||||||
+ IdentityHandlerFactory<id::TextureViewId>
|
+ IdentityHandlerFactory<id::markers::TextureView>
|
||||||
+ IdentityHandlerFactory<id::SamplerId>
|
+ IdentityHandlerFactory<id::markers::Sampler>
|
||||||
+ IdentityHandlerFactory<id::SurfaceId>
|
+ IdentityHandlerFactory<id::markers::Surface>
|
||||||
|
+ IdentityHandlerFactory<id::markers::Queue>
|
||||||
|
+ IdentityHandlerFactory<id::markers::CommandEncoder>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +180,7 @@ pub type Input<G, I> = <G as IdentityHandlerFactory<I>>::Input;
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_epoch_end_of_life() {
|
fn test_epoch_end_of_life() {
|
||||||
use id::TypedId as _;
|
let man = IdentityManager::<id::markers::Buffer>::new();
|
||||||
let man = IdentityManager::<id::BufferId>::new();
|
|
||||||
let forced_id = man.mark_as_used(id::BufferId::zip(0, 1, Backend::Empty));
|
let forced_id = man.mark_as_used(id::BufferId::zip(0, 1, Backend::Empty));
|
||||||
assert_eq!(forced_id.unzip().0, 0);
|
assert_eq!(forced_id.unzip().0, 0);
|
||||||
let id1 = man.process(Backend::Empty);
|
let id1 = man.process(Backend::Empty);
|
||||||
|
@ -6,6 +6,7 @@ use crate::{
|
|||||||
device::{queue::Queue, resource::Device, DeviceDescriptor},
|
device::{queue::Queue, resource::Device, DeviceDescriptor},
|
||||||
global::Global,
|
global::Global,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
|
id::markers,
|
||||||
id::{AdapterId, DeviceId, QueueId, SurfaceId},
|
id::{AdapterId, DeviceId, QueueId, SurfaceId},
|
||||||
identity::{GlobalIdentityHandlerFactory, Input},
|
identity::{GlobalIdentityHandlerFactory, Input},
|
||||||
present::Presentation,
|
present::Presentation,
|
||||||
@ -149,18 +150,20 @@ impl Instance {
|
|||||||
|
|
||||||
pub struct Surface {
|
pub struct Surface {
|
||||||
pub(crate) presentation: Mutex<Option<Presentation>>,
|
pub(crate) presentation: Mutex<Option<Presentation>>,
|
||||||
pub(crate) info: ResourceInfo<SurfaceId>,
|
pub(crate) info: ResourceInfo<Surface>,
|
||||||
pub(crate) raw: AnySurface,
|
pub(crate) raw: AnySurface,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resource<SurfaceId> for Surface {
|
impl Resource for Surface {
|
||||||
const TYPE: ResourceType = "Surface";
|
const TYPE: ResourceType = "Surface";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<SurfaceId> {
|
type Marker = crate::id::markers::Surface;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<SurfaceId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +193,7 @@ impl Surface {
|
|||||||
|
|
||||||
pub struct Adapter<A: HalApi> {
|
pub struct Adapter<A: HalApi> {
|
||||||
pub(crate) raw: hal::ExposedAdapter<A>,
|
pub(crate) raw: hal::ExposedAdapter<A>,
|
||||||
pub(crate) info: ResourceInfo<AdapterId>,
|
pub(crate) info: ResourceInfo<Adapter<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Adapter<A> {
|
impl<A: HalApi> Adapter<A> {
|
||||||
@ -382,14 +385,16 @@ impl<A: HalApi> Adapter<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<AdapterId> for Adapter<A> {
|
impl<A: HalApi> Resource for Adapter<A> {
|
||||||
const TYPE: ResourceType = "Adapter";
|
const TYPE: ResourceType = "Adapter";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<AdapterId> {
|
type Marker = crate::id::markers::Adapter;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<AdapterId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,7 +483,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
display_handle: raw_window_handle::RawDisplayHandle,
|
display_handle: raw_window_handle::RawDisplayHandle,
|
||||||
window_handle: raw_window_handle::RawWindowHandle,
|
window_handle: raw_window_handle::RawWindowHandle,
|
||||||
id_in: Input<G, SurfaceId>,
|
id_in: Input<G, markers::Surface>,
|
||||||
) -> Result<SurfaceId, hal::InstanceError> {
|
) -> Result<SurfaceId, hal::InstanceError> {
|
||||||
profiling::scope!("Instance::create_surface");
|
profiling::scope!("Instance::create_surface");
|
||||||
|
|
||||||
@ -526,7 +531,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
raw: hal_surface,
|
raw: hal_surface,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
let (id, _) = self.surfaces.prepare::<G, _>(id_in).assign(surface);
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,7 +542,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub unsafe fn instance_create_surface_metal(
|
pub unsafe fn instance_create_surface_metal(
|
||||||
&self,
|
&self,
|
||||||
layer: *mut std::ffi::c_void,
|
layer: *mut std::ffi::c_void,
|
||||||
id_in: Input<G, SurfaceId>,
|
id_in: Input<G, markers::Surface>,
|
||||||
) -> SurfaceId {
|
) -> SurfaceId {
|
||||||
profiling::scope!("Instance::create_surface_metal");
|
profiling::scope!("Instance::create_surface_metal");
|
||||||
|
|
||||||
@ -561,7 +566,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
let (id, _) = self.surfaces.prepare::<G, _>(id_in).assign(surface);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,7 +577,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub unsafe fn instance_create_surface_from_visual(
|
pub unsafe fn instance_create_surface_from_visual(
|
||||||
&self,
|
&self,
|
||||||
visual: *mut std::ffi::c_void,
|
visual: *mut std::ffi::c_void,
|
||||||
id_in: Input<G, SurfaceId>,
|
id_in: Input<G, markers::Surface>,
|
||||||
) -> SurfaceId {
|
) -> SurfaceId {
|
||||||
profiling::scope!("Instance::instance_create_surface_from_visual");
|
profiling::scope!("Instance::instance_create_surface_from_visual");
|
||||||
|
|
||||||
@ -592,7 +597,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
let (id, _) = self.surfaces.prepare::<G, _>(id_in).assign(surface);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +608,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub unsafe fn instance_create_surface_from_surface_handle(
|
pub unsafe fn instance_create_surface_from_surface_handle(
|
||||||
&self,
|
&self,
|
||||||
surface_handle: *mut std::ffi::c_void,
|
surface_handle: *mut std::ffi::c_void,
|
||||||
id_in: Input<G, SurfaceId>,
|
id_in: Input<G, markers::Surface>,
|
||||||
) -> SurfaceId {
|
) -> SurfaceId {
|
||||||
profiling::scope!("Instance::instance_create_surface_from_surface_handle");
|
profiling::scope!("Instance::instance_create_surface_from_surface_handle");
|
||||||
|
|
||||||
@ -625,7 +630,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
let (id, _) = self.surfaces.prepare::<G, _>(id_in).assign(surface);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,7 +641,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub unsafe fn instance_create_surface_from_swap_chain_panel(
|
pub unsafe fn instance_create_surface_from_swap_chain_panel(
|
||||||
&self,
|
&self,
|
||||||
swap_chain_panel: *mut std::ffi::c_void,
|
swap_chain_panel: *mut std::ffi::c_void,
|
||||||
id_in: Input<G, SurfaceId>,
|
id_in: Input<G, markers::Surface>,
|
||||||
) -> SurfaceId {
|
) -> SurfaceId {
|
||||||
profiling::scope!("Instance::instance_create_surface_from_swap_chain_panel");
|
profiling::scope!("Instance::instance_create_surface_from_swap_chain_panel");
|
||||||
|
|
||||||
@ -658,7 +663,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let (id, _) = self.surfaces.prepare::<G>(id_in).assign(surface);
|
let (id, _) = self.surfaces.prepare::<G, _>(id_in).assign(surface);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,7 +708,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
&self,
|
&self,
|
||||||
_: A,
|
_: A,
|
||||||
instance: &Option<A::Instance>,
|
instance: &Option<A::Instance>,
|
||||||
inputs: &AdapterInputs<Input<G, AdapterId>>,
|
inputs: &AdapterInputs<Input<G, markers::Adapter>>,
|
||||||
list: &mut Vec<AdapterId>,
|
list: &mut Vec<AdapterId>,
|
||||||
) {
|
) {
|
||||||
let inst = match *instance {
|
let inst = match *instance {
|
||||||
@ -722,12 +727,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
for raw in hal_adapters {
|
for raw in hal_adapters {
|
||||||
let adapter = Adapter::new(raw);
|
let adapter = Adapter::new(raw);
|
||||||
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
||||||
let (id, _) = hub.adapters.prepare::<G>(id_backend).assign(adapter);
|
let (id, _) = hub.adapters.prepare::<G, _>(id_backend).assign(adapter);
|
||||||
list.push(id);
|
list.push(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enumerate_adapters(&self, inputs: AdapterInputs<Input<G, AdapterId>>) -> Vec<AdapterId> {
|
pub fn enumerate_adapters(
|
||||||
|
&self,
|
||||||
|
inputs: AdapterInputs<Input<G, markers::Adapter>>,
|
||||||
|
) -> Vec<AdapterId> {
|
||||||
profiling::scope!("Instance::enumerate_adapters");
|
profiling::scope!("Instance::enumerate_adapters");
|
||||||
api_log!("Instance::enumerate_adapters");
|
api_log!("Instance::enumerate_adapters");
|
||||||
|
|
||||||
@ -758,7 +766,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
fn select<A: HalApi>(
|
fn select<A: HalApi>(
|
||||||
&self,
|
&self,
|
||||||
selected: &mut usize,
|
selected: &mut usize,
|
||||||
new_id: Option<Input<G, AdapterId>>,
|
new_id: Option<Input<G, markers::Adapter>>,
|
||||||
mut list: Vec<hal::ExposedAdapter<A>>,
|
mut list: Vec<hal::ExposedAdapter<A>>,
|
||||||
) -> Option<AdapterId> {
|
) -> Option<AdapterId> {
|
||||||
match selected.checked_sub(list.len()) {
|
match selected.checked_sub(list.len()) {
|
||||||
@ -771,7 +779,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
||||||
let (id, _) = HalApi::hub(self)
|
let (id, _) = HalApi::hub(self)
|
||||||
.adapters
|
.adapters
|
||||||
.prepare::<G>(new_id.unwrap())
|
.prepare::<G, _>(new_id.unwrap())
|
||||||
.assign(adapter);
|
.assign(adapter);
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
@ -781,7 +789,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub fn request_adapter(
|
pub fn request_adapter(
|
||||||
&self,
|
&self,
|
||||||
desc: &RequestAdapterOptions,
|
desc: &RequestAdapterOptions,
|
||||||
inputs: AdapterInputs<Input<G, AdapterId>>,
|
inputs: AdapterInputs<Input<G, markers::Adapter>>,
|
||||||
) -> Result<AdapterId, RequestAdapterError> {
|
) -> Result<AdapterId, RequestAdapterError> {
|
||||||
profiling::scope!("Instance::request_adapter");
|
profiling::scope!("Instance::request_adapter");
|
||||||
api_log!("Instance::request_adapter");
|
api_log!("Instance::request_adapter");
|
||||||
@ -947,24 +955,23 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub unsafe fn create_adapter_from_hal<A: HalApi>(
|
pub unsafe fn create_adapter_from_hal<A: HalApi>(
|
||||||
&self,
|
&self,
|
||||||
hal_adapter: hal::ExposedAdapter<A>,
|
hal_adapter: hal::ExposedAdapter<A>,
|
||||||
input: Input<G, AdapterId>,
|
input: Input<G, markers::Adapter>,
|
||||||
) -> AdapterId {
|
) -> AdapterId {
|
||||||
profiling::scope!("Instance::create_adapter_from_hal");
|
profiling::scope!("Instance::create_adapter_from_hal");
|
||||||
|
|
||||||
let fid = A::hub(self).adapters.prepare::<G>(input);
|
let fid = A::hub(self).adapters.prepare::<G, _>(input);
|
||||||
|
|
||||||
let (id, _adapter): (crate::id::Id<Adapter<hal::empty::Api>>, Arc<Adapter<A>>) =
|
let (id, _adapter): (_, Arc<Adapter<A>>) = match A::VARIANT {
|
||||||
match A::VARIANT {
|
#[cfg(vulkan)]
|
||||||
#[cfg(vulkan)]
|
Backend::Vulkan => fid.assign(Adapter::new(hal_adapter)),
|
||||||
Backend::Vulkan => fid.assign(Adapter::new(hal_adapter)),
|
#[cfg(metal)]
|
||||||
#[cfg(metal)]
|
Backend::Metal => fid.assign(Adapter::new(hal_adapter)),
|
||||||
Backend::Metal => fid.assign(Adapter::new(hal_adapter)),
|
#[cfg(dx12)]
|
||||||
#[cfg(dx12)]
|
Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)),
|
||||||
Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)),
|
#[cfg(gles)]
|
||||||
#[cfg(gles)]
|
Backend::Gl => fid.assign(Adapter::new(hal_adapter)),
|
||||||
Backend::Gl => fid.assign(Adapter::new(hal_adapter)),
|
_ => unreachable!(),
|
||||||
_ => unreachable!(),
|
};
|
||||||
};
|
|
||||||
resource_log!("Created Adapter {:?}", id);
|
resource_log!("Created Adapter {:?}", id);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@ -1065,15 +1072,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
adapter_id: AdapterId,
|
adapter_id: AdapterId,
|
||||||
desc: &DeviceDescriptor,
|
desc: &DeviceDescriptor,
|
||||||
trace_path: Option<&std::path::Path>,
|
trace_path: Option<&std::path::Path>,
|
||||||
device_id_in: Input<G, DeviceId>,
|
device_id_in: Input<G, markers::Device>,
|
||||||
queue_id_in: Input<G, QueueId>,
|
queue_id_in: Input<G, markers::Queue>,
|
||||||
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
||||||
profiling::scope!("Adapter::request_device");
|
profiling::scope!("Adapter::request_device");
|
||||||
api_log!("Adapter::request_device");
|
api_log!("Adapter::request_device");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let device_fid = hub.devices.prepare::<G>(device_id_in);
|
let device_fid = hub.devices.prepare::<G, markers::Device>(device_id_in);
|
||||||
let queue_fid = hub.queues.prepare::<G>(queue_id_in);
|
let queue_fid = hub.queues.prepare::<G, markers::Queue>(queue_id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let adapter = match hub.adapters.get(adapter_id) {
|
let adapter = match hub.adapters.get(adapter_id) {
|
||||||
@ -1114,14 +1121,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
hal_device: OpenDevice<A>,
|
hal_device: OpenDevice<A>,
|
||||||
desc: &DeviceDescriptor,
|
desc: &DeviceDescriptor,
|
||||||
trace_path: Option<&std::path::Path>,
|
trace_path: Option<&std::path::Path>,
|
||||||
device_id_in: Input<G, DeviceId>,
|
device_id_in: Input<G, markers::Device>,
|
||||||
queue_id_in: Input<G, QueueId>,
|
queue_id_in: Input<G, markers::Queue>,
|
||||||
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
||||||
profiling::scope!("Global::create_device_from_hal");
|
profiling::scope!("Global::create_device_from_hal");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
let devices_fid = hub.devices.prepare::<G>(device_id_in);
|
let devices_fid = hub.devices.prepare::<G, markers::Device>(device_id_in);
|
||||||
let queues_fid = hub.queues.prepare::<G>(queue_id_in);
|
let queues_fid = hub.queues.prepare::<G, markers::Queue>(queue_id_in);
|
||||||
|
|
||||||
let error = loop {
|
let error = loop {
|
||||||
let adapter = match hub.adapters.get(adapter_id) {
|
let adapter = match hub.adapters.get(adapter_id) {
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
command::ColorAttachmentError,
|
command::ColorAttachmentError,
|
||||||
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
|
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{ComputePipelineId, PipelineLayoutId, RenderPipelineId, ShaderModuleId},
|
id::{PipelineLayoutId, ShaderModuleId},
|
||||||
resource::{Resource, ResourceInfo, ResourceType},
|
resource::{Resource, ResourceInfo, ResourceType},
|
||||||
resource_log, validation, Label,
|
resource_log, validation, Label,
|
||||||
};
|
};
|
||||||
@ -50,7 +50,7 @@ pub struct ShaderModule<A: HalApi> {
|
|||||||
pub(crate) raw: Option<A::ShaderModule>,
|
pub(crate) raw: Option<A::ShaderModule>,
|
||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) interface: Option<validation::Interface>,
|
pub(crate) interface: Option<validation::Interface>,
|
||||||
pub(crate) info: ResourceInfo<ShaderModuleId>,
|
pub(crate) info: ResourceInfo<ShaderModule<A>>,
|
||||||
pub(crate) label: String,
|
pub(crate) label: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,14 +70,16 @@ impl<A: HalApi> Drop for ShaderModule<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<ShaderModuleId> for ShaderModule<A> {
|
impl<A: HalApi> Resource for ShaderModule<A> {
|
||||||
const TYPE: ResourceType = "ShaderModule";
|
const TYPE: ResourceType = "ShaderModule";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<ShaderModuleId> {
|
type Marker = crate::id::markers::ShaderModule;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<ShaderModuleId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +269,7 @@ pub struct ComputePipeline<A: HalApi> {
|
|||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) _shader_module: Arc<ShaderModule<A>>,
|
pub(crate) _shader_module: Arc<ShaderModule<A>>,
|
||||||
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
|
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
|
||||||
pub(crate) info: ResourceInfo<ComputePipelineId>,
|
pub(crate) info: ResourceInfo<ComputePipeline<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Drop for ComputePipeline<A> {
|
impl<A: HalApi> Drop for ComputePipeline<A> {
|
||||||
@ -288,14 +290,16 @@ impl<A: HalApi> Drop for ComputePipeline<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<ComputePipelineId> for ComputePipeline<A> {
|
impl<A: HalApi> Resource for ComputePipeline<A> {
|
||||||
const TYPE: ResourceType = "ComputePipeline";
|
const TYPE: ResourceType = "ComputePipeline";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<ComputePipelineId> {
|
type Marker = crate::id::markers::ComputePipeline;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<ComputePipelineId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,7 +519,7 @@ pub struct RenderPipeline<A: HalApi> {
|
|||||||
pub(crate) strip_index_format: Option<wgt::IndexFormat>,
|
pub(crate) strip_index_format: Option<wgt::IndexFormat>,
|
||||||
pub(crate) vertex_steps: Vec<VertexStep>,
|
pub(crate) vertex_steps: Vec<VertexStep>,
|
||||||
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
|
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
|
||||||
pub(crate) info: ResourceInfo<RenderPipelineId>,
|
pub(crate) info: ResourceInfo<RenderPipeline<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Drop for RenderPipeline<A> {
|
impl<A: HalApi> Drop for RenderPipeline<A> {
|
||||||
@ -536,14 +540,16 @@ impl<A: HalApi> Drop for RenderPipeline<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<RenderPipelineId> for RenderPipeline<A> {
|
impl<A: HalApi> Resource for RenderPipeline<A> {
|
||||||
const TYPE: ResourceType = "RenderPipeline";
|
const TYPE: ResourceType = "RenderPipeline";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<RenderPipelineId> {
|
type Marker = crate::id::markers::RenderPipeline;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<RenderPipelineId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ use crate::{
|
|||||||
global::Global,
|
global::Global,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
hal_label,
|
hal_label,
|
||||||
|
id::markers,
|
||||||
id::{SurfaceId, TextureId},
|
id::{SurfaceId, TextureId},
|
||||||
identity::{GlobalIdentityHandlerFactory, Input},
|
identity::{GlobalIdentityHandlerFactory, Input},
|
||||||
init_tracker::TextureInitTracker,
|
init_tracker::TextureInitTracker,
|
||||||
@ -125,13 +126,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
pub fn surface_get_current_texture<A: HalApi>(
|
pub fn surface_get_current_texture<A: HalApi>(
|
||||||
&self,
|
&self,
|
||||||
surface_id: SurfaceId,
|
surface_id: SurfaceId,
|
||||||
texture_id_in: Input<G, TextureId>,
|
texture_id_in: Input<G, markers::Texture>,
|
||||||
) -> Result<SurfaceOutput, SurfaceError> {
|
) -> Result<SurfaceOutput, SurfaceError> {
|
||||||
profiling::scope!("SwapChain::get_next_texture");
|
profiling::scope!("SwapChain::get_next_texture");
|
||||||
|
|
||||||
let hub = A::hub(self);
|
let hub = A::hub(self);
|
||||||
|
|
||||||
let fid = hub.textures.prepare::<G>(texture_id_in);
|
let fid = hub.textures.prepare::<G, _>(texture_id_in);
|
||||||
|
|
||||||
let surface = self
|
let surface = self
|
||||||
.surfaces
|
.surfaces
|
||||||
|
@ -4,7 +4,7 @@ use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
|||||||
use wgt::Backend;
|
use wgt::Backend;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
id,
|
id::{self, Id, Marker},
|
||||||
identity::{IdentityHandlerFactory, IdentityManager},
|
identity::{IdentityHandlerFactory, IdentityManager},
|
||||||
resource::Resource,
|
resource::Resource,
|
||||||
storage::{Element, InvalidId, Storage},
|
storage::{Element, InvalidId, Storage},
|
||||||
@ -37,14 +37,14 @@ impl RegistryReport {
|
|||||||
/// any other dependent resource
|
/// any other dependent resource
|
||||||
///
|
///
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Registry<I: id::TypedId, T: Resource<I>> {
|
pub struct Registry<T: Resource> {
|
||||||
identity: Arc<IdentityManager<I>>,
|
identity: Arc<IdentityManager<T::Marker>>,
|
||||||
storage: RwLock<Storage<T, I>>,
|
storage: RwLock<Storage<T>>,
|
||||||
backend: Backend,
|
backend: Backend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
impl<T: Resource> Registry<T> {
|
||||||
pub(crate) fn new<F: IdentityHandlerFactory<I>>(backend: Backend, factory: &F) -> Self {
|
pub(crate) fn new<F: IdentityHandlerFactory<T::Marker>>(backend: Backend, factory: &F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
identity: factory.spawn(),
|
identity: factory.spawn(),
|
||||||
storage: RwLock::new(Storage::new()),
|
storage: RwLock::new(Storage::new()),
|
||||||
@ -52,25 +52,25 @@ impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn without_backend<F: IdentityHandlerFactory<I>>(factory: &F) -> Self {
|
pub(crate) fn without_backend<F: IdentityHandlerFactory<T::Marker>>(factory: &F) -> Self {
|
||||||
Self::new(Backend::Empty, factory)
|
Self::new(Backend::Empty, factory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) struct FutureId<'a, I: id::TypedId, T: Resource<I>> {
|
pub(crate) struct FutureId<'a, T: Resource> {
|
||||||
id: I,
|
id: Id<T::Marker>,
|
||||||
identity: Arc<IdentityManager<I>>,
|
identity: Arc<IdentityManager<T::Marker>>,
|
||||||
data: &'a RwLock<Storage<T, I>>,
|
data: &'a RwLock<Storage<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: id::TypedId + Copy, T: Resource<I>> FutureId<'_, I, T> {
|
impl<T: Resource> FutureId<'_, T> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn id(&self) -> I {
|
pub fn id(&self) -> Id<T::Marker> {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_id(self) -> I {
|
pub fn into_id(self) -> Id<T::Marker> {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ impl<I: id::TypedId + Copy, T: Resource<I>> FutureId<'_, I, T> {
|
|||||||
/// Assign a new resource to this ID.
|
/// Assign a new resource to this ID.
|
||||||
///
|
///
|
||||||
/// Registers it with the registry, and fills out the resource info.
|
/// Registers it with the registry, and fills out the resource info.
|
||||||
pub fn assign(self, value: T) -> (I, Arc<T>) {
|
pub fn assign(self, value: T) -> (Id<T::Marker>, Arc<T>) {
|
||||||
let mut data = self.data.write();
|
let mut data = self.data.write();
|
||||||
data.insert(self.id, self.init(value));
|
data.insert(self.id, self.init(value));
|
||||||
(self.id, data.get(self.id).unwrap().clone())
|
(self.id, data.get(self.id).unwrap().clone())
|
||||||
@ -94,73 +94,76 @@ impl<I: id::TypedId + Copy, T: Resource<I>> FutureId<'_, I, T> {
|
|||||||
///
|
///
|
||||||
/// This _will_ leak the ID, and it will not be recycled again.
|
/// This _will_ leak the ID, and it will not be recycled again.
|
||||||
/// See https://github.com/gfx-rs/wgpu/issues/4912.
|
/// See https://github.com/gfx-rs/wgpu/issues/4912.
|
||||||
pub fn assign_existing(self, value: &Arc<T>) -> I {
|
pub fn assign_existing(self, value: &Arc<T>) -> Id<T::Marker> {
|
||||||
let mut data = self.data.write();
|
let mut data = self.data.write();
|
||||||
debug_assert!(!data.contains(self.id));
|
debug_assert!(!data.contains(self.id));
|
||||||
data.insert(self.id, value.clone());
|
data.insert(self.id, value.clone());
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_error(self, label: &str) -> I {
|
pub fn assign_error(self, label: &str) -> Id<T::Marker> {
|
||||||
self.data.write().insert_error(self.id, label);
|
self.data.write().insert_error(self.id, label);
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
impl<T: Resource> Registry<T> {
|
||||||
pub(crate) fn prepare<F>(&self, id_in: F::Input) -> FutureId<I, T>
|
pub(crate) fn prepare<F, U: Marker>(&self, id_in: F::Input) -> FutureId<T>
|
||||||
where
|
where
|
||||||
F: IdentityHandlerFactory<I>,
|
F: IdentityHandlerFactory<U>,
|
||||||
|
T::Marker: id::transmute::Transmute<U>,
|
||||||
{
|
{
|
||||||
FutureId {
|
FutureId {
|
||||||
id: if F::autogenerate_ids() {
|
id: if F::autogenerate_ids() {
|
||||||
self.identity.process(self.backend)
|
self.identity.process(self.backend)
|
||||||
} else {
|
} else {
|
||||||
self.identity.mark_as_used(F::input_to_id(id_in))
|
self.identity
|
||||||
|
.mark_as_used(F::input_to_id(id_in).transmute())
|
||||||
},
|
},
|
||||||
identity: self.identity.clone(),
|
identity: self.identity.clone(),
|
||||||
data: &self.storage,
|
data: &self.storage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn request(&self) -> FutureId<I, T> {
|
|
||||||
|
pub(crate) fn request(&self) -> FutureId<T> {
|
||||||
FutureId {
|
FutureId {
|
||||||
id: self.identity.process(self.backend),
|
id: self.identity.process(self.backend),
|
||||||
identity: self.identity.clone(),
|
identity: self.identity.clone(),
|
||||||
data: &self.storage,
|
data: &self.storage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn try_get(&self, id: I) -> Result<Option<Arc<T>>, InvalidId> {
|
pub(crate) fn try_get(&self, id: Id<T::Marker>) -> Result<Option<Arc<T>>, InvalidId> {
|
||||||
self.read().try_get(id).map(|o| o.cloned())
|
self.read().try_get(id).map(|o| o.cloned())
|
||||||
}
|
}
|
||||||
pub(crate) fn get(&self, id: I) -> Result<Arc<T>, InvalidId> {
|
pub(crate) fn get(&self, id: Id<T::Marker>) -> Result<Arc<T>, InvalidId> {
|
||||||
self.read().get_owned(id)
|
self.read().get_owned(id)
|
||||||
}
|
}
|
||||||
pub(crate) fn read<'a>(&'a self) -> RwLockReadGuard<'a, Storage<T, I>> {
|
pub(crate) fn read<'a>(&'a self) -> RwLockReadGuard<'a, Storage<T>> {
|
||||||
self.storage.read()
|
self.storage.read()
|
||||||
}
|
}
|
||||||
pub(crate) fn write<'a>(&'a self) -> RwLockWriteGuard<'a, Storage<T, I>> {
|
pub(crate) fn write<'a>(&'a self) -> RwLockWriteGuard<'a, Storage<T>> {
|
||||||
self.storage.write()
|
self.storage.write()
|
||||||
}
|
}
|
||||||
pub fn unregister_locked(&self, id: I, storage: &mut Storage<T, I>) -> Option<Arc<T>> {
|
pub fn unregister_locked(&self, id: Id<T::Marker>, storage: &mut Storage<T>) -> Option<Arc<T>> {
|
||||||
storage.remove(id)
|
storage.remove(id)
|
||||||
}
|
}
|
||||||
pub fn force_replace(&self, id: I, mut value: T) {
|
pub fn force_replace(&self, id: Id<T::Marker>, mut value: T) {
|
||||||
let mut storage = self.storage.write();
|
let mut storage = self.storage.write();
|
||||||
value.as_info_mut().set_id(id, &self.identity);
|
value.as_info_mut().set_id(id, &self.identity);
|
||||||
storage.force_replace(id, value)
|
storage.force_replace(id, value)
|
||||||
}
|
}
|
||||||
pub fn force_replace_with_error(&self, id: I, label: &str) {
|
pub fn force_replace_with_error(&self, id: Id<T::Marker>, label: &str) {
|
||||||
let mut storage = self.storage.write();
|
let mut storage = self.storage.write();
|
||||||
storage.remove(id);
|
storage.remove(id);
|
||||||
storage.insert_error(id, label);
|
storage.insert_error(id, label);
|
||||||
}
|
}
|
||||||
pub(crate) fn unregister(&self, id: I) -> Option<Arc<T>> {
|
pub(crate) fn unregister(&self, id: Id<T::Marker>) -> Option<Arc<T>> {
|
||||||
let value = self.storage.write().remove(id);
|
let value = self.storage.write().remove(id);
|
||||||
//Returning None is legal if it's an error ID
|
//Returning None is legal if it's an error ID
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn label_for_resource(&self, id: I) -> String {
|
pub fn label_for_resource(&self, id: Id<T::Marker>) -> String {
|
||||||
let guard = self.storage.read();
|
let guard = self.storage.read();
|
||||||
|
|
||||||
let type_name = guard.kind();
|
let type_name = guard.kind();
|
||||||
|
@ -8,10 +8,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
global::Global,
|
global::Global,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{
|
id::{AdapterId, BufferId, DeviceId, Id, Marker, SurfaceId, TextureId},
|
||||||
AdapterId, BufferId, DeviceId, QuerySetId, SamplerId, StagingBufferId, SurfaceId,
|
|
||||||
TextureId, TextureViewId, TypedId,
|
|
||||||
},
|
|
||||||
identity::{GlobalIdentityHandlerFactory, IdentityManager},
|
identity::{GlobalIdentityHandlerFactory, IdentityManager},
|
||||||
init_tracker::{BufferInitTracker, TextureInitTracker},
|
init_tracker::{BufferInitTracker, TextureInitTracker},
|
||||||
resource, resource_log,
|
resource, resource_log,
|
||||||
@ -59,9 +56,9 @@ use std::{
|
|||||||
/// [`Device`]: crate::device::resource::Device
|
/// [`Device`]: crate::device::resource::Device
|
||||||
/// [`Buffer`]: crate::resource::Buffer
|
/// [`Buffer`]: crate::resource::Buffer
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ResourceInfo<Id: TypedId> {
|
pub struct ResourceInfo<T: Resource> {
|
||||||
id: Option<Id>,
|
id: Option<Id<T::Marker>>,
|
||||||
identity: Option<Arc<IdentityManager<Id>>>,
|
identity: Option<Arc<IdentityManager<T::Marker>>>,
|
||||||
/// The index of the last queue submission in which the resource
|
/// The index of the last queue submission in which the resource
|
||||||
/// was used.
|
/// was used.
|
||||||
///
|
///
|
||||||
@ -75,7 +72,7 @@ pub struct ResourceInfo<Id: TypedId> {
|
|||||||
pub(crate) label: String,
|
pub(crate) label: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Id: TypedId> Drop for ResourceInfo<Id> {
|
impl<T: Resource> Drop for ResourceInfo<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(identity) = self.identity.as_ref() {
|
if let Some(identity) = self.identity.as_ref() {
|
||||||
let id = self.id.as_ref().unwrap();
|
let id = self.id.as_ref().unwrap();
|
||||||
@ -84,7 +81,7 @@ impl<Id: TypedId> Drop for ResourceInfo<Id> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Id: TypedId> ResourceInfo<Id> {
|
impl<T: Resource> ResourceInfo<T> {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub(crate) fn new(label: &str) -> Self {
|
pub(crate) fn new(label: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -97,7 +94,7 @@ impl<Id: TypedId> ResourceInfo<Id> {
|
|||||||
|
|
||||||
pub(crate) fn label(&self) -> &dyn Debug
|
pub(crate) fn label(&self) -> &dyn Debug
|
||||||
where
|
where
|
||||||
Id: Debug,
|
Id<T::Marker>: Debug,
|
||||||
{
|
{
|
||||||
if !self.label.is_empty() {
|
if !self.label.is_empty() {
|
||||||
return &self.label;
|
return &self.label;
|
||||||
@ -110,11 +107,11 @@ impl<Id: TypedId> ResourceInfo<Id> {
|
|||||||
&""
|
&""
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn id(&self) -> Id {
|
pub(crate) fn id(&self) -> Id<T::Marker> {
|
||||||
self.id.unwrap()
|
self.id.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_id(&mut self, id: Id, identity: &Arc<IdentityManager<Id>>) {
|
pub(crate) fn set_id(&mut self, id: Id<T::Marker>, identity: &Arc<IdentityManager<T::Marker>>) {
|
||||||
self.id = Some(id);
|
self.id = Some(id);
|
||||||
self.identity = Some(identity.clone());
|
self.identity = Some(identity.clone());
|
||||||
}
|
}
|
||||||
@ -133,10 +130,11 @@ impl<Id: TypedId> ResourceInfo<Id> {
|
|||||||
|
|
||||||
pub(crate) type ResourceType = &'static str;
|
pub(crate) type ResourceType = &'static str;
|
||||||
|
|
||||||
pub trait Resource<Id: TypedId>: 'static + WasmNotSendSync {
|
pub trait Resource: 'static + Sized + WasmNotSendSync {
|
||||||
|
type Marker: Marker;
|
||||||
const TYPE: ResourceType;
|
const TYPE: ResourceType;
|
||||||
fn as_info(&self) -> &ResourceInfo<Id>;
|
fn as_info(&self) -> &ResourceInfo<Self>;
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Id>;
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self>;
|
||||||
fn label(&self) -> String {
|
fn label(&self) -> String {
|
||||||
self.as_info().label.clone()
|
self.as_info().label.clone()
|
||||||
}
|
}
|
||||||
@ -377,7 +375,7 @@ pub struct Buffer<A: HalApi> {
|
|||||||
pub(crate) size: wgt::BufferAddress,
|
pub(crate) size: wgt::BufferAddress,
|
||||||
pub(crate) initialization_status: RwLock<BufferInitTracker>,
|
pub(crate) initialization_status: RwLock<BufferInitTracker>,
|
||||||
pub(crate) sync_mapped_writes: Mutex<Option<hal::MemoryRange>>,
|
pub(crate) sync_mapped_writes: Mutex<Option<hal::MemoryRange>>,
|
||||||
pub(crate) info: ResourceInfo<BufferId>,
|
pub(crate) info: ResourceInfo<Buffer<A>>,
|
||||||
pub(crate) map_state: Mutex<BufferMapState<A>>,
|
pub(crate) map_state: Mutex<BufferMapState<A>>,
|
||||||
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
||||||
}
|
}
|
||||||
@ -592,14 +590,16 @@ pub enum CreateBufferError {
|
|||||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<BufferId> for Buffer<A> {
|
impl<A: HalApi> Resource for Buffer<A> {
|
||||||
const TYPE: ResourceType = "Buffer";
|
const TYPE: ResourceType = "Buffer";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<BufferId> {
|
type Marker = crate::id::markers::Buffer;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BufferId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,7 +693,7 @@ pub struct StagingBuffer<A: HalApi> {
|
|||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) size: wgt::BufferAddress,
|
pub(crate) size: wgt::BufferAddress,
|
||||||
pub(crate) is_coherent: bool,
|
pub(crate) is_coherent: bool,
|
||||||
pub(crate) info: ResourceInfo<StagingBufferId>,
|
pub(crate) info: ResourceInfo<StagingBuffer<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Drop for StagingBuffer<A> {
|
impl<A: HalApi> Drop for StagingBuffer<A> {
|
||||||
@ -708,14 +708,16 @@ impl<A: HalApi> Drop for StagingBuffer<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<StagingBufferId> for StagingBuffer<A> {
|
impl<A: HalApi> Resource for StagingBuffer<A> {
|
||||||
const TYPE: ResourceType = "StagingBuffer";
|
const TYPE: ResourceType = "StagingBuffer";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<StagingBufferId> {
|
type Marker = crate::id::markers::StagingBuffer;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<StagingBufferId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,7 +775,7 @@ pub struct Texture<A: HalApi> {
|
|||||||
pub(crate) format_features: wgt::TextureFormatFeatures,
|
pub(crate) format_features: wgt::TextureFormatFeatures,
|
||||||
pub(crate) initialization_status: RwLock<TextureInitTracker>,
|
pub(crate) initialization_status: RwLock<TextureInitTracker>,
|
||||||
pub(crate) full_range: TextureSelector,
|
pub(crate) full_range: TextureSelector,
|
||||||
pub(crate) info: ResourceInfo<TextureId>,
|
pub(crate) info: ResourceInfo<Texture<A>>,
|
||||||
pub(crate) clear_mode: RwLock<TextureClearMode<A>>,
|
pub(crate) clear_mode: RwLock<TextureClearMode<A>>,
|
||||||
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
|
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
|
||||||
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
||||||
@ -1166,14 +1168,16 @@ pub enum CreateTextureError {
|
|||||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<TextureId> for Texture<A> {
|
impl<A: HalApi> Resource for Texture<A> {
|
||||||
const TYPE: ResourceType = "Texture";
|
const TYPE: ResourceType = "Texture";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<TextureId> {
|
type Marker = crate::id::markers::Texture;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<TextureId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1251,7 +1255,7 @@ pub struct TextureView<A: HalApi> {
|
|||||||
pub(crate) render_extent: Result<wgt::Extent3d, TextureViewNotRenderableReason>,
|
pub(crate) render_extent: Result<wgt::Extent3d, TextureViewNotRenderableReason>,
|
||||||
pub(crate) samples: u32,
|
pub(crate) samples: u32,
|
||||||
pub(crate) selector: TextureSelector,
|
pub(crate) selector: TextureSelector,
|
||||||
pub(crate) info: ResourceInfo<TextureViewId>,
|
pub(crate) info: ResourceInfo<TextureView<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Drop for TextureView<A> {
|
impl<A: HalApi> Drop for TextureView<A> {
|
||||||
@ -1329,14 +1333,16 @@ pub enum CreateTextureViewError {
|
|||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum TextureViewDestroyError {}
|
pub enum TextureViewDestroyError {}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<TextureViewId> for TextureView<A> {
|
impl<A: HalApi> Resource for TextureView<A> {
|
||||||
const TYPE: ResourceType = "TextureView";
|
const TYPE: ResourceType = "TextureView";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<TextureViewId> {
|
type Marker = crate::id::markers::TextureView;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<TextureViewId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1374,7 +1380,7 @@ pub struct SamplerDescriptor<'a> {
|
|||||||
pub struct Sampler<A: HalApi> {
|
pub struct Sampler<A: HalApi> {
|
||||||
pub(crate) raw: Option<A::Sampler>,
|
pub(crate) raw: Option<A::Sampler>,
|
||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) info: ResourceInfo<SamplerId>,
|
pub(crate) info: ResourceInfo<Self>,
|
||||||
/// `true` if this is a comparison sampler
|
/// `true` if this is a comparison sampler
|
||||||
pub(crate) comparison: bool,
|
pub(crate) comparison: bool,
|
||||||
/// `true` if this is a filtering sampler
|
/// `true` if this is a filtering sampler
|
||||||
@ -1448,14 +1454,16 @@ pub enum CreateSamplerError {
|
|||||||
MissingFeatures(#[from] MissingFeatures),
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<SamplerId> for Sampler<A> {
|
impl<A: HalApi> Resource for Sampler<A> {
|
||||||
const TYPE: ResourceType = "Sampler";
|
const TYPE: ResourceType = "Sampler";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<SamplerId> {
|
type Marker = crate::id::markers::Sampler;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<SamplerId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1479,7 +1487,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor<Label<'a>>;
|
|||||||
pub struct QuerySet<A: HalApi> {
|
pub struct QuerySet<A: HalApi> {
|
||||||
pub(crate) raw: Option<A::QuerySet>,
|
pub(crate) raw: Option<A::QuerySet>,
|
||||||
pub(crate) device: Arc<Device<A>>,
|
pub(crate) device: Arc<Device<A>>,
|
||||||
pub(crate) info: ResourceInfo<QuerySetId>,
|
pub(crate) info: ResourceInfo<Self>,
|
||||||
pub(crate) desc: wgt::QuerySetDescriptor<()>,
|
pub(crate) desc: wgt::QuerySetDescriptor<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,14 +1508,16 @@ impl<A: HalApi> Drop for QuerySet<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Resource<QuerySetId> for QuerySet<A> {
|
impl<A: HalApi> Resource for QuerySet<A> {
|
||||||
const TYPE: ResourceType = "QuerySet";
|
const TYPE: ResourceType = "QuerySet";
|
||||||
|
|
||||||
fn as_info(&self) -> &ResourceInfo<QuerySetId> {
|
type Marker = crate::id::markers::QuerySet;
|
||||||
|
|
||||||
|
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||||
&self.info
|
&self.info
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<QuerySetId> {
|
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||||
&mut self.info
|
&mut self.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use std::{marker::PhantomData, ops, sync::Arc};
|
use std::ops;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use wgt::Backend;
|
use wgt::Backend;
|
||||||
|
|
||||||
use crate::{id, resource::Resource, Epoch, Index};
|
use crate::id::Id;
|
||||||
|
use crate::resource::Resource;
|
||||||
|
use crate::{Epoch, Index};
|
||||||
|
|
||||||
/// An entry in a `Storage::map` table.
|
/// An entry in a `Storage::map` table.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -30,47 +33,41 @@ pub(crate) struct InvalidId;
|
|||||||
/// values, so you should use an id allocator like `IdentityManager`
|
/// values, so you should use an id allocator like `IdentityManager`
|
||||||
/// that keeps the index values dense and close to zero.
|
/// that keeps the index values dense and close to zero.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Storage<T, I>
|
pub struct Storage<T>
|
||||||
where
|
where
|
||||||
T: Resource<I>,
|
T: Resource,
|
||||||
I: id::TypedId,
|
|
||||||
{
|
{
|
||||||
pub(crate) map: Vec<Element<T>>,
|
pub(crate) map: Vec<Element<T>>,
|
||||||
kind: &'static str,
|
kind: &'static str,
|
||||||
_phantom: PhantomData<I>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, I> ops::Index<I> for Storage<T, I>
|
impl<T> ops::Index<Id<T::Marker>> for Storage<T>
|
||||||
where
|
where
|
||||||
T: Resource<I>,
|
T: Resource,
|
||||||
I: id::TypedId,
|
|
||||||
{
|
{
|
||||||
type Output = Arc<T>;
|
type Output = Arc<T>;
|
||||||
fn index(&self, id: I) -> &Arc<T> {
|
fn index(&self, id: Id<T::Marker>) -> &Arc<T> {
|
||||||
self.get(id).unwrap()
|
self.get(id).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T, I> Storage<T, I>
|
impl<T> Storage<T>
|
||||||
where
|
where
|
||||||
T: Resource<I>,
|
T: Resource,
|
||||||
I: id::TypedId,
|
|
||||||
{
|
{
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
map: Vec::new(),
|
map: Vec::new(),
|
||||||
kind: T::TYPE,
|
kind: T::TYPE,
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, I> Storage<T, I>
|
impl<T> Storage<T>
|
||||||
where
|
where
|
||||||
T: Resource<I>,
|
T: Resource,
|
||||||
I: id::TypedId,
|
|
||||||
{
|
{
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn contains(&self, id: I) -> bool {
|
pub(crate) fn contains(&self, id: Id<T::Marker>) -> bool {
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
match self.map.get(index as usize) {
|
match self.map.get(index as usize) {
|
||||||
Some(&Element::Vacant) => false,
|
Some(&Element::Vacant) => false,
|
||||||
@ -88,7 +85,7 @@ where
|
|||||||
/// This function is primarily intended for the `as_hal` family of functions
|
/// This function is primarily intended for the `as_hal` family of functions
|
||||||
/// where you may need to fallibly get a object backed by an id that could
|
/// where you may need to fallibly get a object backed by an id that could
|
||||||
/// be in a different hub.
|
/// be in a different hub.
|
||||||
pub(crate) fn try_get(&self, id: I) -> Result<Option<&Arc<T>>, InvalidId> {
|
pub(crate) fn try_get(&self, id: Id<T::Marker>) -> Result<Option<&Arc<T>>, InvalidId> {
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
let (result, storage_epoch) = match self.map.get(index as usize) {
|
let (result, storage_epoch) = match self.map.get(index as usize) {
|
||||||
Some(&Element::Occupied(ref v, epoch)) => (Ok(Some(v)), epoch),
|
Some(&Element::Occupied(ref v, epoch)) => (Ok(Some(v)), epoch),
|
||||||
@ -106,7 +103,7 @@ where
|
|||||||
|
|
||||||
/// Get a reference to an item behind a potentially invalid ID.
|
/// Get a reference to an item behind a potentially invalid ID.
|
||||||
/// Panics if there is an epoch mismatch, or the entry is empty.
|
/// Panics if there is an epoch mismatch, or the entry is empty.
|
||||||
pub(crate) fn get(&self, id: I) -> Result<&Arc<T>, InvalidId> {
|
pub(crate) fn get(&self, id: Id<T::Marker>) -> Result<&Arc<T>, InvalidId> {
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
let (result, storage_epoch) = match self.map.get(index as usize) {
|
let (result, storage_epoch) = match self.map.get(index as usize) {
|
||||||
Some(&Element::Occupied(ref v, epoch)) => (Ok(v), epoch),
|
Some(&Element::Occupied(ref v, epoch)) => (Ok(v), epoch),
|
||||||
@ -124,11 +121,11 @@ where
|
|||||||
|
|
||||||
/// Get an owned reference to an item behind a potentially invalid ID.
|
/// Get an owned reference to an item behind a potentially invalid ID.
|
||||||
/// Panics if there is an epoch mismatch, or the entry is empty.
|
/// Panics if there is an epoch mismatch, or the entry is empty.
|
||||||
pub(crate) fn get_owned(&self, id: I) -> Result<Arc<T>, InvalidId> {
|
pub(crate) fn get_owned(&self, id: Id<T::Marker>) -> Result<Arc<T>, InvalidId> {
|
||||||
Ok(Arc::clone(self.get(id)?))
|
Ok(Arc::clone(self.get(id)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn label_for_invalid_id(&self, id: I) -> &str {
|
pub(crate) fn label_for_invalid_id(&self, id: Id<T::Marker>) -> &str {
|
||||||
let (index, _, _) = id.unzip();
|
let (index, _, _) = id.unzip();
|
||||||
match self.map.get(index as usize) {
|
match self.map.get(index as usize) {
|
||||||
Some(Element::Error(_, label)) => label,
|
Some(Element::Error(_, label)) => label,
|
||||||
@ -161,13 +158,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn insert(&mut self, id: I, value: Arc<T>) {
|
pub(crate) fn insert(&mut self, id: Id<T::Marker>, value: Arc<T>) {
|
||||||
log::trace!("User is inserting {}{:?}", T::TYPE, id);
|
log::trace!("User is inserting {}{:?}", T::TYPE, id);
|
||||||
let (index, epoch, _backend) = id.unzip();
|
let (index, epoch, _backend) = id.unzip();
|
||||||
self.insert_impl(index as usize, epoch, Element::Occupied(value, epoch))
|
self.insert_impl(index as usize, epoch, Element::Occupied(value, epoch))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn insert_error(&mut self, id: I, label: &str) {
|
pub(crate) fn insert_error(&mut self, id: Id<T::Marker>, label: &str) {
|
||||||
log::trace!("User is insering as error {}{:?}", T::TYPE, id);
|
log::trace!("User is insering as error {}{:?}", T::TYPE, id);
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
self.insert_impl(
|
self.insert_impl(
|
||||||
@ -177,7 +174,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn replace_with_error(&mut self, id: I) -> Result<Arc<T>, InvalidId> {
|
pub(crate) fn replace_with_error(&mut self, id: Id<T::Marker>) -> Result<Arc<T>, InvalidId> {
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
match std::mem::replace(
|
match std::mem::replace(
|
||||||
&mut self.map[index as usize],
|
&mut self.map[index as usize],
|
||||||
@ -192,13 +189,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn force_replace(&mut self, id: I, value: T) {
|
pub(crate) fn force_replace(&mut self, id: Id<T::Marker>, value: T) {
|
||||||
log::trace!("User is replacing {}{:?}", T::TYPE, id);
|
log::trace!("User is replacing {}{:?}", T::TYPE, id);
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
self.map[index as usize] = Element::Occupied(Arc::new(value), epoch);
|
self.map[index as usize] = Element::Occupied(Arc::new(value), epoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove(&mut self, id: I) -> Option<Arc<T>> {
|
pub(crate) fn remove(&mut self, id: Id<T::Marker>) -> Option<Arc<T>> {
|
||||||
log::trace!("User is removing {}{:?}", T::TYPE, id);
|
log::trace!("User is removing {}{:?}", T::TYPE, id);
|
||||||
let (index, epoch, _) = id.unzip();
|
let (index, epoch, _) = id.unzip();
|
||||||
match std::mem::replace(&mut self.map[index as usize], Element::Vacant) {
|
match std::mem::replace(&mut self.map[index as usize], Element::Vacant) {
|
||||||
@ -211,13 +208,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn iter(&self, backend: Backend) -> impl Iterator<Item = (I, &Arc<T>)> {
|
pub(crate) fn iter(&self, backend: Backend) -> impl Iterator<Item = (Id<T::Marker>, &Arc<T>)> {
|
||||||
self.map
|
self.map
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(move |(index, x)| match *x {
|
.filter_map(move |(index, x)| match *x {
|
||||||
Element::Occupied(ref value, storage_epoch) => {
|
Element::Occupied(ref value, storage_epoch) => {
|
||||||
Some((I::zip(index as Index, storage_epoch, backend), value))
|
Some((Id::zip(index as Index, storage_epoch, backend), value))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
@ -10,7 +10,7 @@ use std::{borrow::Cow, marker::PhantomData, sync::Arc};
|
|||||||
use super::{PendingTransition, ResourceTracker};
|
use super::{PendingTransition, ResourceTracker};
|
||||||
use crate::{
|
use crate::{
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{BufferId, TypedId},
|
id::BufferId,
|
||||||
resource::{Buffer, Resource},
|
resource::{Buffer, Resource},
|
||||||
snatch::SnatchGuard,
|
snatch::SnatchGuard,
|
||||||
storage::Storage,
|
storage::Storage,
|
||||||
@ -26,7 +26,6 @@ use wgt::{strict_assert, strict_assert_eq};
|
|||||||
impl ResourceUses for BufferUses {
|
impl ResourceUses for BufferUses {
|
||||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||||
|
|
||||||
type Id = BufferId;
|
|
||||||
type Selector = ();
|
type Selector = ();
|
||||||
|
|
||||||
fn bits(self) -> u16 {
|
fn bits(self) -> u16 {
|
||||||
@ -92,7 +91,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
|
|||||||
/// Adds the given resource with the given state.
|
/// Adds the given resource with the given state.
|
||||||
pub fn add_single<'a>(
|
pub fn add_single<'a>(
|
||||||
&self,
|
&self,
|
||||||
storage: &'a Storage<Buffer<A>, BufferId>,
|
storage: &'a Storage<Buffer<A>>,
|
||||||
id: BufferId,
|
id: BufferId,
|
||||||
state: BufferUses,
|
state: BufferUses,
|
||||||
) -> Option<&'a Arc<Buffer<A>>> {
|
) -> Option<&'a Arc<Buffer<A>>> {
|
||||||
@ -110,7 +109,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
|
|||||||
pub(crate) struct BufferUsageScope<A: HalApi> {
|
pub(crate) struct BufferUsageScope<A: HalApi> {
|
||||||
state: Vec<BufferUses>,
|
state: Vec<BufferUses>,
|
||||||
|
|
||||||
metadata: ResourceMetadata<A, BufferId, Buffer<A>>,
|
metadata: ResourceMetadata<A, Buffer<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> BufferUsageScope<A> {
|
impl<A: HalApi> BufferUsageScope<A> {
|
||||||
@ -248,7 +247,7 @@ impl<A: HalApi> BufferUsageScope<A> {
|
|||||||
/// the vectors will be extended. A call to set_size is not needed.
|
/// the vectors will be extended. A call to set_size is not needed.
|
||||||
pub fn merge_single<'a>(
|
pub fn merge_single<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
storage: &'a Storage<Buffer<A>, BufferId>,
|
storage: &'a Storage<Buffer<A>>,
|
||||||
id: BufferId,
|
id: BufferId,
|
||||||
new_state: BufferUses,
|
new_state: BufferUses,
|
||||||
) -> Result<&'a Arc<Buffer<A>>, UsageConflict> {
|
) -> Result<&'a Arc<Buffer<A>>, UsageConflict> {
|
||||||
@ -288,12 +287,12 @@ pub(crate) struct BufferTracker<A: HalApi> {
|
|||||||
start: Vec<BufferUses>,
|
start: Vec<BufferUses>,
|
||||||
end: Vec<BufferUses>,
|
end: Vec<BufferUses>,
|
||||||
|
|
||||||
metadata: ResourceMetadata<A, BufferId, Buffer<A>>,
|
metadata: ResourceMetadata<A, Buffer<A>>,
|
||||||
|
|
||||||
temp: Vec<PendingTransition<BufferUses>>,
|
temp: Vec<PendingTransition<BufferUses>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> ResourceTracker<BufferId, Buffer<A>> for BufferTracker<A> {
|
impl<A: HalApi> ResourceTracker<Buffer<A>> for BufferTracker<A> {
|
||||||
/// Try to remove the buffer `id` from this tracker if it is otherwise unused.
|
/// Try to remove the buffer `id` from this tracker if it is otherwise unused.
|
||||||
///
|
///
|
||||||
/// A buffer is 'otherwise unused' when the only references to it are:
|
/// A buffer is 'otherwise unused' when the only references to it are:
|
||||||
@ -654,11 +653,11 @@ impl BufferStateProvider<'_> {
|
|||||||
unsafe fn insert_or_merge<A: HalApi>(
|
unsafe fn insert_or_merge<A: HalApi>(
|
||||||
start_states: Option<&mut [BufferUses]>,
|
start_states: Option<&mut [BufferUses]>,
|
||||||
current_states: &mut [BufferUses],
|
current_states: &mut [BufferUses],
|
||||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||||
index32: u32,
|
index32: u32,
|
||||||
index: usize,
|
index: usize,
|
||||||
state_provider: BufferStateProvider<'_>,
|
state_provider: BufferStateProvider<'_>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||||
) -> Result<(), UsageConflict> {
|
) -> Result<(), UsageConflict> {
|
||||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||||
|
|
||||||
@ -709,11 +708,11 @@ unsafe fn insert_or_merge<A: HalApi>(
|
|||||||
unsafe fn insert_or_barrier_update<A: HalApi>(
|
unsafe fn insert_or_barrier_update<A: HalApi>(
|
||||||
start_states: Option<&mut [BufferUses]>,
|
start_states: Option<&mut [BufferUses]>,
|
||||||
current_states: &mut [BufferUses],
|
current_states: &mut [BufferUses],
|
||||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||||
index: usize,
|
index: usize,
|
||||||
start_state_provider: BufferStateProvider<'_>,
|
start_state_provider: BufferStateProvider<'_>,
|
||||||
end_state_provider: Option<BufferStateProvider<'_>>,
|
end_state_provider: Option<BufferStateProvider<'_>>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||||
barriers: &mut Vec<PendingTransition<BufferUses>>,
|
barriers: &mut Vec<PendingTransition<BufferUses>>,
|
||||||
) {
|
) {
|
||||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||||
@ -743,11 +742,11 @@ unsafe fn insert_or_barrier_update<A: HalApi>(
|
|||||||
unsafe fn insert<A: HalApi>(
|
unsafe fn insert<A: HalApi>(
|
||||||
start_states: Option<&mut [BufferUses]>,
|
start_states: Option<&mut [BufferUses]>,
|
||||||
current_states: &mut [BufferUses],
|
current_states: &mut [BufferUses],
|
||||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||||
index: usize,
|
index: usize,
|
||||||
start_state_provider: BufferStateProvider<'_>,
|
start_state_provider: BufferStateProvider<'_>,
|
||||||
end_state_provider: Option<BufferStateProvider<'_>>,
|
end_state_provider: Option<BufferStateProvider<'_>>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||||
) {
|
) {
|
||||||
let new_start_state = unsafe { start_state_provider.get_state(index) };
|
let new_start_state = unsafe { start_state_provider.get_state(index) };
|
||||||
let new_end_state =
|
let new_end_state =
|
||||||
@ -777,7 +776,7 @@ unsafe fn merge<A: HalApi>(
|
|||||||
index32: u32,
|
index32: u32,
|
||||||
index: usize,
|
index: usize,
|
||||||
state_provider: BufferStateProvider<'_>,
|
state_provider: BufferStateProvider<'_>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||||
) -> Result<(), UsageConflict> {
|
) -> Result<(), UsageConflict> {
|
||||||
let current_state = unsafe { current_states.get_unchecked_mut(index) };
|
let current_state = unsafe { current_states.get_unchecked_mut(index) };
|
||||||
let new_state = unsafe { state_provider.get_state(index) };
|
let new_state = unsafe { state_provider.get_state(index) };
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! The `ResourceMetadata` type.
|
//! The `ResourceMetadata` type.
|
||||||
|
|
||||||
use crate::{hal_api::HalApi, id::TypedId, resource::Resource, Epoch};
|
use crate::{hal_api::HalApi, resource::Resource, Epoch};
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use std::{borrow::Cow, marker::PhantomData, mem, sync::Arc};
|
use std::{borrow::Cow, marker::PhantomData, mem, sync::Arc};
|
||||||
use wgt::strict_assert;
|
use wgt::strict_assert;
|
||||||
@ -13,7 +13,7 @@ use wgt::strict_assert;
|
|||||||
/// members, but a bit vector tracks occupancy, so iteration touches
|
/// members, but a bit vector tracks occupancy, so iteration touches
|
||||||
/// only occupied elements.
|
/// only occupied elements.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct ResourceMetadata<A: HalApi, I: TypedId, T: Resource<I>> {
|
pub(super) struct ResourceMetadata<A: HalApi, T: Resource> {
|
||||||
/// If the resource with index `i` is a member, `owned[i]` is `true`.
|
/// If the resource with index `i` is a member, `owned[i]` is `true`.
|
||||||
owned: BitVec<usize>,
|
owned: BitVec<usize>,
|
||||||
|
|
||||||
@ -21,10 +21,10 @@ pub(super) struct ResourceMetadata<A: HalApi, I: TypedId, T: Resource<I>> {
|
|||||||
resources: Vec<Option<Arc<T>>>,
|
resources: Vec<Option<Arc<T>>>,
|
||||||
|
|
||||||
/// This tells Rust that this type should be covariant with `A`.
|
/// This tells Rust that this type should be covariant with `A`.
|
||||||
_phantom: PhantomData<(A, I)>,
|
_phantom: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi, I: TypedId, T: Resource<I>> ResourceMetadata<A, I, T> {
|
impl<A: HalApi, T: Resource> ResourceMetadata<A, T> {
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
owned: BitVec::default(),
|
owned: BitVec::default(),
|
||||||
@ -172,15 +172,15 @@ impl<A: HalApi, I: TypedId, T: Resource<I>> ResourceMetadata<A, I, T> {
|
|||||||
///
|
///
|
||||||
/// This is used to abstract over the various places
|
/// This is used to abstract over the various places
|
||||||
/// trackers can get new resource metadata from.
|
/// trackers can get new resource metadata from.
|
||||||
pub(super) enum ResourceMetadataProvider<'a, A: HalApi, I: TypedId, T: Resource<I>> {
|
pub(super) enum ResourceMetadataProvider<'a, A: HalApi, T: Resource> {
|
||||||
/// Comes directly from explicit values.
|
/// Comes directly from explicit values.
|
||||||
Direct { resource: Cow<'a, Arc<T>> },
|
Direct { resource: Cow<'a, Arc<T>> },
|
||||||
/// Comes from another metadata tracker.
|
/// Comes from another metadata tracker.
|
||||||
Indirect {
|
Indirect {
|
||||||
metadata: &'a ResourceMetadata<A, I, T>,
|
metadata: &'a ResourceMetadata<A, T>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
impl<A: HalApi, I: TypedId, T: Resource<I>> ResourceMetadataProvider<'_, A, I, T> {
|
impl<A: HalApi, T: Resource> ResourceMetadataProvider<'_, A, T> {
|
||||||
/// Get the epoch and an owned refcount from this.
|
/// Get the epoch and an owned refcount from this.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
@ -104,7 +104,7 @@ mod texture;
|
|||||||
use crate::{
|
use crate::{
|
||||||
binding_model, command, conv,
|
binding_model, command, conv,
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{self, TypedId},
|
id::{self, Id},
|
||||||
pipeline, resource,
|
pipeline, resource,
|
||||||
snatch::SnatchGuard,
|
snatch::SnatchGuard,
|
||||||
storage::Storage,
|
storage::Storage,
|
||||||
@ -182,8 +182,6 @@ pub(crate) trait ResourceUses:
|
|||||||
/// All flags that are exclusive.
|
/// All flags that are exclusive.
|
||||||
const EXCLUSIVE: Self;
|
const EXCLUSIVE: Self;
|
||||||
|
|
||||||
/// The relevant resource ID type.
|
|
||||||
type Id: Copy + fmt::Debug + TypedId;
|
|
||||||
/// The selector used by this resource.
|
/// The selector used by this resource.
|
||||||
type Selector: fmt::Debug;
|
type Selector: fmt::Debug;
|
||||||
|
|
||||||
@ -320,8 +318,8 @@ impl<T: ResourceUses> fmt::Display for InvalidUse<T> {
|
|||||||
pub(crate) struct BindGroupStates<A: HalApi> {
|
pub(crate) struct BindGroupStates<A: HalApi> {
|
||||||
pub buffers: BufferBindGroupState<A>,
|
pub buffers: BufferBindGroupState<A>,
|
||||||
pub textures: TextureBindGroupState<A>,
|
pub textures: TextureBindGroupState<A>,
|
||||||
pub views: StatelessBindGroupSate<id::TextureViewId, resource::TextureView<A>>,
|
pub views: StatelessBindGroupSate<resource::TextureView<A>>,
|
||||||
pub samplers: StatelessBindGroupSate<id::SamplerId, resource::Sampler<A>>,
|
pub samplers: StatelessBindGroupSate<resource::Sampler<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> BindGroupStates<A> {
|
impl<A: HalApi> BindGroupStates<A> {
|
||||||
@ -354,20 +352,19 @@ pub(crate) struct RenderBundleScope<A: HalApi> {
|
|||||||
pub buffers: RwLock<BufferUsageScope<A>>,
|
pub buffers: RwLock<BufferUsageScope<A>>,
|
||||||
pub textures: RwLock<TextureUsageScope<A>>,
|
pub textures: RwLock<TextureUsageScope<A>>,
|
||||||
// Don't need to track views and samplers, they are never used directly, only by bind groups.
|
// Don't need to track views and samplers, they are never used directly, only by bind groups.
|
||||||
pub bind_groups: RwLock<StatelessTracker<A, id::BindGroupId, binding_model::BindGroup<A>>>,
|
pub bind_groups: RwLock<StatelessTracker<A, binding_model::BindGroup<A>>>,
|
||||||
pub render_pipelines:
|
pub render_pipelines: RwLock<StatelessTracker<A, pipeline::RenderPipeline<A>>>,
|
||||||
RwLock<StatelessTracker<A, id::RenderPipelineId, pipeline::RenderPipeline<A>>>,
|
pub query_sets: RwLock<StatelessTracker<A, resource::QuerySet<A>>>,
|
||||||
pub query_sets: RwLock<StatelessTracker<A, id::QuerySetId, resource::QuerySet<A>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> RenderBundleScope<A> {
|
impl<A: HalApi> RenderBundleScope<A> {
|
||||||
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
buffers: &Storage<resource::Buffer<A>, id::BufferId>,
|
buffers: &Storage<resource::Buffer<A>>,
|
||||||
textures: &Storage<resource::Texture<A>, id::TextureId>,
|
textures: &Storage<resource::Texture<A>>,
|
||||||
bind_groups: &Storage<binding_model::BindGroup<A>, id::BindGroupId>,
|
bind_groups: &Storage<binding_model::BindGroup<A>>,
|
||||||
render_pipelines: &Storage<pipeline::RenderPipeline<A>, id::RenderPipelineId>,
|
render_pipelines: &Storage<pipeline::RenderPipeline<A>>,
|
||||||
query_sets: &Storage<resource::QuerySet<A>, id::QuerySetId>,
|
query_sets: &Storage<resource::QuerySet<A>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let value = Self {
|
let value = Self {
|
||||||
buffers: RwLock::new(BufferUsageScope::new()),
|
buffers: RwLock::new(BufferUsageScope::new()),
|
||||||
@ -424,8 +421,8 @@ pub(crate) struct UsageScope<A: HalApi> {
|
|||||||
impl<A: HalApi> UsageScope<A> {
|
impl<A: HalApi> UsageScope<A> {
|
||||||
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
buffers: &Storage<resource::Buffer<A>, id::BufferId>,
|
buffers: &Storage<resource::Buffer<A>>,
|
||||||
textures: &Storage<resource::Texture<A>, id::TextureId>,
|
textures: &Storage<resource::Texture<A>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut value = Self {
|
let mut value = Self {
|
||||||
buffers: BufferUsageScope::new(),
|
buffers: BufferUsageScope::new(),
|
||||||
@ -481,25 +478,24 @@ impl<A: HalApi> UsageScope<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait ResourceTracker<Id, R>
|
pub(crate) trait ResourceTracker<R>
|
||||||
where
|
where
|
||||||
Id: TypedId,
|
R: resource::Resource,
|
||||||
R: resource::Resource<Id>,
|
|
||||||
{
|
{
|
||||||
fn remove_abandoned(&mut self, id: Id) -> bool;
|
fn remove_abandoned(&mut self, id: Id<R::Marker>) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A full double sided tracker used by CommandBuffers and the Device.
|
/// A full double sided tracker used by CommandBuffers and the Device.
|
||||||
pub(crate) struct Tracker<A: HalApi> {
|
pub(crate) struct Tracker<A: HalApi> {
|
||||||
pub buffers: BufferTracker<A>,
|
pub buffers: BufferTracker<A>,
|
||||||
pub textures: TextureTracker<A>,
|
pub textures: TextureTracker<A>,
|
||||||
pub views: StatelessTracker<A, id::TextureViewId, resource::TextureView<A>>,
|
pub views: StatelessTracker<A, resource::TextureView<A>>,
|
||||||
pub samplers: StatelessTracker<A, id::SamplerId, resource::Sampler<A>>,
|
pub samplers: StatelessTracker<A, resource::Sampler<A>>,
|
||||||
pub bind_groups: StatelessTracker<A, id::BindGroupId, binding_model::BindGroup<A>>,
|
pub bind_groups: StatelessTracker<A, binding_model::BindGroup<A>>,
|
||||||
pub compute_pipelines: StatelessTracker<A, id::ComputePipelineId, pipeline::ComputePipeline<A>>,
|
pub compute_pipelines: StatelessTracker<A, pipeline::ComputePipeline<A>>,
|
||||||
pub render_pipelines: StatelessTracker<A, id::RenderPipelineId, pipeline::RenderPipeline<A>>,
|
pub render_pipelines: StatelessTracker<A, pipeline::RenderPipeline<A>>,
|
||||||
pub bundles: StatelessTracker<A, id::RenderBundleId, command::RenderBundle<A>>,
|
pub bundles: StatelessTracker<A, command::RenderBundle<A>>,
|
||||||
pub query_sets: StatelessTracker<A, id::QuerySetId, resource::QuerySet<A>>,
|
pub query_sets: StatelessTracker<A, resource::QuerySet<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> Tracker<A> {
|
impl<A: HalApi> Tracker<A> {
|
||||||
@ -520,15 +516,15 @@ impl<A: HalApi> Tracker<A> {
|
|||||||
/// Pull the maximum IDs from the hubs.
|
/// Pull the maximum IDs from the hubs.
|
||||||
pub fn set_size(
|
pub fn set_size(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffers: Option<&Storage<resource::Buffer<A>, id::BufferId>>,
|
buffers: Option<&Storage<resource::Buffer<A>>>,
|
||||||
textures: Option<&Storage<resource::Texture<A>, id::TextureId>>,
|
textures: Option<&Storage<resource::Texture<A>>>,
|
||||||
views: Option<&Storage<resource::TextureView<A>, id::TextureViewId>>,
|
views: Option<&Storage<resource::TextureView<A>>>,
|
||||||
samplers: Option<&Storage<resource::Sampler<A>, id::SamplerId>>,
|
samplers: Option<&Storage<resource::Sampler<A>>>,
|
||||||
bind_groups: Option<&Storage<binding_model::BindGroup<A>, id::BindGroupId>>,
|
bind_groups: Option<&Storage<binding_model::BindGroup<A>>>,
|
||||||
compute_pipelines: Option<&Storage<pipeline::ComputePipeline<A>, id::ComputePipelineId>>,
|
compute_pipelines: Option<&Storage<pipeline::ComputePipeline<A>>>,
|
||||||
render_pipelines: Option<&Storage<pipeline::RenderPipeline<A>, id::RenderPipelineId>>,
|
render_pipelines: Option<&Storage<pipeline::RenderPipeline<A>>>,
|
||||||
bundles: Option<&Storage<command::RenderBundle<A>, id::RenderBundleId>>,
|
bundles: Option<&Storage<command::RenderBundle<A>>>,
|
||||||
query_sets: Option<&Storage<resource::QuerySet<A>, id::QuerySetId>>,
|
query_sets: Option<&Storage<resource::QuerySet<A>>>,
|
||||||
) {
|
) {
|
||||||
if let Some(buffers) = buffers {
|
if let Some(buffers) = buffers {
|
||||||
self.buffers.set_size(buffers.len());
|
self.buffers.set_size(buffers.len());
|
||||||
|
@ -4,24 +4,27 @@
|
|||||||
* distinction between a usage scope and a full tracker.
|
* distinction between a usage scope and a full tracker.
|
||||||
!*/
|
!*/
|
||||||
|
|
||||||
use std::{marker::PhantomData, sync::Arc};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
hal_api::HalApi, id::TypedId, resource::Resource, resource_log, storage::Storage,
|
hal_api::HalApi, id::Id, resource::Resource, resource_log, storage::Storage,
|
||||||
track::ResourceMetadata,
|
track::ResourceMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ResourceTracker;
|
use super::ResourceTracker;
|
||||||
|
|
||||||
|
/// Satisfy clippy.
|
||||||
|
type Pair<T> = (Id<<T as Resource>::Marker>, Arc<T>);
|
||||||
|
|
||||||
/// Stores all the resources that a bind group stores.
|
/// Stores all the resources that a bind group stores.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct StatelessBindGroupSate<Id: TypedId, T: Resource<Id>> {
|
pub(crate) struct StatelessBindGroupSate<T: Resource> {
|
||||||
resources: Mutex<Vec<(Id, Arc<T>)>>,
|
resources: Mutex<Vec<Pair<T>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Id: TypedId, T: Resource<Id>> StatelessBindGroupSate<Id, T> {
|
impl<T: Resource> StatelessBindGroupSate<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
resources: Mutex::new(Vec::new()),
|
resources: Mutex::new(Vec::new()),
|
||||||
@ -58,7 +61,7 @@ impl<Id: TypedId, T: Resource<Id>> StatelessBindGroupSate<Id, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds the given resource.
|
/// Adds the given resource.
|
||||||
pub fn add_single<'a>(&self, storage: &'a Storage<T, Id>, id: Id) -> Option<&'a T> {
|
pub fn add_single<'a>(&self, storage: &'a Storage<T>, id: Id<T::Marker>) -> Option<&'a T> {
|
||||||
let resource = storage.get(id).ok()?;
|
let resource = storage.get(id).ok()?;
|
||||||
|
|
||||||
let mut resources = self.resources.lock();
|
let mut resources = self.resources.lock();
|
||||||
@ -70,14 +73,11 @@ impl<Id: TypedId, T: Resource<Id>> StatelessBindGroupSate<Id, T> {
|
|||||||
|
|
||||||
/// Stores all resource state within a command buffer or device.
|
/// Stores all resource state within a command buffer or device.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct StatelessTracker<A: HalApi, Id: TypedId, T: Resource<Id>> {
|
pub(crate) struct StatelessTracker<A: HalApi, T: Resource> {
|
||||||
metadata: ResourceMetadata<A, Id, T>,
|
metadata: ResourceMetadata<A, T>,
|
||||||
_phantom: PhantomData<Id>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi, Id: TypedId, T: Resource<Id>> ResourceTracker<Id, T>
|
impl<A: HalApi, T: Resource> ResourceTracker<T> for StatelessTracker<A, T> {
|
||||||
for StatelessTracker<A, Id, T>
|
|
||||||
{
|
|
||||||
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
||||||
/// resource and the epoch matches.
|
/// resource and the epoch matches.
|
||||||
///
|
///
|
||||||
@ -85,7 +85,7 @@ impl<A: HalApi, Id: TypedId, T: Resource<Id>> ResourceTracker<Id, T>
|
|||||||
///
|
///
|
||||||
/// If the ID is higher than the length of internal vectors,
|
/// If the ID is higher than the length of internal vectors,
|
||||||
/// false will be returned.
|
/// false will be returned.
|
||||||
fn remove_abandoned(&mut self, id: Id) -> bool {
|
fn remove_abandoned(&mut self, id: Id<T::Marker>) -> bool {
|
||||||
let index = id.unzip().0 as usize;
|
let index = id.unzip().0 as usize;
|
||||||
|
|
||||||
if index >= self.metadata.size() {
|
if index >= self.metadata.size() {
|
||||||
@ -120,11 +120,10 @@ impl<A: HalApi, Id: TypedId, T: Resource<Id>> ResourceTracker<Id, T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi, Id: TypedId, T: Resource<Id>> StatelessTracker<A, Id, T> {
|
impl<A: HalApi, T: Resource> StatelessTracker<A, T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
metadata: ResourceMetadata::new(),
|
metadata: ResourceMetadata::new(),
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +163,7 @@ impl<A: HalApi, Id: TypedId, T: Resource<Id>> StatelessTracker<A, Id, T> {
|
|||||||
///
|
///
|
||||||
/// If the ID is higher than the length of internal vectors,
|
/// If the ID is higher than the length of internal vectors,
|
||||||
/// the vectors will be extended. A call to set_size is not needed.
|
/// the vectors will be extended. A call to set_size is not needed.
|
||||||
pub fn insert_single(&mut self, id: Id, resource: Arc<T>) {
|
pub fn insert_single(&mut self, id: Id<T::Marker>, resource: Arc<T>) {
|
||||||
let (index32, _epoch, _) = id.unzip();
|
let (index32, _epoch, _) = id.unzip();
|
||||||
let index = index32 as usize;
|
let index = index32 as usize;
|
||||||
|
|
||||||
@ -181,7 +180,11 @@ impl<A: HalApi, Id: TypedId, T: Resource<Id>> StatelessTracker<A, Id, T> {
|
|||||||
///
|
///
|
||||||
/// If the ID is higher than the length of internal vectors,
|
/// If the ID is higher than the length of internal vectors,
|
||||||
/// the vectors will be extended. A call to set_size is not needed.
|
/// the vectors will be extended. A call to set_size is not needed.
|
||||||
pub fn add_single<'a>(&mut self, storage: &'a Storage<T, Id>, id: Id) -> Option<&'a Arc<T>> {
|
pub fn add_single<'a>(
|
||||||
|
&mut self,
|
||||||
|
storage: &'a Storage<T>,
|
||||||
|
id: Id<T::Marker>,
|
||||||
|
) -> Option<&'a Arc<T>> {
|
||||||
let resource = storage.get(id).ok()?;
|
let resource = storage.get(id).ok()?;
|
||||||
|
|
||||||
let (index32, _epoch, _) = id.unzip();
|
let (index32, _epoch, _) = id.unzip();
|
||||||
@ -222,7 +225,7 @@ impl<A: HalApi, Id: TypedId, T: Resource<Id>> StatelessTracker<A, Id, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, id: Id) -> Option<&Arc<T>> {
|
pub fn get(&self, id: Id<T::Marker>) -> Option<&Arc<T>> {
|
||||||
let index = id.unzip().0 as usize;
|
let index = id.unzip().0 as usize;
|
||||||
if index > self.metadata.size() {
|
if index > self.metadata.size() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
use super::{range::RangedStates, PendingTransition, PendingTransitionList, ResourceTracker};
|
use super::{range::RangedStates, PendingTransition, PendingTransitionList, ResourceTracker};
|
||||||
use crate::{
|
use crate::{
|
||||||
hal_api::HalApi,
|
hal_api::HalApi,
|
||||||
id::{TextureId, TypedId},
|
id::TextureId,
|
||||||
resource::{Resource, Texture, TextureInner},
|
resource::{Resource, Texture, TextureInner},
|
||||||
snatch::SnatchGuard,
|
snatch::SnatchGuard,
|
||||||
track::{
|
track::{
|
||||||
@ -50,7 +50,6 @@ pub struct TextureSelector {
|
|||||||
impl ResourceUses for TextureUses {
|
impl ResourceUses for TextureUses {
|
||||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||||
|
|
||||||
type Id = TextureId;
|
|
||||||
type Selector = TextureSelector;
|
type Selector = TextureSelector;
|
||||||
|
|
||||||
fn bits(self) -> u16 {
|
fn bits(self) -> u16 {
|
||||||
@ -232,7 +231,7 @@ impl TextureStateSet {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct TextureUsageScope<A: HalApi> {
|
pub(crate) struct TextureUsageScope<A: HalApi> {
|
||||||
set: TextureStateSet,
|
set: TextureStateSet,
|
||||||
metadata: ResourceMetadata<A, TextureId, Texture<A>>,
|
metadata: ResourceMetadata<A, Texture<A>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> TextureUsageScope<A> {
|
impl<A: HalApi> TextureUsageScope<A> {
|
||||||
@ -387,14 +386,14 @@ pub(crate) struct TextureTracker<A: HalApi> {
|
|||||||
start_set: TextureStateSet,
|
start_set: TextureStateSet,
|
||||||
end_set: TextureStateSet,
|
end_set: TextureStateSet,
|
||||||
|
|
||||||
metadata: ResourceMetadata<A, TextureId, Texture<A>>,
|
metadata: ResourceMetadata<A, Texture<A>>,
|
||||||
|
|
||||||
temp: Vec<PendingTransition<TextureUses>>,
|
temp: Vec<PendingTransition<TextureUses>>,
|
||||||
|
|
||||||
_phantom: PhantomData<A>,
|
_phantom: PhantomData<A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: HalApi> ResourceTracker<TextureId, Texture<A>> for TextureTracker<A> {
|
impl<A: HalApi> ResourceTracker<Texture<A>> for TextureTracker<A> {
|
||||||
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
||||||
/// resource and the epoch matches.
|
/// resource and the epoch matches.
|
||||||
///
|
///
|
||||||
@ -864,10 +863,10 @@ impl<'a> TextureStateProvider<'a> {
|
|||||||
unsafe fn insert_or_merge<A: HalApi>(
|
unsafe fn insert_or_merge<A: HalApi>(
|
||||||
texture_selector: &TextureSelector,
|
texture_selector: &TextureSelector,
|
||||||
current_state_set: &mut TextureStateSet,
|
current_state_set: &mut TextureStateSet,
|
||||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||||
index: usize,
|
index: usize,
|
||||||
state_provider: TextureStateProvider<'_>,
|
state_provider: TextureStateProvider<'_>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||||
) -> Result<(), UsageConflict> {
|
) -> Result<(), UsageConflict> {
|
||||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||||
|
|
||||||
@ -920,11 +919,11 @@ unsafe fn insert_or_barrier_update<A: HalApi>(
|
|||||||
texture_selector: &TextureSelector,
|
texture_selector: &TextureSelector,
|
||||||
start_state: Option<&mut TextureStateSet>,
|
start_state: Option<&mut TextureStateSet>,
|
||||||
current_state_set: &mut TextureStateSet,
|
current_state_set: &mut TextureStateSet,
|
||||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||||
index: usize,
|
index: usize,
|
||||||
start_state_provider: TextureStateProvider<'_>,
|
start_state_provider: TextureStateProvider<'_>,
|
||||||
end_state_provider: Option<TextureStateProvider<'_>>,
|
end_state_provider: Option<TextureStateProvider<'_>>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||||
barriers: &mut Vec<PendingTransition<TextureUses>>,
|
barriers: &mut Vec<PendingTransition<TextureUses>>,
|
||||||
) {
|
) {
|
||||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||||
@ -973,11 +972,11 @@ unsafe fn insert<A: HalApi>(
|
|||||||
texture_selector: Option<&TextureSelector>,
|
texture_selector: Option<&TextureSelector>,
|
||||||
start_state: Option<&mut TextureStateSet>,
|
start_state: Option<&mut TextureStateSet>,
|
||||||
end_state: &mut TextureStateSet,
|
end_state: &mut TextureStateSet,
|
||||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||||
index: usize,
|
index: usize,
|
||||||
start_state_provider: TextureStateProvider<'_>,
|
start_state_provider: TextureStateProvider<'_>,
|
||||||
end_state_provider: Option<TextureStateProvider<'_>>,
|
end_state_provider: Option<TextureStateProvider<'_>>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||||
) {
|
) {
|
||||||
let start_layers = unsafe { start_state_provider.get_state(texture_selector, index) };
|
let start_layers = unsafe { start_state_provider.get_state(texture_selector, index) };
|
||||||
match start_layers {
|
match start_layers {
|
||||||
@ -1060,7 +1059,7 @@ unsafe fn merge<A: HalApi>(
|
|||||||
current_state_set: &mut TextureStateSet,
|
current_state_set: &mut TextureStateSet,
|
||||||
index: usize,
|
index: usize,
|
||||||
state_provider: TextureStateProvider<'_>,
|
state_provider: TextureStateProvider<'_>,
|
||||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||||
) -> Result<(), UsageConflict> {
|
) -> Result<(), UsageConflict> {
|
||||||
let current_simple = unsafe { current_state_set.simple.get_unchecked_mut(index) };
|
let current_simple = unsafe { current_state_set.simple.get_unchecked_mut(index) };
|
||||||
let current_state = if *current_simple == TextureUses::COMPLEX {
|
let current_state = if *current_simple == TextureUses::COMPLEX {
|
||||||
|
@ -24,7 +24,6 @@ use std::{
|
|||||||
};
|
};
|
||||||
use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*};
|
use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*};
|
||||||
use wgc::device::DeviceLostClosure;
|
use wgc::device::DeviceLostClosure;
|
||||||
use wgc::id::TypedId;
|
|
||||||
use wgt::WasmNotSendSync;
|
use wgt::WasmNotSendSync;
|
||||||
|
|
||||||
const LABEL: &str = "label";
|
const LABEL: &str = "label";
|
||||||
@ -604,7 +603,7 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
id: queue_id,
|
id: queue_id,
|
||||||
error_sink,
|
error_sink,
|
||||||
};
|
};
|
||||||
ready(Ok((device_id, device, device_id, queue)))
|
ready(Ok((device_id, device, device_id.transmute(), queue)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instance_poll_all_devices(&self, force_wait: bool) -> bool {
|
fn instance_poll_all_devices(&self, force_wait: bool) -> bool {
|
||||||
@ -1805,7 +1804,8 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
if let Err(cause) = wgc::gfx_select!(
|
if let Err(cause) = wgc::gfx_select!(
|
||||||
encoder => self.0.command_encoder_run_compute_pass(*encoder, pass_data)
|
encoder => self.0.command_encoder_run_compute_pass(*encoder, pass_data)
|
||||||
) {
|
) {
|
||||||
let name = wgc::gfx_select!(encoder => self.0.command_buffer_label(*encoder));
|
let name =
|
||||||
|
wgc::gfx_select!(encoder => self.0.command_buffer_label(encoder.transmute()));
|
||||||
self.handle_error(
|
self.handle_error(
|
||||||
&encoder_data.error_sink,
|
&encoder_data.error_sink,
|
||||||
cause,
|
cause,
|
||||||
@ -1888,7 +1888,8 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
if let Err(cause) =
|
if let Err(cause) =
|
||||||
wgc::gfx_select!(encoder => self.0.command_encoder_run_render_pass(*encoder, pass_data))
|
wgc::gfx_select!(encoder => self.0.command_encoder_run_render_pass(*encoder, pass_data))
|
||||||
{
|
{
|
||||||
let name = wgc::gfx_select!(encoder => self.0.command_buffer_label(*encoder));
|
let name =
|
||||||
|
wgc::gfx_select!(encoder => self.0.command_buffer_label(encoder.transmute()));
|
||||||
self.handle_error(
|
self.handle_error(
|
||||||
&encoder_data.error_sink,
|
&encoder_data.error_sink,
|
||||||
cause,
|
cause,
|
||||||
@ -2922,10 +2923,10 @@ impl crate::Context for ContextWgpuCore {
|
|||||||
|
|
||||||
impl<T> From<ObjectId> for wgc::id::Id<T>
|
impl<T> From<ObjectId> for wgc::id::Id<T>
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: wgc::id::Marker,
|
||||||
{
|
{
|
||||||
fn from(id: ObjectId) -> Self {
|
fn from(id: ObjectId) -> Self {
|
||||||
let id = id.id();
|
let id = wgc::id::RawId::from_non_zero(id.id());
|
||||||
// SAFETY: The id was created via the impl below
|
// SAFETY: The id was created via the impl below
|
||||||
unsafe { Self::from_raw(id) }
|
unsafe { Self::from_raw(id) }
|
||||||
}
|
}
|
||||||
@ -2933,10 +2934,10 @@ where
|
|||||||
|
|
||||||
impl<T> From<wgc::id::Id<T>> for ObjectId
|
impl<T> From<wgc::id::Id<T>> for ObjectId
|
||||||
where
|
where
|
||||||
T: 'static + WasmNotSendSync,
|
T: wgc::id::Marker,
|
||||||
{
|
{
|
||||||
fn from(id: wgc::id::Id<T>) -> Self {
|
fn from(id: wgc::id::Id<T>) -> Self {
|
||||||
let id = id.into_raw();
|
let id = id.into_raw().into_non_zero();
|
||||||
Self::from_global_id(id)
|
Self::from_global_id(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user