aboutsummaryrefslogtreecommitdiff
path: root/adapters/fparkan-render-vulkan/src/ffi/capabilities.rs
diff options
context:
space:
mode:
Diffstat (limited to 'adapters/fparkan-render-vulkan/src/ffi/capabilities.rs')
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/capabilities.rs87
1 files changed, 76 insertions, 11 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/capabilities.rs b/adapters/fparkan-render-vulkan/src/ffi/capabilities.rs
index 94fb3a6..c0de225 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/capabilities.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/capabilities.rs
@@ -1,11 +1,12 @@
#![allow(unsafe_code)]
use ash::vk;
+use fparkan_platform::RenderRequest;
use std::ffi::CStr;
use super::{VulkanInstanceProbe, VulkanSurfaceProbe};
use crate::policy::{
- compare_reports, plan_vulkan_swapchain, validate_device, VulkanCapabilityError,
+ compare_reports, plan_vulkan_swapchain, validate_device_for_request, VulkanCapabilityError,
VulkanCapabilityReport, VulkanDeviceType, VulkanPhysicalDeviceRecord, VulkanQueueFamily,
VulkanSurfaceFormat, VulkanSwapchainError, VulkanSwapchainPlan, VulkanSwapchainRequest,
VulkanSwapchainSurfaceCapabilities,
@@ -133,14 +134,42 @@ pub fn probe_vulkan_runtime_capabilities(
surface: &VulkanSurfaceProbe,
drawable_extent: (u32, u32),
) -> Result<VulkanRuntimeCapabilityProbe, VulkanRuntimeCapabilityError> {
- let selected = select_live_device_candidate(instance, surface, drawable_extent)?;
+ let selected = select_live_device_candidate_for_request(
+ instance,
+ surface,
+ drawable_extent,
+ &RenderRequest::conservative(),
+ )?;
+ Ok(selected.runtime)
+}
+
+/// Probes live Vulkan device, queue, surface and swapchain capabilities for a
+/// specific Stage 0 render request.
+///
+/// # Errors
+///
+/// Returns [`VulkanRuntimeCapabilityError`] when device enumeration, surface
+/// capability queries, Stage 0 device selection, or swapchain planning fails.
+pub fn probe_vulkan_runtime_capabilities_for_request(
+ instance: &VulkanInstanceProbe,
+ surface: &VulkanSurfaceProbe,
+ drawable_extent: (u32, u32),
+ render_request: &RenderRequest,
+) -> Result<VulkanRuntimeCapabilityProbe, VulkanRuntimeCapabilityError> {
+ let selected = select_live_device_candidate_for_request(
+ instance,
+ surface,
+ drawable_extent,
+ render_request,
+ )?;
Ok(selected.runtime)
}
-pub(super) fn select_live_device_candidate(
+pub(super) fn select_live_device_candidate_for_request(
instance: &VulkanInstanceProbe,
surface: &VulkanSurfaceProbe,
drawable_extent: (u32, u32),
+ render_request: &RenderRequest,
) -> Result<SelectedLiveDevice, VulkanRuntimeCapabilityError> {
let devices = {
// SAFETY: The Vulkan instance is live for this query and no handles are retained.
@@ -151,13 +180,14 @@ pub(super) fn select_live_device_candidate(
let mut best: Option<LiveDeviceCandidate> = None;
let mut last_error = None;
for (index, device) in devices.iter().copied().enumerate() {
- let candidate = match live_device_candidate(instance, surface, device, index) {
- Ok(candidate) => candidate,
- Err(err) => {
- last_error = Some(err);
- continue;
- }
- };
+ let candidate =
+ match live_device_candidate(instance, surface, device, index, render_request) {
+ Ok(candidate) => candidate,
+ Err(err) => {
+ last_error = Some(err);
+ continue;
+ }
+ };
match &best {
Some(existing)
if compare_reports(&candidate.capability, &existing.capability)
@@ -192,6 +222,7 @@ fn live_device_candidate(
surface: &VulkanSurfaceProbe,
device: vk::PhysicalDevice,
index: usize,
+ render_request: &RenderRequest,
) -> Result<LiveDeviceCandidate, VulkanRuntimeCapabilityError> {
let properties = {
// SAFETY: `device` was returned by this live instance and the result is copied by value.
@@ -210,6 +241,7 @@ fn live_device_candidate(
let surface_formats = live_surface_formats(surface, device, &name)?;
let present_modes = live_present_modes(surface, device, &name)?;
let surface_capabilities = live_surface_capabilities(surface, device, &name)?;
+ let supported_depth_stencil_formats = live_depth_stencil_formats(instance, device);
let queue_families = queue_properties
.iter()
.enumerate()
@@ -251,8 +283,10 @@ fn live_device_candidate(
surface_formats: surface_formats.clone(),
present_modes: present_modes.clone(),
surface_capabilities,
+ supported_depth_stencil_formats,
};
- let capability = validate_device(&record).map_err(VulkanRuntimeCapabilityError::Capability)?;
+ let capability = validate_device_for_request(&record, render_request)
+ .map_err(VulkanRuntimeCapabilityError::Capability)?;
Ok(LiveDeviceCandidate {
physical_device: device,
capability,
@@ -403,3 +437,34 @@ pub(super) fn live_surface_capabilities(
supported_usage_flags: capabilities.supported_usage_flags.as_raw(),
})
}
+
+fn live_depth_stencil_formats(
+ instance: &VulkanInstanceProbe,
+ device: vk::PhysicalDevice,
+) -> Vec<i32> {
+ [
+ vk::Format::D16_UNORM,
+ vk::Format::X8_D24_UNORM_PACK32,
+ vk::Format::D32_SFLOAT,
+ vk::Format::S8_UINT,
+ vk::Format::D16_UNORM_S8_UINT,
+ vk::Format::D24_UNORM_S8_UINT,
+ vk::Format::D32_SFLOAT_S8_UINT,
+ ]
+ .into_iter()
+ .filter(|format| {
+ let properties = {
+ // SAFETY: `device` belongs to `instance`; format-property queries copy data by value.
+ unsafe {
+ instance
+ .instance
+ .get_physical_device_format_properties(device, *format)
+ }
+ };
+ properties
+ .optimal_tiling_features
+ .contains(vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT)
+ })
+ .map(vk::Format::as_raw)
+ .collect()
+}