refactor(vulkan-backend): satisfy ci quality gates

This commit is contained in:
2026-06-25 06:57:26 +04:00
parent 4d0cb594a7
commit 8f8fa426d5
3 changed files with 101 additions and 75 deletions
@@ -216,77 +216,45 @@ pub(super) fn create_swapchain_resources(
result: error, result: error,
})?; })?;
let mut partial = PartialSwapchainResources { let mut partial = PartialSwapchainResources {
image_views: Vec::with_capacity(images.len()), image_views: create_swapchain_image_views(
device,
&images,
swapchain.report.plan.format.format,
)?,
render_pass: None, render_pass: None,
pipeline_layout: None, pipeline_layout: None,
pipeline: None, pipeline: None,
framebuffers: Vec::with_capacity(images.len()), framebuffers: Vec::new(),
command_buffers: Vec::new(), command_buffers: Vec::new(),
}; };
for image in images.iter().copied() { let (render_pass, pipeline_layout, pipeline) = match create_swapchain_pipeline_bundle(
match create_image_view(device, image, swapchain.report.plan.format.format) { device,
Ok(image_view) => partial.image_views.push(image_view), swapchain.report.plan.format.format,
Err(error) => { swapchain.report.plan.extent,
destroy_partial_swapchain_resources(device, command_pool, partial); ) {
return Err(error); Ok(bundle) => bundle,
}
}
}
let render_pass = match create_render_pass(device, swapchain.report.plan.format.format) {
Ok(render_pass) => render_pass,
Err(error) => { Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial); destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error); return Err(error);
} }
}; };
partial.render_pass = Some(render_pass); partial.render_pass = Some(render_pass);
let pipeline_layout = match create_pipeline_layout(device) {
Ok(pipeline_layout) => pipeline_layout,
Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error);
}
};
partial.pipeline_layout = Some(pipeline_layout); partial.pipeline_layout = Some(pipeline_layout);
let pipeline = match create_graphics_pipeline( partial.pipeline = Some(pipeline);
let framebuffers = match create_swapchain_framebuffers(
device, device,
render_pass, render_pass,
pipeline_layout, &partial.image_views,
swapchain.report.plan.extent, swapchain.report.plan.extent,
) { ) {
Ok(pipeline) => pipeline, Ok(framebuffers) => framebuffers,
Err(error) => { Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial); destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error); return Err(error);
} }
}; };
partial.pipeline = Some(pipeline); partial.framebuffers = framebuffers;
for image_view in partial.image_views.iter().copied() { reset_reusable_command_pool(device, command_pool, reuse_command_pool)?;
match create_framebuffer(
device,
render_pass,
image_view,
swapchain.report.plan.extent,
) {
Ok(framebuffer) => partial.framebuffers.push(framebuffer),
Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error);
}
}
}
if reuse_command_pool {
// SAFETY: All command buffers allocated from the live pool are freed before reallocating them.
unsafe {
device
.device()
.reset_command_pool(command_pool, vk::CommandPoolResetFlags::empty())
}
.map_err(|error| VulkanSmokeRendererError::VulkanOperation {
context: "vkResetCommandPool",
result: error,
})?;
}
let command_buffers = match allocate_command_buffers( let command_buffers = match allocate_command_buffers(
device, device,
command_pool, command_pool,
@@ -310,6 +278,85 @@ pub(super) fn create_swapchain_resources(
}) })
} }
fn create_swapchain_image_views(
device: &VulkanLogicalDeviceProbe,
images: &[vk::Image],
format: i32,
) -> Result<Vec<vk::ImageView>, VulkanSmokeRendererError> {
let mut image_views = Vec::with_capacity(images.len());
for image in images.iter().copied() {
image_views.push(create_image_view(device, image, format)?);
}
Ok(image_views)
}
fn create_swapchain_pipeline_bundle(
device: &VulkanLogicalDeviceProbe,
format: i32,
extent: (u32, u32),
) -> Result<(vk::RenderPass, vk::PipelineLayout, vk::Pipeline), VulkanSmokeRendererError> {
let render_pass = create_render_pass(device, format)?;
let pipeline_layout = create_pipeline_layout(device).inspect_err(|_| {
// SAFETY: The render pass was created above on this live logical device and is destroyed on setup failure.
unsafe { device.device().destroy_render_pass(render_pass, None) };
})?;
let pipeline = create_graphics_pipeline(device, render_pass, pipeline_layout, extent)
.inspect_err(|_| {
// SAFETY: These objects were created above on this live logical device and are destroyed on setup failure.
unsafe {
device
.device()
.destroy_pipeline_layout(pipeline_layout, None);
device.device().destroy_render_pass(render_pass, None);
}
})?;
Ok((render_pass, pipeline_layout, pipeline))
}
fn create_swapchain_framebuffers(
device: &VulkanLogicalDeviceProbe,
render_pass: vk::RenderPass,
image_views: &[vk::ImageView],
extent: (u32, u32),
) -> Result<Vec<vk::Framebuffer>, VulkanSmokeRendererError> {
let mut framebuffers = Vec::with_capacity(image_views.len());
for image_view in image_views.iter().copied() {
match create_framebuffer(device, render_pass, image_view, extent) {
Ok(framebuffer) => framebuffers.push(framebuffer),
Err(error) => {
// SAFETY: These framebuffers were created above on this live logical device and are destroyed on setup failure.
unsafe {
for framebuffer in framebuffers.iter().copied() {
device.device().destroy_framebuffer(framebuffer, None);
}
}
return Err(error);
}
}
}
Ok(framebuffers)
}
fn reset_reusable_command_pool(
device: &VulkanLogicalDeviceProbe,
command_pool: vk::CommandPool,
reuse_command_pool: bool,
) -> Result<(), VulkanSmokeRendererError> {
if !reuse_command_pool {
return Ok(());
}
// SAFETY: All command buffers allocated from the live pool are freed before reallocating them.
unsafe {
device
.device()
.reset_command_pool(command_pool, vk::CommandPoolResetFlags::empty())
}
.map_err(|error| VulkanSmokeRendererError::VulkanOperation {
context: "vkResetCommandPool",
result: error,
})
}
fn create_image_view( fn create_image_view(
device: &VulkanLogicalDeviceProbe, device: &VulkanLogicalDeviceProbe,
image: vk::Image, image: vk::Image,
@@ -45,7 +45,7 @@ impl Default for VulkanPlanningRequestReport {
} }
/// Diagnostics for planning-facade execution telemetry. /// Diagnostics for planning-facade execution telemetry.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, Default, PartialEq)]
pub struct VulkanPlanningExecutionReport { pub struct VulkanPlanningExecutionReport {
/// Total frames planned by the facade. /// Total frames planned by the facade.
pub planned_frames: u64, pub planned_frames: u64,
@@ -57,19 +57,8 @@ pub struct VulkanPlanningExecutionReport {
pub simulated_presents: u64, pub simulated_presents: u64,
} }
impl Default for VulkanPlanningExecutionReport {
fn default() -> Self {
Self {
planned_frames: 0,
submission_plans: 0,
last_capture_size: 0,
simulated_presents: 0,
}
}
}
/// Diagnostics for Vulkan planning backend setup and frame progression. /// Diagnostics for Vulkan planning backend setup and frame progression.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, Default, PartialEq)]
pub struct VulkanPlanningBackendReport { pub struct VulkanPlanningBackendReport {
/// Request-tracking telemetry. /// Request-tracking telemetry.
pub request: VulkanPlanningRequestReport, pub request: VulkanPlanningRequestReport,
@@ -79,16 +68,6 @@ pub struct VulkanPlanningBackendReport {
pub last_frame_submission: Option<VulkanFrameSubmissionPlan>, pub last_frame_submission: Option<VulkanFrameSubmissionPlan>,
} }
impl Default for VulkanPlanningBackendReport {
fn default() -> Self {
Self {
request: VulkanPlanningRequestReport::default(),
execution: VulkanPlanningExecutionReport::default(),
last_frame_submission: None,
}
}
}
/// Vulkan planning backend facade used by the game entrypoint. /// Vulkan planning backend facade used by the game entrypoint.
#[derive(Debug)] #[derive(Debug)]
pub struct VulkanPlanningBackend { pub struct VulkanPlanningBackend {
+2 -2
View File
@@ -104,8 +104,8 @@ fn run(args: &[String]) -> Result<String, String> {
args.frames, args.frames,
last_tick, last_tick,
last_draw_count, last_draw_count,
capture_report.submissions, capture_report.execution.submission_plans,
capture_report.last_capture_size, capture_report.execution.last_capture_size,
json_hash(&last_hash) json_hash(&last_hash)
)) ))
} }