The second unraveling: hub and all types on it are generic free!

gfx_select macros are empty husks now that are waiting to be removed
This commit is contained in:
Andreas Reich 2024-08-05 00:32:03 +02:00
parent 3181251577
commit 24498f04d4
44 changed files with 1465 additions and 1846 deletions

View File

@ -23,6 +23,7 @@ pub const UNSTABLE_FEATURE_NAME: &str = "webgpu";
#[macro_use]
mod macros {
// TODO(#5124): remove this macro.
macro_rules! gfx_select {
($id:expr => $p0:ident.$p1:tt.$method:ident $params:tt) => {
gfx_select!($id => {$p0.$p1}, $method $params)
@ -33,24 +34,7 @@ mod macros {
};
($id:expr => {$($c:tt)*}, $method:ident $params:tt) => {
match $id.backend() {
#[cfg(any(
all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")),
feature = "vulkan-portability"
))]
wgpu_types::Backend::Vulkan => $($c)*.$method::<wgpu_core::api::Vulkan> $params,
#[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))]
wgpu_types::Backend::Metal => $($c)*.$method::<wgpu_core::api::Metal> $params,
#[cfg(all(not(target_arch = "wasm32"), windows))]
wgpu_types::Backend::Dx12 => $($c)*.$method::<wgpu_core::api::Dx12> $params,
#[cfg(any(
all(unix, not(target_os = "macos"), not(target_os = "ios")),
feature = "angle",
target_arch = "wasm32"
))]
wgpu_types::Backend::Gl => $($c)*.$method::<wgpu_core::api::Gles> $params,
other => panic!("Unexpected backend {:?}", other),
}
$($c)*.$method $params
};
}

View File

@ -72,14 +72,10 @@ pub fn op_webgpu_surface_configure(
#[serde]
pub fn op_webgpu_surface_get_current_texture(
state: &mut OpState,
#[smi] device_rid: ResourceId,
#[smi] _device_rid: ResourceId,
#[smi] surface_rid: ResourceId,
) -> Result<WebGpuResult, AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.1;
let surface_resource = state.resource_table.get::<WebGpuSurface>(surface_rid)?;
let surface = surface_resource.1;
@ -102,18 +98,14 @@ pub fn op_webgpu_surface_get_current_texture(
#[op2(fast)]
pub fn op_webgpu_surface_present(
state: &mut OpState,
#[smi] device_rid: ResourceId,
#[smi] _device_rid: ResourceId,
#[smi] surface_rid: ResourceId,
) -> Result<(), AnyError> {
let instance = state.borrow::<super::Instance>();
let device_resource = state
.resource_table
.get::<super::WebGpuDevice>(device_rid)?;
let device = device_resource.1;
let surface_resource = state.resource_table.get::<WebGpuSurface>(surface_rid)?;
let surface = surface_resource.1;
let _ = gfx_select!(device => instance.surface_present(surface))?;
instance.surface_present(surface)?;
Ok(())
}

View File

@ -8,12 +8,12 @@ use wgc::device::trace;
use std::{borrow::Cow, fs, path::Path};
pub trait GlobalPlay {
fn encode_commands<A: wgc::hal_api::HalApi>(
fn encode_commands(
&self,
encoder: wgc::id::CommandEncoderId,
commands: Vec<trace::Command>,
) -> wgc::id::CommandBufferId;
fn process<A: wgc::hal_api::HalApi>(
fn process(
&self,
device: wgc::id::DeviceId,
queue: wgc::id::QueueId,
@ -24,7 +24,7 @@ pub trait GlobalPlay {
}
impl GlobalPlay for wgc::global::Global {
fn encode_commands<A: wgc::hal_api::HalApi>(
fn encode_commands(
&self,
encoder: wgc::id::CommandEncoderId,
commands: Vec<trace::Command>,
@ -38,33 +38,33 @@ impl GlobalPlay for wgc::global::Global {
dst_offset,
size,
} => self
.command_encoder_copy_buffer_to_buffer::<A>(
.command_encoder_copy_buffer_to_buffer(
encoder, src, src_offset, dst, dst_offset, size,
)
.unwrap(),
trace::Command::CopyBufferToTexture { src, dst, size } => self
.command_encoder_copy_buffer_to_texture::<A>(encoder, &src, &dst, &size)
.command_encoder_copy_buffer_to_texture(encoder, &src, &dst, &size)
.unwrap(),
trace::Command::CopyTextureToBuffer { src, dst, size } => self
.command_encoder_copy_texture_to_buffer::<A>(encoder, &src, &dst, &size)
.command_encoder_copy_texture_to_buffer(encoder, &src, &dst, &size)
.unwrap(),
trace::Command::CopyTextureToTexture { src, dst, size } => self
.command_encoder_copy_texture_to_texture::<A>(encoder, &src, &dst, &size)
.command_encoder_copy_texture_to_texture(encoder, &src, &dst, &size)
.unwrap(),
trace::Command::ClearBuffer { dst, offset, size } => self
.command_encoder_clear_buffer::<A>(encoder, dst, offset, size)
.command_encoder_clear_buffer(encoder, dst, offset, size)
.unwrap(),
trace::Command::ClearTexture {
dst,
subresource_range,
} => self
.command_encoder_clear_texture::<A>(encoder, dst, &subresource_range)
.command_encoder_clear_texture(encoder, dst, &subresource_range)
.unwrap(),
trace::Command::WriteTimestamp {
query_set_id,
query_index,
} => self
.command_encoder_write_timestamp::<A>(encoder, query_set_id, query_index)
.command_encoder_write_timestamp(encoder, query_set_id, query_index)
.unwrap(),
trace::Command::ResolveQuerySet {
query_set_id,
@ -73,7 +73,7 @@ impl GlobalPlay for wgc::global::Global {
destination,
destination_offset,
} => self
.command_encoder_resolve_query_set::<A>(
.command_encoder_resolve_query_set(
encoder,
query_set_id,
start_query,
@ -83,19 +83,19 @@ impl GlobalPlay for wgc::global::Global {
)
.unwrap(),
trace::Command::PushDebugGroup(marker) => self
.command_encoder_push_debug_group::<A>(encoder, &marker)
.command_encoder_push_debug_group(encoder, &marker)
.unwrap(),
trace::Command::PopDebugGroup => {
self.command_encoder_pop_debug_group::<A>(encoder).unwrap()
self.command_encoder_pop_debug_group(encoder).unwrap()
}
trace::Command::InsertDebugMarker(marker) => self
.command_encoder_insert_debug_marker::<A>(encoder, &marker)
.command_encoder_insert_debug_marker(encoder, &marker)
.unwrap(),
trace::Command::RunComputePass {
base,
timestamp_writes,
} => {
self.compute_pass_end_with_unresolved_commands::<A>(
self.compute_pass_end_with_unresolved_commands(
encoder,
base,
timestamp_writes.as_ref(),
@ -109,7 +109,7 @@ impl GlobalPlay for wgc::global::Global {
timestamp_writes,
occlusion_query_set_id,
} => {
self.render_pass_end_with_unresolved_commands::<A>(
self.render_pass_end_with_unresolved_commands(
encoder,
base,
&target_colors,
@ -121,15 +121,15 @@ impl GlobalPlay for wgc::global::Global {
}
}
}
let (cmd_buf, error) = self
.command_encoder_finish::<A>(encoder, &wgt::CommandBufferDescriptor { label: None });
let (cmd_buf, error) =
self.command_encoder_finish(encoder, &wgt::CommandBufferDescriptor { label: None });
if let Some(e) = error {
panic!("{e}");
}
cmd_buf
}
fn process<A: wgc::hal_api::HalApi>(
fn process(
&self,
device: wgc::id::DeviceId,
queue: wgc::id::QueueId,
@ -150,83 +150,83 @@ impl GlobalPlay for wgc::global::Global {
panic!("Unexpected Surface action: winit feature is not enabled")
}
Action::CreateBuffer(id, desc) => {
let (_, error) = self.device_create_buffer::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_buffer(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::FreeBuffer(id) => {
self.buffer_destroy::<A>(id).unwrap();
self.buffer_destroy(id).unwrap();
}
Action::DestroyBuffer(id) => {
self.buffer_drop::<A>(id);
self.buffer_drop(id);
}
Action::CreateTexture(id, desc) => {
let (_, error) = self.device_create_texture::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_texture(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::FreeTexture(id) => {
self.texture_destroy::<A>(id).unwrap();
self.texture_destroy(id).unwrap();
}
Action::DestroyTexture(id) => {
self.texture_drop::<A>(id);
self.texture_drop(id);
}
Action::CreateTextureView {
id,
parent_id,
desc,
} => {
let (_, error) = self.texture_create_view::<A>(parent_id, &desc, Some(id));
let (_, error) = self.texture_create_view(parent_id, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyTextureView(id) => {
self.texture_view_drop::<A>(id).unwrap();
self.texture_view_drop(id).unwrap();
}
Action::CreateSampler(id, desc) => {
let (_, error) = self.device_create_sampler::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_sampler(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroySampler(id) => {
self.sampler_drop::<A>(id);
self.sampler_drop(id);
}
Action::GetSurfaceTexture { id, parent_id } => {
self.surface_get_current_texture::<A>(parent_id, Some(id))
self.surface_get_current_texture(parent_id, Some(id))
.unwrap()
.texture_id
.unwrap();
}
Action::CreateBindGroupLayout(id, desc) => {
let (_, error) = self.device_create_bind_group_layout::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_bind_group_layout(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyBindGroupLayout(id) => {
self.bind_group_layout_drop::<A>(id);
self.bind_group_layout_drop(id);
}
Action::CreatePipelineLayout(id, desc) => {
let (_, error) = self.device_create_pipeline_layout::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_pipeline_layout(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyPipelineLayout(id) => {
self.pipeline_layout_drop::<A>(id);
self.pipeline_layout_drop(id);
}
Action::CreateBindGroup(id, desc) => {
let (_, error) = self.device_create_bind_group::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_bind_group(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyBindGroup(id) => {
self.bind_group_drop::<A>(id);
self.bind_group_drop(id);
}
Action::CreateShaderModule { id, desc, data } => {
log::debug!("Creating shader from {}", data);
@ -239,14 +239,13 @@ impl GlobalPlay for wgc::global::Global {
} else {
panic!("Unknown shader {}", data);
};
let (_, error) =
self.device_create_shader_module::<A>(device, &desc, source, Some(id));
let (_, error) = self.device_create_shader_module(device, &desc, source, Some(id));
if let Some(e) = error {
println!("shader compilation error:\n---{code}\n---\n{e}");
}
}
Action::DestroyShaderModule(id) => {
self.shader_module_drop::<A>(id);
self.shader_module_drop(id);
}
Action::CreateComputePipeline {
id,
@ -261,13 +260,13 @@ impl GlobalPlay for wgc::global::Global {
group_ids: &ic.group_ids,
});
let (_, error) =
self.device_create_compute_pipeline::<A>(device, &desc, Some(id), implicit_ids);
self.device_create_compute_pipeline(device, &desc, Some(id), implicit_ids);
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyComputePipeline(id) => {
self.compute_pipeline_drop::<A>(id);
self.compute_pipeline_drop(id);
}
Action::CreateRenderPipeline {
id,
@ -282,24 +281,24 @@ impl GlobalPlay for wgc::global::Global {
group_ids: &ic.group_ids,
});
let (_, error) =
self.device_create_render_pipeline::<A>(device, &desc, Some(id), implicit_ids);
self.device_create_render_pipeline(device, &desc, Some(id), implicit_ids);
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyRenderPipeline(id) => {
self.render_pipeline_drop::<A>(id);
self.render_pipeline_drop(id);
}
Action::CreatePipelineCache { id, desc } => {
let _ = unsafe { self.device_create_pipeline_cache::<A>(device, &desc, Some(id)) };
let _ = unsafe { self.device_create_pipeline_cache(device, &desc, Some(id)) };
}
Action::DestroyPipelineCache(id) => {
self.pipeline_cache_drop::<A>(id);
self.pipeline_cache_drop(id);
}
Action::CreateRenderBundle { id, desc, base } => {
let bundle =
wgc::command::RenderBundleEncoder::new(&desc, device, Some(base)).unwrap();
let (_, error) = self.render_bundle_encoder_finish::<A>(
let (_, error) = self.render_bundle_encoder_finish(
bundle,
&wgt::RenderBundleDescriptor { label: desc.label },
Some(id),
@ -309,16 +308,16 @@ impl GlobalPlay for wgc::global::Global {
}
}
Action::DestroyRenderBundle(id) => {
self.render_bundle_drop::<A>(id);
self.render_bundle_drop(id);
}
Action::CreateQuerySet { id, desc } => {
let (_, error) = self.device_create_query_set::<A>(device, &desc, Some(id));
let (_, error) = self.device_create_query_set(device, &desc, Some(id));
if let Some(e) = error {
panic!("{e}");
}
}
Action::DestroyQuerySet(id) => {
self.query_set_drop::<A>(id);
self.query_set_drop(id);
}
Action::WriteBuffer {
id,
@ -329,10 +328,10 @@ impl GlobalPlay for wgc::global::Global {
let bin = std::fs::read(dir.join(data)).unwrap();
let size = (range.end - range.start) as usize;
if queued {
self.queue_write_buffer::<A>(queue, id, range.start, &bin)
self.queue_write_buffer(queue, id, range.start, &bin)
.unwrap();
} else {
self.device_set_buffer_data::<A>(id, range.start, &bin[..size])
self.device_set_buffer_data(id, range.start, &bin[..size])
.unwrap();
}
}
@ -343,14 +342,14 @@ impl GlobalPlay for wgc::global::Global {
size,
} => {
let bin = std::fs::read(dir.join(data)).unwrap();
self.queue_write_texture::<A>(queue, &to, &bin, &layout, &size)
self.queue_write_texture(queue, &to, &bin, &layout, &size)
.unwrap();
}
Action::Submit(_index, ref commands) if commands.is_empty() => {
self.queue_submit::<A>(queue, &[]).unwrap();
self.queue_submit(queue, &[]).unwrap();
}
Action::Submit(_index, commands) => {
let (encoder, error) = self.device_create_command_encoder::<A>(
let (encoder, error) = self.device_create_command_encoder(
device,
&wgt::CommandEncoderDescriptor { label: None },
Some(
@ -362,8 +361,8 @@ impl GlobalPlay for wgc::global::Global {
if let Some(e) = error {
panic!("{e}");
}
let cmdbuf = self.encode_commands::<A>(encoder, commands);
self.queue_submit::<A>(queue, &[cmdbuf]).unwrap();
let cmdbuf = self.encode_commands(encoder, commands);
self.queue_submit(queue, &[cmdbuf]).unwrap();
}
}
}

View File

@ -13,7 +13,7 @@ async fn draw_test_with_reports(
use wgpu::util::DeviceExt;
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.devices.num_allocated, 1);
assert_eq!(report.queues.num_allocated, 1);
@ -22,7 +22,7 @@ async fn draw_test_with_reports(
.create_shader_module(wgpu::include_wgsl!("./vertex_indices/draw.vert.wgsl"));
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.shader_modules.num_allocated, 1);
let bgl = ctx
@ -42,7 +42,7 @@ async fn draw_test_with_reports(
});
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 0);
assert_eq!(report.bind_groups.num_allocated, 0);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
@ -55,7 +55,7 @@ async fn draw_test_with_reports(
});
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
let bg = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
@ -68,7 +68,7 @@ async fn draw_test_with_reports(
});
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
@ -82,7 +82,7 @@ async fn draw_test_with_reports(
});
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.pipeline_layouts.num_allocated, 1);
assert_eq!(report.render_pipelines.num_allocated, 0);
@ -117,7 +117,7 @@ async fn draw_test_with_reports(
});
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
@ -129,7 +129,7 @@ async fn draw_test_with_reports(
drop(shader);
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.shader_modules.num_allocated, 0);
assert_eq!(report.shader_modules.num_kept_from_user, 0);
assert_eq!(report.textures.num_allocated, 0);
@ -157,7 +157,7 @@ async fn draw_test_with_reports(
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.texture_views.num_allocated, 1);
assert_eq!(report.textures.num_allocated, 1);
@ -165,7 +165,7 @@ async fn draw_test_with_reports(
drop(texture);
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.texture_views.num_allocated, 1);
assert_eq!(report.texture_views.num_kept_from_user, 1);
@ -177,7 +177,7 @@ async fn draw_test_with_reports(
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.command_buffers.num_allocated, 1);
assert_eq!(report.buffers.num_allocated, 1);
@ -197,7 +197,7 @@ async fn draw_test_with_reports(
rpass.set_bind_group(0, &bg, &[]);
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.buffers.num_allocated, 1);
assert_eq!(report.bind_groups.num_allocated, 1);
assert_eq!(report.bind_group_layouts.num_allocated, 1);
@ -220,7 +220,7 @@ async fn draw_test_with_reports(
drop(buffer);
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.command_buffers.num_kept_from_user, 1);
assert_eq!(report.render_pipelines.num_kept_from_user, 0);
assert_eq!(report.pipeline_layouts.num_kept_from_user, 0);
@ -242,7 +242,7 @@ async fn draw_test_with_reports(
// TODO: fix in https://github.com/gfx-rs/wgpu/pull/5141
// let global_report = ctx.instance.generate_report().unwrap();
// let report = global_report.hub_report(ctx.adapter_info.backend);
// let report = global_report.hub_report();
// assert_eq!(report.command_buffers.num_allocated, 0);
ctx.async_poll(wgpu::Maintain::wait_for(submit_index))
@ -250,7 +250,7 @@ async fn draw_test_with_reports(
.panic_on_timeout();
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.render_pipelines.num_allocated, 0);
assert_eq!(report.bind_groups.num_allocated, 0);
@ -265,7 +265,7 @@ async fn draw_test_with_reports(
drop(ctx.adapter);
let global_report = ctx.instance.generate_report().unwrap();
let report = global_report.hub_report(ctx.adapter_info.backend);
let report = global_report.hub_report();
assert_eq!(report.queues.num_kept_from_user, 0);
assert_eq!(report.textures.num_kept_from_user, 0);

View File

@ -2,7 +2,6 @@ use crate::{
device::{
bgl, Device, DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT,
},
hal_api::HalApi,
id::{BindGroupLayoutId, BufferId, SamplerId, TextureViewId},
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
pipeline::{ComputePipeline, RenderPipeline},
@ -417,12 +416,12 @@ pub struct BindGroupEntry<'a> {
/// Bindable resource and the slot to bind it to.
#[derive(Clone, Debug)]
pub struct ResolvedBindGroupEntry<'a, A: HalApi> {
pub struct ResolvedBindGroupEntry<'a> {
/// Slot for which binding provides resource. Corresponds to an entry of the same
/// binding index in the [`BindGroupLayoutDescriptor`].
pub binding: u32,
/// Resource to attach to the binding
pub resource: ResolvedBindingResource<'a, A>,
pub resource: ResolvedBindingResource<'a>,
}
/// Describes a group of bindings and the resources to be bound.
@ -441,15 +440,15 @@ pub struct BindGroupDescriptor<'a> {
/// Describes a group of bindings and the resources to be bound.
#[derive(Clone, Debug)]
pub struct ResolvedBindGroupDescriptor<'a, A: HalApi> {
pub struct ResolvedBindGroupDescriptor<'a> {
/// Debug label of the bind group.
///
/// This will show up in graphics debuggers for easy identification.
pub label: Label<'a>,
/// The [`BindGroupLayout`] that corresponds to this bind group.
pub layout: Arc<BindGroupLayout<A>>,
pub layout: Arc<BindGroupLayout>,
/// The resources to bind to this bind group.
pub entries: Cow<'a, [ResolvedBindGroupEntry<'a, A>]>,
pub entries: Cow<'a, [ResolvedBindGroupEntry<'a>]>,
}
/// Describes a [`BindGroupLayout`].
@ -468,13 +467,13 @@ pub struct BindGroupLayoutDescriptor<'a> {
/// used with a specific pipeline. This constraint only happens when
/// the BGLs have been derived from a pipeline without a layout.
#[derive(Debug)]
pub(crate) enum ExclusivePipeline<A: HalApi> {
pub(crate) enum ExclusivePipeline {
None,
Render(Weak<RenderPipeline<A>>),
Compute(Weak<ComputePipeline<A>>),
Render(Weak<RenderPipeline>),
Compute(Weak<ComputePipeline>),
}
impl<A: HalApi> std::fmt::Display for ExclusivePipeline<A> {
impl std::fmt::Display for ExclusivePipeline {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ExclusivePipeline::None => f.write_str("None"),
@ -498,9 +497,9 @@ impl<A: HalApi> std::fmt::Display for ExclusivePipeline<A> {
/// Bind group layout.
#[derive(Debug)]
pub struct BindGroupLayout<A: HalApi> {
pub struct BindGroupLayout {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynBindGroupLayout>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
pub(crate) entries: bgl::EntryMap,
/// It is very important that we know if the bind group comes from the BGL pool.
///
@ -509,14 +508,14 @@ pub struct BindGroupLayout<A: HalApi> {
/// We cannot unconditionally remove from the pool, as BGLs that don't come from the pool
/// (derived BGLs) must not be removed.
pub(crate) origin: bgl::Origin,
pub(crate) exclusive_pipeline: OnceCell<ExclusivePipeline<A>>,
pub(crate) exclusive_pipeline: OnceCell<ExclusivePipeline>,
#[allow(unused)]
pub(crate) binding_count_validator: BindingTypeMaxCountValidator,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
}
impl<A: HalApi> Drop for BindGroupLayout<A> {
impl Drop for BindGroupLayout {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
if matches!(self.origin, bgl::Origin::Pool) {
@ -530,12 +529,12 @@ impl<A: HalApi> Drop for BindGroupLayout<A> {
}
}
crate::impl_resource_type_generic!(BindGroupLayout);
crate::impl_resource_type!(BindGroupLayout);
crate::impl_labeled!(BindGroupLayout);
crate::impl_parent_device!(BindGroupLayout);
crate::impl_storage_item_generic!(BindGroupLayout);
crate::impl_storage_item!(BindGroupLayout);
impl<A: HalApi> BindGroupLayout<A> {
impl BindGroupLayout {
pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout {
self.raw.as_ref()
}
@ -631,14 +630,14 @@ pub struct PipelineLayoutDescriptor<'a> {
///
/// A `PipelineLayoutDescriptor` can be used to create a pipeline layout.
#[derive(Debug)]
pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> {
pub struct ResolvedPipelineLayoutDescriptor<'a> {
/// Debug label of the pipeline layout.
///
/// This will show up in graphics debuggers for easy identification.
pub label: Label<'a>,
/// Bind groups that this pipeline uses. The first entry will provide all the bindings for
/// "set = 0", second entry will provide all the bindings for "set = 1" etc.
pub bind_group_layouts: Cow<'a, [Arc<BindGroupLayout<A>>]>,
pub bind_group_layouts: Cow<'a, [Arc<BindGroupLayout>]>,
/// Set of push constant ranges this pipeline uses. Each shader stage that
/// uses push constants must define the range in push constant memory that
/// corresponds to its single `layout(push_constant)` uniform block.
@ -650,16 +649,16 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> {
}
#[derive(Debug)]
pub struct PipelineLayout<A: HalApi> {
pub struct PipelineLayout {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynPipelineLayout>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) bind_group_layouts: ArrayVec<Arc<BindGroupLayout<A>>, { hal::MAX_BIND_GROUPS }>,
pub(crate) bind_group_layouts: ArrayVec<Arc<BindGroupLayout>, { hal::MAX_BIND_GROUPS }>,
pub(crate) push_constant_ranges: ArrayVec<wgt::PushConstantRange, { SHADER_STAGE_COUNT }>,
}
impl<A: HalApi> Drop for PipelineLayout<A> {
impl Drop for PipelineLayout {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -670,7 +669,7 @@ impl<A: HalApi> Drop for PipelineLayout<A> {
}
}
impl<A: HalApi> PipelineLayout<A> {
impl PipelineLayout {
pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout {
self.raw.as_ref()
}
@ -761,10 +760,10 @@ impl<A: HalApi> PipelineLayout<A> {
}
}
crate::impl_resource_type_generic!(PipelineLayout);
crate::impl_resource_type!(PipelineLayout);
crate::impl_labeled!(PipelineLayout);
crate::impl_parent_device!(PipelineLayout);
crate::impl_storage_item_generic!(PipelineLayout);
crate::impl_storage_item!(PipelineLayout);
#[repr(C)]
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
@ -776,8 +775,8 @@ pub struct BufferBinding {
}
#[derive(Clone, Debug)]
pub struct ResolvedBufferBinding<A: HalApi> {
pub buffer: Arc<Buffer<A>>,
pub struct ResolvedBufferBinding {
pub buffer: Arc<Buffer>,
pub offset: wgt::BufferAddress,
pub size: Option<wgt::BufferSize>,
}
@ -798,13 +797,13 @@ pub enum BindingResource<'a> {
// Note: Duplicated in `wgpu-rs` as `BindingResource`
// They're different enough that it doesn't make sense to share a common type
#[derive(Debug, Clone)]
pub enum ResolvedBindingResource<'a, A: HalApi> {
Buffer(ResolvedBufferBinding<A>),
BufferArray(Cow<'a, [ResolvedBufferBinding<A>]>),
Sampler(Arc<Sampler<A>>),
SamplerArray(Cow<'a, [Arc<Sampler<A>>]>),
TextureView(Arc<TextureView<A>>),
TextureViewArray(Cow<'a, [Arc<TextureView<A>>]>),
pub enum ResolvedBindingResource<'a> {
Buffer(ResolvedBufferBinding),
BufferArray(Cow<'a, [ResolvedBufferBinding]>),
Sampler(Arc<Sampler>),
SamplerArray(Cow<'a, [Arc<Sampler>]>),
TextureView(Arc<TextureView>),
TextureViewArray(Cow<'a, [Arc<TextureView>]>),
}
#[derive(Clone, Debug, Error)]
@ -886,23 +885,23 @@ pub(crate) fn buffer_binding_type_alignment(
}
#[derive(Debug)]
pub struct BindGroup<A: HalApi> {
pub struct BindGroup {
pub(crate) raw: Snatchable<Box<dyn hal::DynBindGroup>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<BindGroupLayout<A>>,
pub(crate) device: Arc<Device>,
pub(crate) layout: Arc<BindGroupLayout>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) tracking_data: TrackingData,
pub(crate) used: BindGroupStates<A>,
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction<A>>,
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction<A>>,
pub(crate) used: BindGroupStates,
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction>,
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction>,
pub(crate) dynamic_binding_info: Vec<BindGroupDynamicBindingData>,
/// Actual binding sizes for buffers that don't have `min_binding_size`
/// specified in BGL. Listed in the order of iteration of `BGL.entries`.
pub(crate) late_buffer_binding_sizes: Vec<wgt::BufferSize>,
}
impl<A: HalApi> Drop for BindGroup<A> {
impl Drop for BindGroup {
fn drop(&mut self) {
if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw {}", self.error_ident());
@ -913,7 +912,7 @@ impl<A: HalApi> Drop for BindGroup<A> {
}
}
impl<A: HalApi> BindGroup<A> {
impl BindGroup {
pub(crate) fn try_raw<'a>(
&'a self,
guard: &'a SnatchGuard,
@ -985,10 +984,10 @@ impl<A: HalApi> BindGroup<A> {
}
}
crate::impl_resource_type_generic!(BindGroup);
crate::impl_resource_type!(BindGroup);
crate::impl_labeled!(BindGroup);
crate::impl_parent_device!(BindGroup);
crate::impl_storage_item_generic!(BindGroup);
crate::impl_storage_item!(BindGroup);
crate::impl_trackable!(BindGroup);
#[derive(Clone, Debug, Error)]

View File

@ -3,7 +3,6 @@ use std::sync::Arc;
use crate::{
binding_model::{BindGroup, LateMinBufferBindingSizeMismatch, PipelineLayout},
device::SHADER_STAGE_COUNT,
hal_api::HalApi,
pipeline::LateSizedBufferGroup,
resource::{Labeled, ResourceErrorIdent},
};
@ -19,7 +18,6 @@ mod compat {
use crate::{
binding_model::BindGroupLayout,
error::MultiError,
hal_api::HalApi,
resource::{Labeled, ParentDevice, ResourceErrorIdent},
};
use std::{
@ -38,12 +36,12 @@ mod compat {
}
#[derive(Debug, Clone)]
struct Entry<A: HalApi> {
assigned: Option<Arc<BindGroupLayout<A>>>,
expected: Option<Arc<BindGroupLayout<A>>>,
struct Entry {
assigned: Option<Arc<BindGroupLayout>>,
expected: Option<Arc<BindGroupLayout>>,
}
impl<A: HalApi> Entry<A> {
impl Entry {
fn empty() -> Self {
Self {
assigned: None,
@ -192,11 +190,11 @@ mod compat {
}
#[derive(Debug, Default)]
pub(crate) struct BoundBindGroupLayouts<A: HalApi> {
entries: ArrayVec<Entry<A>, { hal::MAX_BIND_GROUPS }>,
pub(crate) struct BoundBindGroupLayouts {
entries: ArrayVec<Entry, { hal::MAX_BIND_GROUPS }>,
}
impl<A: HalApi> BoundBindGroupLayouts<A> {
impl BoundBindGroupLayouts {
pub fn new() -> Self {
Self {
entries: (0..hal::MAX_BIND_GROUPS).map(|_| Entry::empty()).collect(),
@ -214,7 +212,7 @@ mod compat {
pub fn update_expectations(
&mut self,
expectations: &[Arc<BindGroupLayout<A>>],
expectations: &[Arc<BindGroupLayout>],
) -> Range<usize> {
let start_index = self
.entries
@ -236,7 +234,7 @@ mod compat {
self.make_range(start_index)
}
pub fn assign(&mut self, index: usize, value: Arc<BindGroupLayout<A>>) -> Range<usize> {
pub fn assign(&mut self, index: usize, value: Arc<BindGroupLayout>) -> Range<usize> {
self.entries[index].assigned = Some(value);
self.make_range(index)
}
@ -283,9 +281,9 @@ struct LateBufferBinding {
bound_size: wgt::BufferAddress,
}
#[derive(Debug)]
pub(super) struct EntryPayload<A: HalApi> {
pub(super) group: Option<Arc<BindGroup<A>>>,
#[derive(Debug, Default)]
pub(super) struct EntryPayload {
pub(super) group: Option<Arc<BindGroup>>,
pub(super) dynamic_offsets: Vec<wgt::DynamicOffset>,
late_buffer_bindings: Vec<LateBufferBinding>,
/// Since `LateBufferBinding` may contain information about the bindings
@ -293,18 +291,7 @@ pub(super) struct EntryPayload<A: HalApi> {
pub(super) late_bindings_effective_count: usize,
}
impl<A: HalApi> Default for EntryPayload<A> {
fn default() -> Self {
Self {
group: None,
dynamic_offsets: Default::default(),
late_buffer_bindings: Default::default(),
late_bindings_effective_count: Default::default(),
}
}
}
impl<A: HalApi> EntryPayload<A> {
impl EntryPayload {
fn reset(&mut self) {
self.group = None;
self.dynamic_offsets.clear();
@ -314,13 +301,13 @@ impl<A: HalApi> EntryPayload<A> {
}
#[derive(Debug, Default)]
pub(super) struct Binder<A: HalApi> {
pub(super) pipeline_layout: Option<Arc<PipelineLayout<A>>>,
manager: compat::BoundBindGroupLayouts<A>,
payloads: [EntryPayload<A>; hal::MAX_BIND_GROUPS],
pub(super) struct Binder {
pub(super) pipeline_layout: Option<Arc<PipelineLayout>>,
manager: compat::BoundBindGroupLayouts,
payloads: [EntryPayload; hal::MAX_BIND_GROUPS],
}
impl<A: HalApi> Binder<A> {
impl Binder {
pub(super) fn new() -> Self {
Self {
pipeline_layout: None,
@ -338,9 +325,9 @@ impl<A: HalApi> Binder<A> {
pub(super) fn change_pipeline_layout<'a>(
&'a mut self,
new: &Arc<PipelineLayout<A>>,
new: &Arc<PipelineLayout>,
late_sized_buffer_groups: &[LateSizedBufferGroup],
) -> (usize, &'a [EntryPayload<A>]) {
) -> (usize, &'a [EntryPayload]) {
let old_id_opt = self.pipeline_layout.replace(new.clone());
let mut bind_range = self.manager.update_expectations(&new.bind_group_layouts);
@ -380,9 +367,9 @@ impl<A: HalApi> Binder<A> {
pub(super) fn assign_group<'a>(
&'a mut self,
index: usize,
bind_group: &Arc<BindGroup<A>>,
bind_group: &Arc<BindGroup>,
offsets: &[wgt::DynamicOffset],
) -> &'a [EntryPayload<A>] {
) -> &'a [EntryPayload] {
let payload = &mut self.payloads[index];
payload.group = Some(bind_group.clone());
payload.dynamic_offsets.clear();
@ -412,7 +399,7 @@ impl<A: HalApi> Binder<A> {
&self.payloads[bind_range]
}
pub(super) fn list_active<'a>(&'a self) -> impl Iterator<Item = &'a Arc<BindGroup<A>>> + '_ {
pub(super) fn list_active<'a>(&'a self) -> impl Iterator<Item = &'a Arc<BindGroup>> + '_ {
let payloads = &self.payloads;
self.manager
.list_active()

View File

@ -88,7 +88,6 @@ use crate::{
AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext,
SHADER_STAGE_COUNT,
},
hal_api::HalApi,
hub::Hub,
id,
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
@ -110,8 +109,8 @@ use super::{
};
/// <https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-draw>
fn validate_draw<A: HalApi>(
vertex: &[Option<VertexState<A>>],
fn validate_draw(
vertex: &[Option<VertexState>],
step: &[VertexStep],
first_vertex: u32,
vertex_count: u32,
@ -151,10 +150,10 @@ fn validate_draw<A: HalApi>(
}
// See https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-drawindexed
fn validate_indexed_draw<A: HalApi>(
vertex: &[Option<VertexState<A>>],
fn validate_indexed_draw(
vertex: &[Option<VertexState>],
step: &[VertexStep],
index_state: &IndexState<A>,
index_state: &IndexState,
first_index: u32,
index_count: u32,
first_instance: u32,
@ -339,12 +338,12 @@ impl RenderBundleEncoder {
/// and accumulate buffer and texture initialization actions.
///
/// [`ExecuteBundle`]: RenderCommand::ExecuteBundle
pub(crate) fn finish<A: HalApi>(
pub(crate) fn finish(
self,
desc: &RenderBundleDescriptor,
device: &Arc<Device<A>>,
hub: &Hub<A>,
) -> Result<Arc<RenderBundle<A>>, RenderBundleError> {
device: &Arc<Device>,
hub: &Hub,
) -> Result<Arc<RenderBundle>, RenderBundleError> {
let scope = PassErrorScope::Bundle;
device.check_is_valid().map_pass_err(scope)?;
@ -577,9 +576,9 @@ impl RenderBundleEncoder {
}
}
fn set_bind_group<A: HalApi>(
state: &mut State<A>,
bind_group_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<BindGroup<A>>>,
fn set_bind_group(
state: &mut State,
bind_group_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<BindGroup>>,
dynamic_offsets: &[u32],
index: u32,
num_dynamic_offsets: usize,
@ -622,9 +621,9 @@ fn set_bind_group<A: HalApi>(
Ok(())
}
fn set_pipeline<A: HalApi>(
state: &mut State<A>,
pipeline_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<RenderPipeline<A>>>,
fn set_pipeline(
state: &mut State,
pipeline_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<RenderPipeline>>,
context: &RenderPassContext,
is_depth_read_only: bool,
is_stencil_read_only: bool,
@ -665,9 +664,9 @@ fn set_pipeline<A: HalApi>(
Ok(())
}
fn set_index_buffer<A: HalApi>(
state: &mut State<A>,
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Buffer<A>>>,
fn set_index_buffer(
state: &mut State,
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Buffer>>,
buffer_id: id::Id<id::markers::Buffer>,
index_format: wgt::IndexFormat,
offset: u64,
@ -700,9 +699,9 @@ fn set_index_buffer<A: HalApi>(
Ok(())
}
fn set_vertex_buffer<A: HalApi>(
state: &mut State<A>,
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Buffer<A>>>,
fn set_vertex_buffer(
state: &mut State,
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Buffer>>,
slot: u32,
buffer_id: id::Id<id::markers::Buffer>,
offset: u64,
@ -744,8 +743,8 @@ fn set_vertex_buffer<A: HalApi>(
Ok(())
}
fn set_push_constant<A: HalApi>(
state: &mut State<A>,
fn set_push_constant(
state: &mut State,
stages: wgt::ShaderStages,
offset: u32,
size_bytes: u32,
@ -769,8 +768,8 @@ fn set_push_constant<A: HalApi>(
Ok(())
}
fn draw<A: HalApi>(
state: &mut State<A>,
fn draw(
state: &mut State,
dynamic_offsets: &[u32],
vertex_count: u32,
instance_count: u32,
@ -802,8 +801,8 @@ fn draw<A: HalApi>(
Ok(())
}
fn draw_indexed<A: HalApi>(
state: &mut State<A>,
fn draw_indexed(
state: &mut State,
dynamic_offsets: &[u32],
index_count: u32,
instance_count: u32,
@ -843,10 +842,10 @@ fn draw_indexed<A: HalApi>(
Ok(())
}
fn multi_draw_indirect<A: HalApi>(
state: &mut State<A>,
fn multi_draw_indirect(
state: &mut State,
dynamic_offsets: &[u32],
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Buffer<A>>>,
buffer_guard: &crate::lock::RwLockReadGuard<crate::storage::Storage<Buffer>>,
buffer_id: id::Id<id::markers::Buffer>,
offset: u64,
indexed: bool,
@ -923,16 +922,16 @@ pub type RenderBundleDescriptor<'a> = wgt::RenderBundleDescriptor<Label<'a>>;
// The plan is to back it by an actual Vulkan secondary buffer, D3D12 Bundle,
// or Metal indirect command buffer.
#[derive(Debug)]
pub struct RenderBundle<A: HalApi> {
pub struct RenderBundle {
// Normalized command stream. It can be executed verbatim,
// without re-binding anything on the pipeline change.
base: BasePass<ArcRenderCommand<A>>,
base: BasePass<ArcRenderCommand>,
pub(super) is_depth_read_only: bool,
pub(super) is_stencil_read_only: bool,
pub(crate) device: Arc<Device<A>>,
pub(crate) used: RenderBundleScope<A>,
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction<A>>,
pub(crate) device: Arc<Device>,
pub(crate) used: RenderBundleScope,
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction>,
pub(super) context: RenderPassContext,
/// The `label` from the descriptor used to create the resource.
label: String,
@ -940,18 +939,18 @@ pub struct RenderBundle<A: HalApi> {
discard_hal_labels: bool,
}
impl<A: HalApi> Drop for RenderBundle<A> {
impl Drop for RenderBundle {
fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident());
}
}
#[cfg(send_sync)]
unsafe impl<A: HalApi> Send for RenderBundle<A> {}
unsafe impl Send for RenderBundle {}
#[cfg(send_sync)]
unsafe impl<A: HalApi> Sync for RenderBundle<A> {}
unsafe impl Sync for RenderBundle {}
impl<A: HalApi> RenderBundle<A> {
impl RenderBundle {
/// Actually encode the contents into a native command buffer.
///
/// This is partially duplicating the logic of `render_pass_end`.
@ -967,7 +966,7 @@ impl<A: HalApi> RenderBundle<A> {
snatch_guard: &SnatchGuard,
) -> Result<(), ExecutionError> {
let mut offsets = self.base.dynamic_offsets.as_slice();
let mut pipeline_layout = None::<Arc<PipelineLayout<A>>>;
let mut pipeline_layout = None::<Arc<PipelineLayout>>;
if !self.discard_hal_labels {
if let Some(ref label) = self.base.label {
unsafe { raw.begin_debug_marker(label) };
@ -1146,10 +1145,10 @@ impl<A: HalApi> RenderBundle<A> {
}
}
crate::impl_resource_type_generic!(RenderBundle);
crate::impl_resource_type!(RenderBundle);
crate::impl_labeled!(RenderBundle);
crate::impl_parent_device!(RenderBundle);
crate::impl_storage_item_generic!(RenderBundle);
crate::impl_storage_item!(RenderBundle);
crate::impl_trackable!(RenderBundle);
/// A render bundle's current index buffer state.
@ -1158,14 +1157,14 @@ crate::impl_trackable!(RenderBundle);
/// and calls [`State::flush_index`] before any indexed draw command to produce
/// a `SetIndexBuffer` command if one is necessary.
#[derive(Debug)]
struct IndexState<A: HalApi> {
buffer: Arc<Buffer<A>>,
struct IndexState {
buffer: Arc<Buffer>,
format: wgt::IndexFormat,
range: Range<wgt::BufferAddress>,
is_dirty: bool,
}
impl<A: HalApi> IndexState<A> {
impl IndexState {
/// Return the number of entries in the current index buffer.
///
/// Panic if no index buffer has been set.
@ -1180,7 +1179,7 @@ impl<A: HalApi> IndexState<A> {
/// Generate a `SetIndexBuffer` command to prepare for an indexed draw
/// command, if needed.
fn flush(&mut self) -> Option<ArcRenderCommand<A>> {
fn flush(&mut self) -> Option<ArcRenderCommand> {
if self.is_dirty {
self.is_dirty = false;
Some(ArcRenderCommand::SetIndexBuffer {
@ -1205,14 +1204,14 @@ impl<A: HalApi> IndexState<A> {
///
/// [`flush`]: IndexState::flush
#[derive(Debug)]
struct VertexState<A: HalApi> {
buffer: Arc<Buffer<A>>,
struct VertexState {
buffer: Arc<Buffer>,
range: Range<wgt::BufferAddress>,
is_dirty: bool,
}
impl<A: HalApi> VertexState<A> {
fn new(buffer: Arc<Buffer<A>>, range: Range<wgt::BufferAddress>) -> Self {
impl VertexState {
fn new(buffer: Arc<Buffer>, range: Range<wgt::BufferAddress>) -> Self {
Self {
buffer,
range,
@ -1223,7 +1222,7 @@ impl<A: HalApi> VertexState<A> {
/// Generate a `SetVertexBuffer` command for this slot, if necessary.
///
/// `slot` is the index of the vertex buffer slot that `self` tracks.
fn flush(&mut self, slot: u32) -> Option<ArcRenderCommand<A>> {
fn flush(&mut self, slot: u32) -> Option<ArcRenderCommand> {
if self.is_dirty {
self.is_dirty = false;
Some(ArcRenderCommand::SetVertexBuffer {
@ -1240,9 +1239,9 @@ impl<A: HalApi> VertexState<A> {
/// A bind group that has been set at a particular index during render bundle encoding.
#[derive(Debug)]
struct BindState<A: HalApi> {
struct BindState {
/// The id of the bind group set at this index.
bind_group: Arc<BindGroup<A>>,
bind_group: Arc<BindGroup>,
/// The range of dynamic offsets for this bind group, in the original
/// command stream's `BassPass::dynamic_offsets` array.
@ -1254,9 +1253,9 @@ struct BindState<A: HalApi> {
}
/// The bundle's current pipeline, and some cached information needed for validation.
struct PipelineState<A: HalApi> {
struct PipelineState {
/// The pipeline
pipeline: Arc<RenderPipeline<A>>,
pipeline: Arc<RenderPipeline>,
/// How this pipeline's vertex shader traverses each vertex buffer, indexed
/// by vertex buffer slot number.
@ -1270,8 +1269,8 @@ struct PipelineState<A: HalApi> {
used_bind_groups: usize,
}
impl<A: HalApi> PipelineState<A> {
fn new(pipeline: &Arc<RenderPipeline<A>>) -> Self {
impl PipelineState {
fn new(pipeline: &Arc<RenderPipeline>) -> Self {
Self {
pipeline: pipeline.clone(),
steps: pipeline.vertex_steps.to_vec(),
@ -1287,7 +1286,7 @@ impl<A: HalApi> PipelineState<A> {
/// Return a sequence of commands to zero the push constant ranges this
/// pipeline uses. If no initialization is necessary, return `None`.
fn zero_push_constants(&self) -> Option<impl Iterator<Item = ArcRenderCommand<A>>> {
fn zero_push_constants(&self) -> Option<impl Iterator<Item = ArcRenderCommand>> {
if !self.push_constant_ranges.is_empty() {
let nonoverlapping_ranges =
super::bind::compute_nonoverlapping_ranges(&self.push_constant_ranges);
@ -1318,22 +1317,22 @@ impl<A: HalApi> PipelineState<A> {
///
/// [`SetBindGroup`]: RenderCommand::SetBindGroup
/// [`SetIndexBuffer`]: RenderCommand::SetIndexBuffer
struct State<A: HalApi> {
struct State {
/// Resources used by this bundle. This will become [`RenderBundle::used`].
trackers: RenderBundleScope<A>,
trackers: RenderBundleScope,
/// The currently set pipeline, if any.
pipeline: Option<PipelineState<A>>,
pipeline: Option<PipelineState>,
/// The bind group set at each index, if any.
bind: ArrayVec<Option<BindState<A>>, { hal::MAX_BIND_GROUPS }>,
bind: ArrayVec<Option<BindState>, { hal::MAX_BIND_GROUPS }>,
/// The state of each vertex buffer slot.
vertex: ArrayVec<Option<VertexState<A>>, { hal::MAX_VERTEX_BUFFERS }>,
vertex: ArrayVec<Option<VertexState>, { hal::MAX_VERTEX_BUFFERS }>,
/// The current index buffer, if one has been set. We flush this state
/// before indexed draw commands.
index: Option<IndexState<A>>,
index: Option<IndexState>,
/// Dynamic offset values used by the cleaned-up command sequence.
///
@ -1343,16 +1342,16 @@ struct State<A: HalApi> {
/// [`dynamic_offsets`]: BasePass::dynamic_offsets
flat_dynamic_offsets: Vec<wgt::DynamicOffset>,
device: Arc<Device<A>>,
commands: Vec<ArcRenderCommand<A>>,
buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
texture_memory_init_actions: Vec<TextureInitTrackerAction<A>>,
device: Arc<Device>,
commands: Vec<ArcRenderCommand>,
buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
texture_memory_init_actions: Vec<TextureInitTrackerAction>,
next_dynamic_offset: usize,
}
impl<A: HalApi> State<A> {
impl State {
/// Return the current pipeline state. Return an error if none is set.
fn pipeline(&self) -> Result<&PipelineState<A>, RenderBundleErrorInner> {
fn pipeline(&self) -> Result<&PipelineState, RenderBundleErrorInner> {
self.pipeline
.as_ref()
.ok_or(DrawError::MissingPipeline.into())
@ -1368,7 +1367,7 @@ impl<A: HalApi> State<A> {
fn set_bind_group(
&mut self,
slot: u32,
bind_group: &Arc<BindGroup<A>>,
bind_group: &Arc<BindGroup>,
dynamic_offsets: Range<usize>,
) {
// If this call wouldn't actually change this index's state, we can
@ -1407,7 +1406,7 @@ impl<A: HalApi> State<A> {
///
/// - Changing the push constant ranges at all requires re-establishing
/// all bind groups.
fn invalidate_bind_groups(&mut self, new: &PipelineState<A>, layout: &PipelineLayout<A>) {
fn invalidate_bind_groups(&mut self, new: &PipelineState, layout: &PipelineLayout) {
match self.pipeline {
None => {
// Establishing entirely new pipeline state.
@ -1441,7 +1440,7 @@ impl<A: HalApi> State<A> {
/// Set the bundle's current index buffer and its associated parameters.
fn set_index_buffer(
&mut self,
buffer: Arc<Buffer<A>>,
buffer: Arc<Buffer>,
format: wgt::IndexFormat,
range: Range<wgt::BufferAddress>,
) {

View File

@ -8,7 +8,6 @@ use crate::{
device::DeviceError,
get_lowest_common_denom,
global::Global,
hal_api::HalApi,
id::{BufferId, CommandEncoderId, TextureId},
init_tracker::{MemoryInitKind, TextureInitRange},
resource::{
@ -79,7 +78,7 @@ whereas subesource range specified start {subresource_base_array_layer} and coun
}
impl Global {
pub fn command_encoder_clear_buffer<A: HalApi>(
pub fn command_encoder_clear_buffer(
&self,
command_encoder_id: CommandEncoderId,
dst: BufferId,
@ -89,7 +88,7 @@ impl Global {
profiling::scope!("CommandEncoder::clear_buffer");
api_log!("CommandEncoder::clear_buffer {dst:?}");
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers
@ -172,7 +171,7 @@ impl Global {
Ok(())
}
pub fn command_encoder_clear_texture<A: HalApi>(
pub fn command_encoder_clear_texture(
&self,
command_encoder_id: CommandEncoderId,
dst: TextureId,
@ -181,7 +180,7 @@ impl Global {
profiling::scope!("CommandEncoder::clear_texture");
api_log!("CommandEncoder::clear_texture {dst:?}");
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers
@ -268,8 +267,8 @@ impl Global {
}
}
pub(crate) fn clear_texture<A: HalApi, T: TextureTrackerSetSingle<A>>(
dst_texture: &Arc<Texture<A>>,
pub(crate) fn clear_texture<T: TextureTrackerSetSingle>(
dst_texture: &Arc<Texture>,
range: TextureInitRange,
encoder: &mut dyn hal::DynCommandEncoder,
texture_tracker: &mut T,
@ -440,8 +439,8 @@ fn clear_texture_via_buffer_copies(
}
}
fn clear_texture_via_render_passes<A: HalApi>(
dst_texture: &Texture<A>,
fn clear_texture_via_render_passes(
dst_texture: &Texture,
range: TextureInitRange,
is_color: bool,
encoder: &mut dyn hal::DynCommandEncoder,
@ -461,7 +460,7 @@ fn clear_texture_via_render_passes<A: HalApi>(
let (color_attachments, depth_stencil_attachment) = if is_color {
color_attachments_tmp = [Some(hal::ColorAttachment {
target: hal::Attachment {
view: Texture::<A>::get_clear_view(
view: Texture::get_clear_view(
&dst_texture.clear_mode,
&dst_texture.desc,
mip_level,
@ -479,7 +478,7 @@ fn clear_texture_via_render_passes<A: HalApi>(
&[][..],
Some(hal::DepthStencilAttachment {
target: hal::Attachment {
view: Texture::<A>::get_clear_view(
view: Texture::get_clear_view(
&dst_texture.clear_mode,
&dst_texture.desc,
mip_level,

View File

@ -13,7 +13,6 @@ use crate::{
},
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures},
global::Global,
hal_api::HalApi,
hal_label, id,
init_tracker::{BufferInitTrackerAction, MemoryInitKind},
pipeline::ComputePipeline,
@ -34,28 +33,28 @@ use std::{fmt, mem, str};
use super::{bind::BinderError, memory_init::CommandBufferTextureMemoryActions, DynComputePass};
pub struct ComputePass<A: HalApi> {
pub struct ComputePass {
/// All pass data & records is stored here.
///
/// If this is `None`, the pass is in the 'ended' state and can no longer be used.
/// Any attempt to record more commands will result in a validation error.
base: Option<BasePass<ArcComputeCommand<A>>>,
base: Option<BasePass<ArcComputeCommand>>,
/// Parent command buffer that this pass records commands into.
///
/// If it is none, this pass is invalid and any operation on it will return an error.
parent: Option<Arc<CommandBuffer<A>>>,
parent: Option<Arc<CommandBuffer>>,
timestamp_writes: Option<ArcPassTimestampWrites<A>>,
timestamp_writes: Option<ArcPassTimestampWrites>,
// Resource binding dedupe state.
current_bind_groups: BindGroupStateChange,
current_pipeline: StateChange<id::ComputePipelineId>,
}
impl<A: HalApi> ComputePass<A> {
impl ComputePass {
/// If the parent command buffer is invalid, the returned pass will be invalid.
fn new(parent: Option<Arc<CommandBuffer<A>>>, desc: ArcComputePassDescriptor<A>) -> Self {
fn new(parent: Option<Arc<CommandBuffer>>, desc: ArcComputePassDescriptor) -> Self {
let ArcComputePassDescriptor {
label,
timestamp_writes,
@ -79,7 +78,7 @@ impl<A: HalApi> ComputePass<A> {
fn base_mut<'a>(
&'a mut self,
scope: PassErrorScope,
) -> Result<&'a mut BasePass<ArcComputeCommand<A>>, ComputePassError> {
) -> Result<&'a mut BasePass<ArcComputeCommand>, ComputePassError> {
self.base
.as_mut()
.ok_or(ComputePassErrorInner::PassEnded)
@ -87,7 +86,7 @@ impl<A: HalApi> ComputePass<A> {
}
}
impl<A: HalApi> fmt::Debug for ComputePass<A> {
impl fmt::Debug for ComputePass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.parent {
Some(ref cmd_buf) => write!(f, "ComputePass {{ parent: {} }}", cmd_buf.error_ident()),
@ -103,10 +102,10 @@ pub struct ComputePassDescriptor<'a> {
pub timestamp_writes: Option<&'a PassTimestampWrites>,
}
struct ArcComputePassDescriptor<'a, A: HalApi> {
struct ArcComputePassDescriptor<'a> {
pub label: &'a Label<'a>,
/// Defines where and when timestamp values will be written for this pass.
pub timestamp_writes: Option<ArcPassTimestampWrites<A>>,
pub timestamp_writes: Option<ArcPassTimestampWrites>,
}
#[derive(Clone, Debug, Error)]
@ -200,36 +199,36 @@ where
}
}
struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> {
binder: Binder<A>,
pipeline: Option<Arc<ComputePipeline<A>>>,
scope: UsageScope<'scope, A>,
struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> {
binder: Binder,
pipeline: Option<Arc<ComputePipeline>>,
scope: UsageScope<'scope>,
debug_scope_depth: u32,
snatch_guard: SnatchGuard<'snatch_guard>,
device: &'cmd_buf Arc<Device<A>>,
device: &'cmd_buf Arc<Device>,
raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder,
tracker: &'cmd_buf mut Tracker<A>,
buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction<A>>,
texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions<A>,
tracker: &'cmd_buf mut Tracker,
buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction>,
texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions,
temp_offsets: Vec<u32>,
dynamic_offset_count: usize,
string_offset: usize,
active_query: Option<(Arc<resource::QuerySet<A>>, u32)>,
active_query: Option<(Arc<resource::QuerySet>, u32)>,
intermediate_trackers: Tracker<A>,
intermediate_trackers: Tracker,
/// Immediate texture inits required because of prior discards. Need to
/// be inserted before texture reads.
pending_discard_init_fixups: SurfacesInDiscardState<A>,
pending_discard_init_fixups: SurfacesInDiscardState,
}
impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi>
State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A>
impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder>
State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder>
{
fn is_ready(&self) -> Result<(), DispatchError> {
if let Some(pipeline) = self.pipeline.as_ref() {
@ -285,12 +284,12 @@ impl Global {
/// Any operation on an invalid pass will return an error.
///
/// If successful, puts the encoder into the [`CommandEncoderStatus::Locked`] state.
pub fn command_encoder_create_compute_pass<A: HalApi>(
pub fn command_encoder_create_compute_pass(
&self,
encoder_id: id::CommandEncoderId,
desc: &ComputePassDescriptor<'_>,
) -> (ComputePass<A>, Option<CommandEncoderError>) {
let hub = A::hub(self);
) -> (ComputePass, Option<CommandEncoderError>) {
let hub = &self.hub;
let mut arc_desc = ArcComputePassDescriptor {
label: &desc.label,
@ -333,19 +332,16 @@ impl Global {
///
/// If creation fails, an invalid pass is returned.
/// Any operation on an invalid pass will return an error.
pub fn command_encoder_create_compute_pass_dyn<A: HalApi>(
pub fn command_encoder_create_compute_pass_dyn(
&self,
encoder_id: id::CommandEncoderId,
desc: &ComputePassDescriptor,
) -> (Box<dyn DynComputePass>, Option<CommandEncoderError>) {
let (pass, err) = self.command_encoder_create_compute_pass::<A>(encoder_id, desc);
let (pass, err) = self.command_encoder_create_compute_pass(encoder_id, desc);
(Box::new(pass), err)
}
pub fn compute_pass_end<A: HalApi>(
&self,
pass: &mut ComputePass<A>,
) -> Result<(), ComputePassError> {
pub fn compute_pass_end(&self, pass: &mut ComputePass) -> Result<(), ComputePassError> {
let scope = PassErrorScope::Pass;
let cmd_buf = pass
@ -366,13 +362,13 @@ impl Global {
#[doc(hidden)]
#[cfg(any(feature = "serde", feature = "replay"))]
pub fn compute_pass_end_with_unresolved_commands<A: HalApi>(
pub fn compute_pass_end_with_unresolved_commands(
&self,
encoder_id: id::CommandEncoderId,
base: BasePass<super::ComputeCommand>,
timestamp_writes: Option<&PassTimestampWrites>,
) -> Result<(), ComputePassError> {
let hub = A::hub(self);
let hub = &self.hub;
let scope = PassErrorScope::Pass;
let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) {
@ -400,7 +396,7 @@ impl Global {
}
let commands =
super::ComputeCommand::resolve_compute_command_ids(A::hub(self), &base.commands)?;
super::ComputeCommand::resolve_compute_command_ids(&self.hub, &base.commands)?;
let timestamp_writes = if let Some(tw) = timestamp_writes {
Some(ArcPassTimestampWrites {
@ -416,7 +412,7 @@ impl Global {
None
};
self.compute_pass_end_impl::<A>(
self.compute_pass_end_impl(
&cmd_buf,
BasePass {
label: base.label,
@ -429,11 +425,11 @@ impl Global {
)
}
fn compute_pass_end_impl<A: HalApi>(
fn compute_pass_end_impl(
&self,
cmd_buf: &CommandBuffer<A>,
base: BasePass<ArcComputeCommand<A>>,
mut timestamp_writes: Option<ArcPassTimestampWrites<A>>,
cmd_buf: &CommandBuffer,
base: BasePass<ArcComputeCommand>,
mut timestamp_writes: Option<ArcPassTimestampWrites>,
) -> Result<(), ComputePassError> {
profiling::scope!("CommandEncoder::run_compute_pass");
let pass_scope = PassErrorScope::Pass;
@ -660,13 +656,13 @@ impl Global {
}
}
fn set_bind_group<A: HalApi>(
state: &mut State<A>,
cmd_buf: &CommandBuffer<A>,
fn set_bind_group(
state: &mut State,
cmd_buf: &CommandBuffer,
dynamic_offsets: &[DynamicOffset],
index: u32,
num_dynamic_offsets: usize,
bind_group: Arc<BindGroup<A>>,
bind_group: Arc<BindGroup>,
) -> Result<(), ComputePassErrorInner> {
bind_group.same_device_as(cmd_buf)?;
@ -727,10 +723,10 @@ fn set_bind_group<A: HalApi>(
Ok(())
}
fn set_pipeline<A: HalApi>(
state: &mut State<A>,
cmd_buf: &CommandBuffer<A>,
pipeline: Arc<ComputePipeline<A>>,
fn set_pipeline(
state: &mut State,
cmd_buf: &CommandBuffer,
pipeline: Arc<ComputePipeline>,
) -> Result<(), ComputePassErrorInner> {
pipeline.same_device_as(cmd_buf)?;
@ -789,8 +785,8 @@ fn set_pipeline<A: HalApi>(
Ok(())
}
fn set_push_constant<A: HalApi>(
state: &mut State<A>,
fn set_push_constant(
state: &mut State,
push_constant_data: &[u32],
offset: u32,
size_bytes: u32,
@ -826,10 +822,7 @@ fn set_push_constant<A: HalApi>(
Ok(())
}
fn dispatch<A: HalApi>(
state: &mut State<A>,
groups: [u32; 3],
) -> Result<(), ComputePassErrorInner> {
fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorInner> {
state.is_ready()?;
state.flush_states(None)?;
@ -854,10 +847,10 @@ fn dispatch<A: HalApi>(
Ok(())
}
fn dispatch_indirect<A: HalApi>(
state: &mut State<A>,
cmd_buf: &CommandBuffer<A>,
buffer: Arc<Buffer<A>>,
fn dispatch_indirect(
state: &mut State,
cmd_buf: &CommandBuffer,
buffer: Arc<Buffer>,
offset: u64,
) -> Result<(), ComputePassErrorInner> {
buffer.same_device_as(cmd_buf)?;
@ -902,7 +895,7 @@ fn dispatch_indirect<A: HalApi>(
Ok(())
}
fn push_debug_group<A: HalApi>(state: &mut State<A>, string_data: &[u8], len: usize) {
fn push_debug_group(state: &mut State, string_data: &[u8], len: usize) {
state.debug_scope_depth += 1;
if !state
.device
@ -918,7 +911,7 @@ fn push_debug_group<A: HalApi>(state: &mut State<A>, string_data: &[u8], len: us
state.string_offset += len;
}
fn pop_debug_group<A: HalApi>(state: &mut State<A>) -> Result<(), ComputePassErrorInner> {
fn pop_debug_group(state: &mut State) -> Result<(), ComputePassErrorInner> {
if state.debug_scope_depth == 0 {
return Err(ComputePassErrorInner::InvalidPopDebugGroup);
}
@ -935,7 +928,7 @@ fn pop_debug_group<A: HalApi>(state: &mut State<A>) -> Result<(), ComputePassErr
Ok(())
}
fn insert_debug_marker<A: HalApi>(state: &mut State<A>, string_data: &[u8], len: usize) {
fn insert_debug_marker(state: &mut State, string_data: &[u8], len: usize) {
if !state
.device
.instance_flags
@ -948,10 +941,10 @@ fn insert_debug_marker<A: HalApi>(state: &mut State<A>, string_data: &[u8], len:
state.string_offset += len;
}
fn write_timestamp<A: HalApi>(
state: &mut State<A>,
cmd_buf: &CommandBuffer<A>,
query_set: Arc<resource::QuerySet<A>>,
fn write_timestamp(
state: &mut State,
cmd_buf: &CommandBuffer,
query_set: Arc<resource::QuerySet>,
query_index: u32,
) -> Result<(), ComputePassErrorInner> {
query_set.same_device_as(cmd_buf)?;
@ -968,9 +961,9 @@ fn write_timestamp<A: HalApi>(
// Recording a compute pass.
impl Global {
pub fn compute_pass_set_bind_group<A: HalApi>(
pub fn compute_pass_set_bind_group(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
index: u32,
bind_group_id: id::BindGroupId,
offsets: &[DynamicOffset],
@ -993,7 +986,7 @@ impl Global {
return Ok(());
}
let hub = A::hub(self);
let hub = &self.hub;
let bind_group = hub
.bind_groups
.get(bind_group_id)
@ -1009,9 +1002,9 @@ impl Global {
Ok(())
}
pub fn compute_pass_set_pipeline<A: HalApi>(
pub fn compute_pass_set_pipeline(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
pipeline_id: id::ComputePipelineId,
) -> Result<(), ComputePassError> {
let redundant = pass.current_pipeline.set_and_check_redundant(pipeline_id);
@ -1024,7 +1017,7 @@ impl Global {
return Ok(());
}
let hub = A::hub(self);
let hub = &self.hub;
let pipeline = hub
.compute_pipelines
.get(pipeline_id)
@ -1036,9 +1029,9 @@ impl Global {
Ok(())
}
pub fn compute_pass_set_push_constants<A: HalApi>(
pub fn compute_pass_set_push_constants(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
offset: u32,
data: &[u8],
) -> Result<(), ComputePassError> {
@ -1064,7 +1057,7 @@ impl Global {
.map(|arr| u32::from_ne_bytes([arr[0], arr[1], arr[2], arr[3]])),
);
base.commands.push(ArcComputeCommand::<A>::SetPushConstant {
base.commands.push(ArcComputeCommand::SetPushConstant {
offset,
size_bytes: data.len() as u32,
values_offset: value_offset,
@ -1073,9 +1066,9 @@ impl Global {
Ok(())
}
pub fn compute_pass_dispatch_workgroups<A: HalApi>(
pub fn compute_pass_dispatch_workgroups(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
groups_x: u32,
groups_y: u32,
groups_z: u32,
@ -1083,20 +1076,19 @@ impl Global {
let scope = PassErrorScope::Dispatch { indirect: false };
let base = pass.base_mut(scope)?;
base.commands.push(ArcComputeCommand::<A>::Dispatch([
groups_x, groups_y, groups_z,
]));
base.commands
.push(ArcComputeCommand::Dispatch([groups_x, groups_y, groups_z]));
Ok(())
}
pub fn compute_pass_dispatch_workgroups_indirect<A: HalApi>(
pub fn compute_pass_dispatch_workgroups_indirect(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
buffer_id: id::BufferId,
offset: BufferAddress,
) -> Result<(), ComputePassError> {
let hub = A::hub(self);
let hub = &self.hub;
let scope = PassErrorScope::Dispatch { indirect: true };
let base = pass.base_mut(scope)?;
@ -1107,14 +1099,14 @@ impl Global {
.map_pass_err(scope)?;
base.commands
.push(ArcComputeCommand::<A>::DispatchIndirect { buffer, offset });
.push(ArcComputeCommand::DispatchIndirect { buffer, offset });
Ok(())
}
pub fn compute_pass_push_debug_group<A: HalApi>(
pub fn compute_pass_push_debug_group(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
label: &str,
color: u32,
) -> Result<(), ComputePassError> {
@ -1123,7 +1115,7 @@ impl Global {
let bytes = label.as_bytes();
base.string_data.extend_from_slice(bytes);
base.commands.push(ArcComputeCommand::<A>::PushDebugGroup {
base.commands.push(ArcComputeCommand::PushDebugGroup {
color,
len: bytes.len(),
});
@ -1131,20 +1123,20 @@ impl Global {
Ok(())
}
pub fn compute_pass_pop_debug_group<A: HalApi>(
pub fn compute_pass_pop_debug_group(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
) -> Result<(), ComputePassError> {
let base = pass.base_mut(PassErrorScope::PopDebugGroup)?;
base.commands.push(ArcComputeCommand::<A>::PopDebugGroup);
base.commands.push(ArcComputeCommand::PopDebugGroup);
Ok(())
}
pub fn compute_pass_insert_debug_marker<A: HalApi>(
pub fn compute_pass_insert_debug_marker(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
label: &str,
color: u32,
) -> Result<(), ComputePassError> {
@ -1153,8 +1145,7 @@ impl Global {
let bytes = label.as_bytes();
base.string_data.extend_from_slice(bytes);
base.commands
.push(ArcComputeCommand::<A>::InsertDebugMarker {
base.commands.push(ArcComputeCommand::InsertDebugMarker {
color,
len: bytes.len(),
});
@ -1162,16 +1153,16 @@ impl Global {
Ok(())
}
pub fn compute_pass_write_timestamp<A: HalApi>(
pub fn compute_pass_write_timestamp(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
query_set_id: id::QuerySetId,
query_index: u32,
) -> Result<(), ComputePassError> {
let scope = PassErrorScope::WriteTimestamp;
let base = pass.base_mut(scope)?;
let hub = A::hub(self);
let hub = &self.hub;
let query_set = hub
.query_sets
.get(query_set_id)
@ -1186,16 +1177,16 @@ impl Global {
Ok(())
}
pub fn compute_pass_begin_pipeline_statistics_query<A: HalApi>(
pub fn compute_pass_begin_pipeline_statistics_query(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
query_set_id: id::QuerySetId,
query_index: u32,
) -> Result<(), ComputePassError> {
let scope = PassErrorScope::BeginPipelineStatisticsQuery;
let base = pass.base_mut(scope)?;
let hub = A::hub(self);
let hub = &self.hub;
let query_set = hub
.query_sets
.get(query_set_id)
@ -1211,14 +1202,14 @@ impl Global {
Ok(())
}
pub fn compute_pass_end_pipeline_statistics_query<A: HalApi>(
pub fn compute_pass_end_pipeline_statistics_query(
&self,
pass: &mut ComputePass<A>,
pass: &mut ComputePass,
) -> Result<(), ComputePassError> {
let scope = PassErrorScope::EndPipelineStatisticsQuery;
let base = pass.base_mut(scope)?;
base.commands
.push(ArcComputeCommand::<A>::EndPipelineStatisticsQuery);
.push(ArcComputeCommand::EndPipelineStatisticsQuery);
Ok(())
}

View File

@ -2,7 +2,6 @@ use std::sync::Arc;
use crate::{
binding_model::BindGroup,
hal_api::HalApi,
id,
pipeline::ComputePipeline,
resource::{Buffer, QuerySet},
@ -71,10 +70,10 @@ pub enum ComputeCommand {
impl ComputeCommand {
/// Resolves all ids in a list of commands into the corresponding resource Arc.
#[cfg(any(feature = "serde", feature = "replay"))]
pub fn resolve_compute_command_ids<A: HalApi>(
hub: &crate::hub::Hub<A>,
pub fn resolve_compute_command_ids(
hub: &crate::hub::Hub,
commands: &[ComputeCommand],
) -> Result<Vec<ArcComputeCommand<A>>, super::ComputePassError> {
) -> Result<Vec<ArcComputeCommand>, super::ComputePassError> {
use super::{ComputePassError, ComputePassErrorInner, PassErrorScope};
let buffers_guard = hub.buffers.read();
@ -82,9 +81,9 @@ impl ComputeCommand {
let query_set_guard = hub.query_sets.read();
let pipelines_guard = hub.compute_pipelines.read();
let resolved_commands: Vec<ArcComputeCommand<A>> = commands
let resolved_commands: Vec<ArcComputeCommand> = commands
.iter()
.map(|c| -> Result<ArcComputeCommand<A>, ComputePassError> {
.map(|c| -> Result<ArcComputeCommand, ComputePassError> {
Ok(match *c {
ComputeCommand::SetBindGroup {
index,
@ -182,14 +181,14 @@ impl ComputeCommand {
/// Equivalent to `ComputeCommand` but the Ids resolved into resource Arcs.
#[derive(Clone, Debug)]
pub enum ArcComputeCommand<A: HalApi> {
pub enum ArcComputeCommand {
SetBindGroup {
index: u32,
num_dynamic_offsets: usize,
bind_group: Arc<BindGroup<A>>,
bind_group: Arc<BindGroup>,
},
SetPipeline(Arc<ComputePipeline<A>>),
SetPipeline(Arc<ComputePipeline>),
/// Set a range of push constants to values stored in `push_constant_data`.
SetPushConstant {
@ -211,7 +210,7 @@ pub enum ArcComputeCommand<A: HalApi> {
Dispatch([u32; 3]),
DispatchIndirect {
buffer: Arc<Buffer<A>>,
buffer: Arc<Buffer>,
offset: wgt::BufferAddress,
},
@ -228,12 +227,12 @@ pub enum ArcComputeCommand<A: HalApi> {
},
WriteTimestamp {
query_set: Arc<QuerySet<A>>,
query_set: Arc<QuerySet>,
query_index: u32,
},
BeginPipelineStatisticsQuery {
query_set: Arc<QuerySet<A>>,
query_set: Arc<QuerySet>,
query_index: u32,
},

View File

@ -1,6 +1,6 @@
use wgt::WasmNotSendSync;
use crate::{global, hal_api::HalApi, id};
use crate::{global, id};
use super::{ComputePass, ComputePassError};
@ -74,7 +74,7 @@ pub trait DynComputePass: std::fmt::Debug + WasmNotSendSync {
fn label(&self) -> Option<&str>;
}
impl<A: HalApi> DynComputePass for ComputePass<A> {
impl DynComputePass for ComputePass {
fn set_bind_group(
&mut self,
context: &global::Global,

View File

@ -1,6 +1,6 @@
use wgt::WasmNotSendSync;
use crate::{global, hal_api::HalApi, id};
use crate::{global, id};
use super::{RenderPass, RenderPassError};
@ -178,7 +178,7 @@ pub trait DynRenderPass: std::fmt::Debug + WasmNotSendSync {
fn label(&self) -> Option<&str>;
}
impl<A: HalApi> DynRenderPass for RenderPass<A> {
impl DynRenderPass for RenderPass {
fn set_index_buffer(
&mut self,
context: &global::Global,

View File

@ -2,7 +2,6 @@ use std::{collections::hash_map::Entry, ops::Range, sync::Arc, vec::Drain};
use crate::{
device::Device,
hal_api::HalApi,
init_tracker::*,
resource::{DestroyedResourceError, ParentDevice, Texture, Trackable},
snatch::SnatchGuard,
@ -15,39 +14,31 @@ use super::{clear::clear_texture, BakedCommands, ClearError};
/// Surface that was discarded by `StoreOp::Discard` of a preceding renderpass.
/// Any read access to this surface needs to be preceded by a texture initialization.
#[derive(Clone)]
pub(crate) struct TextureSurfaceDiscard<A: HalApi> {
pub texture: Arc<Texture<A>>,
pub(crate) struct TextureSurfaceDiscard {
pub texture: Arc<Texture>,
pub mip_level: u32,
pub layer: u32,
}
pub(crate) type SurfacesInDiscardState<A> = Vec<TextureSurfaceDiscard<A>>;
pub(crate) type SurfacesInDiscardState = Vec<TextureSurfaceDiscard>;
pub(crate) struct CommandBufferTextureMemoryActions<A: HalApi> {
#[derive(Default)]
pub(crate) struct CommandBufferTextureMemoryActions {
/// The tracker actions that we need to be executed before the command
/// buffer is executed.
init_actions: Vec<TextureInitTrackerAction<A>>,
init_actions: Vec<TextureInitTrackerAction>,
/// All the discards that haven't been followed by init again within the
/// command buffer i.e. everything in this list resets the texture init
/// state *after* the command buffer execution
discards: Vec<TextureSurfaceDiscard<A>>,
discards: Vec<TextureSurfaceDiscard>,
}
impl<A: HalApi> Default for CommandBufferTextureMemoryActions<A> {
fn default() -> Self {
Self {
init_actions: Default::default(),
discards: Default::default(),
}
}
}
impl<A: HalApi> CommandBufferTextureMemoryActions<A> {
pub(crate) fn drain_init_actions(&mut self) -> Drain<TextureInitTrackerAction<A>> {
impl CommandBufferTextureMemoryActions {
pub(crate) fn drain_init_actions(&mut self) -> Drain<TextureInitTrackerAction> {
self.init_actions.drain(..)
}
pub(crate) fn discard(&mut self, discard: TextureSurfaceDiscard<A>) {
pub(crate) fn discard(&mut self, discard: TextureSurfaceDiscard) {
self.discards.push(discard);
}
@ -57,8 +48,8 @@ impl<A: HalApi> CommandBufferTextureMemoryActions<A> {
#[must_use]
pub(crate) fn register_init_action(
&mut self,
action: &TextureInitTrackerAction<A>,
) -> SurfacesInDiscardState<A> {
action: &TextureInitTrackerAction,
) -> SurfacesInDiscardState {
let mut immediately_necessary_clears = SurfacesInDiscardState::new();
// Note that within a command buffer we may stack arbitrary memory init
@ -117,7 +108,7 @@ impl<A: HalApi> CommandBufferTextureMemoryActions<A> {
// implicit init, not requiring any immediate resource init.
pub(crate) fn register_implicit_init(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
range: TextureInitRange,
) {
let must_be_empty = self.register_init_action(&TextureInitTrackerAction {
@ -133,14 +124,11 @@ impl<A: HalApi> CommandBufferTextureMemoryActions<A> {
// register_init_action and initializes them on the spot.
//
// Takes care of barriers as well!
pub(crate) fn fixup_discarded_surfaces<
A: HalApi,
InitIter: Iterator<Item = TextureSurfaceDiscard<A>>,
>(
pub(crate) fn fixup_discarded_surfaces<InitIter: Iterator<Item = TextureSurfaceDiscard>>(
inits: InitIter,
encoder: &mut dyn hal::DynCommandEncoder,
texture_tracker: &mut TextureTracker<A>,
device: &Device<A>,
texture_tracker: &mut TextureTracker,
device: &Device,
snatch_guard: &SnatchGuard<'_>,
) {
for init in inits {
@ -160,12 +148,12 @@ pub(crate) fn fixup_discarded_surfaces<
}
}
impl<A: HalApi> BakedCommands<A> {
impl BakedCommands {
// inserts all buffer initializations that are going to be needed for
// executing the commands and updates resource init states accordingly
pub(crate) fn initialize_buffer_memory(
&mut self,
device_tracker: &mut DeviceTracker<A>,
device_tracker: &mut DeviceTracker,
snatch_guard: &SnatchGuard<'_>,
) -> Result<(), DestroyedResourceError> {
profiling::scope!("initialize_buffer_memory");
@ -265,8 +253,8 @@ impl<A: HalApi> BakedCommands<A> {
// uninitialized
pub(crate) fn initialize_texture_memory(
&mut self,
device_tracker: &mut DeviceTracker<A>,
device: &Device<A>,
device_tracker: &mut DeviceTracker,
device: &Device,
snatch_guard: &SnatchGuard<'_>,
) -> Result<(), DestroyedResourceError> {
profiling::scope!("initialize_texture_memory");

View File

@ -37,7 +37,7 @@ use crate::init_tracker::BufferInitTrackerAction;
use crate::resource::Labeled;
use crate::track::{DeviceTracker, Tracker, UsageScope};
use crate::LabelHelpers;
use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label};
use crate::{api_log, global::Global, id, resource_log, Label};
use thiserror::Error;
@ -240,16 +240,16 @@ impl CommandEncoder {
}
}
pub(crate) struct BakedCommands<A: HalApi> {
pub(crate) struct BakedCommands {
pub(crate) encoder: Box<dyn hal::DynCommandEncoder>,
pub(crate) list: Vec<Box<dyn hal::DynCommandBuffer>>,
pub(crate) trackers: Tracker<A>,
buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
texture_memory_actions: CommandBufferTextureMemoryActions<A>,
pub(crate) trackers: Tracker,
buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
texture_memory_actions: CommandBufferTextureMemoryActions,
}
/// The mutable state of a [`CommandBuffer`].
pub struct CommandBufferMutable<A: HalApi> {
pub struct CommandBufferMutable {
/// The [`wgpu_hal::Api::CommandBuffer`]s we've built so far, and the encoder
/// they belong to.
///
@ -260,7 +260,7 @@ pub struct CommandBufferMutable<A: HalApi> {
status: CommandEncoderStatus,
/// All the resources that the commands recorded so far have referred to.
pub(crate) trackers: Tracker<A>,
pub(crate) trackers: Tracker,
/// The regions of buffers and textures these commands will read and write.
///
@ -268,18 +268,18 @@ pub struct CommandBufferMutable<A: HalApi> {
/// buffers/textures we actually need to initialize. If we're
/// definitely going to write to something before we read from it,
/// we don't need to clear its contents.
buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
texture_memory_actions: CommandBufferTextureMemoryActions<A>,
buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
texture_memory_actions: CommandBufferTextureMemoryActions,
pub(crate) pending_query_resets: QueryResetMap<A>,
pub(crate) pending_query_resets: QueryResetMap,
#[cfg(feature = "trace")]
pub(crate) commands: Option<Vec<TraceCommand>>,
}
impl<A: HalApi> CommandBufferMutable<A> {
impl CommandBufferMutable {
pub(crate) fn open_encoder_and_tracker(
&mut self,
) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker<A>), DeviceError> {
) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> {
let encoder = self.encoder.open()?;
let tracker = &mut self.trackers;
@ -305,8 +305,8 @@ impl<A: HalApi> CommandBufferMutable<A> {
/// - Once a command buffer is submitted to the queue, it is removed from the id
/// registry, and its contents are taken to construct a [`BakedCommands`],
/// whose contents eventually become the property of the submission queue.
pub struct CommandBuffer<A: HalApi> {
pub(crate) device: Arc<Device<A>>,
pub struct CommandBuffer {
pub(crate) device: Arc<Device>,
support_clear_texture: bool,
/// The `label` from the descriptor used to create the resource.
label: String,
@ -317,10 +317,10 @@ pub struct CommandBuffer<A: HalApi> {
/// When this is submitted, dropped, or destroyed, its contents are
/// extracted into a [`BakedCommands`] by
/// [`CommandBuffer::extract_baked_commands`].
pub(crate) data: Mutex<Option<CommandBufferMutable<A>>>,
pub(crate) data: Mutex<Option<CommandBufferMutable>>,
}
impl<A: HalApi> Drop for CommandBuffer<A> {
impl Drop for CommandBuffer {
fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident());
if self.data.lock().is_none() {
@ -336,10 +336,10 @@ impl<A: HalApi> Drop for CommandBuffer<A> {
}
}
impl<A: HalApi> CommandBuffer<A> {
impl CommandBuffer {
pub(crate) fn new(
encoder: Box<dyn hal::DynCommandEncoder>,
device: &Arc<Device<A>>,
device: &Arc<Device>,
label: &Label,
) -> Self {
CommandBuffer {
@ -373,8 +373,8 @@ impl<A: HalApi> CommandBuffer<A> {
pub(crate) fn insert_barriers_from_tracker(
raw: &mut dyn hal::DynCommandEncoder,
base: &mut Tracker<A>,
head: &Tracker<A>,
base: &mut Tracker,
head: &Tracker,
snatch_guard: &SnatchGuard,
) {
profiling::scope!("insert_barriers");
@ -387,8 +387,8 @@ impl<A: HalApi> CommandBuffer<A> {
pub(crate) fn insert_barriers_from_scope(
raw: &mut dyn hal::DynCommandEncoder,
base: &mut Tracker<A>,
head: &UsageScope<A>,
base: &mut Tracker,
head: &UsageScope,
snatch_guard: &SnatchGuard,
) {
profiling::scope!("insert_barriers");
@ -401,7 +401,7 @@ impl<A: HalApi> CommandBuffer<A> {
pub(crate) fn drain_barriers(
raw: &mut dyn hal::DynCommandEncoder,
base: &mut Tracker<A>,
base: &mut Tracker,
snatch_guard: &SnatchGuard,
) {
profiling::scope!("drain_barriers");
@ -425,8 +425,8 @@ impl<A: HalApi> CommandBuffer<A> {
pub(crate) fn insert_barriers_from_device_tracker(
raw: &mut dyn hal::DynCommandEncoder,
base: &mut DeviceTracker<A>,
head: &Tracker<A>,
base: &mut DeviceTracker,
head: &Tracker,
snatch_guard: &SnatchGuard,
) {
profiling::scope!("insert_barriers_from_device_tracker");
@ -448,7 +448,7 @@ impl<A: HalApi> CommandBuffer<A> {
}
}
impl<A: HalApi> CommandBuffer<A> {
impl CommandBuffer {
fn lock_encoder_impl(&self, lock: bool) -> Result<(), CommandEncoderError> {
let mut cmd_buf_data_guard = self.data.lock();
let cmd_buf_data = cmd_buf_data_guard.as_mut().unwrap();
@ -508,7 +508,7 @@ impl<A: HalApi> CommandBuffer<A> {
}
}
pub(crate) fn extract_baked_commands(&mut self) -> BakedCommands<A> {
pub(crate) fn extract_baked_commands(&mut self) -> BakedCommands {
let data = self.data.lock().take().unwrap();
BakedCommands {
encoder: data.encoder.raw,
@ -519,17 +519,17 @@ impl<A: HalApi> CommandBuffer<A> {
}
}
pub(crate) fn from_arc_into_baked(self: Arc<Self>) -> BakedCommands<A> {
pub(crate) fn from_arc_into_baked(self: Arc<Self>) -> BakedCommands {
let mut command_buffer = Arc::into_inner(self)
.expect("CommandBuffer cannot be destroyed because is still in use");
command_buffer.extract_baked_commands()
}
}
crate::impl_resource_type_generic!(CommandBuffer);
crate::impl_resource_type!(CommandBuffer);
crate::impl_labeled!(CommandBuffer);
crate::impl_parent_device!(CommandBuffer);
crate::impl_storage_item_generic!(CommandBuffer);
crate::impl_storage_item!(CommandBuffer);
/// A stream of commands for a render pass or compute pass.
///
@ -609,14 +609,14 @@ pub enum CommandEncoderError {
}
impl Global {
pub fn command_encoder_finish<A: HalApi>(
pub fn command_encoder_finish(
&self,
encoder_id: id::CommandEncoderId,
_desc: &wgt::CommandBufferDescriptor<Label>,
) -> (id::CommandBufferId, Option<CommandEncoderError>) {
profiling::scope!("CommandEncoder::finish");
let hub = A::hub(self);
let hub = &self.hub;
let error = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) {
Ok(cmd_buf) => {
@ -651,7 +651,7 @@ impl Global {
(encoder_id.into_command_buffer_id(), error)
}
pub fn command_encoder_push_debug_group<A: HalApi>(
pub fn command_encoder_push_debug_group(
&self,
encoder_id: id::CommandEncoderId,
label: &str,
@ -659,7 +659,7 @@ impl Global {
profiling::scope!("CommandEncoder::push_debug_group");
api_log!("CommandEncoder::push_debug_group {label}");
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) {
Ok(cmd_buf) => cmd_buf,
@ -687,7 +687,7 @@ impl Global {
Ok(())
}
pub fn command_encoder_insert_debug_marker<A: HalApi>(
pub fn command_encoder_insert_debug_marker(
&self,
encoder_id: id::CommandEncoderId,
label: &str,
@ -695,7 +695,7 @@ impl Global {
profiling::scope!("CommandEncoder::insert_debug_marker");
api_log!("CommandEncoder::insert_debug_marker {label}");
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) {
Ok(cmd_buf) => cmd_buf,
@ -724,14 +724,14 @@ impl Global {
Ok(())
}
pub fn command_encoder_pop_debug_group<A: HalApi>(
pub fn command_encoder_pop_debug_group(
&self,
encoder_id: id::CommandEncoderId,
) -> Result<(), CommandEncoderError> {
profiling::scope!("CommandEncoder::pop_debug_marker");
api_log!("CommandEncoder::pop_debug_group");
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) {
Ok(cmd_buf) => cmd_buf,

View File

@ -4,7 +4,6 @@ use crate::{
command::{CommandBuffer, CommandEncoderError},
device::{DeviceError, MissingFeatures},
global::Global,
hal_api::HalApi,
id,
init_tracker::MemoryInitKind,
resource::{
@ -18,17 +17,17 @@ use thiserror::Error;
use wgt::BufferAddress;
#[derive(Debug)]
pub(crate) struct QueryResetMap<A: HalApi> {
map: FastHashMap<TrackerIndex, (Vec<bool>, Arc<QuerySet<A>>)>,
pub(crate) struct QueryResetMap {
map: FastHashMap<TrackerIndex, (Vec<bool>, Arc<QuerySet>)>,
}
impl<A: HalApi> QueryResetMap<A> {
impl QueryResetMap {
pub fn new() -> Self {
Self {
map: FastHashMap::default(),
}
}
pub fn use_query_set(&mut self, query_set: &Arc<QuerySet<A>>, query: u32) -> bool {
pub fn use_query_set(&mut self, query_set: &Arc<QuerySet>, query: u32) -> bool {
let vec_pair = self
.map
.entry(query_set.tracker_index())
@ -161,12 +160,12 @@ pub enum ResolveError {
},
}
impl<A: HalApi> QuerySet<A> {
impl QuerySet {
fn validate_query(
self: &Arc<Self>,
query_type: SimplifiedQueryType,
query_index: u32,
reset_state: Option<&mut QueryResetMap<A>>,
reset_state: Option<&mut QueryResetMap>,
) -> Result<(), QueryUseError> {
// We need to defer our resets because we are in a renderpass,
// add the usage to the reset map.
@ -199,7 +198,7 @@ impl<A: HalApi> QuerySet<A> {
self: &Arc<Self>,
raw_encoder: &mut dyn hal::DynCommandEncoder,
query_index: u32,
reset_state: Option<&mut QueryResetMap<A>>,
reset_state: Option<&mut QueryResetMap>,
) -> Result<(), QueryUseError> {
let needs_reset = reset_state.is_none();
self.validate_query(SimplifiedQueryType::Timestamp, query_index, reset_state)?;
@ -216,13 +215,13 @@ impl<A: HalApi> QuerySet<A> {
}
}
pub(super) fn validate_and_begin_occlusion_query<A: HalApi>(
query_set: Arc<QuerySet<A>>,
pub(super) fn validate_and_begin_occlusion_query(
query_set: Arc<QuerySet>,
raw_encoder: &mut dyn hal::DynCommandEncoder,
tracker: &mut StatelessTracker<QuerySet<A>>,
tracker: &mut StatelessTracker<QuerySet>,
query_index: u32,
reset_state: Option<&mut QueryResetMap<A>>,
active_query: &mut Option<(Arc<QuerySet<A>>, u32)>,
reset_state: Option<&mut QueryResetMap>,
active_query: &mut Option<(Arc<QuerySet>, u32)>,
) -> Result<(), QueryUseError> {
let needs_reset = reset_state.is_none();
query_set.validate_query(SimplifiedQueryType::Occlusion, query_index, reset_state)?;
@ -248,9 +247,9 @@ pub(super) fn validate_and_begin_occlusion_query<A: HalApi>(
Ok(())
}
pub(super) fn end_occlusion_query<A: HalApi>(
pub(super) fn end_occlusion_query(
raw_encoder: &mut dyn hal::DynCommandEncoder,
active_query: &mut Option<(Arc<QuerySet<A>>, u32)>,
active_query: &mut Option<(Arc<QuerySet>, u32)>,
) -> Result<(), QueryUseError> {
if let Some((query_set, query_index)) = active_query.take() {
unsafe { raw_encoder.end_query(query_set.raw(), query_index) };
@ -260,14 +259,14 @@ pub(super) fn end_occlusion_query<A: HalApi>(
}
}
pub(super) fn validate_and_begin_pipeline_statistics_query<A: HalApi>(
query_set: Arc<QuerySet<A>>,
pub(super) fn validate_and_begin_pipeline_statistics_query(
query_set: Arc<QuerySet>,
raw_encoder: &mut dyn hal::DynCommandEncoder,
tracker: &mut StatelessTracker<QuerySet<A>>,
cmd_buf: &CommandBuffer<A>,
tracker: &mut StatelessTracker<QuerySet>,
cmd_buf: &CommandBuffer,
query_index: u32,
reset_state: Option<&mut QueryResetMap<A>>,
active_query: &mut Option<(Arc<QuerySet<A>>, u32)>,
reset_state: Option<&mut QueryResetMap>,
active_query: &mut Option<(Arc<QuerySet>, u32)>,
) -> Result<(), QueryUseError> {
query_set.same_device_as(cmd_buf)?;
@ -299,9 +298,9 @@ pub(super) fn validate_and_begin_pipeline_statistics_query<A: HalApi>(
Ok(())
}
pub(super) fn end_pipeline_statistics_query<A: HalApi>(
pub(super) fn end_pipeline_statistics_query(
raw_encoder: &mut dyn hal::DynCommandEncoder,
active_query: &mut Option<(Arc<QuerySet<A>>, u32)>,
active_query: &mut Option<(Arc<QuerySet>, u32)>,
) -> Result<(), QueryUseError> {
if let Some((query_set, query_index)) = active_query.take() {
unsafe { raw_encoder.end_query(query_set.raw(), query_index) };
@ -312,13 +311,13 @@ pub(super) fn end_pipeline_statistics_query<A: HalApi>(
}
impl Global {
pub fn command_encoder_write_timestamp<A: HalApi>(
pub fn command_encoder_write_timestamp(
&self,
command_encoder_id: id::CommandEncoderId,
query_set_id: id::QuerySetId,
query_index: u32,
) -> Result<(), QueryError> {
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers
@ -361,7 +360,7 @@ impl Global {
Ok(())
}
pub fn command_encoder_resolve_query_set<A: HalApi>(
pub fn command_encoder_resolve_query_set(
&self,
command_encoder_id: id::CommandEncoderId,
query_set_id: id::QuerySetId,
@ -370,7 +369,7 @@ impl Global {
destination: id::BufferId,
destination_offset: BufferAddress,
) -> Result<(), QueryError> {
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers

View File

@ -21,7 +21,6 @@ use crate::{
RenderPassCompatibilityError, RenderPassContext,
},
global::Global,
hal_api::HalApi,
hal_label, id,
init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction},
pipeline::{self, PipelineFlags},
@ -133,11 +132,11 @@ pub struct RenderPassColorAttachment {
/// Describes a color attachment to a render pass.
#[derive(Debug)]
struct ArcRenderPassColorAttachment<A: HalApi> {
struct ArcRenderPassColorAttachment {
/// The view to use as an attachment.
pub view: Arc<TextureView<A>>,
pub view: Arc<TextureView>,
/// The view that will receive the resolved output if multisampling is used.
pub resolve_target: Option<Arc<TextureView<A>>>,
pub resolve_target: Option<Arc<TextureView>>,
/// What operations will be performed on this color attachment.
pub channel: PassChannel<Color>,
}
@ -156,16 +155,16 @@ pub struct RenderPassDepthStencilAttachment {
}
/// Describes a depth/stencil attachment to a render pass.
#[derive(Debug)]
pub struct ArcRenderPassDepthStencilAttachment<A: HalApi> {
pub struct ArcRenderPassDepthStencilAttachment {
/// The view to use as an attachment.
pub view: Arc<TextureView<A>>,
pub view: Arc<TextureView>,
/// What operations will be performed on the depth part of the attachment.
pub depth: PassChannel<f32>,
/// What operations will be performed on the stencil part of the attachment.
pub stencil: PassChannel<u32>,
}
impl<A: HalApi> ArcRenderPassDepthStencilAttachment<A> {
impl ArcRenderPassDepthStencilAttachment {
/// Validate the given aspects' read-only flags against their load
/// and store ops.
///
@ -218,45 +217,45 @@ pub struct RenderPassDescriptor<'a> {
}
/// Describes the attachments of a render pass.
struct ArcRenderPassDescriptor<'a, A: HalApi> {
struct ArcRenderPassDescriptor<'a> {
pub label: &'a Label<'a>,
/// The color attachments of the render pass.
pub color_attachments:
ArrayVec<Option<ArcRenderPassColorAttachment<A>>, { hal::MAX_COLOR_ATTACHMENTS }>,
ArrayVec<Option<ArcRenderPassColorAttachment>, { hal::MAX_COLOR_ATTACHMENTS }>,
/// The depth and stencil attachment of the render pass, if any.
pub depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment<A>>,
pub depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
/// Defines where and when timestamp values will be written for this pass.
pub timestamp_writes: Option<ArcPassTimestampWrites<A>>,
pub timestamp_writes: Option<ArcPassTimestampWrites>,
/// Defines where the occlusion query results will be stored for this pass.
pub occlusion_query_set: Option<Arc<QuerySet<A>>>,
pub occlusion_query_set: Option<Arc<QuerySet>>,
}
pub struct RenderPass<A: HalApi> {
pub struct RenderPass {
/// All pass data & records is stored here.
///
/// If this is `None`, the pass is in the 'ended' state and can no longer be used.
/// Any attempt to record more commands will result in a validation error.
base: Option<BasePass<ArcRenderCommand<A>>>,
base: Option<BasePass<ArcRenderCommand>>,
/// Parent command buffer that this pass records commands into.
///
/// If it is none, this pass is invalid and any operation on it will return an error.
parent: Option<Arc<CommandBuffer<A>>>,
parent: Option<Arc<CommandBuffer>>,
color_attachments:
ArrayVec<Option<ArcRenderPassColorAttachment<A>>, { hal::MAX_COLOR_ATTACHMENTS }>,
depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment<A>>,
timestamp_writes: Option<ArcPassTimestampWrites<A>>,
occlusion_query_set: Option<Arc<QuerySet<A>>>,
ArrayVec<Option<ArcRenderPassColorAttachment>, { hal::MAX_COLOR_ATTACHMENTS }>,
depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
timestamp_writes: Option<ArcPassTimestampWrites>,
occlusion_query_set: Option<Arc<QuerySet>>,
// Resource binding dedupe state.
current_bind_groups: BindGroupStateChange,
current_pipeline: StateChange<id::RenderPipelineId>,
}
impl<A: HalApi> RenderPass<A> {
impl RenderPass {
/// If the parent command buffer is invalid, the returned pass will be invalid.
fn new(parent: Option<Arc<CommandBuffer<A>>>, desc: ArcRenderPassDescriptor<A>) -> Self {
fn new(parent: Option<Arc<CommandBuffer>>, desc: ArcRenderPassDescriptor) -> Self {
let ArcRenderPassDescriptor {
label,
timestamp_writes,
@ -286,7 +285,7 @@ impl<A: HalApi> RenderPass<A> {
fn base_mut<'a>(
&'a mut self,
scope: PassErrorScope,
) -> Result<&'a mut BasePass<ArcRenderCommand<A>>, RenderPassError> {
) -> Result<&'a mut BasePass<ArcRenderCommand>, RenderPassError> {
self.base
.as_mut()
.ok_or(RenderPassErrorInner::PassEnded)
@ -294,7 +293,7 @@ impl<A: HalApi> RenderPass<A> {
}
}
impl<A: HalApi> fmt::Debug for RenderPass<A> {
impl fmt::Debug for RenderPass {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RenderPass")
.field("label", &self.label())
@ -444,38 +443,38 @@ impl VertexState {
}
}
struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> {
struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> {
pipeline_flags: PipelineFlags,
binder: Binder<A>,
binder: Binder,
blend_constant: OptionalState,
stencil_reference: u32,
pipeline: Option<Arc<RenderPipeline<A>>>,
pipeline: Option<Arc<RenderPipeline>>,
index: IndexState,
vertex: VertexState,
debug_scope_depth: u32,
info: RenderPassInfo<'scope, A>,
info: RenderPassInfo<'scope>,
snatch_guard: &'snatch_guard SnatchGuard<'snatch_guard>,
device: &'cmd_buf Arc<Device<A>>,
device: &'cmd_buf Arc<Device>,
raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder,
tracker: &'cmd_buf mut Tracker<A>,
buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction<A>>,
texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions<A>,
tracker: &'cmd_buf mut Tracker,
buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction>,
texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions,
temp_offsets: Vec<u32>,
dynamic_offset_count: usize,
string_offset: usize,
active_occlusion_query: Option<(Arc<QuerySet<A>>, u32)>,
active_pipeline_statistics_query: Option<(Arc<QuerySet<A>>, u32)>,
active_occlusion_query: Option<(Arc<QuerySet>, u32)>,
active_pipeline_statistics_query: Option<(Arc<QuerySet>, u32)>,
}
impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi>
State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A>
impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder>
State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder>
{
fn is_ready(&self, indexed: bool) -> Result<(), DrawError> {
if let Some(pipeline) = self.pipeline.as_ref() {
@ -747,14 +746,14 @@ where
}
}
struct RenderAttachment<A: HalApi> {
texture: Arc<Texture<A>>,
struct RenderAttachment {
texture: Arc<Texture>,
selector: TextureSelector,
usage: hal::TextureUses,
}
impl<A: HalApi> TextureView<A> {
fn to_render_attachment(&self, usage: hal::TextureUses) -> RenderAttachment<A> {
impl TextureView {
fn to_render_attachment(&self, usage: hal::TextureUses) -> RenderAttachment {
RenderAttachment {
texture: self.parent.clone(),
selector: self.selector.clone(),
@ -766,26 +765,26 @@ impl<A: HalApi> TextureView<A> {
const MAX_TOTAL_ATTACHMENTS: usize = hal::MAX_COLOR_ATTACHMENTS + hal::MAX_COLOR_ATTACHMENTS + 1;
type AttachmentDataVec<T> = ArrayVec<T, MAX_TOTAL_ATTACHMENTS>;
struct RenderPassInfo<'d, A: HalApi> {
struct RenderPassInfo<'d> {
context: RenderPassContext,
usage_scope: UsageScope<'d, A>,
usage_scope: UsageScope<'d>,
/// All render attachments, including depth/stencil
render_attachments: AttachmentDataVec<RenderAttachment<A>>,
render_attachments: AttachmentDataVec<RenderAttachment>,
is_depth_read_only: bool,
is_stencil_read_only: bool,
extent: wgt::Extent3d,
pending_discard_init_fixups: SurfacesInDiscardState<A>,
divergent_discarded_depth_stencil_aspect: Option<(wgt::TextureAspect, Arc<TextureView<A>>)>,
pending_discard_init_fixups: SurfacesInDiscardState,
divergent_discarded_depth_stencil_aspect: Option<(wgt::TextureAspect, Arc<TextureView>)>,
multiview: Option<NonZeroU32>,
}
impl<'d, A: HalApi> RenderPassInfo<'d, A> {
impl<'d> RenderPassInfo<'d> {
fn add_pass_texture_init_actions<V>(
channel: &PassChannel<V>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
view: &TextureView<A>,
pending_discard_init_fixups: &mut SurfacesInDiscardState<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions,
view: &TextureView,
pending_discard_init_fixups: &mut SurfacesInDiscardState,
) {
if channel.load_op == LoadOp::Load {
pending_discard_init_fixups.extend(texture_memory_actions.register_init_action(
@ -816,19 +815,19 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
}
fn start(
device: &'d Arc<Device<A>>,
device: &'d Arc<Device>,
hal_label: Option<&str>,
color_attachments: ArrayVec<
Option<ArcRenderPassColorAttachment<A>>,
Option<ArcRenderPassColorAttachment>,
{ hal::MAX_COLOR_ATTACHMENTS },
>,
mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment<A>>,
mut timestamp_writes: Option<ArcPassTimestampWrites<A>>,
mut occlusion_query_set: Option<Arc<QuerySet<A>>>,
mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
mut timestamp_writes: Option<ArcPassTimestampWrites>,
mut occlusion_query_set: Option<Arc<QuerySet>>,
encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
pending_query_resets: &mut QueryResetMap<A>,
trackers: &mut Tracker,
texture_memory_actions: &mut CommandBufferTextureMemoryActions,
pending_query_resets: &mut QueryResetMap,
snatch_guard: &SnatchGuard<'_>,
) -> Result<Self, RenderPassErrorInner> {
profiling::scope!("RenderPassInfo::start");
@ -839,7 +838,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
let mut is_depth_read_only = false;
let mut is_stencil_read_only = false;
let mut render_attachments = AttachmentDataVec::<RenderAttachment<A>>::new();
let mut render_attachments = AttachmentDataVec::<RenderAttachment>::new();
let mut discarded_surfaces = AttachmentDataVec::new();
let mut pending_discard_init_fixups = SurfacesInDiscardState::new();
let mut divergent_discarded_depth_stencil_aspect = None;
@ -853,7 +852,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
let mut detected_multiview: Option<Option<NonZeroU32>> = None;
let mut check_multiview = |view: &TextureView<A>| {
let mut check_multiview = |view: &TextureView| {
// Get the multiview configuration for this texture view
let layers = view.selector.layers.end - view.selector.layers.start;
let this_multiview = if layers >= 2 {
@ -884,7 +883,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
Ok(())
};
let mut add_view = |view: &TextureView<A>, location| {
let mut add_view = |view: &TextureView, location| {
let render_extent = view.render_extent.map_err(|reason| {
RenderPassErrorInner::TextureViewIsNotRenderable { location, reason }
})?;
@ -1048,7 +1047,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
color_attachments_hal.push(None);
continue;
};
let color_view: &TextureView<A> = &at.view;
let color_view: &TextureView = &at.view;
color_view.same_device(device)?;
check_multiview(color_view)?;
add_view(
@ -1256,7 +1255,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
mut self,
raw: &mut dyn hal::DynCommandEncoder,
snatch_guard: &SnatchGuard,
) -> Result<(UsageScope<'d, A>, SurfacesInDiscardState<A>), RenderPassErrorInner> {
) -> Result<(UsageScope<'d>, SurfacesInDiscardState), RenderPassErrorInner> {
profiling::scope!("RenderPassInfo::finish");
unsafe {
raw.end_render_pass();
@ -1332,16 +1331,16 @@ impl Global {
/// Any operation on an invalid pass will return an error.
///
/// If successful, puts the encoder into the [`CommandEncoderStatus::Locked`] state.
pub fn command_encoder_create_render_pass<A: HalApi>(
pub fn command_encoder_create_render_pass(
&self,
encoder_id: id::CommandEncoderId,
desc: &RenderPassDescriptor<'_>,
) -> (RenderPass<A>, Option<CommandEncoderError>) {
fn fill_arc_desc<A: HalApi>(
hub: &crate::hub::Hub<A>,
) -> (RenderPass, Option<CommandEncoderError>) {
fn fill_arc_desc(
hub: &crate::hub::Hub,
desc: &RenderPassDescriptor<'_>,
arc_desc: &mut ArcRenderPassDescriptor<A>,
device: &Device<A>,
arc_desc: &mut ArcRenderPassDescriptor,
device: &Device,
) -> Result<(), CommandEncoderError> {
let query_sets = hub.query_sets.read();
let texture_views = hub.texture_views.read();
@ -1436,7 +1435,7 @@ impl Global {
Ok(())
}
let hub = A::hub(self);
let hub = &self.hub;
let mut arc_desc = ArcRenderPassDescriptor {
label: &desc.label,
timestamp_writes: None,
@ -1466,18 +1465,18 @@ impl Global {
///
/// If creation fails, an invalid pass is returned.
/// Any operation on an invalid pass will return an error.
pub fn command_encoder_create_render_pass_dyn<A: HalApi>(
pub fn command_encoder_create_render_pass_dyn(
&self,
encoder_id: id::CommandEncoderId,
desc: &RenderPassDescriptor<'_>,
) -> (Box<dyn DynRenderPass>, Option<CommandEncoderError>) {
let (pass, err) = self.command_encoder_create_render_pass::<A>(encoder_id, desc);
let (pass, err) = self.command_encoder_create_render_pass(encoder_id, desc);
(Box::new(pass), err)
}
#[doc(hidden)]
#[cfg(any(feature = "serde", feature = "replay"))]
pub fn render_pass_end_with_unresolved_commands<A: HalApi>(
pub fn render_pass_end_with_unresolved_commands(
&self,
encoder_id: id::CommandEncoderId,
base: BasePass<super::RenderCommand>,
@ -1490,7 +1489,7 @@ impl Global {
#[cfg(feature = "trace")]
{
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) {
Ok(cmd_buf) => cmd_buf,
@ -1525,7 +1524,7 @@ impl Global {
push_constant_data,
} = base;
let (mut render_pass, encoder_error) = self.command_encoder_create_render_pass::<A>(
let (mut render_pass, encoder_error) = self.command_encoder_create_render_pass(
encoder_id,
&RenderPassDescriptor {
label: label.as_deref().map(Cow::Borrowed),
@ -1542,7 +1541,7 @@ impl Global {
});
};
let hub = A::hub(self);
let hub = &self.hub;
render_pass.base = Some(BasePass {
label,
commands: super::RenderCommand::resolve_render_command_ids(hub, &commands)?,
@ -1562,10 +1561,7 @@ impl Global {
}
#[doc(hidden)]
pub fn render_pass_end<A: HalApi>(
&self,
pass: &mut RenderPass<A>,
) -> Result<(), RenderPassError> {
pub fn render_pass_end(&self, pass: &mut RenderPass) -> Result<(), RenderPassError> {
let pass_scope = PassErrorScope::Pass;
let base = pass
@ -1945,13 +1941,13 @@ impl Global {
}
}
fn set_bind_group<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
fn set_bind_group(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
dynamic_offsets: &[DynamicOffset],
index: u32,
num_dynamic_offsets: usize,
bind_group: Arc<BindGroup<A>>,
bind_group: Arc<BindGroup>,
) -> Result<(), RenderPassErrorInner> {
api_log!(
"RenderPass::set_bind_group {index} {}",
@ -2026,10 +2022,10 @@ fn set_bind_group<A: HalApi>(
Ok(())
}
fn set_pipeline<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
pipeline: Arc<RenderPipeline<A>>,
fn set_pipeline(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
pipeline: Arc<RenderPipeline>,
) -> Result<(), RenderPassErrorInner> {
api_log!("RenderPass::set_pipeline {}", pipeline.error_ident());
@ -2135,10 +2131,10 @@ fn set_pipeline<A: HalApi>(
Ok(())
}
fn set_index_buffer<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
buffer: Arc<crate::resource::Buffer<A>>,
fn set_index_buffer(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
buffer: Arc<crate::resource::Buffer>,
index_format: IndexFormat,
offset: u64,
size: Option<BufferSize>,
@ -2181,11 +2177,11 @@ fn set_index_buffer<A: HalApi>(
Ok(())
}
fn set_vertex_buffer<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
fn set_vertex_buffer(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
slot: u32,
buffer: Arc<crate::resource::Buffer<A>>,
buffer: Arc<crate::resource::Buffer>,
offset: u64,
size: Option<BufferSize>,
) -> Result<(), RenderPassErrorInner> {
@ -2247,7 +2243,7 @@ fn set_vertex_buffer<A: HalApi>(
Ok(())
}
fn set_blend_constant<A: HalApi>(state: &mut State<A>, color: &Color) {
fn set_blend_constant(state: &mut State, color: &Color) {
api_log!("RenderPass::set_blend_constant");
state.blend_constant = OptionalState::Set;
@ -2262,7 +2258,7 @@ fn set_blend_constant<A: HalApi>(state: &mut State<A>, color: &Color) {
}
}
fn set_stencil_reference<A: HalApi>(state: &mut State<A>, value: u32) {
fn set_stencil_reference(state: &mut State, value: u32) {
api_log!("RenderPass::set_stencil_reference {value}");
state.stencil_reference = value;
@ -2276,8 +2272,8 @@ fn set_stencil_reference<A: HalApi>(state: &mut State<A>, value: u32) {
}
}
fn set_viewport<A: HalApi>(
state: &mut State<A>,
fn set_viewport(
state: &mut State,
rect: Rect<f32>,
depth_min: f32,
depth_max: f32,
@ -2307,8 +2303,8 @@ fn set_viewport<A: HalApi>(
Ok(())
}
fn set_push_constant<A: HalApi>(
state: &mut State<A>,
fn set_push_constant(
state: &mut State,
push_constant_data: &[u32],
stages: ShaderStages,
offset: u32,
@ -2341,10 +2337,7 @@ fn set_push_constant<A: HalApi>(
Ok(())
}
fn set_scissor<A: HalApi>(
state: &mut State<A>,
rect: Rect<u32>,
) -> Result<(), RenderPassErrorInner> {
fn set_scissor(state: &mut State, rect: Rect<u32>) -> Result<(), RenderPassErrorInner> {
api_log!("RenderPass::set_scissor_rect {rect:?}");
if rect.x + rect.w > state.info.extent.width || rect.y + rect.h > state.info.extent.height {
@ -2362,8 +2355,8 @@ fn set_scissor<A: HalApi>(
Ok(())
}
fn draw<A: HalApi>(
state: &mut State<A>,
fn draw(
state: &mut State,
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
@ -2402,8 +2395,8 @@ fn draw<A: HalApi>(
Ok(())
}
fn draw_indexed<A: HalApi>(
state: &mut State<A>,
fn draw_indexed(
state: &mut State,
index_count: u32,
instance_count: u32,
first_index: u32,
@ -2446,10 +2439,10 @@ fn draw_indexed<A: HalApi>(
Ok(())
}
fn multi_draw_indirect<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
indirect_buffer: Arc<crate::resource::Buffer<A>>,
fn multi_draw_indirect(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
indirect_buffer: Arc<crate::resource::Buffer>,
offset: u64,
count: Option<NonZeroU32>,
indexed: bool,
@ -2521,12 +2514,12 @@ fn multi_draw_indirect<A: HalApi>(
Ok(())
}
fn multi_draw_indirect_count<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
indirect_buffer: Arc<crate::resource::Buffer<A>>,
fn multi_draw_indirect_count(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
indirect_buffer: Arc<crate::resource::Buffer>,
offset: u64,
count_buffer: Arc<crate::resource::Buffer<A>>,
count_buffer: Arc<crate::resource::Buffer>,
count_buffer_offset: u64,
max_count: u32,
indexed: bool,
@ -2629,7 +2622,7 @@ fn multi_draw_indirect_count<A: HalApi>(
Ok(())
}
fn push_debug_group<A: HalApi>(state: &mut State<A>, string_data: &[u8], len: usize) {
fn push_debug_group(state: &mut State, string_data: &[u8], len: usize) {
state.debug_scope_depth += 1;
if !state
.device
@ -2647,7 +2640,7 @@ fn push_debug_group<A: HalApi>(state: &mut State<A>, string_data: &[u8], len: us
state.string_offset += len;
}
fn pop_debug_group<A: HalApi>(state: &mut State<A>) -> Result<(), RenderPassErrorInner> {
fn pop_debug_group(state: &mut State) -> Result<(), RenderPassErrorInner> {
api_log!("RenderPass::pop_debug_group");
if state.debug_scope_depth == 0 {
@ -2666,7 +2659,7 @@ fn pop_debug_group<A: HalApi>(state: &mut State<A>) -> Result<(), RenderPassErro
Ok(())
}
fn insert_debug_marker<A: HalApi>(state: &mut State<A>, string_data: &[u8], len: usize) {
fn insert_debug_marker(state: &mut State, string_data: &[u8], len: usize) {
if !state
.device
.instance_flags
@ -2682,11 +2675,11 @@ fn insert_debug_marker<A: HalApi>(state: &mut State<A>, string_data: &[u8], len:
state.string_offset += len;
}
fn write_timestamp<A: HalApi>(
state: &mut State<A>,
cmd_buf: &CommandBuffer<A>,
pending_query_resets: &mut QueryResetMap<A>,
query_set: Arc<QuerySet<A>>,
fn write_timestamp(
state: &mut State,
cmd_buf: &CommandBuffer,
pending_query_resets: &mut QueryResetMap,
query_set: Arc<QuerySet>,
query_index: u32,
) -> Result<(), RenderPassErrorInner> {
api_log!(
@ -2710,10 +2703,10 @@ fn write_timestamp<A: HalApi>(
Ok(())
}
fn execute_bundle<A: HalApi>(
state: &mut State<A>,
cmd_buf: &Arc<CommandBuffer<A>>,
bundle: Arc<super::RenderBundle<A>>,
fn execute_bundle(
state: &mut State,
cmd_buf: &Arc<CommandBuffer>,
bundle: Arc<super::RenderBundle>,
) -> Result<(), RenderPassErrorInner> {
api_log!("RenderPass::execute_bundle {}", bundle.error_ident());
@ -2774,12 +2767,12 @@ fn execute_bundle<A: HalApi>(
}
impl Global {
fn resolve_render_pass_buffer_id<A: HalApi>(
fn resolve_render_pass_buffer_id(
&self,
scope: PassErrorScope,
buffer_id: id::Id<id::markers::Buffer>,
) -> Result<Arc<crate::resource::Buffer<A>>, RenderPassError> {
let hub = A::hub(self);
) -> Result<Arc<crate::resource::Buffer>, RenderPassError> {
let hub = &self.hub;
let buffer = hub
.buffers
.get(buffer_id)
@ -2789,12 +2782,12 @@ impl Global {
Ok(buffer)
}
fn resolve_render_pass_query_set<A: HalApi>(
fn resolve_render_pass_query_set(
&self,
scope: PassErrorScope,
query_set_id: id::Id<id::markers::QuerySet>,
) -> Result<Arc<QuerySet<A>>, RenderPassError> {
let hub = A::hub(self);
) -> Result<Arc<QuerySet>, RenderPassError> {
let hub = &self.hub;
let query_set = hub
.query_sets
.get(query_set_id)
@ -2804,9 +2797,9 @@ impl Global {
Ok(query_set)
}
pub fn render_pass_set_bind_group<A: HalApi>(
pub fn render_pass_set_bind_group(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
index: u32,
bind_group_id: id::BindGroupId,
offsets: &[DynamicOffset],
@ -2828,7 +2821,7 @@ impl Global {
return Ok(());
}
let hub = A::hub(self);
let hub = &self.hub;
let bind_group = hub
.bind_groups
.get(bind_group_id)
@ -2844,9 +2837,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_pipeline<A: HalApi>(
pub fn render_pass_set_pipeline(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
pipeline_id: id::RenderPipelineId,
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::SetPipelineRender;
@ -2859,7 +2852,7 @@ impl Global {
return Ok(());
}
let hub = A::hub(self);
let hub = &self.hub;
let pipeline = hub
.render_pipelines
.get(pipeline_id)
@ -2871,9 +2864,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_index_buffer<A: HalApi>(
pub fn render_pass_set_index_buffer(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
index_format: IndexFormat,
offset: BufferAddress,
@ -2892,9 +2885,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_vertex_buffer<A: HalApi>(
pub fn render_pass_set_vertex_buffer(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
slot: u32,
buffer_id: id::BufferId,
offset: BufferAddress,
@ -2913,9 +2906,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_blend_constant<A: HalApi>(
pub fn render_pass_set_blend_constant(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
color: Color,
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::SetBlendConstant;
@ -2927,9 +2920,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_stencil_reference<A: HalApi>(
pub fn render_pass_set_stencil_reference(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
value: u32,
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::SetStencilReference;
@ -2941,9 +2934,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_viewport<A: HalApi>(
pub fn render_pass_set_viewport(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
x: f32,
y: f32,
w: f32,
@ -2963,9 +2956,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_scissor_rect<A: HalApi>(
pub fn render_pass_set_scissor_rect(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
x: u32,
y: u32,
w: u32,
@ -2980,9 +2973,9 @@ impl Global {
Ok(())
}
pub fn render_pass_set_push_constants<A: HalApi>(
pub fn render_pass_set_push_constants(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
stages: ShaderStages,
offset: u32,
data: &[u8],
@ -3019,9 +3012,9 @@ impl Global {
Ok(())
}
pub fn render_pass_draw<A: HalApi>(
pub fn render_pass_draw(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
vertex_count: u32,
instance_count: u32,
first_vertex: u32,
@ -3043,9 +3036,9 @@ impl Global {
Ok(())
}
pub fn render_pass_draw_indexed<A: HalApi>(
pub fn render_pass_draw_indexed(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
index_count: u32,
instance_count: u32,
first_index: u32,
@ -3069,9 +3062,9 @@ impl Global {
Ok(())
}
pub fn render_pass_draw_indirect<A: HalApi>(
pub fn render_pass_draw_indirect(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
offset: BufferAddress,
) -> Result<(), RenderPassError> {
@ -3091,9 +3084,9 @@ impl Global {
Ok(())
}
pub fn render_pass_draw_indexed_indirect<A: HalApi>(
pub fn render_pass_draw_indexed_indirect(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
offset: BufferAddress,
) -> Result<(), RenderPassError> {
@ -3113,9 +3106,9 @@ impl Global {
Ok(())
}
pub fn render_pass_multi_draw_indirect<A: HalApi>(
pub fn render_pass_multi_draw_indirect(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
offset: BufferAddress,
count: u32,
@ -3136,9 +3129,9 @@ impl Global {
Ok(())
}
pub fn render_pass_multi_draw_indexed_indirect<A: HalApi>(
pub fn render_pass_multi_draw_indexed_indirect(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
offset: BufferAddress,
count: u32,
@ -3159,9 +3152,9 @@ impl Global {
Ok(())
}
pub fn render_pass_multi_draw_indirect_count<A: HalApi>(
pub fn render_pass_multi_draw_indirect_count(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
offset: BufferAddress,
count_buffer_id: id::BufferId,
@ -3175,7 +3168,7 @@ impl Global {
let base = pass.base_mut(scope)?;
// Don't use resolve_render_pass_buffer_id here, because we don't want to take the read-lock twice.
let hub = A::hub(self);
let hub = &self.hub;
let buffers = hub.buffers.read();
let buffer = buffers
.get_owned(buffer_id)
@ -3199,9 +3192,9 @@ impl Global {
Ok(())
}
pub fn render_pass_multi_draw_indexed_indirect_count<A: HalApi>(
pub fn render_pass_multi_draw_indexed_indirect_count(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
buffer_id: id::BufferId,
offset: BufferAddress,
count_buffer_id: id::BufferId,
@ -3215,7 +3208,7 @@ impl Global {
let base = pass.base_mut(scope)?;
// Don't use resolve_render_pass_buffer_id here, because we don't want to take the read-lock twice.
let hub = A::hub(self);
let hub = &self.hub;
let buffers = hub.buffers.read();
let buffer = buffers
.get_owned(buffer_id)
@ -3240,9 +3233,9 @@ impl Global {
Ok(())
}
pub fn render_pass_push_debug_group<A: HalApi>(
pub fn render_pass_push_debug_group(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
label: &str,
color: u32,
) -> Result<(), RenderPassError> {
@ -3259,9 +3252,9 @@ impl Global {
Ok(())
}
pub fn render_pass_pop_debug_group<A: HalApi>(
pub fn render_pass_pop_debug_group(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
) -> Result<(), RenderPassError> {
let base = pass.base_mut(PassErrorScope::PopDebugGroup)?;
@ -3270,9 +3263,9 @@ impl Global {
Ok(())
}
pub fn render_pass_insert_debug_marker<A: HalApi>(
pub fn render_pass_insert_debug_marker(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
label: &str,
color: u32,
) -> Result<(), RenderPassError> {
@ -3289,9 +3282,9 @@ impl Global {
Ok(())
}
pub fn render_pass_write_timestamp<A: HalApi>(
pub fn render_pass_write_timestamp(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
query_set_id: id::QuerySetId,
query_index: u32,
) -> Result<(), RenderPassError> {
@ -3306,9 +3299,9 @@ impl Global {
Ok(())
}
pub fn render_pass_begin_occlusion_query<A: HalApi>(
pub fn render_pass_begin_occlusion_query(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
query_index: u32,
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::BeginOcclusionQuery;
@ -3320,9 +3313,9 @@ impl Global {
Ok(())
}
pub fn render_pass_end_occlusion_query<A: HalApi>(
pub fn render_pass_end_occlusion_query(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::EndOcclusionQuery;
let base = pass.base_mut(scope)?;
@ -3332,9 +3325,9 @@ impl Global {
Ok(())
}
pub fn render_pass_begin_pipeline_statistics_query<A: HalApi>(
pub fn render_pass_begin_pipeline_statistics_query(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
query_set_id: id::QuerySetId,
query_index: u32,
) -> Result<(), RenderPassError> {
@ -3350,9 +3343,9 @@ impl Global {
Ok(())
}
pub fn render_pass_end_pipeline_statistics_query<A: HalApi>(
pub fn render_pass_end_pipeline_statistics_query(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::EndPipelineStatisticsQuery;
let base = pass.base_mut(scope)?;
@ -3363,15 +3356,15 @@ impl Global {
Ok(())
}
pub fn render_pass_execute_bundles<A: HalApi>(
pub fn render_pass_execute_bundles(
&self,
pass: &mut RenderPass<A>,
pass: &mut RenderPass,
render_bundle_ids: &[id::RenderBundleId],
) -> Result<(), RenderPassError> {
let scope = PassErrorScope::ExecuteBundle;
let base = pass.base_mut(scope)?;
let hub = A::hub(self);
let hub = &self.hub;
let bundles = hub.render_bundles.read();
for &bundle_id in render_bundle_ids {

View File

@ -1,6 +1,5 @@
use crate::{
binding_model::BindGroup,
hal_api::HalApi,
id,
pipeline::RenderPipeline,
resource::{Buffer, QuerySet},
@ -126,10 +125,10 @@ pub enum RenderCommand {
impl RenderCommand {
/// Resolves all ids in a list of commands into the corresponding resource Arc.
#[cfg(any(feature = "serde", feature = "replay"))]
pub fn resolve_render_command_ids<A: HalApi>(
hub: &crate::hub::Hub<A>,
pub fn resolve_render_command_ids(
hub: &crate::hub::Hub,
commands: &[RenderCommand],
) -> Result<Vec<ArcRenderCommand<A>>, super::RenderPassError> {
) -> Result<Vec<ArcRenderCommand>, super::RenderPassError> {
use super::{
DrawKind, PassErrorScope, RenderCommandError, RenderPassError, RenderPassErrorInner,
};
@ -140,9 +139,9 @@ impl RenderCommand {
let pipelines_guard = hub.render_pipelines.read();
let render_bundles_guard = hub.render_bundles.read();
let resolved_commands: Vec<ArcRenderCommand<A>> = commands
let resolved_commands: Vec<ArcRenderCommand> = commands
.iter()
.map(|c| -> Result<ArcRenderCommand<A>, RenderPassError> {
.map(|c| -> Result<ArcRenderCommand, RenderPassError> {
Ok(match *c {
RenderCommand::SetBindGroup {
index,
@ -381,22 +380,22 @@ impl RenderCommand {
/// Equivalent to `RenderCommand` with the Ids resolved into resource Arcs.
#[doc(hidden)]
#[derive(Clone, Debug)]
pub enum ArcRenderCommand<A: HalApi> {
pub enum ArcRenderCommand {
SetBindGroup {
index: u32,
num_dynamic_offsets: usize,
bind_group: Arc<BindGroup<A>>,
bind_group: Arc<BindGroup>,
},
SetPipeline(Arc<RenderPipeline<A>>),
SetPipeline(Arc<RenderPipeline>),
SetIndexBuffer {
buffer: Arc<Buffer<A>>,
buffer: Arc<Buffer>,
index_format: wgt::IndexFormat,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetVertexBuffer {
slot: u32,
buffer: Arc<Buffer<A>>,
buffer: Arc<Buffer>,
offset: BufferAddress,
size: Option<BufferSize>,
},
@ -450,16 +449,16 @@ pub enum ArcRenderCommand<A: HalApi> {
first_instance: u32,
},
MultiDrawIndirect {
buffer: Arc<Buffer<A>>,
buffer: Arc<Buffer>,
offset: BufferAddress,
/// Count of `None` represents a non-multi call.
count: Option<NonZeroU32>,
indexed: bool,
},
MultiDrawIndirectCount {
buffer: Arc<Buffer<A>>,
buffer: Arc<Buffer>,
offset: BufferAddress,
count_buffer: Arc<Buffer<A>>,
count_buffer: Arc<Buffer>,
count_buffer_offset: BufferAddress,
max_count: u32,
indexed: bool,
@ -474,7 +473,7 @@ pub enum ArcRenderCommand<A: HalApi> {
len: usize,
},
WriteTimestamp {
query_set: Arc<QuerySet<A>>,
query_set: Arc<QuerySet>,
query_index: u32,
},
BeginOcclusionQuery {
@ -482,9 +481,9 @@ pub enum ArcRenderCommand<A: HalApi> {
},
EndOcclusionQuery,
BeginPipelineStatisticsQuery {
query_set: Arc<QuerySet<A>>,
query_set: Arc<QuerySet>,
query_index: u32,
},
EndPipelineStatisticsQuery,
ExecuteBundle(Arc<RenderBundle<A>>),
ExecuteBundle(Arc<RenderBundle>),
}

View File

@ -1,6 +1,6 @@
use std::sync::Arc;
use crate::{hal_api::HalApi, id};
use crate::id;
/// Describes the writing of timestamp values in a render or compute pass.
#[derive(Clone, Debug, PartialEq, Eq)]
@ -15,9 +15,9 @@ pub struct PassTimestampWrites {
}
/// Describes the writing of timestamp values in a render or compute pass with the query set resolved.
pub struct ArcPassTimestampWrites<A: HalApi> {
pub struct ArcPassTimestampWrites {
/// The query set to write the timestamps to.
pub query_set: Arc<crate::resource::QuerySet<A>>,
pub query_set: Arc<crate::resource::QuerySet>,
/// The index of the query set at which a start timestamp of this pass is written, if any.
pub beginning_of_pass_write_index: Option<u32>,
/// The index of the query set at which an end timestamp of this pass is written, if any.

View File

@ -6,7 +6,6 @@ use crate::{
conv,
device::{Device, DeviceError, MissingDownlevelFlags},
global::Global,
hal_api::HalApi,
id::{BufferId, CommandEncoderId, TextureId},
init_tracker::{
has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange,
@ -159,10 +158,10 @@ impl From<DeviceError> for CopyError {
}
}
pub(crate) fn extract_texture_selector<A: HalApi>(
pub(crate) fn extract_texture_selector(
copy_texture: &ImageCopyTexture,
copy_size: &Extent3d,
texture: &Texture<A>,
texture: &Texture,
) -> Result<(TextureSelector, hal::TextureCopyBase), TransferError> {
let format = texture.desc.format;
let copy_aspect = hal::FormatAspects::new(format, copy_texture.aspect);
@ -407,15 +406,15 @@ pub(crate) fn validate_texture_copy_range(
Ok((copy_extent, array_layer_count))
}
fn handle_texture_init<A: HalApi>(
fn handle_texture_init(
init_kind: MemoryInitKind,
encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
device: &Device<A>,
trackers: &mut Tracker,
texture_memory_actions: &mut CommandBufferTextureMemoryActions,
device: &Device,
copy_texture: &ImageCopyTexture,
copy_size: &Extent3d,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
snatch_guard: &SnatchGuard<'_>,
) -> Result<(), ClearError> {
let init_action = TextureInitTrackerAction {
@ -457,14 +456,14 @@ fn handle_texture_init<A: HalApi>(
///
/// Ensure the source texture of a transfer is in the right initialization
/// state, and record the state for after the transfer operation.
fn handle_src_texture_init<A: HalApi>(
fn handle_src_texture_init(
encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
device: &Device<A>,
trackers: &mut Tracker,
texture_memory_actions: &mut CommandBufferTextureMemoryActions,
device: &Device,
source: &ImageCopyTexture,
copy_size: &Extent3d,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
snatch_guard: &SnatchGuard<'_>,
) -> Result<(), TransferError> {
handle_texture_init(
@ -485,14 +484,14 @@ fn handle_src_texture_init<A: HalApi>(
///
/// Ensure the destination texture of a transfer is in the right initialization
/// state, and record the state for after the transfer operation.
fn handle_dst_texture_init<A: HalApi>(
fn handle_dst_texture_init(
encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
device: &Device<A>,
trackers: &mut Tracker,
texture_memory_actions: &mut CommandBufferTextureMemoryActions,
device: &Device,
destination: &ImageCopyTexture,
copy_size: &Extent3d,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
snatch_guard: &SnatchGuard<'_>,
) -> Result<(), TransferError> {
// Attention: If we don't write full texture subresources, we need to a full
@ -524,7 +523,7 @@ fn handle_dst_texture_init<A: HalApi>(
}
impl Global {
pub fn command_encoder_copy_buffer_to_buffer<A: HalApi>(
pub fn command_encoder_copy_buffer_to_buffer(
&self,
command_encoder_id: CommandEncoderId,
source: BufferId,
@ -541,7 +540,7 @@ impl Global {
if source == destination {
return Err(TransferError::SameSourceDestinationBuffer.into());
}
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers
@ -697,7 +696,7 @@ impl Global {
Ok(())
}
pub fn command_encoder_copy_buffer_to_texture<A: HalApi>(
pub fn command_encoder_copy_buffer_to_texture(
&self,
command_encoder_id: CommandEncoderId,
source: &ImageCopyBuffer,
@ -711,7 +710,7 @@ impl Global {
destination.texture
);
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers
@ -865,7 +864,7 @@ impl Global {
Ok(())
}
pub fn command_encoder_copy_texture_to_buffer<A: HalApi>(
pub fn command_encoder_copy_texture_to_buffer(
&self,
command_encoder_id: CommandEncoderId,
source: &ImageCopyTexture,
@ -879,7 +878,7 @@ impl Global {
destination.buffer
);
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers
@ -1045,7 +1044,7 @@ impl Global {
Ok(())
}
pub fn command_encoder_copy_texture_to_texture<A: HalApi>(
pub fn command_encoder_copy_texture_to_texture(
&self,
command_encoder_id: CommandEncoderId,
source: &ImageCopyTexture,
@ -1059,7 +1058,7 @@ impl Global {
destination.texture
);
let hub = A::hub(self);
let hub = &self.hub;
let cmd_buf = match hub
.command_buffers

View File

@ -1,102 +0,0 @@
use wgt::Backend;
use super::Device;
/// The `AnyDevice` type: a pointer to a `Device<A>` for any backend `A`.
use crate::hal_api::HalApi;
use std::fmt;
use std::mem::ManuallyDrop;
use std::ptr::NonNull;
use std::sync::Arc;
struct AnyDeviceVtable {
// We oppurtunistically store the backend here, since we now it will be used
// with backend selection and it can be stored in static memory.
backend: Backend,
// Drop glue which knows how to drop the stored data.
drop: unsafe fn(*mut ()),
}
/// A pointer to a `Device<A>`, for any backend `A`.
///
/// Any `AnyDevice` is just like an `Arc<Device<A>>`, except that the `A` type
/// parameter is erased. To access the `Device`, you must downcast to a
/// particular backend with the \[`downcast_ref`\] or \[`downcast_clone`\]
/// methods.
pub struct AnyDevice {
data: NonNull<()>,
vtable: &'static AnyDeviceVtable,
}
impl AnyDevice {
/// Return an `AnyDevice` that holds an owning `Arc` pointer to `device`.
pub fn new<A: HalApi>(device: Arc<Device<A>>) -> AnyDevice {
unsafe fn drop_glue<A: HalApi>(ptr: *mut ()) {
// Drop the arc this instance is holding.
unsafe {
_ = Arc::from_raw(ptr.cast::<Device<A>>());
}
}
// SAFETY: The pointer returned by Arc::into_raw is guaranteed to be
// non-null.
let data = unsafe { NonNull::new_unchecked(Arc::into_raw(device).cast_mut()) };
AnyDevice {
data: data.cast(),
vtable: &AnyDeviceVtable {
backend: A::VARIANT,
drop: drop_glue::<A>,
},
}
}
/// If `self` is an `Arc<Device<A>>`, return a reference to the
/// device.
pub fn downcast_ref<A: HalApi>(&self) -> Option<&Device<A>> {
if self.vtable.backend != A::VARIANT {
return None;
}
// SAFETY: We just checked the instance above implicitly by the backend
// that it was statically constructed through.
Some(unsafe { &*(self.data.as_ptr().cast::<Device<A>>()) })
}
/// If `self` is an `Arc<Device<A>>`, return a clone of that.
pub fn downcast_clone<A: HalApi>(&self) -> Option<Arc<Device<A>>> {
if self.vtable.backend != A::VARIANT {
return None;
}
// We need to prevent the destructor of the arc from running, since it
// refers to the instance held by this object. Dropping it would
// invalidate this object.
//
// SAFETY: We just checked the instance above implicitly by the backend
// that it was statically constructed through.
let this =
ManuallyDrop::new(unsafe { Arc::from_raw(self.data.as_ptr().cast::<Device<A>>()) });
// Cloning it increases the reference count, and we return a new arc
// instance.
Some((*this).clone())
}
}
impl Drop for AnyDevice {
fn drop(&mut self) {
unsafe { (self.vtable.drop)(self.data.as_ptr()) }
}
}
impl fmt::Debug for AnyDevice {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "AnyDevice<{}>", self.vtable.backend)
}
}
#[cfg(send_sync)]
unsafe impl Send for AnyDevice {}
#[cfg(send_sync)]
unsafe impl Sync for AnyDevice {}

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ use crate::{
queue::{EncoderInFlight, SubmittedWorkDoneClosure, TempResource},
DeviceError, DeviceLostClosure,
},
hal_api::HalApi,
resource::{self, Buffer, Texture, Trackable},
snatch::SnatchGuard,
SubmissionIndex,
@ -22,7 +21,7 @@ use thiserror::Error;
///
/// [`wgpu_hal`]: hal
/// [`ResourceInfo::submission_index`]: crate::resource::ResourceInfo
struct ActiveSubmission<A: HalApi> {
struct ActiveSubmission {
/// The index of the submission we track.
///
/// When `Device::fence`'s value is greater than or equal to this, our queue
@ -30,10 +29,10 @@ struct ActiveSubmission<A: HalApi> {
index: SubmissionIndex,
/// Temporary resources to be freed once this queue submission has completed.
temp_resources: Vec<TempResource<A>>,
temp_resources: Vec<TempResource>,
/// Buffers to be mapped once this submission has completed.
mapped: Vec<Arc<Buffer<A>>>,
mapped: Vec<Arc<Buffer>>,
/// Command buffers used by this submission, and the encoder that owns them.
///
@ -47,18 +46,18 @@ struct ActiveSubmission<A: HalApi> {
/// the command encoder is recycled.
///
/// [`wgpu_hal::Queue::submit`]: hal::Queue::submit
encoders: Vec<EncoderInFlight<A>>,
encoders: Vec<EncoderInFlight>,
/// List of queue "on_submitted_work_done" closures to be called once this
/// submission has completed.
work_done_closures: SmallVec<[SubmittedWorkDoneClosure; 1]>,
}
impl<A: HalApi> ActiveSubmission<A> {
impl ActiveSubmission {
/// Returns true if this submission contains the given buffer.
///
/// This only uses constant-time operations.
pub fn contains_buffer(&self, buffer: &Buffer<A>) -> bool {
pub fn contains_buffer(&self, buffer: &Buffer) -> bool {
for encoder in &self.encoders {
// The ownership location of buffers depends on where the command encoder
// came from. If it is the staging command encoder on the queue, it is
@ -83,7 +82,7 @@ impl<A: HalApi> ActiveSubmission<A> {
/// Returns true if this submission contains the given texture.
///
/// This only uses constant-time operations.
pub fn contains_texture(&self, texture: &Texture<A>) -> bool {
pub fn contains_texture(&self, texture: &Texture) -> bool {
for encoder in &self.encoders {
// The ownership location of textures depends on where the command encoder
// came from. If it is the staging command encoder on the queue, it is
@ -150,11 +149,11 @@ pub enum WaitIdleError {
///
/// Only calling `Global::buffer_map_async` clones a new `Arc` for the
/// buffer. This new `Arc` is only dropped by `handle_mapping`.
pub(crate) struct LifetimeTracker<A: HalApi> {
pub(crate) struct LifetimeTracker {
/// Buffers for which a call to [`Buffer::map_async`] has succeeded, but
/// which haven't been examined by `triage_mapped` yet to decide when they
/// can be mapped.
mapped: Vec<Arc<Buffer<A>>>,
mapped: Vec<Arc<Buffer>>,
/// Resources used by queue submissions still in flight. One entry per
/// submission, with older submissions appearing before younger.
@ -162,11 +161,11 @@ pub(crate) struct LifetimeTracker<A: HalApi> {
/// Entries are added by `track_submission` and drained by
/// `LifetimeTracker::triage_submissions`. Lots of methods contribute data
/// to particular entries.
active: Vec<ActiveSubmission<A>>,
active: Vec<ActiveSubmission>,
/// Buffers the user has asked us to map, and which are not used by any
/// queue submission still in flight.
ready_to_map: Vec<Arc<Buffer<A>>>,
ready_to_map: Vec<Arc<Buffer>>,
/// Queue "on_submitted_work_done" closures that were initiated for while there is no
/// currently pending submissions. These cannot be immediately invoked as they
@ -180,7 +179,7 @@ pub(crate) struct LifetimeTracker<A: HalApi> {
pub device_lost_closure: Option<DeviceLostClosure>,
}
impl<A: HalApi> LifetimeTracker<A> {
impl LifetimeTracker {
pub fn new() -> Self {
Self {
mapped: Vec::new(),
@ -200,8 +199,8 @@ impl<A: HalApi> LifetimeTracker<A> {
pub fn track_submission(
&mut self,
index: SubmissionIndex,
temp_resources: impl Iterator<Item = TempResource<A>>,
encoders: Vec<EncoderInFlight<A>>,
temp_resources: impl Iterator<Item = TempResource>,
encoders: Vec<EncoderInFlight>,
) {
self.active.push(ActiveSubmission {
index,
@ -212,16 +211,13 @@ impl<A: HalApi> LifetimeTracker<A> {
});
}
pub(crate) fn map(&mut self, value: &Arc<Buffer<A>>) {
pub(crate) fn map(&mut self, value: &Arc<Buffer>) {
self.mapped.push(value.clone());
}
/// Returns the submission index of the most recent submission that uses the
/// given buffer.
pub fn get_buffer_latest_submission_index(
&self,
buffer: &Buffer<A>,
) -> Option<SubmissionIndex> {
pub fn get_buffer_latest_submission_index(&self, buffer: &Buffer) -> Option<SubmissionIndex> {
// We iterate in reverse order, so that we can bail out early as soon
// as we find a hit.
self.active.iter().rev().find_map(|submission| {
@ -237,7 +233,7 @@ impl<A: HalApi> LifetimeTracker<A> {
/// given texture.
pub fn get_texture_latest_submission_index(
&self,
texture: &Texture<A>,
texture: &Texture,
) -> Option<SubmissionIndex> {
// We iterate in reverse order, so that we can bail out early as soon
// as we find a hit.
@ -295,7 +291,7 @@ impl<A: HalApi> LifetimeTracker<A> {
pub fn schedule_resource_destruction(
&mut self,
temp_resource: TempResource<A>,
temp_resource: TempResource,
last_submit_index: SubmissionIndex,
) {
let resources = self

View File

@ -1,6 +1,5 @@
use crate::{
binding_model,
hal_api::HalApi,
hub::Hub,
id::{BindGroupLayoutId, PipelineLayoutId},
resource::{
@ -19,7 +18,6 @@ use wgt::{BufferAddress, DeviceLostReason, TextureFormat};
use std::num::NonZeroU32;
pub mod any_device;
pub(crate) mod bgl;
pub mod global;
mod life;
@ -299,9 +297,9 @@ impl DeviceLostClosure {
}
}
fn map_buffer<A: HalApi>(
fn map_buffer(
raw: &dyn hal::DynDevice,
buffer: &Buffer<A>,
buffer: &Buffer,
offset: BufferAddress,
size: BufferAddress,
kind: HostMap,
@ -434,13 +432,21 @@ pub struct ImplicitPipelineIds<'a> {
}
impl ImplicitPipelineIds<'_> {
fn prepare<A: HalApi>(self, hub: &Hub<A>) -> ImplicitPipelineContext {
fn prepare(self, hub: &Hub) -> ImplicitPipelineContext {
let backend = self.root_id.backend();
ImplicitPipelineContext {
root_id: hub.pipeline_layouts.prepare(Some(self.root_id)).into_id(),
root_id: hub
.pipeline_layouts
.prepare(backend, Some(self.root_id))
.into_id(),
group_ids: self
.group_ids
.iter()
.map(|id_in| hub.bind_group_layouts.prepare(Some(*id_in)).into_id())
.map(|id_in| {
hub.bind_group_layouts
.prepare(backend, Some(*id_in))
.into_id()
})
.collect(),
}
}

View File

@ -10,7 +10,6 @@ use crate::{
device::{DeviceError, WaitIdleError},
get_lowest_common_denom,
global::Global,
hal_api::HalApi,
hal_label,
id::{self, QueueId},
init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange},
@ -37,13 +36,13 @@ use thiserror::Error;
use super::Device;
pub struct Queue<A: HalApi> {
pub struct Queue {
raw: ManuallyDrop<Box<dyn hal::DynQueue>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
}
impl<A: HalApi> Queue<A> {
pub(crate) fn new(device: Arc<Device<A>>, raw: Box<dyn hal::DynQueue>) -> Self {
impl Queue {
pub(crate) fn new(device: Arc<Device>, raw: Box<dyn hal::DynQueue>) -> Self {
Queue {
raw: ManuallyDrop::new(raw),
device,
@ -55,17 +54,17 @@ impl<A: HalApi> Queue<A> {
}
}
crate::impl_resource_type_generic!(Queue);
crate::impl_resource_type!(Queue);
// TODO: https://github.com/gfx-rs/wgpu/issues/4014
impl<A: HalApi> Labeled for Queue<A> {
impl Labeled for Queue {
fn label(&self) -> &str {
""
}
}
crate::impl_parent_device!(Queue);
crate::impl_storage_item_generic!(Queue);
crate::impl_storage_item!(Queue);
impl<A: HalApi> Drop for Queue<A> {
impl Drop for Queue {
fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident());
// SAFETY: we never access `self.raw` beyond this point.
@ -141,10 +140,10 @@ impl SubmittedWorkDoneClosure {
/// - `ActiveSubmission::temp_resources`: temporary resources used by a queue
/// submission, to be freed when it completes
#[derive(Debug)]
pub enum TempResource<A: HalApi> {
StagingBuffer(FlushedStagingBuffer<A>),
DestroyedBuffer(DestroyedBuffer<A>),
DestroyedTexture(DestroyedTexture<A>),
pub enum TempResource {
StagingBuffer(FlushedStagingBuffer),
DestroyedBuffer(DestroyedBuffer),
DestroyedTexture(DestroyedTexture),
}
/// A series of raw [`CommandBuffer`]s that have been submitted to a
@ -152,18 +151,18 @@ pub enum TempResource<A: HalApi> {
///
/// [`CommandBuffer`]: hal::Api::CommandBuffer
/// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder
pub(crate) struct EncoderInFlight<A: HalApi> {
pub(crate) struct EncoderInFlight {
raw: Box<dyn hal::DynCommandEncoder>,
cmd_buffers: Vec<Box<dyn hal::DynCommandBuffer>>,
pub(crate) trackers: Tracker<A>,
pub(crate) trackers: Tracker,
/// These are the buffers that have been tracked by `PendingWrites`.
pub(crate) pending_buffers: FastHashMap<TrackerIndex, Arc<Buffer<A>>>,
pub(crate) pending_buffers: FastHashMap<TrackerIndex, Arc<Buffer>>,
/// These are the textures that have been tracked by `PendingWrites`.
pub(crate) pending_textures: FastHashMap<TrackerIndex, Arc<Texture<A>>>,
pub(crate) pending_textures: FastHashMap<TrackerIndex, Arc<Texture>>,
}
impl<A: HalApi> EncoderInFlight<A> {
impl EncoderInFlight {
/// Free all of our command buffers.
///
/// Return the command encoder, fully reset and ready to be
@ -203,7 +202,7 @@ impl<A: HalApi> EncoderInFlight<A> {
///
/// All uses of [`StagingBuffer`]s end up here.
#[derive(Debug)]
pub(crate) struct PendingWrites<A: HalApi> {
pub(crate) struct PendingWrites {
pub command_encoder: Box<dyn hal::DynCommandEncoder>,
/// True if `command_encoder` is in the "recording" state, as
@ -213,12 +212,12 @@ pub(crate) struct PendingWrites<A: HalApi> {
/// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder
pub is_recording: bool,
temp_resources: Vec<TempResource<A>>,
dst_buffers: FastHashMap<TrackerIndex, Arc<Buffer<A>>>,
dst_textures: FastHashMap<TrackerIndex, Arc<Texture<A>>>,
temp_resources: Vec<TempResource>,
dst_buffers: FastHashMap<TrackerIndex, Arc<Buffer>>,
dst_textures: FastHashMap<TrackerIndex, Arc<Texture>>,
}
impl<A: HalApi> PendingWrites<A> {
impl PendingWrites {
pub fn new(command_encoder: Box<dyn hal::DynCommandEncoder>) -> Self {
Self {
command_encoder,
@ -240,29 +239,29 @@ impl<A: HalApi> PendingWrites<A> {
self.temp_resources.clear();
}
pub fn insert_buffer(&mut self, buffer: &Arc<Buffer<A>>) {
pub fn insert_buffer(&mut self, buffer: &Arc<Buffer>) {
self.dst_buffers
.insert(buffer.tracker_index(), buffer.clone());
}
pub fn insert_texture(&mut self, texture: &Arc<Texture<A>>) {
pub fn insert_texture(&mut self, texture: &Arc<Texture>) {
self.dst_textures
.insert(texture.tracker_index(), texture.clone());
}
pub fn contains_buffer(&self, buffer: &Arc<Buffer<A>>) -> bool {
pub fn contains_buffer(&self, buffer: &Arc<Buffer>) -> bool {
self.dst_buffers.contains_key(&buffer.tracker_index())
}
pub fn contains_texture(&self, texture: &Arc<Texture<A>>) -> bool {
pub fn contains_texture(&self, texture: &Arc<Texture>) -> bool {
self.dst_textures.contains_key(&texture.tracker_index())
}
pub fn consume_temp(&mut self, resource: TempResource<A>) {
pub fn consume_temp(&mut self, resource: TempResource) {
self.temp_resources.push(resource);
}
pub fn consume(&mut self, buffer: FlushedStagingBuffer<A>) {
pub fn consume(&mut self, buffer: FlushedStagingBuffer) {
self.temp_resources
.push(TempResource::StagingBuffer(buffer));
}
@ -272,7 +271,7 @@ impl<A: HalApi> PendingWrites<A> {
command_allocator: &CommandAllocator,
device: &dyn hal::DynDevice,
queue: &dyn hal::DynQueue,
) -> Result<Option<EncoderInFlight<A>>, DeviceError> {
) -> Result<Option<EncoderInFlight>, DeviceError> {
if self.is_recording {
let pending_buffers = mem::take(&mut self.dst_buffers);
let pending_textures = mem::take(&mut self.dst_textures);
@ -362,7 +361,7 @@ pub enum QueueSubmitError {
//TODO: move out common parts of write_xxx.
impl Global {
pub fn queue_write_buffer<A: HalApi>(
pub fn queue_write_buffer(
&self,
queue_id: QueueId,
buffer_id: id::BufferId,
@ -372,7 +371,7 @@ impl Global {
profiling::scope!("Queue::write_buffer");
api_log!("Queue::write_buffer {buffer_id:?} {}bytes", data.len());
let hub = A::hub(self);
let hub = &self.hub;
let buffer = hub
.buffers
@ -433,14 +432,14 @@ impl Global {
result
}
pub fn queue_create_staging_buffer<A: HalApi>(
pub fn queue_create_staging_buffer(
&self,
queue_id: QueueId,
buffer_size: wgt::BufferSize,
id_in: Option<id::StagingBufferId>,
) -> Result<(id::StagingBufferId, NonNull<u8>), QueueWriteError> {
profiling::scope!("Queue::create_staging_buffer");
let hub = A::hub(self);
let hub = &self.hub;
let queue = hub
.queues
@ -452,14 +451,14 @@ impl Global {
let staging_buffer = StagingBuffer::new(device, buffer_size)?;
let ptr = unsafe { staging_buffer.ptr() };
let fid = hub.staging_buffers.prepare(id_in);
let fid = hub.staging_buffers.prepare(queue_id.backend(), id_in);
let id = fid.assign(Arc::new(staging_buffer));
resource_log!("Queue::create_staging_buffer {id:?}");
Ok((id, ptr))
}
pub fn queue_write_staging_buffer<A: HalApi>(
pub fn queue_write_staging_buffer(
&self,
queue_id: QueueId,
buffer_id: id::BufferId,
@ -467,7 +466,7 @@ impl Global {
staging_buffer_id: id::StagingBufferId,
) -> Result<(), QueueWriteError> {
profiling::scope!("Queue::write_staging_buffer");
let hub = A::hub(self);
let hub = &self.hub;
let queue = hub
.queues
@ -503,7 +502,7 @@ impl Global {
result
}
pub fn queue_validate_write_buffer<A: HalApi>(
pub fn queue_validate_write_buffer(
&self,
_queue_id: QueueId,
buffer_id: id::BufferId,
@ -511,7 +510,7 @@ impl Global {
buffer_size: wgt::BufferSize,
) -> Result<(), QueueWriteError> {
profiling::scope!("Queue::validate_write_buffer");
let hub = A::hub(self);
let hub = &self.hub;
let buffer = hub
.buffers
@ -523,9 +522,9 @@ impl Global {
Ok(())
}
fn queue_validate_write_buffer_impl<A: HalApi>(
fn queue_validate_write_buffer_impl(
&self,
buffer: &Buffer<A>,
buffer: &Buffer,
buffer_offset: u64,
buffer_size: wgt::BufferSize,
) -> Result<(), TransferError> {
@ -548,16 +547,16 @@ impl Global {
Ok(())
}
fn queue_write_staging_buffer_impl<A: HalApi>(
fn queue_write_staging_buffer_impl(
&self,
queue: &Arc<Queue<A>>,
device: &Arc<Device<A>>,
pending_writes: &mut PendingWrites<A>,
staging_buffer: &FlushedStagingBuffer<A>,
queue: &Arc<Queue>,
device: &Arc<Device>,
pending_writes: &mut PendingWrites,
staging_buffer: &FlushedStagingBuffer,
buffer_id: id::BufferId,
buffer_offset: u64,
) -> Result<(), QueueWriteError> {
let hub = A::hub(self);
let hub = &self.hub;
let dst = hub
.buffers
@ -606,7 +605,7 @@ impl Global {
Ok(())
}
pub fn queue_write_texture<A: HalApi>(
pub fn queue_write_texture(
&self,
queue_id: QueueId,
destination: &ImageCopyTexture,
@ -617,7 +616,7 @@ impl Global {
profiling::scope!("Queue::write_texture");
api_log!("Queue::write_texture {:?} {size:?}", destination.texture);
let hub = A::hub(self);
let hub = &self.hub;
let queue = hub
.queues
@ -849,7 +848,7 @@ impl Global {
}
#[cfg(webgl)]
pub fn queue_copy_external_image_to_texture<A: HalApi>(
pub fn queue_copy_external_image_to_texture(
&self,
queue_id: QueueId,
source: &wgt::ImageCopyExternalImage,
@ -858,7 +857,7 @@ impl Global {
) -> Result<(), QueueWriteError> {
profiling::scope!("Queue::copy_external_image_to_texture");
let hub = A::hub(self);
let hub = &self.hub;
let queue = hub
.queues
@ -1039,7 +1038,7 @@ impl Global {
Ok(())
}
pub fn queue_submit<A: HalApi>(
pub fn queue_submit(
&self,
queue_id: QueueId,
command_buffer_ids: &[id::CommandBufferId],
@ -1048,7 +1047,7 @@ impl Global {
api_log!("Queue::submit {queue_id:?}");
let (submit_index, callbacks) = {
let hub = A::hub(self);
let hub = &self.hub;
let queue = hub
.queues
@ -1186,13 +1185,13 @@ impl Global {
//Note: locking the trackers has to be done after the storages
let mut trackers = device.trackers.lock();
baked.initialize_buffer_memory(&mut *trackers, &snatch_guard)?;
baked.initialize_texture_memory(&mut *trackers, device, &snatch_guard)?;
baked.initialize_buffer_memory(&mut trackers, &snatch_guard)?;
baked.initialize_texture_memory(&mut trackers, device, &snatch_guard)?;
//Note: stateless trackers are not merged:
// device already knows these resources exist.
CommandBuffer::insert_barriers_from_device_tracker(
baked.encoder.as_mut(),
&mut *trackers,
&mut trackers,
&baked.trackers,
&snatch_guard,
);
@ -1353,18 +1352,15 @@ impl Global {
Ok(submit_index)
}
pub fn queue_get_timestamp_period<A: HalApi>(
&self,
queue_id: QueueId,
) -> Result<f32, InvalidQueue> {
let hub = A::hub(self);
pub fn queue_get_timestamp_period(&self, queue_id: QueueId) -> Result<f32, InvalidQueue> {
let hub = &self.hub;
match hub.queues.get(queue_id) {
Ok(queue) => Ok(unsafe { queue.raw().get_timestamp_period() }),
Err(_) => Err(InvalidQueue),
}
}
pub fn queue_on_submitted_work_done<A: HalApi>(
pub fn queue_on_submitted_work_done(
&self,
queue_id: QueueId,
closure: SubmittedWorkDoneClosure,
@ -1372,7 +1368,7 @@ impl Global {
api_log!("Queue::on_submitted_work_done {queue_id:?}");
//TODO: flush pending writes
let hub = A::hub(self);
let hub = &self.hub;
match hub.queues.get(queue_id) {
Ok(queue) => queue.device.lock_life().add_work_done_closure(closure),
Err(_) => return Err(InvalidQueue),

View File

@ -11,7 +11,6 @@ use crate::{
AttachmentData, DeviceLostInvocation, HostMap, MissingDownlevelFlags, MissingFeatures,
RenderPassContext, CLEANUP_WAIT_MS,
},
hal_api::HalApi,
hal_label,
init_tracker::{
BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange,
@ -77,10 +76,10 @@ use super::{
/// Important:
/// When locking pending_writes please check that trackers is not locked
/// trackers should be locked only when needed for the shortest time possible
pub struct Device<A: HalApi> {
pub struct Device {
raw: ManuallyDrop<Box<dyn hal::DynDevice>>,
pub(crate) adapter: Arc<Adapter>,
pub(crate) queue: OnceCell<Weak<Queue<A>>>,
pub(crate) queue: OnceCell<Weak<Queue>>,
queue_to_drop: OnceCell<Box<dyn hal::DynQueue>>,
pub(crate) zero_buffer: ManuallyDrop<Box<dyn hal::DynBuffer>>,
/// The `label` from the descriptor used to create the resource.
@ -130,30 +129,30 @@ pub struct Device<A: HalApi> {
///
/// Has to be locked temporarily only (locked last)
/// and never before pending_writes
pub(crate) trackers: Mutex<DeviceTracker<A>>,
pub(crate) trackers: Mutex<DeviceTracker>,
pub(crate) tracker_indices: TrackerIndexAllocators,
// Life tracker should be locked right after the device and before anything else.
life_tracker: Mutex<LifetimeTracker<A>>,
life_tracker: Mutex<LifetimeTracker>,
/// Pool of bind group layouts, allowing deduplication.
pub(crate) bgl_pool: ResourcePool<bgl::EntryMap, BindGroupLayout<A>>,
pub(crate) bgl_pool: ResourcePool<bgl::EntryMap, BindGroupLayout>,
pub(crate) alignments: hal::Alignments,
pub(crate) limits: wgt::Limits,
pub(crate) features: wgt::Features,
pub(crate) downlevel: wgt::DownlevelCapabilities,
pub(crate) instance_flags: wgt::InstanceFlags,
pub(crate) pending_writes: Mutex<ManuallyDrop<PendingWrites<A>>>,
pub(crate) deferred_destroy: Mutex<Vec<DeferredDestroy<A>>>,
pub(crate) pending_writes: Mutex<ManuallyDrop<PendingWrites>>,
pub(crate) deferred_destroy: Mutex<Vec<DeferredDestroy>>,
#[cfg(feature = "trace")]
pub(crate) trace: Mutex<Option<trace::Trace>>,
pub(crate) usage_scopes: UsageScopePool<A>,
pub(crate) usage_scopes: UsageScopePool,
}
pub(crate) enum DeferredDestroy<A: HalApi> {
TextureView(Weak<TextureView<A>>),
BindGroup(Weak<BindGroup<A>>),
pub(crate) enum DeferredDestroy {
TextureView(Weak<TextureView>),
BindGroup(Weak<BindGroup>),
}
impl<A: HalApi> std::fmt::Debug for Device<A> {
impl std::fmt::Debug for Device {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Device")
.field("label", &self.label())
@ -164,7 +163,7 @@ impl<A: HalApi> std::fmt::Debug for Device<A> {
}
}
impl<A: HalApi> Drop for Device<A> {
impl Drop for Device {
fn drop(&mut self) {
resource_log!("Drop {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -194,7 +193,7 @@ pub enum CreateDeviceError {
FailedToCreateZeroBuffer(#[from] DeviceError),
}
impl<A: HalApi> Device<A> {
impl Device {
pub(crate) fn raw(&self) -> &dyn hal::DynDevice {
self.raw.as_ref()
}
@ -218,7 +217,7 @@ impl<A: HalApi> Device<A> {
}
}
impl<A: HalApi> Device<A> {
impl Device {
pub(crate) fn new(
raw_device: Box<dyn hal::DynDevice>,
raw_queue: &dyn hal::DynQueue,
@ -238,7 +237,7 @@ impl<A: HalApi> Device<A> {
let pending_encoder = command_allocator
.acquire_encoder(raw_device.as_ref(), raw_queue)
.map_err(|_| CreateDeviceError::OutOfMemory)?;
let mut pending_writes = PendingWrites::<A>::new(pending_encoder);
let mut pending_writes = PendingWrites::new(pending_encoder);
// Create zeroed buffer used for texture clears.
let zero_buffer = unsafe {
@ -297,7 +296,7 @@ impl<A: HalApi> Device<A> {
Ok(mut trace) => {
trace.add(trace::Action::Init {
desc: desc.clone(),
backend: A::VARIANT,
backend: adapter.raw.backend(),
});
Some(trace)
}
@ -321,6 +320,11 @@ impl<A: HalApi> Device<A> {
})
}
/// Returns the backend this device is using.
pub fn backend(&self) -> wgt::Backend {
self.adapter.raw.backend()
}
pub fn is_valid(&self) -> bool {
self.valid.load(Ordering::Acquire)
}
@ -337,7 +341,7 @@ impl<A: HalApi> Device<A> {
assert!(self.queue_to_drop.set(queue).is_ok());
}
pub(crate) fn lock_life<'a>(&'a self) -> MutexGuard<'a, LifetimeTracker<A>> {
pub(crate) fn lock_life<'a>(&'a self) -> MutexGuard<'a, LifetimeTracker> {
self.life_tracker.lock()
}
@ -384,11 +388,11 @@ impl<A: HalApi> Device<A> {
}
}
pub fn get_queue(&self) -> Option<Arc<Queue<A>>> {
pub fn get_queue(&self) -> Option<Arc<Queue>> {
self.queue.get().as_ref()?.upgrade()
}
pub fn set_queue(&self, queue: &Arc<Queue<A>>) {
pub fn set_queue(&self, queue: &Arc<Queue>) {
assert!(self.queue.set(Arc::downgrade(queue)).is_ok());
}
@ -504,7 +508,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_buffer(
self: &Arc<Self>,
desc: &resource::BufferDescriptor,
) -> Result<Arc<Buffer<A>>, resource::CreateBufferError> {
) -> Result<Arc<Buffer>, resource::CreateBufferError> {
self.check_is_valid()?;
if desc.size > self.limits.max_buffer_size {
@ -652,7 +656,7 @@ impl<A: HalApi> Device<A> {
self: &Arc<Self>,
hal_texture: Box<dyn hal::DynTexture>,
desc: &resource::TextureDescriptor,
) -> Result<Arc<Texture<A>>, resource::CreateTextureError> {
) -> Result<Arc<Texture>, resource::CreateTextureError> {
let format_features = self
.describe_format_features(desc.format)
.map_err(|error| resource::CreateTextureError::MissingFeatures(desc.format, error))?;
@ -679,11 +683,11 @@ impl<A: HalApi> Device<A> {
pub fn create_buffer_from_hal(
self: &Arc<Self>,
hal_buffer: A::Buffer,
hal_buffer: Box<dyn hal::DynBuffer>,
desc: &resource::BufferDescriptor,
) -> Arc<Buffer<A>> {
) -> Arc<Buffer> {
let buffer = Buffer {
raw: Snatchable::new(Box::new(hal_buffer)),
raw: Snatchable::new(hal_buffer),
device: self.clone(),
usage: desc.usage,
size: desc.size,
@ -710,7 +714,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_texture(
self: &Arc<Self>,
desc: &resource::TextureDescriptor,
) -> Result<Arc<Texture<A>>, resource::CreateTextureError> {
) -> Result<Arc<Texture>, resource::CreateTextureError> {
use resource::{CreateTextureError, TextureDimensionError};
self.check_is_valid()?;
@ -1017,9 +1021,9 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_texture_view(
self: &Arc<Self>,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
desc: &resource::TextureViewDescriptor,
) -> Result<Arc<TextureView<A>>, resource::CreateTextureViewError> {
) -> Result<Arc<TextureView>, resource::CreateTextureViewError> {
self.check_is_valid()?;
let snatch_guard = texture.device.snatchable_lock.read();
@ -1323,7 +1327,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_sampler(
self: &Arc<Self>,
desc: &resource::SamplerDescriptor,
) -> Result<Arc<Sampler<A>>, resource::CreateSamplerError> {
) -> Result<Arc<Sampler>, resource::CreateSamplerError> {
self.check_is_valid()?;
if desc
@ -1438,7 +1442,7 @@ impl<A: HalApi> Device<A> {
self: &Arc<Self>,
desc: &pipeline::ShaderModuleDescriptor<'a>,
source: pipeline::ShaderModuleSource<'a>,
) -> Result<Arc<pipeline::ShaderModule<A>>, pipeline::CreateShaderModuleError> {
) -> Result<Arc<pipeline::ShaderModule>, pipeline::CreateShaderModuleError> {
self.check_is_valid()?;
let (module, source) = match source {
@ -1567,7 +1571,7 @@ impl<A: HalApi> Device<A> {
self: &Arc<Self>,
desc: &pipeline::ShaderModuleDescriptor<'a>,
source: &'a [u32],
) -> Result<Arc<pipeline::ShaderModule<A>>, pipeline::CreateShaderModuleError> {
) -> Result<Arc<pipeline::ShaderModule>, pipeline::CreateShaderModuleError> {
self.check_is_valid()?;
self.require_features(wgt::Features::SPIRV_SHADER_PASSTHROUGH)?;
@ -1606,7 +1610,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_command_encoder(
self: &Arc<Self>,
label: &crate::Label,
) -> Result<Arc<command::CommandBuffer<A>>, DeviceError> {
) -> Result<Arc<command::CommandBuffer>, DeviceError> {
self.check_is_valid()?;
let queue = self.get_queue().unwrap();
@ -1626,7 +1630,7 @@ impl<A: HalApi> Device<A> {
//TODO: should this be combined with `get_introspection_bind_group_layouts` in some way?
pub(crate) fn make_late_sized_buffer_groups(
shader_binding_sizes: &FastHashMap<naga::ResourceBinding, wgt::BufferSize>,
layout: &binding_model::PipelineLayout<A>,
layout: &binding_model::PipelineLayout,
) -> ArrayVec<pipeline::LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }> {
// Given the shader-required binding sizes and the pipeline layout,
// return the filtered list of them in the layout order,
@ -1664,7 +1668,7 @@ impl<A: HalApi> Device<A> {
label: &crate::Label,
entry_map: bgl::EntryMap,
origin: bgl::Origin,
) -> Result<Arc<BindGroupLayout<A>>, binding_model::CreateBindGroupLayoutError> {
) -> Result<Arc<BindGroupLayout>, binding_model::CreateBindGroupLayoutError> {
#[derive(PartialEq)]
enum WritableStorage {
Yes,
@ -1878,13 +1882,13 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_buffer_binding<'a>(
self: &Arc<Self>,
bb: &'a binding_model::ResolvedBufferBinding<A>,
bb: &'a binding_model::ResolvedBufferBinding,
binding: u32,
decl: &wgt::BindGroupLayoutEntry,
used_buffer_ranges: &mut Vec<BufferInitTrackerAction<A>>,
used_buffer_ranges: &mut Vec<BufferInitTrackerAction>,
dynamic_binding_info: &mut Vec<binding_model::BindGroupDynamicBindingData>,
late_buffer_binding_sizes: &mut FastHashMap<u32, wgt::BufferSize>,
used: &mut BindGroupStates<A>,
used: &mut BindGroupStates,
limits: &wgt::Limits,
snatch_guard: &'a SnatchGuard<'a>,
) -> Result<hal::BufferBinding<'a, dyn hal::DynBuffer>, binding_model::CreateBindGroupError>
@ -2016,10 +2020,10 @@ impl<A: HalApi> Device<A> {
fn create_sampler_binding<'a>(
self: &Arc<Self>,
used: &mut BindGroupStates<A>,
used: &mut BindGroupStates,
binding: u32,
decl: &wgt::BindGroupLayoutEntry,
sampler: &'a Arc<Sampler<A>>,
sampler: &'a Arc<Sampler>,
) -> Result<&'a dyn hal::DynSampler, binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error;
@ -2067,9 +2071,9 @@ impl<A: HalApi> Device<A> {
self: &Arc<Self>,
binding: u32,
decl: &wgt::BindGroupLayoutEntry,
view: &'a Arc<TextureView<A>>,
used: &mut BindGroupStates<A>,
used_texture_ranges: &mut Vec<TextureInitTrackerAction<A>>,
view: &'a Arc<TextureView>,
used: &mut BindGroupStates,
used_texture_ranges: &mut Vec<TextureInitTrackerAction>,
snatch_guard: &'a SnatchGuard<'a>,
) -> Result<hal::TextureBinding<'a, dyn hal::DynTextureView>, binding_model::CreateBindGroupError>
{
@ -2109,8 +2113,8 @@ impl<A: HalApi> Device<A> {
// (not passing a duplicate) beforehand.
pub(crate) fn create_bind_group(
self: &Arc<Self>,
desc: binding_model::ResolvedBindGroupDescriptor<A>,
) -> Result<Arc<BindGroup<A>>, binding_model::CreateBindGroupError> {
desc: binding_model::ResolvedBindGroupDescriptor,
) -> Result<Arc<BindGroup>, binding_model::CreateBindGroupError> {
use crate::binding_model::{CreateBindGroupError as Error, ResolvedBindingResource as Br};
let layout = desc.layout;
@ -2357,7 +2361,7 @@ impl<A: HalApi> Device<A> {
self: &Arc<Self>,
binding: u32,
decl: &wgt::BindGroupLayoutEntry,
view: &TextureView<A>,
view: &TextureView,
expected: &'static str,
) -> Result<(wgt::TextureUsages, hal::TextureUses), binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error;
@ -2486,9 +2490,8 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_pipeline_layout(
self: &Arc<Self>,
desc: &binding_model::ResolvedPipelineLayoutDescriptor<A>,
) -> Result<Arc<binding_model::PipelineLayout<A>>, binding_model::CreatePipelineLayoutError>
{
desc: &binding_model::ResolvedPipelineLayoutDescriptor,
) -> Result<Arc<binding_model::PipelineLayout>, binding_model::CreatePipelineLayoutError> {
use crate::binding_model::CreatePipelineLayoutError as Error;
self.check_is_valid()?;
@ -2594,7 +2597,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn derive_pipeline_layout(
self: &Arc<Self>,
mut derived_group_layouts: ArrayVec<bgl::EntryMap, { hal::MAX_BIND_GROUPS }>,
) -> Result<Arc<binding_model::PipelineLayout<A>>, pipeline::ImplicitLayoutError> {
) -> Result<Arc<binding_model::PipelineLayout>, pipeline::ImplicitLayoutError> {
while derived_group_layouts
.last()
.map_or(false, |map| map.is_empty())
@ -2639,8 +2642,8 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_compute_pipeline(
self: &Arc<Self>,
desc: pipeline::ResolvedComputePipelineDescriptor<A>,
) -> Result<Arc<pipeline::ComputePipeline<A>>, pipeline::CreateComputePipelineError> {
desc: pipeline::ResolvedComputePipelineDescriptor,
) -> Result<Arc<pipeline::ComputePipeline>, pipeline::CreateComputePipelineError> {
self.check_is_valid()?;
self.require_downlevel_flags(wgt::DownlevelFlags::COMPUTE_SHADERS)?;
@ -2772,8 +2775,8 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_render_pipeline(
self: &Arc<Self>,
desc: pipeline::ResolvedRenderPipelineDescriptor<A>,
) -> Result<Arc<pipeline::RenderPipeline<A>>, pipeline::CreateRenderPipelineError> {
desc: pipeline::ResolvedRenderPipelineDescriptor,
) -> Result<Arc<pipeline::RenderPipeline>, pipeline::CreateRenderPipelineError> {
use wgt::TextureFormatFeatureFlags as Tfff;
self.check_is_valid()?;
@ -3400,7 +3403,7 @@ impl<A: HalApi> Device<A> {
pub unsafe fn create_pipeline_cache(
self: &Arc<Self>,
desc: &pipeline::PipelineCacheDescriptor,
) -> Result<Arc<pipeline::PipelineCache<A>>, pipeline::CreatePipelineCacheError> {
) -> Result<Arc<pipeline::PipelineCache>, pipeline::CreatePipelineCacheError> {
use crate::pipeline_cache;
self.check_is_valid()?;
@ -3509,7 +3512,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_query_set(
self: &Arc<Self>,
desc: &resource::QuerySetDescriptor,
) -> Result<Arc<QuerySet<A>>, resource::CreateQuerySetError> {
) -> Result<Arc<QuerySet>, resource::CreateQuerySetError> {
use resource::CreateQuerySetError as Error;
self.check_is_valid()?;
@ -3605,7 +3608,7 @@ impl<A: HalApi> Device<A> {
}
}
pub(crate) fn new_usage_scope(&self) -> UsageScope<'_, A> {
pub(crate) fn new_usage_scope(&self) -> UsageScope<'_> {
UsageScope::new_pooled(&self.usage_scopes, &self.tracker_indices)
}
@ -3618,8 +3621,8 @@ impl<A: HalApi> Device<A> {
}
}
impl<A: HalApi> Device<A> {
pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer<A>) {
impl Device {
pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer) {
let mut baked = cmd_buf.extract_baked_commands();
unsafe {
baked.encoder.reset_all(baked.list);
@ -3656,6 +3659,6 @@ impl<A: HalApi> Device<A> {
}
}
crate::impl_resource_type_generic!(Device);
crate::impl_resource_type!(Device);
crate::impl_labeled!(Device);
crate::impl_storage_item_generic!(Device);
crate::impl_storage_item!(Device);

View File

@ -1,10 +1,6 @@
use std::collections::HashMap;
use wgt::Backend;
use crate::{
hal_api::HalApi,
hub::{HubReport, Hubs},
hub::{Hub, HubReport},
instance::{Instance, Surface},
registry::{Registry, RegistryReport},
resource_log,
@ -13,22 +9,22 @@ use crate::{
#[derive(Debug, PartialEq, Eq)]
pub struct GlobalReport {
pub surfaces: RegistryReport,
pub report_per_backend: HashMap<Backend, HubReport>,
pub hub: HubReport,
}
impl GlobalReport {
pub fn surfaces(&self) -> &RegistryReport {
&self.surfaces
}
pub fn hub_report(&self, backend: Backend) -> &HubReport {
self.report_per_backend.get(&backend).unwrap()
pub fn hub_report(&self) -> &HubReport {
&self.hub
}
}
pub struct Global {
pub instance: Instance,
pub(crate) surfaces: Registry<Surface>,
pub(crate) hubs: Hubs,
pub(crate) hub: Hub,
}
impl Global {
@ -36,8 +32,8 @@ impl Global {
profiling::scope!("Global::new");
Self {
instance: Instance::new(name, instance_desc),
surfaces: Registry::without_backend(),
hubs: Hubs::new(),
surfaces: Registry::new(),
hub: Hub::new(),
}
}
@ -54,8 +50,8 @@ impl Global {
instance_per_backend: std::iter::once((A::VARIANT, dyn_instance)).collect(),
..Default::default()
},
surfaces: Registry::without_backend(),
hubs: Hubs::new(),
surfaces: Registry::new(),
hub: Hub::new(),
}
}
@ -79,47 +75,15 @@ impl Global {
profiling::scope!("Global::new");
Self {
instance,
surfaces: Registry::without_backend(),
hubs: Hubs::new(),
surfaces: Registry::new(),
hub: Hub::new(),
}
}
pub fn generate_report(&self) -> GlobalReport {
let mut report_per_backend = HashMap::default();
let instance_per_backend = &self.instance.instance_per_backend;
#[cfg(vulkan)]
if instance_per_backend
.iter()
.any(|(backend, _)| backend == &Backend::Vulkan)
{
report_per_backend.insert(Backend::Vulkan, self.hubs.vulkan.generate_report());
};
#[cfg(metal)]
if instance_per_backend
.iter()
.any(|(backend, _)| backend == &Backend::Metal)
{
report_per_backend.insert(Backend::Metal, self.hubs.metal.generate_report());
};
#[cfg(dx12)]
if instance_per_backend
.iter()
.any(|(backend, _)| backend == &Backend::Dx12)
{
report_per_backend.insert(Backend::Dx12, self.hubs.dx12.generate_report());
};
#[cfg(gles)]
if instance_per_backend
.iter()
.any(|(backend, _)| backend == &Backend::Gl)
{
report_per_backend.insert(Backend::Gl, self.hubs.gl.generate_report());
};
GlobalReport {
surfaces: self.surfaces.generate_report(),
report_per_backend,
hub: self.hub.generate_report(),
}
}
}
@ -130,23 +94,8 @@ impl Drop for Global {
resource_log!("Global::drop");
let mut surfaces_locked = self.surfaces.write();
// destroy hubs before the instance gets dropped
#[cfg(vulkan)]
{
self.hubs.vulkan.clear(&surfaces_locked);
}
#[cfg(metal)]
{
self.hubs.metal.clear(&surfaces_locked);
}
#[cfg(dx12)]
{
self.hubs.dx12.clear(&surfaces_locked);
}
#[cfg(gles)]
{
self.hubs.gl.clear(&surfaces_locked);
}
// destroy hub before the instance gets dropped
self.hub.clear(&surfaces_locked);
surfaces_locked.map.clear();
}

View File

@ -1,53 +1,29 @@
use wgt::{Backend, WasmNotSendSync};
use crate::{global::Global, hub::Hub};
pub trait HalApi: hal::Api + 'static + WasmNotSendSync {
const VARIANT: Backend;
fn hub(global: &Global) -> &Hub<Self>;
}
impl HalApi for hal::api::Empty {
const VARIANT: Backend = Backend::Empty;
fn hub(_: &Global) -> &Hub<Self> {
unimplemented!("called empty api")
}
}
#[cfg(vulkan)]
impl HalApi for hal::api::Vulkan {
const VARIANT: Backend = Backend::Vulkan;
fn hub(global: &Global) -> &Hub<Self> {
&global.hubs.vulkan
}
}
#[cfg(metal)]
impl HalApi for hal::api::Metal {
const VARIANT: Backend = Backend::Metal;
fn hub(global: &Global) -> &Hub<Self> {
&global.hubs.metal
}
}
#[cfg(dx12)]
impl HalApi for hal::api::Dx12 {
const VARIANT: Backend = Backend::Dx12;
fn hub(global: &Global) -> &Hub<Self> {
&global.hubs.dx12
}
}
#[cfg(gles)]
impl HalApi for hal::api::Gles {
const VARIANT: Backend = Backend::Gl;
fn hub(global: &Global) -> &Hub<Self> {
&global.hubs.gl
}
}

View File

@ -108,7 +108,6 @@ use crate::{
binding_model::{BindGroup, BindGroupLayout, PipelineLayout},
command::{CommandBuffer, RenderBundle},
device::{queue::Queue, Device},
hal_api::HalApi,
instance::{Adapter, Surface},
pipeline::{ComputePipeline, PipelineCache, RenderPipeline, ShaderModule},
registry::{Registry, RegistryReport},
@ -145,10 +144,7 @@ impl HubReport {
}
#[allow(rustdoc::private_intra_doc_links)]
/// All the resources for a particular backend in a [`crate::global::Global`].
///
/// To obtain `global`'s `Hub` for some [`HalApi`] backend type `A`,
/// call [`A::hub(global)`].
/// All the resources tracked by a [`crate::global::Global`].
///
/// ## Locking
///
@ -169,48 +165,48 @@ impl HubReport {
///
///
/// [`A::hub(global)`]: HalApi::hub
pub struct Hub<A: HalApi> {
pub struct Hub {
pub(crate) adapters: Registry<Adapter>,
pub(crate) devices: Registry<Device<A>>,
pub(crate) queues: Registry<Queue<A>>,
pub(crate) pipeline_layouts: Registry<PipelineLayout<A>>,
pub(crate) shader_modules: Registry<ShaderModule<A>>,
pub(crate) bind_group_layouts: Registry<BindGroupLayout<A>>,
pub(crate) bind_groups: Registry<BindGroup<A>>,
pub(crate) command_buffers: Registry<CommandBuffer<A>>,
pub(crate) render_bundles: Registry<RenderBundle<A>>,
pub(crate) render_pipelines: Registry<RenderPipeline<A>>,
pub(crate) compute_pipelines: Registry<ComputePipeline<A>>,
pub(crate) pipeline_caches: Registry<PipelineCache<A>>,
pub(crate) query_sets: Registry<QuerySet<A>>,
pub(crate) buffers: Registry<Buffer<A>>,
pub(crate) staging_buffers: Registry<StagingBuffer<A>>,
pub(crate) textures: Registry<Texture<A>>,
pub(crate) texture_views: Registry<TextureView<A>>,
pub(crate) samplers: Registry<Sampler<A>>,
pub(crate) devices: Registry<Device>,
pub(crate) queues: Registry<Queue>,
pub(crate) pipeline_layouts: Registry<PipelineLayout>,
pub(crate) shader_modules: Registry<ShaderModule>,
pub(crate) bind_group_layouts: Registry<BindGroupLayout>,
pub(crate) bind_groups: Registry<BindGroup>,
pub(crate) command_buffers: Registry<CommandBuffer>,
pub(crate) render_bundles: Registry<RenderBundle>,
pub(crate) render_pipelines: Registry<RenderPipeline>,
pub(crate) compute_pipelines: Registry<ComputePipeline>,
pub(crate) pipeline_caches: Registry<PipelineCache>,
pub(crate) query_sets: Registry<QuerySet>,
pub(crate) buffers: Registry<Buffer>,
pub(crate) staging_buffers: Registry<StagingBuffer>,
pub(crate) textures: Registry<Texture>,
pub(crate) texture_views: Registry<TextureView>,
pub(crate) samplers: Registry<Sampler>,
}
impl<A: HalApi> Hub<A> {
fn new() -> Self {
impl Hub {
pub(crate) fn new() -> Self {
Self {
adapters: Registry::new(A::VARIANT),
devices: Registry::new(A::VARIANT),
queues: Registry::new(A::VARIANT),
pipeline_layouts: Registry::new(A::VARIANT),
shader_modules: Registry::new(A::VARIANT),
bind_group_layouts: Registry::new(A::VARIANT),
bind_groups: Registry::new(A::VARIANT),
command_buffers: Registry::new(A::VARIANT),
render_bundles: Registry::new(A::VARIANT),
render_pipelines: Registry::new(A::VARIANT),
compute_pipelines: Registry::new(A::VARIANT),
pipeline_caches: Registry::new(A::VARIANT),
query_sets: Registry::new(A::VARIANT),
buffers: Registry::new(A::VARIANT),
staging_buffers: Registry::new(A::VARIANT),
textures: Registry::new(A::VARIANT),
texture_views: Registry::new(A::VARIANT),
samplers: Registry::new(A::VARIANT),
adapters: Registry::new(),
devices: Registry::new(),
queues: Registry::new(),
pipeline_layouts: Registry::new(),
shader_modules: Registry::new(),
bind_group_layouts: Registry::new(),
bind_groups: Registry::new(),
command_buffers: Registry::new(),
render_bundles: Registry::new(),
render_pipelines: Registry::new(),
compute_pipelines: Registry::new(),
pipeline_caches: Registry::new(),
query_sets: Registry::new(),
buffers: Registry::new(),
staging_buffers: Registry::new(),
textures: Registry::new(),
texture_views: Registry::new(),
samplers: Registry::new(),
}
}
@ -239,11 +235,9 @@ impl<A: HalApi> Hub<A> {
for element in surface_guard.map.iter() {
if let Element::Occupied(ref surface, _epoch) = *element {
if let Some(ref mut present) = surface.presentation.lock().take() {
if let Some(device) = present.device.downcast_ref::<A>() {
let suf = surface.raw(A::VARIANT);
let suf = surface.raw(present.device.backend());
unsafe {
suf.unwrap().unconfigure(device.raw());
}
suf.unwrap().unconfigure(present.device.raw());
}
}
}
@ -278,33 +272,3 @@ impl<A: HalApi> Hub<A> {
}
}
}
pub struct Hubs {
#[cfg(vulkan)]
pub(crate) vulkan: Hub<hal::api::Vulkan>,
#[cfg(metal)]
pub(crate) metal: Hub<hal::api::Metal>,
#[cfg(dx12)]
pub(crate) dx12: Hub<hal::api::Dx12>,
#[cfg(gles)]
pub(crate) gl: Hub<hal::api::Gles>,
#[cfg(all(not(vulkan), not(metal), not(dx12), not(gles)))]
pub(crate) empty: Hub<hal::api::Empty>,
}
impl Hubs {
pub(crate) fn new() -> Self {
Self {
#[cfg(vulkan)]
vulkan: Hub::new(),
#[cfg(metal)]
metal: Hub::new(),
#[cfg(dx12)]
dx12: Hub::new(),
#[cfg(gles)]
gl: Hub::new(),
#[cfg(all(not(vulkan), not(metal), not(dx12), not(gles)))]
empty: Hub::new(),
}
}
}

View File

@ -1,10 +1,10 @@
use super::{InitTracker, MemoryInitKind};
use crate::{hal_api::HalApi, resource::Buffer};
use crate::resource::Buffer;
use std::{ops::Range, sync::Arc};
#[derive(Debug, Clone)]
pub(crate) struct BufferInitTrackerAction<A: HalApi> {
pub buffer: Arc<Buffer<A>>,
pub(crate) struct BufferInitTrackerAction {
pub buffer: Arc<Buffer>,
pub range: Range<wgt::BufferAddress>,
pub kind: MemoryInitKind,
}
@ -14,21 +14,21 @@ pub(crate) type BufferInitTracker = InitTracker<wgt::BufferAddress>;
impl BufferInitTracker {
/// Checks if an action has/requires any effect on the initialization status
/// and shrinks its range if possible.
pub(crate) fn check_action<A: HalApi>(
pub(crate) fn check_action(
&self,
action: &BufferInitTrackerAction<A>,
) -> Option<BufferInitTrackerAction<A>> {
action: &BufferInitTrackerAction,
) -> Option<BufferInitTrackerAction> {
self.create_action(&action.buffer, action.range.clone(), action.kind)
}
/// Creates an action if it would have any effect on the initialization
/// status and shrinks the range if possible.
pub(crate) fn create_action<A: HalApi>(
pub(crate) fn create_action(
&self,
buffer: &Arc<Buffer<A>>,
buffer: &Arc<Buffer>,
query_range: Range<wgt::BufferAddress>,
kind: MemoryInitKind,
) -> Option<BufferInitTrackerAction<A>> {
) -> Option<BufferInitTrackerAction> {
self.check(query_range)
.map(|range| BufferInitTrackerAction {
buffer: buffer.clone(),

View File

@ -1,5 +1,5 @@
use super::{InitTracker, MemoryInitKind};
use crate::{hal_api::HalApi, resource::Texture, track::TextureSelector};
use crate::{resource::Texture, track::TextureSelector};
use arrayvec::ArrayVec;
use std::{ops::Range, sync::Arc};
@ -35,8 +35,8 @@ impl From<TextureSelector> for TextureInitRange {
}
#[derive(Debug, Clone)]
pub(crate) struct TextureInitTrackerAction<A: HalApi> {
pub(crate) texture: Arc<Texture<A>>,
pub(crate) struct TextureInitTrackerAction {
pub(crate) texture: Arc<Texture>,
pub(crate) range: TextureInitRange,
pub(crate) kind: MemoryInitKind,
}
@ -57,10 +57,10 @@ impl TextureInitTracker {
}
}
pub(crate) fn check_action<A: HalApi>(
pub(crate) fn check_action(
&self,
action: &TextureInitTrackerAction<A>,
) -> Option<TextureInitTrackerAction<A>> {
action: &TextureInitTrackerAction,
) -> Option<TextureInitTrackerAction> {
let mut mip_range_start = usize::MAX;
let mut mip_range_end = usize::MIN;
let mut layer_range_start = u32::MAX;

View File

@ -1,6 +1,7 @@
use std::sync::Arc;
use std::{borrow::Cow, collections::HashMap};
use crate::hub::Hub;
use crate::{
api_log,
device::{queue::Queue, resource::Device, DeviceDescriptor},
@ -262,13 +263,13 @@ impl Adapter {
}
#[allow(clippy::type_complexity)]
fn create_device_and_queue_from_hal<A: HalApi>(
fn create_device_and_queue_from_hal(
self: &Arc<Self>,
hal_device: hal::DynOpenDevice,
desc: &DeviceDescriptor,
instance_flags: wgt::InstanceFlags,
trace_path: Option<&std::path::Path>,
) -> Result<(Arc<Device<A>>, Arc<Queue<A>>), RequestDeviceError> {
) -> Result<(Arc<Device>, Arc<Queue>), RequestDeviceError> {
api_log!("Adapter::create_device");
if let Ok(device) = Device::new(
@ -288,12 +289,12 @@ impl Adapter {
}
#[allow(clippy::type_complexity)]
fn create_device_and_queue<A: HalApi>(
fn create_device_and_queue(
self: &Arc<Self>,
desc: &DeviceDescriptor,
instance_flags: wgt::InstanceFlags,
trace_path: Option<&std::path::Path>,
) -> Result<(Arc<Device<A>>, Arc<Queue<A>>), RequestDeviceError> {
) -> Result<(Arc<Device>, Arc<Queue>), RequestDeviceError> {
// Verify all features were exposed by the adapter
if !self.raw.features.contains(desc.required_features) {
return Err(RequestDeviceError::UnsupportedFeature(
@ -302,7 +303,7 @@ impl Adapter {
}
let caps = &self.raw.capabilities;
if Backends::PRIMARY.contains(Backends::from(A::VARIANT))
if Backends::PRIMARY.contains(Backends::from(self.raw.backend()))
&& !caps.downlevel.is_webgpu_compliant()
{
let missing_flags = wgt::DownlevelFlags::compliant() - caps.downlevel.flags;
@ -495,7 +496,10 @@ impl Global {
};
#[allow(clippy::arc_with_non_send_sync)]
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
let id = self
.surfaces
.prepare(wgt::Backend::Empty, id_in) // No specific backend for Surface, since it's not specific.
.assign(Arc::new(surface));
Ok(id)
}
}
@ -538,7 +542,10 @@ impl Global {
surface_per_backend: std::iter::once((Backend::Metal, raw_surface)).collect(),
};
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
let id = self
.surfaces
.prepare(Backend::Metal, id_in)
.assign(Arc::new(surface));
Ok(id)
}
@ -560,7 +567,10 @@ impl Global {
surface_per_backend: std::iter::once((Backend::Dx12, surface)).collect(),
};
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
let id = self
.surfaces
.prepare(Backend::Dx12, id_in)
.assign(Arc::new(surface));
Ok(id)
}
@ -614,83 +624,65 @@ impl Global {
api_log!("Surface::drop {id:?}");
fn unconfigure<A: HalApi>(surface: &Surface, present: &Presentation) {
if let Some(surface) = surface.raw(A::VARIANT) {
if let Some(device) = present.device.downcast_ref::<A>() {
unsafe { surface.unconfigure(device.raw()) };
}
}
}
let surface = self.surfaces.unregister(id);
let surface = Arc::into_inner(surface.unwrap())
.expect("Surface cannot be destroyed because is still in use");
if let Some(present) = surface.presentation.lock().take() {
// TODO(#5124): Becomes a loop once we use Arc<Device>
#[cfg(vulkan)]
unconfigure::<hal::api::Vulkan>(&surface, &present);
#[cfg(metal)]
unconfigure::<hal::api::Metal>(&surface, &present);
#[cfg(dx12)]
unconfigure::<hal::api::Dx12>(&surface, &present);
#[cfg(gles)]
unconfigure::<hal::api::Gles>(&surface, &present);
for (&backend, surface) in &surface.surface_per_backend {
if backend == present.device.backend() {
unsafe { surface.unconfigure(present.device.raw()) };
}
}
}
drop(surface)
}
fn enumerate<A: HalApi>(
&self,
inputs: &AdapterInputs<markers::Adapter>,
list: &mut Vec<AdapterId>,
) {
let inst = match self
.instance
.instance_per_backend
.iter()
.find(|(backend, _)| backend == &A::VARIANT)
{
Some((_, inst)) => inst.as_ref(),
None => return,
};
let id_backend = match inputs.find(A::VARIANT) {
Some(id) => id,
None => return,
};
profiling::scope!("enumerating", &*format!("{:?}", backend));
let hub: &crate::hub::Hub<A> = HalApi::hub(self);
let hal_adapters = unsafe { inst.enumerate_adapters(None) };
for raw in hal_adapters {
let adapter = Adapter::new(raw);
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
let id = hub.adapters.prepare(id_backend).assign(Arc::new(adapter));
list.push(id);
}
}
pub fn enumerate_adapters(&self, inputs: AdapterInputs<markers::Adapter>) -> Vec<AdapterId> {
profiling::scope!("Instance::enumerate_adapters");
api_log!("Instance::enumerate_adapters");
fn enumerate(
hub: &Hub,
backend: Backend,
instance: &dyn hal::DynInstance,
inputs: &AdapterInputs<markers::Adapter>,
list: &mut Vec<AdapterId>,
) {
let Some(id_backend) = inputs.find(backend) else {
return;
};
profiling::scope!("enumerating", &*format!("{:?}", backend));
let hal_adapters = unsafe { instance.enumerate_adapters(None) };
for raw in hal_adapters {
let adapter = Adapter::new(raw);
log::info!("Adapter {:?}", adapter.raw.info);
let id = hub
.adapters
.prepare(backend, id_backend)
.assign(Arc::new(adapter));
list.push(id);
}
}
let mut adapters = Vec::new();
#[cfg(vulkan)]
self.enumerate::<hal::vulkan::Api>(&inputs, &mut adapters);
#[cfg(metal)]
self.enumerate::<hal::metal::Api>(&inputs, &mut adapters);
#[cfg(dx12)]
self.enumerate::<hal::dx12::Api>(&inputs, &mut adapters);
#[cfg(gles)]
self.enumerate::<hal::gles::Api>(&inputs, &mut adapters);
for (backend, instance) in &self.instance.instance_per_backend {
enumerate(
&self.hub,
*backend,
instance.as_ref(),
&inputs,
&mut adapters,
);
}
adapters
}
fn select<A: HalApi>(
fn select(
&self,
backend: Backend,
selected: &mut usize,
new_id: Option<AdapterId>,
mut list: Vec<hal::DynExposedAdapter>,
@ -703,9 +695,10 @@ impl Global {
None => {
let adapter = Adapter::new(list.swap_remove(*selected));
log::info!("Adapter {:?}", adapter.raw.info);
let id = A::hub(self)
let id = self
.hub
.adapters
.prepare(new_id)
.prepare(backend, new_id)
.assign(Arc::new(adapter));
Some(id)
}
@ -848,19 +841,19 @@ impl Global {
let mut selected = preferred_gpu.unwrap_or(0);
#[cfg(vulkan)]
if let Some(id) = self.select::<hal::api::Vulkan>(&mut selected, id_vulkan, adapters_vk) {
if let Some(id) = self.select(Backend::Vulkan, &mut selected, id_vulkan, adapters_vk) {
return Ok(id);
}
#[cfg(metal)]
if let Some(id) = self.select::<hal::api::Metal>(&mut selected, id_metal, adapters_metal) {
if let Some(id) = self.select(Backend::Metal, &mut selected, id_metal, adapters_metal) {
return Ok(id);
}
#[cfg(dx12)]
if let Some(id) = self.select::<hal::api::Dx12>(&mut selected, id_dx12, adapters_dx12) {
if let Some(id) = self.select(Backend::Dx12, &mut selected, id_dx12, adapters_dx12) {
return Ok(id);
}
#[cfg(gles)]
if let Some(id) = self.select::<hal::api::Gles>(&mut selected, id_gl, adapters_gl) {
if let Some(id) = self.select(Backend::Gl, &mut selected, id_gl, adapters_gl) {
return Ok(id);
}
let _ = selected;
@ -872,113 +865,92 @@ impl Global {
/// # Safety
///
/// `hal_adapter` must be created from this global internal instance handle.
pub unsafe fn create_adapter_from_hal<A: HalApi>(
pub unsafe fn create_adapter_from_hal(
&self,
hal_adapter: hal::DynExposedAdapter,
input: Option<AdapterId>,
) -> AdapterId {
profiling::scope!("Instance::create_adapter_from_hal");
let fid = A::hub(self).adapters.prepare(input);
let fid = self.hub.adapters.prepare(hal_adapter.backend(), input);
let id = fid.assign(Arc::new(Adapter::new(hal_adapter)));
let id = match A::VARIANT {
#[cfg(vulkan)]
Backend::Vulkan => fid.assign(Arc::new(Adapter::new(hal_adapter))),
#[cfg(metal)]
Backend::Metal => fid.assign(Arc::new(Adapter::new(hal_adapter))),
#[cfg(dx12)]
Backend::Dx12 => fid.assign(Arc::new(Adapter::new(hal_adapter))),
#[cfg(gles)]
Backend::Gl => fid.assign(Arc::new(Adapter::new(hal_adapter))),
_ => unreachable!(),
};
resource_log!("Created Adapter {:?}", id);
id
}
pub fn adapter_get_info<A: HalApi>(
pub fn adapter_get_info(
&self,
adapter_id: AdapterId,
) -> Result<wgt::AdapterInfo, InvalidAdapter> {
let hub = A::hub(self);
hub.adapters
self.hub
.adapters
.get(adapter_id)
.map(|adapter| adapter.raw.info.clone())
.map_err(|_| InvalidAdapter)
}
pub fn adapter_get_texture_format_features<A: HalApi>(
pub fn adapter_get_texture_format_features(
&self,
adapter_id: AdapterId,
format: wgt::TextureFormat,
) -> Result<wgt::TextureFormatFeatures, InvalidAdapter> {
let hub = A::hub(self);
hub.adapters
self.hub
.adapters
.get(adapter_id)
.map(|adapter| adapter.get_texture_format_features(format))
.map_err(|_| InvalidAdapter)
}
pub fn adapter_features<A: HalApi>(
&self,
adapter_id: AdapterId,
) -> Result<wgt::Features, InvalidAdapter> {
let hub = A::hub(self);
hub.adapters
pub fn adapter_features(&self, adapter_id: AdapterId) -> Result<wgt::Features, InvalidAdapter> {
self.hub
.adapters
.get(adapter_id)
.map(|adapter| adapter.raw.features)
.map_err(|_| InvalidAdapter)
}
pub fn adapter_limits<A: HalApi>(
&self,
adapter_id: AdapterId,
) -> Result<wgt::Limits, InvalidAdapter> {
let hub = A::hub(self);
hub.adapters
pub fn adapter_limits(&self, adapter_id: AdapterId) -> Result<wgt::Limits, InvalidAdapter> {
self.hub
.adapters
.get(adapter_id)
.map(|adapter| adapter.raw.capabilities.limits.clone())
.map_err(|_| InvalidAdapter)
}
pub fn adapter_downlevel_capabilities<A: HalApi>(
pub fn adapter_downlevel_capabilities(
&self,
adapter_id: AdapterId,
) -> Result<wgt::DownlevelCapabilities, InvalidAdapter> {
let hub = A::hub(self);
hub.adapters
self.hub
.adapters
.get(adapter_id)
.map(|adapter| adapter.raw.capabilities.downlevel.clone())
.map_err(|_| InvalidAdapter)
}
pub fn adapter_get_presentation_timestamp<A: HalApi>(
pub fn adapter_get_presentation_timestamp(
&self,
adapter_id: AdapterId,
) -> Result<wgt::PresentationTimestamp, InvalidAdapter> {
let hub = A::hub(self);
let hub = &self.hub;
let adapter = hub.adapters.get(adapter_id).map_err(|_| InvalidAdapter)?;
Ok(unsafe { adapter.raw.adapter.get_presentation_timestamp() })
}
pub fn adapter_drop<A: HalApi>(&self, adapter_id: AdapterId) {
pub fn adapter_drop(&self, adapter_id: AdapterId) {
profiling::scope!("Adapter::drop");
api_log!("Adapter::drop {adapter_id:?}");
let hub = A::hub(self);
let hub = &self.hub;
hub.adapters.unregister(adapter_id);
}
}
impl Global {
pub fn adapter_request_device<A: HalApi>(
pub fn adapter_request_device(
&self,
adapter_id: AdapterId,
desc: &DeviceDescriptor,
@ -989,12 +961,12 @@ impl Global {
profiling::scope!("Adapter::request_device");
api_log!("Adapter::request_device");
let hub = A::hub(self);
let device_fid = hub.devices.prepare(device_id_in);
let queue_fid = hub.queues.prepare(queue_id_in);
let backend = adapter_id.backend();
let device_fid = self.hub.devices.prepare(backend, device_id_in);
let queue_fid = self.hub.queues.prepare(backend, queue_id_in);
let error = 'error: {
let adapter = match hub.adapters.get(adapter_id) {
let adapter = match self.hub.adapters.get(adapter_id) {
Ok(adapter) => adapter,
Err(_) => break 'error RequestDeviceError::InvalidAdapter,
};
@ -1022,7 +994,7 @@ impl Global {
///
/// - `hal_device` must be created from `adapter_id` or its internal handle.
/// - `desc` must be a subset of `hal_device` features and limits.
pub unsafe fn create_device_from_hal<A: HalApi>(
pub unsafe fn create_device_from_hal(
&self,
adapter_id: AdapterId,
hal_device: hal::DynOpenDevice,
@ -1033,12 +1005,12 @@ impl Global {
) -> (DeviceId, QueueId, Option<RequestDeviceError>) {
profiling::scope!("Global::create_device_from_hal");
let hub = A::hub(self);
let devices_fid = hub.devices.prepare(device_id_in);
let queues_fid = hub.queues.prepare(queue_id_in);
let backend = adapter_id.backend();
let devices_fid = self.hub.devices.prepare(backend, device_id_in);
let queues_fid = self.hub.queues.prepare(backend, queue_id_in);
let error = 'error: {
let adapter = match hub.adapters.get(adapter_id) {
let adapter = match self.hub.adapters.get(adapter_id) {
Ok(adapter) => adapter,
Err(_) => break 'error RequestDeviceError::InvalidAdapter,
};

View File

@ -290,6 +290,8 @@ define_backend_caller! { gfx_if_empty, gfx_if_empty_hidden, "empty" if all(
/// [`wgpu_types::Backend`]: wgt::Backend
/// [`wgpu_core::global::Global`]: crate::global::Global
/// [`Id`]: id::Id
//
// TODO(#5124): Remove this altogether.
#[macro_export]
macro_rules! gfx_select {
// Simple two-component expression, like `self.0.method(..)`.
@ -303,14 +305,7 @@ macro_rules! gfx_select {
};
($id:expr => {$($c:tt)*}, $method:ident $params:tt) => {
match $id.backend() {
wgt::Backend::Vulkan => $crate::gfx_if_vulkan!($($c)*.$method::<$crate::api::Vulkan> $params),
wgt::Backend::Metal => $crate::gfx_if_metal!($($c)*.$method::<$crate::api::Metal> $params),
wgt::Backend::Dx12 => $crate::gfx_if_dx12!($($c)*.$method::<$crate::api::Dx12> $params),
wgt::Backend::Gl => $crate::gfx_if_gles!($($c)*.$method::<$crate::api::Gles> $params),
wgt::Backend::Empty => $crate::gfx_if_empty!($($c)*.$method::<$crate::api::Empty> $params),
other => panic!("Unexpected backend {:?}", other),
}
$($c)*.$method $params
};
}

View File

@ -3,7 +3,6 @@ use crate::{
binding_model::{CreateBindGroupLayoutError, CreatePipelineLayoutError, PipelineLayout},
command::ColorAttachmentError,
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
hal_api::HalApi,
id::{PipelineCacheId, PipelineLayoutId, ShaderModuleId},
resource::{Labeled, TrackingData},
resource_log, validation, Label,
@ -46,15 +45,15 @@ pub struct ShaderModuleDescriptor<'a> {
}
#[derive(Debug)]
pub struct ShaderModule<A: HalApi> {
pub struct ShaderModule {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynShaderModule>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
pub(crate) interface: Option<validation::Interface>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
}
impl<A: HalApi> Drop for ShaderModule<A> {
impl Drop for ShaderModule {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -65,12 +64,12 @@ impl<A: HalApi> Drop for ShaderModule<A> {
}
}
crate::impl_resource_type_generic!(ShaderModule);
crate::impl_resource_type!(ShaderModule);
crate::impl_labeled!(ShaderModule);
crate::impl_parent_device!(ShaderModule);
crate::impl_storage_item_generic!(ShaderModule);
crate::impl_storage_item!(ShaderModule);
impl<A: HalApi> ShaderModule<A> {
impl ShaderModule {
pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule {
self.raw.as_ref()
}
@ -150,9 +149,9 @@ pub struct ProgrammableStageDescriptor<'a> {
/// Describes a programmable pipeline stage.
#[derive(Clone, Debug)]
pub struct ResolvedProgrammableStageDescriptor<'a, A: HalApi> {
pub struct ResolvedProgrammableStageDescriptor<'a> {
/// The compiled shader module for this stage.
pub module: Arc<ShaderModule<A>>,
pub module: Arc<ShaderModule>,
/// The name of the entry point in the compiled shader. The name is selected using the
/// following logic:
///
@ -208,14 +207,14 @@ pub struct ComputePipelineDescriptor<'a> {
/// Describes a compute pipeline.
#[derive(Clone, Debug)]
pub struct ResolvedComputePipelineDescriptor<'a, A: HalApi> {
pub struct ResolvedComputePipelineDescriptor<'a> {
pub label: Label<'a>,
/// The layout of bind groups for this pipeline.
pub layout: Option<Arc<PipelineLayout<A>>>,
pub layout: Option<Arc<PipelineLayout>>,
/// The compiled compute stage and its entry point.
pub stage: ResolvedProgrammableStageDescriptor<'a, A>,
pub stage: ResolvedProgrammableStageDescriptor<'a>,
/// The pipeline cache to use when creating this pipeline.
pub cache: Option<Arc<PipelineCache<A>>>,
pub cache: Option<Arc<PipelineCache>>,
}
#[derive(Clone, Debug, Error)]
@ -240,18 +239,18 @@ pub enum CreateComputePipelineError {
}
#[derive(Debug)]
pub struct ComputePipeline<A: HalApi> {
pub struct ComputePipeline {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynComputePipeline>>,
pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) _shader_module: Arc<ShaderModule<A>>,
pub(crate) layout: Arc<PipelineLayout>,
pub(crate) device: Arc<Device>,
pub(crate) _shader_module: Arc<ShaderModule>,
pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for ComputePipeline<A> {
impl Drop for ComputePipeline {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -262,13 +261,13 @@ impl<A: HalApi> Drop for ComputePipeline<A> {
}
}
crate::impl_resource_type_generic!(ComputePipeline);
crate::impl_resource_type!(ComputePipeline);
crate::impl_labeled!(ComputePipeline);
crate::impl_parent_device!(ComputePipeline);
crate::impl_storage_item_generic!(ComputePipeline);
crate::impl_storage_item!(ComputePipeline);
crate::impl_trackable!(ComputePipeline);
impl<A: HalApi> ComputePipeline<A> {
impl ComputePipeline {
pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline {
self.raw.as_ref()
}
@ -298,14 +297,14 @@ impl From<hal::PipelineCacheError> for CreatePipelineCacheError {
}
#[derive(Debug)]
pub struct PipelineCache<A: HalApi> {
pub struct PipelineCache {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynPipelineCache>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
}
impl<A: HalApi> Drop for PipelineCache<A> {
impl Drop for PipelineCache {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -316,12 +315,12 @@ impl<A: HalApi> Drop for PipelineCache<A> {
}
}
crate::impl_resource_type_generic!(PipelineCache);
crate::impl_resource_type!(PipelineCache);
crate::impl_labeled!(PipelineCache);
crate::impl_parent_device!(PipelineCache);
crate::impl_storage_item_generic!(PipelineCache);
crate::impl_storage_item!(PipelineCache);
impl<A: HalApi> PipelineCache<A> {
impl PipelineCache {
pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache {
self.raw.as_ref()
}
@ -352,9 +351,9 @@ pub struct VertexState<'a> {
/// Describes the vertex process in a render pipeline.
#[derive(Clone, Debug)]
pub struct ResolvedVertexState<'a, A: HalApi> {
pub struct ResolvedVertexState<'a> {
/// The compiled vertex stage and its entry point.
pub stage: ResolvedProgrammableStageDescriptor<'a, A>,
pub stage: ResolvedProgrammableStageDescriptor<'a>,
/// The format of any vertex buffers used with this pipeline.
pub buffers: Cow<'a, [VertexBufferLayout<'a>]>,
}
@ -371,9 +370,9 @@ pub struct FragmentState<'a> {
/// Describes fragment processing in a render pipeline.
#[derive(Clone, Debug)]
pub struct ResolvedFragmentState<'a, A: HalApi> {
pub struct ResolvedFragmentState<'a> {
/// The compiled fragment stage and its entry point.
pub stage: ResolvedProgrammableStageDescriptor<'a, A>,
pub stage: ResolvedProgrammableStageDescriptor<'a>,
/// The effect of draw calls on the color aspect of the output target.
pub targets: Cow<'a, [Option<wgt::ColorTargetState>]>,
}
@ -407,12 +406,12 @@ pub struct RenderPipelineDescriptor<'a> {
/// Describes a render (graphics) pipeline.
#[derive(Clone, Debug)]
pub struct ResolvedRenderPipelineDescriptor<'a, A: HalApi> {
pub struct ResolvedRenderPipelineDescriptor<'a> {
pub label: Label<'a>,
/// The layout of bind groups for this pipeline.
pub layout: Option<Arc<PipelineLayout<A>>>,
pub layout: Option<Arc<PipelineLayout>>,
/// The vertex processing state for this pipeline.
pub vertex: ResolvedVertexState<'a, A>,
pub vertex: ResolvedVertexState<'a>,
/// The properties of the pipeline at the primitive assembly and rasterization level.
pub primitive: wgt::PrimitiveState,
/// The effect of draw calls on the depth and stencil aspects of the output target, if any.
@ -420,12 +419,12 @@ pub struct ResolvedRenderPipelineDescriptor<'a, A: HalApi> {
/// The multi-sampling properties of the pipeline.
pub multisample: wgt::MultisampleState,
/// The fragment processing state for this pipeline.
pub fragment: Option<ResolvedFragmentState<'a, A>>,
pub fragment: Option<ResolvedFragmentState<'a>>,
/// If the pipeline will be used with a multiview render pass, this indicates how many array
/// layers the attachments will have.
pub multiview: Option<NonZeroU32>,
/// The pipeline cache to use when creating this pipeline.
pub cache: Option<Arc<PipelineCache<A>>>,
pub cache: Option<Arc<PipelineCache>>,
}
#[derive(Clone, Debug)]
@ -588,12 +587,11 @@ impl Default for VertexStep {
}
#[derive(Debug)]
pub struct RenderPipeline<A: HalApi> {
pub struct RenderPipeline {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynRenderPipeline>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) _shader_modules:
ArrayVec<Arc<ShaderModule<A>>, { hal::MAX_CONCURRENT_SHADER_STAGES }>,
pub(crate) device: Arc<Device>,
pub(crate) layout: Arc<PipelineLayout>,
pub(crate) _shader_modules: ArrayVec<Arc<ShaderModule>, { hal::MAX_CONCURRENT_SHADER_STAGES }>,
pub(crate) pass_context: RenderPassContext,
pub(crate) flags: PipelineFlags,
pub(crate) strip_index_format: Option<wgt::IndexFormat>,
@ -604,7 +602,7 @@ pub struct RenderPipeline<A: HalApi> {
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for RenderPipeline<A> {
impl Drop for RenderPipeline {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -615,13 +613,13 @@ impl<A: HalApi> Drop for RenderPipeline<A> {
}
}
crate::impl_resource_type_generic!(RenderPipeline);
crate::impl_resource_type!(RenderPipeline);
crate::impl_labeled!(RenderPipeline);
crate::impl_parent_device!(RenderPipeline);
crate::impl_storage_item_generic!(RenderPipeline);
crate::impl_storage_item!(RenderPipeline);
crate::impl_trackable!(RenderPipeline);
impl<A: HalApi> RenderPipeline<A> {
impl RenderPipeline {
pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline {
self.raw.as_ref()
}

View File

@ -15,10 +15,8 @@ use std::{mem::ManuallyDrop, sync::Arc};
use crate::device::trace::Action;
use crate::{
conv,
device::any_device::AnyDevice,
device::{DeviceError, MissingDownlevelFlags, WaitIdleError},
device::{Device, DeviceError, MissingDownlevelFlags, WaitIdleError},
global::Global,
hal_api::HalApi,
hal_label, id,
resource::{self, Trackable},
};
@ -30,7 +28,7 @@ const FRAME_TIMEOUT_MS: u32 = 1000;
#[derive(Debug)]
pub(crate) struct Presentation {
pub(crate) device: AnyDevice, // TODO(#5124): use device: Arc<Device>
pub(crate) device: Arc<Device>,
pub(crate) config: wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
pub(crate) acquired_texture: Option<id::TextureId>,
}
@ -115,16 +113,14 @@ pub struct SurfaceOutput {
}
impl Global {
pub fn surface_get_current_texture<A: HalApi>(
pub fn surface_get_current_texture(
&self,
surface_id: id::SurfaceId,
texture_id_in: Option<id::TextureId>,
) -> Result<SurfaceOutput, SurfaceError> {
profiling::scope!("SwapChain::get_next_texture");
let hub = A::hub(self);
let fid = hub.textures.prepare(texture_id_in);
let hub = &self.hub;
let surface = self
.surfaces
@ -132,17 +128,14 @@ impl Global {
.map_err(|_| SurfaceError::Invalid)?;
let (device, config) = if let Some(ref present) = *surface.presentation.lock() {
match present.device.downcast_clone::<A>() {
Some(device) => {
device.check_is_valid()?;
(device, present.config.clone())
}
None => return Err(SurfaceError::NotConfigured),
}
present.device.check_is_valid()?;
(present.device.clone(), present.config.clone())
} else {
return Err(SurfaceError::NotConfigured);
};
let fid = hub.textures.prepare(device.backend(), texture_id_in);
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
trace.add(Action::GetSurfaceTexture {
@ -153,7 +146,7 @@ impl Global {
let fence = device.fence.read();
let suf = surface.raw(A::VARIANT).unwrap();
let suf = surface.raw(device.backend()).unwrap();
let (texture_id, status) = match unsafe {
suf.acquire_texture(
Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)),
@ -259,13 +252,10 @@ impl Global {
Ok(SurfaceOutput { status, texture_id })
}
pub fn surface_present<A: HalApi>(
&self,
surface_id: id::SurfaceId,
) -> Result<Status, SurfaceError> {
pub fn surface_present(&self, surface_id: id::SurfaceId) -> Result<Status, SurfaceError> {
profiling::scope!("SwapChain::present");
let hub = A::hub(self);
let hub = &self.hub;
let surface = self
.surfaces
@ -278,7 +268,7 @@ impl Global {
None => return Err(SurfaceError::NotConfigured),
};
let device = present.device.downcast_ref::<A>().unwrap();
let device = &present.device;
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
@ -303,7 +293,7 @@ impl Global {
.lock()
.textures
.remove(texture.tracker_index());
let suf = surface.raw(A::VARIANT).unwrap();
let suf = surface.raw(device.backend()).unwrap();
let exclusive_snatch_guard = device.snatchable_lock.write();
match texture.inner.snatch(exclusive_snatch_guard).unwrap() {
resource::TextureInner::Surface { raw, parent_id } => {
@ -335,13 +325,10 @@ impl Global {
}
}
pub fn surface_texture_discard<A: HalApi>(
&self,
surface_id: id::SurfaceId,
) -> Result<(), SurfaceError> {
pub fn surface_texture_discard(&self, surface_id: id::SurfaceId) -> Result<(), SurfaceError> {
profiling::scope!("SwapChain::discard");
let hub = A::hub(self);
let hub = &self.hub;
let surface = self
.surfaces
@ -353,7 +340,7 @@ impl Global {
None => return Err(SurfaceError::NotConfigured),
};
let device = present.device.downcast_ref::<A>().unwrap();
let device = &present.device;
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
@ -378,7 +365,7 @@ impl Global {
.lock()
.textures
.remove(texture.tracker_index());
let suf = surface.raw(A::VARIANT);
let suf = surface.raw(device.backend());
let exclusive_snatch_guard = device.snatchable_lock.write();
match texture.inner.snatch(exclusive_snatch_guard).unwrap() {
resource::TextureInner::Surface { raw, parent_id } => {

View File

@ -1,7 +1,5 @@
use std::sync::Arc;
use wgt::Backend;
use crate::{
id::Id,
identity::IdentityManager,
@ -40,21 +38,15 @@ pub(crate) struct Registry<T: StorageItem> {
// Must only contain an id which has either never been used or has been released from `storage`
identity: Arc<IdentityManager<T::Marker>>,
storage: RwLock<Storage<T>>,
backend: Backend,
}
impl<T: StorageItem> Registry<T> {
pub(crate) fn new(backend: Backend) -> Self {
pub(crate) fn new() -> Self {
Self {
identity: Arc::new(IdentityManager::new()),
storage: RwLock::new(rank::REGISTRY_STORAGE, Storage::new()),
backend,
}
}
pub(crate) fn without_backend() -> Self {
Self::new(Backend::Empty)
}
}
#[must_use]
@ -89,14 +81,18 @@ impl<T: StorageItem> FutureId<'_, T> {
}
impl<T: StorageItem> Registry<T> {
pub(crate) fn prepare(&self, id_in: Option<Id<T::Marker>>) -> FutureId<T> {
pub(crate) fn prepare(
&self,
backend: wgt::Backend,
id_in: Option<Id<T::Marker>>,
) -> FutureId<T> {
FutureId {
id: match id_in {
Some(id_in) => {
self.identity.mark_as_used(id_in);
id_in
}
None => self.identity.process(self.backend),
None => self.identity.process(backend),
},
data: &self.storage,
}
@ -164,13 +160,13 @@ mod tests {
#[test]
fn simultaneous_registration() {
let registry = Registry::without_backend();
let registry = Registry::new();
std::thread::scope(|s| {
for _ in 0..5 {
s.spawn(|| {
for _ in 0..1000 {
let value = Arc::new(TestData);
let new_id = registry.prepare(None);
let new_id = registry.prepare(wgt::Backend::Empty, None);
let id = new_id.assign(value);
registry.unregister(id);
}

View File

@ -86,14 +86,14 @@ impl std::fmt::Display for ResourceErrorIdent {
}
}
pub(crate) trait ParentDevice<A: HalApi>: Labeled {
fn device(&self) -> &Arc<Device<A>>;
pub(crate) trait ParentDevice: Labeled {
fn device(&self) -> &Arc<Device>;
fn is_equal(self: &Arc<Self>, other: &Arc<Self>) -> bool {
Arc::ptr_eq(self, other)
}
fn same_device_as<O: ParentDevice<A>>(&self, other: &O) -> Result<(), DeviceError> {
fn same_device_as<O: ParentDevice>(&self, other: &O) -> Result<(), DeviceError> {
if Arc::ptr_eq(self.device(), other.device()) {
Ok(())
} else {
@ -106,7 +106,7 @@ pub(crate) trait ParentDevice<A: HalApi>: Labeled {
}
}
fn same_device(&self, device: &Arc<Device<A>>) -> Result<(), DeviceError> {
fn same_device(&self, device: &Arc<Device>) -> Result<(), DeviceError> {
if Arc::ptr_eq(self.device(), device) {
Ok(())
} else {
@ -123,8 +123,8 @@ pub(crate) trait ParentDevice<A: HalApi>: Labeled {
#[macro_export]
macro_rules! impl_parent_device {
($ty:ident) => {
impl<A: HalApi> $crate::resource::ParentDevice<A> for $ty<A> {
fn device(&self) -> &Arc<Device<A>> {
impl $crate::resource::ParentDevice for $ty {
fn device(&self) -> &Arc<Device> {
&self.device
}
}
@ -135,16 +135,6 @@ pub(crate) trait ResourceType {
const TYPE: &'static str;
}
// TODO(#5124): Remove the typed version.
#[macro_export]
macro_rules! impl_resource_type_generic {
($ty:ident) => {
impl<A: HalApi> $crate::resource::ResourceType for $ty<A> {
const TYPE: &'static str = stringify!($ty);
}
};
}
#[macro_export]
macro_rules! impl_resource_type {
($ty:ident) => {
@ -173,7 +163,7 @@ pub(crate) trait Labeled: ResourceType {
#[macro_export]
macro_rules! impl_labeled {
($ty:ident) => {
impl<A: HalApi> $crate::resource::Labeled for $ty<A> {
impl $crate::resource::Labeled for $ty {
fn label(&self) -> &str {
&self.label
}
@ -188,7 +178,7 @@ pub(crate) trait Trackable {
#[macro_export]
macro_rules! impl_trackable {
($ty:ident) => {
impl<A: HalApi> $crate::resource::Trackable for $ty<A> {
impl $crate::resource::Trackable for $ty {
fn tracker_index(&self) -> $crate::track::TrackerIndex {
self.tracking_data.tracker_index()
}
@ -230,11 +220,11 @@ pub enum BufferMapAsyncStatus {
}
#[derive(Debug)]
pub(crate) enum BufferMapState<A: HalApi> {
pub(crate) enum BufferMapState {
/// Mapped at creation.
Init { staging_buffer: StagingBuffer<A> },
Init { staging_buffer: StagingBuffer },
/// Waiting for GPU to be done before mapping
Waiting(BufferPendingMapping<A>),
Waiting(BufferPendingMapping),
/// Mapped
Active {
mapping: hal::BufferMapping,
@ -246,9 +236,9 @@ pub(crate) enum BufferMapState<A: HalApi> {
}
#[cfg(send_sync)]
unsafe impl<A: HalApi> Send for BufferMapState<A> {}
unsafe impl Send for BufferMapState {}
#[cfg(send_sync)]
unsafe impl<A: HalApi> Sync for BufferMapState<A> {}
unsafe impl Sync for BufferMapState {}
#[repr(C)]
pub struct BufferMapCallbackC {
@ -423,30 +413,30 @@ pub struct DestroyedResourceError(pub ResourceErrorIdent);
pub type BufferAccessResult = Result<(), BufferAccessError>;
#[derive(Debug)]
pub(crate) struct BufferPendingMapping<A: HalApi> {
pub(crate) struct BufferPendingMapping {
pub(crate) range: Range<wgt::BufferAddress>,
pub(crate) op: BufferMapOperation,
// hold the parent alive while the mapping is active
pub(crate) _parent_buffer: Arc<Buffer<A>>,
pub(crate) _parent_buffer: Arc<Buffer>,
}
pub type BufferDescriptor<'a> = wgt::BufferDescriptor<Label<'a>>;
#[derive(Debug)]
pub struct Buffer<A: HalApi> {
pub struct Buffer {
pub(crate) raw: Snatchable<Box<dyn hal::DynBuffer>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
pub(crate) usage: wgt::BufferUsages,
pub(crate) size: wgt::BufferAddress,
pub(crate) initialization_status: RwLock<BufferInitTracker>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) tracking_data: TrackingData,
pub(crate) map_state: Mutex<BufferMapState<A>>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
pub(crate) map_state: Mutex<BufferMapState>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup>>>,
}
impl<A: HalApi> Drop for Buffer<A> {
impl Drop for Buffer {
fn drop(&mut self) {
if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw {}", self.error_ident());
@ -457,7 +447,7 @@ impl<A: HalApi> Drop for Buffer<A> {
}
}
impl<A: HalApi> Buffer<A> {
impl Buffer {
pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a dyn hal::DynBuffer> {
self.raw.get(guard).map(|b| b.as_ref())
}
@ -761,28 +751,28 @@ pub enum CreateBufferError {
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
}
crate::impl_resource_type_generic!(Buffer);
crate::impl_resource_type!(Buffer);
crate::impl_labeled!(Buffer);
crate::impl_parent_device!(Buffer);
crate::impl_storage_item_generic!(Buffer);
crate::impl_storage_item!(Buffer);
crate::impl_trackable!(Buffer);
/// A buffer that has been marked as destroyed and is staged for actual deletion soon.
#[derive(Debug)]
pub struct DestroyedBuffer<A: HalApi> {
pub struct DestroyedBuffer {
raw: ManuallyDrop<Box<dyn hal::DynBuffer>>,
device: Arc<Device<A>>,
device: Arc<Device>,
label: String,
bind_groups: Vec<Weak<BindGroup<A>>>,
bind_groups: Vec<Weak<BindGroup>>,
}
impl<A: HalApi> DestroyedBuffer<A> {
impl DestroyedBuffer {
pub fn label(&self) -> &dyn Debug {
&self.label
}
}
impl<A: HalApi> Drop for DestroyedBuffer<A> {
impl Drop for DestroyedBuffer {
fn drop(&mut self) {
let mut deferred = self.device.deferred_destroy.lock();
for bind_group in self.bind_groups.drain(..) {
@ -800,9 +790,9 @@ impl<A: HalApi> Drop for DestroyedBuffer<A> {
}
#[cfg(send_sync)]
unsafe impl<A: HalApi> Send for StagingBuffer<A> {}
unsafe impl Send for StagingBuffer {}
#[cfg(send_sync)]
unsafe impl<A: HalApi> Sync for StagingBuffer<A> {}
unsafe impl Sync for StagingBuffer {}
/// A temporary buffer, consumed by the command that uses it.
///
@ -824,16 +814,16 @@ unsafe impl<A: HalApi> Sync for StagingBuffer<A> {}
/// [`queue_write_texture`]: Global::queue_write_texture
/// [`Device::pending_writes`]: crate::device::Device
#[derive(Debug)]
pub struct StagingBuffer<A: HalApi> {
pub struct StagingBuffer {
raw: Box<dyn hal::DynBuffer>,
device: Arc<Device<A>>,
device: Arc<Device>,
pub(crate) size: wgt::BufferSize,
is_coherent: bool,
ptr: NonNull<u8>,
}
impl<A: HalApi> StagingBuffer<A> {
pub(crate) fn new(device: &Arc<Device<A>>, size: wgt::BufferSize) -> Result<Self, DeviceError> {
impl StagingBuffer {
pub(crate) fn new(device: &Arc<Device>, size: wgt::BufferSize) -> Result<Self, DeviceError> {
profiling::scope!("StagingBuffer::new");
let stage_desc = hal::BufferDescriptor {
label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags),
@ -901,7 +891,7 @@ impl<A: HalApi> StagingBuffer<A> {
}
}
pub(crate) fn flush(self) -> FlushedStagingBuffer<A> {
pub(crate) fn flush(self) -> FlushedStagingBuffer {
let device = self.device.raw();
if !self.is_coherent {
#[allow(clippy::single_range_in_vec_init)]
@ -923,23 +913,23 @@ impl<A: HalApi> StagingBuffer<A> {
}
}
crate::impl_resource_type_generic!(StagingBuffer);
crate::impl_storage_item_generic!(StagingBuffer);
crate::impl_resource_type!(StagingBuffer);
crate::impl_storage_item!(StagingBuffer);
#[derive(Debug)]
pub struct FlushedStagingBuffer<A: HalApi> {
pub struct FlushedStagingBuffer {
raw: ManuallyDrop<Box<dyn hal::DynBuffer>>,
device: Arc<Device<A>>,
device: Arc<Device>,
pub(crate) size: wgt::BufferSize,
}
impl<A: HalApi> FlushedStagingBuffer<A> {
impl FlushedStagingBuffer {
pub(crate) fn raw(&self) -> &dyn hal::DynBuffer {
self.raw.as_ref()
}
}
impl<A: HalApi> Drop for FlushedStagingBuffer<A> {
impl Drop for FlushedStagingBuffer {
fn drop(&mut self) {
resource_log!("Destroy raw StagingBuffer");
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -987,9 +977,9 @@ pub enum TextureClearMode {
}
#[derive(Debug)]
pub struct Texture<A: HalApi> {
pub struct Texture {
pub(crate) inner: Snatchable<TextureInner>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
pub(crate) desc: wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>,
pub(crate) hal_usage: hal::TextureUses,
pub(crate) format_features: wgt::TextureFormatFeatures,
@ -999,13 +989,13 @@ pub struct Texture<A: HalApi> {
pub(crate) label: String,
pub(crate) tracking_data: TrackingData,
pub(crate) clear_mode: TextureClearMode,
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
pub(crate) views: Mutex<Vec<Weak<TextureView>>>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup>>>,
}
impl<A: HalApi> Texture<A> {
impl Texture {
pub(crate) fn new(
device: &Arc<Device<A>>,
device: &Arc<Device>,
inner: TextureInner,
hal_usage: hal::TextureUses,
desc: &TextureDescriptor,
@ -1056,7 +1046,7 @@ impl<A: HalApi> Texture<A> {
}
}
impl<A: HalApi> Drop for Texture<A> {
impl Drop for Texture {
fn drop(&mut self) {
match self.clear_mode {
TextureClearMode::Surface {
@ -1092,7 +1082,7 @@ impl<A: HalApi> Drop for Texture<A> {
}
}
impl<A: HalApi> Texture<A> {
impl Texture {
pub(crate) fn try_inner<'a>(
&'a self,
guard: &'a SnatchGuard,
@ -1208,7 +1198,7 @@ impl Global {
) -> R {
profiling::scope!("Buffer::as_hal");
let hub = A::hub(self);
let hub = &self.hub;
if let Ok(buffer) = hub.buffers.get(id) {
let snatch_guard = buffer.device.snatchable_lock.read();
@ -1231,7 +1221,7 @@ impl Global {
) -> R {
profiling::scope!("Texture::as_hal");
let hub = A::hub(self);
let hub = &self.hub;
if let Ok(texture) = hub.textures.get(id) {
let snatch_guard = texture.device.snatchable_lock.read();
@ -1255,7 +1245,7 @@ impl Global {
) -> R {
profiling::scope!("TextureView::as_hal");
let hub = A::hub(self);
let hub = &self.hub;
if let Ok(texture_view) = hub.texture_views.get(id) {
let snatch_guard = texture_view.device.snatchable_lock.read();
@ -1279,7 +1269,7 @@ impl Global {
) -> R {
profiling::scope!("Adapter::as_hal");
let hub = A::hub(self);
let hub = &self.hub;
let adapter = hub.adapters.get(id).ok();
let hal_adapter = adapter
.as_ref()
@ -1299,7 +1289,7 @@ impl Global {
) -> R {
profiling::scope!("Device::as_hal");
let hub = A::hub(self);
let hub = &self.hub;
let device = hub.devices.get(id).ok();
let hal_device = device
.as_ref()
@ -1319,7 +1309,7 @@ impl Global {
) -> R {
profiling::scope!("Device::fence_as_hal");
let hub = A::hub(self);
let hub = &self.hub;
if let Ok(device) = hub.devices.get(id) {
let fence = device.fence.read();
@ -1361,7 +1351,7 @@ impl Global {
) -> R {
profiling::scope!("CommandEncoder::as_hal");
let hub = A::hub(self);
let hub = &self.hub;
if let Ok(cmd_buf) = hub.command_buffers.get(id.into_command_buffer_id()) {
let mut cmd_buf_data = cmd_buf.data.lock();
@ -1380,21 +1370,21 @@ impl Global {
/// A texture that has been marked as destroyed and is staged for actual deletion soon.
#[derive(Debug)]
pub struct DestroyedTexture<A: HalApi> {
pub struct DestroyedTexture {
raw: ManuallyDrop<Box<dyn hal::DynTexture>>,
views: Vec<Weak<TextureView<A>>>,
bind_groups: Vec<Weak<BindGroup<A>>>,
device: Arc<Device<A>>,
views: Vec<Weak<TextureView>>,
bind_groups: Vec<Weak<BindGroup>>,
device: Arc<Device>,
label: String,
}
impl<A: HalApi> DestroyedTexture<A> {
impl DestroyedTexture {
pub fn label(&self) -> &dyn Debug {
&self.label
}
}
impl<A: HalApi> Drop for DestroyedTexture<A> {
impl Drop for DestroyedTexture {
fn drop(&mut self) {
let device = &self.device;
@ -1508,13 +1498,13 @@ pub enum CreateTextureError {
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
}
crate::impl_resource_type_generic!(Texture);
crate::impl_resource_type!(Texture);
crate::impl_labeled!(Texture);
crate::impl_parent_device!(Texture);
crate::impl_storage_item_generic!(Texture);
crate::impl_storage_item!(Texture);
crate::impl_trackable!(Texture);
impl<A: HalApi> Borrow<TextureSelector> for Texture<A> {
impl Borrow<TextureSelector> for Texture {
fn borrow(&self) -> &TextureSelector {
&self.full_range
}
@ -1575,11 +1565,11 @@ pub enum TextureViewNotRenderableReason {
}
#[derive(Debug)]
pub struct TextureView<A: HalApi> {
pub struct TextureView {
pub(crate) raw: Snatchable<Box<dyn hal::DynTextureView>>,
// if it's a surface texture - it's none
pub(crate) parent: Arc<Texture<A>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) parent: Arc<Texture>,
pub(crate) device: Arc<Device>,
pub(crate) desc: HalTextureViewDescriptor,
pub(crate) format_features: wgt::TextureFormatFeatures,
/// This is `Err` only if the texture view is not renderable
@ -1591,7 +1581,7 @@ pub struct TextureView<A: HalApi> {
pub(crate) tracking_data: TrackingData,
}
impl<A: HalApi> Drop for TextureView<A> {
impl Drop for TextureView {
fn drop(&mut self) {
if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw {}", self.error_ident());
@ -1602,7 +1592,7 @@ impl<A: HalApi> Drop for TextureView<A> {
}
}
impl<A: HalApi> TextureView<A> {
impl TextureView {
pub(crate) fn raw<'a>(
&'a self,
snatch_guard: &'a SnatchGuard,
@ -1676,10 +1666,10 @@ pub enum CreateTextureViewError {
#[non_exhaustive]
pub enum TextureViewDestroyError {}
crate::impl_resource_type_generic!(TextureView);
crate::impl_resource_type!(TextureView);
crate::impl_labeled!(TextureView);
crate::impl_parent_device!(TextureView);
crate::impl_storage_item_generic!(TextureView);
crate::impl_storage_item!(TextureView);
crate::impl_trackable!(TextureView);
/// Describes a [`Sampler`]
@ -1712,9 +1702,9 @@ pub struct SamplerDescriptor<'a> {
}
#[derive(Debug)]
pub struct Sampler<A: HalApi> {
pub struct Sampler {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynSampler>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) tracking_data: TrackingData,
@ -1724,7 +1714,7 @@ pub struct Sampler<A: HalApi> {
pub(crate) filtering: bool,
}
impl<A: HalApi> Drop for Sampler<A> {
impl Drop for Sampler {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -1735,7 +1725,7 @@ impl<A: HalApi> Drop for Sampler<A> {
}
}
impl<A: HalApi> Sampler<A> {
impl Sampler {
pub(crate) fn raw(&self) -> &dyn hal::DynSampler {
self.raw.as_ref()
}
@ -1785,10 +1775,10 @@ pub enum CreateSamplerError {
MissingFeatures(#[from] MissingFeatures),
}
crate::impl_resource_type_generic!(Sampler);
crate::impl_resource_type!(Sampler);
crate::impl_labeled!(Sampler);
crate::impl_parent_device!(Sampler);
crate::impl_storage_item_generic!(Sampler);
crate::impl_storage_item!(Sampler);
crate::impl_trackable!(Sampler);
#[derive(Clone, Debug, Error)]
@ -1807,16 +1797,16 @@ pub enum CreateQuerySetError {
pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor<Label<'a>>;
#[derive(Debug)]
pub struct QuerySet<A: HalApi> {
pub struct QuerySet {
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynQuerySet>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) device: Arc<Device>,
/// The `label` from the descriptor used to create the resource.
pub(crate) label: String,
pub(crate) tracking_data: TrackingData,
pub(crate) desc: wgt::QuerySetDescriptor<()>,
}
impl<A: HalApi> Drop for QuerySet<A> {
impl Drop for QuerySet {
fn drop(&mut self) {
resource_log!("Destroy raw {}", self.error_ident());
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point.
@ -1827,13 +1817,13 @@ impl<A: HalApi> Drop for QuerySet<A> {
}
}
crate::impl_resource_type_generic!(QuerySet);
crate::impl_resource_type!(QuerySet);
crate::impl_labeled!(QuerySet);
crate::impl_parent_device!(QuerySet);
crate::impl_storage_item_generic!(QuerySet);
crate::impl_storage_item!(QuerySet);
crate::impl_trackable!(QuerySet);
impl<A: HalApi> QuerySet<A> {
impl QuerySet {
pub(crate) fn raw(&self) -> &dyn hal::DynQuerySet {
self.raw.as_ref()
}

View File

@ -28,16 +28,6 @@ pub(crate) trait StorageItem: ResourceType {
type Marker: Marker;
}
// TODO(#5124): Remove the typed version.
#[macro_export]
macro_rules! impl_storage_item_generic {
($ty:ident) => {
impl<A: HalApi> $crate::storage::StorageItem for $ty<A> {
type Marker = $crate::id::markers::$ty;
}
};
}
#[macro_export]
macro_rules! impl_storage_item {
($ty:ident) => {

View File

@ -8,7 +8,6 @@ use std::sync::{Arc, Weak};
use super::{PendingTransition, TrackerIndex};
use crate::{
hal_api::HalApi,
resource::{Buffer, Trackable},
snatch::SnatchGuard,
track::{
@ -39,10 +38,10 @@ impl ResourceUses for BufferUses {
/// Stores a bind group's buffers + their usages (within the bind group).
#[derive(Debug)]
pub(crate) struct BufferBindGroupState<A: HalApi> {
buffers: Vec<(Arc<Buffer<A>>, BufferUses)>,
pub(crate) struct BufferBindGroupState {
buffers: Vec<(Arc<Buffer>, BufferUses)>,
}
impl<A: HalApi> BufferBindGroupState<A> {
impl BufferBindGroupState {
pub fn new() -> Self {
Self {
buffers: Vec::new(),
@ -68,19 +67,19 @@ impl<A: HalApi> BufferBindGroupState<A> {
}
/// Adds the given resource with the given state.
pub fn insert_single(&mut self, buffer: Arc<Buffer<A>>, state: BufferUses) {
pub fn insert_single(&mut self, buffer: Arc<Buffer>, state: BufferUses) {
self.buffers.push((buffer, state));
}
}
/// Stores all buffer state within a single usage scope.
#[derive(Debug)]
pub(crate) struct BufferUsageScope<A: HalApi> {
pub(crate) struct BufferUsageScope {
state: Vec<BufferUses>,
metadata: ResourceMetadata<Arc<Buffer<A>>>,
metadata: ResourceMetadata<Arc<Buffer>>,
}
impl<A: HalApi> Default for BufferUsageScope<A> {
impl Default for BufferUsageScope {
fn default() -> Self {
Self {
state: Vec::new(),
@ -89,7 +88,7 @@ impl<A: HalApi> Default for BufferUsageScope<A> {
}
}
impl<A: HalApi> BufferUsageScope<A> {
impl BufferUsageScope {
fn tracker_assert_in_bounds(&self, index: usize) {
strict_assert!(index < self.state.len());
self.metadata.tracker_assert_in_bounds(index);
@ -129,7 +128,7 @@ impl<A: HalApi> BufferUsageScope<A> {
/// method is called.
pub unsafe fn merge_bind_group(
&mut self,
bind_group: &BufferBindGroupState<A>,
bind_group: &BufferBindGroupState,
) -> Result<(), ResourceUsageCompatibilityError> {
for &(ref resource, state) in bind_group.buffers.iter() {
let index = resource.tracker_index().as_usize();
@ -199,7 +198,7 @@ impl<A: HalApi> BufferUsageScope<A> {
/// the vectors will be extended. A call to set_size is not needed.
pub fn merge_single(
&mut self,
buffer: &Arc<Buffer<A>>,
buffer: &Arc<Buffer>,
new_state: BufferUses,
) -> Result<(), ResourceUsageCompatibilityError> {
let index = buffer.tracker_index().as_usize();
@ -225,16 +224,16 @@ impl<A: HalApi> BufferUsageScope<A> {
}
/// Stores all buffer state within a command buffer.
pub(crate) struct BufferTracker<A: HalApi> {
pub(crate) struct BufferTracker {
start: Vec<BufferUses>,
end: Vec<BufferUses>,
metadata: ResourceMetadata<Arc<Buffer<A>>>,
metadata: ResourceMetadata<Arc<Buffer>>,
temp: Vec<PendingTransition<BufferUses>>,
}
impl<A: HalApi> BufferTracker<A> {
impl BufferTracker {
pub fn new() -> Self {
Self {
start: Vec::new(),
@ -271,12 +270,12 @@ impl<A: HalApi> BufferTracker<A> {
}
/// Returns true if the given buffer is tracked.
pub fn contains(&self, buffer: &Buffer<A>) -> bool {
pub fn contains(&self, buffer: &Buffer) -> bool {
self.metadata.contains(buffer.tracker_index().as_usize())
}
/// Returns a list of all buffers tracked.
pub fn used_resources(&self) -> impl Iterator<Item = Arc<Buffer<A>>> + '_ {
pub fn used_resources(&self) -> impl Iterator<Item = Arc<Buffer>> + '_ {
self.metadata.owned_resources()
}
@ -301,7 +300,7 @@ impl<A: HalApi> BufferTracker<A> {
/// the vectors will be extended. A call to set_size is not needed.
pub fn set_single(
&mut self,
buffer: &Arc<Buffer<A>>,
buffer: &Arc<Buffer>,
state: BufferUses,
) -> Option<PendingTransition<BufferUses>> {
let index: usize = buffer.tracker_index().as_usize();
@ -374,7 +373,7 @@ impl<A: HalApi> BufferTracker<A> {
///
/// 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 set_from_usage_scope(&mut self, scope: &BufferUsageScope<A>) {
pub fn set_from_usage_scope(&mut self, scope: &BufferUsageScope) {
let incoming_size = scope.state.len();
if incoming_size > self.start.len() {
self.set_size(incoming_size);
@ -422,7 +421,7 @@ impl<A: HalApi> BufferTracker<A> {
/// method is called.
pub unsafe fn set_and_remove_from_usage_scope_sparse(
&mut self,
scope: &mut BufferUsageScope<A>,
scope: &mut BufferUsageScope,
index_source: impl IntoIterator<Item = TrackerIndex>,
) {
let incoming_size = scope.state.len();
@ -461,13 +460,13 @@ impl<A: HalApi> BufferTracker<A> {
}
/// Stores all buffer state within a device.
pub(crate) struct DeviceBufferTracker<A: HalApi> {
pub(crate) struct DeviceBufferTracker {
current_states: Vec<BufferUses>,
metadata: ResourceMetadata<Weak<Buffer<A>>>,
metadata: ResourceMetadata<Weak<Buffer>>,
temp: Vec<PendingTransition<BufferUses>>,
}
impl<A: HalApi> DeviceBufferTracker<A> {
impl DeviceBufferTracker {
pub fn new() -> Self {
Self {
current_states: Vec::new(),
@ -490,14 +489,14 @@ impl<A: HalApi> DeviceBufferTracker<A> {
}
/// Returns a list of all buffers tracked.
pub fn used_resources(&self) -> impl Iterator<Item = Weak<Buffer<A>>> + '_ {
pub fn used_resources(&self) -> impl Iterator<Item = Weak<Buffer>> + '_ {
self.metadata.owned_resources()
}
/// Inserts a single buffer and its state into the resource tracker.
///
/// If the resource already exists in the tracker, it will be overwritten.
pub fn insert_single(&mut self, buffer: &Arc<Buffer<A>>, state: BufferUses) {
pub fn insert_single(&mut self, buffer: &Arc<Buffer>, state: BufferUses) {
let index = buffer.tracker_index().as_usize();
self.allow_index(index);
@ -525,7 +524,7 @@ impl<A: HalApi> DeviceBufferTracker<A> {
/// is returned. No more than one transition is needed.
pub fn set_single(
&mut self,
buffer: &Arc<Buffer<A>>,
buffer: &Arc<Buffer>,
state: BufferUses,
) -> Option<PendingTransition<BufferUses>> {
let index: usize = buffer.tracker_index().as_usize();
@ -555,7 +554,7 @@ impl<A: HalApi> DeviceBufferTracker<A> {
/// those transitions are returned.
pub fn set_from_tracker_and_drain_transitions<'a, 'b: 'a>(
&'a mut self,
tracker: &'a BufferTracker<A>,
tracker: &'a BufferTracker,
snatch_guard: &'b SnatchGuard<'b>,
) -> impl Iterator<Item = BufferBarrier<'a, dyn hal::DynBuffer>> {
for index in tracker.metadata.owned_indices() {
@ -621,14 +620,14 @@ impl BufferStateProvider<'_> {
/// Indexes must be valid indexes into all arrays passed in
/// to this function, either directly or via metadata or provider structs.
#[inline(always)]
unsafe fn insert_or_merge<A: HalApi>(
unsafe fn insert_or_merge(
start_states: Option<&mut [BufferUses]>,
current_states: &mut [BufferUses],
resource_metadata: &mut ResourceMetadata<Arc<Buffer<A>>>,
resource_metadata: &mut ResourceMetadata<Arc<Buffer>>,
index32: u32,
index: usize,
state_provider: BufferStateProvider<'_>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Buffer<A>>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Buffer>>,
) -> Result<(), ResourceUsageCompatibilityError> {
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
@ -677,14 +676,14 @@ unsafe fn insert_or_merge<A: HalApi>(
/// Indexes must be valid indexes into all arrays passed in
/// to this function, either directly or via metadata or provider structs.
#[inline(always)]
unsafe fn insert_or_barrier_update<A: HalApi>(
unsafe fn insert_or_barrier_update(
start_states: Option<&mut [BufferUses]>,
current_states: &mut [BufferUses],
resource_metadata: &mut ResourceMetadata<Arc<Buffer<A>>>,
resource_metadata: &mut ResourceMetadata<Arc<Buffer>>,
index: usize,
start_state_provider: BufferStateProvider<'_>,
end_state_provider: Option<BufferStateProvider<'_>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Buffer<A>>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Buffer>>,
barriers: &mut Vec<PendingTransition<BufferUses>>,
) {
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
@ -741,12 +740,12 @@ unsafe fn insert<T: Clone>(
}
#[inline(always)]
unsafe fn merge<A: HalApi>(
unsafe fn merge(
current_states: &mut [BufferUses],
_index32: u32,
index: usize,
state_provider: BufferStateProvider<'_>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Buffer<A>>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Buffer>>,
) -> Result<(), ResourceUsageCompatibilityError> {
let current_state = unsafe { current_states.get_unchecked_mut(index) };
let new_state = unsafe { state_provider.get_state(index) };

View File

@ -1,7 +1,7 @@
/*! Resource State and Lifetime Trackers
These structures are responsible for keeping track of resource state,
generating barriers where needed, and making sure resources are kept
generating barriers where needednd making sure resources are kept
alive until the trackers die.
## General Architecture
@ -35,7 +35,7 @@ Stateless trackers only store metadata and own the given resource.
## Use Case
Within each type of tracker, the trackers are further split into 3 different
use cases, Bind Group, Usage Scope, and a full Tracker.
use cases, Bind Group, Usage Scopend a full Tracker.
Bind Group trackers are just a list of different resources, their refcount,
and how they are used. Textures are used via a selector and a usage type.
@ -60,7 +60,7 @@ not always contain every resource. Some resources (or even most resources) go
unused in any given command buffer. So to help speed up the process of iterating
through possibly thousands of resources, we use a bit vector to represent if
a resource is in the buffer or not. This allows us extremely efficient memory
utilization, as well as being able to bail out of whole blocks of 32-64 resources
utilizations well as being able to bail out of whole blocks of 32-64 resources
with a single usize comparison with zero. In practice this means that merging
partially resident buffers is extremely quick.
@ -103,7 +103,6 @@ mod texture;
use crate::{
binding_model, command,
hal_api::HalApi,
lock::{rank, Mutex},
pipeline,
resource::{self, Labeled, ResourceErrorIdent},
@ -257,9 +256,9 @@ pub(crate) type PendingTransitionList = Vec<PendingTransition<hal::TextureUses>>
impl PendingTransition<hal::BufferUses> {
/// Produce the hal barrier corresponding to the transition.
pub fn into_hal<'a, A: HalApi>(
pub fn into_hal<'a>(
self,
buf: &'a resource::Buffer<A>,
buf: &'a resource::Buffer,
snatch_guard: &'a SnatchGuard<'a>,
) -> hal::BufferBarrier<'a, dyn hal::DynBuffer> {
let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed");
@ -352,8 +351,8 @@ pub enum ResourceUsageCompatibilityError {
}
impl ResourceUsageCompatibilityError {
fn from_buffer<A: HalApi>(
buffer: &resource::Buffer<A>,
fn from_buffer(
buffer: &resource::Buffer,
current_state: hal::BufferUses,
new_state: hal::BufferUses,
) -> Self {
@ -366,8 +365,8 @@ impl ResourceUsageCompatibilityError {
}
}
fn from_texture<A: HalApi>(
texture: &resource::Texture<A>,
fn from_texture(
texture: &resource::Texture,
selector: TextureSelector,
current_state: hal::TextureUses,
new_state: hal::TextureUses,
@ -417,13 +416,13 @@ impl<T: ResourceUses> fmt::Display for InvalidUse<T> {
/// All bind group states are sorted by their ID so that when adding to a tracker,
/// they are added in the most efficient order possible (ascending order).
#[derive(Debug)]
pub(crate) struct BindGroupStates<A: HalApi> {
pub buffers: BufferBindGroupState<A>,
pub views: TextureViewBindGroupState<A>,
pub samplers: StatelessTracker<resource::Sampler<A>>,
pub(crate) struct BindGroupStates {
pub buffers: BufferBindGroupState,
pub views: TextureViewBindGroupState,
pub samplers: StatelessTracker<resource::Sampler>,
}
impl<A: HalApi> BindGroupStates<A> {
impl BindGroupStates {
pub fn new() -> Self {
Self {
buffers: BufferBindGroupState::new(),
@ -450,15 +449,15 @@ impl<A: HalApi> BindGroupStates<A> {
/// that are not normally included in a usage scope, but are used by render bundles
/// and need to be owned by the render bundles.
#[derive(Debug)]
pub(crate) struct RenderBundleScope<A: HalApi> {
pub buffers: BufferUsageScope<A>,
pub textures: TextureUsageScope<A>,
pub(crate) struct RenderBundleScope {
pub buffers: BufferUsageScope,
pub textures: TextureUsageScope,
// Don't need to track views and samplers, they are never used directly, only by bind groups.
pub bind_groups: StatelessTracker<binding_model::BindGroup<A>>,
pub render_pipelines: StatelessTracker<pipeline::RenderPipeline<A>>,
pub bind_groups: StatelessTracker<binding_model::BindGroup>,
pub render_pipelines: StatelessTracker<pipeline::RenderPipeline>,
}
impl<A: HalApi> RenderBundleScope<A> {
impl RenderBundleScope {
/// Create the render bundle scope and pull the maximum IDs from the hubs.
pub fn new() -> Self {
Self {
@ -471,7 +470,7 @@ impl<A: HalApi> RenderBundleScope<A> {
/// Merge the inner contents of a bind group into the render bundle tracker.
///
/// Only stateful things are merged in here, all other resources are owned
/// Only stateful things are merged in herell other resources are owned
/// indirectly by the bind group.
///
/// # Safety
@ -480,7 +479,7 @@ impl<A: HalApi> RenderBundleScope<A> {
/// length of the storage given at the call to `new`.
pub unsafe fn merge_bind_group(
&mut self,
bind_group: &BindGroupStates<A>,
bind_group: &BindGroupStates,
) -> Result<(), ResourceUsageCompatibilityError> {
unsafe { self.buffers.merge_bind_group(&bind_group.buffers)? };
unsafe { self.textures.merge_bind_group(&bind_group.views)? };
@ -492,18 +491,18 @@ impl<A: HalApi> RenderBundleScope<A> {
/// A pool for storing the memory used by [`UsageScope`]s. We take and store this memory when the
/// scope is dropped to avoid reallocating. The memory required only grows and allocation cost is
/// significant when a large number of resources have been used.
pub(crate) type UsageScopePool<A> = Mutex<Vec<(BufferUsageScope<A>, TextureUsageScope<A>)>>;
pub(crate) type UsageScopePool = Mutex<Vec<(BufferUsageScope, TextureUsageScope)>>;
/// A usage scope tracker. Only needs to store stateful resources as stateless
/// resources cannot possibly have a usage conflict.
#[derive(Debug)]
pub(crate) struct UsageScope<'a, A: HalApi> {
pub pool: &'a UsageScopePool<A>,
pub buffers: BufferUsageScope<A>,
pub textures: TextureUsageScope<A>,
pub(crate) struct UsageScope<'a> {
pub pool: &'a UsageScopePool,
pub buffers: BufferUsageScope,
pub textures: TextureUsageScope,
}
impl<'a, A: HalApi> Drop for UsageScope<'a, A> {
impl<'a> Drop for UsageScope<'a> {
fn drop(&mut self) {
// clear vecs and push into pool
self.buffers.clear();
@ -515,14 +514,14 @@ impl<'a, A: HalApi> Drop for UsageScope<'a, A> {
}
}
impl<A: HalApi> UsageScope<'static, A> {
impl UsageScope<'static> {
pub fn new_pooled<'d>(
pool: &'d UsageScopePool<A>,
pool: &'d UsageScopePool,
tracker_indices: &TrackerIndexAllocators,
) -> UsageScope<'d, A> {
) -> UsageScope<'d> {
let pooled = pool.lock().pop().unwrap_or_default();
let mut scope = UsageScope::<'d, A> {
let mut scope = UsageScope::<'d> {
pool,
buffers: pooled.0,
textures: pooled.1,
@ -534,10 +533,10 @@ impl<A: HalApi> UsageScope<'static, A> {
}
}
impl<'a, A: HalApi> UsageScope<'a, A> {
impl<'a> UsageScope<'a> {
/// Merge the inner contents of a bind group into the usage scope.
///
/// Only stateful things are merged in here, all other resources are owned
/// Only stateful things are merged in herell other resources are owned
/// indirectly by the bind group.
///
/// # Safety
@ -546,7 +545,7 @@ impl<'a, A: HalApi> UsageScope<'a, A> {
/// length of the storage given at the call to `new`.
pub unsafe fn merge_bind_group(
&mut self,
bind_group: &BindGroupStates<A>,
bind_group: &BindGroupStates,
) -> Result<(), ResourceUsageCompatibilityError> {
unsafe {
self.buffers.merge_bind_group(&bind_group.buffers)?;
@ -558,7 +557,7 @@ impl<'a, A: HalApi> UsageScope<'a, A> {
/// Merge the inner contents of a bind group into the usage scope.
///
/// Only stateful things are merged in here, all other resources are owned
/// Only stateful things are merged in herell other resources are owned
/// indirectly by a bind group or are merged directly into the command buffer tracker.
///
/// # Safety
@ -567,7 +566,7 @@ impl<'a, A: HalApi> UsageScope<'a, A> {
/// length of the storage given at the call to `new`.
pub unsafe fn merge_render_bundle(
&mut self,
render_bundle: &RenderBundleScope<A>,
render_bundle: &RenderBundleScope,
) -> Result<(), ResourceUsageCompatibilityError> {
self.buffers.merge_usage_scope(&render_bundle.buffers)?;
self.textures.merge_usage_scope(&render_bundle.textures)?;
@ -577,12 +576,12 @@ impl<'a, A: HalApi> UsageScope<'a, A> {
}
/// A tracker used by Device.
pub(crate) struct DeviceTracker<A: HalApi> {
pub buffers: DeviceBufferTracker<A>,
pub textures: DeviceTextureTracker<A>,
pub(crate) struct DeviceTracker {
pub buffers: DeviceBufferTracker,
pub textures: DeviceTextureTracker,
}
impl<A: HalApi> DeviceTracker<A> {
impl DeviceTracker {
pub fn new() -> Self {
Self {
buffers: DeviceBufferTracker::new(),
@ -592,18 +591,18 @@ impl<A: HalApi> DeviceTracker<A> {
}
/// A full double sided tracker used by CommandBuffers.
pub(crate) struct Tracker<A: HalApi> {
pub buffers: BufferTracker<A>,
pub textures: TextureTracker<A>,
pub views: StatelessTracker<resource::TextureView<A>>,
pub bind_groups: StatelessTracker<binding_model::BindGroup<A>>,
pub compute_pipelines: StatelessTracker<pipeline::ComputePipeline<A>>,
pub render_pipelines: StatelessTracker<pipeline::RenderPipeline<A>>,
pub bundles: StatelessTracker<command::RenderBundle<A>>,
pub query_sets: StatelessTracker<resource::QuerySet<A>>,
pub(crate) struct Tracker {
pub buffers: BufferTracker,
pub textures: TextureTracker,
pub views: StatelessTracker<resource::TextureView>,
pub bind_groups: StatelessTracker<binding_model::BindGroup>,
pub compute_pipelines: StatelessTracker<pipeline::ComputePipeline>,
pub render_pipelines: StatelessTracker<pipeline::RenderPipeline>,
pub bundles: StatelessTracker<command::RenderBundle>,
pub query_sets: StatelessTracker<resource::QuerySet>,
}
impl<A: HalApi> Tracker<A> {
impl Tracker {
pub fn new() -> Self {
Self {
buffers: BufferTracker::new(),
@ -632,7 +631,7 @@ impl<A: HalApi> Tracker<A> {
/// bind group as a source of which IDs to look at. The bind groups
/// must have first been added to the usage scope.
///
/// Only stateful things are merged in here, all other resources are owned
/// Only stateful things are merged in herell other resources are owned
/// indirectly by the bind group.
///
/// # Safety
@ -641,8 +640,8 @@ impl<A: HalApi> Tracker<A> {
/// value given to `set_size`
pub unsafe fn set_and_remove_from_usage_scope_sparse(
&mut self,
scope: &mut UsageScope<A>,
bind_group: &BindGroupStates<A>,
scope: &mut UsageScope,
bind_group: &BindGroupStates,
) {
unsafe {
self.buffers.set_and_remove_from_usage_scope_sparse(

View File

@ -20,7 +20,6 @@
use super::{range::RangedStates, PendingTransition, PendingTransitionList, TrackerIndex};
use crate::{
hal_api::HalApi,
resource::{Texture, TextureInner, TextureView, Trackable},
snatch::SnatchGuard,
track::{
@ -152,10 +151,10 @@ impl ComplexTextureState {
/// Stores a bind group's texture views + their usages (within the bind group).
#[derive(Debug)]
pub(crate) struct TextureViewBindGroupState<A: HalApi> {
views: Vec<(Arc<TextureView<A>>, TextureUses)>,
pub(crate) struct TextureViewBindGroupState {
views: Vec<(Arc<TextureView>, TextureUses)>,
}
impl<A: HalApi> TextureViewBindGroupState<A> {
impl TextureViewBindGroupState {
pub fn new() -> Self {
Self { views: Vec::new() }
}
@ -170,7 +169,7 @@ impl<A: HalApi> TextureViewBindGroupState<A> {
}
/// Adds the given resource with the given state.
pub fn insert_single(&mut self, view: Arc<TextureView<A>>, usage: TextureUses) {
pub fn insert_single(&mut self, view: Arc<TextureView>, usage: TextureUses) {
self.views.push((view, usage));
}
}
@ -202,12 +201,12 @@ impl TextureStateSet {
/// Stores all texture state within a single usage scope.
#[derive(Debug)]
pub(crate) struct TextureUsageScope<A: HalApi> {
pub(crate) struct TextureUsageScope {
set: TextureStateSet,
metadata: ResourceMetadata<Arc<Texture<A>>>,
metadata: ResourceMetadata<Arc<Texture>>,
}
impl<A: HalApi> Default for TextureUsageScope<A> {
impl Default for TextureUsageScope {
fn default() -> Self {
Self {
set: TextureStateSet::new(),
@ -216,7 +215,7 @@ impl<A: HalApi> Default for TextureUsageScope<A> {
}
}
impl<A: HalApi> TextureUsageScope<A> {
impl TextureUsageScope {
fn tracker_assert_in_bounds(&self, index: usize) {
self.metadata.tracker_assert_in_bounds(index);
@ -305,7 +304,7 @@ impl<A: HalApi> TextureUsageScope<A> {
/// method is called.
pub unsafe fn merge_bind_group(
&mut self,
bind_group: &TextureViewBindGroupState<A>,
bind_group: &TextureViewBindGroupState,
) -> Result<(), ResourceUsageCompatibilityError> {
for (view, usage) in bind_group.views.iter() {
unsafe { self.merge_single(&view.parent, Some(view.selector.clone()), *usage)? };
@ -329,7 +328,7 @@ impl<A: HalApi> TextureUsageScope<A> {
/// method is called.
pub unsafe fn merge_single(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
selector: Option<TextureSelector>,
new_state: TextureUses,
) -> Result<(), ResourceUsageCompatibilityError> {
@ -353,26 +352,26 @@ impl<A: HalApi> TextureUsageScope<A> {
}
}
pub(crate) trait TextureTrackerSetSingle<A: HalApi> {
pub(crate) trait TextureTrackerSetSingle {
fn set_single(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
selector: TextureSelector,
new_state: TextureUses,
) -> Drain<'_, PendingTransition<TextureUses>>;
}
/// Stores all texture state within a command buffer.
pub(crate) struct TextureTracker<A: HalApi> {
pub(crate) struct TextureTracker {
start_set: TextureStateSet,
end_set: TextureStateSet,
metadata: ResourceMetadata<Arc<Texture<A>>>,
metadata: ResourceMetadata<Arc<Texture>>,
temp: Vec<PendingTransition<TextureUses>>,
}
impl<A: HalApi> TextureTracker<A> {
impl TextureTracker {
pub fn new() -> Self {
Self {
start_set: TextureStateSet::new(),
@ -425,12 +424,12 @@ impl<A: HalApi> TextureTracker<A> {
}
/// Returns true if the tracker owns the given texture.
pub fn contains(&self, texture: &Texture<A>) -> bool {
pub fn contains(&self, texture: &Texture) -> bool {
self.metadata.contains(texture.tracker_index().as_usize())
}
/// Returns a list of all textures tracked.
pub fn used_resources(&self) -> impl Iterator<Item = Arc<Texture<A>>> + '_ {
pub fn used_resources(&self) -> impl Iterator<Item = Arc<Texture>> + '_ {
self.metadata.owned_resources()
}
@ -461,7 +460,7 @@ impl<A: HalApi> TextureTracker<A> {
/// the vectors will be extended. A call to set_size is not needed.
pub fn set_single(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
selector: TextureSelector,
new_state: TextureUses,
) -> Drain<'_, PendingTransition<TextureUses>> {
@ -539,7 +538,7 @@ impl<A: HalApi> TextureTracker<A> {
///
/// 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 set_from_usage_scope(&mut self, scope: &TextureUsageScope<A>) {
pub fn set_from_usage_scope(&mut self, scope: &TextureUsageScope) {
let incoming_size = scope.set.simple.len();
if incoming_size > self.start_set.simple.len() {
self.set_size(incoming_size);
@ -587,8 +586,8 @@ impl<A: HalApi> TextureTracker<A> {
/// method is called.
pub unsafe fn set_and_remove_from_usage_scope_sparse(
&mut self,
scope: &mut TextureUsageScope<A>,
bind_group_state: &TextureViewBindGroupState<A>,
scope: &mut TextureUsageScope,
bind_group_state: &TextureViewBindGroupState,
) {
let incoming_size = scope.set.simple.len();
if incoming_size > self.start_set.simple.len() {
@ -624,10 +623,10 @@ impl<A: HalApi> TextureTracker<A> {
}
}
impl<A: HalApi> TextureTrackerSetSingle<A> for TextureTracker<A> {
impl TextureTrackerSetSingle for TextureTracker {
fn set_single(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
selector: TextureSelector,
new_state: TextureUses,
) -> Drain<'_, PendingTransition<TextureUses>> {
@ -636,13 +635,13 @@ impl<A: HalApi> TextureTrackerSetSingle<A> for TextureTracker<A> {
}
/// Stores all texture state within a device.
pub(crate) struct DeviceTextureTracker<A: HalApi> {
pub(crate) struct DeviceTextureTracker {
current_state_set: TextureStateSet,
metadata: ResourceMetadata<Weak<Texture<A>>>,
metadata: ResourceMetadata<Weak<Texture>>,
temp: Vec<PendingTransition<TextureUses>>,
}
impl<A: HalApi> DeviceTextureTracker<A> {
impl DeviceTextureTracker {
pub fn new() -> Self {
Self {
current_state_set: TextureStateSet::new(),
@ -674,14 +673,14 @@ impl<A: HalApi> DeviceTextureTracker<A> {
}
/// Returns a list of all textures tracked.
pub fn used_resources(&self) -> impl Iterator<Item = Weak<Texture<A>>> + '_ {
pub fn used_resources(&self) -> impl Iterator<Item = Weak<Texture>> + '_ {
self.metadata.owned_resources()
}
/// Inserts a single texture and a state into the resource tracker.
///
/// If the resource already exists in the tracker, it will be overwritten.
pub fn insert_single(&mut self, texture: &Arc<Texture<A>>, usage: TextureUses) {
pub fn insert_single(&mut self, texture: &Arc<Texture>, usage: TextureUses) {
let index = texture.tracker_index().as_usize();
self.allow_index(index);
@ -710,7 +709,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
/// is returned.
pub fn set_single(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
selector: TextureSelector,
new_state: TextureUses,
) -> Drain<'_, PendingTransition<TextureUses>> {
@ -752,7 +751,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
/// those transitions are returned.
pub fn set_from_tracker_and_drain_transitions<'a, 'b: 'a>(
&'a mut self,
tracker: &'a TextureTracker<A>,
tracker: &'a TextureTracker,
snatch_guard: &'b SnatchGuard<'b>,
) -> impl Iterator<Item = TextureBarrier<'a, dyn hal::DynTexture>> {
for index in tracker.metadata.owned_indices() {
@ -796,7 +795,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
/// those transitions are returned.
pub fn set_from_usage_scope_and_drain_transitions<'a, 'b: 'a>(
&'a mut self,
scope: &'a TextureUsageScope<A>,
scope: &'a TextureUsageScope,
snatch_guard: &'b SnatchGuard<'b>,
) -> impl Iterator<Item = TextureBarrier<'a, dyn hal::DynTexture>> {
for index in scope.metadata.owned_indices() {
@ -856,10 +855,10 @@ impl<A: HalApi> DeviceTextureTracker<A> {
}
}
impl<A: HalApi> TextureTrackerSetSingle<A> for DeviceTextureTracker<A> {
impl TextureTrackerSetSingle for DeviceTextureTracker {
fn set_single(
&mut self,
texture: &Arc<Texture<A>>,
texture: &Arc<Texture>,
selector: TextureSelector,
new_state: TextureUses,
) -> Drain<'_, PendingTransition<TextureUses>> {
@ -978,13 +977,13 @@ impl<'a> TextureStateProvider<'a> {
/// Indexes must be valid indexes into all arrays passed in
/// to this function, either directly or via metadata or provider structs.
#[inline(always)]
unsafe fn insert_or_merge<A: HalApi>(
unsafe fn insert_or_merge(
texture_selector: &TextureSelector,
current_state_set: &mut TextureStateSet,
resource_metadata: &mut ResourceMetadata<Arc<Texture<A>>>,
resource_metadata: &mut ResourceMetadata<Arc<Texture>>,
index: usize,
state_provider: TextureStateProvider<'_>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Texture<A>>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Texture>>,
) -> Result<(), ResourceUsageCompatibilityError> {
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
@ -1034,15 +1033,15 @@ unsafe fn insert_or_merge<A: HalApi>(
/// Indexes must be valid indexes into all arrays passed in
/// to this function, either directly or via metadata or provider structs.
#[inline(always)]
unsafe fn insert_or_barrier_update<A: HalApi>(
unsafe fn insert_or_barrier_update(
texture_selector: &TextureSelector,
start_state: Option<&mut TextureStateSet>,
current_state_set: &mut TextureStateSet,
resource_metadata: &mut ResourceMetadata<Arc<Texture<A>>>,
resource_metadata: &mut ResourceMetadata<Arc<Texture>>,
index: usize,
start_state_provider: TextureStateProvider<'_>,
end_state_provider: Option<TextureStateProvider<'_>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Texture<A>>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Texture>>,
barriers: &mut Vec<PendingTransition<TextureUses>>,
) {
let currently_owned = unsafe { resource_metadata.contains_unchecked(index) };
@ -1163,12 +1162,12 @@ unsafe fn insert<T: Clone>(
}
#[inline(always)]
unsafe fn merge<A: HalApi>(
unsafe fn merge(
texture_selector: &TextureSelector,
current_state_set: &mut TextureStateSet,
index: usize,
state_provider: TextureStateProvider<'_>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Texture<A>>>,
metadata_provider: ResourceMetadataProvider<'_, Arc<Texture>>,
) -> Result<(), ResourceUsageCompatibilityError> {
let current_simple = unsafe { current_state_set.simple.get_unchecked_mut(index) };
let current_state = if *current_simple == TextureUses::COMPLEX {

View File

@ -36,7 +36,6 @@ impl SurfaceTexture {
self.presented = true;
DynContext::surface_present(
&*self.texture.context,
&self.texture.id,
// This call to as_ref is essential because we want the DynContext implementation to see the inner
// value of the Box (T::SurfaceOutputDetail), not the Box itself.
self.detail.as_ref(),
@ -49,7 +48,6 @@ impl Drop for SurfaceTexture {
if !self.presented && !thread::panicking() {
DynContext::surface_texture_discard(
&*self.texture.context,
&self.texture.id,
// This call to as_ref is essential because we want the DynContext implementation to see the inner
// value of the Box (T::SurfaceOutputDetail), not the Box itself.
self.detail.as_ref(),

View File

@ -1495,15 +1495,11 @@ impl crate::context::Context for ContextWebGpu {
)
}
fn surface_present(&self, _texture: &Self::TextureId, _detail: &Self::SurfaceOutputDetail) {
fn surface_present(&self, _detail: &Self::SurfaceOutputDetail) {
// Swapchain is presented automatically
}
fn surface_texture_discard(
&self,
_texture: &Self::TextureId,
_detail: &Self::SurfaceOutputDetail,
) {
fn surface_texture_discard(&self, _detail: &Self::SurfaceOutputDetail) {
// Can't really discard this on the Web
}

View File

@ -72,10 +72,7 @@ impl ContextWgpuCore {
&self,
hal_adapter: hal::ExposedAdapter<A>,
) -> wgc::id::AdapterId {
unsafe {
self.0
.create_adapter_from_hal::<A>(hal_adapter.into(), None)
}
unsafe { self.0.create_adapter_from_hal(hal_adapter.into(), None) }
}
pub unsafe fn adapter_as_hal<
@ -112,7 +109,7 @@ impl ContextWgpuCore {
log::error!("Feature 'trace' has been removed temporarily, see https://github.com/gfx-rs/wgpu/issues/5974");
}
let (device_id, queue_id, error) = unsafe {
self.0.create_device_from_hal::<A>(
self.0.create_device_from_hal(
*adapter,
hal_device.into(),
&desc.map_label(|l| l.map(Borrowed)),
@ -146,7 +143,7 @@ impl ContextWgpuCore {
let descriptor = desc.map_label_and_view_formats(|l| l.map(Borrowed), |v| v.to_vec());
let (id, error) = unsafe {
self.0
.create_texture_from_hal::<A>(Box::new(hal_texture), device.id, &descriptor, None)
.create_texture_from_hal(Box::new(hal_texture), device.id, &descriptor, None)
};
if let Some(cause) = error {
self.handle_error(
@ -795,20 +792,14 @@ impl crate::Context for ContextWgpuCore {
fn surface_get_current_texture(
&self,
surface: &Self::SurfaceId,
surface_data: &Self::SurfaceData,
_surface_data: &Self::SurfaceData,
) -> (
Option<Self::TextureId>,
Option<Self::TextureData>,
SurfaceStatus,
Self::SurfaceOutputDetail,
) {
let device_id = surface_data
.configured_device
.lock()
.expect("Surface was not configured?");
match wgc::gfx_select!(
device_id => self.0.surface_get_current_texture(*surface, None)
) {
match self.0.surface_get_current_texture(*surface, None) {
Ok(wgc::present::SurfaceOutput { status, texture_id }) => {
let (id, data) = {
(
@ -833,19 +824,15 @@ impl crate::Context for ContextWgpuCore {
}
}
fn surface_present(&self, texture: &Self::TextureId, detail: &Self::SurfaceOutputDetail) {
match wgc::gfx_select!(texture => self.0.surface_present(detail.surface_id)) {
fn surface_present(&self, detail: &Self::SurfaceOutputDetail) {
match self.0.surface_present(detail.surface_id) {
Ok(_status) => (),
Err(err) => self.handle_error_fatal(err, "Surface::present"),
}
}
fn surface_texture_discard(
&self,
texture: &Self::TextureId,
detail: &Self::SurfaceOutputDetail,
) {
match wgc::gfx_select!(texture => self.0.surface_texture_discard(detail.surface_id)) {
fn surface_texture_discard(&self, detail: &Self::SurfaceOutputDetail) {
match self.0.surface_texture_discard(detail.surface_id) {
Ok(_status) => (),
Err(err) => self.handle_error_fatal(err, "Surface::discard_texture"),
}

View File

@ -178,12 +178,8 @@ pub trait Context: Debug + WasmNotSendSync + Sized {
SurfaceStatus,
Self::SurfaceOutputDetail,
);
fn surface_present(&self, texture: &Self::TextureId, detail: &Self::SurfaceOutputDetail);
fn surface_texture_discard(
&self,
texture: &Self::TextureId,
detail: &Self::SurfaceOutputDetail,
);
fn surface_present(&self, detail: &Self::SurfaceOutputDetail);
fn surface_texture_discard(&self, detail: &Self::SurfaceOutputDetail);
fn device_features(&self, device: &Self::DeviceId, device_data: &Self::DeviceData) -> Features;
fn device_limits(&self, device: &Self::DeviceId, device_data: &Self::DeviceData) -> Limits;
@ -1241,8 +1237,8 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync {
SurfaceStatus,
Box<dyn AnyWasmNotSendSync>,
);
fn surface_present(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync);
fn surface_texture_discard(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync);
fn surface_present(&self, detail: &dyn AnyWasmNotSendSync);
fn surface_texture_discard(&self, detail: &dyn AnyWasmNotSendSync);
fn device_features(&self, device: &ObjectId, device_data: &crate::Data) -> Features;
fn device_limits(&self, device: &ObjectId, device_data: &crate::Data) -> Limits;
@ -2204,14 +2200,12 @@ where
)
}
fn surface_present(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync) {
let texture = <T::TextureId>::from(*texture);
Context::surface_present(self, &texture, detail.downcast_ref().unwrap())
fn surface_present(&self, detail: &dyn AnyWasmNotSendSync) {
Context::surface_present(self, detail.downcast_ref().unwrap())
}
fn surface_texture_discard(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync) {
let texture = <T::TextureId>::from(*texture);
Context::surface_texture_discard(self, &texture, detail.downcast_ref().unwrap())
fn surface_texture_discard(&self, detail: &dyn AnyWasmNotSendSync) {
Context::surface_texture_discard(self, detail.downcast_ref().unwrap())
}
fn device_features(&self, device: &ObjectId, device_data: &crate::Data) -> Features {