vk: do own queue selection and fix error type
This commit is contained in:
parent
455b56ce8e
commit
40b9f08234
|
@ -1,3 +1,25 @@
|
||||||
use std::error::Error;
|
use librashader_preprocess::PreprocessError;
|
||||||
|
use librashader_presets::ParsePresetError;
|
||||||
|
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
|
||||||
|
use librashader_runtime::image::ImageError;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
#[derive(Error, Debug)]
|
||||||
|
pub enum FilterChainError {
|
||||||
|
#[error("SPIRV reflection error")]
|
||||||
|
SpirvCrossReflectError(#[from] spirv_cross::ErrorCode),
|
||||||
|
#[error("shader preset parse error")]
|
||||||
|
ShaderPresetError(#[from] ParsePresetError),
|
||||||
|
#[error("shader preprocess error")]
|
||||||
|
ShaderPreprocessError(#[from] PreprocessError),
|
||||||
|
#[error("shader compile error")]
|
||||||
|
ShaderCompileError(#[from] ShaderCompileError),
|
||||||
|
#[error("shader reflect error")]
|
||||||
|
ShaderReflectError(#[from] ShaderReflectError),
|
||||||
|
#[error("lut loading error")]
|
||||||
|
LutLoadError(#[from] ImageError),
|
||||||
|
#[error("vulkan error")]
|
||||||
|
VulkanResult(#[from] ash::vk::Result),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = std::result::Result<T, FilterChainError>;
|
||||||
|
|
|
@ -4,18 +4,14 @@ use crate::framebuffer::OutputImage;
|
||||||
use crate::luts::LutTexture;
|
use crate::luts::LutTexture;
|
||||||
use crate::render_target::{RenderTarget, DEFAULT_MVP};
|
use crate::render_target::{RenderTarget, DEFAULT_MVP};
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::texture::{InputImage, OwnedImage, OwnedImageLayout, VulkanImage};
|
use crate::texture::{InputImage, OwnedImage, VulkanImage};
|
||||||
use crate::ubo_ring::VkUboRing;
|
use crate::ubo_ring::VkUboRing;
|
||||||
use crate::viewport::Viewport;
|
use crate::viewport::Viewport;
|
||||||
use crate::vulkan_state::VulkanGraphicsPipeline;
|
use crate::vulkan_state::VulkanGraphicsPipeline;
|
||||||
use crate::{error, util};
|
use crate::{error, util};
|
||||||
use ash::extensions::ext::DebugUtils;
|
use ash::extensions::ext::DebugUtils;
|
||||||
use ash::vk::{
|
use ash::vk;
|
||||||
CommandPoolCreateFlags, DebugUtilsObjectNameInfoEXT, Handle, PFN_vkGetInstanceProcAddr, Queue,
|
use librashader_common::{ImageFormat, Size};
|
||||||
StaticFn,
|
|
||||||
};
|
|
||||||
use ash::{vk, Device, Entry};
|
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::SpirV;
|
use librashader_reflect::back::targets::SpirV;
|
||||||
|
@ -29,16 +25,15 @@ use librashader_runtime::image::{Image, UVDirection};
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::error::Error;
|
|
||||||
use std::ffi::CStr;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use crate::error::FilterChainError;
|
||||||
|
use crate::queue_selection::get_graphics_queue;
|
||||||
|
|
||||||
pub struct Vulkan {
|
pub struct Vulkan {
|
||||||
// physical_device: vk::PhysicalDevice,
|
// physical_device: vk::PhysicalDevice,
|
||||||
pub(crate) device: ash::Device,
|
pub(crate) device: ash::Device,
|
||||||
// instance: ash::Instance,
|
// instance: ash::Instance,
|
||||||
queue: vk::Queue,
|
queue: vk::Queue,
|
||||||
command_pool: vk::CommandPool,
|
|
||||||
pipeline_cache: vk::PipelineCache,
|
pipeline_cache: vk::PipelineCache,
|
||||||
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
||||||
// debug: DebugUtils,
|
// debug: DebugUtils,
|
||||||
|
@ -51,57 +46,47 @@ type ShaderPassMeta = (
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VulkanInfo<'a> {
|
pub struct VulkanInfo {
|
||||||
// physical_device: &'a vk::PhysicalDevice,
|
device: vk::Device,
|
||||||
device: &'a vk::Device,
|
instance: vk::Instance,
|
||||||
instance: &'a vk::Instance,
|
physical_device: vk::PhysicalDevice,
|
||||||
queue: &'a vk::Queue,
|
get_instance_proc_addr: vk::PFN_vkGetInstanceProcAddr,
|
||||||
memory_properties: &'a vk::PhysicalDeviceMemoryProperties,
|
|
||||||
get_instance_proc_addr: PFN_vkGetInstanceProcAddr,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<VulkanInfo<'_>> for Vulkan {
|
impl TryFrom<VulkanInfo> for Vulkan {
|
||||||
type Error = Box<dyn Error>;
|
type Error = FilterChainError;
|
||||||
|
|
||||||
fn try_from(vulkan: VulkanInfo) -> Result<Self, Box<dyn Error>> {
|
fn try_from(vulkan: VulkanInfo) -> Result<Self, FilterChainError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let instance = ash::Instance::load(
|
let instance = ash::Instance::load(
|
||||||
&StaticFn {
|
&vk::StaticFn {
|
||||||
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
||||||
},
|
},
|
||||||
vulkan.instance.clone(),
|
vulkan.instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
let device = ash::Device::load(instance.fp_v1_0(), vulkan.device.clone());
|
let device = ash::Device::load(instance.fp_v1_0(), vulkan.device);
|
||||||
|
|
||||||
let pipeline_cache = unsafe {
|
let pipeline_cache = unsafe {
|
||||||
device.create_pipeline_cache(&vk::PipelineCacheCreateInfo::default(), None)?
|
device.create_pipeline_cache(&vk::PipelineCacheCreateInfo::default(), None)?
|
||||||
};
|
};
|
||||||
|
|
||||||
// the queue is only used for lut loading.. we may want to select our own queue.
|
|
||||||
let command_pool = unsafe {
|
|
||||||
device.create_command_pool(
|
|
||||||
&vk::CommandPoolCreateInfo::builder()
|
|
||||||
.flags(CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
|
|
||||||
.build(),
|
|
||||||
None,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let debug = DebugUtils::new(
|
let debug = DebugUtils::new(
|
||||||
&Entry::from_static_fn(StaticFn {
|
&ash::Entry::from_static_fn(vk::StaticFn {
|
||||||
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
||||||
}),
|
}),
|
||||||
&instance,
|
&instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let queue = get_graphics_queue(&instance, &device, vulkan.physical_device);
|
||||||
|
let memory_properties = instance.get_physical_device_memory_properties(vulkan.physical_device);
|
||||||
|
|
||||||
Ok(Vulkan {
|
Ok(Vulkan {
|
||||||
device,
|
device,
|
||||||
// instance,
|
// instance,
|
||||||
queue: vulkan.queue.clone(),
|
queue,
|
||||||
command_pool,
|
|
||||||
pipeline_cache,
|
pipeline_cache,
|
||||||
memory_properties: vulkan.memory_properties.clone(),
|
memory_properties,
|
||||||
// debug,
|
// debug,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -110,44 +95,36 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
|
||||||
|
|
||||||
impl
|
impl
|
||||||
TryFrom<(
|
TryFrom<(
|
||||||
|
vk::PhysicalDevice,
|
||||||
|
ash::Instance,
|
||||||
ash::Device,
|
ash::Device,
|
||||||
vk::Queue,
|
|
||||||
vk::PhysicalDeviceMemoryProperties,
|
|
||||||
DebugUtils,
|
|
||||||
)> for Vulkan
|
)> for Vulkan
|
||||||
{
|
{
|
||||||
type Error = Box<dyn Error>;
|
type Error = FilterChainError;
|
||||||
|
|
||||||
fn try_from(
|
fn try_from(
|
||||||
value: (
|
value: (
|
||||||
Device,
|
vk::PhysicalDevice,
|
||||||
Queue,
|
ash::Instance,
|
||||||
vk::PhysicalDeviceMemoryProperties,
|
ash::Device,
|
||||||
DebugUtils,
|
|
||||||
),
|
),
|
||||||
) -> error::Result<Self> {
|
) -> error::Result<Self> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let device = value.0;
|
let device = value.2;
|
||||||
|
|
||||||
let pipeline_cache = unsafe {
|
let pipeline_cache = unsafe {
|
||||||
device.create_pipeline_cache(&vk::PipelineCacheCreateInfo::default(), None)?
|
device.create_pipeline_cache(&vk::PipelineCacheCreateInfo::default(), None)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let command_pool = unsafe {
|
let queue = get_graphics_queue(&value.1, &device, value.0);
|
||||||
device.create_command_pool(
|
|
||||||
&vk::CommandPoolCreateInfo::builder()
|
let memory_properties = value.1.get_physical_device_memory_properties(value.0);
|
||||||
.flags(CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
|
|
||||||
.build(),
|
|
||||||
None,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Vulkan {
|
Ok(Vulkan {
|
||||||
device,
|
device,
|
||||||
queue: value.1,
|
queue,
|
||||||
command_pool,
|
|
||||||
pipeline_cache,
|
pipeline_cache,
|
||||||
memory_properties: value.2,
|
memory_properties,
|
||||||
// debug: value.3,
|
// debug: value.3,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -227,7 +204,7 @@ pub type FilterChainOptionsVulkan = ();
|
||||||
impl FilterChainVulkan {
|
impl FilterChainVulkan {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub fn load_from_path(
|
||||||
vulkan: impl TryInto<Vulkan, Error = Box<dyn Error>>,
|
vulkan: impl TryInto<Vulkan, Error = FilterChainError>,
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan> {
|
) -> error::Result<FilterChainVulkan> {
|
||||||
|
@ -237,7 +214,7 @@ impl FilterChainVulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_from_preset(
|
pub fn load_from_preset(
|
||||||
vulkan: impl TryInto<Vulkan, Error = Box<dyn Error>>,
|
vulkan: impl TryInto<Vulkan, Error = FilterChainError>,
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan> {
|
) -> error::Result<FilterChainVulkan> {
|
||||||
|
@ -325,7 +302,7 @@ impl FilterChainVulkan {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok::<_, Box<dyn Error>>((shader, source, reflect))
|
Ok::<_, FilterChainError>((shader, source, reflect))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
.collect::<error::Result<Vec<(ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
||||||
|
@ -431,11 +408,21 @@ impl FilterChainVulkan {
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureConfig],
|
||||||
) -> error::Result<FxHashMap<usize, LutTexture>> {
|
) -> error::Result<FxHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FxHashMap::default();
|
let mut luts = FxHashMap::default();
|
||||||
|
|
||||||
|
let command_pool = unsafe {
|
||||||
|
vulkan.device.create_command_pool(
|
||||||
|
&vk::CommandPoolCreateInfo::builder()
|
||||||
|
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
|
||||||
|
.build(),
|
||||||
|
None,
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
let command_buffer = unsafe {
|
let command_buffer = unsafe {
|
||||||
// panic safety: command buffer count = 1
|
// panic safety: command buffer count = 1
|
||||||
vulkan.device.allocate_command_buffers(
|
vulkan.device.allocate_command_buffers(
|
||||||
&vk::CommandBufferAllocateInfo::builder()
|
&vk::CommandBufferAllocateInfo::builder()
|
||||||
.command_pool(vulkan.command_pool)
|
.command_pool(command_pool)
|
||||||
.level(vk::CommandBufferLevel::PRIMARY)
|
.level(vk::CommandBufferLevel::PRIMARY)
|
||||||
.command_buffer_count(1)
|
.command_buffer_count(1)
|
||||||
.build(),
|
.build(),
|
||||||
|
@ -454,7 +441,7 @@ impl FilterChainVulkan {
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.iter().enumerate() {
|
||||||
let image = Image::load(&texture.path, UVDirection::TopLeft)?;
|
let image = Image::load(&texture.path, UVDirection::TopLeft)?;
|
||||||
|
|
||||||
let texture = LutTexture::new(vulkan, &command_buffer, image, texture)?;
|
let texture = LutTexture::new(vulkan, command_buffer, image, texture)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,9 +455,13 @@ impl FilterChainVulkan {
|
||||||
.device
|
.device
|
||||||
.queue_submit(vulkan.queue, &submits, vk::Fence::null())?;
|
.queue_submit(vulkan.queue, &submits, vk::Fence::null())?;
|
||||||
vulkan.device.queue_wait_idle(vulkan.queue)?;
|
vulkan.device.queue_wait_idle(vulkan.queue)?;
|
||||||
|
|
||||||
vulkan
|
vulkan
|
||||||
.device
|
.device
|
||||||
.free_command_buffers(vulkan.command_pool, &buffers);
|
.free_command_buffers(command_pool, &buffers);
|
||||||
|
|
||||||
|
vulkan.device
|
||||||
|
.destroy_command_pool(command_pool, None);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,8 +347,7 @@ impl VulkanWindow {
|
||||||
.queue_present(vulkan.base.graphics_queue, &present_info)
|
.queue_present(vulkan.base.graphics_queue, &present_info)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
//oops i pooped my pants
|
|
||||||
// std::mem::forget(intermediates);
|
|
||||||
vulkan.base.device.device_wait_idle().unwrap();
|
vulkan.base.device.device_wait_idle().unwrap();
|
||||||
drop(intermediates)
|
drop(intermediates)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_dev
|
||||||
use crate::hello_triangle::surface::VulkanSurface;
|
use crate::hello_triangle::surface::VulkanSurface;
|
||||||
use ash::prelude::VkResult;
|
use ash::prelude::VkResult;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
use crate::error::FilterChainError;
|
||||||
|
|
||||||
const WINDOW_TITLE: &'static [u8] = b"librashader Vulkan\0";
|
const WINDOW_TITLE: &'static [u8] = b"librashader Vulkan\0";
|
||||||
const KHRONOS_VALIDATION: &'static [u8] = b"VK_LAYER_KHRONOS_validation\0";
|
const KHRONOS_VALIDATION: &'static [u8] = b"VK_LAYER_KHRONOS_validation\0";
|
||||||
|
@ -162,14 +163,13 @@ impl Drop for VulkanBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&VulkanBase> for Vulkan {
|
impl TryFrom<&VulkanBase> for Vulkan {
|
||||||
type Error = Box<dyn Error>;
|
type Error = FilterChainError;
|
||||||
|
|
||||||
fn try_from(value: &VulkanBase) -> Result<Self, Self::Error> {
|
fn try_from(value: &VulkanBase) -> Result<Self, Self::Error> {
|
||||||
Vulkan::try_from((
|
Vulkan::try_from((
|
||||||
|
value.physical_device,
|
||||||
|
value.instance.clone(),
|
||||||
value.device.clone(),
|
value.device.clone(),
|
||||||
value.graphics_queue.clone(),
|
|
||||||
value.mem_props,
|
|
||||||
value.debug.loader.clone(),
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
|
|
||||||
mod draw_quad;
|
mod draw_quad;
|
||||||
mod error;
|
|
||||||
mod filter_chain;
|
mod filter_chain;
|
||||||
mod filter_pass;
|
mod filter_pass;
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
#[cfg(test)]
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
mod luts;
|
mod luts;
|
||||||
mod render_target;
|
mod render_target;
|
||||||
|
@ -17,6 +17,14 @@ mod util;
|
||||||
mod viewport;
|
mod viewport;
|
||||||
mod vulkan_primitives;
|
mod vulkan_primitives;
|
||||||
mod vulkan_state;
|
mod vulkan_state;
|
||||||
|
mod queue_selection;
|
||||||
|
|
||||||
|
pub use filter_chain::FilterChainFrameIntermediates;
|
||||||
|
pub use filter_chain::FilterChainVulkan;
|
||||||
|
pub use viewport::Viewport;
|
||||||
|
|
||||||
|
pub mod error;
|
||||||
|
pub mod options;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub struct LutTexture {
|
||||||
impl LutTexture {
|
impl LutTexture {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vulkan: &Vulkan,
|
vulkan: &Vulkan,
|
||||||
cmd: &vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
image: Image<BGRA8>,
|
image: Image<BGRA8>,
|
||||||
config: &TextureConfig,
|
config: &TextureConfig,
|
||||||
) -> error::Result<LutTexture> {
|
) -> error::Result<LutTexture> {
|
||||||
|
@ -97,7 +97,7 @@ impl LutTexture {
|
||||||
unsafe {
|
unsafe {
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&vulkan.device,
|
&vulkan.device,
|
||||||
*cmd,
|
cmd,
|
||||||
texture,
|
texture,
|
||||||
vk::REMAINING_MIP_LEVELS,
|
vk::REMAINING_MIP_LEVELS,
|
||||||
vk::ImageLayout::UNDEFINED,
|
vk::ImageLayout::UNDEFINED,
|
||||||
|
@ -115,7 +115,7 @@ impl LutTexture {
|
||||||
);
|
);
|
||||||
|
|
||||||
vulkan.device.cmd_copy_buffer_to_image(
|
vulkan.device.cmd_copy_buffer_to_image(
|
||||||
*cmd,
|
cmd,
|
||||||
staging.handle,
|
staging.handle,
|
||||||
texture,
|
texture,
|
||||||
if config.mipmap {
|
if config.mipmap {
|
||||||
|
@ -183,7 +183,7 @@ impl LutTexture {
|
||||||
unsafe {
|
unsafe {
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&vulkan.device,
|
&vulkan.device,
|
||||||
*cmd,
|
cmd,
|
||||||
texture,
|
texture,
|
||||||
vk::REMAINING_MIP_LEVELS,
|
vk::REMAINING_MIP_LEVELS,
|
||||||
vk::ImageLayout::GENERAL,
|
vk::ImageLayout::GENERAL,
|
||||||
|
@ -198,13 +198,13 @@ impl LutTexture {
|
||||||
|
|
||||||
// todo: respect mipmap filter?
|
// todo: respect mipmap filter?
|
||||||
vulkan.device.cmd_blit_image(
|
vulkan.device.cmd_blit_image(
|
||||||
*cmd,
|
cmd,
|
||||||
texture,
|
texture,
|
||||||
vk::ImageLayout::GENERAL,
|
vk::ImageLayout::GENERAL,
|
||||||
texture,
|
texture,
|
||||||
vk::ImageLayout::GENERAL,
|
vk::ImageLayout::GENERAL,
|
||||||
&image_blit,
|
&image_blit,
|
||||||
vk::Filter::LINEAR,
|
config.filter_mode.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ impl LutTexture {
|
||||||
unsafe {
|
unsafe {
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
&vulkan.device,
|
&vulkan.device,
|
||||||
*cmd,
|
cmd,
|
||||||
texture,
|
texture,
|
||||||
vk::REMAINING_MIP_LEVELS,
|
vk::REMAINING_MIP_LEVELS,
|
||||||
if config.mipmap {
|
if config.mipmap {
|
||||||
|
|
0
librashader-runtime-vk/src/options.rs
Normal file
0
librashader-runtime-vk/src/options.rs
Normal file
24
librashader-runtime-vk/src/queue_selection.rs
Normal file
24
librashader-runtime-vk/src/queue_selection.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
use ash::vk;
|
||||||
|
|
||||||
|
fn find_graphics_queue_family(
|
||||||
|
instance: &ash::Instance,
|
||||||
|
physical_device: vk::PhysicalDevice,
|
||||||
|
) -> u32 {
|
||||||
|
let queue_families =
|
||||||
|
unsafe { instance.get_physical_device_queue_family_properties(physical_device) };
|
||||||
|
// find the most specialized transfer queue.
|
||||||
|
for (index, queue_family) in queue_families.iter().enumerate() {
|
||||||
|
if queue_family.queue_count > 0
|
||||||
|
&& queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS)
|
||||||
|
{
|
||||||
|
return index as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_graphics_queue(instance: &ash::Instance, device: &ash::Device, physical_device: vk::PhysicalDevice) -> vk::Queue {
|
||||||
|
let queue_family = find_graphics_queue_family(instance, physical_device);
|
||||||
|
unsafe { device.get_device_queue(queue_family, 0) }
|
||||||
|
}
|
Loading…
Reference in a new issue