librashader/librashader-runtime-vk/src/util.rs

107 lines
3 KiB
Rust
Raw Normal View History

2022-12-07 18:05:10 +11:00
use ash::vk;
use gpu_allocator::vulkan::{Allocator, AllocatorCreateDesc};
2023-02-10 13:03:55 +11:00
use parking_lot::RwLock;
use std::sync::Arc;
2023-01-13 17:48:04 +11:00
2023-01-14 08:10:54 +11:00
use crate::error;
use crate::error::FilterChainError;
2023-01-15 19:06:09 +11:00
use librashader_reflect::reflect::semantics::BindingStage;
2022-12-07 18:05:10 +11:00
pub fn binding_stage_to_vulkan_stage(stage_mask: BindingStage) -> vk::ShaderStageFlags {
let mut mask = vk::ShaderStageFlags::default();
if stage_mask.contains(BindingStage::VERTEX) {
mask |= vk::ShaderStageFlags::VERTEX;
}
if stage_mask.contains(BindingStage::FRAGMENT) {
mask |= vk::ShaderStageFlags::FRAGMENT;
}
mask
}
#[allow(unused)]
2022-12-22 13:39:31 +11:00
pub fn find_vulkan_memory_type(
props: &vk::PhysicalDeviceMemoryProperties,
device_reqs: u32,
host_reqs: vk::MemoryPropertyFlags,
2023-01-14 08:10:54 +11:00
) -> error::Result<u32> {
2022-12-07 18:05:10 +11:00
for i in 0..vk::MAX_MEMORY_TYPES {
if device_reqs & (1 << i) != 0
2022-12-22 13:39:31 +11:00
&& props.memory_types[i].property_flags & host_reqs == host_reqs
{
2023-01-14 08:10:54 +11:00
return Ok(i as u32);
2022-12-07 18:05:10 +11:00
}
}
if host_reqs == vk::MemoryPropertyFlags::empty() {
2023-01-14 08:10:54 +11:00
Err(FilterChainError::VulkanMemoryError(device_reqs))
2022-12-07 18:05:10 +11:00
} else {
2023-01-15 19:06:09 +11:00
Ok(find_vulkan_memory_type(
props,
device_reqs,
vk::MemoryPropertyFlags::empty(),
)?)
2022-12-07 18:05:10 +11:00
}
2022-12-22 13:13:35 +11:00
}
#[inline(always)]
2022-12-22 13:39:31 +11:00
pub unsafe fn vulkan_image_layout_transition_levels(
device: &ash::Device,
cmd: vk::CommandBuffer,
image: vk::Image,
levels: u32,
old_layout: vk::ImageLayout,
new_layout: vk::ImageLayout,
src_access: vk::AccessFlags,
dst_access: vk::AccessFlags,
src_stage: vk::PipelineStageFlags,
dst_stage: vk::PipelineStageFlags,
2022-12-22 13:13:35 +11:00
2022-12-22 13:39:31 +11:00
src_queue_family_index: u32,
dst_queue_family_index: u32,
) {
2022-12-22 13:13:35 +11:00
let mut barrier = vk::ImageMemoryBarrier::default();
barrier.s_type = vk::StructureType::IMAGE_MEMORY_BARRIER;
barrier.p_next = std::ptr::null();
barrier.src_access_mask = src_access;
barrier.dst_access_mask = dst_access;
barrier.old_layout = old_layout;
barrier.new_layout = new_layout;
barrier.src_queue_family_index = src_queue_family_index;
barrier.dst_queue_family_index = dst_queue_family_index;
2023-01-16 03:08:13 +11:00
barrier.image = image;
2022-12-22 13:13:35 +11:00
barrier.subresource_range.aspect_mask = vk::ImageAspectFlags::COLOR;
barrier.subresource_range.base_array_layer = 0;
barrier.subresource_range.level_count = levels;
barrier.subresource_range.layer_count = vk::REMAINING_ARRAY_LAYERS;
unsafe {
device.cmd_pipeline_barrier(
cmd,
src_stage,
dst_stage,
vk::DependencyFlags::empty(),
&[],
&[],
&[barrier],
)
}
2022-12-22 13:13:35 +11:00
}
pub fn create_allocator(
device: ash::Device,
instance: ash::Instance,
physical_device: vk::PhysicalDevice,
) -> error::Result<Arc<RwLock<Allocator>>> {
let alloc = Allocator::new(&AllocatorCreateDesc {
instance,
device,
physical_device,
debug_settings: Default::default(),
buffer_device_address: false,
})?;
Ok(Arc::new(RwLock::new(alloc)))
}