diff --git a/player/src/main.rs b/player/src/main.rs index 658b58ccb6..a2fa2bd4e6 100644 --- a/player/src/main.rs +++ b/player/src/main.rs @@ -228,8 +228,7 @@ impl GlobalExt for wgc::hub::Global { self.device_create_pipeline_layout::( device, &wgc::binding_model::PipelineLayoutDescriptor { - bind_group_layouts: bind_group_layouts.as_ptr(), - bind_group_layouts_length: bind_group_layouts.len(), + bind_group_layouts: &bind_group_layouts, }, id, ) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 9e41ddf559..d7733dd80f 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -229,12 +229,7 @@ pub struct BindGroupLayout { pub(crate) count_validator: BindingTypeMaxCountValidator, } -#[repr(C)] -#[derive(Debug)] -pub struct PipelineLayoutDescriptor { - pub bind_group_layouts: *const BindGroupLayoutId, - pub bind_group_layouts_length: usize, -} +pub type PipelineLayoutDescriptor<'a> = wgt::PipelineLayoutDescriptor<'a, BindGroupLayoutId>; #[derive(Clone, Debug)] pub enum PipelineLayoutError { @@ -260,7 +255,8 @@ pub struct BufferBinding { pub size: Option, } -// Note: Duplicated in wgpu-rs as BindingResource +// Note: Duplicated in `wgpu-rs` as `BindingResource` +// They're different enough that it doesn't make sense to share a common type #[derive(Debug)] pub enum BindingResource<'a> { Buffer(BufferBinding), @@ -269,20 +265,10 @@ pub enum BindingResource<'a> { TextureViewArray(&'a [TextureViewId]), } -// Note: Duplicated in wgpu-rs as Binding -#[derive(Debug)] -pub struct BindGroupEntry<'a> { - pub binding: u32, - pub resource: BindingResource<'a>, -} +pub type BindGroupEntry<'a> = wgt::BindGroupEntry>; -// Note: Duplicated in wgpu-rs as BindGroupDescriptor -#[derive(Debug)] -pub struct BindGroupDescriptor<'a> { - pub label: Option<&'a str>, - pub layout: BindGroupLayoutId, - pub entries: &'a [BindGroupEntry<'a>], -} +pub type BindGroupDescriptor<'a> = + wgt::BindGroupDescriptor<'a, BindGroupLayoutId, BindGroupEntry<'a>>; #[derive(Debug)] pub enum BindError { diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index cb5f6ae173..94475d2956 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -58,11 +58,8 @@ fn is_depth_stencil_read_only( true } -#[derive(Debug)] -pub struct RenderPassDescriptor<'a> { - pub color_attachments: &'a [ColorAttachmentDescriptor], - pub depth_stencil_attachment: Option<&'a DepthStencilAttachmentDescriptor>, -} +pub type RenderPassDescriptor<'a> = + wgt::RenderPassDescriptor<'a, ColorAttachmentDescriptor, &'a DepthStencilAttachmentDescriptor>; #[derive(Clone, Copy, Debug, Default)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 0798cb1a7c..d359c9544d 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -14,7 +14,7 @@ use crate::{ }; use hal::command::CommandBuffer as _; -use wgt::{BufferAddress, BufferUsage, Extent3d, Origin3d, TextureDataLayout, TextureUsage}; +use wgt::{BufferAddress, BufferUsage, Extent3d, TextureDataLayout, TextureUsage}; use std::iter; @@ -22,24 +22,9 @@ type Result = std::result::Result<(), TransferError>; pub(crate) const BITS_PER_BYTE: u32 = 8; -#[repr(C)] -#[derive(Clone, Debug)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] -pub struct BufferCopyView { - pub buffer: BufferId, - pub layout: TextureDataLayout, -} +pub type BufferCopyView = wgt::BufferCopyView; -#[repr(C)] -#[derive(Clone, Debug)] -#[cfg_attr(feature = "trace", derive(serde::Serialize))] -#[cfg_attr(feature = "replay", derive(serde::Deserialize))] -pub struct TextureCopyView { - pub texture: TextureId, - pub mip_level: u32, - pub origin: Origin3d, -} +pub type TextureCopyView = wgt::TextureCopyView; /// Error encountered while attempting a data transfer. #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -75,48 +60,46 @@ pub enum TransferError { MismatchedAspects, } -impl TextureCopyView { - //TODO: we currently access each texture twice for a transfer, - // once only to get the aspect flags, which is unfortunate. - pub(crate) fn to_hal( - &self, - texture_guard: &Storage, TextureId>, - ) -> ( - hal::image::SubresourceLayers, - hal::image::SubresourceRange, - hal::image::Offset, - ) { - let texture = &texture_guard[self.texture]; - let aspects = texture.full_range.aspects; - let level = self.mip_level as hal::image::Level; - let (layer, z) = match texture.dimension { - wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { - (self.origin.z as hal::image::Layer, 0) - } - wgt::TextureDimension::D3 => (0, self.origin.z as i32), - }; +//TODO: we currently access each texture twice for a transfer, +// once only to get the aspect flags, which is unfortunate. +pub(crate) fn texture_copy_view_to_hal( + view: &TextureCopyView, + texture_guard: &Storage, TextureId>, +) -> ( + hal::image::SubresourceLayers, + hal::image::SubresourceRange, + hal::image::Offset, +) { + let texture = &texture_guard[view.texture]; + let aspects = texture.full_range.aspects; + let level = view.mip_level as hal::image::Level; + let (layer, z) = match texture.dimension { + wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { + (view.origin.z as hal::image::Layer, 0) + } + wgt::TextureDimension::D3 => (0, view.origin.z as i32), + }; - // TODO: Can't satisfy clippy here unless we modify - // `hal::image::SubresourceRange` in gfx to use `std::ops::RangeBounds`. - #[allow(clippy::range_plus_one)] - ( - hal::image::SubresourceLayers { - aspects, - level: self.mip_level as hal::image::Level, - layers: layer..layer + 1, - }, - hal::image::SubresourceRange { - aspects, - levels: level..level + 1, - layers: layer..layer + 1, - }, - hal::image::Offset { - x: self.origin.x as i32, - y: self.origin.y as i32, - z, - }, - ) - } + // TODO: Can't satisfy clippy here unless we modify + // `hal::image::SubresourceRange` in gfx to use `std::ops::RangeBounds`. + #[allow(clippy::range_plus_one)] + ( + hal::image::SubresourceLayers { + aspects, + level: view.mip_level as hal::image::Level, + layers: layer..layer + 1, + }, + hal::image::SubresourceRange { + aspects, + levels: level..level + 1, + layers: layer..layer + 1, + }, + hal::image::Offset { + x: view.origin.x as i32, + y: view.origin.y as i32, + z, + }, + ) } /// Function copied with minor modifications from webgpu standard https://gpuweb.github.io/gpuweb/#valid-texture-copy-range @@ -337,7 +320,8 @@ impl Global { let cmb = &mut cmb_guard[command_encoder_id]; let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token); - let (dst_layers, dst_range, dst_offset) = destination.to_hal(&*texture_guard); + let (dst_layers, dst_range, dst_offset) = + texture_copy_view_to_hal(destination, &*texture_guard); #[cfg(feature = "trace")] match cmb.commands { @@ -437,7 +421,7 @@ impl Global { let cmb = &mut cmb_guard[command_encoder_id]; let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token); - let (src_layers, src_range, src_offset) = source.to_hal(&*texture_guard); + let (src_layers, src_range, src_offset) = texture_copy_view_to_hal(source, &*texture_guard); #[cfg(feature = "trace")] match cmb.commands { @@ -541,8 +525,9 @@ impl Global { // we can't hold both src_pending and dst_pending in scope because they // borrow the buffer tracker mutably... let mut barriers = Vec::new(); - let (src_layers, src_range, src_offset) = source.to_hal(&*texture_guard); - let (dst_layers, dst_range, dst_offset) = destination.to_hal(&*texture_guard); + let (src_layers, src_range, src_offset) = texture_copy_view_to_hal(source, &*texture_guard); + let (dst_layers, dst_range, dst_offset) = + texture_copy_view_to_hal(destination, &*texture_guard); if src_layers.aspects != dst_layers.aspects { return Err(TransferError::MismatchedAspects); } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index cf5cf96a5a..4ea92fbc3b 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -24,8 +24,10 @@ use hal::{ use parking_lot::{Mutex, MutexGuard}; use wgt::{BufferAddress, BufferSize, InputStepMode, TextureDimension, TextureFormat}; +#[cfg(feature = "trace")] +use std::slice; use std::{ - collections::hash_map::Entry, ffi, iter, marker::PhantomData, mem, ops::Range, ptr, slice, + collections::hash_map::Entry, ffi, iter, marker::PhantomData, mem, ops::Range, ptr, sync::atomic::Ordering, }; @@ -1357,13 +1359,11 @@ impl Global { let (device_guard, mut token) = hub.devices.read(&mut token); let device = &device_guard[device_id]; - let bind_group_layout_ids = unsafe { - slice::from_raw_parts(desc.bind_group_layouts, desc.bind_group_layouts_length) - }; + let bind_group_layout_ids = desc.bind_group_layouts; - if desc.bind_group_layouts_length > (device.limits.max_bind_groups as usize) { + if bind_group_layout_ids.len() > (device.limits.max_bind_groups as usize) { return Err(binding_model::PipelineLayoutError::TooManyGroups( - desc.bind_group_layouts_length, + bind_group_layout_ids.len(), )); } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 6f998db859..0785db771a 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -248,7 +248,8 @@ impl Global { let (mut device_guard, mut token) = hub.devices.write(&mut token); let device = &mut device_guard[queue_id]; let (texture_guard, _) = hub.textures.read(&mut token); - let (image_layers, image_range, image_offset) = destination.to_hal(&*texture_guard); + let (image_layers, image_range, image_offset) = + crate::command::texture_copy_view_to_hal(destination, &*texture_guard); #[cfg(feature = "trace")] match device.trace { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 04b683807c..ce859cd48f 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -25,23 +25,7 @@ use hal::{ }; use std::fmt::Display; -#[repr(C)] -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] -pub struct RequestAdapterOptions { - pub power_preference: PowerPreference, - pub compatible_surface: Option, -} - -impl Default for RequestAdapterOptions { - fn default() -> Self { - RequestAdapterOptions { - power_preference: PowerPreference::Default, - compatible_surface: None, - } - } -} +pub type RequestAdapterOptions = wgt::RequestAdapterOptions; #[derive(Debug)] pub struct Instance { diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 6e5e414361..75113cbda6 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -9,10 +9,7 @@ use crate::{ LifeGuard, RefCount, Stored, }; use std::borrow::Borrow; -use wgt::{ - BufferAddress, ColorStateDescriptor, DepthStencilStateDescriptor, IndexFormat, InputStepMode, - PrimitiveTopology, RasterizationStateDescriptor, VertexStateDescriptor, -}; +use wgt::{BufferAddress, IndexFormat, InputStepMode}; #[repr(C)] #[derive(Debug)] @@ -29,18 +26,10 @@ pub struct ShaderModule { pub(crate) module: Option, } -#[derive(Debug)] -pub struct ProgrammableStageDescriptor<'a> { - pub module: ShaderModuleId, - pub entry_point: &'a str, -} +pub type ProgrammableStageDescriptor<'a> = wgt::ProgrammableStageDescriptor<'a, ShaderModuleId>; -#[repr(C)] -#[derive(Debug)] -pub struct ComputePipelineDescriptor<'a> { - pub layout: PipelineLayoutId, - pub compute_stage: ProgrammableStageDescriptor<'a>, -} +pub type ComputePipelineDescriptor<'a> = + wgt::ComputePipelineDescriptor>; #[derive(Clone, Debug)] pub enum ComputePipelineError { @@ -61,20 +50,8 @@ impl Borrow for ComputePipeline { } } -#[derive(Debug)] -pub struct RenderPipelineDescriptor<'a> { - pub layout: PipelineLayoutId, - pub vertex_stage: ProgrammableStageDescriptor<'a>, - pub fragment_stage: Option>, - pub primitive_topology: PrimitiveTopology, - pub rasterization_state: Option, - pub color_states: &'a [ColorStateDescriptor], - pub depth_stencil_state: Option, - pub vertex_state: VertexStateDescriptor<'a>, - pub sample_count: u32, - pub sample_mask: u32, - pub alpha_to_coverage_enabled: bool, -} +pub type RenderPipelineDescriptor<'a> = + wgt::RenderPipelineDescriptor<'a, PipelineLayoutId, ProgrammableStageDescriptor<'a>>; #[derive(Clone, Debug)] pub enum RenderPipelineError { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index de6506b8a0..c8711a9d7a 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -101,6 +101,19 @@ impl From for BackendBit { } } +/// Options for requesting adapter. +#[repr(C)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "trace", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct RequestAdapterOptions { + /// Power preference for the adapter. + pub power_preference: PowerPreference, + /// Surface that is required to be presentable with the requested adapter. This does not + /// create the surface, only guarantees that the adapter can present to said surface. + pub compatible_surface: Option, +} + bitflags::bitflags! { /// Features that are not guaranteed to be supported. /// @@ -1132,6 +1145,15 @@ pub struct RenderPassDepthStencilAttachmentDescriptorBase { pub stencil: PassChannel, } +/// Describes the attachments of a render pass. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct RenderPassDescriptor<'a, C, D> { + /// The color attachments of the render pass. + pub color_attachments: &'a [C], + /// The depth and stencil attachment of the render pass, if any. + pub depth_stencil_attachment: Option, +} + /// RGBA double precision color. /// /// This is not to be used as a generic color type, only for specific wgpu interfaces. @@ -1443,6 +1465,90 @@ impl SamplerDescriptor { } } +/// Bindable resource and the slot to bind it to. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct BindGroupEntry { + /// 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: R, +} + +/// Describes a group of bindings and the resources to be bound. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct BindGroupDescriptor<'a, L, B> { + /// Debug label of the bind group. This will show up in graphics debuggers for easy identification. + pub label: Option<&'a str>, + /// The [`BindGroupLayout`] that corresponds to this bind group. + pub layout: L, + /// The resources to bind to this bind group. + pub entries: &'a [B], +} + +/// Describes a pipeline layout. +/// +/// A `PipelineLayoutDescriptor` can be used to create a pipeline layout. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct PipelineLayoutDescriptor<'a, B> { + /// 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: &'a [B], +} + +/// Describes a programmable pipeline stage. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ProgrammableStageDescriptor<'a, M> { + /// The compiled shader module for this stage. + pub module: M, + /// The name of the entry point in the compiled shader. There must be a function that returns + /// void with this name in the shader. + pub entry_point: &'a str, +} + +/// Describes a render (graphics) pipeline. +#[derive(Clone, Debug)] +pub struct RenderPipelineDescriptor<'a, L, D> { + /// The layout of bind groups for this pipeline. + pub layout: L, + /// The compiled vertex stage and its entry point. + pub vertex_stage: D, + /// The compiled fragment stage and its entry point, if any. + pub fragment_stage: Option, + /// The rasterization process for this pipeline. + pub rasterization_state: Option, + /// The primitive topology used to interpret vertices. + pub primitive_topology: PrimitiveTopology, + /// The effect of draw calls on the color aspect of the output target. + pub color_states: &'a [ColorStateDescriptor], + /// The effect of draw calls on the depth and stencil aspects of the output target, if any. + pub depth_stencil_state: Option, + /// The vertex input state for this pipeline. + pub vertex_state: VertexStateDescriptor<'a>, + /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures, + /// this should be `1` + pub sample_count: u32, + /// Bitmask that restricts the samples of a pixel modified by this pipeline. All samples + /// can be enabled using the value `!0` + pub sample_mask: u32, + /// When enabled, produces another sample mask per pixel based on the alpha output value, that + /// is ANDed with the sample_mask and the primitive coverage to restrict the set of samples + /// affected by a primitive. + /// + /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one + /// is guaranteed to be all 1-s. + pub alpha_to_coverage_enabled: bool, +} + +/// Describes a compute pipeline. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ComputePipelineDescriptor { + /// The layout of bind groups for this pipeline. + pub layout: L, + /// The compiled compute stage and its entry point. + pub compute_stage: D, +} + /// Describes a [`CommandBuffer`]. #[repr(C)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] @@ -1729,3 +1835,27 @@ pub struct BindGroupLayoutDescriptor<'a> { /// Array of entries in this BindGroupLayout pub entries: &'a [BindGroupLayoutEntry], } + +/// View of a buffer which can be used to copy to/from a texture. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct BufferCopyView { + /// The buffer to be copied to/from. + pub buffer: B, + /// The layout of the texture data in this buffer. + pub layout: TextureDataLayout, +} + +/// View of a texture which can be used to copy to/from a buffer/texture. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "trace", derive(serde::Serialize))] +#[cfg_attr(feature = "replay", derive(serde::Deserialize))] +pub struct TextureCopyView { + /// The texture to be copied to/from. + pub texture: T, + /// The target mip level of the texture. + pub mip_level: u32, + /// The base texel of the texture in the selected `mip_level`. + pub origin: Origin3d, +}