render_pass.rs (4341B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 //! FFI-friendly mirrors of render pass APIs in [`wgc`]. 6 7 use crate::id; 8 9 /// FFI-friendly analogue of [`std::option::Option`]. 10 /// 11 /// In some cases, Rust's standard `Option` type is FFI-friendly, in that `T` and `Option<T>` map 12 /// to the same C++ type. For example, both `&U` and `Option<&U>` can be represented as `U *` in 13 /// C++. 14 /// 15 /// For other types, `Option<T>` may not be FFI-safe. For such cases, this type is a `repr(u8)` 16 /// analog to the standard 17 /// 18 /// See also: <https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimization> 19 #[repr(u8)] 20 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 21 pub enum FfiOption<T> { 22 Some(T), 23 None, 24 } 25 26 impl<T> FfiOption<T> { 27 pub fn to_std(self) -> std::option::Option<T> { 28 match self { 29 Self::Some(value) => Some(value), 30 Self::None => None, 31 } 32 } 33 } 34 35 /// FFI-safe analogue of [`wgc::command::RenderPassColorAttachment`]. 36 #[repr(C)] 37 #[derive(Clone, Debug, PartialEq)] 38 pub struct FfiRenderPassColorAttachment { 39 pub view: id::TextureViewId, 40 pub depth_slice: FfiOption<u32>, 41 pub resolve_target: Option<id::TextureViewId>, 42 pub load_op: wgc::command::LoadOp<wgt::Color>, 43 pub store_op: wgc::command::StoreOp, 44 } 45 46 impl FfiRenderPassColorAttachment { 47 pub(crate) fn to_wgpu(self) -> wgc::command::RenderPassColorAttachment { 48 let Self { 49 view, 50 depth_slice, 51 resolve_target, 52 load_op, 53 store_op, 54 } = self; 55 56 wgc::command::RenderPassColorAttachment { 57 view, 58 depth_slice: depth_slice.to_std(), 59 resolve_target, 60 load_op, 61 store_op, 62 } 63 } 64 } 65 66 /// FFI-safe analogue of [`wgc::command::RenderPassDepthStencilAttachment`]. 67 #[repr(C)] 68 #[derive(Clone, Debug, PartialEq)] 69 pub struct RenderPassDepthStencilAttachment { 70 pub view: id::TextureViewId, 71 pub depth: PassChannel<FfiOption<f32>>, 72 pub stencil: PassChannel<FfiOption<u32>>, 73 } 74 75 impl RenderPassDepthStencilAttachment { 76 pub(crate) fn to_wgpu( 77 self, 78 ) -> wgc::command::RenderPassDepthStencilAttachment<id::TextureViewId> { 79 let Self { 80 view, 81 depth, 82 stencil, 83 } = self; 84 85 wgc::command::RenderPassDepthStencilAttachment { 86 view, 87 depth: depth.to_wgpu().map_clear_value(|opt| opt.to_std()), 88 stencil: stencil.to_wgpu().map_clear_value(|opt| opt.to_std()), 89 } 90 } 91 } 92 93 /// FFI-safe analogue of [`wgc::command::PassChannel`]. 94 #[repr(C)] 95 #[derive(Clone, Debug, PartialEq)] 96 pub struct PassChannel<V> { 97 pub load_op: FfiOption<wgc::command::LoadOp<V>>, 98 pub store_op: FfiOption<wgc::command::StoreOp>, 99 pub read_only: bool, 100 } 101 102 impl<V> PassChannel<V> { 103 pub(crate) fn to_wgpu(self) -> wgc::command::PassChannel<V> { 104 let Self { 105 load_op, 106 store_op, 107 read_only, 108 } = self; 109 110 wgc::command::PassChannel { 111 load_op: load_op.to_std(), 112 store_op: store_op.to_std(), 113 read_only, 114 } 115 } 116 } 117 118 trait MapClearValue<V1, V2> { 119 type Converted; 120 121 fn map_clear_value(self, f: impl FnOnce(V1) -> V2) -> Self::Converted; 122 } 123 124 impl<V1, V2> MapClearValue<V1, V2> for wgc::command::PassChannel<V1> { 125 type Converted = wgc::command::PassChannel<V2>; 126 127 fn map_clear_value(self, f: impl FnOnce(V1) -> V2) -> Self::Converted { 128 let Self { 129 load_op, 130 store_op, 131 read_only, 132 } = self; 133 wgc::command::PassChannel { 134 load_op: load_op.map(|o| o.map_clear_value(f)), 135 store_op, 136 read_only, 137 } 138 } 139 } 140 141 impl<V1, V2> MapClearValue<V1, V2> for wgc::command::LoadOp<V1> { 142 type Converted = wgc::command::LoadOp<V2>; 143 144 fn map_clear_value(self, f: impl FnOnce(V1) -> V2) -> Self::Converted { 145 match self { 146 Self::Clear(value) => wgc::command::LoadOp::Clear(f(value)), 147 Self::Load => wgc::command::LoadOp::Load, 148 Self::DontCare(token) => wgc::command::LoadOp::DontCare(token), 149 } 150 } 151 }