rt(vk): allow specifying the queue to use
This commit is contained in:
parent
16108838b1
commit
aeb0a16cfb
|
@ -268,6 +268,9 @@ typedef struct libra_device_vk_t {
|
||||||
/// A raw `VkDevice` handle
|
/// A raw `VkDevice` handle
|
||||||
/// for the device attached to the instance that will perform rendering.
|
/// for the device attached to the instance that will perform rendering.
|
||||||
VkDevice device;
|
VkDevice device;
|
||||||
|
/// The queue to use, if this is `NULL`, then
|
||||||
|
/// a suitable queue will be chosen.
|
||||||
|
VkQueue queue;
|
||||||
/// The entry loader for the Vulkan library.
|
/// The entry loader for the Vulkan library.
|
||||||
PFN_vkGetInstanceProcAddr entry;
|
PFN_vkGetInstanceProcAddr entry;
|
||||||
} libra_device_vk_t;
|
} libra_device_vk_t;
|
||||||
|
|
|
@ -173,6 +173,7 @@ include = [
|
||||||
|
|
||||||
exclude = [
|
exclude = [
|
||||||
"Option_ID3D11DeviceContext",
|
"Option_ID3D11DeviceContext",
|
||||||
|
"Option_PFN_vkGetInstanceProcAddr",
|
||||||
"PMTLCommandQueue",
|
"PMTLCommandQueue",
|
||||||
"PMTLCommandBuffer",
|
"PMTLCommandBuffer",
|
||||||
"PMTLTexture"
|
"PMTLTexture"
|
||||||
|
@ -198,6 +199,7 @@ exclude = [
|
||||||
"CommandBuffer" = "VkCommandBuffer"
|
"CommandBuffer" = "VkCommandBuffer"
|
||||||
"Format" = "VkFormat"
|
"Format" = "VkFormat"
|
||||||
"Image" = "VkImage"
|
"Image" = "VkImage"
|
||||||
|
"Queue" = "VkQueue"
|
||||||
|
|
||||||
# hack to get proper pointer indirection for COM pointers
|
# hack to get proper pointer indirection for COM pointers
|
||||||
# we don't need one for ID3D11DeviceContext.
|
# we don't need one for ID3D11DeviceContext.
|
||||||
|
@ -214,6 +216,9 @@ exclude = [
|
||||||
# hack to force cbindgen to not generate option type for nullable ID3D11DeviceContext.
|
# hack to force cbindgen to not generate option type for nullable ID3D11DeviceContext.
|
||||||
"Option_ID3D11DeviceContext" = "ID3D11DeviceContext *"
|
"Option_ID3D11DeviceContext" = "ID3D11DeviceContext *"
|
||||||
|
|
||||||
|
# hack to force cbindgen to not generate option type for nullable PFN_vkGetInstanceProcAddr.
|
||||||
|
"Option_PFN_vkGetInstanceProcAddr" = "PFN_vkGetInstanceProcAddr"
|
||||||
|
|
||||||
# hack to get proper pointer indirection for COM pointers
|
# hack to get proper pointer indirection for COM pointers
|
||||||
"ID3D12Device" = "ID3D12Device *"
|
"ID3D12Device" = "ID3D12Device *"
|
||||||
"ID3D12Resource" = "ID3D12Resource *"
|
"ID3D12Resource" = "ID3D12Resource *"
|
||||||
|
|
|
@ -15,9 +15,9 @@ use std::slice;
|
||||||
use librashader::runtime::FilterChainParameters;
|
use librashader::runtime::FilterChainParameters;
|
||||||
use librashader::runtime::{Size, Viewport};
|
use librashader::runtime::{Size, Viewport};
|
||||||
|
|
||||||
use ash::vk;
|
|
||||||
|
|
||||||
use crate::LIBRASHADER_API_VERSION;
|
use crate::LIBRASHADER_API_VERSION;
|
||||||
|
use ash::vk;
|
||||||
|
use ash::vk::Handle;
|
||||||
pub use ash::vk::PFN_vkGetInstanceProcAddr;
|
pub use ash::vk::PFN_vkGetInstanceProcAddr;
|
||||||
|
|
||||||
/// A Vulkan instance function loader that the Vulkan filter chain needs to be initialized with.
|
/// A Vulkan instance function loader that the Vulkan filter chain needs to be initialized with.
|
||||||
|
@ -49,8 +49,11 @@ pub struct libra_device_vk_t {
|
||||||
/// A raw `VkDevice` handle
|
/// A raw `VkDevice` handle
|
||||||
/// for the device attached to the instance that will perform rendering.
|
/// for the device attached to the instance that will perform rendering.
|
||||||
pub device: vk::Device,
|
pub device: vk::Device,
|
||||||
|
/// The queue to use, if this is `NULL`, then
|
||||||
|
/// a suitable queue will be chosen. This must be a graphics queue.
|
||||||
|
pub queue: vk::Queue,
|
||||||
/// The entry loader for the Vulkan library.
|
/// The entry loader for the Vulkan library.
|
||||||
pub entry: vk::PFN_vkGetInstanceProcAddr,
|
pub entry: Option<vk::PFN_vkGetInstanceProcAddr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<libra_image_vk_t> for VulkanImage {
|
impl From<libra_image_vk_t> for VulkanImage {
|
||||||
|
@ -65,11 +68,18 @@ impl From<libra_image_vk_t> for VulkanImage {
|
||||||
|
|
||||||
impl From<libra_device_vk_t> for VulkanInstance {
|
impl From<libra_device_vk_t> for VulkanInstance {
|
||||||
fn from(value: libra_device_vk_t) -> Self {
|
fn from(value: libra_device_vk_t) -> Self {
|
||||||
|
let queue = if value.queue.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(value.queue)
|
||||||
|
};
|
||||||
|
|
||||||
VulkanInstance {
|
VulkanInstance {
|
||||||
device: value.device,
|
device: value.device,
|
||||||
instance: value.instance,
|
instance: value.instance,
|
||||||
physical_device: value.physical_device,
|
physical_device: value.physical_device,
|
||||||
get_instance_proc_addr: value.entry,
|
get_instance_proc_addr: value.entry,
|
||||||
|
queue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ use thiserror::Error;
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum FilterChainError {
|
pub enum FilterChainError {
|
||||||
|
#[error("a vulkan handle that is required to be not null is null")]
|
||||||
|
HandleIsNull,
|
||||||
#[error("shader preset parse error")]
|
#[error("shader preset parse error")]
|
||||||
ShaderPresetError(#[from] ParsePresetError),
|
ShaderPresetError(#[from] ParsePresetError),
|
||||||
#[error("shader preprocess error")]
|
#[error("shader preprocess error")]
|
||||||
|
|
|
@ -13,39 +13,38 @@ use crate::{error, memory, util};
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
|
|
||||||
|
use ash::vk::Handle;
|
||||||
use gpu_allocator::vulkan::Allocator;
|
use gpu_allocator::vulkan::Allocator;
|
||||||
|
use librashader_cache::CachedCompilation;
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
|
use librashader_presets::context::VideoDriver;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::SPIRV;
|
use librashader_reflect::back::targets::SPIRV;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::SpirvCompilation;
|
use librashader_reflect::front::SpirvCompilation;
|
||||||
|
use librashader_reflect::reflect::cross::SpirvCross;
|
||||||
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
||||||
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::binding::BindingUtil;
|
use librashader_runtime::binding::BindingUtil;
|
||||||
|
use librashader_runtime::framebuffer::FramebufferInit;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection, BGRA8};
|
use librashader_runtime::image::{Image, ImageError, UVDirection, BGRA8};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
|
use librashader_runtime::render_target::RenderTarget;
|
||||||
|
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
use rayon::prelude::*;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use librashader_cache::CachedCompilation;
|
|
||||||
use librashader_presets::context::VideoDriver;
|
|
||||||
use librashader_reflect::reflect::cross::SpirvCross;
|
|
||||||
use librashader_runtime::framebuffer::FramebufferInit;
|
|
||||||
use librashader_runtime::render_target::RenderTarget;
|
|
||||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
|
||||||
use rayon::prelude::*;
|
|
||||||
|
|
||||||
/// A Vulkan device and metadata that is required by the shader runtime.
|
/// A Vulkan device and metadata that is required by the shader runtime.
|
||||||
pub struct VulkanObjects {
|
pub struct VulkanObjects {
|
||||||
pub(crate) device: Arc<ash::Device>,
|
pub(crate) device: Arc<ash::Device>,
|
||||||
pub(crate) alloc: Arc<Mutex<Allocator>>,
|
pub(crate) alloc: Arc<Mutex<Allocator>>,
|
||||||
queue: vk::Queue,
|
queue: vk::Queue,
|
||||||
// pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of handles needed to access the Vulkan instance.
|
/// A collection of handles needed to access the Vulkan instance.
|
||||||
|
@ -58,27 +57,43 @@ pub struct VulkanInstance {
|
||||||
/// A `VkPhysicalDevice` handle.
|
/// A `VkPhysicalDevice` handle.
|
||||||
pub physical_device: vk::PhysicalDevice,
|
pub physical_device: vk::PhysicalDevice,
|
||||||
/// A function pointer to the Vulkan library entry point.
|
/// A function pointer to the Vulkan library entry point.
|
||||||
pub get_instance_proc_addr: vk::PFN_vkGetInstanceProcAddr,
|
/// If this is `None`, [`FilterChainError::HandleIsNull`] will be returned.
|
||||||
|
pub get_instance_proc_addr: Option<vk::PFN_vkGetInstanceProcAddr>,
|
||||||
|
/// The graphics queue to use to submit commands. If this is `None`,
|
||||||
|
/// a queue will be chosen.
|
||||||
|
pub queue: Option<vk::Queue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<VulkanInstance> for VulkanObjects {
|
impl TryFrom<VulkanInstance> for VulkanObjects {
|
||||||
type Error = FilterChainError;
|
type Error = FilterChainError;
|
||||||
|
|
||||||
fn try_from(vulkan: VulkanInstance) -> Result<Self, FilterChainError> {
|
fn try_from(vulkan: VulkanInstance) -> Result<Self, FilterChainError> {
|
||||||
|
if vulkan.queue.is_some_and(|q| q.is_null())
|
||||||
|
|| vulkan.device.is_null()
|
||||||
|
|| vulkan.instance.is_null()
|
||||||
|
{
|
||||||
|
return Err(FilterChainError::HandleIsNull);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(get_instance_proc_addr) = vulkan.get_instance_proc_addr else {
|
||||||
|
return Err(FilterChainError::HandleIsNull);
|
||||||
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let instance = ash::Instance::load(
|
let instance = ash::Instance::load(
|
||||||
&ash::StaticFn {
|
&ash::StaticFn {
|
||||||
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
get_instance_proc_addr,
|
||||||
},
|
},
|
||||||
vulkan.instance,
|
vulkan.instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
let device = ash::Device::load(instance.fp_v1_0(), vulkan.device);
|
let device = ash::Device::load(instance.fp_v1_0(), vulkan.device);
|
||||||
|
|
||||||
let queue = get_graphics_queue(&instance, &device, vulkan.physical_device);
|
let queue = vulkan.queue.unwrap_or(get_graphics_queue(
|
||||||
|
&instance,
|
||||||
// let memory_properties =
|
&device,
|
||||||
// instance.get_physical_device_memory_properties(vulkan.physical_device);
|
vulkan.physical_device,
|
||||||
|
));
|
||||||
|
|
||||||
let alloc = memory::create_allocator(device.clone(), instance, vulkan.physical_device)?;
|
let alloc = memory::create_allocator(device.clone(), instance, vulkan.physical_device)?;
|
||||||
|
|
||||||
|
@ -86,8 +101,6 @@ impl TryFrom<VulkanInstance> for VulkanObjects {
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
alloc,
|
alloc,
|
||||||
queue,
|
queue,
|
||||||
// memory_properties,
|
|
||||||
// debug,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,20 +110,47 @@ impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device)> for VulkanObjects
|
||||||
type Error = FilterChainError;
|
type Error = FilterChainError;
|
||||||
|
|
||||||
fn try_from(value: (vk::PhysicalDevice, ash::Instance, ash::Device)) -> error::Result<Self> {
|
fn try_from(value: (vk::PhysicalDevice, ash::Instance, ash::Device)) -> error::Result<Self> {
|
||||||
|
if value.0.is_null() {
|
||||||
|
return Err(FilterChainError::HandleIsNull);
|
||||||
|
}
|
||||||
|
|
||||||
let device = value.2;
|
let device = value.2;
|
||||||
|
|
||||||
let queue = get_graphics_queue(&value.1, &device, value.0);
|
let queue = get_graphics_queue(&value.1, &device, value.0);
|
||||||
|
|
||||||
// let memory_properties = value.1.get_physical_device_memory_properties(value.0);
|
|
||||||
|
|
||||||
let alloc = memory::create_allocator(device.clone(), value.1, value.0)?;
|
let alloc = memory::create_allocator(device.clone(), value.1, value.0)?;
|
||||||
|
|
||||||
Ok(VulkanObjects {
|
Ok(VulkanObjects {
|
||||||
alloc,
|
alloc,
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
queue,
|
queue,
|
||||||
// memory_properties,
|
})
|
||||||
// debug: value.3,
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device, vk::Queue)> for VulkanObjects {
|
||||||
|
type Error = FilterChainError;
|
||||||
|
|
||||||
|
fn try_from(
|
||||||
|
value: (vk::PhysicalDevice, ash::Instance, ash::Device, vk::Queue),
|
||||||
|
) -> error::Result<Self> {
|
||||||
|
if value.0.is_null() {
|
||||||
|
return Err(FilterChainError::HandleIsNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
let device = value.2;
|
||||||
|
let queue = if value.3.is_null() {
|
||||||
|
get_graphics_queue(&value.1, &device, value.0)
|
||||||
|
} else {
|
||||||
|
value.3
|
||||||
|
};
|
||||||
|
|
||||||
|
let alloc = memory::create_allocator(device.clone(), value.1, value.0)?;
|
||||||
|
|
||||||
|
Ok(VulkanObjects {
|
||||||
|
alloc,
|
||||||
|
device: Arc::new(device),
|
||||||
|
queue,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,16 @@ impl VulkanWindow {
|
||||||
// vk::QUEUE_FAMILY_IGNORED
|
// vk::QUEUE_FAMILY_IGNORED
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
let viewport = Viewport::new_render_target_sized_origin(
|
||||||
|
VulkanImage {
|
||||||
|
size: vulkan.swapchain.extent.into(),
|
||||||
|
image: swapchain_image,
|
||||||
|
format: vulkan.swapchain.format.format,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
filter
|
filter
|
||||||
.frame(
|
.frame(
|
||||||
&VulkanImage {
|
&VulkanImage {
|
||||||
|
@ -244,17 +254,7 @@ impl VulkanWindow {
|
||||||
image: framebuffer_image,
|
image: framebuffer_image,
|
||||||
format: vulkan.swapchain.format.format,
|
format: vulkan.swapchain.format.format,
|
||||||
},
|
},
|
||||||
&Viewport {
|
&viewport,
|
||||||
x: 0.0,
|
|
||||||
y: 0.0,
|
|
||||||
output: VulkanImage {
|
|
||||||
size: vulkan.swapchain.extent.into(),
|
|
||||||
image: swapchain_image,
|
|
||||||
format: vulkan.swapchain.format.format,
|
|
||||||
},
|
|
||||||
mvp: None,
|
|
||||||
size: vulkan.swapchain.extent.into(),
|
|
||||||
},
|
|
||||||
cmd,
|
cmd,
|
||||||
frame,
|
frame,
|
||||||
Some(&FrameOptionsVulkan {
|
Some(&FrameOptionsVulkan {
|
||||||
|
|
Loading…
Reference in a new issue