diff --git a/ffi/wgpu.h b/ffi/wgpu.h index 774ebf719..375221640 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -2,7 +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/. */ -/* Generated with cbindgen:0.13.1 */ +/* Generated with cbindgen:0.13.2 */ /* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. * To generate this file: @@ -11,7 +11,10 @@ * 2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate wgpu-remote -o dom/webgpu/ffi/wgpu_ffi_generated.h` */ -#define WGPU_LOCAL +typedef unsigned long long WGPUNonZeroU64; +typedef unsigned long long WGPUOption_AdapterId; +typedef unsigned long long WGPUOption_SurfaceId; +typedef unsigned long long WGPUOption_TextureViewId; #include @@ -19,6 +22,9 @@ #include #include +/** + * Bound uniform/storage buffer offsets must be aligned to this number. + */ #define WGPUBIND_BUFFER_ALIGNMENT 256 #define WGPUDEFAULT_BIND_GROUPS 4 @@ -278,11 +284,11 @@ typedef enum { WGPUVertexFormat_Int4 = 48, } WGPUVertexFormat; -typedef uint64_t WGPUId_Adapter_Dummy; +typedef WGPUNonZeroU64 WGPUId_Adapter_Dummy; typedef WGPUId_Adapter_Dummy WGPUAdapterId; -typedef uint64_t WGPUId_Device_Dummy; +typedef WGPUNonZeroU64 WGPUId_Device_Dummy; typedef WGPUId_Device_Dummy WGPUDeviceId; @@ -299,11 +305,11 @@ typedef struct { WGPULimits limits; } WGPUDeviceDescriptor; -typedef uint64_t WGPUId_BindGroup_Dummy; +typedef WGPUNonZeroU64 WGPUId_BindGroup_Dummy; typedef WGPUId_BindGroup_Dummy WGPUBindGroupId; -typedef uint64_t WGPUId_Buffer_Dummy; +typedef WGPUNonZeroU64 WGPUId_Buffer_Dummy; typedef WGPUId_Buffer_Dummy WGPUBufferId; @@ -313,7 +319,7 @@ typedef void (*WGPUBufferMapReadCallback)(WGPUBufferMapAsyncStatus status, const typedef void (*WGPUBufferMapWriteCallback)(WGPUBufferMapAsyncStatus status, uint8_t *data, uint8_t *userdata); -typedef uint64_t WGPUId_CommandBuffer_Dummy; +typedef WGPUNonZeroU64 WGPUId_CommandBuffer_Dummy; typedef WGPUId_CommandBuffer_Dummy WGPUCommandBufferId; @@ -330,12 +336,10 @@ typedef struct { uint32_t todo; } WGPUComputePassDescriptor; -typedef uint64_t WGPUId_TextureView_Dummy; +typedef WGPUNonZeroU64 WGPUId_TextureView_Dummy; typedef WGPUId_TextureView_Dummy WGPUTextureViewId; -typedef const WGPUTextureViewId *WGPUOptionRef_TextureViewId; - typedef struct { double r; double g; @@ -351,13 +355,13 @@ typedef struct { typedef struct { WGPUTextureViewId attachment; - WGPUOptionRef_TextureViewId resolve_target; + WGPUOption_TextureViewId resolve_target; WGPULoadOp load_op; WGPUStoreOp store_op; WGPUColor clear_color; -} WGPURenderPassColorAttachmentDescriptorBase_TextureViewId__OptionRef_TextureViewId; +} WGPURenderPassColorAttachmentDescriptorBase_TextureViewId; -typedef WGPURenderPassColorAttachmentDescriptorBase_TextureViewId__OptionRef_TextureViewId WGPURenderPassColorAttachmentDescriptor; +typedef WGPURenderPassColorAttachmentDescriptorBase_TextureViewId WGPURenderPassColorAttachmentDescriptor; typedef struct { WGPUTextureViewId attachment; @@ -384,7 +388,7 @@ typedef struct { uint32_t rows_per_image; } WGPUBufferCopyView; -typedef uint64_t WGPUId_Texture_Dummy; +typedef WGPUNonZeroU64 WGPUId_Texture_Dummy; typedef WGPUId_Texture_Dummy WGPUTextureId; @@ -418,15 +422,15 @@ typedef const char *WGPURawString; typedef uint32_t WGPUDynamicOffset; -typedef uint64_t WGPUId_ComputePipeline_Dummy; +typedef WGPUNonZeroU64 WGPUId_ComputePipeline_Dummy; typedef WGPUId_ComputePipeline_Dummy WGPUComputePipelineId; -typedef uint64_t WGPUId_Surface; +typedef WGPUNonZeroU64 WGPUId_Surface; typedef WGPUId_Surface WGPUSurfaceId; -typedef uint64_t WGPUId_BindGroupLayout_Dummy; +typedef WGPUNonZeroU64 WGPUId_BindGroupLayout_Dummy; typedef WGPUId_BindGroupLayout_Dummy WGPUBindGroupLayoutId; @@ -436,7 +440,7 @@ typedef struct { WGPUBufferAddress size; } WGPUBufferBinding; -typedef uint64_t WGPUId_Sampler_Dummy; +typedef WGPUNonZeroU64 WGPUId_Sampler_Dummy; typedef WGPUId_Sampler_Dummy WGPUSamplerId; @@ -525,11 +529,11 @@ typedef struct { const char *label; } WGPUCommandEncoderDescriptor; -typedef uint64_t WGPUId_PipelineLayout_Dummy; +typedef WGPUNonZeroU64 WGPUId_PipelineLayout_Dummy; typedef WGPUId_PipelineLayout_Dummy WGPUPipelineLayoutId; -typedef uint64_t WGPUId_ShaderModule_Dummy; +typedef WGPUNonZeroU64 WGPUId_ShaderModule_Dummy; typedef WGPUId_ShaderModule_Dummy WGPUShaderModuleId; @@ -548,7 +552,7 @@ typedef struct { uintptr_t bind_group_layouts_length; } WGPUPipelineLayoutDescriptor; -typedef uint64_t WGPUId_RenderPipeline_Dummy; +typedef WGPUNonZeroU64 WGPUId_RenderPipeline_Dummy; typedef WGPUId_RenderPipeline_Dummy WGPURenderPipelineId; @@ -655,7 +659,7 @@ typedef struct { WGPUU32Array code; } WGPUShaderModuleDescriptor; -typedef uint64_t WGPUId_SwapChain_Dummy; +typedef WGPUNonZeroU64 WGPUId_SwapChain_Dummy; typedef WGPUId_SwapChain_Dummy WGPUSwapChainId; @@ -691,21 +695,21 @@ typedef WGPUDeviceId WGPUQueueId; typedef WGPURawPass *WGPURenderPassId; -typedef uint64_t WGPUId_RenderBundle_Dummy; +typedef WGPUNonZeroU64 WGPUId_RenderBundle_Dummy; typedef WGPUId_RenderBundle_Dummy WGPURenderBundleId; typedef struct { WGPUPowerPreference power_preference; - WGPUSurfaceId compatible_surface; + WGPUOption_SurfaceId compatible_surface; } WGPURequestAdapterOptions; typedef uint32_t WGPUBackendBit; -typedef void (*WGPURequestAdapterCallback)(WGPUAdapterId id, void *userdata); +typedef void (*WGPURequestAdapterCallback)(WGPUOption_AdapterId id, void *userdata); typedef struct { - WGPUTextureViewId view_id; + WGPUOption_TextureViewId view_id; } WGPUSwapChainOutput; typedef struct { diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index b455fd99e..765aaa256 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -35,7 +35,6 @@ use std::{ slice, thread::ThreadId, }; -use wgt::RenderPassColorAttachmentDescriptorBase; #[derive(Clone, Copy, Debug, peek_poke::PeekCopy, peek_poke::Poke)] @@ -197,14 +196,35 @@ impl CommandBuffer { } } -pub type RawRenderPassColorAttachmentDescriptor = - RenderPassColorAttachmentDescriptorBase; +#[repr(C)] +#[derive(peek_poke::PeekCopy, peek_poke::Poke)] +struct PassComponent { + load_op: wgt::LoadOp, + store_op: wgt::StoreOp, + clear_value: T, +} #[repr(C)] #[derive(peek_poke::PeekCopy, peek_poke::Poke)] -pub struct RawRenderTargets { - pub colors: [RawRenderPassColorAttachmentDescriptor; MAX_COLOR_TARGETS], - pub depth_stencil: RenderPassDepthStencilAttachmentDescriptor, +struct RawRenderPassColorAttachmentDescriptor { + attachment: u64, + resolve_target: u64, + component: PassComponent, +} + +#[repr(C)] +#[derive(peek_poke::PeekCopy, peek_poke::Poke)] +struct RawRenderPassDepthStencilAttachmentDescriptor { + attachment: u64, + depth: PassComponent, + stencil: PassComponent, +} + +#[repr(C)] +#[derive(peek_poke::PeekCopy, peek_poke::Poke)] +struct RawRenderTargets { + colors: [RawRenderPassColorAttachmentDescriptor; MAX_COLOR_TARGETS], + depth_stencil: RawRenderPassDepthStencilAttachmentDescriptor, } impl Global { diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index e6dde232e..735a62731 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -5,8 +5,10 @@ use crate::{ command::{ bind::{Binder, LayoutChange}, + PassComponent, PhantomSlice, RawRenderPassColorAttachmentDescriptor, + RawRenderPassDepthStencilAttachmentDescriptor, RawRenderTargets, }, conv, @@ -52,18 +54,15 @@ use std::{ slice, }; -//Note: this could look better if `cbindgen` wasn't confused by &T used in place of -// a generic parameter, it's not able to manage -pub type OptionRef<'a, T> = Option<&'a T>; -pub type RenderPassColorAttachmentDescriptor<'a> = - RenderPassColorAttachmentDescriptorBase>; +pub type RenderPassColorAttachmentDescriptor = + RenderPassColorAttachmentDescriptorBase; pub type RenderPassDepthStencilAttachmentDescriptor = RenderPassDepthStencilAttachmentDescriptorBase; #[repr(C)] #[derive(Debug)] pub struct RenderPassDescriptor<'a> { - pub color_attachments: *const RenderPassColorAttachmentDescriptor<'a>, + pub color_attachments: *const RenderPassColorAttachmentDescriptor, pub color_attachments_length: usize, pub depth_stencil_attachment: Option<&'a RenderPassDepthStencilAttachmentDescriptor>, } @@ -133,22 +132,35 @@ impl super::RawPass { pub unsafe fn new_render(parent_id: id::CommandEncoderId, desc: &RenderPassDescriptor) -> Self { let mut pass = Self::from_vec(Vec::::with_capacity(1), parent_id); - let mut targets = RawRenderTargets { - depth_stencil: desc.depth_stencil_attachment - .cloned() - .unwrap_or_else(|| mem::zeroed()), - colors: mem::zeroed(), - }; + let mut targets: RawRenderTargets = mem::zeroed(); + if let Some(ds) = desc.depth_stencil_attachment { + targets.depth_stencil = RawRenderPassDepthStencilAttachmentDescriptor { + attachment: ds.attachment.into_raw(), + depth: PassComponent { + load_op: ds.depth_load_op, + store_op: ds.depth_store_op, + clear_value: ds.clear_depth, + }, + stencil: PassComponent { + load_op: ds.stencil_load_op, + store_op: ds.stencil_store_op, + clear_value: ds.clear_stencil, + }, + }; + } + for (color, at) in targets.colors .iter_mut() .zip(slice::from_raw_parts(desc.color_attachments, desc.color_attachments_length)) { *color = RawRenderPassColorAttachmentDescriptor { - attachment: at.attachment, - resolve_target: at.resolve_target.map_or(id::TextureViewId::ERROR, |rt| *rt), - load_op: at.load_op, - store_op: at.store_op, - clear_color: at.clear_color, + attachment: at.attachment.into_raw(), + resolve_target: at.resolve_target.map_or(0, |id| id.into_raw()), + component: PassComponent { + load_op: at.load_op, + store_op: at.store_op, + clear_value: at.clear_color, + }, }; } @@ -321,25 +333,32 @@ impl Global { let color_attachments = targets.colors .iter() - .take_while(|at| at.attachment != id::TextureViewId::ERROR) + .take_while(|at| at.attachment != 0) .map(|at| { RenderPassColorAttachmentDescriptor { - attachment: at.attachment, - resolve_target: if at.resolve_target == id::TextureViewId::ERROR { - None - } else { - Some(&at.resolve_target) - }, - load_op: at.load_op, - store_op: at.store_op, - clear_color: at.clear_color, + attachment: id::TextureViewId::from_raw(at.attachment).unwrap(), + resolve_target: id::TextureViewId::from_raw(at.resolve_target), + load_op: at.component.load_op, + store_op: at.component.store_op, + clear_color: at.component.clear_value, } }) .collect::>(); - let depth_stencil_attachment = if targets.depth_stencil.attachment == id::TextureViewId::ERROR { + let depth_stencil_attachment_body; + let depth_stencil_attachment = if targets.depth_stencil.attachment == 0 { None } else { - Some(&targets.depth_stencil) + let at = &targets.depth_stencil; + depth_stencil_attachment_body = RenderPassDepthStencilAttachmentDescriptor { + attachment: id::TextureViewId::from_raw(at.attachment).unwrap(), + depth_load_op: at.depth.load_op, + depth_store_op: at.depth.store_op, + clear_depth: at.depth.clear_value, + stencil_load_op: at.stencil.load_op, + stencil_store_op: at.stencil.store_op, + clear_stencil: at.stencil.clear_value, + }; + Some(&depth_stencil_attachment_body) }; let (context, sample_count) = { @@ -485,7 +504,7 @@ impl Global { }); } - for &resolve_target in color_attachments + for resolve_target in color_attachments .iter() .flat_map(|at| at.resolve_target) { @@ -642,7 +661,6 @@ impl Global { resolves: color_attachments .iter() .filter_map(|at| at.resolve_target) - .cloned() .collect(), depth_stencil: depth_stencil_attachment.map(|at| at.attachment), }; @@ -774,7 +792,7 @@ impl Global { resolves: color_attachments .iter() .filter_map(|at| at.resolve_target) - .map(|resolve| view_guard[*resolve].format) + .map(|resolve| view_guard[resolve].format) .collect(), depth_stencil: depth_stencil_attachment.map(|at| view_guard[at.attachment].format), }; diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 29bb26450..9c581b9ee 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -103,7 +103,9 @@ pub(crate) type RenderPassKey = AttachmentData; pub(crate) type FramebufferKey = AttachmentData; pub(crate) type RenderPassContext = AttachmentData; -type BufferMapResult = Result<*mut u8, hal::device::MapError>; +// This typedef is needed to work around cbindgen limitations. +type RawBufferMut = *mut u8; +type BufferMapResult = Result; type BufferMapPendingCallback = (resource::BufferMapOperation, BufferMapResult); pub type BufferMapReadCallback = diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 3ecd27d32..a06c77d38 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -6,7 +6,7 @@ use crate::{Epoch, Index}; #[cfg(feature = "serde")] use serde_crate::{Deserialize, Serialize}; use wgt::Backend; -use std::{fmt, marker::PhantomData, mem}; +use std::{fmt, marker::PhantomData, mem, num::NonZeroU64}; const BACKEND_BITS: usize = 3; const EPOCH_MASK: u32 = (1 << (32 - BACKEND_BITS)) - 1; @@ -14,13 +14,11 @@ type Dummy = crate::backend::Empty; #[repr(transparent)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate="serde_crate"))] -pub struct Id(u64, PhantomData); +pub struct Id(NonZeroU64, PhantomData); impl Id { - pub const ERROR: Self = Self(0, PhantomData); - pub fn backend(self) -> Backend { - match self.0 >> (64 - BACKEND_BITS) as u8 { + match self.0.get() >> (64 - BACKEND_BITS) as u8 { 0 => Backend::Empty, 1 => Backend::Vulkan, 2 => Backend::Metal, @@ -30,6 +28,14 @@ impl Id { _ => unreachable!(), } } + + pub(crate) fn into_raw(self) -> u64 { + self.0.get() + } + + pub(crate) fn from_raw(value: u64) -> Option { + NonZeroU64::new(value).map(|nz| Id(nz, PhantomData)) + } } impl Copy for Id {} @@ -65,13 +71,16 @@ unsafe impl peek_poke::Poke for Id { mem::size_of::() } unsafe fn poke_into(&self, data: *mut u8) -> *mut u8 { - self.0.poke_into(data) + self.0.get().poke_into(data) } } impl peek_poke::Peek for Id { - unsafe fn peek_from(&mut self, data: *const u8) -> *const u8 { - self.0.peek_from(data) + unsafe fn peek_from(&mut self, mut data: *const u8) -> *const u8 { + let mut v = 0u64; + data = v.peek_from(data); + self.0 = NonZeroU64::new(v).unwrap(); + data } } @@ -84,13 +93,13 @@ impl TypedId for Id { fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self { assert_eq!(0, epoch >> (32 - BACKEND_BITS)); let v = index as u64 | ((epoch as u64) << 32) | ((backend as u64) << (64 - BACKEND_BITS)); - Id(v, PhantomData) + Id(NonZeroU64::new(v).unwrap(), PhantomData) } fn unzip(self) -> (Index, Epoch, Backend) { ( - self.0 as u32, - (self.0 >> 32) as u32 & EPOCH_MASK, + self.0.get() as u32, + (self.0.get() >> 32) as u32 & EPOCH_MASK, self.backend(), ) } @@ -147,7 +156,7 @@ fn test_id_backend() { Backend::Dx11, Backend::Gl, ] { - let id: Id<()> = Id::zip(0, 0, b); + let id: Id<()> = Id::zip(1, 0, b); assert_eq!(id.backend(), b); } } diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index ea2506b06..51ea99129 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -33,14 +33,14 @@ use hal::{ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate="serde_crate"))] pub struct RequestAdapterOptions { pub power_preference: PowerPreference, - pub compatible_surface: SurfaceId, + pub compatible_surface: Option, } impl Default for RequestAdapterOptions { fn default() -> Self { RequestAdapterOptions { power_preference: PowerPreference::Default, - compatible_surface: SurfaceId::ERROR, + compatible_surface: None, } } } @@ -285,11 +285,7 @@ impl Global { let instance = &self.instance; let mut token = Token::root(); let (surface_guard, mut token) = self.surfaces.read(&mut token); - let compatible_surface = if desc.compatible_surface != SurfaceId::ERROR { - Some(&surface_guard[desc.compatible_surface]) - } else { - None - }; + let compatible_surface = desc.compatible_surface.map(|id| &surface_guard[id]); let mut device_types = Vec::new(); let id_vulkan = inputs.find(Backend::Vulkan); diff --git a/wgpu-core/src/swap_chain.rs b/wgpu-core/src/swap_chain.rs index aca821ece..118b5899a 100644 --- a/wgpu-core/src/swap_chain.rs +++ b/wgpu-core/src/swap_chain.rs @@ -85,7 +85,7 @@ pub(crate) fn swap_chain_descriptor_to_hal( #[repr(C)] #[derive(Debug)] pub struct SwapChainOutput { - pub view_id: TextureViewId, + pub view_id: Option, } #[derive(Debug)] @@ -150,7 +150,7 @@ impl Global { life_guard: LifeGuard::new(), }; let ref_count = view.life_guard.add_ref(); - let view_id = hub + let id = hub .texture_views .register_identity(view_id_in, view, &mut token); @@ -159,11 +159,11 @@ impl Global { "Swap chain image is already acquired" ); sc.acquired_view_id = Some(Stored { - value: view_id, + value: id, ref_count, }); - Ok(SwapChainOutput { view_id }) + Ok(SwapChainOutput { view_id: Some(id) }) } pub fn swap_chain_present(&self, swap_chain_id: SwapChainId) { diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index 6ddcf5994..0b86bb5b4 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -122,7 +122,7 @@ mod test { first: Some(BufferUsage::INDEX), last: BufferUsage::STORAGE, }; - let id = TypedId::zip(0, 0, wgt::Backend::Empty); + let id = TypedId::zip(1, 0, wgt::Backend::Empty); assert!(bs.change(id, (), BufferUsage::VERTEX, None).is_err()); bs.change(id, (), BufferUsage::VERTEX, Some(&mut Vec::new())) .unwrap(); diff --git a/wgpu-native/cbindgen.toml b/wgpu-native/cbindgen.toml index 0d86ceaef..13e85be5f 100644 --- a/wgpu-native/cbindgen.toml +++ b/wgpu-native/cbindgen.toml @@ -8,7 +8,10 @@ autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated usi * 2. Run `rustup run nightly cbindgen toolkit/library/rust/ --lockfile Cargo.lock --crate wgpu-remote -o dom/webgpu/ffi/wgpu_ffi_generated.h` */ -#define WGPU_LOCAL +typedef unsigned long long WGPUNonZeroU64; +typedef unsigned long long WGPUOption_AdapterId; +typedef unsigned long long WGPUOption_SurfaceId; +typedef unsigned long long WGPUOption_TextureViewId; """ include_version = true braces = "SameLine" @@ -19,7 +22,7 @@ language = "C" [export] prefix = "WGPU" #TODO: figure out why cbindgen even tries to export a private type... -exclude = ["BufferMapResult"] +exclude = ["Option_AdapterId", "Option_SurfaceId", "Option_TextureViewId"] [parse] parse_deps = true diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index ff3d2120a..16471f97a 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -13,7 +13,7 @@ use std::{marker::PhantomData, slice}; use objc::{msg_send, runtime::Object, sel, sel_impl}; pub type RequestAdapterCallback = - unsafe extern "C" fn(id: id::AdapterId, userdata: *mut std::ffi::c_void); + unsafe extern "C" fn(id: Option, userdata: *mut std::ffi::c_void); pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> id::SurfaceId { use raw_window_handle::RawWindowHandle as Rwh; @@ -162,10 +162,7 @@ pub unsafe extern "C" fn wgpu_request_adapter_async( &desc.cloned().unwrap_or_default(), core::instance::AdapterInputs::Mask(mask, || PhantomData), ); - callback( - id.unwrap_or(id::AdapterId::ERROR), - userdata, - ); + callback(id, userdata); } #[no_mangle] @@ -415,7 +412,7 @@ pub extern "C" fn wgpu_swap_chain_get_next_texture( ) -> core::swap_chain::SwapChainOutput { gfx_select!(swap_chain_id => GLOBAL.swap_chain_get_next_texture(swap_chain_id, PhantomData)) .unwrap_or(core::swap_chain::SwapChainOutput { - view_id: id::TextureViewId::ERROR, + view_id: None, }) } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 3b003854f..90c65f877 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -637,12 +637,11 @@ pub enum StoreOp { } #[repr(C)] -#[derive(Debug)] +#[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "peek-poke", derive(PeekCopy, Poke))] -pub struct RenderPassColorAttachmentDescriptorBase { +pub struct RenderPassColorAttachmentDescriptorBase { pub attachment: T, - pub resolve_target: R, + pub resolve_target: Option, pub load_op: LoadOp, pub store_op: StoreOp, pub clear_color: Color, @@ -663,7 +662,6 @@ pub struct RenderPassDepthStencilAttachmentDescriptorBase { } #[repr(C)] - #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "peek-poke", derive(PeekCopy, Poke))]