From 6d51fab8648b41843cbff0d317df7974fe262638 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 6 Jun 2021 02:24:59 -0400 Subject: [PATCH] hal:: Fill the command buffer calls --- wgpu-core/src/command/bundle.rs | 2 +- wgpu-core/src/command/compute.rs | 4 +- wgpu-core/src/command/draw.rs | 2 +- wgpu-core/src/command/mod.rs | 13 +- wgpu-core/src/command/query.rs | 1 - wgpu-core/src/conv.rs | 71 +++++++++++ wgpu-core/src/device/mod.rs | 85 +++++++------ wgpu-core/src/device/queue.rs | 137 ++++++++------------- wgpu-core/src/resource.rs | 7 +- wgpu-core/src/swap_chain.rs | 2 +- wgpu-core/src/track/buffer.rs | 7 +- wgpu-core/src/track/mod.rs | 35 +++++- wgpu-core/src/track/texture.rs | 2 +- wgpu-hal/src/empty.rs | 204 ++++++++++++++++++++++--------- wgpu-hal/src/lib.rs | 195 +++++++++++++++++++++++++++-- 15 files changed, 537 insertions(+), 230 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index be1dcaa60e..e9b96a43c2 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -47,10 +47,10 @@ use crate::{ AttachmentData, Device, DeviceError, RenderPassContext, MAX_VERTEX_BUFFERS, SHADER_STAGE_COUNT, }, + hal::BufferUse, hub::{GlobalIdentityHandlerFactory, HalApi, Hub, Resource, Storage, Token}, id, memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, - resource::BufferUse, track::{TrackerSet, UsageConflict}, validation::check_buffer_usage, Label, LabelHelpers, LifeGuard, Stored, MAX_BIND_GROUPS, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 5e2cdb7fed..0ed2aee7b7 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -18,7 +18,7 @@ use crate::{ Label, DOWNLEVEL_ERROR_WARNING_MESSAGE, }; -use hal::command::CommandBuffer as _; +use hal::CommandBuffer as _; use thiserror::Error; use wgt::{BufferAddress, BufferUsage, ShaderStage}; @@ -216,7 +216,7 @@ impl State { fn flush_states( &mut self, - raw_cmd_buf: &mut B::CommandBuffer, + raw_cmd_buf: &mut A::CommandBuffer, base_trackers: &mut TrackerSet, bind_group_guard: &Storage, id::BindGroupId>, buffer_guard: &Storage, id::BufferId>, diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index 7c40603df9..f86588db9a 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -7,8 +7,8 @@ use crate::{ binding_model::PushConstantUploadError, + hal::BufferUse, id, - resource::BufferUse, track::UseExtendError, validation::{MissingBufferUsageError, MissingTextureUsageError}, }; diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 8c84f7ed07..bcf40b297b 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -114,15 +114,13 @@ impl CommandBuffer { } pub(crate) fn insert_barriers( - raw: &mut B::CommandBuffer, + raw: &mut A::CommandBuffer, base: &mut TrackerSet, head_buffers: &ResourceTracker, head_textures: &ResourceTracker, buffer_guard: &Storage, id::BufferId>, texture_guard: &Storage, id::TextureId>, ) { - use hal::command::CommandBuffer as _; - profiling::scope!("insert_barriers"); debug_assert_eq!(A::VARIANT, base.backend()); @@ -135,14 +133,9 @@ impl CommandBuffer { pending.into_hal(tex) }); - //TODO: be more deliberate about the stages - let stages = all_buffer_stages() | all_image_stages(); unsafe { - raw.pipeline_barrier( - stages..stages, - hal::memory::Dependencies::empty(), - buffer_barriers.chain(texture_barriers), - ); + raw.transition_buffers(buffer_barriers); + raw.transition_textures(texture_barriers); } } } diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index e7fa1440a8..01e2d5080a 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -8,7 +8,6 @@ use hal::command::CommandBuffer as _; use crate::device::trace::Command as TraceCommand; use crate::{ command::{CommandBuffer, CommandEncoderError}, - device::all_buffer_stages, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, id::{self, Id, TypedId}, resource::{BufferUse, QuerySet}, diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 4fff746e61..4966f92bb9 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -24,6 +24,77 @@ pub fn is_valid_copy_dst_texture_format(format: wgt::TextureFormat) -> bool { } } +pub fn map_buffer_usage(usage: wgt::BufferUsage) -> hal::BufferUse { + let mut u = hal::BufferUse::empty(); + u.set( + hal::BufferUse::MAP_READ, + usage.contains(wgt::BufferUsage::MAP_READ), + ); + u.set( + hal::BufferUse::MAP_WRITE, + usage.contains(wgt::BufferUsage::MAP_WRITE), + ); + u.set( + hal::BufferUse::COPY_SRC, + usage.contains(wgt::BufferUsage::COPY_SRC), + ); + u.set( + hal::BufferUse::COPY_DST, + usage.contains(wgt::BufferUsage::COPY_DST), + ); + u.set( + hal::BufferUse::INDEX, + usage.contains(wgt::BufferUsage::INDEX), + ); + u.set( + hal::BufferUse::VERTEX, + usage.contains(wgt::BufferUsage::VERTEX), + ); + u.set( + hal::BufferUse::UNIFORM, + usage.contains(wgt::BufferUsage::UNIFORM), + ); + u.set( + hal::BufferUse::STORAGE, + usage.contains(wgt::BufferUsage::STORAGE), + ); + u.set( + hal::BufferUse::INDIRECT, + usage.contains(wgt::BufferUsage::INDIRECT), + ); + u +} + +pub fn map_texture_usage(usage: wgt::TextureUsage, aspect: hal::FormatAspect) -> hal::TextureUse { + let mut u = hal::TextureUse::empty(); + u.set( + hal::TextureUse::COPY_SRC, + usage.contains(wgt::TextureUsage::COPY_SRC), + ); + u.set( + hal::TextureUse::COPY_DST, + usage.contains(wgt::TextureUsage::COPY_DST), + ); + u.set( + hal::TextureUse::SAMPLED, + usage.contains(wgt::TextureUsage::SAMPLED), + ); + u.set( + hal::TextureUse::STORAGE_LOAD | hal::TextureUse::STORAGE_STORE, + usage.contains(wgt::TextureUsage::STORAGE), + ); + let is_color = aspect.contains(hal::FormatAspect::COLOR); + u.set( + hal::TextureUse::COLOR_TARGET, + usage.contains(wgt::TextureUsage::RENDER_ATTACHMENT) && is_color, + ); + u.set( + hal::TextureUse::DEPTH_STENCIL_READ | hal::TextureUse::DEPTH_STENCIL_WRITE, + usage.contains(wgt::TextureUsage::RENDER_ATTACHMENT) && !is_color, + ); + u +} + pub fn check_texture_dimension_size( dimension: wgt::TextureDimension, wgt::Extent3d { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index be2b8f816b..1d7a049820 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -448,13 +448,13 @@ impl Device { return Err(resource::CreateBufferError::EmptyUsage); } - let buffer = unsafe { - self.raw.create_buffer(&resource::BufferDescriptor { - usage, - ..desc.clone() - }) - } - .map_err(DeviceError::from)?; + let hal_desc = hal::BufferDescriptor { + label: desc.label, + size: desc.size, + usage: conv::map_buffer_usage(usage), + memory_flags: hal::MemoryFlag::empty(), + }; + let buffer = unsafe { self.raw.create_buffer(&hal_desc) }.map_err(DeviceError::from)?; Ok(resource::Buffer { raw: Some(buffer), @@ -529,10 +529,24 @@ impl Device { return Err(resource::CreateTextureError::InvalidMipLevelCount(mips)); } - let mut image = unsafe { self.raw.create_image(desc).map_err(DeviceError::from)? }; + let hal_desc = hal::TextureDescriptor { + label: desc.label, + size: desc.size, + mip_level_count: desc.mip_level_count, + sample_count: desc.sample_count, + dimension: desc.dimension, + format: desc.format, + usage: conv::map_texture_usage(desc.usage, desc.format.into()), + memory_flags: hal::MemoryFlag::empty(), + }; + let mut raw = unsafe { + self.raw + .create_texture(&hal_desc) + .map_err(DeviceError::from)? + }; Ok(resource::Texture { - raw: Some(image), + raw: Some(raw), device_id: Stored { value: id::Valid(self_id), ref_count: self.life_guard.add_ref(), @@ -698,9 +712,9 @@ impl Device { samples: texture.kind.num_samples(), // once a storage - forever a storage sampled_internal_use: if texture.usage.contains(wgt::TextureUsage::STORAGE) { - resource::TextureUse::SAMPLED | resource::TextureUse::STORAGE_LOAD + hal::TextureUse::SAMPLED | hal::TextureUse::STORAGE_LOAD } else { - resource::TextureUse::SAMPLED + hal::TextureUse::SAMPLED }, selector, life_guard: LifeGuard::new(desc.label.borrow_or_default()), @@ -1083,15 +1097,15 @@ impl Device { let (pub_usage, internal_use, range_limit) = match binding_ty { wgt::BufferBindingType::Uniform => ( wgt::BufferUsage::UNIFORM, - resource::BufferUse::UNIFORM, + hal::BufferUse::UNIFORM, limits.max_uniform_buffer_binding_size, ), wgt::BufferBindingType::Storage { read_only } => ( wgt::BufferUsage::STORAGE, if read_only { - resource::BufferUse::STORAGE_LOAD + hal::BufferUse::STORAGE_LOAD } else { - resource::BufferUse::STORAGE_STORE + hal::BufferUse::STORAGE_STORE }, limits.max_storage_buffer_binding_size, ), @@ -1360,10 +1374,10 @@ impl Device { } let internal_use = match access { wgt::StorageTextureAccess::ReadOnly => { - resource::TextureUse::STORAGE_LOAD + hal::TextureUse::STORAGE_LOAD } wgt::StorageTextureAccess::WriteOnly => { - resource::TextureUse::STORAGE_STORE + hal::TextureUse::STORAGE_STORE } wgt::StorageTextureAccess::ReadWrite => { if !view.format_features.flags.contains( @@ -1374,8 +1388,7 @@ impl Device { )); } - resource::TextureUse::STORAGE_STORE - | resource::TextureUse::STORAGE_LOAD + hal::TextureUse::STORAGE_STORE | hal::TextureUse::STORAGE_LOAD } }; (wgt::TextureUsage::STORAGE, internal_use) @@ -2459,7 +2472,7 @@ impl Global { let ref_count = buffer.life_guard.add_ref(); let buffer_use = if !desc.mapped_at_creation { - resource::BufferUse::EMPTY + hal::BufferUse::EMPTY } else if desc.usage.contains(wgt::BufferUsage::MAP_WRITE) { // buffer is mappable, so we are just doing that at start let map_size = buffer.size; @@ -2480,7 +2493,7 @@ impl Global { range: 0..map_size, host: HostMap::Write, }; - resource::BufferUse::MAP_WRITE + hal::BufferUse::MAP_WRITE } else { // buffer needs staging area for initialization only let stage_desc = wgt::BufferDescriptor { @@ -2533,7 +2546,7 @@ impl Global { stage_buffer, stage_memory, }; - resource::BufferUse::COPY_DST + hal::BufferUse::COPY_DST }; let id = fid.assign(buffer, &mut token); @@ -4236,8 +4249,8 @@ impl Global { let mut token = Token::root(); let (device_guard, mut token) = hub.devices.read(&mut token); let (pub_usage, internal_use) = match op.host { - HostMap::Read => (wgt::BufferUsage::MAP_READ, resource::BufferUse::MAP_READ), - HostMap::Write => (wgt::BufferUsage::MAP_WRITE, resource::BufferUse::MAP_WRITE), + HostMap::Read => (wgt::BufferUsage::MAP_READ, hal::BufferUse::MAP_READ), + HostMap::Write => (wgt::BufferUsage::MAP_WRITE, hal::BufferUse::MAP_WRITE), }; if range.start % wgt::MAP_ALIGNMENT != 0 || range.end % wgt::COPY_BUFFER_ALIGNMENT != 0 { @@ -4404,32 +4417,26 @@ impl Global { .ok_or(resource::BufferAccessError::Destroyed)?; buffer.life_guard.use_at(device.active_submission_index + 1); - let region = hal::command::BufferCopy { + let region = hal::BufferCopy { src: 0, dst: 0, size: buffer.size, }; - let transition_src = hal::memory::Barrier::Buffer { - states: hal::buffer::Access::HOST_WRITE..hal::buffer::Access::TRANSFER_READ, - target: &stage_buffer, - range: hal::buffer::SubRange::WHOLE, - families: None, + let transition_src = hal::BufferBarrier { + buffer: &stage_buffer, + usage: hal::BufferUse::MAP_WRITE..hal::BufferUse::COPY_SRC, }; - let transition_dst = hal::memory::Barrier::Buffer { - states: hal::buffer::Access::empty()..hal::buffer::Access::TRANSFER_WRITE, - target: buf_raw, - range: hal::buffer::SubRange::WHOLE, - families: None, + let transition_dst = hal::BufferBarrier { + buffer: buf_raw, + usage: hal::BufferUse::empty()..hal::BufferUse::COPY_DST, }; unsafe { - let cmdbuf = device.borrow_pending_writes(); - cmdbuf.pipeline_barrier( - hal::pso::PipelineStage::HOST..hal::pso::PipelineStage::TRANSFER, - hal::memory::Dependencies::empty(), + let cmd_buf = device.borrow_pending_writes(); + cmd_buf.transition_buffers( iter::once(transition_src).chain(iter::once(transition_dst)), ); if buffer.size > 0 { - cmdbuf.copy_buffer(&stage_buffer, buf_raw, iter::once(region)); + cmd_buf.copy_buffer_to_buffer(&stage_buffer, buf_raw, iter::once(region)); } } device diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 87551f5470..b41a42f9d3 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -7,38 +7,37 @@ use crate::device::trace::Action; use crate::{ command::{ texture_copy_view_to_hal, validate_linear_texture_data, validate_texture_copy_range, - CommandAllocator, CommandBuffer, CopySide, ImageCopyTexture, TransferError, BITS_PER_BYTE, + CommandBuffer, CopySide, ImageCopyTexture, TransferError, BITS_PER_BYTE, }, conv, - device::{alloc, DeviceError, WaitIdleError}, + device::{DeviceError, WaitIdleError}, hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token}, id, memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, - resource::{Buffer, BufferAccessError, BufferMapState, BufferUse, TextureUse}, + resource::{Buffer, BufferAccessError, BufferMapState}, FastHashMap, FastHashSet, }; -use hal::{command::CommandBuffer as _, device::Device as _, queue::Queue as _}; +use hal::{CommandBuffer as _, Device as _, Queue as _}; use smallvec::SmallVec; use std::{iter, ops::Range, ptr}; use thiserror::Error; struct StagingData { - buffer: B::Buffer, - memory: alloc::MemoryBlock, - cmdbuf: B::CommandBuffer, + buffer: A::Buffer, + cmdbuf: A::CommandBuffer, } #[derive(Debug)] pub enum TempResource { - Buffer(B::Buffer), - Image(B::Image), + Buffer(A::Buffer), + Texture(A::Texture), } #[derive(Debug)] pub(crate) struct PendingWrites { - pub command_buffer: Option, - pub temp_resources: Vec<(TempResource, alloc::MemoryBlock)>, + pub command_buffer: Option, + pub temp_resources: Vec>, pub dst_buffers: FastHashSet, pub dst_textures: FastHashSet, } @@ -53,40 +52,35 @@ impl PendingWrites { } } - pub fn dispose( - self, - device: &B::Device, - cmd_allocator: &CommandAllocator, - mem_allocator: &mut alloc::MemoryAllocator, - ) { + pub fn dispose(self, device: &A::Device) { if let Some(raw) = self.command_buffer { - cmd_allocator.discard_internal(raw); + unsafe { + device.destroy_command_buffer(raw); + } } - for (resource, memory) in self.temp_resources { - mem_allocator.free(device, memory); + for resource in self.temp_resources { match resource { TempResource::Buffer(buffer) => unsafe { device.destroy_buffer(buffer); }, - TempResource::Image(image) => unsafe { - device.destroy_image(image); + TempResource::Texture(texture) => unsafe { + device.destroy_image(texture); }, } } } - pub fn consume_temp(&mut self, resource: TempResource, memory: alloc::MemoryBlock) { - self.temp_resources.push((resource, memory)); + pub fn consume_temp(&mut self, resource: TempResource) { + self.temp_resources.push(resource); } fn consume(&mut self, stage: StagingData) { - self.temp_resources - .push((TempResource::Buffer(stage.buffer), stage.memory)); + self.temp_resources.push(TempResource::Buffer(stage.buffer)); self.command_buffer = Some(stage.cmdbuf); } #[must_use] - fn finish(&mut self) -> Option { + fn finish(&mut self) -> Option { self.dst_buffers.clear(); self.dst_textures.clear(); self.command_buffer.take().map(|mut cmd_buf| unsafe { @@ -95,13 +89,19 @@ impl PendingWrites { }) } - fn borrow_cmd_buf(&mut self, cmd_allocator: &CommandAllocator) -> &mut B::CommandBuffer { + fn create_cmd_buf(device: &A::Device) -> A::CommandBuffer { + unsafe { + let mut cmd_buf = device.create_command_buffer(&hal::CommandBufferDescriptor { + label: Some("_PendingWrites"), + }); + cmd_buf.begin(); + cmd_buf + } + } + + fn borrow_cmd_buf(&mut self, device: &A::Device) -> &mut A::CommandBuffer { if self.command_buffer.is_none() { - let mut cmdbuf = cmd_allocator.allocate_internal(); - unsafe { - cmdbuf.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT); - } - self.command_buffer = Some(cmdbuf); + self.command_buffer = Some(Self::create_cmd_buf(device)); } self.command_buffer.as_mut().unwrap() } @@ -141,52 +141,25 @@ impl RequiredBufferInits { } impl super::Device { - pub fn borrow_pending_writes(&mut self) -> &mut B::CommandBuffer { - self.pending_writes.borrow_cmd_buf(&self.cmd_allocator) + pub fn borrow_pending_writes(&mut self) -> &mut A::CommandBuffer { + self.pending_writes.borrow_cmd_buf(&self.raw) } fn prepare_stage(&mut self, size: wgt::BufferAddress) -> Result, DeviceError> { profiling::scope!("prepare_stage"); - let mut buffer = unsafe { - self.raw - .create_buffer( - size, - hal::buffer::Usage::TRANSFER_SRC, - hal::memory::SparseFlags::empty(), - ) - .map_err(|err| match err { - hal::buffer::CreationError::OutOfMemory(_) => DeviceError::OutOfMemory, - _ => panic!("failed to create staging buffer: {}", err), - })? + let stage_desc = hal::BufferDescriptor { + label: Some("_Staging"), + size, + usage: hal::BufferUse::MAP_WRITE | hal::BufferUse::COPY_SRC, + memory_flags: hal::MemoryFlag::TRANSIENT, }; - //TODO: do we need to transition into HOST_WRITE access first? - let requirements = unsafe { - self.raw.set_buffer_name(&mut buffer, ""); - self.raw.get_buffer_requirements(&buffer) - }; - - let block = self.mem_allocator.lock().allocate( - &self.raw, - requirements, - gpu_alloc::UsageFlags::UPLOAD | gpu_alloc::UsageFlags::TRANSIENT, - )?; - block.bind_buffer(&self.raw, &mut buffer)?; + let mut buffer = unsafe { self.raw.create_buffer(&stage_desc)? }; let cmdbuf = match self.pending_writes.command_buffer.take() { Some(cmdbuf) => cmdbuf, - None => { - let mut cmdbuf = self.cmd_allocator.allocate_internal(); - unsafe { - cmdbuf.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT); - } - cmdbuf - } + None => PendingWrites::create_cmd_buf(&self.raw), }; - Ok(StagingData { - buffer, - memory: block, - cmdbuf, - }) + Ok(StagingData { buffer, cmdbuf }) } fn initialize_buffer_memory( @@ -217,7 +190,7 @@ impl super::Device { let transition = trackers.buffers.change_replace_tracked( id::Valid(buffer_id), (), - BufferUse::COPY_DST, + hal::BufferUse::COPY_DST, ); let buffer = buffer_guard.get(buffer_id).unwrap(); let &(ref buffer_raw, _) = buffer @@ -225,27 +198,15 @@ impl super::Device { .as_ref() .ok_or(QueueSubmitError::DestroyedBuffer(buffer_id))?; unsafe { - cmd_buf.pipeline_barrier( - super::all_buffer_stages()..hal::pso::PipelineStage::TRANSFER, - hal::memory::Dependencies::empty(), - transition.map(|pending| pending.into_hal(buffer)), - ); + cmd_buf.transition_buffers(transition.map(|pending| pending.into_hal(buffer))); } - for range in ranges { - let size = range.end - range.start; + for range in ranges { assert!(range.start % 4 == 0, "Buffer {:?} has an uninitialized range with a start not aligned to 4 (start was {})", buffer, range.start); - assert!(size % 4 == 0, "Buffer {:?} has an uninitialized range with a size not aligned to 4 (size was {})", buffer, size); + assert!(range.end % 4 == 0, "Buffer {:?} has an uninitialized range with an end not aligned to 4 (end was {})", buffer, range.end); unsafe { - cmd_buf.fill_buffer( - buffer_raw, - hal::buffer::SubRange { - offset: range.start, - size: Some(size), - }, - 0, - ); + cmd_buf.fill_buffer(buffer_raw, range, 0); } } } @@ -326,7 +287,7 @@ impl Global { let mut trackers = device.trackers.lock(); let (dst, transition) = trackers .buffers - .use_replace(&*buffer_guard, buffer_id, (), BufferUse::COPY_DST) + .use_replace(&*buffer_guard, buffer_id, (), hal::BufferUse::COPY_DST) .map_err(TransferError::InvalidBuffer)?; let &(ref dst_raw, _) = dst .raw diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 46c38d5d4f..9e84a7f20b 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -16,9 +16,6 @@ use thiserror::Error; use std::{borrow::Borrow, num::NonZeroU8, ops::Range, ptr::NonNull}; -//TODO: remove the alias, just use it from `hal` -pub(crate) use hal::{BufferUse, TextureUse}; - #[repr(C)] #[derive(Debug)] pub enum BufferMapAsyncStatus { @@ -166,7 +163,7 @@ pub type TextureDescriptor<'a> = wgt::TextureDescriptor>; #[derive(Debug)] pub struct Texture { - pub(crate) raw: Option, + pub(crate) raw: Option, pub(crate) device_id: Stored, pub(crate) desc: wgt::TextureDescriptor<()>, pub(crate) format_features: wgt::TextureFormatFeatures, @@ -272,7 +269,7 @@ pub struct TextureView { pub(crate) extent: wgt::Extent3d, pub(crate) samples: u32, /// Internal use of this texture view when used as `BindingType::Texture`. - pub(crate) sampled_internal_use: TextureUse, + pub(crate) sampled_internal_use: hal::TextureUse, pub(crate) selector: TextureSelector, pub(crate) life_guard: LifeGuard, } diff --git a/wgpu-core/src/swap_chain.rs b/wgpu-core/src/swap_chain.rs index 43cffca6df..7ff69a04d4 100644 --- a/wgpu-core/src/swap_chain.rs +++ b/wgpu-core/src/swap_chain.rs @@ -210,7 +210,7 @@ impl Global { }, samples: 1, framebuffer_attachment: sc.framebuffer_attachment.clone(), - sampled_internal_use: resource::TextureUse::empty(), + sampled_internal_use: hal::TextureUse::empty(), selector: TextureSelector { layers: 0..1, levels: 0..1, diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index e4999a9ae4..c0cdee2060 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -3,12 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::{PendingTransition, ResourceState, Unit}; -use crate::{ - id::{BufferId, Valid}, - resource::BufferUse, -}; +use crate::id::{BufferId, Valid}; +use hal::BufferUse; -//TODO: store `hal::buffer::State` here to avoid extra conversions pub(crate) type BufferState = Unit; impl PendingTransition { diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 798d4362dd..b07ce3866a 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -124,6 +124,21 @@ pub(crate) struct PendingTransition { pub usage: ops::Range, } +impl PendingTransition { + /// Produce the hal barrier corresponding to the transition. + pub fn into_hal<'a, A: hal::Api>( + self, + buf: &'a resource::Buffer, + ) -> hal::BufferBarrier<'a, A> { + log::trace!("\tbuffer -> {:?}", self); + let &(ref buffer, _) = buf.raw.as_ref().expect("Buffer is destroyed"); + hal::BufferBarrier { + buffer, + usage: self.usage, + } + } +} + impl From> for UsageConflict { fn from(e: PendingTransition) -> Self { Self::Buffer { @@ -133,6 +148,22 @@ impl From> for UsageConflict { } } +impl PendingTransition { + /// Produce the hal barrier corresponding to the transition. + pub fn into_hal<'a, A: hal::Api>( + self, + tex: &'a resource::Texture, + ) -> hal::TextureBarrier<'a, A> { + log::trace!("\ttexture -> {:?}", self); + let &(ref texture, _) = tex.raw.as_ref().expect("Texture is destroyed"); + hal::TextureBarrier { + texture, + subresource: self.selector, + usage: self.usage, + } + } +} + impl From> for UsageConflict { fn from(e: PendingTransition) -> Self { Self::Texture { @@ -514,14 +545,14 @@ pub enum UsageConflict { )] Buffer { id: id::BufferId, - combined_use: resource::BufferUse, + combined_use: hal::BufferUse, }, #[error("Attempted to use texture {id:?} mips {mip_levels:?} layers {array_layers:?} as a combination of {combined_use:?} within a usage scope.")] Texture { id: id::TextureId, mip_levels: ops::Range, array_layers: ops::Range, - combined_use: resource::TextureUse, + combined_use: hal::TextureUse, }, } diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index 635d7017da..174a15d0ba 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -6,8 +6,8 @@ use super::{range::RangedStates, PendingTransition, ResourceState, Unit}; use crate::{ device::MAX_MIP_LEVELS, id::{TextureId, Valid}, - resource::TextureUse, }; +use hal::TextureUse; use arrayvec::ArrayVec; diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 39bc45a6fb..8e7446539b 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -1,3 +1,5 @@ +#![allow(unused_variables)] + #[derive(Clone)] pub struct Api; pub struct Context; @@ -42,161 +44,241 @@ impl crate::Instance for Context { impl crate::Surface for Context { unsafe fn configure( &mut self, - _device: &Context, - _config: &crate::SurfaceConfiguration, + device: &Context, + config: &crate::SurfaceConfiguration, ) -> Result<(), crate::SurfaceError> { Ok(()) } - unsafe fn unconfigure(&mut self, _device: &Context) {} + unsafe fn unconfigure(&mut self, device: &Context) {} unsafe fn acquire_texture( &mut self, - _timeout_ms: u32, + timeout_ms: u32, ) -> Result<(Resource, Option), crate::SurfaceError> { Ok((Resource, None)) } } impl crate::Adapter for Context { - unsafe fn open(&self, _features: wgt::Features) -> DeviceResult> { + unsafe fn open(&self, features: wgt::Features) -> DeviceResult> { Err(crate::DeviceError::Lost) } - unsafe fn close(&self, _device: Context) {} + unsafe fn close(&self, device: Context) {} unsafe fn texture_format_capabilities( &self, - _format: wgt::TextureFormat, + format: wgt::TextureFormat, ) -> crate::TextureFormatCapability { crate::TextureFormatCapability::empty() } - unsafe fn surface_capabilities( - &self, - _surface: &Context, - ) -> Option { + unsafe fn surface_capabilities(&self, surface: &Context) -> Option { None } } impl crate::Queue for Context { - unsafe fn submit>(&mut self, _command_buffers: I) {} + unsafe fn submit(&mut self, command_buffers: I) {} } impl crate::Device for Context { - unsafe fn create_buffer( - &self, - _desc: &wgt::BufferDescriptor, - ) -> DeviceResult { + unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_buffer(&self, _buffer: Resource) {} + unsafe fn destroy_buffer(&self, buffer: Resource) {} unsafe fn map_buffer( &self, - _buffer: &Resource, - _range: crate::MemoryRange, + buffer: &Resource, + range: crate::MemoryRange, ) -> DeviceResult> { Err(crate::DeviceError::Lost) } - unsafe fn unmap_buffer(&self, _buffer: &Resource) {} - unsafe fn flush_mapped_ranges>( - &self, - _buffer: &Resource, - _ranges: I, - ) { - } - unsafe fn invalidate_mapped_ranges>( - &self, - _buffer: &Resource, - _ranges: I, - ) { - } + unsafe fn unmap_buffer(&self, buffer: &Resource) {} + unsafe fn flush_mapped_ranges(&self, buffer: &Resource, ranges: I) {} + unsafe fn invalidate_mapped_ranges(&self, buffer: &Resource, ranges: I) {} - unsafe fn create_texture( - &self, - _desc: &wgt::TextureDescriptor, - ) -> DeviceResult { + unsafe fn create_texture(&self, desc: &crate::TextureDescriptor) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_texture(&self, _texture: Resource) {} + unsafe fn destroy_texture(&self, texture: Resource) {} unsafe fn create_texture_view( &self, - _texture: &Resource, - _desc: &crate::TextureViewDescriptor, + texture: &Resource, + desc: &crate::TextureViewDescriptor, ) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_texture_view(&self, _view: Resource) {} - unsafe fn create_sampler(&self, _desc: &crate::SamplerDescriptor) -> DeviceResult { + unsafe fn destroy_texture_view(&self, view: Resource) {} + unsafe fn create_sampler(&self, desc: &crate::SamplerDescriptor) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_sampler(&self, _sampler: Resource) {} + unsafe fn destroy_sampler(&self, sampler: Resource) {} unsafe fn create_command_buffer( &self, - _desc: &crate::CommandBufferDescriptor, + desc: &crate::CommandBufferDescriptor, ) -> DeviceResult { Ok(Encoder) } - unsafe fn destroy_command_buffer(&self, _cmd_buf: Encoder) {} + unsafe fn destroy_command_buffer(&self, cmd_buf: Encoder) {} unsafe fn create_bind_group_layout( &self, - _desc: &crate::BindGroupLayoutDescriptor, + desc: &crate::BindGroupLayoutDescriptor, ) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_bind_group_layout(&self, _bg_layout: Resource) {} + unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {} unsafe fn create_pipeline_layout( &self, - _desc: &crate::PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_pipeline_layout(&self, _pipeline_layout: Resource) {} + unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {} unsafe fn create_bind_group( &self, - _desc: &crate::BindGroupDescriptor, + desc: &crate::BindGroupDescriptor, ) -> DeviceResult { Ok(Resource) } - unsafe fn destroy_bind_group(&self, _group: Resource) {} + unsafe fn destroy_bind_group(&self, group: Resource) {} unsafe fn create_shader_module( &self, - _desc: &crate::ShaderModuleDescriptor, - _shader: crate::NagaShader, + desc: &crate::ShaderModuleDescriptor, + shader: crate::NagaShader, ) -> Result { Ok(Resource) } - unsafe fn destroy_shader_module(&self, _module: Resource) {} + unsafe fn destroy_shader_module(&self, module: Resource) {} unsafe fn create_render_pipeline( &self, - _desc: &crate::RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor, ) -> Result { Ok(Resource) } - unsafe fn destroy_render_pipeline(&self, _pipeline: Resource) {} + unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {} unsafe fn create_compute_pipeline( &self, - _desc: &crate::ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor, ) -> Result { Ok(Resource) } - unsafe fn destroy_compute_pipeline(&self, _pipeline: Resource) {} + unsafe fn destroy_compute_pipeline(&self, pipeline: Resource) {} } impl crate::CommandBuffer for Encoder { unsafe fn begin(&mut self) {} unsafe fn end(&mut self) {} + unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) + where + T: Iterator>, + { + } + + unsafe fn transition_textures<'a, T>(&mut self, barriers: T) + where + T: Iterator>, + { + } + + unsafe fn fill_buffer(&mut self, buffer: &Resource, range: crate::MemoryRange, value: u8) {} + + unsafe fn copy_buffer_to_buffer(&mut self, src: &Resource, dst: &Resource, regions: T) + where + T: Iterator, + { + } + + /// Note: `dst` current usage has to be `TextureUse::COPY_DST`. + unsafe fn copy_texture_to_texture( + &mut self, + src: &Resource, + src_usage: crate::TextureUse, + dst: &Resource, + regions: T, + ) { + } + + /// Note: `dst` current usage has to be `TextureUse::COPY_DST`. + unsafe fn copy_buffer_to_texture(&mut self, src: &Resource, dst: &Resource, regions: T) {} + + unsafe fn copy_texture_to_buffer( + &mut self, + src: &Resource, + src_usage: crate::TextureUse, + dst: &Resource, + regions: T, + ) { + } + unsafe fn begin_render_pass(&mut self) -> Encoder { Encoder } - unsafe fn end_render_pass(&mut self, _pass: Encoder) {} + unsafe fn end_render_pass(&mut self, pass: Encoder) {} unsafe fn begin_compute_pass(&mut self) -> Encoder { Encoder } - unsafe fn end_compute_pass(&mut self, _pass: Encoder) {} + unsafe fn end_compute_pass(&mut self, pass: Encoder) {} } -impl crate::RenderPass for Encoder {} -impl crate::ComputePass for Encoder {} +impl crate::RenderPass for Encoder { + unsafe fn set_pipeline(&mut self, pipeline: &Resource) {} + + unsafe fn set_bind_group(&mut self, layout: &Resource, index: u32, group: &Resource) {} + + unsafe fn set_index_buffer<'a>( + &mut self, + binding: crate::BufferBinding<'a, Api>, + format: wgt::IndexFormat, + ) { + } + unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: crate::BufferBinding<'a, Api>) { + } + unsafe fn set_viewport(&mut self, rect: &crate::Rect, depth_range: std::ops::Range) {} + unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect) {} + unsafe fn set_stencil_reference(&mut self, value: u32) {} + unsafe fn set_blend_constants(&mut self, color: wgt::Color) {} + + unsafe fn draw( + &mut self, + start_vertex: u32, + vertex_count: u32, + start_instance: u32, + instance_count: u32, + ) { + } + unsafe fn draw_indexed( + &mut self, + start_index: u32, + index_count: u32, + base_vertex: i32, + start_instance: u32, + instance_count: u32, + ) { + } + unsafe fn draw_indirect( + &mut self, + buffer: &Resource, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + } + unsafe fn draw_indexed_indirect( + &mut self, + buffer: &Resource, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + } +} + +impl crate::ComputePass for Encoder { + unsafe fn set_pipeline(&mut self, pipeline: &Resource) {} + + unsafe fn set_bind_group(&mut self, layout: &Resource, index: u32, group: &Resource) {} + + unsafe fn dispatch(&mut self, count: [u32; 3]) {} + unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} +} diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 2bd89a8811..918d401990 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -10,7 +10,7 @@ * - Objects are passed by references and returned by value. No IDs. * - Mapping is persistent, with explicit synchronization. * - Resource transitions are explicit. - * - All layouts are explicit. + * - All layouts are explicit. Binding model has compatibility. */ #![allow( @@ -107,9 +107,9 @@ pub trait Api: Clone + Sized { type RenderPass: RenderPass; type ComputePass: ComputePass; - type Buffer: fmt::Debug + Send + Sync; + type Buffer: fmt::Debug + Send + Sync + 'static; type QuerySet: fmt::Debug + Send + Sync; - type Texture: fmt::Debug + Send + Sync; + type Texture: fmt::Debug + Send + Sync + 'static; type SurfaceTexture: fmt::Debug + Send + Sync + Borrow; type TextureView: fmt::Debug + Send + Sync; type Sampler: fmt::Debug + Send + Sync; @@ -158,10 +158,8 @@ pub trait Adapter { } pub trait Device { - unsafe fn create_buffer( - &self, - desc: &wgt::BufferDescriptor