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,
})?;
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,
pipeline_layout: None,
pipeline: None,
framebuffers: Vec::with_capacity(images.len()),
framebuffers: Vec::new(),
command_buffers: Vec::new(),
};
for image in images.iter().copied() {
match create_image_view(device, image, swapchain.report.plan.format.format) {
Ok(image_view) => partial.image_views.push(image_view),
Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error);
}
}
}
let render_pass = match create_render_pass(device, swapchain.report.plan.format.format) {
Ok(render_pass) => render_pass,
let (render_pass, pipeline_layout, pipeline) = match create_swapchain_pipeline_bundle(
device,
swapchain.report.plan.format.format,
swapchain.report.plan.extent,
) {
Ok(bundle) => bundle,
Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error);
}
};
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);
let pipeline = match create_graphics_pipeline(
partial.pipeline = Some(pipeline);
let framebuffers = match create_swapchain_framebuffers(
device,
render_pass,
pipeline_layout,
&partial.image_views,
swapchain.report.plan.extent,
) {
Ok(pipeline) => pipeline,
Ok(framebuffers) => framebuffers,
Err(error) => {
destroy_partial_swapchain_resources(device, command_pool, partial);
return Err(error);
}
};
partial.pipeline = Some(pipeline);
for image_view in partial.image_views.iter().copied() {
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,
})?;
}
partial.framebuffers = framebuffers;
reset_reusable_command_pool(device, command_pool, reuse_command_pool)?;
let command_buffers = match allocate_command_buffers(
device,
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(
device: &VulkanLogicalDeviceProbe,
image: vk::Image,
@@ -45,7 +45,7 @@ impl Default for VulkanPlanningRequestReport {
}
/// Diagnostics for planning-facade execution telemetry.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct VulkanPlanningExecutionReport {
/// Total frames planned by the facade.
pub planned_frames: u64,
@@ -57,19 +57,8 @@ pub struct VulkanPlanningExecutionReport {
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.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct VulkanPlanningBackendReport {
/// Request-tracking telemetry.
pub request: VulkanPlanningRequestReport,
@@ -79,16 +68,6 @@ pub struct VulkanPlanningBackendReport {
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.
#[derive(Debug)]
pub struct VulkanPlanningBackend {
+2 -2
View File
@@ -104,8 +104,8 @@ fn run(args: &[String]) -> Result<String, String> {
args.frames,
last_tick,
last_draw_count,
capture_report.submissions,
capture_report.last_capture_size,
capture_report.execution.submission_plans,
capture_report.execution.last_capture_size,
json_hash(&last_hash)
))
}