aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--adapters/fparkan-render-vulkan/src/ffi/tests.rs26
-rw-r--r--adapters/fparkan-render-vulkan/src/policy.rs2
-rw-r--r--docs/reference/render-frame.md16
3 files changed, 44 insertions, 0 deletions
diff --git a/adapters/fparkan-render-vulkan/src/ffi/tests.rs b/adapters/fparkan-render-vulkan/src/ffi/tests.rs
index b06bb26..4b2f7d2 100644
--- a/adapters/fparkan-render-vulkan/src/ffi/tests.rs
+++ b/adapters/fparkan-render-vulkan/src/ffi/tests.rs
@@ -419,6 +419,32 @@ fn swapchain_plan_enables_transfer_source_when_surface_supports_it() {
}
#[test]
+fn swapchain_plan_falls_back_to_immediate_without_overriding_supported_preference() {
+ let mut request = swapchain_request();
+ request.present_modes = vec![
+ vk::PresentModeKHR::IMMEDIATE.as_raw(),
+ vk::PresentModeKHR::FIFO.as_raw(),
+ ];
+ assert_eq!(
+ plan_vulkan_swapchain(&request).unwrap().present_mode,
+ vk::PresentModeKHR::IMMEDIATE.as_raw()
+ );
+ request.preferred_present_mode = vk::PresentModeKHR::FIFO.as_raw();
+ assert_eq!(
+ plan_vulkan_swapchain(&request).unwrap().present_mode,
+ vk::PresentModeKHR::FIFO.as_raw()
+ );
+ request
+ .present_modes
+ .push(vk::PresentModeKHR::MAILBOX.as_raw());
+ request.preferred_present_mode = vk::PresentModeKHR::MAILBOX.as_raw();
+ assert_eq!(
+ plan_vulkan_swapchain(&request).unwrap().present_mode,
+ vk::PresentModeKHR::MAILBOX.as_raw()
+ );
+}
+
+#[test]
fn swapchain_plan_uses_fifo_and_current_extent_fallbacks() {
let mut request = swapchain_request();
request.preferred_present_mode = vk::PresentModeKHR::IMMEDIATE.as_raw();
diff --git a/adapters/fparkan-render-vulkan/src/policy.rs b/adapters/fparkan-render-vulkan/src/policy.rs
index e1f01c8..8eceb22 100644
--- a/adapters/fparkan-render-vulkan/src/policy.rs
+++ b/adapters/fparkan-render-vulkan/src/policy.rs
@@ -495,6 +495,8 @@ fn undefined_surface_format_override(
fn select_present_mode(present_modes: &[i32], preferred: i32) -> Result<i32, VulkanSwapchainError> {
if present_modes.contains(&preferred) {
Ok(preferred)
+ } else if present_modes.contains(&vk::PresentModeKHR::IMMEDIATE.as_raw()) {
+ Ok(vk::PresentModeKHR::IMMEDIATE.as_raw())
} else if present_modes.contains(&vk::PresentModeKHR::FIFO.as_raw()) {
Ok(vk::PresentModeKHR::FIFO.as_raw())
} else {
diff --git a/docs/reference/render-frame.md b/docs/reference/render-frame.md
index 80796a3..88f30b5 100644
--- a/docs/reference/render-frame.md
+++ b/docs/reference/render-frame.md
@@ -213,6 +213,22 @@ RVA `0x4EBE0` использует соглашение о вызовах `__std
`REFLECTION_SHIFTED`. Это свидетельство ABI фабрики, а не восстановленный
контракт матрицы вида или проекции.
+## Представление готового кадра
+
+Vulkan сохраняет явно выбранный режим, если поверхность его поддерживает.
+Приложение предпочитает MAILBOX: готовый новый кадр заменяет ожидающий,
+а показ остаётся привязан к развёртке. При отсутствии MAILBOX выбирается
+IMMEDIATE, затем FIFO. IMMEDIATE допускает разрывы изображения, зато не
+навязывает ожидание вертикальной развёртки; FIFO остаётся запасным режимом.
+Семантика режимов описана в [спецификации Vulkan](https://docs.vulkan.org/refpages/latest/refpages/source/VkPresentModeKHR.html).
+
+Оконная ветка GOG Ngi32.dll (SHA-256 из [таблицы модулей](original-binaries.md))
+по RVA `0x6E1B` вызывает `IDirectDrawSurface7::Blt` с `DDBLT_WAIT`.
+Эта ветка наблюдалась при нативных захватах. Флаг ждёт готовности блиттера,
+а не задаёт интервал развёртки — см. [описание Microsoft](https://learn.microsoft.com/en-us/windows/win32/api/ddraw/nf-ddraw-idirectdrawsurface7-blt).
+Современный композитор и драйвер всё равно могут влиять на фактический показ;
+это правило выбора API, а не гарантия одинаковой задержки двух движков.
+
## Предпросмотр по захвату камеры D3D7
`fparkan-game --legacy-camera-capture <json>` принимает матрицу камеры