diff options
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/ffi/tests.rs | 26 | ||||
| -rw-r--r-- | adapters/fparkan-render-vulkan/src/policy.rs | 2 | ||||
| -rw-r--r-- | docs/reference/render-frame.md | 16 |
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>` принимает матрицу камеры |
