vidya/crates/renderer/src/lib.rs

1021 lines
48 KiB
Rust

#![feature(
negative_impls,
map_try_insert,
debug_closure_helpers,
)]
use std::{collections::HashMap, sync::Arc};
use ash::{prelude::VkResult, vk};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
pub use ash;
pub mod commands;
#[path = "egui.rs"]
mod egui_pass;
pub mod render_graph;
pub mod rendering;
pub mod swapchain;
mod text;
pub mod util;
pub(crate) use renderer_resources::{buffers, images, pipeline};
pub use renderer_device::{device, instance, queue, sync};
pub use renderer_device::{
compatible_extension_properties, extension_intersection,
get_physical_device_features, get_physical_device_properties, make_extension,
DebugUtils, DebugUtilsCreateInfo, Device, DeviceOwned, DeviceRef, Error,
ExtendsDeviceFeatures2Debug, ExtendsDeviceProperties2Debug, Extension, Instance,
PhysicalDeviceFeatures, PhysicalDeviceInfo, PhysicalDeviceProperties, Result,
SurfaceCapabilities,
};
pub use renderer_macros::DeviceRef;
mod texture {
use std::{collections::BTreeMap, sync::Arc};
use crate::{Device, def_monotonic_id, images::Image};
def_monotonic_id!(pub TextureId);
pub struct TextureManager {
pub textures: BTreeMap<TextureId, Arc<Image>>,
#[allow(unused)]
dev: Device,
}
impl TextureManager {
pub fn new(dev: Device) -> Self {
Self {
dev,
textures: BTreeMap::new(),
}
}
pub fn insert_image(&mut self, image: Arc<Image>) -> TextureId {
let id = TextureId::new();
self.textures.insert(id, image);
id
}
pub fn insert_image_with_id(&mut self, id: TextureId, image: Arc<Image>) {
self.textures.insert(id, image);
}
pub fn remove_texture(&mut self, id: TextureId) -> Option<Arc<Image>> {
self.textures.remove(&id)
}
pub fn get_texture(&self, id: TextureId) -> Option<Arc<Image>> {
self.textures.get(&id).cloned()
}
}
}
use util::Rgba;
pub struct SamplerCache {
device: Device,
samplers: HashMap<pipeline::SamplerDesc, pipeline::Sampler>,
}
impl SamplerCache {
pub fn new(device: Device) -> SamplerCache {
Self {
device,
samplers: HashMap::new(),
}
}
pub fn get_sampler(&mut self, desc: pipeline::SamplerDesc) -> VkResult<vk::Sampler> {
use std::collections::hash_map::Entry;
let entry = match self.samplers.entry(desc) {
Entry::Occupied(entry) => entry.get().raw(),
Entry::Vacant(entry) => {
let sampler = pipeline::Sampler::new(self.device.clone(), entry.key())?;
entry.insert(sampler).raw()
}
};
Ok(entry)
}
}
#[derive(Debug)]
pub struct EguiState {
textures: HashMap<egui::TextureId, EguiTextureInfo>,
#[allow(unused)]
descriptor_pool: pipeline::DescriptorPool,
descriptor_set: vk::DescriptorSet,
#[allow(unused)]
descriptor_layout: pipeline::DescriptorSetLayout,
pipeline: Arc<pipeline::Pipeline>,
}
#[derive(Debug, Clone, Copy)]
pub struct EguiTextureInfo {
id: texture::TextureId,
options: egui::epaint::textures::TextureOptions,
}
impl EguiTextureInfo {
fn as_sampler_desc(&self) -> pipeline::SamplerDesc {
let address_mode = match self.options.wrap_mode {
egui::TextureWrapMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE,
egui::TextureWrapMode::Repeat => vk::SamplerAddressMode::REPEAT,
egui::TextureWrapMode::MirroredRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT,
};
pipeline::SamplerDesc {
min_filter: match self.options.minification {
egui::TextureFilter::Nearest => vk::Filter::NEAREST,
egui::TextureFilter::Linear => vk::Filter::LINEAR,
},
mag_filter: match self.options.magnification {
egui::TextureFilter::Nearest => vk::Filter::NEAREST,
egui::TextureFilter::Linear => vk::Filter::LINEAR,
},
mipmap_mode: match self.options.mipmap_mode {
Some(egui::TextureFilter::Linear) => vk::SamplerMipmapMode::LINEAR,
Some(egui::TextureFilter::Nearest) => vk::SamplerMipmapMode::NEAREST,
None => Default::default(),
},
address_u: address_mode,
address_v: address_mode,
address_w: address_mode,
max_lod: vk::LOD_CLAMP_NONE,
..Default::default()
}
}
}
impl EguiState {
const TEXTURE_BINDING: u32 = 0;
const UNIFORM_BINDING: u32 = 1;
pub fn new(device: Device) -> Result<Self> {
let (descriptor_pool, descriptor_layout, sets) =
util::timed("Create Descriptor Set", || {
let descriptor_pool = pipeline::DescriptorPool::new(
device.clone(),
pipeline::DescriptorPoolDesc {
flags: vk::DescriptorPoolCreateFlags::UPDATE_AFTER_BIND,
name: Some("egui-descriptorpool".into()),
sizes: &[
vk::DescriptorPoolSize {
ty: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
descriptor_count: 10,
},
vk::DescriptorPoolSize {
ty: vk::DescriptorType::STORAGE_BUFFER,
descriptor_count: 1,
},
],
max_sets: 1,
},
)?;
let descriptor_layout = pipeline::DescriptorSetLayout::new(
device.clone(),
pipeline::DescriptorSetLayoutDesc {
flags: vk::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND_POOL,
name: Some("egui-descriptor-layout".into()),
bindings: &[
pipeline::DescriptorSetLayoutBindingDesc {
binding: Self::TEXTURE_BINDING,
count: 10,
kind: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
stage: vk::ShaderStageFlags::FRAGMENT,
flags: Some(
vk::DescriptorBindingFlags::PARTIALLY_BOUND
| vk::DescriptorBindingFlags::UPDATE_AFTER_BIND,
),
},
pipeline::DescriptorSetLayoutBindingDesc {
binding: Self::UNIFORM_BINDING,
count: 1,
kind: vk::DescriptorType::STORAGE_BUFFER,
stage: vk::ShaderStageFlags::FRAGMENT,
flags: None,
},
],
},
)?;
let sets = descriptor_pool.allocate(&[pipeline::DescriptorSetAllocDesc {
name: None,
layout: &descriptor_layout,
}])?;
Result::Ok((descriptor_pool, descriptor_layout, sets))
})?;
let pipeline_layout = Arc::new(pipeline::PipelineLayout::new(
device.clone(),
pipeline::PipelineLayoutDesc {
descriptor_set_layouts: &[&descriptor_layout],
push_constant_ranges: &[vk::PushConstantRange {
offset: 0,
size: 128,
stage_flags: vk::ShaderStageFlags::VERTEX,
}],
name: Some("egui-pipeline-layout".into()),
},
)?);
let frag_shader = pipeline::ShaderModule::new_from_path(
device.clone(),
"crates/renderer/shaders/egui_frag.spv",
)?;
let vert_shader = pipeline::ShaderModule::new_from_path(
device.clone(),
"crates/renderer/shaders/egui_vert.spv",
)?;
let pipeline = pipeline::Pipeline::new_graphics(
device.clone(),
pipeline::GraphicsPipelineDesc {
flags: Default::default(),
name: Some("egui-pipeline".into()),
shader_stages: &[
pipeline::ShaderStageDesc {
flags: vk::PipelineShaderStageCreateFlags::empty(),
module: &frag_shader,
stage: vk::ShaderStageFlags::FRAGMENT,
entry: c"main".into(),
},
pipeline::ShaderStageDesc {
flags: vk::PipelineShaderStageCreateFlags::empty(),
module: &vert_shader,
stage: vk::ShaderStageFlags::VERTEX,
entry: c"main".into(),
},
],
render_pass: None,
layout: pipeline_layout,
subpass: None,
base_pipeline: None,
vertex_input: Some(pipeline::VertexInputState {
bindings: &[vk::VertexInputBindingDescription {
binding: 0,
stride: 20,
input_rate: vk::VertexInputRate::VERTEX,
}],
attributes: &[
vk::VertexInputAttributeDescription {
location: 0,
binding: 0,
format: vk::Format::R32G32_SFLOAT,
offset: 0,
},
vk::VertexInputAttributeDescription {
location: 1,
binding: 0,
format: vk::Format::R32G32_SFLOAT,
offset: 8,
},
vk::VertexInputAttributeDescription {
location: 2,
binding: 0,
format: vk::Format::R8G8B8A8_UNORM,
offset: 16,
},
],
}),
input_assembly: Some(pipeline::InputAssemblyState {
topology: vk::PrimitiveTopology::TRIANGLE_LIST,
primitive_restart: false,
}),
tessellation: None,
viewport: Some(pipeline::ViewportState {
num_viewports: 1,
num_scissors: 1,
..Default::default()
}),
rasterization: Some(pipeline::RasterizationState {
cull_mode: vk::CullModeFlags::NONE,
..Default::default()
}),
multisample: Some(pipeline::MultisampleState {
..Default::default()
}),
depth_stencil: Some(pipeline::DepthStencilState {
depth: Some(pipeline::DepthState {
write_enable: false,
compare_op: Some(vk::CompareOp::LESS),
bounds: Some(pipeline::DepthBounds { min: 0.0, max: 1.0 }),
}),
..Default::default()
}),
color_blend: Some(pipeline::ColorBlendState {
attachments: &[vk::PipelineColorBlendAttachmentState::default()
.color_write_mask(vk::ColorComponentFlags::RGBA)
.blend_enable(true)
.color_blend_op(vk::BlendOp::ADD)
.src_color_blend_factor(vk::BlendFactor::ONE)
.dst_color_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA)
.alpha_blend_op(vk::BlendOp::ADD)
.src_alpha_blend_factor(vk::BlendFactor::ONE)
.dst_alpha_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA)],
..Default::default()
}),
rendering: Some(pipeline::RenderingState {
color_formats: &[vk::Format::R8G8B8A8_UNORM],
..Default::default()
}),
dynamic: Some(pipeline::DynamicState {
dynamic_states: &[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR],
..Default::default()
}),
},
)?;
Ok(Self {
textures: HashMap::new(),
descriptor_pool,
descriptor_layout,
descriptor_set: sets[0],
pipeline: Arc::new(pipeline),
})
}
pub fn lookup_texture(&self, id: egui::epaint::TextureId) -> Option<texture::TextureId> {
self.textures.get(&id).map(|entry| entry.id)
}
}
#[derive(renderer_macros::DeviceRef)]
pub struct Renderer2 {
#[device]
pub device: Device,
pub samplers: SamplerCache,
pub texture_manager: texture::TextureManager,
#[allow(unused)]
// keep this around because the vulkan device has been created with this
// display handle in mind. Might not be necessary.
display: RawDisplayHandle,
}
impl Renderer2 {
pub fn new(display: RawDisplayHandle) -> Result<Self> {
let instance = Instance::new(&InstanceDesc {
..Default::default()
})?;
let adapter = instance.choose_adapter_default(None, &[], None)?;
let device = adapter.create_logical_device(
&instance,
&[],
PhysicalDeviceFeatures {
core: vk::PhysicalDeviceFeatures {
multi_draw_indirect: vk::TRUE,
..Default::default()
},
core11: vk::PhysicalDeviceVulkan11Features {
shader_draw_parameters: vk::TRUE,
..Default::default()
},
core12: vk::PhysicalDeviceVulkan12Features {
descriptor_binding_partially_bound: vk::TRUE,
descriptor_binding_sampled_image_update_after_bind: vk::TRUE,
runtime_descriptor_array: vk::TRUE,
..Default::default()
},
core13: vk::PhysicalDeviceVulkan13Features {
synchronization2: vk::TRUE,
dynamic_rendering: vk::TRUE,
maintenance4: vk::TRUE,
..Default::default()
},
..Default::default()
},
Some(display),
)?;
Ok(Self {
samplers: SamplerCache::new(device.clone()),
texture_manager: texture::TextureManager::new(device.clone()),
display,
device,
})
}
pub fn device(&self) -> &Device {
&self.device
}
pub fn samplers_mut(&mut self) -> &mut SamplerCache {
&mut self.samplers
}
pub fn samplers(&self) -> &SamplerCache {
&self.samplers
}
pub fn texture_manager_mut(&mut self) -> &mut texture::TextureManager {
&mut self.texture_manager
}
pub fn texture_manager(&self) -> &texture::TextureManager {
&self.texture_manager
}
pub fn create_surface(
&self,
window: RawWindowHandle,
extent: vk::Extent2D,
) -> Result<swapchain::Surface> {
let surface = unsafe {
swapchain::Surface::new_from_raw_window_handle(
&self.device.instance,
self.display,
window,
)?
};
surface.configure(
&self.device,
swapchain::SwapchainConfiguration {
extent,
..Default::default()
},
)?;
Ok(surface)
}
pub async fn draw_graph<T, F: FnOnce(&mut Renderer2, &mut render_graph::RenderGraph) -> T>(
&mut self,
surface: &swapchain::Surface,
cb: F,
) -> Result<T> {
let Some(frame) = surface.acquire_image() else {
return Err(Error::SuboptimalSwapchain);
};
let (frame, _suboptimal) = frame.await?;
let mut rg = render_graph::RenderGraph::new();
let _framebuffer = rg.import_framebuffer(frame.image().clone());
let out = cb(self, &mut rg);
let cmds = rg.resolve(self.device.clone())?;
let future = cmds.submit(
Some((frame.acquire, vk::PipelineStageFlags::TRANSFER)),
Some(frame.release),
Arc::new(sync::Fence::from_pool(&self.device, None)?),
)?;
future.await;
// window.window.pre_present_notify();
let wait = Some(frame.release);
frame.present(wait)?;
Ok(out)
}
}
pub use vk::Extent2D;
use crate::{
instance::InstanceDesc,
};
pub mod utils {
#![allow(dead_code)]
use ash::vk;
pub trait SplitCollect: Iterator {
fn collect2<F>(self, mut pred: F) -> (Vec<Self::Item>, Vec<Self::Item>)
where
Self: Sized,
F: FnMut(&Self::Item) -> bool,
{
let mut left = Vec::new();
let mut right = Vec::new();
for item in self {
if pred(&item) {
left.push(item);
} else {
right.push(item);
}
}
(left, right)
}
}
pub fn eq_device_features10(
lhs: &vk::PhysicalDeviceFeatures,
rhs: &vk::PhysicalDeviceFeatures,
) -> bool {
lhs.robust_buffer_access == rhs.robust_buffer_access
&& lhs.full_draw_index_uint32 == rhs.full_draw_index_uint32
&& lhs.image_cube_array == rhs.image_cube_array
&& lhs.independent_blend == rhs.independent_blend
&& lhs.geometry_shader == rhs.geometry_shader
&& lhs.tessellation_shader == rhs.tessellation_shader
&& lhs.sample_rate_shading == rhs.sample_rate_shading
&& lhs.dual_src_blend == rhs.dual_src_blend
&& lhs.logic_op == rhs.logic_op
&& lhs.multi_draw_indirect == rhs.multi_draw_indirect
&& lhs.draw_indirect_first_instance == rhs.draw_indirect_first_instance
&& lhs.depth_clamp == rhs.depth_clamp
&& lhs.depth_bias_clamp == rhs.depth_bias_clamp
&& lhs.fill_mode_non_solid == rhs.fill_mode_non_solid
&& lhs.depth_bounds == rhs.depth_bounds
&& lhs.wide_lines == rhs.wide_lines
&& lhs.large_points == rhs.large_points
&& lhs.alpha_to_one == rhs.alpha_to_one
&& lhs.multi_viewport == rhs.multi_viewport
&& lhs.sampler_anisotropy == rhs.sampler_anisotropy
&& lhs.texture_compression_etc2 == rhs.texture_compression_etc2
&& lhs.texture_compression_astc_ldr == rhs.texture_compression_astc_ldr
&& lhs.texture_compression_bc == rhs.texture_compression_bc
&& lhs.occlusion_query_precise == rhs.occlusion_query_precise
&& lhs.pipeline_statistics_query == rhs.pipeline_statistics_query
&& lhs.vertex_pipeline_stores_and_atomics == rhs.vertex_pipeline_stores_and_atomics
&& lhs.fragment_stores_and_atomics == rhs.fragment_stores_and_atomics
&& lhs.shader_tessellation_and_geometry_point_size
== rhs.shader_tessellation_and_geometry_point_size
&& lhs.shader_image_gather_extended == rhs.shader_image_gather_extended
&& lhs.shader_storage_image_extended_formats
== rhs.shader_storage_image_extended_formats
&& lhs.shader_storage_image_multisample == rhs.shader_storage_image_multisample
&& lhs.shader_storage_image_read_without_format
== rhs.shader_storage_image_read_without_format
&& lhs.shader_storage_image_write_without_format
== rhs.shader_storage_image_write_without_format
&& lhs.shader_uniform_buffer_array_dynamic_indexing
== rhs.shader_uniform_buffer_array_dynamic_indexing
&& lhs.shader_sampled_image_array_dynamic_indexing
== rhs.shader_sampled_image_array_dynamic_indexing
&& lhs.shader_storage_buffer_array_dynamic_indexing
== rhs.shader_storage_buffer_array_dynamic_indexing
&& lhs.shader_storage_image_array_dynamic_indexing
== rhs.shader_storage_image_array_dynamic_indexing
&& lhs.shader_clip_distance == rhs.shader_clip_distance
&& lhs.shader_cull_distance == rhs.shader_cull_distance
&& lhs.shader_float64 == rhs.shader_float64
&& lhs.shader_int64 == rhs.shader_int64
&& lhs.shader_int16 == rhs.shader_int16
&& lhs.shader_resource_residency == rhs.shader_resource_residency
&& lhs.shader_resource_min_lod == rhs.shader_resource_min_lod
&& lhs.sparse_binding == rhs.sparse_binding
&& lhs.sparse_residency_buffer == rhs.sparse_residency_buffer
&& lhs.sparse_residency_image2_d == rhs.sparse_residency_image2_d
&& lhs.sparse_residency_image3_d == rhs.sparse_residency_image3_d
&& lhs.sparse_residency2_samples == rhs.sparse_residency2_samples
&& lhs.sparse_residency4_samples == rhs.sparse_residency4_samples
&& lhs.sparse_residency8_samples == rhs.sparse_residency8_samples
&& lhs.sparse_residency16_samples == rhs.sparse_residency16_samples
&& lhs.sparse_residency_aliased == rhs.sparse_residency_aliased
&& lhs.variable_multisample_rate == rhs.variable_multisample_rate
&& lhs.inherited_queries == rhs.inherited_queries
}
pub fn eq_device_features11(
lhs: &vk::PhysicalDeviceVulkan11Features,
rhs: &vk::PhysicalDeviceVulkan11Features,
) -> bool {
lhs.storage_buffer16_bit_access == rhs.storage_buffer16_bit_access
&& lhs.uniform_and_storage_buffer16_bit_access
== rhs.uniform_and_storage_buffer16_bit_access
&& lhs.storage_push_constant16 == rhs.storage_push_constant16
&& lhs.storage_input_output16 == rhs.storage_input_output16
&& lhs.multiview == rhs.multiview
&& lhs.multiview_geometry_shader == rhs.multiview_geometry_shader
&& lhs.multiview_tessellation_shader == rhs.multiview_tessellation_shader
&& lhs.variable_pointers_storage_buffer == rhs.variable_pointers_storage_buffer
&& lhs.variable_pointers == rhs.variable_pointers
&& lhs.protected_memory == rhs.protected_memory
&& lhs.sampler_ycbcr_conversion == rhs.sampler_ycbcr_conversion
&& lhs.shader_draw_parameters == rhs.shader_draw_parameters
}
pub fn eq_device_features12(
lhs: &vk::PhysicalDeviceVulkan12Features,
rhs: &vk::PhysicalDeviceVulkan12Features,
) -> bool {
lhs.sampler_mirror_clamp_to_edge == rhs.sampler_mirror_clamp_to_edge
&& lhs.draw_indirect_count == rhs.draw_indirect_count
&& lhs.storage_buffer8_bit_access == rhs.storage_buffer8_bit_access
&& lhs.uniform_and_storage_buffer8_bit_access
== rhs.uniform_and_storage_buffer8_bit_access
&& lhs.storage_push_constant8 == rhs.storage_push_constant8
&& lhs.shader_buffer_int64_atomics == rhs.shader_buffer_int64_atomics
&& lhs.shader_shared_int64_atomics == rhs.shader_shared_int64_atomics
&& lhs.shader_float16 == rhs.shader_float16
&& lhs.shader_int8 == rhs.shader_int8
&& lhs.descriptor_indexing == rhs.descriptor_indexing
&& lhs.shader_input_attachment_array_dynamic_indexing
== rhs.shader_input_attachment_array_dynamic_indexing
&& lhs.shader_uniform_texel_buffer_array_dynamic_indexing
== rhs.shader_uniform_texel_buffer_array_dynamic_indexing
&& lhs.shader_storage_texel_buffer_array_dynamic_indexing
== rhs.shader_storage_texel_buffer_array_dynamic_indexing
&& lhs.shader_uniform_buffer_array_non_uniform_indexing
== rhs.shader_uniform_buffer_array_non_uniform_indexing
&& lhs.shader_sampled_image_array_non_uniform_indexing
== rhs.shader_sampled_image_array_non_uniform_indexing
&& lhs.shader_storage_buffer_array_non_uniform_indexing
== rhs.shader_storage_buffer_array_non_uniform_indexing
&& lhs.shader_storage_image_array_non_uniform_indexing
== rhs.shader_storage_image_array_non_uniform_indexing
&& lhs.shader_input_attachment_array_non_uniform_indexing
== rhs.shader_input_attachment_array_non_uniform_indexing
&& lhs.shader_uniform_texel_buffer_array_non_uniform_indexing
== rhs.shader_uniform_texel_buffer_array_non_uniform_indexing
&& lhs.shader_storage_texel_buffer_array_non_uniform_indexing
== rhs.shader_storage_texel_buffer_array_non_uniform_indexing
&& lhs.descriptor_binding_uniform_buffer_update_after_bind
== rhs.descriptor_binding_uniform_buffer_update_after_bind
&& lhs.descriptor_binding_sampled_image_update_after_bind
== rhs.descriptor_binding_sampled_image_update_after_bind
&& lhs.descriptor_binding_storage_image_update_after_bind
== rhs.descriptor_binding_storage_image_update_after_bind
&& lhs.descriptor_binding_storage_buffer_update_after_bind
== rhs.descriptor_binding_storage_buffer_update_after_bind
&& lhs.descriptor_binding_uniform_texel_buffer_update_after_bind
== rhs.descriptor_binding_uniform_texel_buffer_update_after_bind
&& lhs.descriptor_binding_storage_texel_buffer_update_after_bind
== rhs.descriptor_binding_storage_texel_buffer_update_after_bind
&& lhs.descriptor_binding_update_unused_while_pending
== rhs.descriptor_binding_update_unused_while_pending
&& lhs.descriptor_binding_partially_bound == rhs.descriptor_binding_partially_bound
&& lhs.descriptor_binding_variable_descriptor_count
== rhs.descriptor_binding_variable_descriptor_count
&& lhs.runtime_descriptor_array == rhs.runtime_descriptor_array
&& lhs.sampler_filter_minmax == rhs.sampler_filter_minmax
&& lhs.scalar_block_layout == rhs.scalar_block_layout
&& lhs.imageless_framebuffer == rhs.imageless_framebuffer
&& lhs.uniform_buffer_standard_layout == rhs.uniform_buffer_standard_layout
&& lhs.shader_subgroup_extended_types == rhs.shader_subgroup_extended_types
&& lhs.separate_depth_stencil_layouts == rhs.separate_depth_stencil_layouts
&& lhs.host_query_reset == rhs.host_query_reset
&& lhs.timeline_semaphore == rhs.timeline_semaphore
&& lhs.buffer_device_address == rhs.buffer_device_address
&& lhs.buffer_device_address_capture_replay == rhs.buffer_device_address_capture_replay
&& lhs.buffer_device_address_multi_device == rhs.buffer_device_address_multi_device
&& lhs.vulkan_memory_model == rhs.vulkan_memory_model
&& lhs.vulkan_memory_model_device_scope == rhs.vulkan_memory_model_device_scope
&& lhs.vulkan_memory_model_availability_visibility_chains
== rhs.vulkan_memory_model_availability_visibility_chains
&& lhs.shader_output_viewport_index == rhs.shader_output_viewport_index
&& lhs.shader_output_layer == rhs.shader_output_layer
&& lhs.subgroup_broadcast_dynamic_id == rhs.subgroup_broadcast_dynamic_id
}
pub fn eq_device_features13(
lhs: &vk::PhysicalDeviceVulkan13Features,
rhs: &vk::PhysicalDeviceVulkan13Features,
) -> bool {
lhs.robust_image_access == rhs.robust_image_access
&& lhs.inline_uniform_block == rhs.inline_uniform_block
&& lhs.descriptor_binding_inline_uniform_block_update_after_bind
== rhs.descriptor_binding_inline_uniform_block_update_after_bind
&& lhs.pipeline_creation_cache_control == rhs.pipeline_creation_cache_control
&& lhs.private_data == rhs.private_data
&& lhs.shader_demote_to_helper_invocation == rhs.shader_demote_to_helper_invocation
&& lhs.shader_terminate_invocation == rhs.shader_terminate_invocation
&& lhs.subgroup_size_control == rhs.subgroup_size_control
&& lhs.compute_full_subgroups == rhs.compute_full_subgroups
&& lhs.synchronization2 == rhs.synchronization2
&& lhs.texture_compression_astc_hdr == rhs.texture_compression_astc_hdr
&& lhs.shader_zero_initialize_workgroup_memory
== rhs.shader_zero_initialize_workgroup_memory
&& lhs.dynamic_rendering == rhs.dynamic_rendering
&& lhs.shader_integer_dot_product == rhs.shader_integer_dot_product
&& lhs.maintenance4 == rhs.maintenance4
}
pub fn bitand_device_features10(
lhs: &vk::PhysicalDeviceFeatures,
rhs: &vk::PhysicalDeviceFeatures,
) -> vk::PhysicalDeviceFeatures {
use core::ops::BitAnd;
vk::PhysicalDeviceFeatures {
robust_buffer_access: lhs.robust_buffer_access.bitand(&rhs.robust_buffer_access),
full_draw_index_uint32: lhs
.full_draw_index_uint32
.bitand(&rhs.full_draw_index_uint32),
image_cube_array: lhs.image_cube_array.bitand(&rhs.image_cube_array),
independent_blend: lhs.independent_blend.bitand(&rhs.independent_blend),
geometry_shader: lhs.geometry_shader.bitand(&rhs.geometry_shader),
tessellation_shader: lhs.tessellation_shader.bitand(&rhs.tessellation_shader),
sample_rate_shading: lhs.sample_rate_shading.bitand(&rhs.sample_rate_shading),
dual_src_blend: lhs.dual_src_blend.bitand(&rhs.dual_src_blend),
logic_op: lhs.logic_op.bitand(&rhs.logic_op),
multi_draw_indirect: lhs.multi_draw_indirect.bitand(&rhs.multi_draw_indirect),
draw_indirect_first_instance: lhs
.draw_indirect_first_instance
.bitand(&rhs.draw_indirect_first_instance),
depth_clamp: lhs.depth_clamp.bitand(&rhs.depth_clamp),
depth_bias_clamp: lhs.depth_bias_clamp.bitand(&rhs.depth_bias_clamp),
fill_mode_non_solid: lhs.fill_mode_non_solid.bitand(&rhs.fill_mode_non_solid),
depth_bounds: lhs.depth_bounds.bitand(&rhs.depth_bounds),
wide_lines: lhs.wide_lines.bitand(&rhs.wide_lines),
large_points: lhs.large_points.bitand(&rhs.large_points),
alpha_to_one: lhs.alpha_to_one.bitand(&rhs.alpha_to_one),
multi_viewport: lhs.multi_viewport.bitand(&rhs.multi_viewport),
sampler_anisotropy: lhs.sampler_anisotropy.bitand(&rhs.sampler_anisotropy),
texture_compression_etc2: lhs
.texture_compression_etc2
.bitand(&rhs.texture_compression_etc2),
texture_compression_astc_ldr: lhs
.texture_compression_astc_ldr
.bitand(&rhs.texture_compression_astc_ldr),
texture_compression_bc: lhs
.texture_compression_bc
.bitand(&rhs.texture_compression_bc),
occlusion_query_precise: lhs
.occlusion_query_precise
.bitand(&rhs.occlusion_query_precise),
pipeline_statistics_query: lhs
.pipeline_statistics_query
.bitand(&rhs.pipeline_statistics_query),
vertex_pipeline_stores_and_atomics: lhs
.vertex_pipeline_stores_and_atomics
.bitand(&rhs.vertex_pipeline_stores_and_atomics),
fragment_stores_and_atomics: lhs
.fragment_stores_and_atomics
.bitand(&rhs.fragment_stores_and_atomics),
shader_tessellation_and_geometry_point_size: lhs
.shader_tessellation_and_geometry_point_size
.bitand(&rhs.shader_tessellation_and_geometry_point_size),
shader_image_gather_extended: lhs
.shader_image_gather_extended
.bitand(&rhs.shader_image_gather_extended),
shader_storage_image_extended_formats: lhs
.shader_storage_image_extended_formats
.bitand(&rhs.shader_storage_image_extended_formats),
shader_storage_image_multisample: lhs
.shader_storage_image_multisample
.bitand(&rhs.shader_storage_image_multisample),
shader_storage_image_read_without_format: lhs
.shader_storage_image_read_without_format
.bitand(&rhs.shader_storage_image_read_without_format),
shader_storage_image_write_without_format: lhs
.shader_storage_image_write_without_format
.bitand(&rhs.shader_storage_image_write_without_format),
shader_uniform_buffer_array_dynamic_indexing: lhs
.shader_uniform_buffer_array_dynamic_indexing
.bitand(&rhs.shader_uniform_buffer_array_dynamic_indexing),
shader_sampled_image_array_dynamic_indexing: lhs
.shader_sampled_image_array_dynamic_indexing
.bitand(&rhs.shader_sampled_image_array_dynamic_indexing),
shader_storage_buffer_array_dynamic_indexing: lhs
.shader_storage_buffer_array_dynamic_indexing
.bitand(&rhs.shader_storage_buffer_array_dynamic_indexing),
shader_storage_image_array_dynamic_indexing: lhs
.shader_storage_image_array_dynamic_indexing
.bitand(&rhs.shader_storage_image_array_dynamic_indexing),
shader_clip_distance: lhs.shader_clip_distance.bitand(&rhs.shader_clip_distance),
shader_cull_distance: lhs.shader_cull_distance.bitand(&rhs.shader_cull_distance),
shader_float64: lhs.shader_float64.bitand(&rhs.shader_float64),
shader_int64: lhs.shader_int64.bitand(&rhs.shader_int64),
shader_int16: lhs.shader_int16.bitand(&rhs.shader_int16),
shader_resource_residency: lhs
.shader_resource_residency
.bitand(&rhs.shader_resource_residency),
shader_resource_min_lod: lhs
.shader_resource_min_lod
.bitand(&rhs.shader_resource_min_lod),
sparse_binding: lhs.sparse_binding.bitand(&rhs.sparse_binding),
sparse_residency_buffer: lhs
.sparse_residency_buffer
.bitand(&rhs.sparse_residency_buffer),
sparse_residency_image2_d: lhs
.sparse_residency_image2_d
.bitand(&rhs.sparse_residency_image2_d),
sparse_residency_image3_d: lhs
.sparse_residency_image3_d
.bitand(&rhs.sparse_residency_image3_d),
sparse_residency2_samples: lhs
.sparse_residency2_samples
.bitand(&rhs.sparse_residency2_samples),
sparse_residency4_samples: lhs
.sparse_residency4_samples
.bitand(&rhs.sparse_residency4_samples),
sparse_residency8_samples: lhs
.sparse_residency8_samples
.bitand(&rhs.sparse_residency8_samples),
sparse_residency16_samples: lhs
.sparse_residency16_samples
.bitand(&rhs.sparse_residency16_samples),
sparse_residency_aliased: lhs
.sparse_residency_aliased
.bitand(&rhs.sparse_residency_aliased),
variable_multisample_rate: lhs
.variable_multisample_rate
.bitand(&rhs.variable_multisample_rate),
inherited_queries: lhs.inherited_queries.bitand(&rhs.inherited_queries),
}
}
pub fn bitand_device_features11(
lhs: &vk::PhysicalDeviceVulkan11Features,
rhs: &vk::PhysicalDeviceVulkan11Features,
) -> vk::PhysicalDeviceVulkan11Features<'static> {
use core::ops::BitAnd;
vk::PhysicalDeviceVulkan11Features {
storage_buffer16_bit_access: lhs
.storage_buffer16_bit_access
.bitand(&rhs.storage_buffer16_bit_access),
uniform_and_storage_buffer16_bit_access: lhs
.uniform_and_storage_buffer16_bit_access
.bitand(&rhs.uniform_and_storage_buffer16_bit_access),
storage_push_constant16: lhs
.storage_push_constant16
.bitand(&rhs.storage_push_constant16),
storage_input_output16: lhs
.storage_input_output16
.bitand(&rhs.storage_input_output16),
multiview: lhs.multiview.bitand(&rhs.multiview),
multiview_geometry_shader: lhs
.multiview_geometry_shader
.bitand(&rhs.multiview_geometry_shader),
multiview_tessellation_shader: lhs
.multiview_tessellation_shader
.bitand(&rhs.multiview_tessellation_shader),
variable_pointers_storage_buffer: lhs
.variable_pointers_storage_buffer
.bitand(&rhs.variable_pointers_storage_buffer),
variable_pointers: lhs.variable_pointers.bitand(&rhs.variable_pointers),
protected_memory: lhs.protected_memory.bitand(&rhs.protected_memory),
sampler_ycbcr_conversion: lhs
.sampler_ycbcr_conversion
.bitand(&rhs.sampler_ycbcr_conversion),
shader_draw_parameters: lhs
.shader_draw_parameters
.bitand(&rhs.shader_draw_parameters),
..Default::default()
}
}
pub fn bitand_device_features12(
lhs: &vk::PhysicalDeviceVulkan12Features,
rhs: &vk::PhysicalDeviceVulkan12Features,
) -> vk::PhysicalDeviceVulkan12Features<'static> {
use core::ops::BitAnd;
vk::PhysicalDeviceVulkan12Features {
sampler_mirror_clamp_to_edge: lhs
.sampler_mirror_clamp_to_edge
.bitand(&rhs.sampler_mirror_clamp_to_edge),
draw_indirect_count: lhs.draw_indirect_count.bitand(&rhs.draw_indirect_count),
storage_buffer8_bit_access: lhs
.storage_buffer8_bit_access
.bitand(&rhs.storage_buffer8_bit_access),
uniform_and_storage_buffer8_bit_access: lhs
.uniform_and_storage_buffer8_bit_access
.bitand(&rhs.uniform_and_storage_buffer8_bit_access),
storage_push_constant8: lhs
.storage_push_constant8
.bitand(&rhs.storage_push_constant8),
shader_buffer_int64_atomics: lhs
.shader_buffer_int64_atomics
.bitand(&rhs.shader_buffer_int64_atomics),
shader_shared_int64_atomics: lhs
.shader_shared_int64_atomics
.bitand(&rhs.shader_shared_int64_atomics),
shader_float16: lhs.shader_float16.bitand(&rhs.shader_float16),
shader_int8: lhs.shader_int8.bitand(&rhs.shader_int8),
descriptor_indexing: lhs.descriptor_indexing.bitand(&rhs.descriptor_indexing),
shader_input_attachment_array_dynamic_indexing: lhs
.shader_input_attachment_array_dynamic_indexing
.bitand(&rhs.shader_input_attachment_array_dynamic_indexing),
shader_uniform_texel_buffer_array_dynamic_indexing: lhs
.shader_uniform_texel_buffer_array_dynamic_indexing
.bitand(&rhs.shader_uniform_texel_buffer_array_dynamic_indexing),
shader_storage_texel_buffer_array_dynamic_indexing: lhs
.shader_storage_texel_buffer_array_dynamic_indexing
.bitand(&rhs.shader_storage_texel_buffer_array_dynamic_indexing),
shader_uniform_buffer_array_non_uniform_indexing: lhs
.shader_uniform_buffer_array_non_uniform_indexing
.bitand(&rhs.shader_uniform_buffer_array_non_uniform_indexing),
shader_sampled_image_array_non_uniform_indexing: lhs
.shader_sampled_image_array_non_uniform_indexing
.bitand(&rhs.shader_sampled_image_array_non_uniform_indexing),
shader_storage_buffer_array_non_uniform_indexing: lhs
.shader_storage_buffer_array_non_uniform_indexing
.bitand(&rhs.shader_storage_buffer_array_non_uniform_indexing),
shader_storage_image_array_non_uniform_indexing: lhs
.shader_storage_image_array_non_uniform_indexing
.bitand(&rhs.shader_storage_image_array_non_uniform_indexing),
shader_input_attachment_array_non_uniform_indexing: lhs
.shader_input_attachment_array_non_uniform_indexing
.bitand(&rhs.shader_input_attachment_array_non_uniform_indexing),
shader_uniform_texel_buffer_array_non_uniform_indexing: lhs
.shader_uniform_texel_buffer_array_non_uniform_indexing
.bitand(&rhs.shader_uniform_texel_buffer_array_non_uniform_indexing),
shader_storage_texel_buffer_array_non_uniform_indexing: lhs
.shader_storage_texel_buffer_array_non_uniform_indexing
.bitand(&rhs.shader_storage_texel_buffer_array_non_uniform_indexing),
descriptor_binding_uniform_buffer_update_after_bind: lhs
.descriptor_binding_uniform_buffer_update_after_bind
.bitand(&rhs.descriptor_binding_uniform_buffer_update_after_bind),
descriptor_binding_sampled_image_update_after_bind: lhs
.descriptor_binding_sampled_image_update_after_bind
.bitand(&rhs.descriptor_binding_sampled_image_update_after_bind),
descriptor_binding_storage_image_update_after_bind: lhs
.descriptor_binding_storage_image_update_after_bind
.bitand(&rhs.descriptor_binding_storage_image_update_after_bind),
descriptor_binding_storage_buffer_update_after_bind: lhs
.descriptor_binding_storage_buffer_update_after_bind
.bitand(&rhs.descriptor_binding_storage_buffer_update_after_bind),
descriptor_binding_uniform_texel_buffer_update_after_bind: lhs
.descriptor_binding_uniform_texel_buffer_update_after_bind
.bitand(&rhs.descriptor_binding_uniform_texel_buffer_update_after_bind),
descriptor_binding_storage_texel_buffer_update_after_bind: lhs
.descriptor_binding_storage_texel_buffer_update_after_bind
.bitand(&rhs.descriptor_binding_storage_texel_buffer_update_after_bind),
descriptor_binding_update_unused_while_pending: lhs
.descriptor_binding_update_unused_while_pending
.bitand(&rhs.descriptor_binding_update_unused_while_pending),
descriptor_binding_partially_bound: lhs
.descriptor_binding_partially_bound
.bitand(&rhs.descriptor_binding_partially_bound),
descriptor_binding_variable_descriptor_count: lhs
.descriptor_binding_variable_descriptor_count
.bitand(&rhs.descriptor_binding_variable_descriptor_count),
runtime_descriptor_array: lhs
.runtime_descriptor_array
.bitand(&rhs.runtime_descriptor_array),
sampler_filter_minmax: lhs.sampler_filter_minmax.bitand(&rhs.sampler_filter_minmax),
scalar_block_layout: lhs.scalar_block_layout.bitand(&rhs.scalar_block_layout),
imageless_framebuffer: lhs.imageless_framebuffer.bitand(&rhs.imageless_framebuffer),
uniform_buffer_standard_layout: lhs
.uniform_buffer_standard_layout
.bitand(&rhs.uniform_buffer_standard_layout),
shader_subgroup_extended_types: lhs
.shader_subgroup_extended_types
.bitand(&rhs.shader_subgroup_extended_types),
separate_depth_stencil_layouts: lhs
.separate_depth_stencil_layouts
.bitand(&rhs.separate_depth_stencil_layouts),
host_query_reset: lhs.host_query_reset.bitand(&rhs.host_query_reset),
timeline_semaphore: lhs.timeline_semaphore.bitand(&rhs.timeline_semaphore),
buffer_device_address: lhs.buffer_device_address.bitand(&rhs.buffer_device_address),
buffer_device_address_capture_replay: lhs
.buffer_device_address_capture_replay
.bitand(&rhs.buffer_device_address_capture_replay),
buffer_device_address_multi_device: lhs
.buffer_device_address_multi_device
.bitand(&rhs.buffer_device_address_multi_device),
vulkan_memory_model: lhs.vulkan_memory_model.bitand(&rhs.vulkan_memory_model),
vulkan_memory_model_device_scope: lhs
.vulkan_memory_model_device_scope
.bitand(&rhs.vulkan_memory_model_device_scope),
vulkan_memory_model_availability_visibility_chains: lhs
.vulkan_memory_model_availability_visibility_chains
.bitand(&rhs.vulkan_memory_model_availability_visibility_chains),
shader_output_viewport_index: lhs
.shader_output_viewport_index
.bitand(&rhs.shader_output_viewport_index),
shader_output_layer: lhs.shader_output_layer.bitand(&rhs.shader_output_layer),
subgroup_broadcast_dynamic_id: lhs
.subgroup_broadcast_dynamic_id
.bitand(&rhs.subgroup_broadcast_dynamic_id),
..Default::default()
}
}
pub fn bitand_device_features13(
lhs: &vk::PhysicalDeviceVulkan13Features,
rhs: &vk::PhysicalDeviceVulkan13Features,
) -> vk::PhysicalDeviceVulkan13Features<'static> {
use core::ops::BitAnd;
vk::PhysicalDeviceVulkan13Features {
robust_image_access: lhs.robust_image_access.bitand(&rhs.robust_image_access),
inline_uniform_block: lhs.inline_uniform_block.bitand(&rhs.inline_uniform_block),
descriptor_binding_inline_uniform_block_update_after_bind: lhs
.descriptor_binding_inline_uniform_block_update_after_bind
.bitand(&rhs.descriptor_binding_inline_uniform_block_update_after_bind),
pipeline_creation_cache_control: lhs
.pipeline_creation_cache_control
.bitand(&rhs.pipeline_creation_cache_control),
private_data: lhs.private_data.bitand(&rhs.private_data),
shader_demote_to_helper_invocation: lhs
.shader_demote_to_helper_invocation
.bitand(&rhs.shader_demote_to_helper_invocation),
shader_terminate_invocation: lhs
.shader_terminate_invocation
.bitand(&rhs.shader_terminate_invocation),
subgroup_size_control: lhs.subgroup_size_control.bitand(&rhs.subgroup_size_control),
compute_full_subgroups: lhs
.compute_full_subgroups
.bitand(&rhs.compute_full_subgroups),
synchronization2: lhs.synchronization2.bitand(&rhs.synchronization2),
texture_compression_astc_hdr: lhs
.texture_compression_astc_hdr
.bitand(&rhs.texture_compression_astc_hdr),
shader_zero_initialize_workgroup_memory: lhs
.shader_zero_initialize_workgroup_memory
.bitand(&rhs.shader_zero_initialize_workgroup_memory),
dynamic_rendering: lhs.dynamic_rendering.bitand(&rhs.dynamic_rendering),
shader_integer_dot_product: lhs
.shader_integer_dot_product
.bitand(&rhs.shader_integer_dot_product),
maintenance4: lhs.maintenance4.bitand(&rhs.maintenance4),
..Default::default()
}
}
}