mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +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>>()?;
|
||||
|
||||
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 {
|
||||
let resource = state.resource_table.take::<WebGpuCommandBuffer>(rid)?;
|
||||
@ -84,7 +84,7 @@ pub fn op_webgpu_write_buffer(
|
||||
None => &buf[data_offset..],
|
||||
};
|
||||
let maybe_err = gfx_select!(queue => instance.queue_write_buffer(
|
||||
queue,
|
||||
queue.transmute(),
|
||||
buffer,
|
||||
buffer_offset,
|
||||
data
|
||||
@ -120,7 +120,7 @@ pub fn op_webgpu_write_texture(
|
||||
let data_layout = data_layout.into();
|
||||
|
||||
gfx_ok!(queue => instance.queue_write_texture(
|
||||
queue,
|
||||
queue.transmute(),
|
||||
&destination,
|
||||
buf,
|
||||
&data_layout,
|
||||
|
@ -61,7 +61,7 @@ fn main() {
|
||||
global.instance_create_surface(
|
||||
window.display_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();
|
||||
@ -79,22 +79,21 @@ fn main() {
|
||||
#[cfg(not(feature = "winit"))]
|
||||
compatible_surface: None,
|
||||
},
|
||||
wgc::instance::AdapterInputs::IdSet(
|
||||
&[wgc::id::TypedId::zip(0, 0, backend)],
|
||||
|id| id.backend(),
|
||||
),
|
||||
wgc::instance::AdapterInputs::IdSet(&[wgc::id::Id::zip(0, 0, backend)], |id| {
|
||||
id.backend()
|
||||
}),
|
||||
)
|
||||
.expect("Unable to find an adapter for selected backend");
|
||||
|
||||
let info = gfx_select!(adapter => global.adapter_get_info(adapter)).unwrap();
|
||||
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(
|
||||
adapter,
|
||||
&desc,
|
||||
None,
|
||||
id,
|
||||
id
|
||||
id.transmute()
|
||||
));
|
||||
if let Some(e) = error {
|
||||
panic!("{:?}", e);
|
||||
|
@ -14,10 +14,10 @@ use std::{borrow::Cow, fs, path::Path};
|
||||
|
||||
pub struct IdentityPassThroughFactory;
|
||||
|
||||
impl<I: wgc::id::TypedId> wgc::identity::IdentityHandlerFactory<I> for IdentityPassThroughFactory {
|
||||
type Input = I;
|
||||
impl<T: wgc::id::Marker> wgc::identity::IdentityHandlerFactory<T> for IdentityPassThroughFactory {
|
||||
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
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ pub trait GlobalPlay {
|
||||
device: wgc::id::DeviceId,
|
||||
action: trace::Action,
|
||||
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,
|
||||
action: trace::Action,
|
||||
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;
|
||||
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 size = (range.end - range.start) as usize;
|
||||
if queued {
|
||||
self.queue_write_buffer::<A>(device, id, range.start, &bin)
|
||||
self.queue_write_buffer::<A>(device.transmute(), id, range.start, &bin)
|
||||
.unwrap();
|
||||
} else {
|
||||
self.device_wait_for_buffer::<A>(device, id).unwrap();
|
||||
@ -365,23 +365,24 @@ impl GlobalPlay for wgc::global::Global<IdentityPassThroughFactory> {
|
||||
size,
|
||||
} => {
|
||||
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();
|
||||
}
|
||||
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) => {
|
||||
let (encoder, error) = self.device_create_command_encoder::<A>(
|
||||
device,
|
||||
&wgt::CommandEncoderDescriptor { label: None },
|
||||
comb_manager.process(device.backend()),
|
||||
comb_manager.process(device.backend()).transmute(),
|
||||
);
|
||||
if let Some(e) = error {
|
||||
panic!("{e}");
|
||||
}
|
||||
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,
|
||||
) {
|
||||
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(
|
||||
adapter,
|
||||
&wgt::DeviceDescriptor {
|
||||
@ -115,7 +115,7 @@ impl Test<'_> {
|
||||
},
|
||||
None,
|
||||
device_id,
|
||||
device_id
|
||||
device_id.transmute()
|
||||
));
|
||||
if let Some(e) = error {
|
||||
panic!("{:?}", e);
|
||||
@ -128,7 +128,7 @@ impl Test<'_> {
|
||||
}
|
||||
println!("\t\t\tMapping...");
|
||||
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(
|
||||
buffer,
|
||||
expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress,
|
||||
@ -148,7 +148,7 @@ impl Test<'_> {
|
||||
|
||||
for expect in self.expectations {
|
||||
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) =
|
||||
wgc::gfx_select!(device_id => global.buffer_get_mapped_range(buffer, expect.offset, Some(expect.data.len() as wgt::BufferAddress)))
|
||||
.unwrap();
|
||||
@ -221,10 +221,9 @@ impl Corpus {
|
||||
force_fallback_adapter: false,
|
||||
compatible_surface: None,
|
||||
},
|
||||
wgc::instance::AdapterInputs::IdSet(
|
||||
&[wgc::id::TypedId::zip(0, 0, backend)],
|
||||
|id| id.backend(),
|
||||
),
|
||||
wgc::instance::AdapterInputs::IdSet(&[wgc::id::Id::zip(0, 0, backend)], |id| {
|
||||
id.backend()
|
||||
}),
|
||||
) {
|
||||
Ok(adapter) => adapter,
|
||||
Err(_) => continue,
|
||||
|
@ -6,10 +6,7 @@ use crate::{
|
||||
},
|
||||
error::{ErrorFormatter, PrettyError},
|
||||
hal_api::HalApi,
|
||||
id::{
|
||||
BindGroupId, BindGroupLayoutId, BufferId, PipelineLayoutId, SamplerId, TextureId,
|
||||
TextureViewId,
|
||||
},
|
||||
id::{BindGroupLayoutId, BufferId, SamplerId, TextureId, TextureViewId},
|
||||
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource_log,
|
||||
@ -441,7 +438,7 @@ pub struct BindGroupLayoutDescriptor<'a> {
|
||||
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.
|
||||
#[derive(Debug)]
|
||||
@ -458,7 +455,7 @@ pub struct BindGroupLayout<A: HalApi> {
|
||||
pub(crate) origin: bgl::Origin,
|
||||
#[allow(unused)]
|
||||
pub(crate) binding_count_validator: BindingTypeMaxCountValidator,
|
||||
pub(crate) info: ResourceInfo<BindGroupLayoutId>,
|
||||
pub(crate) info: ResourceInfo<BindGroupLayout<A>>,
|
||||
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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<BindGroupLayoutId> {
|
||||
type Marker = crate::id::markers::BindGroupLayout;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BindGroupLayoutId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@ -602,7 +601,7 @@ pub struct PipelineLayoutDescriptor<'a> {
|
||||
pub struct PipelineLayout<A: HalApi> {
|
||||
pub(crate) raw: Option<A::PipelineLayout>,
|
||||
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) 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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<PipelineLayoutId> {
|
||||
type Marker = crate::id::markers::PipelineLayout;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<PipelineLayoutId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -830,7 +831,7 @@ pub struct BindGroup<A: HalApi> {
|
||||
pub(crate) raw: Snatchable<A::BindGroup>,
|
||||
pub(crate) device: Arc<Device<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_buffer_ranges: Vec<BufferInitTrackerAction<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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<BindGroupId> {
|
||||
type Marker = crate::id::markers::BindGroup;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BindGroupId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ use crate::{
|
||||
error::{ErrorFormatter, PrettyError},
|
||||
hal_api::HalApi,
|
||||
hub::Hub,
|
||||
id::{self, RenderBundleId},
|
||||
id,
|
||||
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
|
||||
pipeline::{PipelineFlags, RenderPipeline, VertexStep},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
@ -832,7 +832,7 @@ pub struct RenderBundle<A: HalApi> {
|
||||
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
|
||||
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction<A>>,
|
||||
pub(super) context: RenderPassContext,
|
||||
pub(crate) info: ResourceInfo<RenderBundleId>,
|
||||
pub(crate) info: ResourceInfo<RenderBundle<A>>,
|
||||
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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<RenderBundleId> {
|
||||
type Marker = crate::id::markers::RenderBundle;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<RenderBundleId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ impl<A: HalApi> State<A> {
|
||||
&mut self,
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
base_trackers: &mut Tracker<A>,
|
||||
bind_group_guard: &Storage<BindGroup<A>, id::BindGroupId>,
|
||||
bind_group_guard: &Storage<BindGroup<A>>,
|
||||
indirect_buffer: Option<id::BufferId>,
|
||||
snatch_guard: &SnatchGuard,
|
||||
) -> Result<(), UsageConflict> {
|
||||
|
@ -140,7 +140,7 @@ pub struct CommandBuffer<A: HalApi> {
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
limits: wgt::Limits,
|
||||
support_clear_texture: bool,
|
||||
pub(crate) info: ResourceInfo<CommandBufferId>,
|
||||
pub(crate) info: ResourceInfo<CommandBuffer<A>>,
|
||||
pub(crate) data: Mutex<Option<CommandBufferMutable<A>>>,
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ impl<A: HalApi> CommandBuffer<A> {
|
||||
id: id::CommandEncoderId,
|
||||
) -> Result<Arc<Self>, CommandEncoderError> {
|
||||
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 {
|
||||
CommandEncoderStatus::Recording => Ok(cmd_buf.clone()),
|
||||
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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<CommandBufferId> {
|
||||
type Marker = crate::id::markers::CommandBuffer;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<CommandBufferId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@ -418,7 +420,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
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) => {
|
||||
let mut cmd_buf_data = cmd_buf.data.lock();
|
||||
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
||||
@ -444,7 +446,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
Err(_) => Some(CommandEncoderError::Invalid),
|
||||
};
|
||||
|
||||
(encoder_id, error)
|
||||
(encoder_id.transmute(), error)
|
||||
}
|
||||
|
||||
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
|
||||
match *self {
|
||||
Self::Pass(id) => {
|
||||
fmt.command_buffer_label(&id);
|
||||
fmt.command_buffer_label(&id.transmute());
|
||||
}
|
||||
Self::SetBindGroup(id) => {
|
||||
fmt.bind_group_label(&id);
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
device::DeviceError,
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{self, Id, TypedId},
|
||||
id::{self, Id},
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
init_tracker::MemoryInitKind,
|
||||
resource::QuerySet,
|
||||
@ -49,7 +49,7 @@ impl<A: HalApi> QueryResetMap<A> {
|
||||
pub fn reset_queries(
|
||||
&mut self,
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
query_set_storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
||||
query_set_storage: &Storage<QuerySet<A>>,
|
||||
backend: wgt::Backend,
|
||||
) -> Result<(), id::QuerySetId> {
|
||||
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>(
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
||||
storage: &Storage<QuerySet<A>>,
|
||||
active_query: &mut Option<(id::QuerySetId, u32)>,
|
||||
) -> Result<(), QueryUseError> {
|
||||
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>(
|
||||
raw_encoder: &mut A::CommandEncoder,
|
||||
storage: &Storage<QuerySet<A>, id::QuerySetId>,
|
||||
storage: &Storage<QuerySet<A>>,
|
||||
active_query: &mut Option<(id::QuerySetId, u32)>,
|
||||
) -> Result<(), QueryUseError> {
|
||||
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>,
|
||||
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
|
||||
pending_query_resets: &mut QueryResetMap<A>,
|
||||
view_guard: &'a Storage<TextureView<A>, id::TextureViewId>,
|
||||
buffer_guard: &'a Storage<Buffer<A>, id::BufferId>,
|
||||
texture_guard: &'a Storage<Texture<A>, id::TextureId>,
|
||||
query_set_guard: &'a Storage<QuerySet<A>, id::QuerySetId>,
|
||||
view_guard: &'a Storage<TextureView<A>>,
|
||||
buffer_guard: &'a Storage<Buffer<A>>,
|
||||
texture_guard: &'a Storage<Texture<A>>,
|
||||
query_set_guard: &'a Storage<QuerySet<A>>,
|
||||
snatch_guard: &SnatchGuard<'a>,
|
||||
) -> Result<Self, RenderPassErrorInner> {
|
||||
profiling::scope!("RenderPassInfo::start");
|
||||
@ -2391,7 +2391,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
(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 cmd_buf_data = cmd_buf_data.as_mut().unwrap();
|
||||
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::markers,
|
||||
id::{self, AdapterId, DeviceId, QueueId, SurfaceId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
init_tracker::TextureInitTracker,
|
||||
@ -146,12 +147,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::BufferDescriptor,
|
||||
id_in: Input<G, id::BufferId>,
|
||||
id_in: Input<G, markers::Buffer>,
|
||||
) -> (id::BufferId, Option<CreateBufferError>) {
|
||||
profiling::scope!("Device::create_buffer");
|
||||
|
||||
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 error = loop {
|
||||
@ -309,20 +310,20 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
/// [`device_create_buffer`]: Global::device_create_buffer
|
||||
/// [`usage`]: https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-usage
|
||||
/// [`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 fid = hub.buffers.prepare::<G>(id_in);
|
||||
let fid = hub.buffers.prepare::<G, _>(id_in);
|
||||
|
||||
fid.assign_error(label.borrow_or_default());
|
||||
}
|
||||
|
||||
pub fn create_render_bundle_error<A: HalApi>(
|
||||
&self,
|
||||
id_in: Input<G, id::RenderBundleId>,
|
||||
id_in: Input<G, markers::RenderBundle>,
|
||||
label: Label,
|
||||
) {
|
||||
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());
|
||||
}
|
||||
@ -330,9 +331,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
/// Assign `id_in` an error with the given `label`.
|
||||
///
|
||||
/// 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 fid = hub.textures.prepare::<G>(id_in);
|
||||
let fid = hub.textures.prepare::<G, _>(id_in);
|
||||
|
||||
fid.assign_error(label.borrow_or_default());
|
||||
}
|
||||
@ -545,13 +546,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::TextureDescriptor,
|
||||
id_in: Input<G, id::TextureId>,
|
||||
id_in: Input<G, markers::Texture>,
|
||||
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
||||
profiling::scope!("Device::create_texture");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -599,13 +600,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
hal_texture: A::Texture,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::TextureDescriptor,
|
||||
id_in: Input<G, id::TextureId>,
|
||||
id_in: Input<G, markers::Texture>,
|
||||
) -> (id::TextureId, Option<resource::CreateTextureError>) {
|
||||
profiling::scope!("Device::create_texture_from_hal");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -673,12 +674,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
hal_buffer: A::Buffer,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::BufferDescriptor,
|
||||
id_in: Input<G, id::BufferId>,
|
||||
id_in: Input<G, markers::Buffer>,
|
||||
) -> (id::BufferId, Option<CreateBufferError>) {
|
||||
profiling::scope!("Device::create_buffer");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -783,13 +784,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
texture_id: id::TextureId,
|
||||
desc: &resource::TextureViewDescriptor,
|
||||
id_in: Input<G, id::TextureViewId>,
|
||||
id_in: Input<G, markers::TextureView>,
|
||||
) -> (id::TextureViewId, Option<resource::CreateTextureViewError>) {
|
||||
profiling::scope!("Texture::create_view");
|
||||
|
||||
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 texture = match hub.textures.get(texture_id) {
|
||||
@ -873,12 +874,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::SamplerDescriptor,
|
||||
id_in: Input<G, id::SamplerId>,
|
||||
id_in: Input<G, markers::Sampler>,
|
||||
) -> (id::SamplerId, Option<resource::CreateSamplerError>) {
|
||||
profiling::scope!("Device::create_sampler");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -934,7 +935,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &binding_model::BindGroupLayoutDescriptor,
|
||||
id_in: Input<G, id::BindGroupLayoutId>,
|
||||
id_in: Input<G, markers::BindGroupLayout>,
|
||||
) -> (
|
||||
id::BindGroupLayoutId,
|
||||
Option<binding_model::CreateBindGroupLayoutError>,
|
||||
@ -942,7 +943,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
profiling::scope!("Device::create_bind_group_layout");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1004,7 +1005,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
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());
|
||||
(id, Some(error))
|
||||
}
|
||||
@ -1033,7 +1034,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &binding_model::PipelineLayoutDescriptor,
|
||||
id_in: Input<G, id::PipelineLayoutId>,
|
||||
id_in: Input<G, markers::PipelineLayout>,
|
||||
) -> (
|
||||
id::PipelineLayoutId,
|
||||
Option<binding_model::CreatePipelineLayoutError>,
|
||||
@ -1041,7 +1042,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
profiling::scope!("Device::create_pipeline_layout");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1094,12 +1095,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &binding_model::BindGroupDescriptor,
|
||||
id_in: Input<G, id::BindGroupId>,
|
||||
id_in: Input<G, markers::BindGroup>,
|
||||
) -> (id::BindGroupId, Option<binding_model::CreateBindGroupError>) {
|
||||
profiling::scope!("Device::create_bind_group");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1178,7 +1179,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::ShaderModuleDescriptor,
|
||||
source: pipeline::ShaderModuleSource,
|
||||
id_in: Input<G, id::ShaderModuleId>,
|
||||
id_in: Input<G, markers::ShaderModule>,
|
||||
) -> (
|
||||
id::ShaderModuleId,
|
||||
Option<pipeline::CreateShaderModuleError>,
|
||||
@ -1186,7 +1187,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
profiling::scope!("Device::create_shader_module");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1256,7 +1257,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::ShaderModuleDescriptor,
|
||||
source: Cow<[u32]>,
|
||||
id_in: Input<G, id::ShaderModuleId>,
|
||||
id_in: Input<G, markers::ShaderModule>,
|
||||
) -> (
|
||||
id::ShaderModuleId,
|
||||
Option<pipeline::CreateShaderModuleError>,
|
||||
@ -1264,7 +1265,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
profiling::scope!("Device::create_shader_module");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1318,12 +1319,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &wgt::CommandEncoderDescriptor<Label>,
|
||||
id_in: Input<G, id::CommandEncoderId>,
|
||||
id_in: Input<G, markers::CommandEncoder>,
|
||||
) -> (id::CommandEncoderId, Option<DeviceError>) {
|
||||
profiling::scope!("Device::create_command_encoder");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1359,11 +1362,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (id, _) = fid.assign(command_buffer);
|
||||
api_log!("Device::create_command_encoder -> {id:?}");
|
||||
return (id, None);
|
||||
return (id.transmute(), None);
|
||||
};
|
||||
|
||||
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 {
|
||||
@ -1376,7 +1379,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
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
|
||||
.device
|
||||
.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) {
|
||||
profiling::scope!("CommandBuffer::drop");
|
||||
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(
|
||||
@ -1394,7 +1400,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
device_id: DeviceId,
|
||||
desc: &command::RenderBundleEncoderDescriptor,
|
||||
) -> (
|
||||
id::RenderBundleEncoderId,
|
||||
*mut command::RenderBundleEncoder,
|
||||
Option<command::CreateRenderBundleError>,
|
||||
) {
|
||||
profiling::scope!("Device::create_render_bundle_encoder");
|
||||
@ -1410,13 +1416,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
bundle_encoder: command::RenderBundleEncoder,
|
||||
desc: &command::RenderBundleDescriptor,
|
||||
id_in: Input<G, id::RenderBundleId>,
|
||||
id_in: Input<G, markers::RenderBundle>,
|
||||
) -> (id::RenderBundleId, Option<command::RenderBundleError>) {
|
||||
profiling::scope!("RenderBundleEncoder::finish");
|
||||
|
||||
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 device = match hub.devices.get(bundle_encoder.parent()) {
|
||||
@ -1480,12 +1486,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &resource::QuerySetDescriptor,
|
||||
id_in: Input<G, id::QuerySetId>,
|
||||
id_in: Input<G, markers::QuerySet>,
|
||||
) -> (id::QuerySetId, Option<resource::CreateQuerySetError>) {
|
||||
profiling::scope!("Device::create_query_set");
|
||||
|
||||
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 device = match hub.devices.get(device_id) {
|
||||
@ -1554,7 +1560,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::RenderPipelineDescriptor,
|
||||
id_in: Input<G, id::RenderPipelineId>,
|
||||
id_in: Input<G, markers::RenderPipeline>,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
) -> (
|
||||
id::RenderPipelineId,
|
||||
@ -1564,7 +1570,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
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_error_context = implicit_context.clone();
|
||||
|
||||
@ -1633,7 +1639,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
pipeline_id: id::RenderPipelineId,
|
||||
index: u32,
|
||||
id_in: Input<G, id::BindGroupLayoutId>,
|
||||
id_in: Input<G, markers::BindGroupLayout>,
|
||||
) -> (
|
||||
id::BindGroupLayoutId,
|
||||
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) {
|
||||
Some(bg) => hub
|
||||
.bind_group_layouts
|
||||
.prepare::<G>(id_in)
|
||||
.prepare::<G, _>(id_in)
|
||||
.assign_existing(bg),
|
||||
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
||||
};
|
||||
@ -1657,7 +1663,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let id = hub
|
||||
.bind_group_layouts
|
||||
.prepare::<G>(id_in)
|
||||
.prepare::<G, _>(id_in)
|
||||
.assign_error("<derived>");
|
||||
(id, Some(error))
|
||||
}
|
||||
@ -1692,7 +1698,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: DeviceId,
|
||||
desc: &pipeline::ComputePipelineDescriptor,
|
||||
id_in: Input<G, id::ComputePipelineId>,
|
||||
id_in: Input<G, markers::ComputePipeline>,
|
||||
implicit_pipeline_ids: Option<ImplicitPipelineIds<G>>,
|
||||
) -> (
|
||||
id::ComputePipelineId,
|
||||
@ -1702,7 +1708,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
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_error_context = implicit_context.clone();
|
||||
|
||||
@ -1766,7 +1772,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
pipeline_id: id::ComputePipelineId,
|
||||
index: u32,
|
||||
id_in: Input<G, id::BindGroupLayoutId>,
|
||||
id_in: Input<G, markers::BindGroupLayout>,
|
||||
) -> (
|
||||
id::BindGroupLayoutId,
|
||||
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) {
|
||||
Some(bg) => hub
|
||||
.bind_group_layouts
|
||||
.prepare::<G>(id_in)
|
||||
.prepare::<G, _>(id_in)
|
||||
.assign_existing(bg),
|
||||
None => break binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index),
|
||||
};
|
||||
@ -1792,7 +1798,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let id = hub
|
||||
.bind_group_layouts
|
||||
.prepare::<G>(id_in)
|
||||
.prepare::<G, _>(id_in)
|
||||
.assign_error("<derived>");
|
||||
(id, Some(error))
|
||||
}
|
||||
@ -2118,7 +2124,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
|
||||
let (closures, queue_empty) = {
|
||||
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(
|
||||
submission_index.queue_id,
|
||||
device_id,
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
},
|
||||
hal_api::HalApi,
|
||||
id::{
|
||||
self, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, PipelineLayoutId,
|
||||
self, BindGroupId, BindGroupLayoutId, BufferId, ComputePipelineId, Id, PipelineLayoutId,
|
||||
QuerySetId, RenderBundleId, RenderPipelineId, SamplerId, StagingBufferId, TextureId,
|
||||
TextureViewId,
|
||||
},
|
||||
@ -419,15 +419,14 @@ impl<A: HalApi> LifetimeTracker<A> {
|
||||
}
|
||||
|
||||
impl<A: HalApi> LifetimeTracker<A> {
|
||||
fn triage_resources<Id, R>(
|
||||
resources_map: &mut FastHashMap<Id, Arc<R>>,
|
||||
fn triage_resources<R>(
|
||||
resources_map: &mut FastHashMap<Id<R::Marker>, Arc<R>>,
|
||||
active: &mut [ActiveSubmission<A>],
|
||||
trackers: &mut impl ResourceTracker<Id, R>,
|
||||
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<Id, Arc<R>>,
|
||||
trackers: &mut impl ResourceTracker<R>,
|
||||
get_resource_map: impl Fn(&mut ResourceMaps<A>) -> &mut FastHashMap<Id<R::Marker>, Arc<R>>,
|
||||
) -> Vec<Arc<R>>
|
||||
where
|
||||
Id: id::TypedId,
|
||||
R: Resource<Id>,
|
||||
R: Resource,
|
||||
{
|
||||
let mut removed_resources = Vec::new();
|
||||
resources_map.retain(|&id, resource| {
|
||||
|
@ -2,7 +2,8 @@ use crate::{
|
||||
binding_model,
|
||||
hal_api::HalApi,
|
||||
hub::Hub,
|
||||
id::{self},
|
||||
id,
|
||||
id::markers,
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
resource::{Buffer, BufferAccessResult},
|
||||
resource::{BufferAccessError, BufferMapOperation},
|
||||
@ -463,18 +464,18 @@ pub struct ImplicitPipelineContext {
|
||||
}
|
||||
|
||||
pub struct ImplicitPipelineIds<'a, G: GlobalIdentityHandlerFactory> {
|
||||
pub root_id: Input<G, id::PipelineLayoutId>,
|
||||
pub group_ids: &'a [Input<G, id::BindGroupLayoutId>],
|
||||
pub root_id: Input<G, markers::PipelineLayout>,
|
||||
pub group_ids: &'a [Input<G, markers::BindGroupLayout>],
|
||||
}
|
||||
|
||||
impl<G: GlobalIdentityHandlerFactory> ImplicitPipelineIds<'_, G> {
|
||||
fn prepare<A: HalApi>(self, hub: &Hub<A>) -> 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
|
||||
.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(),
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use crate::{
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
id::markers,
|
||||
id::{self, QueueId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
|
||||
@ -37,17 +38,19 @@ use super::Device;
|
||||
pub struct Queue<A: HalApi> {
|
||||
pub device: Option<Arc<Device<A>>>,
|
||||
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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<QueueId> {
|
||||
type Marker = crate::id::markers::Queue;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<QueueId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -436,7 +439,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
queue_id: QueueId,
|
||||
buffer_size: wgt::BufferSize,
|
||||
id_in: Input<G, id::StagingBufferId>,
|
||||
id_in: Input<G, markers::StagingBuffer>,
|
||||
) -> Result<(id::StagingBufferId, *mut u8), QueueWriteError> {
|
||||
profiling::scope!("Queue::create_staging_buffer");
|
||||
let hub = A::hub(self);
|
||||
@ -451,7 +454,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let (staging_buffer, staging_buffer_ptr) =
|
||||
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);
|
||||
resource_log!("Queue::create_staging_buffer {id:?}");
|
||||
|
||||
@ -669,7 +672,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.get(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());
|
||||
}
|
||||
|
||||
@ -1150,7 +1153,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
if cmdbuf.device.as_info().id() != queue_id {
|
||||
if cmdbuf.device.as_info().id() != queue_id.transmute() {
|
||||
return Err(DeviceError::WrongDevice.into());
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
hub::Hub,
|
||||
id::{self, DeviceId, QueueId},
|
||||
id::QueueId,
|
||||
init_tracker::{
|
||||
BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange,
|
||||
TextureInitTracker, TextureInitTrackerAction,
|
||||
@ -90,7 +90,7 @@ pub struct Device<A: HalApi> {
|
||||
pub(crate) queue_id: RwLock<Option<QueueId>>,
|
||||
queue_to_drop: RwLock<Option<A::Queue>>,
|
||||
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>>>,
|
||||
//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>,
|
||||
late_buffer_binding_sizes: &mut FastHashMap<u32, wgt::BufferSize>,
|
||||
used: &mut BindGroupStates<A>,
|
||||
storage: &'a Storage<Buffer<A>, id::BufferId>,
|
||||
storage: &'a Storage<Buffer<A>>,
|
||||
limits: &wgt::Limits,
|
||||
snatch_guard: &'a SnatchGuard<'a>,
|
||||
) -> Result<hal::BufferBinding<'a, A>, binding_model::CreateBindGroupError> {
|
||||
@ -2386,7 +2386,7 @@ impl<A: HalApi> Device<A> {
|
||||
pub(crate) fn create_pipeline_layout(
|
||||
self: &Arc<Self>,
|
||||
desc: &binding_model::PipelineLayoutDescriptor,
|
||||
bgl_registry: &Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
||||
bgl_registry: &Registry<BindGroupLayout<A>>,
|
||||
) -> Result<binding_model::PipelineLayout<A>, binding_model::CreatePipelineLayoutError> {
|
||||
use crate::binding_model::CreatePipelineLayoutError as Error;
|
||||
|
||||
@ -2499,8 +2499,8 @@ impl<A: HalApi> Device<A> {
|
||||
self: &Arc<Self>,
|
||||
implicit_context: Option<ImplicitPipelineContext>,
|
||||
mut derived_group_layouts: ArrayVec<bgl::EntryMap, { hal::MAX_BIND_GROUPS }>,
|
||||
bgl_registry: &Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
||||
pipeline_layout_registry: &Registry<id::PipelineLayoutId, binding_model::PipelineLayout<A>>,
|
||||
bgl_registry: &Registry<BindGroupLayout<A>>,
|
||||
pipeline_layout_registry: &Registry<binding_model::PipelineLayout<A>>,
|
||||
) -> Result<Arc<binding_model::PipelineLayout<A>>, pipeline::ImplicitLayoutError> {
|
||||
while derived_group_layouts
|
||||
.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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<DeviceId> {
|
||||
type Marker = crate::id::markers::Device;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<DeviceId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use wgt::Backend;
|
||||
use crate::{
|
||||
hal_api::HalApi,
|
||||
hub::{HubReport, Hubs},
|
||||
id::SurfaceId,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
instance::{Instance, Surface},
|
||||
registry::{Registry, RegistryReport},
|
||||
@ -47,7 +46,7 @@ impl GlobalReport {
|
||||
|
||||
pub struct Global<G: GlobalIdentityHandlerFactory> {
|
||||
pub instance: Instance,
|
||||
pub surfaces: Registry<SurfaceId, Surface>,
|
||||
pub surfaces: Registry<Surface>,
|
||||
pub(crate) hubs: Hubs,
|
||||
_phantom: PhantomData<G>,
|
||||
}
|
||||
|
@ -2,10 +2,13 @@
|
||||
|
||||
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
|
||||
`Id<Device<Empty>>`, and [`id::BufferId`] is an alias for
|
||||
`Id<Buffer<Empty>>`. `Id` implements `Copy`, `Hash`, `Eq`, `Ord`, and
|
||||
`Id<markers::Device>`, and [`id::BufferId`] is an alias for
|
||||
`Id<markers::Buffer>`. `Id` implements `Copy`, `Hash`, `Eq`, `Ord`, and
|
||||
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
|
||||
also a Backend indicating which `wgpu` backend it belongs to. You
|
||||
can use the [`gfx_select`] macro to dynamically dispatch on an id's
|
||||
@ -43,7 +46,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
device_id: id::DeviceId,
|
||||
desc: &resource::BufferDescriptor,
|
||||
id_in: Input<G, id::BufferId>,
|
||||
id_in: Input<G>,
|
||||
) -> (id::BufferId, Option<resource::CreateBufferError>) {
|
||||
/* ... */
|
||||
}
|
||||
@ -115,7 +118,6 @@ use crate::{
|
||||
command::{CommandBuffer, RenderBundle},
|
||||
device::{queue::Queue, Device},
|
||||
hal_api::HalApi,
|
||||
id,
|
||||
identity::GlobalIdentityHandlerFactory,
|
||||
instance::{Adapter, HalSurface, Surface},
|
||||
pipeline::{ComputePipeline, RenderPipeline, ShaderModule},
|
||||
@ -177,23 +179,23 @@ impl HubReport {
|
||||
///
|
||||
/// [`A::hub(global)`]: HalApi::hub
|
||||
pub struct Hub<A: HalApi> {
|
||||
pub adapters: Registry<id::AdapterId, Adapter<A>>,
|
||||
pub devices: Registry<id::DeviceId, Device<A>>,
|
||||
pub queues: Registry<id::QueueId, Queue<A>>,
|
||||
pub pipeline_layouts: Registry<id::PipelineLayoutId, PipelineLayout<A>>,
|
||||
pub shader_modules: Registry<id::ShaderModuleId, ShaderModule<A>>,
|
||||
pub bind_group_layouts: Registry<id::BindGroupLayoutId, BindGroupLayout<A>>,
|
||||
pub bind_groups: Registry<id::BindGroupId, BindGroup<A>>,
|
||||
pub command_buffers: Registry<id::CommandBufferId, CommandBuffer<A>>,
|
||||
pub render_bundles: Registry<id::RenderBundleId, RenderBundle<A>>,
|
||||
pub render_pipelines: Registry<id::RenderPipelineId, RenderPipeline<A>>,
|
||||
pub compute_pipelines: Registry<id::ComputePipelineId, ComputePipeline<A>>,
|
||||
pub query_sets: Registry<id::QuerySetId, QuerySet<A>>,
|
||||
pub buffers: Registry<id::BufferId, Buffer<A>>,
|
||||
pub staging_buffers: Registry<id::StagingBufferId, StagingBuffer<A>>,
|
||||
pub textures: Registry<id::TextureId, Texture<A>>,
|
||||
pub texture_views: Registry<id::TextureViewId, TextureView<A>>,
|
||||
pub samplers: Registry<id::SamplerId, Sampler<A>>,
|
||||
pub adapters: Registry<Adapter<A>>,
|
||||
pub devices: Registry<Device<A>>,
|
||||
pub queues: Registry<Queue<A>>,
|
||||
pub pipeline_layouts: Registry<PipelineLayout<A>>,
|
||||
pub shader_modules: Registry<ShaderModule<A>>,
|
||||
pub bind_group_layouts: Registry<BindGroupLayout<A>>,
|
||||
pub bind_groups: Registry<BindGroup<A>>,
|
||||
pub command_buffers: Registry<CommandBuffer<A>>,
|
||||
pub render_bundles: Registry<RenderBundle<A>>,
|
||||
pub render_pipelines: Registry<RenderPipeline<A>>,
|
||||
pub compute_pipelines: Registry<ComputePipeline<A>>,
|
||||
pub query_sets: Registry<QuerySet<A>>,
|
||||
pub buffers: Registry<Buffer<A>>,
|
||||
pub staging_buffers: Registry<StagingBuffer<A>>,
|
||||
pub textures: Registry<Texture<A>>,
|
||||
pub texture_views: Registry<TextureView<A>>,
|
||||
pub samplers: Registry<Sampler<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Hub<A> {
|
||||
@ -222,11 +224,7 @@ impl<A: HalApi> Hub<A> {
|
||||
//TODO: instead of having a hacky `with_adapters` parameter,
|
||||
// we should have `clear_device(device_id)` that specifically destroys
|
||||
// everything related to a logical device.
|
||||
pub(crate) fn clear(
|
||||
&self,
|
||||
surface_guard: &Storage<Surface, id::SurfaceId>,
|
||||
with_adapters: bool,
|
||||
) {
|
||||
pub(crate) fn clear(&self, surface_guard: &Storage<Surface>, with_adapters: bool) {
|
||||
use hal::Surface;
|
||||
|
||||
let mut devices = self.devices.write();
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::{Epoch, Index};
|
||||
use std::{
|
||||
any::Any,
|
||||
cmp::Ordering,
|
||||
fmt::{self, Debug},
|
||||
hash::Hash,
|
||||
@ -9,15 +8,74 @@ use std::{
|
||||
use wgt::{Backend, WasmNotSendSync};
|
||||
|
||||
type IdType = u64;
|
||||
type NonZeroId = std::num::NonZeroU64;
|
||||
type ZippedIndex = Index;
|
||||
type NonZeroId = std::num::NonZeroU64;
|
||||
|
||||
const INDEX_BITS: usize = std::mem::size_of::<ZippedIndex>() * 8;
|
||||
const EPOCH_BITS: usize = INDEX_BITS - BACKEND_BITS;
|
||||
const BACKEND_BITS: usize = 3;
|
||||
const BACKEND_SHIFT: usize = INDEX_BITS * 2 - BACKEND_BITS;
|
||||
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.
|
||||
///
|
||||
@ -49,21 +107,13 @@ type Dummy = hal::api::Empty;
|
||||
/// [`Registry`]: crate::hub::Registry
|
||||
/// [`Empty`]: hal::api::Empty
|
||||
#[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(
|
||||
feature = "replay",
|
||||
derive(serde::Deserialize),
|
||||
serde(from = "SerialId")
|
||||
any(feature = "serde", feature = "trace", feature = "replay"),
|
||||
serde(transparent)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
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>);
|
||||
pub struct Id<T: Marker>(RawId, PhantomData<T>);
|
||||
|
||||
// This type represents Id in a more readable (and editable) way.
|
||||
#[allow(dead_code)]
|
||||
@ -72,39 +122,40 @@ enum SerialId {
|
||||
// The only variant forces RON to not ignore "Id"
|
||||
Id(Index, Epoch, Backend),
|
||||
}
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
impl<T> From<Id<T>> for SerialId
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
fn from(id: Id<T>) -> Self {
|
||||
impl From<RawId> for SerialId {
|
||||
fn from(id: RawId) -> Self {
|
||||
let (index, epoch, backend) = id.unzip();
|
||||
Self::Id(index, epoch, backend)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "replay")]
|
||||
impl<T> From<SerialId> for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
impl From<SerialId> for RawId {
|
||||
fn from(id: SerialId) -> Self {
|
||||
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>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
/// # Safety
|
||||
///
|
||||
/// 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)
|
||||
}
|
||||
|
||||
/// Coerce the identifiers into its raw underlying representation.
|
||||
pub fn into_raw(self) -> RawId {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn dummy(index: u32) -> Self {
|
||||
Id::zip(index, 1, Backend::Empty)
|
||||
@ -115,24 +166,53 @@ where
|
||||
self.backend() != Backend::Empty
|
||||
}
|
||||
|
||||
/// Get the backend this identifier corresponds to.
|
||||
#[inline]
|
||||
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!(),
|
||||
}
|
||||
self.0.backend()
|
||||
}
|
||||
|
||||
/// Transmute this identifier to one with a different marker trait.
|
||||
///
|
||||
/// Legal use is governed through a sealed trait, however it's correctness
|
||||
/// 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>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
@ -140,7 +220,7 @@ where
|
||||
|
||||
impl<T> Debug for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let (index, epoch, backend) = self.unzip();
|
||||
@ -159,8 +239,9 @@ where
|
||||
|
||||
impl<T> Hash for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
#[inline]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
@ -168,19 +249,21 @@ where
|
||||
|
||||
impl<T> PartialEq for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
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>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.0.partial_cmp(&other.0)
|
||||
}
|
||||
@ -188,78 +271,73 @@ where
|
||||
|
||||
impl<T> Ord for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: Marker,
|
||||
{
|
||||
#[inline]
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
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
|
||||
/// need to construct `Id` values directly, or access their components, like the
|
||||
/// WGPU recording player, may use this trait to do so.
|
||||
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;
|
||||
}
|
||||
/// For example, `Device<A>` will have the same type of identifier as
|
||||
/// `Device<B>` because `Device<T>` for any `T` defines the same maker type.
|
||||
pub trait Marker: 'static + WasmNotSendSync {}
|
||||
|
||||
#[allow(trivial_numeric_casts)]
|
||||
impl<T> TypedId for Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
{
|
||||
fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
|
||||
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)
|
||||
}
|
||||
// This allows `()` to be used as a marker type for tests.
|
||||
//
|
||||
// We don't want these in production code, since they essentially remove type
|
||||
// safety, like how identifiers across different types can be compared.
|
||||
#[cfg(test)]
|
||||
impl Marker for () {}
|
||||
|
||||
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(),
|
||||
)
|
||||
}
|
||||
/// Define identifiers for each resource.
|
||||
macro_rules! ids {
|
||||
($(
|
||||
$(#[$($meta:meta)*])*
|
||||
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>>;
|
||||
pub type SurfaceId = Id<crate::instance::Surface>;
|
||||
// Device
|
||||
pub type DeviceId = Id<crate::device::Device<Dummy>>;
|
||||
pub type QueueId = DeviceId;
|
||||
// Resource
|
||||
pub type BufferId = Id<crate::resource::Buffer<Dummy>>;
|
||||
pub type StagingBufferId = Id<crate::resource::StagingBuffer<Dummy>>;
|
||||
pub type TextureViewId = Id<crate::resource::TextureView<Dummy>>;
|
||||
pub type TextureId = Id<crate::resource::Texture<Dummy>>;
|
||||
pub type SamplerId = Id<crate::resource::Sampler<Dummy>>;
|
||||
// Binding model
|
||||
pub type BindGroupLayoutId = Id<crate::binding_model::BindGroupLayout<Dummy>>;
|
||||
pub type PipelineLayoutId = Id<crate::binding_model::PipelineLayout<Dummy>>;
|
||||
pub type BindGroupId = Id<crate::binding_model::BindGroup<Dummy>>;
|
||||
// Pipeline
|
||||
pub type ShaderModuleId = Id<crate::pipeline::ShaderModule<Dummy>>;
|
||||
pub type RenderPipelineId = Id<crate::pipeline::RenderPipeline<Dummy>>;
|
||||
pub type ComputePipelineId = Id<crate::pipeline::ComputePipeline<Dummy>>;
|
||||
// Command
|
||||
pub type CommandEncoderId = CommandBufferId;
|
||||
pub type CommandBufferId = Id<crate::command::CommandBuffer<Dummy>>;
|
||||
pub type RenderPassEncoderId = *mut crate::command::RenderPass;
|
||||
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>>;
|
||||
ids! {
|
||||
pub type AdapterId Adapter;
|
||||
pub type SurfaceId Surface;
|
||||
pub type DeviceId Device;
|
||||
pub type QueueId Queue;
|
||||
pub type BufferId Buffer;
|
||||
pub type StagingBufferId StagingBuffer;
|
||||
pub type TextureViewId TextureView;
|
||||
pub type TextureId Texture;
|
||||
pub type SamplerId Sampler;
|
||||
pub type BindGroupLayoutId BindGroupLayout;
|
||||
pub type PipelineLayoutId PipelineLayout;
|
||||
pub type BindGroupId BindGroup;
|
||||
pub type ShaderModuleId ShaderModule;
|
||||
pub type RenderPipelineId RenderPipeline;
|
||||
pub type ComputePipelineId ComputePipeline;
|
||||
pub type CommandEncoderId CommandEncoder;
|
||||
pub type CommandBufferId CommandBuffer;
|
||||
pub type RenderPassEncoderId RenderPassEncoder;
|
||||
pub type ComputePassEncoderId ComputePassEncoder;
|
||||
pub type RenderBundleEncoderId RenderBundleEncoder;
|
||||
pub type RenderBundleId RenderBundle;
|
||||
pub type QuerySetId QuerySet;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_backend() {
|
||||
@ -270,7 +348,7 @@ fn test_id_backend() {
|
||||
Backend::Dx12,
|
||||
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();
|
||||
assert_eq!(id.backend(), b);
|
||||
assert_eq!(backend, b);
|
||||
@ -292,7 +370,7 @@ fn test_id() {
|
||||
for &i in &indexes {
|
||||
for &e in &epochs {
|
||||
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();
|
||||
assert_eq!(index, i);
|
||||
assert_eq!(epoch, e);
|
||||
|
@ -2,7 +2,7 @@ use parking_lot::Mutex;
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::{
|
||||
id::{self},
|
||||
id::{self, Id, Marker},
|
||||
Epoch, FastHashMap, Index,
|
||||
};
|
||||
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
|
||||
/// 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;
|
||||
match self.free.pop() {
|
||||
Some((index, epoch)) => I::zip(index, epoch + 1, backend),
|
||||
Some((index, epoch)) => Id::zip(index, epoch + 1, backend),
|
||||
None => {
|
||||
let epoch = 1;
|
||||
let used = self.used.entry(epoch).or_insert_with(Default::default);
|
||||
@ -60,12 +60,12 @@ impl IdentityValues {
|
||||
0
|
||||
};
|
||||
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;
|
||||
let (index, epoch, _backend) = id.unzip();
|
||||
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.
|
||||
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();
|
||||
self.free.push((index, epoch));
|
||||
self.count -= 1;
|
||||
@ -86,24 +86,24 @@ impl IdentityValues {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IdentityManager<I: id::TypedId> {
|
||||
pub struct IdentityManager<T: Marker> {
|
||||
pub(super) values: Mutex<IdentityValues>,
|
||||
_phantom: PhantomData<I>,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<I: id::TypedId> IdentityManager<I> {
|
||||
pub fn process(&self, backend: Backend) -> I {
|
||||
impl<T: Marker> IdentityManager<T> {
|
||||
pub fn process(&self, backend: Backend) -> Id<T> {
|
||||
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)
|
||||
}
|
||||
pub fn free(&self, id: I) {
|
||||
pub fn free(&self, id: Id<T>) {
|
||||
self.values.lock().release(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: id::TypedId> IdentityManager<I> {
|
||||
impl<T: Marker> IdentityManager<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
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`.
|
||||
///
|
||||
/// See the module-level documentation for details.
|
||||
pub trait IdentityHandlerFactory<I: id::TypedId> {
|
||||
pub trait IdentityHandlerFactory<T: Marker> {
|
||||
type Input: Copy;
|
||||
/// Create an [`IdentityManager<I>`] implementation that can
|
||||
/// transform proto-ids into ids of type `I`.
|
||||
@ -123,11 +123,11 @@ pub trait IdentityHandlerFactory<I: id::TypedId> {
|
||||
/// and are not generated by wgpu
|
||||
///
|
||||
/// [`IdentityManager<I>`]: IdentityManager
|
||||
fn spawn(&self) -> Arc<IdentityManager<I>> {
|
||||
fn spawn(&self) -> Arc<IdentityManager<T>> {
|
||||
Arc::new(IdentityManager::new())
|
||||
}
|
||||
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`].
|
||||
@ -138,13 +138,13 @@ pub trait IdentityHandlerFactory<I: id::TypedId> {
|
||||
#[derive(Debug)]
|
||||
pub struct IdentityManagerFactory;
|
||||
|
||||
impl<I: id::TypedId> IdentityHandlerFactory<I> for IdentityManagerFactory {
|
||||
impl<T: Marker> IdentityHandlerFactory<T> for IdentityManagerFactory {
|
||||
type Input = ();
|
||||
fn autogenerate_ids() -> bool {
|
||||
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")
|
||||
}
|
||||
}
|
||||
@ -152,23 +152,25 @@ impl<I: id::TypedId> IdentityHandlerFactory<I> for IdentityManagerFactory {
|
||||
/// A factory that can build [`IdentityManager`]s for all resource
|
||||
/// types.
|
||||
pub trait GlobalIdentityHandlerFactory:
|
||||
IdentityHandlerFactory<id::AdapterId>
|
||||
+ IdentityHandlerFactory<id::DeviceId>
|
||||
+ IdentityHandlerFactory<id::PipelineLayoutId>
|
||||
+ IdentityHandlerFactory<id::ShaderModuleId>
|
||||
+ IdentityHandlerFactory<id::BindGroupLayoutId>
|
||||
+ IdentityHandlerFactory<id::BindGroupId>
|
||||
+ IdentityHandlerFactory<id::CommandBufferId>
|
||||
+ IdentityHandlerFactory<id::RenderBundleId>
|
||||
+ IdentityHandlerFactory<id::RenderPipelineId>
|
||||
+ IdentityHandlerFactory<id::ComputePipelineId>
|
||||
+ IdentityHandlerFactory<id::QuerySetId>
|
||||
+ IdentityHandlerFactory<id::BufferId>
|
||||
+ IdentityHandlerFactory<id::StagingBufferId>
|
||||
+ IdentityHandlerFactory<id::TextureId>
|
||||
+ IdentityHandlerFactory<id::TextureViewId>
|
||||
+ IdentityHandlerFactory<id::SamplerId>
|
||||
+ IdentityHandlerFactory<id::SurfaceId>
|
||||
IdentityHandlerFactory<id::markers::Adapter>
|
||||
+ IdentityHandlerFactory<id::markers::Device>
|
||||
+ IdentityHandlerFactory<id::markers::PipelineLayout>
|
||||
+ IdentityHandlerFactory<id::markers::ShaderModule>
|
||||
+ IdentityHandlerFactory<id::markers::BindGroupLayout>
|
||||
+ IdentityHandlerFactory<id::markers::BindGroup>
|
||||
+ IdentityHandlerFactory<id::markers::CommandBuffer>
|
||||
+ IdentityHandlerFactory<id::markers::RenderBundle>
|
||||
+ IdentityHandlerFactory<id::markers::RenderPipeline>
|
||||
+ IdentityHandlerFactory<id::markers::ComputePipeline>
|
||||
+ IdentityHandlerFactory<id::markers::QuerySet>
|
||||
+ IdentityHandlerFactory<id::markers::Buffer>
|
||||
+ IdentityHandlerFactory<id::markers::StagingBuffer>
|
||||
+ IdentityHandlerFactory<id::markers::Texture>
|
||||
+ IdentityHandlerFactory<id::markers::TextureView>
|
||||
+ IdentityHandlerFactory<id::markers::Sampler>
|
||||
+ 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]
|
||||
fn test_epoch_end_of_life() {
|
||||
use id::TypedId as _;
|
||||
let man = IdentityManager::<id::BufferId>::new();
|
||||
let man = IdentityManager::<id::markers::Buffer>::new();
|
||||
let forced_id = man.mark_as_used(id::BufferId::zip(0, 1, Backend::Empty));
|
||||
assert_eq!(forced_id.unzip().0, 0);
|
||||
let id1 = man.process(Backend::Empty);
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
device::{queue::Queue, resource::Device, DeviceDescriptor},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::markers,
|
||||
id::{AdapterId, DeviceId, QueueId, SurfaceId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
present::Presentation,
|
||||
@ -149,18 +150,20 @@ impl Instance {
|
||||
|
||||
pub struct Surface {
|
||||
pub(crate) presentation: Mutex<Option<Presentation>>,
|
||||
pub(crate) info: ResourceInfo<SurfaceId>,
|
||||
pub(crate) info: ResourceInfo<Surface>,
|
||||
pub(crate) raw: AnySurface,
|
||||
}
|
||||
|
||||
impl Resource<SurfaceId> for Surface {
|
||||
impl Resource for 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
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<SurfaceId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@ -190,7 +193,7 @@ impl Surface {
|
||||
|
||||
pub struct Adapter<A: HalApi> {
|
||||
pub(crate) raw: hal::ExposedAdapter<A>,
|
||||
pub(crate) info: ResourceInfo<AdapterId>,
|
||||
pub(crate) info: ResourceInfo<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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<AdapterId> {
|
||||
type Marker = crate::id::markers::Adapter;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<AdapterId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -478,7 +483,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
display_handle: raw_window_handle::RawDisplayHandle,
|
||||
window_handle: raw_window_handle::RawWindowHandle,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
id_in: Input<G, markers::Surface>,
|
||||
) -> Result<SurfaceId, hal::InstanceError> {
|
||||
profiling::scope!("Instance::create_surface");
|
||||
|
||||
@ -526,7 +531,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -537,7 +542,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub unsafe fn instance_create_surface_metal(
|
||||
&self,
|
||||
layer: *mut std::ffi::c_void,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
id_in: Input<G, markers::Surface>,
|
||||
) -> SurfaceId {
|
||||
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
|
||||
}
|
||||
|
||||
@ -572,7 +577,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub unsafe fn instance_create_surface_from_visual(
|
||||
&self,
|
||||
visual: *mut std::ffi::c_void,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
id_in: Input<G, markers::Surface>,
|
||||
) -> SurfaceId {
|
||||
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
|
||||
}
|
||||
|
||||
@ -603,7 +608,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub unsafe fn instance_create_surface_from_surface_handle(
|
||||
&self,
|
||||
surface_handle: *mut std::ffi::c_void,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
id_in: Input<G, markers::Surface>,
|
||||
) -> SurfaceId {
|
||||
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
|
||||
}
|
||||
|
||||
@ -636,7 +641,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub unsafe fn instance_create_surface_from_swap_chain_panel(
|
||||
&self,
|
||||
swap_chain_panel: *mut std::ffi::c_void,
|
||||
id_in: Input<G, SurfaceId>,
|
||||
id_in: Input<G, markers::Surface>,
|
||||
) -> SurfaceId {
|
||||
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
|
||||
}
|
||||
|
||||
@ -703,7 +708,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&self,
|
||||
_: A,
|
||||
instance: &Option<A::Instance>,
|
||||
inputs: &AdapterInputs<Input<G, AdapterId>>,
|
||||
inputs: &AdapterInputs<Input<G, markers::Adapter>>,
|
||||
list: &mut Vec<AdapterId>,
|
||||
) {
|
||||
let inst = match *instance {
|
||||
@ -722,12 +727,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
for raw in hal_adapters {
|
||||
let adapter = Adapter::new(raw);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
api_log!("Instance::enumerate_adapters");
|
||||
|
||||
@ -758,7 +766,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
fn select<A: HalApi>(
|
||||
&self,
|
||||
selected: &mut usize,
|
||||
new_id: Option<Input<G, AdapterId>>,
|
||||
new_id: Option<Input<G, markers::Adapter>>,
|
||||
mut list: Vec<hal::ExposedAdapter<A>>,
|
||||
) -> Option<AdapterId> {
|
||||
match selected.checked_sub(list.len()) {
|
||||
@ -771,7 +779,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
||||
let (id, _) = HalApi::hub(self)
|
||||
.adapters
|
||||
.prepare::<G>(new_id.unwrap())
|
||||
.prepare::<G, _>(new_id.unwrap())
|
||||
.assign(adapter);
|
||||
Some(id)
|
||||
}
|
||||
@ -781,7 +789,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn request_adapter(
|
||||
&self,
|
||||
desc: &RequestAdapterOptions,
|
||||
inputs: AdapterInputs<Input<G, AdapterId>>,
|
||||
inputs: AdapterInputs<Input<G, markers::Adapter>>,
|
||||
) -> Result<AdapterId, RequestAdapterError> {
|
||||
profiling::scope!("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>(
|
||||
&self,
|
||||
hal_adapter: hal::ExposedAdapter<A>,
|
||||
input: Input<G, AdapterId>,
|
||||
input: Input<G, markers::Adapter>,
|
||||
) -> AdapterId {
|
||||
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>>) =
|
||||
match A::VARIANT {
|
||||
#[cfg(vulkan)]
|
||||
Backend::Vulkan => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(metal)]
|
||||
Backend::Metal => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(dx12)]
|
||||
Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(gles)]
|
||||
Backend::Gl => fid.assign(Adapter::new(hal_adapter)),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (id, _adapter): (_, Arc<Adapter<A>>) = match A::VARIANT {
|
||||
#[cfg(vulkan)]
|
||||
Backend::Vulkan => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(metal)]
|
||||
Backend::Metal => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(dx12)]
|
||||
Backend::Dx12 => fid.assign(Adapter::new(hal_adapter)),
|
||||
#[cfg(gles)]
|
||||
Backend::Gl => fid.assign(Adapter::new(hal_adapter)),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
resource_log!("Created Adapter {:?}", id);
|
||||
id
|
||||
}
|
||||
@ -1065,15 +1072,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
adapter_id: AdapterId,
|
||||
desc: &DeviceDescriptor,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
device_id_in: Input<G, DeviceId>,
|
||||
queue_id_in: Input<G, QueueId>,
|
||||
device_id_in: Input<G, markers::Device>,
|
||||
queue_id_in: Input<G, markers::Queue>,
|
||||
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
||||
profiling::scope!("Adapter::request_device");
|
||||
api_log!("Adapter::request_device");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let device_fid = hub.devices.prepare::<G>(device_id_in);
|
||||
let queue_fid = hub.queues.prepare::<G>(queue_id_in);
|
||||
let device_fid = hub.devices.prepare::<G, markers::Device>(device_id_in);
|
||||
let queue_fid = hub.queues.prepare::<G, markers::Queue>(queue_id_in);
|
||||
|
||||
let error = loop {
|
||||
let adapter = match hub.adapters.get(adapter_id) {
|
||||
@ -1114,14 +1121,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
hal_device: OpenDevice<A>,
|
||||
desc: &DeviceDescriptor,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
device_id_in: Input<G, DeviceId>,
|
||||
queue_id_in: Input<G, QueueId>,
|
||||
device_id_in: Input<G, markers::Device>,
|
||||
queue_id_in: Input<G, markers::Queue>,
|
||||
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
|
||||
profiling::scope!("Global::create_device_from_hal");
|
||||
|
||||
let hub = A::hub(self);
|
||||
let devices_fid = hub.devices.prepare::<G>(device_id_in);
|
||||
let queues_fid = hub.queues.prepare::<G>(queue_id_in);
|
||||
let devices_fid = hub.devices.prepare::<G, markers::Device>(device_id_in);
|
||||
let queues_fid = hub.queues.prepare::<G, markers::Queue>(queue_id_in);
|
||||
|
||||
let error = loop {
|
||||
let adapter = match hub.adapters.get(adapter_id) {
|
||||
|
@ -5,7 +5,7 @@ use crate::{
|
||||
command::ColorAttachmentError,
|
||||
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
|
||||
hal_api::HalApi,
|
||||
id::{ComputePipelineId, PipelineLayoutId, RenderPipelineId, ShaderModuleId},
|
||||
id::{PipelineLayoutId, ShaderModuleId},
|
||||
resource::{Resource, ResourceInfo, ResourceType},
|
||||
resource_log, validation, Label,
|
||||
};
|
||||
@ -50,7 +50,7 @@ pub struct ShaderModule<A: HalApi> {
|
||||
pub(crate) raw: Option<A::ShaderModule>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) interface: Option<validation::Interface>,
|
||||
pub(crate) info: ResourceInfo<ShaderModuleId>,
|
||||
pub(crate) info: ResourceInfo<ShaderModule<A>>,
|
||||
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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<ShaderModuleId> {
|
||||
type Marker = crate::id::markers::ShaderModule;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<ShaderModuleId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@ -267,7 +269,7 @@ pub struct ComputePipeline<A: HalApi> {
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) _shader_module: Arc<ShaderModule<A>>,
|
||||
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> {
|
||||
@ -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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<ComputePipelineId> {
|
||||
type Marker = crate::id::markers::ComputePipeline;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<ComputePipelineId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -515,7 +519,7 @@ pub struct RenderPipeline<A: HalApi> {
|
||||
pub(crate) strip_index_format: Option<wgt::IndexFormat>,
|
||||
pub(crate) vertex_steps: Vec<VertexStep>,
|
||||
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> {
|
||||
@ -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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<RenderPipelineId> {
|
||||
type Marker = crate::id::markers::RenderPipeline;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<RenderPipelineId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ use crate::{
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
hal_label,
|
||||
id::markers,
|
||||
id::{SurfaceId, TextureId},
|
||||
identity::{GlobalIdentityHandlerFactory, Input},
|
||||
init_tracker::TextureInitTracker,
|
||||
@ -125,13 +126,13 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
pub fn surface_get_current_texture<A: HalApi>(
|
||||
&self,
|
||||
surface_id: SurfaceId,
|
||||
texture_id_in: Input<G, TextureId>,
|
||||
texture_id_in: Input<G, markers::Texture>,
|
||||
) -> Result<SurfaceOutput, SurfaceError> {
|
||||
profiling::scope!("SwapChain::get_next_texture");
|
||||
|
||||
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
|
||||
.surfaces
|
||||
|
@ -4,7 +4,7 @@ use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::{
|
||||
id,
|
||||
id::{self, Id, Marker},
|
||||
identity::{IdentityHandlerFactory, IdentityManager},
|
||||
resource::Resource,
|
||||
storage::{Element, InvalidId, Storage},
|
||||
@ -37,14 +37,14 @@ impl RegistryReport {
|
||||
/// any other dependent resource
|
||||
///
|
||||
#[derive(Debug)]
|
||||
pub struct Registry<I: id::TypedId, T: Resource<I>> {
|
||||
identity: Arc<IdentityManager<I>>,
|
||||
storage: RwLock<Storage<T, I>>,
|
||||
pub struct Registry<T: Resource> {
|
||||
identity: Arc<IdentityManager<T::Marker>>,
|
||||
storage: RwLock<Storage<T>>,
|
||||
backend: Backend,
|
||||
}
|
||||
|
||||
impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
||||
pub(crate) fn new<F: IdentityHandlerFactory<I>>(backend: Backend, factory: &F) -> Self {
|
||||
impl<T: Resource> Registry<T> {
|
||||
pub(crate) fn new<F: IdentityHandlerFactory<T::Marker>>(backend: Backend, factory: &F) -> Self {
|
||||
Self {
|
||||
identity: factory.spawn(),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub(crate) struct FutureId<'a, I: id::TypedId, T: Resource<I>> {
|
||||
id: I,
|
||||
identity: Arc<IdentityManager<I>>,
|
||||
data: &'a RwLock<Storage<T, I>>,
|
||||
pub(crate) struct FutureId<'a, T: Resource> {
|
||||
id: Id<T::Marker>,
|
||||
identity: Arc<IdentityManager<T::Marker>>,
|
||||
data: &'a RwLock<Storage<T>>,
|
||||
}
|
||||
|
||||
impl<I: id::TypedId + Copy, T: Resource<I>> FutureId<'_, I, T> {
|
||||
impl<T: Resource> FutureId<'_, T> {
|
||||
#[allow(dead_code)]
|
||||
pub fn id(&self) -> I {
|
||||
pub fn id(&self) -> Id<T::Marker> {
|
||||
self.id
|
||||
}
|
||||
|
||||
pub fn into_id(self) -> I {
|
||||
pub fn into_id(self) -> Id<T::Marker> {
|
||||
self.id
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ impl<I: id::TypedId + Copy, T: Resource<I>> FutureId<'_, I, T> {
|
||||
/// Assign a new resource to this ID.
|
||||
///
|
||||
/// 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();
|
||||
data.insert(self.id, self.init(value));
|
||||
(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.
|
||||
/// 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();
|
||||
debug_assert!(!data.contains(self.id));
|
||||
data.insert(self.id, value.clone());
|
||||
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.id
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: id::TypedId, T: Resource<I>> Registry<I, T> {
|
||||
pub(crate) fn prepare<F>(&self, id_in: F::Input) -> FutureId<I, T>
|
||||
impl<T: Resource> Registry<T> {
|
||||
pub(crate) fn prepare<F, U: Marker>(&self, id_in: F::Input) -> FutureId<T>
|
||||
where
|
||||
F: IdentityHandlerFactory<I>,
|
||||
F: IdentityHandlerFactory<U>,
|
||||
T::Marker: id::transmute::Transmute<U>,
|
||||
{
|
||||
FutureId {
|
||||
id: if F::autogenerate_ids() {
|
||||
self.identity.process(self.backend)
|
||||
} 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(),
|
||||
data: &self.storage,
|
||||
}
|
||||
}
|
||||
pub(crate) fn request(&self) -> FutureId<I, T> {
|
||||
|
||||
pub(crate) fn request(&self) -> FutureId<T> {
|
||||
FutureId {
|
||||
id: self.identity.process(self.backend),
|
||||
identity: self.identity.clone(),
|
||||
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())
|
||||
}
|
||||
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)
|
||||
}
|
||||
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()
|
||||
}
|
||||
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()
|
||||
}
|
||||
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)
|
||||
}
|
||||
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();
|
||||
value.as_info_mut().set_id(id, &self.identity);
|
||||
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();
|
||||
storage.remove(id);
|
||||
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);
|
||||
//Returning None is legal if it's an error ID
|
||||
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 type_name = guard.kind();
|
||||
|
@ -8,10 +8,7 @@ use crate::{
|
||||
},
|
||||
global::Global,
|
||||
hal_api::HalApi,
|
||||
id::{
|
||||
AdapterId, BufferId, DeviceId, QuerySetId, SamplerId, StagingBufferId, SurfaceId,
|
||||
TextureId, TextureViewId, TypedId,
|
||||
},
|
||||
id::{AdapterId, BufferId, DeviceId, Id, Marker, SurfaceId, TextureId},
|
||||
identity::{GlobalIdentityHandlerFactory, IdentityManager},
|
||||
init_tracker::{BufferInitTracker, TextureInitTracker},
|
||||
resource, resource_log,
|
||||
@ -59,9 +56,9 @@ use std::{
|
||||
/// [`Device`]: crate::device::resource::Device
|
||||
/// [`Buffer`]: crate::resource::Buffer
|
||||
#[derive(Debug)]
|
||||
pub struct ResourceInfo<Id: TypedId> {
|
||||
id: Option<Id>,
|
||||
identity: Option<Arc<IdentityManager<Id>>>,
|
||||
pub struct ResourceInfo<T: Resource> {
|
||||
id: Option<Id<T::Marker>>,
|
||||
identity: Option<Arc<IdentityManager<T::Marker>>>,
|
||||
/// The index of the last queue submission in which the resource
|
||||
/// was used.
|
||||
///
|
||||
@ -75,7 +72,7 @@ pub struct ResourceInfo<Id: TypedId> {
|
||||
pub(crate) label: String,
|
||||
}
|
||||
|
||||
impl<Id: TypedId> Drop for ResourceInfo<Id> {
|
||||
impl<T: Resource> Drop for ResourceInfo<T> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(identity) = self.identity.as_ref() {
|
||||
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)]
|
||||
pub(crate) fn new(label: &str) -> Self {
|
||||
Self {
|
||||
@ -97,7 +94,7 @@ impl<Id: TypedId> ResourceInfo<Id> {
|
||||
|
||||
pub(crate) fn label(&self) -> &dyn Debug
|
||||
where
|
||||
Id: Debug,
|
||||
Id<T::Marker>: Debug,
|
||||
{
|
||||
if !self.label.is_empty() {
|
||||
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()
|
||||
}
|
||||
|
||||
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.identity = Some(identity.clone());
|
||||
}
|
||||
@ -133,10 +130,11 @@ impl<Id: TypedId> ResourceInfo<Id> {
|
||||
|
||||
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;
|
||||
fn as_info(&self) -> &ResourceInfo<Id>;
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Id>;
|
||||
fn as_info(&self) -> &ResourceInfo<Self>;
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self>;
|
||||
fn label(&self) -> String {
|
||||
self.as_info().label.clone()
|
||||
}
|
||||
@ -377,7 +375,7 @@ pub struct Buffer<A: HalApi> {
|
||||
pub(crate) size: wgt::BufferAddress,
|
||||
pub(crate) initialization_status: RwLock<BufferInitTracker>,
|
||||
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) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
||||
}
|
||||
@ -592,14 +590,16 @@ pub enum CreateBufferError {
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource<BufferId> for Buffer<A> {
|
||||
impl<A: HalApi> Resource for Buffer<A> {
|
||||
const TYPE: ResourceType = "Buffer";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<BufferId> {
|
||||
type Marker = crate::id::markers::Buffer;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<BufferId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -693,7 +693,7 @@ pub struct StagingBuffer<A: HalApi> {
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) size: wgt::BufferAddress,
|
||||
pub(crate) is_coherent: bool,
|
||||
pub(crate) info: ResourceInfo<StagingBufferId>,
|
||||
pub(crate) info: ResourceInfo<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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<StagingBufferId> {
|
||||
type Marker = crate::id::markers::StagingBuffer;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<StagingBufferId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
|
||||
@ -773,7 +775,7 @@ pub struct Texture<A: HalApi> {
|
||||
pub(crate) format_features: wgt::TextureFormatFeatures,
|
||||
pub(crate) initialization_status: RwLock<TextureInitTracker>,
|
||||
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) views: Mutex<Vec<Weak<TextureView<A>>>>,
|
||||
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
|
||||
@ -1166,14 +1168,16 @@ pub enum CreateTextureError {
|
||||
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource<TextureId> for Texture<A> {
|
||||
impl<A: HalApi> Resource for Texture<A> {
|
||||
const TYPE: ResourceType = "Texture";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<TextureId> {
|
||||
type Marker = crate::id::markers::Texture;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<TextureId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -1251,7 +1255,7 @@ pub struct TextureView<A: HalApi> {
|
||||
pub(crate) render_extent: Result<wgt::Extent3d, TextureViewNotRenderableReason>,
|
||||
pub(crate) samples: u32,
|
||||
pub(crate) selector: TextureSelector,
|
||||
pub(crate) info: ResourceInfo<TextureViewId>,
|
||||
pub(crate) info: ResourceInfo<TextureView<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Drop for TextureView<A> {
|
||||
@ -1329,14 +1333,16 @@ pub enum CreateTextureViewError {
|
||||
#[non_exhaustive]
|
||||
pub enum TextureViewDestroyError {}
|
||||
|
||||
impl<A: HalApi> Resource<TextureViewId> for TextureView<A> {
|
||||
impl<A: HalApi> Resource for TextureView<A> {
|
||||
const TYPE: ResourceType = "TextureView";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<TextureViewId> {
|
||||
type Marker = crate::id::markers::TextureView;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<TextureViewId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -1374,7 +1380,7 @@ pub struct SamplerDescriptor<'a> {
|
||||
pub struct Sampler<A: HalApi> {
|
||||
pub(crate) raw: Option<A::Sampler>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) info: ResourceInfo<SamplerId>,
|
||||
pub(crate) info: ResourceInfo<Self>,
|
||||
/// `true` if this is a comparison sampler
|
||||
pub(crate) comparison: bool,
|
||||
/// `true` if this is a filtering sampler
|
||||
@ -1448,14 +1454,16 @@ pub enum CreateSamplerError {
|
||||
MissingFeatures(#[from] MissingFeatures),
|
||||
}
|
||||
|
||||
impl<A: HalApi> Resource<SamplerId> for Sampler<A> {
|
||||
impl<A: HalApi> Resource for Sampler<A> {
|
||||
const TYPE: ResourceType = "Sampler";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<SamplerId> {
|
||||
type Marker = crate::id::markers::Sampler;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<SamplerId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&mut self.info
|
||||
}
|
||||
}
|
||||
@ -1479,7 +1487,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor<Label<'a>>;
|
||||
pub struct QuerySet<A: HalApi> {
|
||||
pub(crate) raw: Option<A::QuerySet>,
|
||||
pub(crate) device: Arc<Device<A>>,
|
||||
pub(crate) info: ResourceInfo<QuerySetId>,
|
||||
pub(crate) info: ResourceInfo<Self>,
|
||||
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";
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<QuerySetId> {
|
||||
type Marker = crate::id::markers::QuerySet;
|
||||
|
||||
fn as_info(&self) -> &ResourceInfo<Self> {
|
||||
&self.info
|
||||
}
|
||||
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<QuerySetId> {
|
||||
fn as_info_mut(&mut self) -> &mut ResourceInfo<Self> {
|
||||
&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 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.
|
||||
#[derive(Debug)]
|
||||
@ -30,47 +33,41 @@ pub(crate) struct InvalidId;
|
||||
/// values, so you should use an id allocator like `IdentityManager`
|
||||
/// that keeps the index values dense and close to zero.
|
||||
#[derive(Debug)]
|
||||
pub struct Storage<T, I>
|
||||
pub struct Storage<T>
|
||||
where
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
T: Resource,
|
||||
{
|
||||
pub(crate) map: Vec<Element<T>>,
|
||||
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
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
T: Resource,
|
||||
{
|
||||
type Output = Arc<T>;
|
||||
fn index(&self, id: I) -> &Arc<T> {
|
||||
fn index(&self, id: Id<T::Marker>) -> &Arc<T> {
|
||||
self.get(id).unwrap()
|
||||
}
|
||||
}
|
||||
impl<T, I> Storage<T, I>
|
||||
impl<T> Storage<T>
|
||||
where
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
T: Resource,
|
||||
{
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
map: Vec::new(),
|
||||
kind: T::TYPE,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I> Storage<T, I>
|
||||
impl<T> Storage<T>
|
||||
where
|
||||
T: Resource<I>,
|
||||
I: id::TypedId,
|
||||
T: Resource,
|
||||
{
|
||||
#[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();
|
||||
match self.map.get(index as usize) {
|
||||
Some(&Element::Vacant) => false,
|
||||
@ -88,7 +85,7 @@ where
|
||||
/// 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
|
||||
/// 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 (result, storage_epoch) = match self.map.get(index as usize) {
|
||||
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.
|
||||
/// 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 (result, storage_epoch) = match self.map.get(index as usize) {
|
||||
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.
|
||||
/// 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)?))
|
||||
}
|
||||
|
||||
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();
|
||||
match self.map.get(index as usize) {
|
||||
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);
|
||||
let (index, epoch, _backend) = id.unzip();
|
||||
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);
|
||||
let (index, epoch, _) = id.unzip();
|
||||
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();
|
||||
match std::mem::replace(
|
||||
&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);
|
||||
let (index, epoch, _) = id.unzip();
|
||||
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);
|
||||
let (index, epoch, _) = id.unzip();
|
||||
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
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(move |(index, x)| match *x {
|
||||
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,
|
||||
})
|
||||
|
@ -10,7 +10,7 @@ use std::{borrow::Cow, marker::PhantomData, sync::Arc};
|
||||
use super::{PendingTransition, ResourceTracker};
|
||||
use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{BufferId, TypedId},
|
||||
id::BufferId,
|
||||
resource::{Buffer, Resource},
|
||||
snatch::SnatchGuard,
|
||||
storage::Storage,
|
||||
@ -26,7 +26,6 @@ use wgt::{strict_assert, strict_assert_eq};
|
||||
impl ResourceUses for BufferUses {
|
||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||
|
||||
type Id = BufferId;
|
||||
type Selector = ();
|
||||
|
||||
fn bits(self) -> u16 {
|
||||
@ -92,7 +91,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
|
||||
/// Adds the given resource with the given state.
|
||||
pub fn add_single<'a>(
|
||||
&self,
|
||||
storage: &'a Storage<Buffer<A>, BufferId>,
|
||||
storage: &'a Storage<Buffer<A>>,
|
||||
id: BufferId,
|
||||
state: BufferUses,
|
||||
) -> Option<&'a Arc<Buffer<A>>> {
|
||||
@ -110,7 +109,7 @@ impl<A: HalApi> BufferBindGroupState<A> {
|
||||
pub(crate) struct BufferUsageScope<A: HalApi> {
|
||||
state: Vec<BufferUses>,
|
||||
|
||||
metadata: ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
metadata: ResourceMetadata<A, Buffer<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.
|
||||
pub fn merge_single<'a>(
|
||||
&mut self,
|
||||
storage: &'a Storage<Buffer<A>, BufferId>,
|
||||
storage: &'a Storage<Buffer<A>>,
|
||||
id: BufferId,
|
||||
new_state: BufferUses,
|
||||
) -> Result<&'a Arc<Buffer<A>>, UsageConflict> {
|
||||
@ -288,12 +287,12 @@ pub(crate) struct BufferTracker<A: HalApi> {
|
||||
start: Vec<BufferUses>,
|
||||
end: Vec<BufferUses>,
|
||||
|
||||
metadata: ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
metadata: ResourceMetadata<A, Buffer<A>>,
|
||||
|
||||
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.
|
||||
///
|
||||
/// 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>(
|
||||
start_states: Option<&mut [BufferUses]>,
|
||||
current_states: &mut [BufferUses],
|
||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||
index32: u32,
|
||||
index: usize,
|
||||
state_provider: BufferStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
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>(
|
||||
start_states: Option<&mut [BufferUses]>,
|
||||
current_states: &mut [BufferUses],
|
||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||
index: usize,
|
||||
start_state_provider: BufferStateProvider<'_>,
|
||||
end_state_provider: Option<BufferStateProvider<'_>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
barriers: &mut Vec<PendingTransition<BufferUses>>,
|
||||
) {
|
||||
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>(
|
||||
start_states: Option<&mut [BufferUses]>,
|
||||
current_states: &mut [BufferUses],
|
||||
resource_metadata: &mut ResourceMetadata<A, BufferId, Buffer<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, Buffer<A>>,
|
||||
index: usize,
|
||||
start_state_provider: 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_end_state =
|
||||
@ -777,7 +776,7 @@ unsafe fn merge<A: HalApi>(
|
||||
index32: u32,
|
||||
index: usize,
|
||||
state_provider: BufferStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, BufferId, Buffer<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Buffer<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let current_state = unsafe { current_states.get_unchecked_mut(index) };
|
||||
let new_state = unsafe { state_provider.get_state(index) };
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! 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 std::{borrow::Cow, marker::PhantomData, mem, sync::Arc};
|
||||
use wgt::strict_assert;
|
||||
@ -13,7 +13,7 @@ use wgt::strict_assert;
|
||||
/// members, but a bit vector tracks occupancy, so iteration touches
|
||||
/// only occupied elements.
|
||||
#[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`.
|
||||
owned: BitVec<usize>,
|
||||
|
||||
@ -21,10 +21,10 @@ pub(super) struct ResourceMetadata<A: HalApi, I: TypedId, T: Resource<I>> {
|
||||
resources: Vec<Option<Arc<T>>>,
|
||||
|
||||
/// 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 {
|
||||
Self {
|
||||
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
|
||||
/// 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.
|
||||
Direct { resource: Cow<'a, Arc<T>> },
|
||||
/// Comes from another metadata tracker.
|
||||
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.
|
||||
///
|
||||
/// # Safety
|
||||
|
@ -104,7 +104,7 @@ mod texture;
|
||||
use crate::{
|
||||
binding_model, command, conv,
|
||||
hal_api::HalApi,
|
||||
id::{self, TypedId},
|
||||
id::{self, Id},
|
||||
pipeline, resource,
|
||||
snatch::SnatchGuard,
|
||||
storage::Storage,
|
||||
@ -182,8 +182,6 @@ pub(crate) trait ResourceUses:
|
||||
/// All flags that are exclusive.
|
||||
const EXCLUSIVE: Self;
|
||||
|
||||
/// The relevant resource ID type.
|
||||
type Id: Copy + fmt::Debug + TypedId;
|
||||
/// The selector used by this resource.
|
||||
type Selector: fmt::Debug;
|
||||
|
||||
@ -320,8 +318,8 @@ impl<T: ResourceUses> fmt::Display for InvalidUse<T> {
|
||||
pub(crate) struct BindGroupStates<A: HalApi> {
|
||||
pub buffers: BufferBindGroupState<A>,
|
||||
pub textures: TextureBindGroupState<A>,
|
||||
pub views: StatelessBindGroupSate<id::TextureViewId, resource::TextureView<A>>,
|
||||
pub samplers: StatelessBindGroupSate<id::SamplerId, resource::Sampler<A>>,
|
||||
pub views: StatelessBindGroupSate<resource::TextureView<A>>,
|
||||
pub samplers: StatelessBindGroupSate<resource::Sampler<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> BindGroupStates<A> {
|
||||
@ -354,20 +352,19 @@ pub(crate) struct RenderBundleScope<A: HalApi> {
|
||||
pub buffers: RwLock<BufferUsageScope<A>>,
|
||||
pub textures: RwLock<TextureUsageScope<A>>,
|
||||
// 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 render_pipelines:
|
||||
RwLock<StatelessTracker<A, id::RenderPipelineId, pipeline::RenderPipeline<A>>>,
|
||||
pub query_sets: RwLock<StatelessTracker<A, id::QuerySetId, resource::QuerySet<A>>>,
|
||||
pub bind_groups: RwLock<StatelessTracker<A, binding_model::BindGroup<A>>>,
|
||||
pub render_pipelines: RwLock<StatelessTracker<A, pipeline::RenderPipeline<A>>>,
|
||||
pub query_sets: RwLock<StatelessTracker<A, resource::QuerySet<A>>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> RenderBundleScope<A> {
|
||||
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
||||
pub fn new(
|
||||
buffers: &Storage<resource::Buffer<A>, id::BufferId>,
|
||||
textures: &Storage<resource::Texture<A>, id::TextureId>,
|
||||
bind_groups: &Storage<binding_model::BindGroup<A>, id::BindGroupId>,
|
||||
render_pipelines: &Storage<pipeline::RenderPipeline<A>, id::RenderPipelineId>,
|
||||
query_sets: &Storage<resource::QuerySet<A>, id::QuerySetId>,
|
||||
buffers: &Storage<resource::Buffer<A>>,
|
||||
textures: &Storage<resource::Texture<A>>,
|
||||
bind_groups: &Storage<binding_model::BindGroup<A>>,
|
||||
render_pipelines: &Storage<pipeline::RenderPipeline<A>>,
|
||||
query_sets: &Storage<resource::QuerySet<A>>,
|
||||
) -> Self {
|
||||
let value = Self {
|
||||
buffers: RwLock::new(BufferUsageScope::new()),
|
||||
@ -424,8 +421,8 @@ pub(crate) struct UsageScope<A: HalApi> {
|
||||
impl<A: HalApi> UsageScope<A> {
|
||||
/// Create the render bundle scope and pull the maximum IDs from the hubs.
|
||||
pub fn new(
|
||||
buffers: &Storage<resource::Buffer<A>, id::BufferId>,
|
||||
textures: &Storage<resource::Texture<A>, id::TextureId>,
|
||||
buffers: &Storage<resource::Buffer<A>>,
|
||||
textures: &Storage<resource::Texture<A>>,
|
||||
) -> Self {
|
||||
let mut value = Self {
|
||||
buffers: BufferUsageScope::new(),
|
||||
@ -481,25 +478,24 @@ impl<A: HalApi> UsageScope<A> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ResourceTracker<Id, R>
|
||||
pub(crate) trait ResourceTracker<R>
|
||||
where
|
||||
Id: TypedId,
|
||||
R: resource::Resource<Id>,
|
||||
R: resource::Resource,
|
||||
{
|
||||
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.
|
||||
pub(crate) struct Tracker<A: HalApi> {
|
||||
pub buffers: BufferTracker<A>,
|
||||
pub textures: TextureTracker<A>,
|
||||
pub views: StatelessTracker<A, id::TextureViewId, resource::TextureView<A>>,
|
||||
pub samplers: StatelessTracker<A, id::SamplerId, resource::Sampler<A>>,
|
||||
pub bind_groups: StatelessTracker<A, id::BindGroupId, binding_model::BindGroup<A>>,
|
||||
pub compute_pipelines: StatelessTracker<A, id::ComputePipelineId, pipeline::ComputePipeline<A>>,
|
||||
pub render_pipelines: StatelessTracker<A, id::RenderPipelineId, pipeline::RenderPipeline<A>>,
|
||||
pub bundles: StatelessTracker<A, id::RenderBundleId, command::RenderBundle<A>>,
|
||||
pub query_sets: StatelessTracker<A, id::QuerySetId, resource::QuerySet<A>>,
|
||||
pub views: StatelessTracker<A, resource::TextureView<A>>,
|
||||
pub samplers: StatelessTracker<A, resource::Sampler<A>>,
|
||||
pub bind_groups: StatelessTracker<A, binding_model::BindGroup<A>>,
|
||||
pub compute_pipelines: StatelessTracker<A, pipeline::ComputePipeline<A>>,
|
||||
pub render_pipelines: StatelessTracker<A, pipeline::RenderPipeline<A>>,
|
||||
pub bundles: StatelessTracker<A, command::RenderBundle<A>>,
|
||||
pub query_sets: StatelessTracker<A, resource::QuerySet<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Tracker<A> {
|
||||
@ -520,15 +516,15 @@ impl<A: HalApi> Tracker<A> {
|
||||
/// Pull the maximum IDs from the hubs.
|
||||
pub fn set_size(
|
||||
&mut self,
|
||||
buffers: Option<&Storage<resource::Buffer<A>, id::BufferId>>,
|
||||
textures: Option<&Storage<resource::Texture<A>, id::TextureId>>,
|
||||
views: Option<&Storage<resource::TextureView<A>, id::TextureViewId>>,
|
||||
samplers: Option<&Storage<resource::Sampler<A>, id::SamplerId>>,
|
||||
bind_groups: Option<&Storage<binding_model::BindGroup<A>, id::BindGroupId>>,
|
||||
compute_pipelines: Option<&Storage<pipeline::ComputePipeline<A>, id::ComputePipelineId>>,
|
||||
render_pipelines: Option<&Storage<pipeline::RenderPipeline<A>, id::RenderPipelineId>>,
|
||||
bundles: Option<&Storage<command::RenderBundle<A>, id::RenderBundleId>>,
|
||||
query_sets: Option<&Storage<resource::QuerySet<A>, id::QuerySetId>>,
|
||||
buffers: Option<&Storage<resource::Buffer<A>>>,
|
||||
textures: Option<&Storage<resource::Texture<A>>>,
|
||||
views: Option<&Storage<resource::TextureView<A>>>,
|
||||
samplers: Option<&Storage<resource::Sampler<A>>>,
|
||||
bind_groups: Option<&Storage<binding_model::BindGroup<A>>>,
|
||||
compute_pipelines: Option<&Storage<pipeline::ComputePipeline<A>>>,
|
||||
render_pipelines: Option<&Storage<pipeline::RenderPipeline<A>>>,
|
||||
bundles: Option<&Storage<command::RenderBundle<A>>>,
|
||||
query_sets: Option<&Storage<resource::QuerySet<A>>>,
|
||||
) {
|
||||
if let Some(buffers) = buffers {
|
||||
self.buffers.set_size(buffers.len());
|
||||
|
@ -4,24 +4,27 @@
|
||||
* distinction between a usage scope and a full tracker.
|
||||
!*/
|
||||
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
use super::ResourceTracker;
|
||||
|
||||
/// Satisfy clippy.
|
||||
type Pair<T> = (Id<<T as Resource>::Marker>, Arc<T>);
|
||||
|
||||
/// Stores all the resources that a bind group stores.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct StatelessBindGroupSate<Id: TypedId, T: Resource<Id>> {
|
||||
resources: Mutex<Vec<(Id, Arc<T>)>>,
|
||||
pub(crate) struct StatelessBindGroupSate<T: Resource> {
|
||||
resources: Mutex<Vec<Pair<T>>>,
|
||||
}
|
||||
|
||||
impl<Id: TypedId, T: Resource<Id>> StatelessBindGroupSate<Id, T> {
|
||||
impl<T: Resource> StatelessBindGroupSate<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
resources: Mutex::new(Vec::new()),
|
||||
@ -58,7 +61,7 @@ impl<Id: TypedId, T: Resource<Id>> StatelessBindGroupSate<Id, T> {
|
||||
}
|
||||
|
||||
/// 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 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.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct StatelessTracker<A: HalApi, Id: TypedId, T: Resource<Id>> {
|
||||
metadata: ResourceMetadata<A, Id, T>,
|
||||
_phantom: PhantomData<Id>,
|
||||
pub(crate) struct StatelessTracker<A: HalApi, T: Resource> {
|
||||
metadata: ResourceMetadata<A, T>,
|
||||
}
|
||||
|
||||
impl<A: HalApi, Id: TypedId, T: Resource<Id>> ResourceTracker<Id, T>
|
||||
for StatelessTracker<A, Id, T>
|
||||
{
|
||||
impl<A: HalApi, T: Resource> ResourceTracker<T> for StatelessTracker<A, T> {
|
||||
/// Try to remove the given resource from the tracker iff we have the last reference to the
|
||||
/// 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,
|
||||
/// 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;
|
||||
|
||||
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 {
|
||||
Self {
|
||||
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,
|
||||
/// 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 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,
|
||||
/// 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 (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;
|
||||
if index > self.metadata.size() {
|
||||
return None;
|
||||
|
@ -22,7 +22,7 @@
|
||||
use super::{range::RangedStates, PendingTransition, PendingTransitionList, ResourceTracker};
|
||||
use crate::{
|
||||
hal_api::HalApi,
|
||||
id::{TextureId, TypedId},
|
||||
id::TextureId,
|
||||
resource::{Resource, Texture, TextureInner},
|
||||
snatch::SnatchGuard,
|
||||
track::{
|
||||
@ -50,7 +50,6 @@ pub struct TextureSelector {
|
||||
impl ResourceUses for TextureUses {
|
||||
const EXCLUSIVE: Self = Self::EXCLUSIVE;
|
||||
|
||||
type Id = TextureId;
|
||||
type Selector = TextureSelector;
|
||||
|
||||
fn bits(self) -> u16 {
|
||||
@ -232,7 +231,7 @@ impl TextureStateSet {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TextureUsageScope<A: HalApi> {
|
||||
set: TextureStateSet,
|
||||
metadata: ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
metadata: ResourceMetadata<A, Texture<A>>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> TextureUsageScope<A> {
|
||||
@ -387,14 +386,14 @@ pub(crate) struct TextureTracker<A: HalApi> {
|
||||
start_set: TextureStateSet,
|
||||
end_set: TextureStateSet,
|
||||
|
||||
metadata: ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
metadata: ResourceMetadata<A, Texture<A>>,
|
||||
|
||||
temp: Vec<PendingTransition<TextureUses>>,
|
||||
|
||||
_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
|
||||
/// resource and the epoch matches.
|
||||
///
|
||||
@ -864,10 +863,10 @@ impl<'a> TextureStateProvider<'a> {
|
||||
unsafe fn insert_or_merge<A: HalApi>(
|
||||
texture_selector: &TextureSelector,
|
||||
current_state_set: &mut TextureStateSet,
|
||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||
index: usize,
|
||||
state_provider: TextureStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||
|
||||
@ -920,11 +919,11 @@ unsafe fn insert_or_barrier_update<A: HalApi>(
|
||||
texture_selector: &TextureSelector,
|
||||
start_state: Option<&mut TextureStateSet>,
|
||||
current_state_set: &mut TextureStateSet,
|
||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||
index: usize,
|
||||
start_state_provider: TextureStateProvider<'_>,
|
||||
end_state_provider: Option<TextureStateProvider<'_>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
barriers: &mut Vec<PendingTransition<TextureUses>>,
|
||||
) {
|
||||
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
|
||||
@ -973,11 +972,11 @@ unsafe fn insert<A: HalApi>(
|
||||
texture_selector: Option<&TextureSelector>,
|
||||
start_state: Option<&mut TextureStateSet>,
|
||||
end_state: &mut TextureStateSet,
|
||||
resource_metadata: &mut ResourceMetadata<A, TextureId, Texture<A>>,
|
||||
resource_metadata: &mut ResourceMetadata<A, Texture<A>>,
|
||||
index: usize,
|
||||
start_state_provider: 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) };
|
||||
match start_layers {
|
||||
@ -1060,7 +1059,7 @@ unsafe fn merge<A: HalApi>(
|
||||
current_state_set: &mut TextureStateSet,
|
||||
index: usize,
|
||||
state_provider: TextureStateProvider<'_>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, TextureId, Texture<A>>,
|
||||
metadata_provider: ResourceMetadataProvider<'_, A, Texture<A>>,
|
||||
) -> Result<(), UsageConflict> {
|
||||
let current_simple = unsafe { current_state_set.simple.get_unchecked_mut(index) };
|
||||
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::device::DeviceLostClosure;
|
||||
use wgc::id::TypedId;
|
||||
use wgt::WasmNotSendSync;
|
||||
|
||||
const LABEL: &str = "label";
|
||||
@ -604,7 +603,7 @@ impl crate::Context for ContextWgpuCore {
|
||||
id: queue_id,
|
||||
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 {
|
||||
@ -1805,7 +1804,8 @@ impl crate::Context for ContextWgpuCore {
|
||||
if let Err(cause) = wgc::gfx_select!(
|
||||
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(
|
||||
&encoder_data.error_sink,
|
||||
cause,
|
||||
@ -1888,7 +1888,8 @@ impl crate::Context for ContextWgpuCore {
|
||||
if let Err(cause) =
|
||||
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(
|
||||
&encoder_data.error_sink,
|
||||
cause,
|
||||
@ -2922,10 +2923,10 @@ impl crate::Context for ContextWgpuCore {
|
||||
|
||||
impl<T> From<ObjectId> for wgc::id::Id<T>
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: wgc::id::Marker,
|
||||
{
|
||||
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
|
||||
unsafe { Self::from_raw(id) }
|
||||
}
|
||||
@ -2933,10 +2934,10 @@ where
|
||||
|
||||
impl<T> From<wgc::id::Id<T>> for ObjectId
|
||||
where
|
||||
T: 'static + WasmNotSendSync,
|
||||
T: wgc::id::Marker,
|
||||
{
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user