From 645eca551004f9eea8e2276e9110f3a66a1ddc69 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Sat, 18 Jul 2026 08:26:37 +0400 Subject: [PATCH] feat(vulkan): select canonical depth attachment formats --- .../fparkan-render-vulkan/src/ffi/tests.rs | 39 +++++++++++++++++++ adapters/fparkan-render-vulkan/src/policy.rs | 24 +++++++++--- docs/tomes/05-render.md | 7 ++++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/adapters/fparkan-render-vulkan/src/ffi/tests.rs b/adapters/fparkan-render-vulkan/src/ffi/tests.rs index 6cf070e..791fff8 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/tests.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/tests.rs @@ -320,6 +320,45 @@ fn capability_gate_respects_request_specific_depth_profiles() { assert!(report.rejected_devices.is_empty()); } +#[test] +fn depth_attachment_selection_is_canonical_and_request_scoped() { + let supported = [ + vk::Format::D32_SFLOAT_S8_UINT.as_raw(), + vk::Format::D24_UNORM_S8_UINT.as_raw(), + vk::Format::D32_SFLOAT.as_raw(), + ]; + assert_eq!( + select_depth_stencil_attachment_format( + &supported, + DepthStencilSupport { + depth_bits: 24, + stencil_bits: 8, + }, + ), + Some(vk::Format::D24_UNORM_S8_UINT.as_raw()) + ); + assert_eq!( + select_depth_stencil_attachment_format( + &supported, + DepthStencilSupport { + depth_bits: 32, + stencil_bits: 0, + }, + ), + Some(vk::Format::D32_SFLOAT.as_raw()) + ); + assert_eq!( + select_depth_stencil_attachment_format( + &supported, + DepthStencilSupport { + depth_bits: 0, + stencil_bits: 0, + }, + ), + None + ); +} + #[test] fn capability_report_preserves_informational_sampled_formats_and_limits() { let report = select_physical_device(&[device( diff --git a/adapters/fparkan-render-vulkan/src/policy.rs b/adapters/fparkan-render-vulkan/src/policy.rs index 38650c6..bb26aee 100644 --- a/adapters/fparkan-render-vulkan/src/policy.rs +++ b/adapters/fparkan-render-vulkan/src/policy.rs @@ -806,11 +806,25 @@ fn supports_depth_stencil_request( if depth.depth_bits == 0 && depth.stencil_bits == 0 { return true; } - required_depth_stencil_formats(depth).iter().any(|format| { - device - .supported_depth_stencil_formats - .contains(&format.as_raw()) - }) + select_depth_stencil_attachment_format(&device.supported_depth_stencil_formats, depth).is_some() +} + +/// 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 +/// by device admission and future render-pass allocation. +#[must_use] +pub fn select_depth_stencil_attachment_format( + supported_formats: &[i32], + depth: DepthStencilSupport, +) -> Option { + if depth.depth_bits == 0 && depth.stencil_bits == 0 { + return None; + } + required_depth_stencil_formats(depth) + .iter() + .map(|format| format.as_raw()) + .find(|format| supported_formats.contains(format)) } fn informational_capabilities( diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md index ccbc578..545b8db 100644 --- a/docs/tomes/05-render.md +++ b/docs/tomes/05-render.md @@ -853,6 +853,13 @@ depth attachment либо alpha-test shader variant, поэтому он не д дополнительного дизассемблирования. Это частично реализованная compatibility boundary, а не заявление о готовой parity fixed-function state. +Выбор будущего depth/stencil attachment уже отделён от renderer lifetime: +`select_depth_stencil_attachment_format` применяет тот же фиксированный порядок +форматов, что и capability gate, к фактически поддерживаемому списку GPU. +Это исключает ситуацию, когда admission принимает один совместимый формат, а +allocation позднее выбирает другой; сам attachment и render-pass integration +остаются следующей отдельной задачей. + После последнего world pass renderer закрывает сцену и выводит back buffer. World3D снимает `in_render`, восстанавливает временный viewport state и вызывает `on_end_render` у active objects. Только после этого допустимо освобождать