diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 1a1098568..d74035cc3 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -10,6 +10,7 @@ use crate::{ device::all_buffer_stages, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token}, id, + resource::BufferUse, }; use hal::command::CommandBuffer as _; @@ -228,7 +229,7 @@ impl Global { &*buffer_guard, buffer_id, (), - BufferUsage::INDIRECT, + BufferUse::INDIRECT, ); assert!(src_buffer.usage.contains(BufferUsage::INDIRECT)); diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index d19b2fc90..bb9c18649 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -15,7 +15,7 @@ use crate::{ hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token}, id, pipeline::PipelineFlags, - resource::TextureViewInner, + resource::{BufferUse, TextureUse, TextureViewInner}, track::TrackerSet, Stored, }; @@ -385,7 +385,7 @@ impl Global { type OutputAttachment<'a> = ( &'a Stored, &'a hal::image::SubresourceRange, - Option, + Option, ); let mut output_attachments = ArrayVec::<[OutputAttachment; MAX_TOTAL_ATTACHMENTS]>::new(); @@ -414,12 +414,12 @@ impl Global { }; // Using render pass for transition. - let consistent_usage = base_trackers + let consistent_use = base_trackers .textures .query(source_id.value, view.range.clone()); - output_attachments.push((source_id, &view.range, consistent_usage)); + output_attachments.push((source_id, &view.range, consistent_use)); - let old_layout = match consistent_usage { + let old_layout = match consistent_use { Some(usage) => { conv::map_texture_state( usage, @@ -464,12 +464,12 @@ impl Global { let layouts = match view.inner { TextureViewInner::Native { ref source_id, .. } => { - let consistent_usage = base_trackers + let consistent_use = base_trackers .textures .query(source_id.value, view.range.clone()); - output_attachments.push((source_id, &view.range, consistent_usage)); + output_attachments.push((source_id, &view.range, consistent_use)); - let old_layout = match consistent_usage { + let old_layout = match consistent_use { Some(usage) => { conv::map_texture_state(usage, hal::format::Aspects::COLOR).1 } @@ -516,12 +516,12 @@ impl Global { let layouts = match view.inner { TextureViewInner::Native { ref source_id, .. } => { - let consistent_usage = base_trackers + let consistent_use = base_trackers .textures .query(source_id.value, view.range.clone()); - output_attachments.push((source_id, &view.range, consistent_usage)); + output_attachments.push((source_id, &view.range, consistent_use)); - let old_layout = match consistent_usage { + let old_layout = match consistent_use { Some(usage) => { conv::map_texture_state(usage, hal::format::Aspects::COLOR).1 } @@ -559,11 +559,11 @@ impl Global { } }; - for (source_id, view_range, consistent_usage) in output_attachments { + for (source_id, view_range, consistent_use) in output_attachments { let texture = &texture_guard[source_id.value]; assert!(texture.usage.contains(TextureUsage::OUTPUT_ATTACHMENT)); - let usage = consistent_usage.unwrap_or(TextureUsage::OUTPUT_ATTACHMENT); + let usage = consistent_use.unwrap_or(TextureUse::OUTPUT_ATTACHMENT); // this is important to record the `first` state. let _ = trackers.textures.change_replace( source_id.value, @@ -571,14 +571,14 @@ impl Global { view_range.clone(), usage, ); - if consistent_usage.is_some() { + if consistent_use.is_some() { // If we expect the texture to be transited to a new state by the // render pass configuration, make the tracker aware of that. let _ = trackers.textures.change_replace( source_id.value, &source_id.ref_count, view_range.clone(), - TextureUsage::OUTPUT_ATTACHMENT, + TextureUse::OUTPUT_ATTACHMENT, ); }; } @@ -944,7 +944,7 @@ impl Global { if let Some((buffer_id, ref range)) = state.index.bound_buffer_view { let buffer = trackers .buffers - .use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDEX) + .use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDEX) .unwrap(); let view = hal::buffer::IndexBufferView { @@ -982,7 +982,7 @@ impl Global { } => { let buffer = trackers .buffers - .use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDEX) + .use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDEX) .unwrap(); assert!(buffer.usage.contains(BufferUsage::INDEX), "An invalid setIndexBuffer call has been made. The buffer usage is {:?} which does not contain required usage INDEX", buffer.usage); @@ -1015,7 +1015,7 @@ impl Global { } => { let buffer = trackers .buffers - .use_extend(&*buffer_guard, buffer_id, (), BufferUsage::VERTEX) + .use_extend(&*buffer_guard, buffer_id, (), BufferUse::VERTEX) .unwrap(); assert!(buffer.usage.contains(BufferUsage::VERTEX), "An invalid setVertexBuffer call has been made. The buffer usage is {:?} which does not contain required usage VERTEX", buffer.usage); let empty_slots = (1 + slot as usize).saturating_sub(state.vertex.inputs.len()); @@ -1139,7 +1139,7 @@ impl Global { let buffer = trackers .buffers - .use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDIRECT) + .use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDIRECT) .unwrap(); assert!(buffer.usage.contains(BufferUsage::INDIRECT), "An invalid drawIndirect call has been made. The buffer usage is {:?} which does not contain required usage INDIRECT", buffer.usage); @@ -1152,7 +1152,7 @@ impl Global { let buffer = trackers .buffers - .use_extend(&*buffer_guard, buffer_id, (), BufferUsage::INDIRECT) + .use_extend(&*buffer_guard, buffer_id, (), BufferUse::INDIRECT) .unwrap(); assert!(buffer.usage.contains(BufferUsage::INDIRECT), "An invalid drawIndexedIndirect call has been made. The buffer usage is {:?} which does not contain required usage INDIRECT", buffer.usage); diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 81c704438..62fcb56f8 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -7,6 +7,7 @@ use crate::{ device::{all_buffer_stages, all_image_stages}, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token}, id::{BufferId, CommandEncoderId, TextureId}, + resource::{BufferUse, TextureUse}, }; use hal::command::CommandBuffer as _; @@ -92,16 +93,14 @@ impl Global { let (src_buffer, src_pending) = cmb.trackers .buffers - .use_replace(&*buffer_guard, source, (), BufferUsage::COPY_SRC); + .use_replace(&*buffer_guard, source, (), BufferUse::COPY_SRC); assert!(src_buffer.usage.contains(BufferUsage::COPY_SRC)); barriers.extend(src_pending.map(|pending| pending.into_hal(src_buffer))); - let (dst_buffer, dst_pending) = cmb.trackers.buffers.use_replace( - &*buffer_guard, - destination, - (), - BufferUsage::COPY_DST, - ); + let (dst_buffer, dst_pending) = + cmb.trackers + .buffers + .use_replace(&*buffer_guard, destination, (), BufferUse::COPY_DST); assert!(dst_buffer.usage.contains(BufferUsage::COPY_DST)); barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_buffer))); @@ -140,7 +139,7 @@ impl Global { &*buffer_guard, source.buffer, (), - BufferUsage::COPY_SRC, + BufferUse::COPY_SRC, ); assert!(src_buffer.usage.contains(BufferUsage::COPY_SRC)); let src_barriers = src_pending.map(|pending| pending.into_hal(src_buffer)); @@ -149,7 +148,7 @@ impl Global { &*texture_guard, destination.texture, destination.to_selector(aspects), - TextureUsage::COPY_DST, + TextureUse::COPY_DST, ); assert!(dst_texture.usage.contains(TextureUsage::COPY_DST)); let dst_barriers = dst_pending.map(|pending| pending.into_hal(dst_texture)); @@ -204,7 +203,7 @@ impl Global { &*texture_guard, source.texture, source.to_selector(aspects), - TextureUsage::COPY_SRC, + TextureUse::COPY_SRC, ); assert!(src_texture.usage.contains(TextureUsage::COPY_SRC)); let src_barriers = src_pending.map(|pending| pending.into_hal(src_texture)); @@ -213,7 +212,7 @@ impl Global { &*buffer_guard, destination.buffer, (), - BufferUsage::COPY_DST, + BufferUse::COPY_DST, ); assert!(dst_buffer.usage.contains(BufferUsage::COPY_DST)); let dst_barrier = dst_barriers.map(|pending| pending.into_hal(dst_buffer)); @@ -273,7 +272,7 @@ impl Global { &*texture_guard, source.texture, source.to_selector(aspects), - TextureUsage::COPY_SRC, + TextureUse::COPY_SRC, ); assert!(src_texture.usage.contains(TextureUsage::COPY_SRC)); barriers.extend(src_pending.map(|pending| pending.into_hal(src_texture))); @@ -282,7 +281,7 @@ impl Global { &*texture_guard, destination.texture, destination.to_selector(aspects), - TextureUsage::COPY_DST, + TextureUse::COPY_DST, ); assert!(dst_texture.usage.contains(TextureUsage::COPY_DST)); barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_texture))); diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 23790ac00..60ae0ab76 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -2,13 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::{binding_model, Features}; -use wgt::{ - BlendDescriptor, BlendFactor, Color, ColorStateDescriptor, ColorWrite, CompareFunction, - CullMode, DepthStencilStateDescriptor, Extent3d, FrontFace, IndexFormat, Origin3d, - PrimitiveTopology, RasterizationStateDescriptor, StencilOperation, StencilStateFaceDescriptor, - TextureFormat, VertexFormat, -}; +use crate::{binding_model, resource, Features}; pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::memory::Properties) { use hal::buffer::Usage as U; @@ -39,7 +33,7 @@ pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::me if usage.contains(W::UNIFORM) { hal_usage |= U::UNIFORM; } - if usage.intersects(W::STORAGE | W::STORAGE_READ) { + if usage.contains(W::STORAGE) { hal_usage |= U::STORAGE; } if usage.contains(W::INDIRECT) { @@ -135,7 +129,7 @@ pub fn map_shader_stage_flags(shader_stage_flags: wgt::ShaderStage) -> hal::pso: value } -pub fn map_origin(origin: Origin3d) -> hal::image::Offset { +pub fn map_origin(origin: wgt::Origin3d) -> hal::image::Offset { hal::image::Offset { x: origin.x as i32, y: origin.y as i32, @@ -143,7 +137,7 @@ pub fn map_origin(origin: Origin3d) -> hal::image::Offset { } } -pub fn map_extent(extent: Extent3d) -> hal::image::Extent { +pub fn map_extent(extent: wgt::Extent3d) -> hal::image::Extent { hal::image::Extent { width: extent.width, height: extent.height, @@ -151,7 +145,7 @@ pub fn map_extent(extent: Extent3d) -> hal::image::Extent { } } -pub fn map_primitive_topology(primitive_topology: PrimitiveTopology) -> hal::pso::Primitive { +pub fn map_primitive_topology(primitive_topology: wgt::PrimitiveTopology) -> hal::pso::Primitive { use hal::pso::Primitive as H; use wgt::PrimitiveTopology as Pt; match primitive_topology { @@ -163,10 +157,10 @@ pub fn map_primitive_topology(primitive_topology: PrimitiveTopology) -> hal::pso } } -pub fn map_color_state_descriptor(desc: &ColorStateDescriptor) -> hal::pso::ColorBlendDesc { +pub fn map_color_state_descriptor(desc: &wgt::ColorStateDescriptor) -> hal::pso::ColorBlendDesc { let color_mask = desc.write_mask; - let blend_state = if desc.color_blend != BlendDescriptor::REPLACE - || desc.alpha_blend != BlendDescriptor::REPLACE + let blend_state = if desc.color_blend != wgt::BlendDescriptor::REPLACE + || desc.alpha_blend != wgt::BlendDescriptor::REPLACE { Some(hal::pso::BlendState { color: map_blend_descriptor(&desc.color_blend), @@ -181,7 +175,7 @@ pub fn map_color_state_descriptor(desc: &ColorStateDescriptor) -> hal::pso::Colo } } -fn map_color_write_flags(flags: ColorWrite) -> hal::pso::ColorMask { +fn map_color_write_flags(flags: wgt::ColorWrite) -> hal::pso::ColorMask { use hal::pso::ColorMask as H; use wgt::ColorWrite as Cw; @@ -201,7 +195,7 @@ fn map_color_write_flags(flags: ColorWrite) -> hal::pso::ColorMask { value } -fn map_blend_descriptor(blend_desc: &BlendDescriptor) -> hal::pso::BlendOp { +fn map_blend_descriptor(blend_desc: &wgt::BlendDescriptor) -> hal::pso::BlendOp { use hal::pso::BlendOp as H; use wgt::BlendOperation as Bo; match blend_desc.operation { @@ -222,7 +216,7 @@ fn map_blend_descriptor(blend_desc: &BlendDescriptor) -> hal::pso::BlendOp { } } -fn map_blend_factor(blend_factor: BlendFactor) -> hal::pso::Factor { +fn map_blend_factor(blend_factor: wgt::BlendFactor) -> hal::pso::Factor { use hal::pso::Factor as H; use wgt::BlendFactor as Bf; match blend_factor { @@ -243,10 +237,10 @@ fn map_blend_factor(blend_factor: BlendFactor) -> hal::pso::Factor { } pub fn map_depth_stencil_state_descriptor( - desc: &DepthStencilStateDescriptor, + desc: &wgt::DepthStencilStateDescriptor, ) -> hal::pso::DepthStencilDesc { hal::pso::DepthStencilDesc { - depth: if desc.depth_write_enabled || desc.depth_compare != CompareFunction::Always { + depth: if desc.depth_write_enabled || desc.depth_compare != wgt::CompareFunction::Always { Some(hal::pso::DepthTest { fun: map_compare_function(desc.depth_compare) .expect("DepthStencilStateDescriptor has undefined compare function"), @@ -258,8 +252,8 @@ pub fn map_depth_stencil_state_descriptor( depth_bounds: false, // TODO stencil: if desc.stencil_read_mask != !0 || desc.stencil_write_mask != !0 - || desc.stencil_front != StencilStateFaceDescriptor::IGNORE - || desc.stencil_back != StencilStateFaceDescriptor::IGNORE + || desc.stencil_front != wgt::StencilStateFaceDescriptor::IGNORE + || desc.stencil_back != wgt::StencilStateFaceDescriptor::IGNORE { Some(hal::pso::StencilTest { faces: hal::pso::Sided { @@ -280,7 +274,9 @@ pub fn map_depth_stencil_state_descriptor( } } -fn map_stencil_face(stencil_state_face_desc: &StencilStateFaceDescriptor) -> hal::pso::StencilFace { +fn map_stencil_face( + stencil_state_face_desc: &wgt::StencilStateFaceDescriptor, +) -> hal::pso::StencilFace { hal::pso::StencilFace { fun: map_compare_function(stencil_state_face_desc.compare) .expect("StencilStateFaceDescriptor has undefined compare function"), @@ -290,7 +286,9 @@ fn map_stencil_face(stencil_state_face_desc: &StencilStateFaceDescriptor) -> hal } } -pub fn map_compare_function(compare_function: CompareFunction) -> Option { +pub fn map_compare_function( + compare_function: wgt::CompareFunction, +) -> Option { use hal::pso::Comparison as H; use wgt::CompareFunction as Cf; match compare_function { @@ -306,7 +304,7 @@ pub fn map_compare_function(compare_function: CompareFunction) -> Option hal::pso::StencilOp { +fn map_stencil_operation(stencil_operation: wgt::StencilOperation) -> hal::pso::StencilOp { use hal::pso::StencilOp as H; use wgt::StencilOperation as So; match stencil_operation { @@ -322,7 +320,7 @@ fn map_stencil_operation(stencil_operation: StencilOperation) -> hal::pso::Stenc } pub(crate) fn map_texture_format( - texture_format: TextureFormat, + texture_format: wgt::TextureFormat, features: Features, ) -> hal::format::Format { use hal::format::Format as H; @@ -394,7 +392,7 @@ pub(crate) fn map_texture_format( } } -pub fn map_vertex_format(vertex_format: VertexFormat) -> hal::format::Format { +pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> hal::format::Format { use hal::format::Format as H; use wgt::VertexFormat as Vf; match vertex_format { @@ -438,11 +436,11 @@ fn checked_u32_as_u16(value: u32) -> u16 { pub fn map_texture_dimension_size( dimension: wgt::TextureDimension, - Extent3d { + wgt::Extent3d { width, height, depth, - }: Extent3d, + }: wgt::Extent3d, sample_size: u32, ) -> hal::image::Kind { use hal::image::Kind as H; @@ -481,9 +479,9 @@ pub fn map_texture_view_dimension(dimension: wgt::TextureViewDimension) -> hal:: } } -pub fn map_buffer_state(usage: wgt::BufferUsage) -> hal::buffer::State { +pub(crate) fn map_buffer_state(usage: resource::BufferUse) -> hal::buffer::State { + use crate::resource::BufferUse as W; use hal::buffer::Access as A; - use wgt::BufferUsage as W; let mut access = A::empty(); if usage.contains(W::MAP_READ) { @@ -507,22 +505,22 @@ pub fn map_buffer_state(usage: wgt::BufferUsage) -> hal::buffer::State { if usage.contains(W::UNIFORM) { access |= A::UNIFORM_READ | A::SHADER_READ; } - if usage.contains(W::STORAGE_READ) { + if usage.contains(W::STORAGE_LOAD) { access |= A::SHADER_READ; } - if usage.contains(W::STORAGE) { + if usage.contains(W::STORAGE_STORE) { access |= A::SHADER_WRITE; } access } -pub fn map_texture_state( - usage: wgt::TextureUsage, +pub(crate) fn map_texture_state( + usage: resource::TextureUse, aspects: hal::format::Aspects, ) -> hal::image::State { + use crate::resource::TextureUse as W; use hal::image::{Access as A, Layout as L}; - use wgt::TextureUsage as W; let is_color = aspects.contains(hal::format::Aspects::COLOR); let layout = match usage { @@ -545,9 +543,6 @@ pub fn map_texture_state( if usage.contains(W::SAMPLED) { access |= A::SHADER_READ; } - if usage.contains(W::STORAGE) { - access |= A::SHADER_READ | A::SHADER_WRITE; - } if usage.contains(W::OUTPUT_ATTACHMENT) { //TODO: read-only attachments access |= if is_color { @@ -556,6 +551,12 @@ pub fn map_texture_state( A::DEPTH_STENCIL_ATTACHMENT_WRITE }; } + if usage.contains(W::STORAGE_LOAD) { + access |= A::SHADER_READ; + } + if usage.contains(W::STORAGE_STORE) { + access |= A::SHADER_WRITE; + } (access, layout) } @@ -573,7 +574,7 @@ pub fn map_load_store_ops(load: wgt::LoadOp, store: wgt::StoreOp) -> hal::pass:: } } -pub fn map_color_f32(color: &Color) -> hal::pso::ColorValue { +pub fn map_color_f32(color: &wgt::Color) -> hal::pso::ColorValue { [ color.r as f32, color.g as f32, @@ -581,7 +582,7 @@ pub fn map_color_f32(color: &Color) -> hal::pso::ColorValue { color.a as f32, ] } -pub fn map_color_i32(color: &Color) -> [i32; 4] { +pub fn map_color_i32(color: &wgt::Color) -> [i32; 4] { [ color.r as i32, color.g as i32, @@ -589,7 +590,7 @@ pub fn map_color_i32(color: &Color) -> [i32; 4] { color.a as i32, ] } -pub fn map_color_u32(color: &Color) -> [u32; 4] { +pub fn map_color_u32(color: &wgt::Color) -> [u32; 4] { [ color.r as u32, color.g as u32, @@ -616,20 +617,20 @@ pub fn map_wrap(address: wgt::AddressMode) -> hal::image::WrapMode { } pub fn map_rasterization_state_descriptor( - desc: &RasterizationStateDescriptor, + desc: &wgt::RasterizationStateDescriptor, ) -> hal::pso::Rasterizer { use hal::pso; pso::Rasterizer { depth_clamping: false, polygon_mode: pso::PolygonMode::Fill, cull_face: match desc.cull_mode { - CullMode::None => pso::Face::empty(), - CullMode::Front => pso::Face::FRONT, - CullMode::Back => pso::Face::BACK, + wgt::CullMode::None => pso::Face::empty(), + wgt::CullMode::Front => pso::Face::FRONT, + wgt::CullMode::Back => pso::Face::BACK, }, front_face: match desc.front_face { - FrontFace::Ccw => pso::FrontFace::CounterClockwise, - FrontFace::Cw => pso::FrontFace::Clockwise, + wgt::FrontFace::Ccw => pso::FrontFace::CounterClockwise, + wgt::FrontFace::Cw => pso::FrontFace::Clockwise, }, depth_bias: if desc.depth_bias != 0 || desc.depth_bias_slope_scale != 0.0 @@ -648,9 +649,9 @@ pub fn map_rasterization_state_descriptor( } } -pub fn map_index_format(index_format: IndexFormat) -> hal::IndexType { +pub fn map_index_format(index_format: wgt::IndexFormat) -> hal::IndexType { match index_format { - IndexFormat::Uint16 => hal::IndexType::U16, - IndexFormat::Uint32 => hal::IndexType::U32, + wgt::IndexFormat::Uint16 => hal::IndexType::U16, + wgt::IndexFormat::Uint32 => hal::IndexType::U32, } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 6db35bbf6..60a965fd3 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -58,7 +58,7 @@ pub fn all_image_stages() -> hal::pso::PipelineStage { } #[derive(Clone, Copy, Debug, PartialEq)] -enum HostMap { +pub enum HostMap { Read, Write, } @@ -500,7 +500,7 @@ impl Global { .init( id, ref_count, - BufferState::with_usage(wgt::BufferUsage::empty()), + BufferState::with_usage(resource::BufferUse::EMPTY), ) .unwrap(); id @@ -547,7 +547,7 @@ impl Global { .init( id, ref_count, - BufferState::with_usage(wgt::BufferUsage::MAP_WRITE), + BufferState::with_usage(resource::BufferUse::MAP_WRITE), ) .unwrap(); @@ -1084,16 +1084,22 @@ impl Global { .expect("Failed to find binding declaration for binding"); let descriptor = match b.resource { binding_model::BindingResource::Buffer(ref bb) => { - let (alignment, usage) = match decl.ty { - binding_model::BindingType::UniformBuffer => { - (BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::UNIFORM) - } - binding_model::BindingType::StorageBuffer => { - (BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::STORAGE) - } - binding_model::BindingType::ReadonlyStorageBuffer => { - (BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::STORAGE_READ) - } + let (alignment, pub_usage, internal_use) = match decl.ty { + binding_model::BindingType::UniformBuffer => ( + BIND_BUFFER_ALIGNMENT, + wgt::BufferUsage::UNIFORM, + resource::BufferUse::UNIFORM, + ), + binding_model::BindingType::StorageBuffer => ( + BIND_BUFFER_ALIGNMENT, + wgt::BufferUsage::STORAGE, + resource::BufferUse::STORAGE_STORE, + ), + binding_model::BindingType::ReadonlyStorageBuffer => ( + BIND_BUFFER_ALIGNMENT, + wgt::BufferUsage::STORAGE, + resource::BufferUse::STORAGE_LOAD, + ), binding_model::BindingType::Sampler | binding_model::BindingType::ComparisonSampler | binding_model::BindingType::SampledTexture @@ -1110,12 +1116,12 @@ impl Global { ); let buffer = used .buffers - .use_extend(&*buffer_guard, bb.buffer, (), usage) + .use_extend(&*buffer_guard, bb.buffer, (), internal_use) .unwrap(); assert!( - buffer.usage.contains(usage), + buffer.usage.contains(pub_usage), "Expected buffer usage {:?}", - usage + pub_usage ); let sub_range = hal::buffer::SubRange { @@ -1148,15 +1154,22 @@ impl Global { hal::pso::Descriptor::Sampler(&sampler.raw) } binding_model::BindingResource::TextureView(id) => { - let (usage, image_layout) = match decl.ty { + let (pub_usage, internal_use, image_layout) = match decl.ty { binding_model::BindingType::SampledTexture => ( wgt::TextureUsage::SAMPLED, + resource::TextureUse::SAMPLED, hal::image::Layout::ShaderReadOnlyOptimal, ), - binding_model::BindingType::ReadonlyStorageTexture - | binding_model::BindingType::WriteonlyStorageTexture => { - (wgt::TextureUsage::STORAGE, hal::image::Layout::General) - } + binding_model::BindingType::ReadonlyStorageTexture => ( + wgt::TextureUsage::STORAGE, + resource::TextureUse::STORAGE_LOAD, + hal::image::Layout::General, + ), + binding_model::BindingType::WriteonlyStorageTexture => ( + wgt::TextureUsage::STORAGE, + resource::TextureUse::STORAGE_STORE, + hal::image::Layout::General, + ), found => panic!("Mismatched texture binding type in {:?}. Expected a type of SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture but found {:?}", decl, found), }; let view = used @@ -1176,10 +1189,14 @@ impl Global { source_id.value, &source_id.ref_count, view.range.clone(), - usage, + internal_use, ) .unwrap(); - assert!(texture.usage.contains(usage)); + assert!( + texture.usage.contains(pub_usage), + "Expected buffer usage {:?}", + pub_usage + ); hal::pso::Descriptor::Image(raw, image_layout) } @@ -2099,26 +2116,26 @@ impl Global { pub fn buffer_map_async( &self, buffer_id: id::BufferId, - usage: wgt::BufferUsage, range: std::ops::Range, operation: resource::BufferMapOperation, ) { let hub = B::hub(self); let mut token = Token::root(); let (device_guard, mut token) = hub.devices.read(&mut token); + let (pub_usage, internal_use) = match operation { + resource::BufferMapOperation::Read { .. } => { + (wgt::BufferUsage::MAP_READ, resource::BufferUse::MAP_READ) + } + resource::BufferMapOperation::Write { .. } => { + (wgt::BufferUsage::MAP_WRITE, resource::BufferUse::MAP_WRITE) + } + }; let (device_id, ref_count) = { let (mut buffer_guard, _) = hub.buffers.write(&mut token); let buffer = &mut buffer_guard[buffer_id]; - if usage.contains(wgt::BufferUsage::MAP_READ) { - assert!(buffer.usage.contains(wgt::BufferUsage::MAP_READ)); - } - - if usage.contains(wgt::BufferUsage::MAP_WRITE) { - assert!(buffer.usage.contains(wgt::BufferUsage::MAP_WRITE)); - } - + assert!(buffer.usage.contains(pub_usage)); buffer.map_state = match buffer.map_state { resource::BufferMapState::Active => panic!("Buffer already mapped"), resource::BufferMapState::Waiting(_) => { @@ -2147,7 +2164,7 @@ impl Global { .trackers .lock() .buffers - .change_replace(buffer_id, &ref_count, (), usage); + .change_replace(buffer_id, &ref_count, (), internal_use); device.lock_life(&mut token).map(buffer_id, ref_count); } diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 5fb998842..99d7892df 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -26,7 +26,7 @@ pub mod backend { pub mod binding_model; pub mod command; -pub mod conv; +mod conv; pub mod device; pub mod hub; pub mod id; @@ -35,7 +35,7 @@ pub mod pipeline; pub mod power; pub mod resource; pub mod swap_chain; -pub mod track; +mod track; pub use hal::pso::read_spirv; diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index ec3b4be45..de7bf80c4 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -13,6 +13,55 @@ use wgt::{BufferAddress, BufferUsage, TextureFormat, TextureUsage}; use std::{borrow::Borrow, fmt}; +bitflags::bitflags! { + /// The internal enum mirrored from `BufferUsage`. The values don't have to match! + pub (crate) struct BufferUse: u32 { + const EMPTY = 0; + const MAP_READ = 1; + const MAP_WRITE = 2; + const COPY_SRC = 4; + const COPY_DST = 8; + const INDEX = 16; + const VERTEX = 32; + const UNIFORM = 64; + const STORAGE_LOAD = 128; + const STORAGE_STORE = 256; + const INDIRECT = 512; + /// The combination of all read-only usages. + const READ_ALL = Self::MAP_READ.bits | Self::COPY_SRC.bits | + Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits | + Self::STORAGE_LOAD.bits | Self::INDIRECT.bits; + /// The combination of all write-only and read-write usages. + const WRITE_ALL = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE_STORE.bits; + /// The combination of all usages that the are guaranteed to be be ordered by the hardware. + /// If a usage is not ordered, then even if it doesn't change between draw calls, there + /// still need to be pipeline barriers inserted for synchronization. + const ORDERED = Self::READ_ALL.bits | Self::MAP_WRITE.bits | Self::COPY_DST.bits; + } +} + +bitflags::bitflags! { + /// The internal enum mirrored from `TextureUsage`. The values don't have to match! + pub(crate) struct TextureUse: u32 { + const EMPTY = 0; + const COPY_SRC = 1; + const COPY_DST = 2; + const SAMPLED = 4; + const OUTPUT_ATTACHMENT = 8; + const STORAGE_LOAD = 16; + const STORAGE_STORE = 32; + /// The combination of all read-only usages. + const READ_ALL = Self::COPY_SRC.bits | Self::SAMPLED.bits | Self::STORAGE_LOAD.bits; + /// The combination of all write-only and read-write usages. + const WRITE_ALL = Self::COPY_DST.bits | Self::OUTPUT_ATTACHMENT.bits | Self::STORAGE_STORE.bits; + /// The combination of all usages that the are guaranteed to be be ordered by the hardware. + /// If a usage is not ordered, then even if it doesn't change between draw calls, there + /// still need to be pipeline barriers inserted for synchronization. + const ORDERED = Self::READ_ALL.bits | Self::COPY_DST.bits | Self::OUTPUT_ATTACHMENT.bits; + const UNINITIALIZED = 0xFFFF; + } +} + #[repr(C)] #[derive(Debug)] pub enum BufferMapAsyncStatus { diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index fbeb3d640..1c41d3611 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -3,18 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::{PendingTransition, ResourceState, Unit}; -use crate::id::BufferId; - -use wgt::BufferUsage; +use crate::{id::BufferId, resource::BufferUse}; //TODO: store `hal::buffer::State` here to avoid extra conversions -pub type BufferState = Unit; +pub(crate) type BufferState = Unit; impl PendingTransition { - fn collapse(self) -> Result { + fn collapse(self) -> Result { if self.usage.start.is_empty() || self.usage.start == self.usage.end - || !BufferUsage::WRITE_ALL.intersects(self.usage.start | self.usage.end) + || !BufferUse::WRITE_ALL.intersects(self.usage.start | self.usage.end) { Ok(self.usage.start | self.usage.end) } else { @@ -27,13 +25,13 @@ impl Default for BufferState { fn default() -> Self { BufferState { first: None, - last: BufferUsage::empty(), + last: BufferUse::empty(), } } } impl BufferState { - pub fn with_usage(usage: BufferUsage) -> Self { + pub fn with_usage(usage: BufferUse) -> Self { Unit::new(usage) } } @@ -41,7 +39,7 @@ impl BufferState { impl ResourceState for BufferState { type Id = BufferId; type Selector = (); - type Usage = BufferUsage; + type Usage = BufferUse; fn query(&self, _selector: Self::Selector) -> Option { Some(self.last) @@ -55,7 +53,7 @@ impl ResourceState for BufferState { output: Option<&mut Vec>>, ) -> Result<(), PendingTransition> { let old = self.last; - if old != usage || !BufferUsage::ORDERED.contains(usage) { + if old != usage || !BufferUse::ORDERED.contains(usage) { let pending = PendingTransition { id, selector: (), @@ -89,7 +87,7 @@ impl ResourceState for BufferState { ) -> Result<(), PendingTransition> { let old = self.last; let new = other.port(); - if old == new && BufferUsage::ORDERED.contains(new) { + if old == new && BufferUse::ORDERED.contains(new) { if output.is_some() && self.first.is_none() { self.first = Some(old); } @@ -131,64 +129,64 @@ mod test { fn change_extend() { let mut bs = Unit { first: None, - last: BufferUsage::INDEX, + last: BufferUse::INDEX, }; let id = Id::default(); assert_eq!( - bs.change(id, (), BufferUsage::STORAGE, None), + bs.change(id, (), BufferUse::STORAGE_STORE, None), Err(PendingTransition { id, selector: (), - usage: BufferUsage::INDEX..BufferUsage::STORAGE, + usage: BufferUse::INDEX..BufferUse::STORAGE_STORE, }), ); - bs.change(id, (), BufferUsage::VERTEX, None).unwrap(); - bs.change(id, (), BufferUsage::INDEX, None).unwrap(); - assert_eq!(bs, Unit::new(BufferUsage::VERTEX | BufferUsage::INDEX)); + bs.change(id, (), BufferUse::VERTEX, None).unwrap(); + bs.change(id, (), BufferUse::INDEX, None).unwrap(); + assert_eq!(bs, Unit::new(BufferUse::VERTEX | BufferUse::INDEX)); } #[test] fn change_replace() { let mut bs = Unit { first: None, - last: BufferUsage::STORAGE, + last: BufferUse::STORAGE_STORE, }; let id = Id::default(); let mut list = Vec::new(); - bs.change(id, (), BufferUsage::VERTEX, Some(&mut list)) + bs.change(id, (), BufferUse::VERTEX, Some(&mut list)) .unwrap(); assert_eq!( &list, &[PendingTransition { id, selector: (), - usage: BufferUsage::STORAGE..BufferUsage::VERTEX, + usage: BufferUse::STORAGE_STORE..BufferUse::VERTEX, }], ); assert_eq!( bs, Unit { - first: Some(BufferUsage::STORAGE), - last: BufferUsage::VERTEX, + first: Some(BufferUse::STORAGE_STORE), + last: BufferUse::VERTEX, } ); list.clear(); - bs.change(id, (), BufferUsage::STORAGE, Some(&mut list)) + bs.change(id, (), BufferUse::STORAGE_STORE, Some(&mut list)) .unwrap(); assert_eq!( &list, &[PendingTransition { id, selector: (), - usage: BufferUsage::VERTEX..BufferUsage::STORAGE, + usage: BufferUse::VERTEX..BufferUse::STORAGE_STORE, }], ); assert_eq!( bs, Unit { - first: Some(BufferUsage::STORAGE), - last: BufferUsage::STORAGE, + first: Some(BufferUse::STORAGE_STORE), + last: BufferUse::STORAGE_STORE, } ); } diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 576a3d1f1..b3c67d9db 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -17,8 +17,8 @@ use std::{ borrow::Borrow, collections::hash_map::Entry, fmt, marker::PhantomData, ops, vec::Drain, }; -pub use buffer::BufferState; -pub use texture::TextureState; +pub(crate) use buffer::BufferState; +pub(crate) use texture::TextureState; /// A single unit of state tracking. It keeps an initial /// usage as well as the last/current one, similar to `Range`. @@ -436,7 +436,7 @@ pub const DUMMY_SELECTOR: () = (); /// A set of trackers for all relevant resources. #[derive(Debug)] -pub struct TrackerSet { +pub(crate) struct TrackerSet { pub buffers: ResourceTracker, pub textures: ResourceTracker, pub views: ResourceTracker>, diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index d37ac6bb5..77d1cd713 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -3,28 +3,27 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use super::{range::RangedStates, PendingTransition, ResourceState, Unit}; -use crate::{device::MAX_MIP_LEVELS, id::TextureId}; +use crate::{device::MAX_MIP_LEVELS, id::TextureId, resource::TextureUse}; use arrayvec::ArrayVec; -use wgt::TextureUsage; use std::{iter, ops::Range}; //TODO: store `hal::image::State` here to avoid extra conversions -type PlaneStates = RangedStates>; +type PlaneStates = RangedStates>; #[derive(Clone, Debug, Default, PartialEq)] -pub struct TextureState { +pub(crate) struct TextureState { mips: ArrayVec<[PlaneStates; MAX_MIP_LEVELS]>, /// True if we have the information about all the subresources here full: bool, } impl PendingTransition { - fn collapse(self) -> Result { + fn collapse(self) -> Result { if self.usage.start.is_empty() || self.usage.start == self.usage.end - || !TextureUsage::WRITE_ALL.intersects(self.usage.start | self.usage.end) + || !TextureUse::WRITE_ALL.intersects(self.usage.start | self.usage.end) { Ok(self.usage.start | self.usage.end) } else { @@ -39,7 +38,7 @@ impl TextureState { debug_assert_eq!(range.levels.start, 0); TextureState { mips: iter::repeat_with(|| { - PlaneStates::from_range(0..range.layers.end, Unit::new(TextureUsage::UNINITIALIZED)) + PlaneStates::from_range(0..range.layers.end, Unit::new(TextureUse::UNINITIALIZED)) }) .take(range.levels.end as usize) .collect(), @@ -51,7 +50,7 @@ impl TextureState { impl ResourceState for TextureState { type Id = TextureId; type Selector = hal::image::SubresourceRange; - type Usage = TextureUsage; + type Usage = TextureUse; fn query(&self, selector: Self::Selector) -> Option { let mut result = None; @@ -99,7 +98,7 @@ impl ResourceState for TextureState { let level = selector.levels.start + mip_id as hal::image::Level; let layers = mip.isolate(&selector.layers, Unit::new(usage)); for &mut (ref range, ref mut unit) in layers { - if unit.last == usage && TextureUsage::ORDERED.contains(usage) { + if unit.last == usage && TextureUse::ORDERED.contains(usage) { continue; } // TODO: Can't satisfy clippy here unless we modify @@ -176,7 +175,7 @@ impl ResourceState for TextureState { end: Some(end), } => { let to_usage = end.port(); - if start.last == to_usage && TextureUsage::ORDERED.contains(to_usage) { + if start.last == to_usage && TextureUse::ORDERED.contains(to_usage) { Unit { first: match output { None => start.first, @@ -245,9 +244,9 @@ mod test { let mut ts = TextureState::default(); ts.mips.push(PlaneStates::empty()); ts.mips.push(PlaneStates::from_slice(&[ - (1..3, Unit::new(TextureUsage::SAMPLED)), - (3..5, Unit::new(TextureUsage::SAMPLED)), - (5..6, Unit::new(TextureUsage::STORAGE)), + (1..3, Unit::new(TextureUse::SAMPLED)), + (3..5, Unit::new(TextureUse::SAMPLED)), + (5..6, Unit::new(TextureUse::STORAGE_LOAD)), ])); assert_eq!( @@ -257,7 +256,7 @@ mod test { layers: 2..5, }), // level 1 matches - Some(TextureUsage::SAMPLED), + Some(TextureUse::SAMPLED), ); assert_eq!( ts.query(SubresourceRange { @@ -266,7 +265,7 @@ mod test { layers: 2..5, }), // level 0 is empty, level 1 matches - Some(TextureUsage::SAMPLED), + Some(TextureUse::SAMPLED), ); assert_eq!( ts.query(SubresourceRange { @@ -275,7 +274,7 @@ mod test { layers: 1..5, }), // level 1 matches with gaps - Some(TextureUsage::SAMPLED), + Some(TextureUse::SAMPLED), ); assert_eq!( ts.query(SubresourceRange { @@ -294,7 +293,7 @@ mod test { let mut ts1 = TextureState::default(); ts1.mips.push(PlaneStates::from_slice(&[( 1..3, - Unit::new(TextureUsage::SAMPLED), + Unit::new(TextureUse::SAMPLED), )])); let mut ts2 = TextureState::default(); assert_eq!( @@ -305,7 +304,7 @@ mod test { ts2.mips.push(PlaneStates::from_slice(&[( 1..2, - Unit::new(TextureUsage::COPY_SRC), + Unit::new(TextureUse::COPY_SRC), )])); assert_eq!( ts1.merge(Id::default(), &ts2, None), @@ -316,12 +315,12 @@ mod test { ts1.mips[0].query(&(1..2), |&v| v), Some(Ok(Unit { first: None, - last: TextureUsage::SAMPLED | TextureUsage::COPY_SRC, + last: TextureUse::SAMPLED | TextureUse::COPY_SRC, })), "wrong extension result" ); - ts2.mips[0] = PlaneStates::from_slice(&[(1..2, Unit::new(TextureUsage::COPY_DST))]); + ts2.mips[0] = PlaneStates::from_slice(&[(1..2, Unit::new(TextureUse::COPY_DST))]); assert_eq!( ts1.clone().merge(Id::default(), &ts2, None), Err(PendingTransition { @@ -331,19 +330,19 @@ mod test { levels: 0..1, layers: 1..2, }, - usage: TextureUsage::SAMPLED | TextureUsage::COPY_SRC..TextureUsage::COPY_DST, + usage: TextureUse::SAMPLED | TextureUse::COPY_SRC..TextureUse::COPY_DST, }), "wrong error on extending with incompatible state" ); let mut list = Vec::new(); ts2.mips[0] = PlaneStates::from_slice(&[ - (1..2, Unit::new(TextureUsage::COPY_DST)), + (1..2, Unit::new(TextureUse::COPY_DST)), ( 2..3, Unit { - first: Some(TextureUsage::COPY_SRC), - last: TextureUsage::OUTPUT_ATTACHMENT, + first: Some(TextureUse::COPY_SRC), + last: TextureUse::OUTPUT_ATTACHMENT, }, ), ]); @@ -358,7 +357,7 @@ mod test { levels: 0..1, layers: 1..2, }, - usage: TextureUsage::SAMPLED | TextureUsage::COPY_SRC..TextureUsage::COPY_DST, + usage: TextureUse::SAMPLED | TextureUse::COPY_SRC..TextureUse::COPY_DST, }, PendingTransition { id, @@ -369,7 +368,7 @@ mod test { }, // the transition links the end of the base rage (..SAMPLED) // with the start of the next range (COPY_SRC..) - usage: TextureUsage::SAMPLED..TextureUsage::COPY_SRC, + usage: TextureUse::SAMPLED..TextureUse::COPY_SRC, }, ], "replacing produced wrong transitions" @@ -377,16 +376,16 @@ mod test { assert_eq!( ts1.mips[0].query(&(1..2), |&v| v), Some(Ok(Unit { - first: Some(TextureUsage::SAMPLED | TextureUsage::COPY_SRC), - last: TextureUsage::COPY_DST, + first: Some(TextureUse::SAMPLED | TextureUse::COPY_SRC), + last: TextureUse::COPY_DST, })), "wrong final layer 1 state" ); assert_eq!( ts1.mips[0].query(&(2..3), |&v| v), Some(Ok(Unit { - first: Some(TextureUsage::SAMPLED), - last: TextureUsage::OUTPUT_ATTACHMENT, + first: Some(TextureUse::SAMPLED), + last: TextureUse::OUTPUT_ATTACHMENT, })), "wrong final layer 2 state" ); @@ -395,8 +394,8 @@ mod test { ts2.mips[0] = PlaneStates::from_slice(&[( 2..3, Unit { - first: Some(TextureUsage::OUTPUT_ATTACHMENT), - last: TextureUsage::COPY_SRC, + first: Some(TextureUse::OUTPUT_ATTACHMENT), + last: TextureUse::COPY_SRC, }, )]); ts1.merge(Id::default(), &ts2, Some(&mut list)).unwrap(); @@ -406,8 +405,8 @@ mod test { ts2.mips[0] = PlaneStates::from_slice(&[( 2..3, Unit { - first: Some(TextureUsage::COPY_DST), - last: TextureUsage::COPY_DST, + first: Some(TextureUse::COPY_DST), + last: TextureUse::COPY_DST, }, )]); ts1.merge(Id::default(), &ts2, Some(&mut list)).unwrap(); @@ -420,7 +419,7 @@ mod test { levels: 0..1, layers: 2..3, }, - usage: TextureUsage::COPY_SRC..TextureUsage::COPY_DST, + usage: TextureUse::COPY_SRC..TextureUse::COPY_DST, },], "invalid replacing transition" ); @@ -428,8 +427,8 @@ mod test { ts1.mips[0].query(&(2..3), |&v| v), Some(Ok(Unit { // the initial state here is never expected to change - first: Some(TextureUsage::SAMPLED), - last: TextureUsage::COPY_DST, + first: Some(TextureUse::SAMPLED), + last: TextureUse::COPY_DST, })), "wrong final layer 2 state" ); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 249f8c476..2f7c0a928 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -523,18 +523,6 @@ bitflags::bitflags! { const UNIFORM = 64; const STORAGE = 128; const INDIRECT = 256; - const STORAGE_READ = 512; - const NONE = 0; - /// The combination of all read-only usages. - const READ_ALL = Self::MAP_READ.bits | Self::COPY_SRC.bits | - Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits | - Self::STORAGE_READ.bits | Self::INDIRECT.bits; - /// The combination of all write-only and read-write usages. - const WRITE_ALL = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE.bits; - /// The combination of all usages that the are guaranteed to be be ordered by the hardware. - /// If a usage is not ordered, then even if it doesn't change between draw calls, there - /// still need to be pipeline barriers inserted for synchronization. - const ORDERED = Self::READ_ALL.bits; } } @@ -592,16 +580,6 @@ bitflags::bitflags! { const SAMPLED = 4; const STORAGE = 8; const OUTPUT_ATTACHMENT = 16; - const NONE = 0; - /// The combination of all read-only usages. - const READ_ALL = Self::COPY_SRC.bits | Self::SAMPLED.bits; - /// The combination of all write-only and read-write usages. - const WRITE_ALL = Self::COPY_DST.bits | Self::STORAGE.bits | Self::OUTPUT_ATTACHMENT.bits; - /// The combination of all usages that the are guaranteed to be be ordered by the hardware. - /// If a usage is not ordered, then even if it doesn't change between draw calls, there - /// still need to be pipeline barriers inserted for synchronization. - const ORDERED = Self::READ_ALL.bits | Self::OUTPUT_ATTACHMENT.bits; - const UNINITIALIZED = 0xFFFF; } }