1021 lines
48 KiB
Rust
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()
|
|
}
|
|
}
|
|
}
|