diff --git a/docs/internal/upstream/martin-pr16-vulkan-mailbox-policy.md b/docs/internal/upstream/martin-pr16-vulkan-mailbox-policy.md new file mode 100644 index 00000000..cce0578d --- /dev/null +++ b/docs/internal/upstream/martin-pr16-vulkan-mailbox-policy.md @@ -0,0 +1,23 @@ +# Martin Penkava PR #16: Vulkan MAILBOX tear-free policy + +Last evaluated: 2026-07-14 + +| Item | Value | +| --- | --- | +| Head repository/branch | `shaneomac1337/psxrecomp`, `smackdown2-fixes` (submitted as `mstan/psxrecomp` PR #16) | +| Source commit | `d05d14bb11caafad2963abe824f249249a80cb11` | +| Source author | Martin Penkava `` | +| Local base | `7085721afe338a03cb114321a3576cdff420b732` (`origin/master`) | +| Local branch | `perf/pr16-vulkan-mailbox-tear-free-mpenkava` | + +## Included scope + +The tear-free Vulkan policy prefers MAILBOX because PSXRecomp's frontend already paces frames. If MAILBOX is unavailable, Vulkan's required FIFO mode remains the fallback; the explicit tearing policy still requests IMMEDIATE. + +## Deliberate exclusions + +- Source-commit benchmark comments naming a particular game are omitted; the policy itself is title-independent. +- Command-buffer batching and staging reuse are isolated on separate branches. +- Timing diagnostics, CRT presentation, and game-specific data are excluded. + +The source commit has no secondary co-author trailer; only Martin Penkava is credited in the local commit trailer. diff --git a/runtime/include/gpu_vk_renderer.h b/runtime/include/gpu_vk_renderer.h index ea4b18a2..fa12405e 100644 --- a/runtime/include/gpu_vk_renderer.h +++ b/runtime/include/gpu_vk_renderer.h @@ -45,9 +45,9 @@ void vk_renderer_present_blank(void); * server, 24-bit present). No-op when the Vulkan path is inactive. */ void vk_renderer_sync_cpu(void); -/* Set the present mode: 1=FIFO (vsync), 0=IMMEDIATE (lowest latency, may tear), - * -1=MAILBOX (low-latency, tear-free). Applied on the next swapchain (re)build; - * unsupported modes fall back to FIFO (always available). */ +/* Set the present policy: 1=tear-free, 0=IMMEDIATE (lowest latency, may tear), + * -1=MAILBOX. Tear-free prefers MAILBOX because the frontend already paces + * frames; unsupported modes fall back to FIFO (always available). */ void vk_renderer_set_present_mode(int mode); #ifdef __cplusplus diff --git a/runtime/src/gpu_vk_renderer.c b/runtime/src/gpu_vk_renderer.c index 251ebe0b..503d9bf7 100644 --- a/runtime/src/gpu_vk_renderer.c +++ b/runtime/src/gpu_vk_renderer.c @@ -226,7 +226,7 @@ static VkFormat s_sc_format; static VkExtent2D s_sc_extent; static uint32_t s_sc_count; static VkImage s_sc_images[8]; -static int s_present_mode_req = 1; /* 1 FIFO, 0 IMMEDIATE, -1 MAILBOX */ +static int s_present_mode_req = 1; /* 1 tear-free, 0 IMMEDIATE, -1 MAILBOX */ /* Per-frame sync (double-buffered command recording). */ #define VK_FRAMES 2 @@ -778,9 +778,11 @@ static VkPresentModeKHR choose_present_mode(void) { if (n > 8) n = 8; VkPresentModeKHR modes[8]; p_vkGetPhysicalDeviceSurfacePresentModesKHR(s_phys, s_surface, &n, modes); - VkPresentModeKHR want = (s_present_mode_req == 0) ? VK_PRESENT_MODE_IMMEDIATE_KHR - : (s_present_mode_req < 0) ? VK_PRESENT_MODE_MAILBOX_KHR - : VK_PRESENT_MODE_FIFO_KHR; + /* The frontend already owns frame cadence. Prefer MAILBOX for tear-free + * delivery so FIFO does not introduce a second blocking pacer. */ + VkPresentModeKHR want = (s_present_mode_req == 0) + ? VK_PRESENT_MODE_IMMEDIATE_KHR + : VK_PRESENT_MODE_MAILBOX_KHR; for (uint32_t i = 0; i < n; i++) if (modes[i] == want) return want; return VK_PRESENT_MODE_FIFO_KHR; /* always supported */ } diff --git a/runtime/tests/test_vk_mailbox_policy.py b/runtime/tests/test_vk_mailbox_policy.py new file mode 100644 index 00000000..5d61ed7c --- /dev/null +++ b/runtime/tests/test_vk_mailbox_policy.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +from pathlib import Path +import re + +source = (Path(__file__).parents[1] / "src" / "gpu_vk_renderer.c").read_text() +choose = re.search(r"static VkPresentModeKHR choose_present_mode\(.*?\n\}", source, re.DOTALL) +assert choose +body = choose.group(0) +assert "s_present_mode_req == 0" in body +assert "VK_PRESENT_MODE_IMMEDIATE_KHR" in body +assert "VK_PRESENT_MODE_MAILBOX_KHR" in body +assert "return VK_PRESENT_MODE_FIFO_KHR" in body +assert "s_present_mode_req < 0" not in body +print("Vulkan MAILBOX present-policy test passed")