aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-07-18 07:26:37 +0300
committerValentin Popov <valentin@popov.link>2026-07-18 07:26:37 +0300
commit645eca551004f9eea8e2276e9110f3a66a1ddc69 (patch)
tree2577a38a2ad4a7e7b49b6ca2084687f4e7738242
parente7c16641716b41b8682b05bb96f74f25707d9d93 (diff)
downloadfparkan-645eca551004f9eea8e2276e9110f3a66a1ddc69.tar.xz
fparkan-645eca551004f9eea8e2276e9110f3a66a1ddc69.zip
feat(vulkan): select canonical depth attachment formats
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/tests.rs39
-rw-r--r--adapters/fparkan-render-vulkan/src/policy.rs24
-rw-r--r--docs/tomes/05-render.md7
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
@@ -321,6 +321,45 @@ fn capability_gate_respects_request_specific_depth_profiles() {
}
#[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(
"Telemetry GPU",
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<i32> {
+ 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. Только после этого допустимо освобождать