546: NonZero internal Id representation r=grovesNL a=kvark

Fixes  #544
Based on #545 
Blocked by https://github.com/eqrion/cbindgen/issues/500

Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot] 2020-04-04 23:43:53 +00:00 committed by GitHub
commit 902a0ebca3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 149 additions and 102 deletions

View File

@ -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 <stdarg.h>
@ -19,6 +22,9 @@
#include <stdint.h>
#include <stdlib.h>
/**
* 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 {

View File

@ -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<B: GfxBackend> CommandBuffer<B> {
}
}
pub type RawRenderPassColorAttachmentDescriptor =
RenderPassColorAttachmentDescriptorBase<id::TextureViewId, id::TextureViewId>;
#[repr(C)]
#[derive(peek_poke::PeekCopy, peek_poke::Poke)]
struct PassComponent<T> {
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<wgt::Color>,
}
#[repr(C)]
#[derive(peek_poke::PeekCopy, peek_poke::Poke)]
struct RawRenderPassDepthStencilAttachmentDescriptor {
attachment: u64,
depth: PassComponent<f32>,
stencil: PassComponent<u32>,
}
#[repr(C)]
#[derive(peek_poke::PeekCopy, peek_poke::Poke)]
struct RawRenderTargets {
colors: [RawRenderPassColorAttachmentDescriptor; MAX_COLOR_TARGETS],
depth_stencil: RawRenderPassDepthStencilAttachmentDescriptor,
}
impl<G: GlobalIdentityHandlerFactory> Global<G> {

View File

@ -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<id::TextureViewId, OptionRef<'a, id::TextureViewId>>;
pub type RenderPassColorAttachmentDescriptor =
RenderPassColorAttachmentDescriptorBase<id::TextureViewId>;
pub type RenderPassDepthStencilAttachmentDescriptor =
RenderPassDepthStencilAttachmentDescriptorBase<id::TextureViewId>;
#[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::<RenderCommand>::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<G: GlobalIdentityHandlerFactory> Global<G> {
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::<ArrayVec<[_; MAX_COLOR_TARGETS]>>();
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<G: GlobalIdentityHandlerFactory> Global<G> {
});
}
for &resolve_target in color_attachments
for resolve_target in color_attachments
.iter()
.flat_map(|at| at.resolve_target)
{
@ -642,7 +661,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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),
};

View File

@ -103,7 +103,9 @@ pub(crate) type RenderPassKey = AttachmentData<hal::pass::Attachment>;
pub(crate) type FramebufferKey = AttachmentData<id::TextureViewId>;
pub(crate) type RenderPassContext = AttachmentData<TextureFormat>;
type BufferMapResult = Result<*mut u8, hal::device::MapError>;
// This typedef is needed to work around cbindgen limitations.
type RawBufferMut = *mut u8;
type BufferMapResult = Result<RawBufferMut, hal::device::MapError>;
type BufferMapPendingCallback = (resource::BufferMapOperation, BufferMapResult);
pub type BufferMapReadCallback =

View File

@ -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<T>(u64, PhantomData<T>);
pub struct Id<T>(NonZeroU64, PhantomData<T>);
impl<T> Id<T> {
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<T> Id<T> {
_ => unreachable!(),
}
}
pub(crate) fn into_raw(self) -> u64 {
self.0.get()
}
pub(crate) fn from_raw(value: u64) -> Option<Self> {
NonZeroU64::new(value).map(|nz| Id(nz, PhantomData))
}
}
impl<T> Copy for Id<T> {}
@ -65,13 +71,16 @@ unsafe impl<T> peek_poke::Poke for Id<T> {
mem::size_of::<u64>()
}
unsafe fn poke_into(&self, data: *mut u8) -> *mut u8 {
self.0.poke_into(data)
self.0.get().poke_into(data)
}
}
impl<T> peek_poke::Peek for Id<T> {
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<T> TypedId for Id<T> {
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);
}
}

View File

@ -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<SurfaceId>,
}
impl Default for RequestAdapterOptions {
fn default() -> Self {
RequestAdapterOptions {
power_preference: PowerPreference::Default,
compatible_surface: SurfaceId::ERROR,
compatible_surface: None,
}
}
}
@ -285,11 +285,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
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);

View File

@ -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<TextureViewId>,
}
#[derive(Debug)]
@ -150,7 +150,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
"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<B: GfxBackend>(&self, swap_chain_id: SwapChainId) {

View File

@ -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();

View File

@ -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

View File

@ -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<id::AdapterId>, 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,
})
}

View File

@ -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<T, R> {
pub struct RenderPassColorAttachmentDescriptorBase<T> {
pub attachment: T,
pub resolve_target: R,
pub resolve_target: Option<T>,
pub load_op: LoadOp,
pub store_op: StoreOp,
pub clear_color: Color,
@ -663,7 +662,6 @@ pub struct RenderPassDepthStencilAttachmentDescriptorBase<T> {
}
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "peek-poke", derive(PeekCopy, Poke))]