Skip to main content

bedrock/
shading.rs

1//! Vulkan Shading(Shader/Pipeline)
2use bedrock_vk::{self as brvk, TypedVulkanStructure, VkRawHandle};
3
4use crate::ffi_helper::slice_as_ptr_empty_null;
5use crate::*;
6use core::{
7    ffi::{CStr, c_void},
8    marker::PhantomData,
9    ops::*,
10};
11use derives::{bitflags_newtype, implements};
12
13#[repr(u32)]
14#[derive(Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, Hash)]
15pub enum ShaderStage {
16    Vertex = brvk::VK_SHADER_STAGE_VERTEX_BIT,
17    TessellationControl = brvk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
18    TessellationEvaluation = brvk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
19    Geometry = brvk::VK_SHADER_STAGE_GEOMETRY_BIT,
20    Fragment = brvk::VK_SHADER_STAGE_FRAGMENT_BIT,
21    Compute = brvk::VK_SHADER_STAGE_COMPUTE_BIT,
22}
23
24/// Stencil comparison function
25#[repr(i32)]
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27pub enum CompareOp {
28    /// The test never passes
29    Never = brvk::VK_COMPARE_OP_NEVER,
30    /// The test passes when `Ref < Stencil`
31    Less = brvk::VK_COMPARE_OP_LESS,
32    /// The test passes when `Ref == Stencil`
33    Equal = brvk::VK_COMPARE_OP_EQUAL,
34    /// The test passes when `Ref <= Stencil`
35    LessOrEqual = brvk::VK_COMPARE_OP_LESS_OR_EQUAL,
36    /// The test passes when `Ref > Stencil`
37    Greater = brvk::VK_COMPARE_OP_GREATER,
38    /// The test passes when `Ref != Stencil`
39    NotEqual = brvk::VK_COMPARE_OP_NOT_EQUAL,
40    /// The test passes when `Ref >= Stencil`
41    GreaterOrEqual = brvk::VK_COMPARE_OP_GREATER_OR_EQUAL,
42    /// The test always passes
43    Always = brvk::VK_COMPARE_OP_ALWAYS,
44}
45
46/// Stencil action function
47#[repr(i32)]
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub enum StencilOp {
50    /// Keeps the current value
51    Keep = brvk::VK_STENCIL_OP_KEEP,
52    /// Sets the value to 0
53    Zero = brvk::VK_STENCIL_OP_ZERO,
54    /// Sets the value to `reference`
55    Replace = brvk::VK_STENCIL_OP_REPLACE,
56    /// Increments the current value and clamps to the maximum representable unsigned value
57    IncrementClamp = brvk::VK_STENCIL_OP_INCREMENT_AND_CLAMP,
58    /// Decrements the current value and clamps to 0
59    DecrementClamp = brvk::VK_STENCIL_OP_DECREMENT_AND_CLAMP,
60    /// Bitwise-inverts the current value
61    Invert = brvk::VK_STENCIL_OP_INVERT,
62    /// Increments the current value and wraps to 0 when the maximum value would have been exceeded
63    IncrementWrap = brvk::VK_STENCIL_OP_INCREMENT_AND_WRAP,
64    /// Decrements the current value and wraps to the maximum possible value when the value would go below 0
65    DecrementWrap = brvk::VK_STENCIL_OP_DECREMENT_AND_WRAP,
66}
67
68/// Framebuffer logical operations
69#[repr(i32)]
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub enum LogicOp {
72    /// 0
73    Clear = brvk::VK_LOGIC_OP_CLEAR,
74    /// source & dest
75    And = brvk::VK_LOGIC_OP_AND,
76    /// source & ~dest
77    AndReverse = brvk::VK_LOGIC_OP_AND_REVERSE,
78    /// source
79    Copy = brvk::VK_LOGIC_OP_COPY,
80    /// ~source & dest
81    AndInverted = brvk::VK_LOGIC_OP_AND_INVERTED,
82    /// dest
83    NoOp = brvk::VK_LOGIC_OP_NO_OP,
84    /// source ^ dest
85    Xor = brvk::VK_LOGIC_OP_XOR,
86    /// source | dest
87    Or = brvk::VK_LOGIC_OP_OR,
88    /// ~(source | dest)
89    Nor = brvk::VK_LOGIC_OP_NOR,
90    /// ~(source ^ dest)
91    Equivalent = brvk::VK_LOGIC_OP_EQUIVALENT,
92    /// ~dest
93    Invert = brvk::VK_LOGIC_OP_INVERT,
94    /// source | ~dest
95    OrReverse = brvk::VK_LOGIC_OP_OR_REVERSE,
96    /// ~source
97    CopyInverted = brvk::VK_LOGIC_OP_COPY_INVERTED,
98    /// ~source | dest
99    OrInverted = brvk::VK_LOGIC_OP_OR_INVERTED,
100    /// ~(source & dest)
101    Nand = brvk::VK_LOGIC_OP_NAND,
102    /// 1
103    Set = brvk::VK_LOGIC_OP_SET,
104}
105
106/// Bitmask specifying sets of stencil state for which to update the compare mask
107#[repr(u32)]
108#[derive(Debug, Clone, PartialEq, Eq, Copy)]
109pub enum StencilFaceMask {
110    /// Only the front set of stencil state
111    Front = brvk::VK_STENCIL_FACE_FRONT_BIT,
112    /// Only the back set of stencil state
113    Back = brvk::VK_STENCIL_FACE_BACK_BIT,
114    /// Both sets of stencil state
115    Both = brvk::VK_STENCIL_FACE_FRONT_AND_BACK,
116}
117
118#[repr(transparent)]
119pub struct StencilOpState(pub brvk::VkStencilOpState);
120impl StencilOpState {
121    pub const NOP: Self = Self::always_forall(StencilOp::Keep);
122
123    pub const fn always(pass: StencilOp, fail: StencilOp, depth_fail: StencilOp) -> Self {
124        Self(brvk::VkStencilOpState {
125            passOp: pass as _,
126            failOp: fail as _,
127            depthFailOp: depth_fail as _,
128            compareOp: CompareOp::Always as _,
129            compareMask: 0,
130            writeMask: 0,
131            reference: 0,
132        })
133    }
134
135    pub const fn always_forall(op: StencilOp) -> Self {
136        Self::always(op, op, op)
137    }
138
139    pub const fn write_mask(mut self, mask: u32) -> Self {
140        self.0.writeMask = mask;
141        self
142    }
143
144    pub const fn set_compare(mut self, op: CompareOp, reference: u32, mask: u32) -> Self {
145        self.0.compareOp = op as _;
146        self.0.reference = reference;
147        self.0.compareMask = mask;
148        self
149    }
150
151    pub const fn always_pass(mut self) -> Self {
152        self.0.compareOp = CompareOp::Always as _;
153        self
154    }
155}
156
157#[repr(transparent)]
158#[derive(Clone)]
159pub struct ShaderModuleCreateInfo<'d>(brvk::VkShaderModuleCreateInfo, core::marker::PhantomData<&'d [u32]>);
160impl<'d> ShaderModuleCreateInfo<'d> {
161    pub const fn new(code: &'d [u32]) -> Self {
162        Self(
163            brvk::VkShaderModuleCreateInfo {
164                sType: brvk::VkShaderModuleCreateInfo::TYPE,
165                pNext: core::ptr::null(),
166                flags: 0,
167                // Note: ここはbyte単位
168                codeSize: code.len() << 2,
169                pCode: slice_as_ptr_empty_null(code),
170            },
171            core::marker::PhantomData,
172        )
173    }
174
175    /// # Safety
176    ///
177    /// `raw` must have a valid [`brvk::VkShaderModuleCreateInfo`] struct.
178    pub const unsafe fn from_raw(raw: brvk::VkShaderModuleCreateInfo) -> Self {
179        Self(raw, core::marker::PhantomData)
180    }
181
182    pub const fn into_raw(self) -> brvk::VkShaderModuleCreateInfo {
183        self.0
184    }
185}
186
187/// Opaque handle to a shader module object
188#[derive(VkHandle, VkObject)]
189#[VkObject(type = brvk::VkShaderModule::OBJECT_TYPE)]
190pub struct ShaderModuleObject<Device: VkHandle<Handle = brvk::VkDevice>>(brvk::VkShaderModule, Device);
191#[implements]
192impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for ShaderModuleObject<Device> {
193    #[inline(always)]
194    fn drop(&mut self) {
195        unsafe {
196            crate::vkfn_wrapper::destroy_shader_module(
197                self.1.as_transparent_ref(),
198                VkHandleRefMut::dangling(self.0),
199                None,
200            );
201        }
202    }
203}
204unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for ShaderModuleObject<Device> {}
205unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for ShaderModuleObject<Device> {}
206impl<Device: VkHandle<Handle = brvk::VkDevice>> ShaderModule for ShaderModuleObject<Device> {}
207impl<Device: VkHandle<Handle = brvk::VkDevice>> ShaderModuleObject<Device> {
208    /// Constructs from raw values
209    /// # Safety
210    /// the resource must be created from the device and not freed anywhere
211    pub const unsafe fn manage(handle: brvk::VkShaderModule, parent: Device) -> Self {
212        Self(handle, parent)
213    }
214
215    /// Purges the construct (Drop will not be called for this resource)
216    pub const fn unmanage(self) -> (brvk::VkShaderModule, Device) {
217        let h = self.0;
218        let p = unsafe { core::ptr::read(&self.1) };
219        core::mem::forget(self);
220
221        (h, p)
222    }
223}
224impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> ShaderModuleObject<&'_ Device> {
225    /// Owning parent object by cloning it.
226    #[inline(always)]
227    pub fn clone_parent(self) -> ShaderModuleObject<Device> {
228        let r = ShaderModuleObject(self.0, self.1.clone());
229        core::mem::forget(self);
230
231        r
232    }
233}
234impl<Device: crate::Device> ShaderModuleObject<Device> {
235    /// Creates a new shader module object
236    /// # Failures
237    /// On failure, this command returns
238    ///
239    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
240    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
241    /// * [`brvk::VK_ERROR_INVALID_SHADER_NV`]
242    #[implements]
243    #[inline]
244    pub fn new(device: Device, info: &ShaderModuleCreateInfo) -> crate::Result<Self> {
245        Ok(unsafe {
246            Self::manage(
247                crate::vkfn_wrapper::create_shader_module(device.as_transparent_ref(), info, None)?,
248                device,
249            )
250        })
251    }
252}
253
254pub trait ShaderModule: VkHandle<Handle = brvk::VkShaderModule> {
255    /// Constructs a new [`PipelineShaderStage`] data.
256    #[inline(always)]
257    fn on_stage<'m, 's>(&'m self, stage: ShaderStage, entry_point: &'m CStr) -> PipelineShaderStage<'m, 's> {
258        PipelineShaderStage::new(stage, self, entry_point)
259    }
260}
261DerefContainerBracketImpl!(for ShaderModule {});
262GuardsImpl!(for ShaderModule {});
263
264#[repr(transparent)]
265#[derive(Clone)]
266pub struct PipelineCacheCreateInfo<'d>(brvk::VkPipelineCacheCreateInfo, core::marker::PhantomData<&'d [u8]>);
267impl<'d> PipelineCacheCreateInfo<'d> {
268    pub const fn new(initial_data: &'d [u8]) -> Self {
269        Self(
270            brvk::VkPipelineCacheCreateInfo {
271                sType: brvk::VkPipelineCacheCreateInfo::TYPE,
272                pNext: core::ptr::null(),
273                flags: 0,
274                initialDataSize: initial_data.len() as _,
275                pInitialData: slice_as_ptr_empty_null(initial_data) as _,
276            },
277            core::marker::PhantomData,
278        )
279    }
280
281    /// # Safety
282    ///
283    /// `raw` must have a valid [`brvk::VkPipelineCacheCreateInfo`] struct.
284    pub const unsafe fn from_raw(raw: brvk::VkPipelineCacheCreateInfo) -> Self {
285        Self(raw, core::marker::PhantomData)
286    }
287
288    pub const fn into_raw(self) -> brvk::VkPipelineCacheCreateInfo {
289        self.0
290    }
291}
292
293/// Opaque handle to a pipeline cache object
294#[derive(VkHandle, VkObject)]
295#[VkObject(type = brvk::VkPipelineCache::OBJECT_TYPE)]
296pub struct PipelineCacheObject<Device: VkHandle<Handle = brvk::VkDevice>>(brvk::VkPipelineCache, Device);
297#[implements]
298impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for PipelineCacheObject<Device> {
299    #[inline(always)]
300    fn drop(&mut self) {
301        unsafe {
302            crate::vkfn_wrapper::destroy_pipeline_cache(
303                self.1.as_transparent_ref(),
304                VkHandleRefMut::dangling(self.0),
305                None,
306            );
307        }
308    }
309}
310unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for PipelineCacheObject<Device> {}
311unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for PipelineCacheObject<Device> {}
312impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for PipelineCacheObject<Device> {
313    #[inline(always)]
314    fn device_handle(&self) -> brvk::VkDevice {
315        self.1.native_ptr()
316    }
317}
318impl<Device: VkHandle<Handle = brvk::VkDevice>> PipelineCache for PipelineCacheObject<Device> {}
319impl<Device: VkHandle<Handle = brvk::VkDevice>> PipelineCacheMut for PipelineCacheObject<Device> {}
320impl<Device: VkHandle<Handle = brvk::VkDevice>> PipelineCacheObject<Device> {
321    /// Constructs from raw values
322    /// # Safety
323    /// the resource must be created from the device and not freed anywhere
324    pub const unsafe fn manage(handle: brvk::VkPipelineCache, parent: Device) -> Self {
325        Self(handle, parent)
326    }
327
328    /// Purges the construct (Drop will not be called for this resource)
329    pub const fn unmanage(self) -> (brvk::VkPipelineCache, Device) {
330        let h = self.0;
331        let p = unsafe { core::ptr::read(&self.1) };
332        core::mem::forget(self);
333
334        (h, p)
335    }
336}
337impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> PipelineCacheObject<&'_ Device> {
338    /// Owning parent object by cloning it.
339    #[inline(always)]
340    pub fn clone_parent(self) -> PipelineCacheObject<Device> {
341        let r = PipelineCacheObject(self.0, self.1.clone());
342        core::mem::forget(self);
343
344        r
345    }
346}
347impl<Device: crate::Device> PipelineCacheObject<Device> {
348    /// Create a new pipeline cache
349    /// # Failures
350    /// On failure, this command returns
351    ///
352    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
353    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
354    #[implements]
355    pub fn new(device: Device, create_info: &PipelineCacheCreateInfo) -> crate::Result<Self> {
356        Ok(unsafe {
357            Self::manage(
358                crate::vkfn_wrapper::create_pipeline_cache(device.as_transparent_ref(), create_info, None)?,
359                device,
360            )
361        })
362    }
363}
364
365pub trait PipelineCache: VkHandle<Handle = brvk::VkPipelineCache> + DeviceChildHandle {
366    /// Get the size of the data store from a pipeline cache
367    /// # Failures
368    /// On failure, this command returns
369    ///
370    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
371    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
372    #[implements]
373    #[inline(always)]
374    fn data_len(&self) -> crate::Result<usize> {
375        unsafe {
376            crate::vkfn_wrapper::get_pipeline_cache_data_byte_length(
377                self.device_transparent_ref(),
378                self.as_transparent_ref(),
379            )
380        }
381    }
382
383    /// Get the content of the data store from a pipeline cache
384    /// # Failures
385    /// On failure, this command returns
386    ///
387    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
388    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
389    #[implements]
390    #[inline(always)]
391    fn data_into(&self, store: &mut [core::mem::MaybeUninit<u8>]) -> crate::Result<ArrayQueryResult<usize>> {
392        unsafe {
393            crate::vkfn_wrapper::get_pipeline_cache_data(
394                self.device_transparent_ref(),
395                self.as_transparent_ref(),
396                store,
397            )
398        }
399    }
400}
401DerefContainerBracketImpl!(for PipelineCache {});
402GuardsImpl!(for PipelineCache {});
403
404pub trait PipelineCacheMut: PipelineCache + VkHandleMut {
405    /// Combine the data stores of pipeline caches into `self`
406    /// # Failures
407    /// On failure, this command returns
408    ///
409    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
410    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
411    #[implements]
412    #[inline]
413    fn merge(&mut self, srcs: &[VkHandleRef<brvk::VkPipelineCache>]) -> crate::Result<()> {
414        crate::error::translate_vk_result(unsafe {
415            brvk::fns::merge_pipeline_caches(
416                self.device_handle(),
417                self.native_ptr_mut(),
418                srcs.len() as _,
419                slice_as_ptr_empty_null(srcs).cast(),
420            )
421        })?;
422        Ok(())
423    }
424}
425DerefContainerBracketImpl!(for mut PipelineCacheMut {});
426GuardsImpl!(for mut PipelineCacheMut {});
427
428#[repr(transparent)]
429#[derive(Clone)]
430pub struct PipelineLayoutCreateInfo<'d>(
431    brvk::VkPipelineLayoutCreateInfo,
432    core::marker::PhantomData<(
433        &'d dyn VkHandle<Handle = brvk::VkDescriptorSetLayout>,
434        &'d [PushConstantRange],
435    )>,
436);
437impl<'d> PipelineLayoutCreateInfo<'d> {
438    pub const fn new(
439        descriptor_set_layouts: &'d [VkHandleRef<'d, brvk::VkDescriptorSetLayout>],
440        push_constant_ranges: &'d [PushConstantRange],
441    ) -> Self {
442        Self(
443            brvk::VkPipelineLayoutCreateInfo {
444                sType: brvk::VkPipelineLayoutCreateInfo::TYPE,
445                pNext: core::ptr::null(),
446                flags: 0,
447                setLayoutCount: descriptor_set_layouts.len() as _,
448                pSetLayouts: slice_as_ptr_empty_null(descriptor_set_layouts) as _,
449                pushConstantRangeCount: push_constant_ranges.len() as _,
450                pPushConstantRanges: slice_as_ptr_empty_null(push_constant_ranges).cast(),
451            },
452            core::marker::PhantomData,
453        )
454    }
455
456    /// # Safety
457    ///
458    /// `raw` must have a valid [`brvk::VkPipelineLayoutCreateInfo`] struct.
459    pub const unsafe fn from_raw(raw: brvk::VkPipelineLayoutCreateInfo) -> Self {
460        Self(raw, core::marker::PhantomData)
461    }
462
463    pub const fn into_raw(self) -> brvk::VkPipelineLayoutCreateInfo {
464        self.0
465    }
466}
467
468/// Opaque handle to a pipeline layout object
469#[derive(VkHandle, VkObject)]
470#[VkObject(type = brvk::VkPipelineLayout::OBJECT_TYPE)]
471pub struct PipelineLayoutObject<Device: VkHandle<Handle = brvk::VkDevice>>(brvk::VkPipelineLayout, Device);
472#[implements]
473impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for PipelineLayoutObject<Device> {
474    #[inline(always)]
475    fn drop(&mut self) {
476        unsafe {
477            crate::vkfn_wrapper::destroy_pipeline_layout(
478                self.1.as_transparent_ref(),
479                VkHandleRefMut::dangling(self.0),
480                None,
481            );
482        }
483    }
484}
485unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for PipelineLayoutObject<Device> {}
486unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for PipelineLayoutObject<Device> {}
487impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for PipelineLayoutObject<Device> {
488    #[inline]
489    fn device_handle(&self) -> brvk::VkDevice {
490        self.1.native_ptr()
491    }
492}
493impl<Device: crate::Device> DeviceChild for PipelineLayoutObject<Device> {
494    type ConcreteDevice = Device;
495
496    #[inline]
497    fn device(&self) -> &Self::ConcreteDevice {
498        &self.1
499    }
500}
501impl<Device: VkHandle<Handle = brvk::VkDevice>> PipelineLayout for PipelineLayoutObject<Device> {}
502impl<Device: VkHandle<Handle = brvk::VkDevice>> PipelineLayoutObject<Device> {
503    /// Constructs from raw values
504    /// # Safety
505    /// the resource must be created from the device and not freed anywhere
506    pub const unsafe fn manage(handle: brvk::VkPipelineLayout, parent: Device) -> Self {
507        Self(handle, parent)
508    }
509
510    /// Purges the construct (Drop will not be called for this resource)
511    pub const fn unmanage(self) -> (brvk::VkPipelineLayout, Device) {
512        let r = unsafe { (self.0, core::ptr::read(&self.1)) };
513        core::mem::forget(self);
514
515        r
516    }
517}
518impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> PipelineLayoutObject<&'_ Device> {
519    /// Owning parent object by cloning it.
520    #[inline(always)]
521    pub fn clone_parent(self) -> PipelineLayoutObject<Device> {
522        let r = PipelineLayoutObject(self.0, self.1.clone());
523        core::mem::forget(self);
524
525        r
526    }
527}
528impl<Device: crate::Device> PipelineLayoutObject<Device> {
529    /// Creates a new pipeline layout object
530    /// # Failures
531    /// On failure, this command returns
532    ///
533    /// * [`brvk::VK_ERROR_OUT_OF_HOST_MEMORY`]
534    /// * [`brvk::VK_ERROR_OUT_OF_DEVICE_MEMORY`]
535    #[implements]
536    #[inline]
537    pub fn new(device: Device, info: &PipelineLayoutCreateInfo) -> crate::Result<Self> {
538        Ok(unsafe { Self::manage(device.new_pipeline_layout_raw(info, None)?, device) })
539    }
540}
541
542#[repr(transparent)]
543pub struct PushConstantRange(pub brvk::VkPushConstantRange);
544impl PushConstantRange {
545    pub const fn new(shader_stage: brvk::VkShaderStageFlags, byte_range: Range<u32>) -> Self {
546        Self(brvk::VkPushConstantRange {
547            stageFlags: shader_stage,
548            offset: byte_range.start,
549            size: byte_range.end - byte_range.start,
550        })
551    }
552
553    pub const fn for_type<T>(shader_stage: brvk::VkShaderStageFlags, offset: u32) -> Self {
554        Self(brvk::VkPushConstantRange {
555            stageFlags: shader_stage,
556            offset,
557            size: core::mem::size_of::<T>() as _,
558        })
559    }
560}
561
562pub trait PipelineLayout: VkHandle<Handle = brvk::VkPipelineLayout> {}
563DerefContainerBracketImpl!(for PipelineLayout {});
564GuardsImpl!(for PipelineLayout {});
565
566/// Opaque handle to a pipeline object
567#[derive(VkHandle, VkObject)]
568#[VkObject(type = brvk::VkPipeline::OBJECT_TYPE)]
569pub struct PipelineObject<Device: VkHandle<Handle = brvk::VkDevice>>(brvk::VkPipeline, Device);
570#[implements]
571impl<Device: VkHandle<Handle = brvk::VkDevice>> Drop for PipelineObject<Device> {
572    #[inline(always)]
573    fn drop(&mut self) {
574        unsafe {
575            crate::vkfn_wrapper::destroy_pipeline(self.1.as_transparent_ref(), VkHandleRefMut::dangling(self.0), None);
576        }
577    }
578}
579unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Sync> Sync for PipelineObject<Device> {}
580unsafe impl<Device: VkHandle<Handle = brvk::VkDevice> + Send> Send for PipelineObject<Device> {}
581impl<Device: VkHandle<Handle = brvk::VkDevice>> DeviceChildHandle for PipelineObject<Device> {
582    #[inline]
583    fn device_handle(&self) -> brvk::VkDevice {
584        self.1.native_ptr()
585    }
586}
587impl<Device: crate::Device> DeviceChild for PipelineObject<Device> {
588    type ConcreteDevice = Device;
589
590    #[inline]
591    fn device(&self) -> &Self::ConcreteDevice {
592        &self.1
593    }
594}
595impl<Device: VkHandle<Handle = brvk::VkDevice>> Pipeline for PipelineObject<Device> {}
596impl<Device: VkHandle<Handle = brvk::VkDevice>> PipelineObject<Device> {
597    /// Constructs from raw values
598    /// # Safety
599    /// the resource must be created from the device and not freed anywhere
600    pub const unsafe fn manage(handle: brvk::VkPipeline, parent: Device) -> Self {
601        Self(handle, parent)
602    }
603
604    /// Purges the construct (Drop will not be called for this resource)
605    pub const fn unmanage(self) -> (brvk::VkPipeline, Device) {
606        let r = unsafe { (self.0, core::ptr::read(&self.1)) };
607        core::mem::forget(self);
608
609        r
610    }
611}
612impl<Device: VkHandle<Handle = brvk::VkDevice> + Clone> PipelineObject<&'_ Device> {
613    /// Owning parent object by cloning it.
614    #[inline(always)]
615    pub fn clone_parent(self) -> PipelineObject<Device> {
616        let r = PipelineObject(self.0, self.1.clone());
617        core::mem::forget(self);
618
619        r
620    }
621}
622
623pub trait Pipeline: VkHandle<Handle = brvk::VkPipeline> {}
624DerefContainerBracketImpl!(for Pipeline {});
625GuardsImpl!(for Pipeline {});
626
627/// Structure specifying parameters of a newly created pipeline dynamic state
628#[repr(transparent)]
629#[derive(Clone)]
630pub struct PipelineDynamicStateCreateInfo<'d>(
631    brvk::VkPipelineDynamicStateCreateInfo,
632    core::marker::PhantomData<&'d [brvk::VkDynamicState]>,
633);
634impl<'d> PipelineDynamicStateCreateInfo<'d> {
635    pub const fn new(states: &'d [brvk::VkDynamicState]) -> Self {
636        Self(
637            brvk::VkPipelineDynamicStateCreateInfo {
638                sType: brvk::VkPipelineDynamicStateCreateInfo::TYPE,
639                pNext: core::ptr::null(),
640                flags: 0,
641                dynamicStateCount: states.len() as _,
642                pDynamicStates: slice_as_ptr_empty_null(states),
643            },
644            core::marker::PhantomData,
645        )
646    }
647
648    /// # Safety
649    ///
650    /// `raw` must have a valid [`brvk::VkPipelineDynamicStateCreateInfo`] struct.
651    pub const unsafe fn from_raw(raw: brvk::VkPipelineDynamicStateCreateInfo) -> Self {
652        Self(raw, core::marker::PhantomData)
653    }
654
655    pub const fn into_raw(self) -> brvk::VkPipelineDynamicStateCreateInfo {
656        self.0
657    }
658}
659
660#[repr(transparent)]
661#[derive(Clone)]
662pub struct PipelineShaderStage<'d, 's>(
663    pub(crate) brvk::VkPipelineShaderStageCreateInfo,
664    #[allow(clippy::type_complexity)]
665    core::marker::PhantomData<(
666        Option<&'d dyn brvk::VulkanStructure>,
667        &'d dyn VkHandle<Handle = brvk::VkShaderModule>,
668        &'d core::ffi::CStr,
669        Option<&'s SpecializationInfo<'d>>,
670    )>,
671);
672impl<'d, 's> PipelineShaderStage<'d, 's> {
673    #[inline(always)]
674    pub fn new(
675        stage: ShaderStage,
676        shader: &'d (impl VkHandle<Handle = brvk::VkShaderModule> + ?Sized),
677        entrypoint_name: &'d core::ffi::CStr,
678    ) -> Self {
679        Self(
680            brvk::VkPipelineShaderStageCreateInfo {
681                sType: brvk::VkPipelineShaderStageCreateInfo::TYPE,
682                pNext: core::ptr::null(),
683                flags: 0,
684                stage: stage as _,
685                module: Some(shader.native_ptr()),
686                pName: entrypoint_name.as_ptr(),
687                pSpecializationInfo: core::ptr::null(),
688            },
689            core::marker::PhantomData,
690        )
691    }
692
693    /// # Safety
694    ///
695    /// `raw` must have a valid [`brvk::VkPipelineShaderStageCreateInfo`] struct.
696    pub const unsafe fn from_raw(raw: brvk::VkPipelineShaderStageCreateInfo) -> Self {
697        Self(raw, core::marker::PhantomData)
698    }
699
700    pub const fn into_raw(self) -> brvk::VkPipelineShaderStageCreateInfo {
701        self.0
702    }
703
704    #[inline(always)]
705    pub fn with_next(mut self, next: &'d (impl brvk::TypedVulkanStructure + ?Sized)) -> Self {
706        self.0.pNext = next.as_generic() as *const _ as _;
707        self
708    }
709
710    pub const fn with_specialization_info(mut self, info: &'s SpecializationInfo<'d>) -> Self {
711        self.0.pSpecializationInfo = info as *const _ as _;
712        self
713    }
714}
715
716/// A trait for types that can be used as specialization constants.
717///
718/// # Safety
719///
720/// `ENTRIES` must be represent an content of this structs.
721pub unsafe trait SpecializationConstants {
722    const ENTRIES: &'static [SpecializationMapEntry];
723
724    fn as_ptr(&self) -> *const c_void;
725}
726DerefContainerBracketImpl!(unsafe for SpecializationConstants {
727    const ENTRIES: &'static [SpecializationMapEntry] = T::ENTRIES;
728
729    #[inline(always)]
730    fn as_ptr(&self) -> *const c_void {
731        T::as_ptr(self)
732    }
733});
734
735#[repr(transparent)]
736pub struct SpecializationMapEntry(pub brvk::VkSpecializationMapEntry);
737impl SpecializationMapEntry {
738    pub const fn for_byte_range(constant_id: u32, byte_range: core::ops::Range<u32>) -> Self {
739        Self(brvk::VkSpecializationMapEntry {
740            constantID: constant_id,
741            offset: byte_range.start,
742            size: (byte_range.end - byte_range.start) as _,
743        })
744    }
745
746    pub const fn for_type<T>(constant_id: u32, offset: u32) -> Self {
747        Self(brvk::VkSpecializationMapEntry {
748            constantID: constant_id,
749            offset,
750            size: core::mem::size_of::<T>(),
751        })
752    }
753}
754
755#[repr(transparent)]
756#[derive(Clone)]
757pub struct SpecializationInfo<'d>(
758    brvk::VkSpecializationInfo,
759    core::marker::PhantomData<(&'d [brvk::VkSpecializationMapEntry], &'d dyn core::any::Any)>,
760);
761impl<'d> SpecializationInfo<'d> {
762    pub fn new<T: 'd + SpecializationConstants>(data: &'d T) -> Self {
763        Self(
764            brvk::VkSpecializationInfo {
765                mapEntryCount: T::ENTRIES.len() as _,
766                pMapEntries: slice_as_ptr_empty_null(T::ENTRIES).cast(),
767                dataSize: core::mem::size_of::<T>() as _,
768                pData: data.as_ptr(),
769            },
770            core::marker::PhantomData,
771        )
772    }
773
774    /// # Safety
775    /// `data` must have enough size.
776    pub const unsafe fn from_any_type<T: 'd>(entries: &'d [SpecializationMapEntry], data: &'d T) -> Self {
777        Self(
778            brvk::VkSpecializationInfo {
779                mapEntryCount: entries.len() as _,
780                pMapEntries: slice_as_ptr_empty_null(entries).cast(),
781                dataSize: core::mem::size_of::<T>() as _,
782                pData: data as *const _ as _,
783            },
784            core::marker::PhantomData,
785        )
786    }
787
788    /// # Safety
789    /// `data` must have enough size.
790    pub const unsafe fn from_binary(entries: &'d [SpecializationMapEntry], data: &'d [u8]) -> Self {
791        Self(
792            brvk::VkSpecializationInfo {
793                mapEntryCount: entries.len() as _,
794                pMapEntries: slice_as_ptr_empty_null(entries).cast(),
795                dataSize: data.len() as _,
796                pData: data.as_ptr() as _,
797            },
798            core::marker::PhantomData,
799        )
800    }
801
802    /// # Safety
803    ///
804    /// `raw` must have a valid [`brvk::VkSpecializationInfo`] struct.
805    pub const unsafe fn from_raw(raw: brvk::VkSpecializationInfo) -> Self {
806        Self(raw, core::marker::PhantomData)
807    }
808
809    pub const fn into_raw(self) -> brvk::VkSpecializationInfo {
810        self.0
811    }
812}
813
814#[repr(transparent)]
815#[derive(Debug, Clone)]
816pub struct VertexInputBindingDescription(pub brvk::VkVertexInputBindingDescription);
817impl VertexInputBindingDescription {
818    /// Consumed per vertex with stride
819    pub const fn per_vertex(binding: u32, stride: u32) -> Self {
820        Self(brvk::VkVertexInputBindingDescription {
821            binding,
822            stride,
823            inputRate: brvk::VK_VERTEX_INPUT_RATE_VERTEX,
824        })
825    }
826
827    /// Consumed per instance with stride
828    pub const fn per_instance(binding: u32, stride: u32) -> Self {
829        Self(brvk::VkVertexInputBindingDescription {
830            binding,
831            stride,
832            inputRate: brvk::VK_VERTEX_INPUT_RATE_INSTANCE,
833        })
834    }
835
836    /// Consumed per vertex the structured data
837    pub const fn per_vertex_typed<T>(binding: u32) -> Self {
838        Self::per_vertex(binding, core::mem::size_of::<T>() as _)
839    }
840
841    /// Consumed per instance the structured data
842    pub const fn per_instance_typed<T>(binding: u32) -> Self {
843        Self::per_instance(binding, core::mem::size_of::<T>() as _)
844    }
845}
846
847#[repr(transparent)]
848#[derive(Debug, Clone)]
849pub struct VertexInputAttributeDescription(pub brvk::VkVertexInputAttributeDescription);
850
851/// Structure specifying parameters of a newly created pipeline vertex input state
852#[repr(transparent)]
853#[derive(Clone)]
854pub struct PipelineVertexInputStateCreateInfo<'d>(
855    brvk::VkPipelineVertexInputStateCreateInfo,
856    core::marker::PhantomData<(
857        &'d [VertexInputBindingDescription],
858        &'d [VertexInputAttributeDescription],
859    )>,
860);
861impl<'d> PipelineVertexInputStateCreateInfo<'d> {
862    pub const fn new(
863        bindings: &'d [VertexInputBindingDescription],
864        attributes: &'d [VertexInputAttributeDescription],
865    ) -> Self {
866        Self(
867            brvk::VkPipelineVertexInputStateCreateInfo {
868                sType: brvk::VkPipelineVertexInputStateCreateInfo::TYPE,
869                pNext: core::ptr::null(),
870                flags: 0,
871                vertexBindingDescriptionCount: bindings.len() as _,
872                pVertexBindingDescriptions: slice_as_ptr_empty_null(bindings).cast(),
873                vertexAttributeDescriptionCount: attributes.len() as _,
874                pVertexAttributeDescriptions: slice_as_ptr_empty_null(attributes).cast(),
875            },
876            core::marker::PhantomData,
877        )
878    }
879
880    /// # Safety
881    ///
882    /// `raw` must have a valid [`brvk::VkPipelineVertexInputStateCreateInfo`] struct.
883    pub const unsafe fn from_raw(raw: brvk::VkPipelineVertexInputStateCreateInfo) -> Self {
884        Self(raw, core::marker::PhantomData)
885    }
886
887    pub const fn into_raw(self) -> brvk::VkPipelineVertexInputStateCreateInfo {
888        self.0
889    }
890}
891
892/// Supported primitive topologies
893#[repr(i32)]
894#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
895pub enum PrimitiveTopology {
896    /// A series of [separate point primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-point-lists)
897    PointList = brvk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
898    /// A series of [separate line primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-line-lists)
899    LineList = brvk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
900    /// A series of [connected line primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-line-strips)
901    /// with consecutive lines sharing a vertex
902    LineStrip = brvk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
903    /// A series of [separate triangle primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-triangle-lists)
904    TriangleList = brvk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
905    /// A series of [connected triangle primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-triangle-strips)
906    /// with consecutive triangles sharing an edge
907    TriangleStrip = brvk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
908    /// A series of [connected triangle primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-triangle-strips)
909    /// with all triangles sharing a common vertex
910    TriangleFan = brvk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
911    /// A series of [separate line primitives with adjacency](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-line-lists-with-adjacency)
912    LineListWithAdjacency = brvk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
913    /// A series of [connected line primitives with adjacency](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-line-strips-with-adjacency)
914    /// with consecutive primitives sharing three vertices
915    LineStripWithAdjacency = brvk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
916    /// A series of [separate triangle primitives with adjacency](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-triangle-lists-with-adjacency)
917    TriangleListWithAdjacency = brvk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
918    /// [Connected triangle primitives with adjacency](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-triangle-strips-with-adjacency)
919    /// with consecutive triangles sharing an edge
920    TriangleStripWithAdjacency = brvk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
921    /// [Separate patch primitives](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#drawing-patch-lists)
922    PatchList = brvk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
923}
924
925/// Structure specifying parameters of a newly created pipeline input assembly state
926#[repr(transparent)]
927#[derive(Clone)]
928pub struct PipelineInputAssemblyStateCreateInfo(brvk::VkPipelineInputAssemblyStateCreateInfo);
929impl PipelineInputAssemblyStateCreateInfo {
930    pub const fn new(topology: PrimitiveTopology) -> Self {
931        Self(brvk::VkPipelineInputAssemblyStateCreateInfo {
932            sType: brvk::VkPipelineInputAssemblyStateCreateInfo::TYPE,
933            pNext: core::ptr::null(),
934            flags: 0,
935            topology: topology as _,
936            primitiveRestartEnable: false as _,
937        })
938    }
939
940    /// # Safety
941    ///
942    /// `raw` must have a valid [`brvk::VkPipelineInputAssemblyStateCreateInfo`] struct.
943    pub const unsafe fn from_raw(raw: brvk::VkPipelineInputAssemblyStateCreateInfo) -> Self {
944        Self(raw)
945    }
946
947    pub const fn into_raw(self) -> brvk::VkPipelineInputAssemblyStateCreateInfo {
948        self.0
949    }
950
951    pub const fn enable_primitive_restart(mut self) -> Self {
952        self.0.primitiveRestartEnable = true as _;
953        self
954    }
955}
956
957/// Structure specifying parameters of a newly created pipeline tessellation state
958#[repr(transparent)]
959#[derive(Clone)]
960pub struct PipelineTessellationStateCreateInfo(brvk::VkPipelineTessellationStateCreateInfo);
961impl PipelineTessellationStateCreateInfo {
962    pub const fn new(patch_control_points: u32) -> Self {
963        Self(brvk::VkPipelineTessellationStateCreateInfo {
964            sType: brvk::VkPipelineTessellationStateCreateInfo::TYPE,
965            pNext: core::ptr::null(),
966            flags: 0,
967            patchControlPoints: patch_control_points,
968        })
969    }
970
971    /// # Safety
972    ///
973    /// `raw` must have a valid [`brvk::VkPipelineTessellationStateCreateInfo`] struct.
974    pub const unsafe fn from_raw(raw: brvk::VkPipelineTessellationStateCreateInfo) -> Self {
975        Self(raw)
976    }
977
978    pub const fn into_raw(self) -> brvk::VkPipelineTessellationStateCreateInfo {
979        self.0
980    }
981}
982
983/// Structure specifying parameters of a newly created pipeline viewport state
984#[repr(transparent)]
985#[derive(Clone)]
986pub struct PipelineViewportStateCreateInfo<'d>(
987    brvk::VkPipelineViewportStateCreateInfo,
988    core::marker::PhantomData<(&'d [brvk::VkViewport], &'d [brvk::VkRect2D])>,
989);
990impl<'d> PipelineViewportStateCreateInfo<'d> {
991    /// # Safety
992    ///
993    /// `viewports` and `scissors` must have same length.
994    pub const unsafe fn new_unchecked(viewports: &'d [brvk::VkViewport], scissors: &'d [brvk::VkRect2D]) -> Self {
995        Self(
996            brvk::VkPipelineViewportStateCreateInfo {
997                sType: brvk::VkPipelineViewportStateCreateInfo::TYPE,
998                pNext: core::ptr::null(),
999                flags: 0,
1000                viewportCount: viewports.len() as _,
1001                pViewports: slice_as_ptr_empty_null(viewports),
1002                scissorCount: scissors.len() as _,
1003                pScissors: slice_as_ptr_empty_null(scissors),
1004            },
1005            core::marker::PhantomData,
1006        )
1007    }
1008
1009    #[inline]
1010    pub fn new(viewports: &'d [brvk::VkViewport], scissors: &'d [brvk::VkRect2D]) -> Self {
1011        assert_eq!(viewports.len(), scissors.len());
1012
1013        unsafe { Self::new_unchecked(viewports, scissors) }
1014    }
1015
1016    pub const fn new_array<const N: usize>(
1017        viewports: &'d [brvk::VkViewport; N],
1018        scissors: &'d [brvk::VkRect2D; N],
1019    ) -> Self {
1020        // checked that both length are identitcal by const generic parameter
1021        unsafe { Self::new_unchecked(viewports, scissors) }
1022    }
1023
1024    pub const fn new_dynamic(count: u32) -> Self {
1025        Self(
1026            brvk::VkPipelineViewportStateCreateInfo {
1027                sType: brvk::VkPipelineViewportStateCreateInfo::TYPE,
1028                pNext: core::ptr::null(),
1029                flags: 0,
1030                viewportCount: count,
1031                pViewports: core::ptr::null(),
1032                scissorCount: count,
1033                pScissors: core::ptr::null(),
1034            },
1035            core::marker::PhantomData,
1036        )
1037    }
1038
1039    pub const fn new_dynamic_with_count() -> Self {
1040        Self::new_dynamic(0)
1041    }
1042
1043    /// # Safety
1044    ///
1045    /// `raw` must have a valid [`brvk::VkPipelineViewportStateCreateInfo`] struct.
1046    pub const unsafe fn from_raw(raw: brvk::VkPipelineViewportStateCreateInfo) -> Self {
1047        Self(raw, core::marker::PhantomData)
1048    }
1049
1050    pub const fn into_raw(self) -> brvk::VkPipelineViewportStateCreateInfo {
1051        self.0
1052    }
1053}
1054
1055#[repr(i32)]
1056#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1057pub enum PolygonMode {
1058    Fill = brvk::VK_POLYGON_MODE_FILL,
1059    Line = brvk::VK_POLYGON_MODE_LINE,
1060    Point = brvk::VK_POLYGON_MODE_POINT,
1061}
1062
1063#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1064#[bitflags_newtype]
1065pub struct CullModeFlags(brvk::VkCullModeFlags);
1066impl CullModeFlags {
1067    pub const NONE: Self = Self(brvk::VK_CULL_MODE_NONE);
1068    pub const FRONT: Self = Self(brvk::VK_CULL_MODE_FRONT_BIT);
1069    pub const BACK: Self = Self(brvk::VK_CULL_MODE_BACK_BIT);
1070    pub const FRONT_AND_BACK: Self = Self(brvk::VK_CULL_MODE_FRONT_AND_BACK);
1071}
1072
1073#[repr(i32)]
1074#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1075pub enum FrontFace {
1076    Clockwise = brvk::VK_FRONT_FACE_CLOCKWISE,
1077    CounterClockwise = brvk::VK_FRONT_FACE_COUNTER_CLOCKWISE,
1078}
1079
1080/// Structure specifying parameters of a newly created pipeline rasterization state
1081#[repr(transparent)]
1082#[derive(Clone)]
1083pub struct PipelineRasterizationStateCreateInfo<'d>(
1084    brvk::VkPipelineRasterizationStateCreateInfo,
1085    core::marker::PhantomData<Option<&'d dyn brvk::VulkanStructure>>,
1086);
1087impl<'d> PipelineRasterizationStateCreateInfo<'d> {
1088    pub const fn new(polygon_mode: PolygonMode, cull_mode: CullModeFlags, front_face: FrontFace) -> Self {
1089        Self(
1090            brvk::VkPipelineRasterizationStateCreateInfo {
1091                sType: brvk::VkPipelineRasterizationStateCreateInfo::TYPE,
1092                pNext: core::ptr::null(),
1093                flags: 0,
1094                depthClampEnable: false as _,
1095                rasterizerDiscardEnable: false as _,
1096                polygonMode: polygon_mode as _,
1097                cullMode: cull_mode.bits(),
1098                frontFace: front_face as _,
1099                depthBiasEnable: false as _,
1100                depthBiasConstantFactor: 0.0,
1101                depthBiasClamp: 0.0,
1102                depthBiasSlopeFactor: 0.0,
1103                lineWidth: 1.0,
1104            },
1105            core::marker::PhantomData,
1106        )
1107    }
1108
1109    /// # Safety
1110    ///
1111    /// `raw` must have a valid [`brvk::VkPipelineRasterizationStateCreateInfo`] struct.
1112    pub const unsafe fn from_raw(raw: brvk::VkPipelineRasterizationStateCreateInfo) -> Self {
1113        Self(raw, core::marker::PhantomData)
1114    }
1115
1116    pub const fn into_raw(self) -> brvk::VkPipelineRasterizationStateCreateInfo {
1117        self.0
1118    }
1119
1120    #[inline]
1121    pub fn with_next(mut self, next: &'d (impl brvk::VulkanStructure + ?Sized)) -> Self {
1122        self.0.pNext = next as *const _ as _;
1123        self
1124    }
1125
1126    pub const fn enable_depth_clamp(mut self) -> Self {
1127        self.0.depthClampEnable = true as _;
1128        self
1129    }
1130
1131    pub const fn enable_rasterizer_discard(mut self) -> Self {
1132        self.0.rasterizerDiscardEnable = true as _;
1133        self
1134    }
1135
1136    pub const fn enable_depth_bias(mut self, constant_factor: f32, clamp: f32, slope_factor: f32) -> Self {
1137        self.0.depthBiasEnable = true as _;
1138        self.0.depthBiasConstantFactor = constant_factor;
1139        self.0.depthBiasClamp = clamp;
1140        self.0.depthBiasSlopeFactor = slope_factor;
1141        self
1142    }
1143
1144    pub const fn line_width(mut self, w: f32) -> Self {
1145        self.0.lineWidth = w;
1146        self
1147    }
1148}
1149
1150/// Specify the conservative rasterization mode
1151#[cfg(feature = "VK_EXT_conservative_rasterization")]
1152#[repr(i32)]
1153#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1154pub enum ConservativeRasterizationMode {
1155    /// Conservative rasterization is disabled and rasterization proceeds as normal
1156    Disabled = brvk::VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT,
1157    /// Conservative rasterization is enabled in overestimation mode
1158    Overestimate = brvk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,
1159    /// Conservative rasterization is enabled in underestimation mode
1160    Underestimate = brvk::VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,
1161}
1162
1163/// Structure specifying conservative raster state
1164#[cfg(feature = "VK_EXT_conservative_rasterization")]
1165#[repr(transparent)]
1166#[derive(Debug, Clone)]
1167pub struct PipelineRasterizationConservativeStateCreateInfo<'d>(
1168    brvk::VkPipelineRasterizationConservativeStateCreateInfoEXT,
1169    core::marker::PhantomData<Option<&'d dyn brvk::VulkanStructure>>,
1170);
1171#[cfg(feature = "VK_EXT_conservative_rasterization")]
1172unsafe impl brvk::VulkanStructure for PipelineRasterizationConservativeStateCreateInfo<'_> {
1173    #[inline(always)]
1174    fn as_generic(&self) -> &brvk::GenericVulkanStructure {
1175        unsafe { core::mem::transmute(self) }
1176    }
1177
1178    #[inline(always)]
1179    fn as_generic_mut(&mut self) -> &mut brvk::GenericVulkanStructure {
1180        unsafe { core::mem::transmute(self) }
1181    }
1182}
1183#[cfg(feature = "VK_EXT_conservative_rasterization")]
1184impl<'d> PipelineRasterizationConservativeStateCreateInfo<'d> {
1185    pub const fn new(mode: ConservativeRasterizationMode, extra_primitive_overestimation_size: f32) -> Self {
1186        Self(
1187            brvk::VkPipelineRasterizationConservativeStateCreateInfoEXT {
1188                sType: brvk::VkPipelineRasterizationConservativeStateCreateInfoEXT::TYPE,
1189                pNext: core::ptr::null(),
1190                flags: 0,
1191                conservativeRasterizationMode: mode as _,
1192                extraPrimitiveOverestimationSize: extra_primitive_overestimation_size,
1193            },
1194            core::marker::PhantomData,
1195        )
1196    }
1197
1198    pub const unsafe fn from_raw(raw: brvk::VkPipelineRasterizationConservativeStateCreateInfoEXT) -> Self {
1199        Self(raw, core::marker::PhantomData)
1200    }
1201
1202    pub const fn into_raw(self) -> brvk::VkPipelineRasterizationConservativeStateCreateInfoEXT {
1203        self.0
1204    }
1205
1206    #[inline]
1207    pub fn with_next(mut self, next: &'d (impl brvk::VulkanStructure + ?Sized)) -> Self {
1208        self.0.pNext = next as *const _ as _;
1209        self
1210    }
1211}
1212
1213/// Line rasterization modes
1214#[cfg(feature = "VK_KHR_line_rasterization")]
1215#[repr(i32)]
1216#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1217pub enum LineRasterizationMode {
1218    /// Equivalent to [`LineRasterizationMode::Rectangular`] if [`brvk::VkPhysicalDeviceLimits::strictLines`] is true,
1219    /// otherwise lines are drawn as non-`strictLines` parallelograms.
1220    /// Both of these modes are defined in [Basic Line Segment Rasterization](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#primsrast-lines-basic)
1221    Default = brvk::VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR,
1222    /// Lines drawn as if they were rectangles extruded from the line
1223    Rectangular = brvk::VK_LINE_RASTERIZATION_MODE_RECTANGULAR_KHR,
1224    /// Lines drawn by determining which pixel diamonds the line intersects and exits,
1225    /// as defined in [Bresenham Line Segment Rasterization](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#primsrast-lines-bresenham)
1226    Bresenham = brvk::VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR,
1227    /// Lines drawn if they were rectangles extruded from the line, with alpha falloff,
1228    /// as defined in [Smooth Lines](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#primsrast-lines-smooth)
1229    RectangularSmooth = brvk::VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR,
1230}
1231
1232/// Structure specifying parameters of a newly created pipeline line rasterization state
1233#[cfg(feature = "VK_KHR_line_rasterization")]
1234#[repr(transparent)]
1235#[derive(Debug, Clone)]
1236pub struct PipelineRasterizationLineStateCreateInfo<'d>(
1237    brvk::VkPipelineRasterizationLineStateCreateInfoKHR,
1238    core::marker::PhantomData<Option<&'d dyn brvk::VulkanStructure>>,
1239);
1240#[cfg(feature = "VK_KHR_line_rasterization")]
1241unsafe impl brvk::VulkanStructure for PipelineRasterizationLineStateCreateInfo<'_> {
1242    #[inline(always)]
1243    fn as_generic(&self) -> &brvk::GenericVulkanStructure {
1244        unsafe { core::mem::transmute(self) }
1245    }
1246
1247    #[inline(always)]
1248    fn as_generic_mut(&mut self) -> &mut brvk::GenericVulkanStructure {
1249        unsafe { core::mem::transmute(self) }
1250    }
1251}
1252#[cfg(feature = "VK_KHR_line_rasterization")]
1253impl<'d> PipelineRasterizationLineStateCreateInfo<'d> {
1254    pub const fn new(mode: LineRasterizationMode) -> Self {
1255        Self(
1256            brvk::VkPipelineRasterizationLineStateCreateInfoKHR {
1257                sType: brvk::VkPipelineRasterizationLineStateCreateInfoKHR::TYPE,
1258                pNext: core::ptr::null(),
1259                lineRasterizationMode: mode as _,
1260                stippledLineEnable: false as _,
1261                lineStippleFactor: 0,
1262                lineStipplePattern: 0,
1263            },
1264            core::marker::PhantomData,
1265        )
1266    }
1267
1268    /// # Safety
1269    ///
1270    /// `raw` must have a valid [`brvk::VkPipelineRasterizationLineStateCreateInfoKHR`] struct.
1271    pub const unsafe fn from_raw(raw: brvk::VkPipelineRasterizationLineStateCreateInfoKHR) -> Self {
1272        Self(raw, core::marker::PhantomData)
1273    }
1274
1275    pub const fn into_raw(self) -> brvk::VkPipelineRasterizationLineStateCreateInfoKHR {
1276        self.0
1277    }
1278
1279    #[inline]
1280    pub fn with_next(mut self, next: &'d (impl brvk::VulkanStructure + ?Sized)) -> Self {
1281        self.0.pNext = next as *const _ as _;
1282        self
1283    }
1284
1285    pub const fn stippled(mut self, factor: u32, pattern: u16) -> Self {
1286        self.0.stippledLineEnable = true as _;
1287        self.0.lineStippleFactor = factor;
1288        self.0.lineStipplePattern = pattern;
1289        self
1290    }
1291}
1292
1293/// Structure specifying parameters of a newly created pipeline multisample state
1294#[repr(transparent)]
1295#[derive(Clone)]
1296pub struct PipelineMultisampleStateCreateInfo<'d> {
1297    data: brvk::VkPipelineMultisampleStateCreateInfo,
1298    samplemask_lifetime_binder: PhantomData<&'d [brvk::VkSampleMask]>,
1299}
1300impl<'d> PipelineMultisampleStateCreateInfo<'d> {
1301    pub const fn new() -> Self {
1302        Self {
1303            data: brvk::VkPipelineMultisampleStateCreateInfo {
1304                sType: brvk::VkPipelineMultisampleStateCreateInfo::TYPE,
1305                pNext: core::ptr::null(),
1306                flags: 0,
1307                rasterizationSamples: 1,
1308                sampleShadingEnable: brvk::VK_FALSE,
1309                minSampleShading: 1.0,
1310                pSampleMask: core::ptr::null(),
1311                alphaToCoverageEnable: brvk::VK_FALSE,
1312                alphaToOneEnable: brvk::VK_FALSE,
1313            },
1314            samplemask_lifetime_binder: PhantomData,
1315        }
1316    }
1317
1318    /// # Safety
1319    ///
1320    /// `raw` must have a valid [`brvk::VkPipelineMultisampleStateCreateInfo`] struct.
1321    pub const unsafe fn from_raw(raw: brvk::VkPipelineMultisampleStateCreateInfo) -> Self {
1322        Self {
1323            data: raw,
1324            samplemask_lifetime_binder: core::marker::PhantomData,
1325        }
1326    }
1327
1328    pub const fn into_raw(self) -> brvk::VkPipelineMultisampleStateCreateInfo {
1329        self.data
1330    }
1331
1332    /// Specifies the number of samples per pixel used in rasterization. default=1
1333    pub const fn rasterization_samples(mut self, samples: usize) -> Self {
1334        self.data.rasterizationSamples = samples as _;
1335        self
1336    }
1337
1338    /// A bitmask of static coverage information that is ANDed with the coverage information generated
1339    /// during rasterization, as described in [Sample Mask](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#fragops-samplemask).
1340    pub fn sample_mask(mut self, mask: &'d [brvk::VkSampleMask]) -> Self {
1341        if mask.is_empty() {
1342            self.data.pSampleMask = core::ptr::null();
1343            return self;
1344        }
1345
1346        assert_eq!(mask.len(), self.data.rasterizationSamples.div_ceil(32) as _);
1347        self.data.pSampleMask = mask.as_ptr();
1348        self
1349    }
1350
1351    /// Specifies a minimum fraction of sample shading(must be in the range [0, 1]).
1352    /// Pass a `None` to disable [Sample Shading](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#primsrast-sampleshading).
1353    pub const fn sample_shading(mut self, min: f32) -> Self {
1354        assert!(
1355            0.0 <= min && min <= 1.0,
1356            "Invalid usage: brvk::VkPipelineMultisampleStateCreateInfo::minSampleShading must be in the range [0, 1]"
1357        );
1358
1359        self.data.sampleShadingEnable = true as _;
1360        self.data.minSampleShading = min;
1361        self
1362    }
1363
1364    /// Controls whether a temporary coverage value is generated based on the alpha component of the fragment's
1365    /// first color output as specified in the [Multisample Coverage](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#fragops-covg) section.
1366    pub const fn enable_alpha_to_coverage(mut self) -> Self {
1367        self.data.alphaToCoverageEnable = true as _;
1368        self
1369    }
1370
1371    /// Controls whether the alpha component of the fragment's first color output is replaced with one as described in
1372    /// [Multisample Coverage](https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#fragops-covg).
1373    pub const fn replace_alpha_to_one(mut self) -> Self {
1374        self.data.alphaToOneEnable = true as _;
1375        self
1376    }
1377}
1378
1379/// Structure specifying parameters of a newly created pipeline depth stencil state
1380#[repr(transparent)]
1381#[derive(Clone)]
1382pub struct PipelineDepthStencilStateCreateInfo(brvk::VkPipelineDepthStencilStateCreateInfo);
1383impl PipelineDepthStencilStateCreateInfo {
1384    pub const fn new() -> Self {
1385        Self(brvk::VkPipelineDepthStencilStateCreateInfo {
1386            sType: brvk::VkPipelineDepthStencilStateCreateInfo::TYPE,
1387            pNext: core::ptr::null(),
1388            flags: 0,
1389            depthTestEnable: brvk::VK_FALSE,
1390            depthWriteEnable: brvk::VK_FALSE,
1391            depthCompareOp: brvk::VK_COMPARE_OP_LESS,
1392            depthBoundsTestEnable: brvk::VK_FALSE,
1393            stencilTestEnable: brvk::VK_FALSE,
1394            front: brvk::VkStencilOpState {
1395                failOp: brvk::VK_STENCIL_OP_KEEP,
1396                passOp: brvk::VK_STENCIL_OP_KEEP,
1397                depthFailOp: brvk::VK_STENCIL_OP_KEEP,
1398                compareOp: brvk::VK_COMPARE_OP_ALWAYS,
1399                compareMask: 0,
1400                writeMask: 0,
1401                reference: 0,
1402            },
1403            back: brvk::VkStencilOpState {
1404                failOp: brvk::VK_STENCIL_OP_KEEP,
1405                passOp: brvk::VK_STENCIL_OP_KEEP,
1406                depthFailOp: brvk::VK_STENCIL_OP_KEEP,
1407                compareOp: brvk::VK_COMPARE_OP_ALWAYS,
1408                compareMask: 0,
1409                writeMask: 0,
1410                reference: 0,
1411            },
1412            minDepthBounds: 0.0,
1413            maxDepthBounds: 1.0,
1414        })
1415    }
1416
1417    /// # Safety
1418    ///
1419    /// `raw` must have a valid [`brvk::VkPipelineDepthStencilStateCreateInfo`] struct.
1420    pub const unsafe fn from_raw(raw: brvk::VkPipelineDepthStencilStateCreateInfo) -> Self {
1421        Self(raw)
1422    }
1423
1424    pub const fn into_raw(self) -> brvk::VkPipelineDepthStencilStateCreateInfo {
1425        self.0
1426    }
1427
1428    /// Configures depth operation
1429    ///
1430    /// Controls whether depth testing is enabled, depth writes are enabled, and the comparison operator used in the depth test
1431    /// Specifying `None` to `compare_to` disables depth testing
1432    pub const fn config_depth(mut self, compare_op: Option<CompareOp>, write_enable: bool) -> Self {
1433        self.0.depthTestEnable = compare_op.is_some() as _;
1434        self.0.depthCompareOp = match compare_op {
1435            Some(x) => x,
1436            None => CompareOp::Always,
1437        } as _;
1438        self.0.depthWriteEnable = write_enable as _;
1439
1440        self
1441    }
1442
1443    /// Disables depth testing
1444    pub const fn disable_depth_test(mut self) -> Self {
1445        self.0.depthTestEnable = false as _;
1446        self
1447    }
1448
1449    /// Controls whether depth writes are enabled, or always disabled
1450    pub const fn depth_write(mut self, enable: bool) -> Self {
1451        self.0.depthWriteEnable = enable as _;
1452        self
1453    }
1454
1455    /// Sets depth bounds. Specifying `None` to disable depth bounds test
1456    pub const fn depth_bounds(mut self, bounds: Option<core::ops::Range<f32>>) -> Self {
1457        self.0.depthBoundsTestEnable = bounds.is_some() as _;
1458        self.0.minDepthBounds = match bounds {
1459            Some(ref r) => r.start,
1460            None => 0.0,
1461        };
1462        self.0.maxDepthBounds = match bounds {
1463            Some(ref r) => r.end,
1464            None => 0.0,
1465        };
1466
1467        self
1468    }
1469
1470    /// Controls whether stencil testing is enabled
1471    pub const fn stencil_test(mut self, enable: bool) -> Self {
1472        self.0.stencilTestEnable = enable as _;
1473        self
1474    }
1475
1476    /// Sets the state parameters for the front-face stencil test
1477    pub const fn stencil_state_front(mut self, state: StencilOpState) -> Self {
1478        self.0.front = state.0;
1479        self
1480    }
1481
1482    /// Sets the state parameters for the back-face stencil test
1483    pub const fn stencil_state_back(mut self, state: StencilOpState) -> Self {
1484        self.0.back = state.0;
1485        self
1486    }
1487}
1488
1489/// Structure specifying parameters of a newly created pipeline color blend state
1490#[repr(transparent)]
1491#[derive(Clone)]
1492pub struct PipelineColorBlendStateCreateInfo<'d>(
1493    brvk::VkPipelineColorBlendStateCreateInfo,
1494    core::marker::PhantomData<&'d [PipelineColorBlendAttachmentState]>,
1495);
1496impl<'d> PipelineColorBlendStateCreateInfo<'d> {
1497    pub const fn new(attachments: &'d [PipelineColorBlendAttachmentState]) -> Self {
1498        Self(
1499            brvk::VkPipelineColorBlendStateCreateInfo {
1500                sType: brvk::VkPipelineColorBlendStateCreateInfo::TYPE,
1501                pNext: core::ptr::null(),
1502                flags: 0,
1503                logicOpEnable: false as _,
1504                logicOp: LogicOp::NoOp as _,
1505                attachmentCount: attachments.len() as _,
1506                pAttachments: slice_as_ptr_empty_null(attachments).cast(),
1507                blendConstants: [0.0; 4],
1508            },
1509            core::marker::PhantomData,
1510        )
1511    }
1512
1513    /// # Safety
1514    ///
1515    /// `raw` must have a valid [`brvk::VkPipelineColorBlendStateCreateInfo`] struct.
1516    pub const unsafe fn from_raw(raw: brvk::VkPipelineColorBlendStateCreateInfo) -> Self {
1517        Self(raw, core::marker::PhantomData)
1518    }
1519
1520    pub const fn into_raw(self) -> brvk::VkPipelineColorBlendStateCreateInfo {
1521        self.0
1522    }
1523
1524    pub const fn logic_op(mut self, logic_op: LogicOp) -> Self {
1525        self.0.logicOpEnable = true as _;
1526        self.0.logicOp = logic_op as _;
1527        self
1528    }
1529
1530    pub const fn blend_constants(mut self, constants: [f32; 4]) -> Self {
1531        self.0.blendConstants = constants;
1532        self
1533    }
1534}
1535
1536#[repr(transparent)]
1537pub struct PipelineColorBlendAttachmentState(pub brvk::VkPipelineColorBlendAttachmentState);
1538impl PipelineColorBlendAttachmentState {
1539    pub const NOBLEND: Self = Self(brvk::VkPipelineColorBlendAttachmentState {
1540        colorWriteMask: brvk::VK_COLOR_COMPONENT_A_BIT
1541            | brvk::VK_COLOR_COMPONENT_R_BIT
1542            | brvk::VK_COLOR_COMPONENT_G_BIT
1543            | brvk::VK_COLOR_COMPONENT_B_BIT,
1544        blendEnable: brvk::VK_FALSE,
1545        ..unsafe { std::mem::MaybeUninit::zeroed().assume_init() }
1546    });
1547
1548    /// `src * 1 + dst * (1 - src.a)` for both color and alpha.
1549    ///
1550    /// https://stackoverflow.com/questions/18918643/how-to-achieve-d3d-output-with-premultiplied-alpha-for-use-with-d3dimage-in-wpf
1551    pub const PREMULTIPLIED: Self = Self(brvk::VkPipelineColorBlendAttachmentState {
1552        colorWriteMask: brvk::VK_COLOR_COMPONENT_A_BIT
1553            | brvk::VK_COLOR_COMPONENT_R_BIT
1554            | brvk::VK_COLOR_COMPONENT_G_BIT
1555            | brvk::VK_COLOR_COMPONENT_B_BIT,
1556        blendEnable: brvk::VK_TRUE,
1557        srcColorBlendFactor: brvk::VK_BLEND_FACTOR_ONE,
1558        dstColorBlendFactor: brvk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1559        colorBlendOp: brvk::VK_BLEND_OP_ADD,
1560        // srcAlphaBlendFactor: BlendFactor::OneMinusDestAlpha as _,
1561        // dstAlphaBlendFactor: BlendFactor::One as _,
1562        srcAlphaBlendFactor: brvk::VK_BLEND_FACTOR_ONE,
1563        dstAlphaBlendFactor: brvk::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1564        alphaBlendOp: brvk::VK_BLEND_OP_ADD,
1565    });
1566
1567    pub const fn enabled(mut self) -> Self {
1568        self.0.blendEnable = brvk::VK_TRUE;
1569        self
1570    }
1571
1572    pub const fn disabled(mut self) -> Self {
1573        self.0.blendEnable = brvk::VK_FALSE;
1574        self
1575    }
1576
1577    pub const fn color_blend_factor_src(mut self, f: brvk::VkBlendFactor) -> Self {
1578        self.0.srcColorBlendFactor = f;
1579        self
1580    }
1581
1582    pub const fn color_blend_factor_dst(mut self, f: brvk::VkBlendFactor) -> Self {
1583        self.0.dstColorBlendFactor = f;
1584        self
1585    }
1586
1587    pub const fn alpha_blend_factor_src(mut self, f: brvk::VkBlendFactor) -> Self {
1588        self.0.srcAlphaBlendFactor = f;
1589        self
1590    }
1591
1592    pub const fn alpha_blend_factor_dst(mut self, f: brvk::VkBlendFactor) -> Self {
1593        self.0.dstAlphaBlendFactor = f;
1594        self
1595    }
1596
1597    pub const fn color_blend_op(mut self, op: brvk::VkBlendOp) -> Self {
1598        self.0.colorBlendOp = op;
1599        self
1600    }
1601
1602    pub const fn alpha_blend_op(mut self, op: brvk::VkBlendOp) -> Self {
1603        self.0.alphaBlendOp = op;
1604        self
1605    }
1606
1607    pub const fn color_blend(
1608        mut self,
1609        src: brvk::VkBlendFactor,
1610        op: brvk::VkBlendOp,
1611        dst: brvk::VkBlendFactor,
1612    ) -> Self {
1613        self.0.srcColorBlendFactor = src;
1614        self.0.dstColorBlendFactor = dst;
1615        self.0.colorBlendOp = op;
1616        self
1617    }
1618
1619    pub const fn alpha_blend(
1620        mut self,
1621        src: brvk::VkBlendFactor,
1622        op: brvk::VkBlendOp,
1623        dst: brvk::VkBlendFactor,
1624    ) -> Self {
1625        self.0.srcAlphaBlendFactor = src;
1626        self.0.dstAlphaBlendFactor = dst;
1627        self.0.alphaBlendOp = op;
1628        self
1629    }
1630}
1631
1632#[repr(transparent)]
1633#[derive(Clone)]
1634pub struct GraphicsPipelineCreateInfo<'d>(
1635    brvk::VkGraphicsPipelineCreateInfo,
1636    #[allow(clippy::type_complexity)]
1637    core::marker::PhantomData<(
1638        &'d dyn VkHandle<Handle = brvk::VkPipelineLayout>,
1639        &'d dyn VkHandle<Handle = brvk::VkRenderPass>,
1640        &'d [PipelineShaderStage<'d, 'd>],
1641        &'d PipelineVertexInputStateCreateInfo<'d>,
1642        &'d PipelineInputAssemblyStateCreateInfo,
1643        Option<&'d PipelineTessellationStateCreateInfo>,
1644        &'d PipelineViewportStateCreateInfo<'d>,
1645        &'d PipelineRasterizationStateCreateInfo<'d>,
1646        Option<&'d PipelineMultisampleStateCreateInfo<'d>>,
1647        Option<&'d PipelineDepthStencilStateCreateInfo>,
1648        &'d PipelineColorBlendStateCreateInfo<'d>,
1649        Option<&'d PipelineDynamicStateCreateInfo<'d>>,
1650        Option<&'d dyn VkHandle<Handle = brvk::VkPipeline>>,
1651    )>,
1652);
1653impl<'d> GraphicsPipelineCreateInfo<'d> {
1654    #[inline]
1655    #[allow(clippy::too_many_arguments)]
1656    pub fn new(
1657        layout: &'d (impl VkHandle<Handle = brvk::VkPipelineLayout> + ?Sized),
1658        pass: SubpassRef<'d, impl VkHandle<Handle = brvk::VkRenderPass> + ?Sized>,
1659        stages: &'d [PipelineShaderStage<'d, 'd>],
1660        vertex_input_state: &'d PipelineVertexInputStateCreateInfo<'d>,
1661        input_assembly_state: &'d PipelineInputAssemblyStateCreateInfo,
1662        viewport_state: &'d PipelineViewportStateCreateInfo<'d>,
1663        rasterization_state: &'d PipelineRasterizationStateCreateInfo<'d>,
1664        color_blend_state: &'d PipelineColorBlendStateCreateInfo<'d>,
1665    ) -> Self {
1666        Self(
1667            brvk::VkGraphicsPipelineCreateInfo {
1668                sType: brvk::VkGraphicsPipelineCreateInfo::TYPE,
1669                pNext: core::ptr::null(),
1670                flags: 0,
1671                stageCount: stages.len() as _,
1672                pStages: slice_as_ptr_empty_null(stages) as _,
1673                pVertexInputState: vertex_input_state as *const _ as _,
1674                pInputAssemblyState: input_assembly_state as *const _ as _,
1675                pTessellationState: core::ptr::null(),
1676                pViewportState: viewport_state as *const _ as _,
1677                pRasterizationState: rasterization_state as *const _ as _,
1678                pMultisampleState: core::ptr::null(),
1679                pDepthStencilState: core::ptr::null(),
1680                pColorBlendState: color_blend_state as *const _ as _,
1681                pDynamicState: core::ptr::null(),
1682                layout: Some(layout.native_ptr()),
1683                renderPass: Some(pass.0.native_ptr()),
1684                subpass: pass.1,
1685                basePipelineHandle: None,
1686                basePipelineIndex: -1,
1687            },
1688            core::marker::PhantomData,
1689        )
1690    }
1691
1692    #[inline]
1693    pub fn derived_by_handle(parent: &'d (impl VkHandle<Handle = brvk::VkPipeline> + ?Sized)) -> Self {
1694        Self(
1695            brvk::VkGraphicsPipelineCreateInfo {
1696                sType: brvk::VkGraphicsPipelineCreateInfo::TYPE,
1697                pNext: core::ptr::null(),
1698                flags: brvk::VK_PIPELINE_CREATE_DERIVATIVE_BIT,
1699                stageCount: 0,
1700                pStages: core::ptr::null(),
1701                pVertexInputState: core::ptr::null(),
1702                pInputAssemblyState: core::ptr::null(),
1703                pTessellationState: core::ptr::null(),
1704                pViewportState: core::ptr::null(),
1705                pRasterizationState: core::ptr::null(),
1706                pMultisampleState: core::ptr::null(),
1707                pDepthStencilState: core::ptr::null(),
1708                pColorBlendState: core::ptr::null(),
1709                pDynamicState: core::ptr::null(),
1710                layout: None,
1711                renderPass: None,
1712                subpass: 0,
1713                basePipelineHandle: Some(parent.native_ptr()),
1714                basePipelineIndex: -1,
1715            },
1716            core::marker::PhantomData,
1717        )
1718    }
1719
1720    pub const fn derived_by_index(parent: i32) -> Self {
1721        Self(
1722            brvk::VkGraphicsPipelineCreateInfo {
1723                sType: brvk::VkGraphicsPipelineCreateInfo::TYPE,
1724                pNext: core::ptr::null(),
1725                flags: brvk::VK_PIPELINE_CREATE_DERIVATIVE_BIT,
1726                stageCount: 0,
1727                pStages: core::ptr::null(),
1728                pVertexInputState: core::ptr::null(),
1729                pInputAssemblyState: core::ptr::null(),
1730                pTessellationState: core::ptr::null(),
1731                pViewportState: core::ptr::null(),
1732                pRasterizationState: core::ptr::null(),
1733                pMultisampleState: core::ptr::null(),
1734                pDepthStencilState: core::ptr::null(),
1735                pColorBlendState: core::ptr::null(),
1736                pDynamicState: core::ptr::null(),
1737                layout: None,
1738                renderPass: None,
1739                subpass: 0,
1740                basePipelineHandle: None,
1741                basePipelineIndex: parent,
1742            },
1743            core::marker::PhantomData,
1744        )
1745    }
1746
1747    /// # Safety
1748    ///
1749    /// `raw` must have a valid [`VkGraphicsPipelineCreateInfo`] struct.
1750    pub const unsafe fn from_raw(raw: brvk::VkGraphicsPipelineCreateInfo) -> Self {
1751        Self(raw, core::marker::PhantomData)
1752    }
1753
1754    pub const fn into_raw(self) -> brvk::VkGraphicsPipelineCreateInfo {
1755        self.0
1756    }
1757
1758    pub const fn allow_derivatives(mut self) -> Self {
1759        self.0.flags |= brvk::VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
1760        self
1761    }
1762
1763    #[inline(always)]
1764    pub fn set_layout(mut self, layout: &'d (impl VkHandle<Handle = brvk::VkPipelineLayout> + ?Sized)) -> Self {
1765        self.0.layout = Some(layout.native_ptr());
1766        self
1767    }
1768
1769    #[inline(always)]
1770    pub fn set_pass(mut self, pass: SubpassRef<'d, impl VkHandle<Handle = brvk::VkRenderPass> + ?Sized>) -> Self {
1771        self.0.renderPass = Some(pass.0.native_ptr());
1772        self.0.subpass = pass.1;
1773        self
1774    }
1775
1776    pub const fn set_stages(mut self, stages: &'d [PipelineShaderStage<'d, 'd>]) -> Self {
1777        self.0.pStages = slice_as_ptr_empty_null(stages) as _;
1778        self
1779    }
1780
1781    pub const fn set_vertex_input_state(mut self, state: &'d PipelineVertexInputStateCreateInfo<'d>) -> Self {
1782        self.0.pVertexInputState = state as *const _ as _;
1783        self
1784    }
1785
1786    pub const fn set_input_assembly_state(mut self, state: &'d PipelineInputAssemblyStateCreateInfo) -> Self {
1787        self.0.pInputAssemblyState = state as *const _ as _;
1788        self
1789    }
1790
1791    pub const fn set_tessellation_state(mut self, state: &'d PipelineTessellationStateCreateInfo) -> Self {
1792        self.0.pTessellationState = state as *const _ as _;
1793        self
1794    }
1795
1796    pub const fn set_viewport_state(mut self, state: &'d PipelineViewportStateCreateInfo<'d>) -> Self {
1797        self.0.pViewportState = state as *const _ as _;
1798        self
1799    }
1800
1801    pub const fn set_rasterization_state(mut self, state: &'d PipelineRasterizationStateCreateInfo<'d>) -> Self {
1802        self.0.pRasterizationState = state as *const _ as _;
1803        self
1804    }
1805
1806    pub const fn set_multisample_state(mut self, state: &'d PipelineMultisampleStateCreateInfo<'d>) -> Self {
1807        self.0.pMultisampleState = state as *const _ as _;
1808        self
1809    }
1810
1811    pub const fn set_depth_stencil_state(mut self, state: &'d PipelineDepthStencilStateCreateInfo) -> Self {
1812        self.0.pDepthStencilState = state as *const _ as _;
1813        self
1814    }
1815
1816    pub const fn set_color_blend_state(mut self, state: &'d PipelineColorBlendStateCreateInfo<'d>) -> Self {
1817        self.0.pColorBlendState = state as *const _ as _;
1818        self
1819    }
1820
1821    pub const fn set_dynamic_state(mut self, states: &'d PipelineDynamicStateCreateInfo) -> Self {
1822        self.0.pDynamicState = states as *const _ as _;
1823        self
1824    }
1825}
1826
1827/// Structure specifying parameters of a newly created compute pipeline
1828#[repr(transparent)]
1829#[derive(Clone)]
1830pub struct ComputePipelineCreateInfo<'d>(
1831    brvk::VkComputePipelineCreateInfo,
1832    #[allow(clippy::type_complexity)]
1833    core::marker::PhantomData<(
1834        &'d dyn VkHandle<Handle = brvk::VkPipelineLayout>,
1835        PipelineShaderStage<'d, 'd>,
1836        Option<&'d dyn VkHandle<Handle = brvk::VkPipeline>>,
1837    )>,
1838);
1839impl<'d> ComputePipelineCreateInfo<'d> {
1840    #[inline]
1841    pub fn new(
1842        layout: &'d (impl VkHandle<Handle = brvk::VkPipelineLayout> + ?Sized),
1843        stage: PipelineShaderStage<'d, 'd>,
1844    ) -> Self {
1845        Self(
1846            brvk::VkComputePipelineCreateInfo {
1847                sType: brvk::VkComputePipelineCreateInfo::TYPE,
1848                pNext: core::ptr::null(),
1849                flags: 0,
1850                stage: stage.0,
1851                layout: Some(layout.native_ptr()),
1852                basePipelineHandle: None,
1853                basePipelineIndex: -1,
1854            },
1855            core::marker::PhantomData,
1856        )
1857    }
1858
1859    #[inline]
1860    pub fn derived_by_handle(parent: &'d (impl VkHandle<Handle = brvk::VkPipeline> + ?Sized)) -> Self {
1861        Self(
1862            brvk::VkComputePipelineCreateInfo {
1863                sType: brvk::VkComputePipelineCreateInfo::TYPE,
1864                pNext: core::ptr::null(),
1865                flags: brvk::VK_PIPELINE_CREATE_DERIVATIVE_BIT,
1866                stage: brvk::VkPipelineShaderStageCreateInfo {
1867                    sType: brvk::VkPipelineShaderStageCreateInfo::TYPE,
1868                    pNext: core::ptr::null(),
1869                    flags: 0,
1870                    stage: 0,
1871                    module: None,
1872                    pName: core::ptr::null(),
1873                    pSpecializationInfo: core::ptr::null(),
1874                },
1875                layout: None,
1876                basePipelineHandle: Some(parent.native_ptr()),
1877                basePipelineIndex: -1,
1878            },
1879            core::marker::PhantomData,
1880        )
1881    }
1882
1883    #[inline]
1884    pub fn derived_by_index(parent: i32) -> Self {
1885        Self(
1886            brvk::VkComputePipelineCreateInfo {
1887                sType: brvk::VkComputePipelineCreateInfo::TYPE,
1888                pNext: core::ptr::null(),
1889                flags: brvk::VK_PIPELINE_CREATE_DERIVATIVE_BIT,
1890                stage: brvk::VkPipelineShaderStageCreateInfo {
1891                    sType: brvk::VkPipelineShaderStageCreateInfo::TYPE,
1892                    pNext: core::ptr::null(),
1893                    flags: 0,
1894                    stage: 0,
1895                    module: None,
1896                    pName: core::ptr::null(),
1897                    pSpecializationInfo: core::ptr::null(),
1898                },
1899                layout: None,
1900                basePipelineHandle: None,
1901                basePipelineIndex: parent,
1902            },
1903            core::marker::PhantomData,
1904        )
1905    }
1906
1907    /// # Safety
1908    ///
1909    /// `raw` must have a valid [`VkComputePipelineCreateInfo`] struct.
1910    pub const unsafe fn from_raw(raw: brvk::VkComputePipelineCreateInfo) -> Self {
1911        Self(raw, core::marker::PhantomData)
1912    }
1913
1914    pub const fn into_raw(self) -> brvk::VkComputePipelineCreateInfo {
1915        self.0
1916    }
1917
1918    pub const fn allow_derivatives(mut self) -> Self {
1919        self.0.flags |= brvk::VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
1920        self
1921    }
1922
1923    pub const fn set_stage(mut self, stage: PipelineShaderStage<'d, 'd>) -> Self {
1924        self.0.stage = stage.0;
1925        self
1926    }
1927
1928    #[inline]
1929    pub fn set_layout(mut self, layout: &'d (impl VkHandle<Handle = brvk::VkPipelineLayout> + ?Sized)) -> Self {
1930        self.0.layout = Some(layout.native_ptr());
1931        self
1932    }
1933}
1934
1935/// Bitmask specifying pipeline stages
1936#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
1937#[bitflags_newtype]
1938pub struct PipelineStageFlags(pub brvk::VkPipelineStageFlags);
1939impl PipelineStageFlags {
1940    /// The stage of the pipeline where any commands are initially received by the queue
1941    pub const TOP_OF_PIPE: Self = Self(brvk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
1942    /// The stage of the pipeline where Draw/DispatchIndirect data structures are consumed
1943    pub const DRAW_INDIRECT: Self = Self(brvk::VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
1944    /// The stage of the pipeline where vertex and index buffers are consumed
1945    pub const VERTEX_INPUT: Self = Self(brvk::VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
1946    /// The vertex shader stage
1947    pub const VERTEX_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT);
1948    /// The tessellation control shader stage
1949    pub const TESSELLATION_CONTROL_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT);
1950    /// The tessellation evaluation shader stage
1951    pub const TESSELLATION_EVALUATION_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT);
1952    /// The geometry shader stage
1953    pub const GEOMETRY_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT);
1954    /// The fragment shader stage
1955    pub const FRAGMENT_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1956    /// The stage of the pipeline where early fragment tests (depth and stencil tests before fragment shading) are performed
1957    pub const EARLY_FRAGMENT_TESTS: Self = Self(brvk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
1958    /// The stage of the pipeline where late fragment tests (depth and stencil tests after fragment shading) are performed
1959    pub const LATE_FRAGMENT_TESTS: Self = Self(brvk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1960    /// The stage of the pipeline after blending where the final color values are output from the pipeline
1961    pub const COLOR_ATTACHMENT_OUTPUT: Self = Self(brvk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1962    /// The execution of copy commands
1963    pub const TRANSFER: Self = Self(brvk::VK_PIPELINE_STAGE_TRANSFER_BIT);
1964    /// The execution of a compute shader
1965    pub const COMPUTE_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
1966    /// The final stage in the pipeline where operations generated by all commands complete execution
1967    pub const BOTTOM_OF_PIPE: Self = Self(brvk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
1968    /// A pseudo-stage indicating execution on the host of reads/writes of device memory
1969    pub const HOST: Self = Self(brvk::VK_PIPELINE_STAGE_HOST_BIT);
1970    /// The execution of all graphics pipeline stages
1971    pub const ALL_GRAPHICS: Self = Self(brvk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
1972    /// Equivalent to the logical OR of every other pipeline stage flag that is supported on the quue it is used with
1973    pub const ALL_COMMANDS: Self = Self(brvk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1974}
1975
1976/// Bitmask specifying pipeline stages (extended)
1977#[cfg(feature = "VK_KHR_synchronization2")]
1978#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
1979#[bitflags_newtype]
1980pub struct PipelineStageFlags2(pub brvk::VkPipelineStageFlags2KHR);
1981#[cfg(feature = "VK_KHR_synchronization2")]
1982impl PipelineStageFlags2 {
1983    pub const TOP_OF_PIPE: Self = Self(brvk::VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR);
1984    pub const DRAW_INDIRECT: Self = Self(brvk::VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR);
1985    pub const VERTEX_INPUT: Self = Self(brvk::VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR);
1986    pub const VERTEX_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR);
1987    pub const TESSELLATION_CONTROL_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR);
1988    pub const TESSELLATION_EVALUATION_SHADER: Self =
1989        Self(brvk::VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR);
1990    pub const GEOMETRY_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR);
1991    pub const FRAGMENT_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR);
1992    pub const EARLY_FRAGMENT_TESTS: Self = Self(brvk::VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR);
1993    pub const LATE_FRAGMENT_TESTS: Self = Self(brvk::VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR);
1994    pub const COLOR_ATTACHMENT_OUTPUT: Self = Self(brvk::VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR);
1995    pub const COMPUTE_SHADER: Self = Self(brvk::VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR);
1996    pub const ALL_TRANSFER: Self = Self(brvk::VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR);
1997    pub const BOTTOM_OF_PIPE: Self = Self(brvk::VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR);
1998    pub const HOST: Self = Self(brvk::VK_PIPELINE_STAGE_2_HOST_BIT_KHR);
1999    pub const ALL_GRAPHICS: Self = Self(brvk::VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR);
2000    pub const ALL_COMMANDS: Self = Self(brvk::VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR);
2001    pub const COPY: Self = Self(brvk::VK_PIPELINE_STAGE_2_COPY_BIT_KHR);
2002    pub const RESOLVE: Self = Self(brvk::VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR);
2003    pub const BLIT: Self = Self(brvk::VK_PIPELINE_STAGE_2_BLIT_BIT_KHR);
2004    pub const CLEAR: Self = Self(brvk::VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR);
2005    pub const INDEX_INPUT: Self = Self(brvk::VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR);
2006    pub const VERTEX_ATTRIBUTE_INPUT: Self = Self(brvk::VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR);
2007    pub const PRE_RASTERIZATION_SHADERS: Self = Self(brvk::VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR);
2008}