aboutsummaryrefslogtreecommitdiff
path: root/adapters/fparkan-render-vulkan/src
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-07-18 07:59:28 +0300
committerValentin Popov <valentin@popov.link>2026-07-18 07:59:28 +0300
commit9f6b21638d396783809bbd941d4cf0d548122995 (patch)
tree629ee6db9d2ac1d822b5c30177d50ca4927dde66 /adapters/fparkan-render-vulkan/src
parentb500e32ca2b35fbefbdd5c94a1cf782e309ed20a (diff)
downloadfparkan-9f6b21638d396783809bbd941d4cf0d548122995.tar.xz
fparkan-9f6b21638d396783809bbd941d4cf0d548122995.zip
feat(vulkan): select readback-capable swapchains
Diffstat (limited to 'adapters/fparkan-render-vulkan/src')
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/smoke.rs4
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs2
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/swapchain.rs2
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/tests.rs20
-rw-r--r--adapters/fparkan-render-vulkan/src/planning_backend.rs1
-rw-r--r--adapters/fparkan-render-vulkan/src/policy.rs16
6 files changed, 42 insertions, 3 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
index 4862ca0..0d5e6b4 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs
@@ -241,6 +241,7 @@ impl VulkanSmokeRenderer {
enabled_extension_count: 0,
swapchain_extent: (0, 0),
swapchain_image_count: 0,
+ swapchain_image_usage: 0,
},
};
renderer.rebuild_swapchain_resources(false)?;
@@ -268,6 +269,7 @@ impl VulkanSmokeRenderer {
.unwrap_or(u32::MAX),
swapchain_extent: swapchain_ref.report.plan.extent,
swapchain_image_count: swapchain_ref.report.image_count,
+ swapchain_image_usage: swapchain_ref.report.plan.image_usage,
};
Ok(renderer)
}
@@ -571,11 +573,13 @@ impl VulkanSmokeRenderer {
let frame_sync = create_frame_sync(device)?;
let swapchain_extent = self.swapchain_ref()?.report.plan.extent;
let swapchain_image_count = self.swapchain_ref()?.report.image_count;
+ let swapchain_image_usage = self.swapchain_ref()?.report.plan.image_usage;
let resources = resources.commit();
self.images_in_flight = vec![vk::Fence::null(); resources.image_views.len()];
self.frame_sync = frame_sync;
self.report.swapchain_extent = swapchain_extent;
self.report.swapchain_image_count = swapchain_image_count;
+ self.report.swapchain_image_usage = swapchain_image_usage;
self.swapchain_resources = Some(resources);
Ok(())
}
diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
index 70881d3..cbf978a 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/smoke_types.rs
@@ -457,6 +457,8 @@ pub struct VulkanSmokeRendererReport {
pub swapchain_extent: (u32, u32),
/// Current swapchain image count.
pub swapchain_image_count: u32,
+ /// Current swapchain image-usage flags as raw Vulkan bits.
+ pub swapchain_image_usage: u32,
}
/// Measured validation counters from the live smoke loop.
diff --git a/adapters/fparkan-render-vulkan/src/ffi/swapchain.rs b/adapters/fparkan-render-vulkan/src/ffi/swapchain.rs
index ca754d4..96ddedb 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/swapchain.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/swapchain.rs
@@ -185,7 +185,7 @@ pub fn create_vulkan_swapchain_probe_for_extent(
height: plan.extent.1,
})
.image_array_layers(1)
- .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
+ .image_usage(vk::ImageUsageFlags::from_raw(plan.image_usage))
.image_sharing_mode(sharing_mode)
.queue_family_indices(&queue_family_indices)
.pre_transform(raw_capabilities.current_transform)
diff --git a/adapters/fparkan-render-vulkan/src/ffi/tests.rs b/adapters/fparkan-render-vulkan/src/ffi/tests.rs
index 44e064b..0f6f5a8 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/tests.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/tests.rs
@@ -94,6 +94,7 @@ fn frame_submission_plan_json_is_stable() -> Result<(), RenderError> {
},
present_mode: vk::PresentModeKHR::FIFO.as_raw(),
image_count: 3,
+ image_usage: vk::ImageUsageFlags::COLOR_ATTACHMENT.as_raw(),
};
let plan = plan_vulkan_frame_submission(&swapchain, &commands)?;
@@ -543,6 +544,23 @@ fn swapchain_plan_prefers_srgb_mailbox_and_clamps_extent() {
assert_eq!(plan.present_mode, vk::PresentModeKHR::MAILBOX.as_raw());
assert_eq!(plan.extent, (1024, 720));
assert_eq!(plan.image_count, 3);
+ assert_eq!(
+ plan.image_usage,
+ vk::ImageUsageFlags::COLOR_ATTACHMENT.as_raw()
+ );
+}
+
+#[test]
+fn swapchain_plan_enables_transfer_source_when_surface_supports_it() {
+ let mut request = swapchain_request();
+ request.capabilities.supported_usage_flags |= vk::ImageUsageFlags::TRANSFER_SRC.as_raw();
+
+ let plan = plan_vulkan_swapchain(&request).expect("swapchain plan");
+
+ assert_eq!(
+ plan.image_usage,
+ (vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSFER_SRC).as_raw()
+ );
}
#[test]
@@ -606,7 +624,7 @@ fn swapchain_plan_json_and_recreation_reports_are_stable() {
let plan = plan_vulkan_swapchain(&swapchain_request()).expect("swapchain plan");
assert_eq!(
render_swapchain_plan_json(&plan),
- "{\"schema\":1,\"extent\":[1024,720],\"format\":50,\"color_space\":0,\"present_mode\":1,\"image_count\":3}"
+ "{\"schema\":1,\"extent\":[1024,720],\"format\":50,\"color_space\":0,\"present_mode\":1,\"image_count\":3,\"image_usage\":16}"
);
let report = swapchain_recreation_report(
diff --git a/adapters/fparkan-render-vulkan/src/planning_backend.rs b/adapters/fparkan-render-vulkan/src/planning_backend.rs
index b68b054..9a91712 100644
--- a/adapters/fparkan-render-vulkan/src/planning_backend.rs
+++ b/adapters/fparkan-render-vulkan/src/planning_backend.rs
@@ -163,5 +163,6 @@ fn default_stage0_swapchain_plan() -> VulkanSwapchainPlan {
},
present_mode: vk::PresentModeKHR::FIFO.as_raw(),
image_count: 2,
+ image_usage: vk::ImageUsageFlags::COLOR_ATTACHMENT.as_raw(),
}
}
diff --git a/adapters/fparkan-render-vulkan/src/policy.rs b/adapters/fparkan-render-vulkan/src/policy.rs
index bb26aee..c79b8dc 100644
--- a/adapters/fparkan-render-vulkan/src/policy.rs
+++ b/adapters/fparkan-render-vulkan/src/policy.rs
@@ -96,6 +96,8 @@ pub struct VulkanSwapchainPlan {
pub present_mode: i32,
/// Selected image count.
pub image_count: u32,
+ /// Selected image-usage flags as raw Vulkan bits.
+ pub image_usage: u32,
}
/// Swapchain planning error.
@@ -425,6 +427,7 @@ pub fn plan_vulkan_swapchain(
format,
present_mode,
image_count: select_image_count(request.capabilities),
+ image_usage: select_swapchain_image_usage(request.capabilities),
})
}
@@ -521,6 +524,7 @@ pub fn render_swapchain_plan_json(plan: &VulkanSwapchainPlan) -> String {
color_space: i32,
present_mode: i32,
image_count: u32,
+ image_usage: u32,
}
serialize_json_or_fallback(
@@ -531,8 +535,9 @@ pub fn render_swapchain_plan_json(plan: &VulkanSwapchainPlan) -> String {
color_space: plan.format.color_space,
present_mode: plan.present_mode,
image_count: plan.image_count,
+ image_usage: plan.image_usage,
},
- "{\"schema\":0,\"extent\":[0,0],\"format\":0,\"color_space\":0,\"present_mode\":0,\"image_count\":0}",
+ "{\"schema\":0,\"extent\":[0,0],\"format\":0,\"color_space\":0,\"present_mode\":0,\"image_count\":0,\"image_usage\":0}",
)
}
@@ -809,6 +814,15 @@ fn supports_depth_stencil_request(
select_depth_stencil_attachment_format(&device.supported_depth_stencil_formats, depth).is_some()
}
+fn select_swapchain_image_usage(capabilities: VulkanSwapchainSurfaceCapabilities) -> u32 {
+ let mut usage = vk::ImageUsageFlags::COLOR_ATTACHMENT;
+ let supported = vk::ImageUsageFlags::from_raw(capabilities.supported_usage_flags);
+ if supported.contains(vk::ImageUsageFlags::TRANSFER_SRC) {
+ usage |= vk::ImageUsageFlags::TRANSFER_SRC;
+ }
+ usage.as_raw()
+}
+
/// Selects the first canonical depth/stencil attachment format supported by a device.
///
/// The order is part of the Windows Vulkan compatibility contract and is shared