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
|
||||
/// for the device attached to the instance that will perform rendering.
|
||||
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.
|
||||
PFN_vkGetInstanceProcAddr entry;
|
||||
} libra_device_vk_t;
|
||||
|
|
|
@ -173,6 +173,7 @@ include = [
|
|||
|
||||
exclude = [
|
||||
"Option_ID3D11DeviceContext",
|
||||
"Option_PFN_vkGetInstanceProcAddr",
|
||||
"PMTLCommandQueue",
|
||||
"PMTLCommandBuffer",
|
||||
"PMTLTexture"
|
||||
|
@ -198,6 +199,7 @@ exclude = [
|
|||
"CommandBuffer" = "VkCommandBuffer"
|
||||
"Format" = "VkFormat"
|
||||
"Image" = "VkImage"
|
||||
"Queue" = "VkQueue"
|
||||
|
||||
# hack to get proper pointer indirection for COM pointers
|
||||
# we don't need one for ID3D11DeviceContext.
|
||||
|
@ -214,6 +216,9 @@ exclude = [
|
|||
# hack to force cbindgen to not generate option type for nullable 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
|
||||
"ID3D12Device" = "ID3D12Device *"
|
||||
"ID3D12Resource" = "ID3D12Resource *"
|
||||
|
|
|
@ -15,9 +15,9 @@ use std::slice;
|
|||
use librashader::runtime::FilterChainParameters;
|
||||
use librashader::runtime::{Size, Viewport};
|
||||
|
||||
use ash::vk;
|
||||
|
||||
use crate::LIBRASHADER_API_VERSION;
|
||||
use ash::vk;
|
||||
use ash::vk::Handle;
|
||||
pub use ash::vk::PFN_vkGetInstanceProcAddr;
|
||||
|
||||
/// 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
|
||||
/// for the device attached to the instance that will perform rendering.
|
||||
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.
|
||||
pub entry: vk::PFN_vkGetInstanceProcAddr,
|
||||
pub entry: Option<vk::PFN_vkGetInstanceProcAddr>,
|
||||
}
|
||||
|
||||
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 {
|
||||
fn from(value: libra_device_vk_t) -> Self {
|
||||
let queue = if value.queue.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(value.queue)
|
||||
};
|
||||
|
||||
VulkanInstance {
|
||||
device: value.device,
|
||||
instance: value.instance,
|
||||
physical_device: value.physical_device,
|
||||
get_instance_proc_addr: value.entry,
|
||||
queue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ use thiserror::Error;
|
|||
#[derive(Error, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum FilterChainError {
|
||||
#[error("a vulkan handle that is required to be not null is null")]
|
||||
HandleIsNull,
|
||||
#[error("shader preset parse error")]
|
||||
ShaderPresetError(#[from] ParsePresetError),
|
||||
#[error("shader preprocess error")]
|
||||
|
|
|
@ -13,39 +13,38 @@ use crate::{error, memory, util};
|
|||
use ash::vk;
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
|
||||
use ash::vk::Handle;
|
||||
use gpu_allocator::vulkan::Allocator;
|
||||
use librashader_cache::CachedCompilation;
|
||||
use librashader_common::map::FastHashMap;
|
||||
use librashader_presets::context::VideoDriver;
|
||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||
use librashader_reflect::back::targets::SPIRV;
|
||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||
use librashader_reflect::front::SpirvCompilation;
|
||||
use librashader_reflect::reflect::cross::SpirvCross;
|
||||
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
||||
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||
use librashader_reflect::reflect::ReflectShader;
|
||||
use librashader_runtime::binding::BindingUtil;
|
||||
use librashader_runtime::framebuffer::FramebufferInit;
|
||||
use librashader_runtime::image::{Image, ImageError, UVDirection, BGRA8};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use librashader_runtime::render_target::RenderTarget;
|
||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use parking_lot::Mutex;
|
||||
use rayon::prelude::*;
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::Infallible;
|
||||
use std::path::Path;
|
||||
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.
|
||||
pub struct VulkanObjects {
|
||||
pub(crate) device: Arc<ash::Device>,
|
||||
pub(crate) alloc: Arc<Mutex<Allocator>>,
|
||||
queue: vk::Queue,
|
||||
// pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
|
||||
}
|
||||
|
||||
/// A collection of handles needed to access the Vulkan instance.
|
||||
|
@ -58,27 +57,43 @@ pub struct VulkanInstance {
|
|||
/// A `VkPhysicalDevice` handle.
|
||||
pub physical_device: vk::PhysicalDevice,
|
||||
/// 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 {
|
||||
type Error = 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 {
|
||||
let instance = ash::Instance::load(
|
||||
&ash::StaticFn {
|
||||
get_instance_proc_addr: vulkan.get_instance_proc_addr,
|
||||
get_instance_proc_addr,
|
||||
},
|
||||
vulkan.instance,
|
||||
);
|
||||
|
||||
let device = ash::Device::load(instance.fp_v1_0(), vulkan.device);
|
||||
|
||||
let queue = get_graphics_queue(&instance, &device, vulkan.physical_device);
|
||||
|
||||
// let memory_properties =
|
||||
// instance.get_physical_device_memory_properties(vulkan.physical_device);
|
||||
let queue = vulkan.queue.unwrap_or(get_graphics_queue(
|
||||
&instance,
|
||||
&device,
|
||||
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),
|
||||
alloc,
|
||||
queue,
|
||||
// memory_properties,
|
||||
// debug,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -97,20 +110,47 @@ impl TryFrom<(vk::PhysicalDevice, ash::Instance, ash::Device)> for VulkanObjects
|
|||
type Error = FilterChainError;
|
||||
|
||||
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 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)?;
|
||||
|
||||
Ok(VulkanObjects {
|
||||
alloc,
|
||||
device: Arc::new(device),
|
||||
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
|
||||
// );
|
||||
|
||||
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
|
||||
.frame(
|
||||
&VulkanImage {
|
||||
|
@ -244,17 +254,7 @@ impl VulkanWindow {
|
|||
image: framebuffer_image,
|
||||
format: vulkan.swapchain.format.format,
|
||||
},
|
||||
&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(),
|
||||
},
|
||||
&viewport,
|
||||
cmd,
|
||||
frame,
|
||||
Some(&FrameOptionsVulkan {
|
||||
|
|
Loading…
Reference in a new issue