fix(vulkan-policy): report sampled formats and limits
This commit is contained in:
@@ -7,9 +7,9 @@ use std::ffi::CStr;
|
||||
use super::{VulkanInstanceProbe, VulkanSurfaceProbe};
|
||||
use crate::policy::{
|
||||
compare_reports, plan_vulkan_swapchain, validate_device_for_request, VulkanCapabilityError,
|
||||
VulkanCapabilityReport, VulkanDeviceType, VulkanPhysicalDeviceRecord, VulkanQueueFamily,
|
||||
VulkanSurfaceFormat, VulkanSwapchainError, VulkanSwapchainPlan, VulkanSwapchainRequest,
|
||||
VulkanSwapchainSurfaceCapabilities,
|
||||
VulkanCapabilityReport, VulkanDeviceLimits, VulkanDeviceType, VulkanPhysicalDeviceRecord,
|
||||
VulkanQueueFamily, VulkanSurfaceFormat, VulkanSwapchainError, VulkanSwapchainPlan,
|
||||
VulkanSwapchainRequest, VulkanSwapchainSurfaceCapabilities,
|
||||
};
|
||||
|
||||
/// Live Vulkan device/surface capability probe.
|
||||
@@ -242,6 +242,7 @@ fn live_device_candidate(
|
||||
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 sampled_image_formats = live_sampled_image_formats(instance, device);
|
||||
let queue_families = queue_properties
|
||||
.iter()
|
||||
.enumerate()
|
||||
@@ -284,6 +285,13 @@ fn live_device_candidate(
|
||||
present_modes: present_modes.clone(),
|
||||
surface_capabilities,
|
||||
supported_depth_stencil_formats,
|
||||
sampled_image_formats,
|
||||
limits: VulkanDeviceLimits {
|
||||
max_image_dimension_2d: properties.limits.max_image_dimension2_d,
|
||||
max_sampler_allocation_count: properties.limits.max_sampler_allocation_count,
|
||||
max_per_stage_descriptor_samplers: properties.limits.max_per_stage_descriptor_samplers,
|
||||
max_bound_descriptor_sets: properties.limits.max_bound_descriptor_sets,
|
||||
},
|
||||
};
|
||||
let capability = validate_device_for_request(&record, render_request)
|
||||
.map_err(VulkanRuntimeCapabilityError::Capability)?;
|
||||
@@ -468,3 +476,33 @@ fn live_depth_stencil_formats(
|
||||
.map(vk::Format::as_raw)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn live_sampled_image_formats(
|
||||
instance: &VulkanInstanceProbe,
|
||||
device: vk::PhysicalDevice,
|
||||
) -> Vec<i32> {
|
||||
[
|
||||
vk::Format::R8G8B8A8_SRGB,
|
||||
vk::Format::B8G8R8A8_SRGB,
|
||||
vk::Format::D16_UNORM,
|
||||
vk::Format::D32_SFLOAT,
|
||||
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::SAMPLED_IMAGE)
|
||||
})
|
||||
.map(vk::Format::as_raw)
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -317,6 +317,36 @@ fn capability_gate_respects_request_specific_depth_profiles() {
|
||||
assert!(report.rejected_devices.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capability_report_preserves_informational_sampled_formats_and_limits() {
|
||||
let report = select_physical_device(&[device(
|
||||
"Telemetry GPU",
|
||||
VulkanDeviceType::DiscreteGpu,
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
)])
|
||||
.expect("selected device");
|
||||
|
||||
assert_eq!(
|
||||
report.informational_capabilities.sampled_color_formats,
|
||||
vec![vk::Format::B8G8R8A8_SRGB.as_raw()]
|
||||
);
|
||||
assert_eq!(
|
||||
report.informational_capabilities.sampled_depth_formats,
|
||||
vec![vk::Format::D32_SFLOAT.as_raw()]
|
||||
);
|
||||
assert_eq!(
|
||||
report.informational_capabilities.limits,
|
||||
VulkanDeviceLimits {
|
||||
max_image_dimension_2d: 4096,
|
||||
max_sampler_allocation_count: 4096,
|
||||
max_per_stage_descriptor_samplers: 16,
|
||||
max_bound_descriptor_sets: 4,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn capability_report_json_is_stable() {
|
||||
let mut rejected = device("Rejected", VulkanDeviceType::IntegratedGpu, 0, true, false);
|
||||
@@ -329,7 +359,7 @@ fn capability_report_json_is_stable() {
|
||||
|
||||
assert_eq!(
|
||||
render_capability_report_json(&report),
|
||||
"{\"schema\":1,\"vulkan_api\":\"1.1.0\",\"device_name\":\"GPU \\\"A\\\"\",\"score\":1101,\"graphics_queue_family\":3,\"present_queue_family\":3,\"portability_subset\":false,\"enabled_extensions\":[\"VK_KHR_swapchain\"],\"rejected_devices\":[{\"device_name\":\"Rejected\",\"reason_code\":\"missing_present_mode\",\"reason\":\"Vulkan device Rejected has no supported present mode\"}]}"
|
||||
"{\"schema\":1,\"vulkan_api\":\"1.1.0\",\"device_name\":\"GPU \\\"A\\\"\",\"score\":1101,\"graphics_queue_family\":3,\"present_queue_family\":3,\"portability_subset\":false,\"enabled_extensions\":[\"VK_KHR_swapchain\"],\"informational_capabilities\":{\"sampled_color_formats\":[50],\"sampled_depth_formats\":[126],\"limits\":{\"max_image_dimension_2d\":4096,\"max_sampler_allocation_count\":4096,\"max_per_stage_descriptor_samplers\":16,\"max_bound_descriptor_sets\":4}},\"rejected_devices\":[{\"device_name\":\"Rejected\",\"reason_code\":\"missing_present_mode\",\"reason\":\"Vulkan device Rejected has no supported present mode\"}]}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -695,6 +725,16 @@ fn device(
|
||||
vk::Format::D32_SFLOAT_S8_UINT.as_raw(),
|
||||
vk::Format::D32_SFLOAT.as_raw(),
|
||||
],
|
||||
sampled_image_formats: vec![
|
||||
vk::Format::B8G8R8A8_SRGB.as_raw(),
|
||||
vk::Format::D32_SFLOAT.as_raw(),
|
||||
],
|
||||
limits: VulkanDeviceLimits {
|
||||
max_image_dimension_2d: 4096,
|
||||
max_sampler_allocation_count: 4096,
|
||||
max_per_stage_descriptor_samplers: 16,
|
||||
max_bound_descriptor_sets: 4,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user