mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
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:
parent
3181251577
commit
24498f04d4
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)]
|
||||
|
@ -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()
|
||||
|
@ -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>,
|
||||
) {
|
||||
|
@ -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,
|
||||
|
@ -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,25 +1145,24 @@ impl Global {
|
||||
let bytes = label.as_bytes();
|
||||
base.string_data.extend_from_slice(bytes);
|
||||
|
||||
base.commands
|
||||
.push(ArcComputeCommand::<A>::InsertDebugMarker {
|
||||
color,
|
||||
len: bytes.len(),
|
||||
});
|
||||
base.commands.push(ArcComputeCommand::InsertDebugMarker {
|
||||
color,
|
||||
len: bytes.len(),
|
||||
});
|
||||
|
||||
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(())
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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>),
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
unsafe {
|
||||
suf.unwrap().unconfigure(device.raw());
|
||||
}
|
||||
let suf = surface.raw(present.device.backend());
|
||||
unsafe {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 } => {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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) };
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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"),
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user