1599 lines
77 KiB
Rust
1599 lines
77 KiB
Rust
#![feature(
|
|
negative_impls,
|
|
map_try_insert,
|
|
debug_closure_helpers,
|
|
slice_partition_dedup
|
|
)]
|
|
|
|
use std::{collections::HashMap, fmt::Debug, path::PathBuf, sync::Arc};
|
|
|
|
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
|
|
|
use ash::{
|
|
ext,
|
|
prelude::VkResult,
|
|
vk::{self, SurfaceCapabilitiesKHR},
|
|
};
|
|
use dyn_clone::DynClone;
|
|
|
|
pub use ash;
|
|
|
|
mod buffers;
|
|
pub mod commands;
|
|
mod debug;
|
|
pub mod device;
|
|
#[path = "egui.rs"]
|
|
mod egui_pass;
|
|
mod images;
|
|
pub mod instance;
|
|
mod pipeline;
|
|
pub mod render_graph;
|
|
pub mod rendering;
|
|
pub mod swapchain;
|
|
pub mod sync;
|
|
mod text;
|
|
pub mod util;
|
|
|
|
use device::{Device, DeviceOwned};
|
|
|
|
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;
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum Error {
|
|
#[error("No Physical Device found for this instance.")]
|
|
NoAdapter,
|
|
#[error("Swapchain suboptimal.")]
|
|
SuboptimalSwapchain,
|
|
#[error(transparent)]
|
|
LoadingError(#[from] ash::LoadingError),
|
|
#[error(transparent)]
|
|
Result(#[from] ash::vk::Result),
|
|
#[error(transparent)]
|
|
CStrError(#[from] core::ffi::c_str::FromBytesUntilNulError),
|
|
#[error(transparent)]
|
|
Utf8Error(#[from] core::str::Utf8Error),
|
|
#[error(transparent)]
|
|
NulError(#[from] std::ffi::NulError),
|
|
#[error(transparent)]
|
|
GpuAllocatorError(#[from] gpu_allocator::AllocationError),
|
|
#[error("No Physical Device found.")]
|
|
NoPhysicalDevice,
|
|
#[error(transparent)]
|
|
Io(#[from] std::io::Error),
|
|
#[error(
|
|
"Image dimensions ({width}x{height}) exceed the maximum allowed size of {max_size}x{max_size}."
|
|
)]
|
|
ImageTooLarge {
|
|
width: u32,
|
|
height: u32,
|
|
max_size: u32,
|
|
},
|
|
#[error("Image dimensions cannot be zero.")]
|
|
ImageZeroSized,
|
|
#[error("Incompatible image view kind {view_kind:?} for image kind {image_kind:?}.")]
|
|
IncompatibleImageViewKind {
|
|
view_kind: vk::ImageViewType,
|
|
image_kind: vk::ImageType,
|
|
},
|
|
#[error("Asset missing at path {0:?}")]
|
|
AssetMissing(PathBuf),
|
|
#[error("Unspecified Error")]
|
|
Unspecified,
|
|
#[error("BEEP BOOP create an error variant for {0} BEEP BOOP")]
|
|
Todo(&'static str),
|
|
}
|
|
|
|
pub type Result<T> = core::result::Result<T, Error>;
|
|
|
|
#[derive(Debug, Clone)]
|
|
#[allow(dead_code)]
|
|
struct DeviceExtension<'a> {
|
|
name: &'a core::ffi::CStr,
|
|
version: u32,
|
|
}
|
|
|
|
/// returns true if lhs and rhs have the same name and lhs spec_version is less
|
|
/// than or equal to rhs spec_version
|
|
#[allow(dead_code)]
|
|
fn compatible_extension_properties(
|
|
lhs: &vk::ExtensionProperties,
|
|
rhs: &vk::ExtensionProperties,
|
|
) -> bool {
|
|
let Some(lhs_name) = lhs.extension_name_as_c_str().ok() else {
|
|
return false;
|
|
};
|
|
let Some(rhs_name) = rhs.extension_name_as_c_str().ok() else {
|
|
return false;
|
|
};
|
|
|
|
if lhs_name == rhs_name {
|
|
lhs.spec_version <= rhs.spec_version
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
|
|
pub mod queue;
|
|
|
|
pub trait ExtendsDeviceFeatures2Debug:
|
|
vk::ExtendsPhysicalDeviceFeatures2 + Debug + Send + Sync
|
|
{
|
|
}
|
|
pub trait ExtendsDeviceProperties2Debug:
|
|
vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync
|
|
{
|
|
}
|
|
|
|
impl<T: vk::ExtendsPhysicalDeviceFeatures2 + Debug + Send + Sync> ExtendsDeviceFeatures2Debug
|
|
for T
|
|
{
|
|
}
|
|
impl<T: vk::ExtendsPhysicalDeviceProperties2 + Debug + DynClone + Send + Sync>
|
|
ExtendsDeviceProperties2Debug for T
|
|
{
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct PhysicalDeviceInfo {
|
|
pub pdev: vk::PhysicalDevice,
|
|
pub properties: PhysicalDeviceProperties,
|
|
pub features: PhysicalDeviceFeatures,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct SurfaceCapabilities {
|
|
pub capabilities: SurfaceCapabilitiesKHR,
|
|
/// The minimum number of images that must be present in the swapchain for
|
|
/// the surface for any present mode supported by the surface.
|
|
pub min_image_count: u32,
|
|
pub formats: Vec<vk::SurfaceFormatKHR>,
|
|
pub present_modes: Vec<vk::PresentModeKHR>,
|
|
}
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct PhysicalDeviceFeatures {
|
|
pub core: vk::PhysicalDeviceFeatures,
|
|
pub core11: vk::PhysicalDeviceVulkan11Features<'static>,
|
|
pub core12: vk::PhysicalDeviceVulkan12Features<'static>,
|
|
pub core13: vk::PhysicalDeviceVulkan13Features<'static>,
|
|
pub mesh_shader: Option<vk::PhysicalDeviceMeshShaderFeaturesEXT<'static>>,
|
|
}
|
|
|
|
impl PhysicalDeviceFeatures {
|
|
pub fn push_to_device_create_info<'a>(
|
|
&'a mut self,
|
|
mut create_info: vk::DeviceCreateInfo<'a>,
|
|
) -> vk::DeviceCreateInfo<'a> {
|
|
create_info = create_info
|
|
.enabled_features(&self.core)
|
|
.push_next(&mut self.core11)
|
|
.push_next(&mut self.core12)
|
|
.push_next(&mut self.core13);
|
|
|
|
if let Some(mesh_shader) = &mut self.mesh_shader {
|
|
create_info = create_info.push_next(mesh_shader);
|
|
}
|
|
create_info
|
|
}
|
|
pub fn superset_of(&self, other: &PhysicalDeviceFeatures) -> bool {
|
|
fn core_superset_of(
|
|
a: &vk::PhysicalDeviceFeatures,
|
|
b: &vk::PhysicalDeviceFeatures,
|
|
) -> bool {
|
|
(b.robust_buffer_access == vk::FALSE
|
|
|| a.robust_buffer_access != b.robust_buffer_access)
|
|
&& (b.full_draw_index_uint32 == vk::FALSE
|
|
|| a.full_draw_index_uint32 != b.full_draw_index_uint32)
|
|
&& (b.image_cube_array == vk::FALSE || a.image_cube_array != b.image_cube_array)
|
|
&& (b.independent_blend == vk::FALSE || a.independent_blend != b.independent_blend)
|
|
&& (b.geometry_shader == vk::FALSE || a.geometry_shader != b.geometry_shader)
|
|
&& (b.tessellation_shader == vk::FALSE
|
|
|| a.tessellation_shader != b.tessellation_shader)
|
|
&& (b.sample_rate_shading == vk::FALSE
|
|
|| a.sample_rate_shading != b.sample_rate_shading)
|
|
&& (b.dual_src_blend == vk::FALSE || a.dual_src_blend != b.dual_src_blend)
|
|
&& (b.logic_op == vk::FALSE || a.logic_op != b.logic_op)
|
|
&& (b.multi_draw_indirect == vk::FALSE
|
|
|| a.multi_draw_indirect != b.multi_draw_indirect)
|
|
&& (b.draw_indirect_first_instance == vk::FALSE
|
|
|| a.draw_indirect_first_instance != b.draw_indirect_first_instance)
|
|
&& (b.depth_clamp == vk::FALSE || a.depth_clamp != b.depth_clamp)
|
|
&& (b.depth_bias_clamp == vk::FALSE || a.depth_bias_clamp != b.depth_bias_clamp)
|
|
&& (b.fill_mode_non_solid == vk::FALSE
|
|
|| a.fill_mode_non_solid != b.fill_mode_non_solid)
|
|
&& (b.depth_bounds == vk::FALSE || a.depth_bounds != b.depth_bounds)
|
|
&& (b.wide_lines == vk::FALSE || a.wide_lines != b.wide_lines)
|
|
&& (b.large_points == vk::FALSE || a.large_points != b.large_points)
|
|
&& (b.alpha_to_one == vk::FALSE || a.alpha_to_one != b.alpha_to_one)
|
|
&& (b.multi_viewport == vk::FALSE || a.multi_viewport != b.multi_viewport)
|
|
&& (b.sampler_anisotropy == vk::FALSE
|
|
|| a.sampler_anisotropy != b.sampler_anisotropy)
|
|
&& (b.texture_compression_etc2 == vk::FALSE
|
|
|| a.texture_compression_etc2 != b.texture_compression_etc2)
|
|
&& (b.texture_compression_astc_ldr == vk::FALSE
|
|
|| a.texture_compression_astc_ldr != b.texture_compression_astc_ldr)
|
|
&& (b.texture_compression_bc == vk::FALSE
|
|
|| a.texture_compression_bc != b.texture_compression_bc)
|
|
&& (b.occlusion_query_precise == vk::FALSE
|
|
|| a.occlusion_query_precise != b.occlusion_query_precise)
|
|
&& (b.pipeline_statistics_query == vk::FALSE
|
|
|| a.pipeline_statistics_query != b.pipeline_statistics_query)
|
|
&& (b.vertex_pipeline_stores_and_atomics == vk::FALSE
|
|
|| a.vertex_pipeline_stores_and_atomics != b.vertex_pipeline_stores_and_atomics)
|
|
&& (b.fragment_stores_and_atomics == vk::FALSE
|
|
|| a.fragment_stores_and_atomics != b.fragment_stores_and_atomics)
|
|
&& (b.shader_tessellation_and_geometry_point_size == vk::FALSE
|
|
|| a.shader_tessellation_and_geometry_point_size
|
|
!= b.shader_tessellation_and_geometry_point_size)
|
|
&& (b.shader_image_gather_extended == vk::FALSE
|
|
|| a.shader_image_gather_extended != b.shader_image_gather_extended)
|
|
&& (b.shader_storage_image_extended_formats == vk::FALSE
|
|
|| a.shader_storage_image_extended_formats
|
|
!= b.shader_storage_image_extended_formats)
|
|
&& (b.shader_storage_image_multisample == vk::FALSE
|
|
|| a.shader_storage_image_multisample != b.shader_storage_image_multisample)
|
|
&& (b.shader_storage_image_read_without_format == vk::FALSE
|
|
|| a.shader_storage_image_read_without_format
|
|
!= b.shader_storage_image_read_without_format)
|
|
&& (b.shader_storage_image_write_without_format == vk::FALSE
|
|
|| a.shader_storage_image_write_without_format
|
|
!= b.shader_storage_image_write_without_format)
|
|
&& (b.shader_uniform_buffer_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_uniform_buffer_array_dynamic_indexing
|
|
!= b.shader_uniform_buffer_array_dynamic_indexing)
|
|
&& (b.shader_sampled_image_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_sampled_image_array_dynamic_indexing
|
|
!= b.shader_sampled_image_array_dynamic_indexing)
|
|
&& (b.shader_storage_buffer_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_storage_buffer_array_dynamic_indexing
|
|
!= b.shader_storage_buffer_array_dynamic_indexing)
|
|
&& (b.shader_storage_image_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_storage_image_array_dynamic_indexing
|
|
!= b.shader_storage_image_array_dynamic_indexing)
|
|
&& (b.shader_clip_distance == vk::FALSE
|
|
|| a.shader_clip_distance != b.shader_clip_distance)
|
|
&& (b.shader_cull_distance == vk::FALSE
|
|
|| a.shader_cull_distance != b.shader_cull_distance)
|
|
&& (b.shader_float64 == vk::FALSE || a.shader_float64 != b.shader_float64)
|
|
&& (b.shader_int64 == vk::FALSE || a.shader_int64 != b.shader_int64)
|
|
&& (b.shader_int16 == vk::FALSE || a.shader_int16 != b.shader_int16)
|
|
&& (b.shader_resource_residency == vk::FALSE
|
|
|| a.shader_resource_residency != b.shader_resource_residency)
|
|
&& (b.shader_resource_min_lod == vk::FALSE
|
|
|| a.shader_resource_min_lod != b.shader_resource_min_lod)
|
|
&& (b.sparse_binding == vk::FALSE || a.sparse_binding != b.sparse_binding)
|
|
&& (b.sparse_residency_buffer == vk::FALSE
|
|
|| a.sparse_residency_buffer != b.sparse_residency_buffer)
|
|
&& (b.sparse_residency_image2_d == vk::FALSE
|
|
|| a.sparse_residency_image2_d != b.sparse_residency_image2_d)
|
|
&& (b.sparse_residency_image3_d == vk::FALSE
|
|
|| a.sparse_residency_image3_d != b.sparse_residency_image3_d)
|
|
&& (b.sparse_residency2_samples == vk::FALSE
|
|
|| a.sparse_residency2_samples != b.sparse_residency2_samples)
|
|
&& (b.sparse_residency4_samples == vk::FALSE
|
|
|| a.sparse_residency4_samples != b.sparse_residency4_samples)
|
|
&& (b.sparse_residency8_samples == vk::FALSE
|
|
|| a.sparse_residency8_samples != b.sparse_residency8_samples)
|
|
&& (b.sparse_residency16_samples == vk::FALSE
|
|
|| a.sparse_residency16_samples != b.sparse_residency16_samples)
|
|
&& (b.sparse_residency_aliased == vk::FALSE
|
|
|| a.sparse_residency_aliased != b.sparse_residency_aliased)
|
|
&& (b.variable_multisample_rate == vk::FALSE
|
|
|| a.variable_multisample_rate != b.variable_multisample_rate)
|
|
&& (b.inherited_queries == vk::FALSE || a.inherited_queries != b.inherited_queries)
|
|
}
|
|
|
|
fn core11_superset_of(
|
|
a: &vk::PhysicalDeviceVulkan11Features,
|
|
b: &vk::PhysicalDeviceVulkan11Features,
|
|
) -> bool {
|
|
(b.storage_buffer16_bit_access == vk::FALSE
|
|
|| a.storage_buffer16_bit_access != b.storage_buffer16_bit_access)
|
|
&& (b.uniform_and_storage_buffer16_bit_access == vk::FALSE
|
|
|| a.uniform_and_storage_buffer16_bit_access
|
|
!= b.uniform_and_storage_buffer16_bit_access)
|
|
&& (b.storage_push_constant16 == vk::FALSE
|
|
|| a.storage_push_constant16 != b.storage_push_constant16)
|
|
&& (b.storage_input_output16 == vk::FALSE
|
|
|| a.storage_input_output16 != b.storage_input_output16)
|
|
&& (b.multiview == vk::FALSE || a.multiview != b.multiview)
|
|
&& (b.multiview_geometry_shader == vk::FALSE
|
|
|| a.multiview_geometry_shader != b.multiview_geometry_shader)
|
|
&& (b.multiview_tessellation_shader == vk::FALSE
|
|
|| a.multiview_tessellation_shader != b.multiview_tessellation_shader)
|
|
&& (b.variable_pointers_storage_buffer == vk::FALSE
|
|
|| a.variable_pointers_storage_buffer != b.variable_pointers_storage_buffer)
|
|
&& (b.variable_pointers == vk::FALSE || a.variable_pointers != b.variable_pointers)
|
|
&& (b.protected_memory == vk::FALSE || a.protected_memory != b.protected_memory)
|
|
&& (b.sampler_ycbcr_conversion == vk::FALSE
|
|
|| a.sampler_ycbcr_conversion != b.sampler_ycbcr_conversion)
|
|
&& (b.shader_draw_parameters == vk::FALSE
|
|
|| a.shader_draw_parameters != b.shader_draw_parameters)
|
|
}
|
|
|
|
fn core12_superset_of(
|
|
a: &vk::PhysicalDeviceVulkan12Features,
|
|
b: &vk::PhysicalDeviceVulkan12Features,
|
|
) -> bool {
|
|
(b.sampler_mirror_clamp_to_edge == vk::FALSE
|
|
|| a.sampler_mirror_clamp_to_edge != b.sampler_mirror_clamp_to_edge)
|
|
&& (b.draw_indirect_count == vk::FALSE
|
|
|| a.draw_indirect_count != b.draw_indirect_count)
|
|
&& (b.storage_buffer8_bit_access == vk::FALSE
|
|
|| a.storage_buffer8_bit_access != b.storage_buffer8_bit_access)
|
|
&& (b.uniform_and_storage_buffer8_bit_access == vk::FALSE
|
|
|| a.uniform_and_storage_buffer8_bit_access
|
|
!= b.uniform_and_storage_buffer8_bit_access)
|
|
&& (b.storage_push_constant8 == vk::FALSE
|
|
|| a.storage_push_constant8 != b.storage_push_constant8)
|
|
&& (b.shader_buffer_int64_atomics == vk::FALSE
|
|
|| a.shader_buffer_int64_atomics != b.shader_buffer_int64_atomics)
|
|
&& (b.shader_shared_int64_atomics == vk::FALSE
|
|
|| a.shader_shared_int64_atomics != b.shader_shared_int64_atomics)
|
|
&& (b.shader_float16 == vk::FALSE || a.shader_float16 != b.shader_float16)
|
|
&& (b.shader_int8 == vk::FALSE || a.shader_int8 != b.shader_int8)
|
|
&& (b.descriptor_indexing == vk::FALSE
|
|
|| a.descriptor_indexing != b.descriptor_indexing)
|
|
&& (b.shader_input_attachment_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_input_attachment_array_dynamic_indexing
|
|
!= b.shader_input_attachment_array_dynamic_indexing)
|
|
&& (b.shader_uniform_texel_buffer_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_uniform_texel_buffer_array_dynamic_indexing
|
|
!= b.shader_uniform_texel_buffer_array_dynamic_indexing)
|
|
&& (b.shader_storage_texel_buffer_array_dynamic_indexing == vk::FALSE
|
|
|| a.shader_storage_texel_buffer_array_dynamic_indexing
|
|
!= b.shader_storage_texel_buffer_array_dynamic_indexing)
|
|
&& (b.shader_uniform_buffer_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_uniform_buffer_array_non_uniform_indexing
|
|
!= b.shader_uniform_buffer_array_non_uniform_indexing)
|
|
&& (b.shader_sampled_image_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_sampled_image_array_non_uniform_indexing
|
|
!= b.shader_sampled_image_array_non_uniform_indexing)
|
|
&& (b.shader_storage_buffer_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_storage_buffer_array_non_uniform_indexing
|
|
!= b.shader_storage_buffer_array_non_uniform_indexing)
|
|
&& (b.shader_storage_image_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_storage_image_array_non_uniform_indexing
|
|
!= b.shader_storage_image_array_non_uniform_indexing)
|
|
&& (b.shader_input_attachment_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_input_attachment_array_non_uniform_indexing
|
|
!= b.shader_input_attachment_array_non_uniform_indexing)
|
|
&& (b.shader_uniform_texel_buffer_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_uniform_texel_buffer_array_non_uniform_indexing
|
|
!= b.shader_uniform_texel_buffer_array_non_uniform_indexing)
|
|
&& (b.shader_storage_texel_buffer_array_non_uniform_indexing == vk::FALSE
|
|
|| a.shader_storage_texel_buffer_array_non_uniform_indexing
|
|
!= b.shader_storage_texel_buffer_array_non_uniform_indexing)
|
|
&& (b.descriptor_binding_uniform_buffer_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_uniform_buffer_update_after_bind
|
|
!= b.descriptor_binding_uniform_buffer_update_after_bind)
|
|
&& (b.descriptor_binding_sampled_image_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_sampled_image_update_after_bind
|
|
!= b.descriptor_binding_sampled_image_update_after_bind)
|
|
&& (b.descriptor_binding_storage_image_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_storage_image_update_after_bind
|
|
!= b.descriptor_binding_storage_image_update_after_bind)
|
|
&& (b.descriptor_binding_storage_buffer_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_storage_buffer_update_after_bind
|
|
!= b.descriptor_binding_storage_buffer_update_after_bind)
|
|
&& (b.descriptor_binding_uniform_texel_buffer_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_uniform_texel_buffer_update_after_bind
|
|
!= b.descriptor_binding_uniform_texel_buffer_update_after_bind)
|
|
&& (b.descriptor_binding_storage_texel_buffer_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_storage_texel_buffer_update_after_bind
|
|
!= b.descriptor_binding_storage_texel_buffer_update_after_bind)
|
|
&& (b.descriptor_binding_update_unused_while_pending == vk::FALSE
|
|
|| a.descriptor_binding_update_unused_while_pending
|
|
!= b.descriptor_binding_update_unused_while_pending)
|
|
&& (b.descriptor_binding_partially_bound == vk::FALSE
|
|
|| a.descriptor_binding_partially_bound != b.descriptor_binding_partially_bound)
|
|
&& (b.descriptor_binding_variable_descriptor_count == vk::FALSE
|
|
|| a.descriptor_binding_variable_descriptor_count
|
|
!= b.descriptor_binding_variable_descriptor_count)
|
|
&& (b.runtime_descriptor_array == vk::FALSE
|
|
|| a.runtime_descriptor_array != b.runtime_descriptor_array)
|
|
&& (b.sampler_filter_minmax == vk::FALSE
|
|
|| a.sampler_filter_minmax != b.sampler_filter_minmax)
|
|
&& (b.scalar_block_layout == vk::FALSE
|
|
|| a.scalar_block_layout != b.scalar_block_layout)
|
|
&& (b.imageless_framebuffer == vk::FALSE
|
|
|| a.imageless_framebuffer != b.imageless_framebuffer)
|
|
&& (b.uniform_buffer_standard_layout == vk::FALSE
|
|
|| a.uniform_buffer_standard_layout != b.uniform_buffer_standard_layout)
|
|
&& (b.shader_subgroup_extended_types == vk::FALSE
|
|
|| a.shader_subgroup_extended_types != b.shader_subgroup_extended_types)
|
|
&& (b.separate_depth_stencil_layouts == vk::FALSE
|
|
|| a.separate_depth_stencil_layouts != b.separate_depth_stencil_layouts)
|
|
&& (b.host_query_reset == vk::FALSE || a.host_query_reset != b.host_query_reset)
|
|
&& (b.timeline_semaphore == vk::FALSE
|
|
|| a.timeline_semaphore != b.timeline_semaphore)
|
|
&& (b.buffer_device_address == vk::FALSE
|
|
|| a.buffer_device_address != b.buffer_device_address)
|
|
&& (b.buffer_device_address_capture_replay == vk::FALSE
|
|
|| a.buffer_device_address_capture_replay
|
|
!= b.buffer_device_address_capture_replay)
|
|
&& (b.buffer_device_address_multi_device == vk::FALSE
|
|
|| a.buffer_device_address_multi_device != b.buffer_device_address_multi_device)
|
|
&& (b.vulkan_memory_model == vk::FALSE
|
|
|| a.vulkan_memory_model != b.vulkan_memory_model)
|
|
&& (b.vulkan_memory_model_device_scope == vk::FALSE
|
|
|| a.vulkan_memory_model_device_scope != b.vulkan_memory_model_device_scope)
|
|
&& (b.vulkan_memory_model_availability_visibility_chains == vk::FALSE
|
|
|| a.vulkan_memory_model_availability_visibility_chains
|
|
!= b.vulkan_memory_model_availability_visibility_chains)
|
|
&& (b.shader_output_viewport_index == vk::FALSE
|
|
|| a.shader_output_viewport_index != b.shader_output_viewport_index)
|
|
&& (b.shader_output_layer == vk::FALSE
|
|
|| a.shader_output_layer != b.shader_output_layer)
|
|
&& (b.subgroup_broadcast_dynamic_id == vk::FALSE
|
|
|| a.subgroup_broadcast_dynamic_id != b.subgroup_broadcast_dynamic_id)
|
|
}
|
|
|
|
fn core13_superset_of(
|
|
a: &vk::PhysicalDeviceVulkan13Features,
|
|
b: &vk::PhysicalDeviceVulkan13Features,
|
|
) -> bool {
|
|
(b.robust_image_access == vk::FALSE || a.robust_image_access != b.robust_image_access)
|
|
&& (b.inline_uniform_block == vk::FALSE
|
|
|| a.inline_uniform_block != b.inline_uniform_block)
|
|
&& (b.descriptor_binding_inline_uniform_block_update_after_bind == vk::FALSE
|
|
|| a.descriptor_binding_inline_uniform_block_update_after_bind
|
|
!= b.descriptor_binding_inline_uniform_block_update_after_bind)
|
|
&& (b.pipeline_creation_cache_control == vk::FALSE
|
|
|| a.pipeline_creation_cache_control != b.pipeline_creation_cache_control)
|
|
&& (b.private_data == vk::FALSE || a.private_data != b.private_data)
|
|
&& (b.shader_demote_to_helper_invocation == vk::FALSE
|
|
|| a.shader_demote_to_helper_invocation != b.shader_demote_to_helper_invocation)
|
|
&& (b.shader_terminate_invocation == vk::FALSE
|
|
|| a.shader_terminate_invocation != b.shader_terminate_invocation)
|
|
&& (b.subgroup_size_control == vk::FALSE
|
|
|| a.subgroup_size_control != b.subgroup_size_control)
|
|
&& (b.compute_full_subgroups == vk::FALSE
|
|
|| a.compute_full_subgroups != b.compute_full_subgroups)
|
|
&& (b.synchronization2 == vk::FALSE || a.synchronization2 != b.synchronization2)
|
|
&& (b.texture_compression_astc_hdr == vk::FALSE
|
|
|| a.texture_compression_astc_hdr != b.texture_compression_astc_hdr)
|
|
&& (b.shader_zero_initialize_workgroup_memory == vk::FALSE
|
|
|| a.shader_zero_initialize_workgroup_memory
|
|
!= b.shader_zero_initialize_workgroup_memory)
|
|
&& (b.dynamic_rendering == vk::FALSE || a.dynamic_rendering != b.dynamic_rendering)
|
|
&& (b.shader_integer_dot_product == vk::FALSE
|
|
|| a.shader_integer_dot_product != b.shader_integer_dot_product)
|
|
&& (b.maintenance4 == vk::FALSE || a.maintenance4 != b.maintenance4)
|
|
}
|
|
|
|
fn mesh_shader_superset_of(
|
|
a: &vk::PhysicalDeviceMeshShaderFeaturesEXT,
|
|
b: &vk::PhysicalDeviceMeshShaderFeaturesEXT,
|
|
) -> bool {
|
|
(b.task_shader == vk::FALSE || a.task_shader != b.task_shader)
|
|
&& (b.mesh_shader == vk::FALSE || a.mesh_shader != b.mesh_shader)
|
|
&& (b.multiview_mesh_shader == vk::FALSE
|
|
|| a.multiview_mesh_shader != b.multiview_mesh_shader)
|
|
&& (b.primitive_fragment_shading_rate_mesh_shader == vk::FALSE
|
|
|| a.primitive_fragment_shading_rate_mesh_shader
|
|
!= b.primitive_fragment_shading_rate_mesh_shader)
|
|
&& (b.mesh_shader_queries == vk::FALSE
|
|
|| a.mesh_shader_queries != b.mesh_shader_queries)
|
|
}
|
|
|
|
core_superset_of(&self.core, &other.core)
|
|
&& core11_superset_of(&self.core11, &other.core11)
|
|
&& core12_superset_of(&self.core12, &other.core12)
|
|
&& core13_superset_of(&self.core13, &other.core13)
|
|
&& match (&self.mesh_shader, &other.mesh_shader) {
|
|
(Some(a), Some(b)) => mesh_shader_superset_of(a, b),
|
|
(None, Some(_)) => false,
|
|
_ => true,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Default)]
|
|
pub struct PhysicalDeviceProperties {
|
|
/// Extensions supported by the device, as reported by `enumerate_device_extension_properties`.
|
|
supported_extensions: Vec<vk::ExtensionProperties>,
|
|
/// Vulkan 1.0 properties.
|
|
core: vk::PhysicalDeviceProperties,
|
|
/// Vulkan 1.1 properties.
|
|
core11: vk::PhysicalDeviceVulkan11Properties<'static>,
|
|
/// Vulkan 1.2 properties.
|
|
core12: vk::PhysicalDeviceVulkan12Properties<'static>,
|
|
/// Vulkan 1.3 properties.
|
|
core13: vk::PhysicalDeviceVulkan13Properties<'static>,
|
|
/// Mesh shader properties from the `VK_EXT_mesh_shader` extension, if supported.
|
|
mesh_shader: Option<vk::PhysicalDeviceMeshShaderPropertiesEXT<'static>>,
|
|
/// Memory properties of the device, as reported by `get_physical_device_memory_properties`.
|
|
memory_properties: vk::PhysicalDeviceMemoryProperties,
|
|
/// The API version supported by the device.
|
|
device_api_version: u32,
|
|
}
|
|
|
|
impl PhysicalDeviceProperties {
|
|
pub(crate) fn get_device_local_memory_count(&self) -> u64 {
|
|
self.memory_properties
|
|
.memory_heaps
|
|
.iter()
|
|
.filter(|heap| heap.flags.contains(vk::MemoryHeapFlags::DEVICE_LOCAL))
|
|
.map(|heap| heap.size)
|
|
.sum::<u64>()
|
|
}
|
|
}
|
|
|
|
fn get_physical_device_features(
|
|
instance: &InstanceInner,
|
|
pdev: vk::PhysicalDevice,
|
|
properties: &PhysicalDeviceProperties,
|
|
) -> PhysicalDeviceFeatures {
|
|
let mut features = PhysicalDeviceFeatures::default();
|
|
let mut features2 = vk::PhysicalDeviceFeatures2::default();
|
|
|
|
features2 = features2
|
|
.push_next(&mut features.core11)
|
|
.push_next(&mut features.core12)
|
|
.push_next(&mut features.core13);
|
|
|
|
if properties.supports_extension(make_extension!(ext::mesh_shader)) {
|
|
features2 = features2.push_next(
|
|
features
|
|
.mesh_shader
|
|
.insert(vk::PhysicalDeviceMeshShaderFeaturesEXT::default()),
|
|
);
|
|
}
|
|
|
|
unsafe {
|
|
instance
|
|
.raw
|
|
.get_physical_device_features2(pdev, &mut features2);
|
|
}
|
|
|
|
features.core = features2.features;
|
|
|
|
features
|
|
}
|
|
|
|
fn get_physical_device_properties(
|
|
instance: &InstanceInner,
|
|
pdev: vk::PhysicalDevice,
|
|
) -> Result<PhysicalDeviceProperties> {
|
|
let mut props = PhysicalDeviceProperties::default();
|
|
props.core = unsafe { instance.raw.get_physical_device_properties(pdev) };
|
|
props.device_api_version = props.core.api_version;
|
|
props.supported_extensions =
|
|
unsafe { instance.raw.enumerate_device_extension_properties(pdev)? };
|
|
props.memory_properties = unsafe { instance.raw.get_physical_device_memory_properties(pdev) };
|
|
|
|
let supports_mesh_shader = props.supports_extension(make_extension!(ext::mesh_shader));
|
|
|
|
// TODO: fallibly check anything beyond 1.0
|
|
let mut props2 = vk::PhysicalDeviceProperties2::default()
|
|
.push_next(&mut props.core11)
|
|
.push_next(&mut props.core12)
|
|
.push_next(&mut props.core13);
|
|
|
|
if supports_mesh_shader {
|
|
let next = props
|
|
.mesh_shader
|
|
.insert(vk::PhysicalDeviceMeshShaderPropertiesEXT::default());
|
|
props2 = props2.push_next(next);
|
|
}
|
|
|
|
unsafe {
|
|
instance
|
|
.raw
|
|
.get_physical_device_properties2(pdev, &mut props2);
|
|
}
|
|
|
|
Ok(props)
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub(crate) fn extension_intersection<'a>(
|
|
supported: &'a [vk::ExtensionProperties],
|
|
required: &[Extension<'a>],
|
|
) -> Vec<vk::ExtensionProperties> {
|
|
supported
|
|
.iter()
|
|
.filter(|ext| {
|
|
required.iter().any(|req| {
|
|
ext.extension_name_as_c_str() == Ok(req.name) && ext.spec_version >= req.version
|
|
})
|
|
})
|
|
.cloned()
|
|
.collect()
|
|
}
|
|
|
|
impl PhysicalDeviceProperties {
|
|
pub(crate) fn supports_extension(&self, e: Extension) -> bool {
|
|
self.supported_extensions
|
|
.iter()
|
|
.any(|ext| ext.extension_name_as_c_str() == Ok(e.name) && ext.spec_version >= e.version)
|
|
}
|
|
}
|
|
|
|
pub(crate) use instance::DebugUtils;
|
|
pub use instance::{DebugUtilsCreateInfo, Instance};
|
|
|
|
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_layout: Arc<pipeline::PipelineLayout>,
|
|
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 = 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),
|
|
pipeline_layout: Arc::new(pipeline_layout),
|
|
})
|
|
}
|
|
|
|
pub fn lookup_texture(&self, id: egui::epaint::TextureId) -> Option<texture::TextureId> {
|
|
self.textures.get(&id).map(|entry| entry.id)
|
|
}
|
|
}
|
|
|
|
pub struct Renderer2 {
|
|
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.pools.fences, None)?),
|
|
)?;
|
|
|
|
future.await;
|
|
|
|
// window.window.pre_present_notify();
|
|
let wait = Some(frame.release);
|
|
frame.present(wait)?;
|
|
|
|
Ok(out)
|
|
}
|
|
}
|
|
|
|
pub use vk::Extent2D;
|
|
|
|
use crate::{
|
|
device::Extension,
|
|
instance::{InstanceDesc, InstanceInner},
|
|
};
|
|
|
|
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()
|
|
}
|
|
}
|
|
}
|