From f9ecf99ca9883ad5d079b67741f9bdf031c4a930 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Mon, 11 Jul 2022 12:24:17 -0700 Subject: [PATCH] kopper: Use the swap interval that was set at swapchain creation time. We need to track what the caller has given us for swap interval, and use that to set the present mode at startup. Fixes incorrect vblank syncing in apitrace's glretrace, which sets the swap interval to 0 before the swapchain is made. Reviewed-By: Mike Blumenkrantz Reviewed-by: Adam Jackson Part-of: --- include/kopper_interface.h | 1 + src/gallium/drivers/zink/zink_kopper.c | 40 +++++++++++++++----------- src/gallium/frontends/dri/kopper.c | 8 ++++-- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/include/kopper_interface.h b/include/kopper_interface.h index 584214e113a..f5db825f425 100644 --- a/include/kopper_interface.h +++ b/include/kopper_interface.h @@ -95,6 +95,7 @@ struct kopper_loader_info { #endif }; int has_alpha; + int initial_swap_interval; }; #define __DRI_KOPPER_LOADER "DRI_KopperLoader" diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c index d27b32bd4ec..be547ade0c2 100644 --- a/src/gallium/drivers/zink/zink_kopper.c +++ b/src/gallium/drivers/zink/zink_kopper.c @@ -29,6 +29,26 @@ #include "zink_kopper.h" #include "vk_enum_to_str.h" +static void +zink_kopper_set_present_mode_for_interval(struct kopper_displaytarget *cdt, int interval) +{ +#ifdef WIN32 + // not hooked up yet so let's not sabotage benchmarks + cdt->present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; +#else + assert(interval >= 0); /* TODO: VK_PRESENT_MODE_FIFO_RELAXED_KHR */ + if (interval == 0) { + if (cdt->present_modes & BITFIELD_BIT(VK_PRESENT_MODE_IMMEDIATE_KHR)) + cdt->present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; + else + cdt->present_mode = VK_PRESENT_MODE_MAILBOX_KHR; + } else if (interval > 0) { + cdt->present_mode = VK_PRESENT_MODE_FIFO_KHR; + } + assert(cdt->present_modes & BITFIELD_BIT(cdt->present_mode)); +#endif +} + static void init_dt_type(struct kopper_displaytarget *cdt) { @@ -52,13 +72,6 @@ init_dt_type(struct kopper_displaytarget *cdt) default: unreachable("unsupported!"); } -#ifdef WIN32 - // not hooked up yet so let's not sabotage benchmarks - cdt->present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; -#else - // Matches the EGL and GLX_SGI_swap_interval default - cdt->present_mode = VK_PRESENT_MODE_FIFO_KHR; -#endif } static VkSurfaceKHR @@ -112,6 +125,8 @@ kopper_CreateSurface(struct zink_screen *screen, struct kopper_displaytarget *cd cdt->present_modes |= BITFIELD_BIT(modes[i]); } + zink_kopper_set_present_mode_for_interval(cdt, cdt->info.initial_swap_interval); + return surface; fail: VKSCR(DestroySurfaceKHR)(screen->instance, surface, NULL); @@ -884,16 +899,7 @@ zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource struct kopper_displaytarget *cdt = res->obj->dt; VkPresentModeKHR old_present_mode = cdt->present_mode; - assert(interval >= 0); /* TODO: VK_PRESENT_MODE_FIFO_RELAXED_KHR */ - if (interval == 0) { - if (cdt->present_modes & BITFIELD_BIT(VK_PRESENT_MODE_IMMEDIATE_KHR)) - cdt->present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; - else - cdt->present_mode = VK_PRESENT_MODE_MAILBOX_KHR; - } else if (interval > 0) { - cdt->present_mode = VK_PRESENT_MODE_FIFO_KHR; - } - assert(cdt->present_modes & BITFIELD_BIT(cdt->present_mode)); + zink_kopper_set_present_mode_for_interval(cdt, interval); if (old_present_mode != cdt->present_mode) update_swapchain(screen, cdt, cdt->caps.currentExtent.width, cdt->caps.currentExtent.height); diff --git a/src/gallium/frontends/dri/kopper.c b/src/gallium/frontends/dri/kopper.c index 9e7547b7828..f8ef75d9b9d 100644 --- a/src/gallium/frontends/dri/kopper.c +++ b/src/gallium/frontends/dri/kopper.c @@ -975,6 +975,7 @@ static void kopperSetSwapInterval(__DRIdrawable *dPriv, int interval) { struct dri_drawable *drawable = dri_drawable(dPriv); + struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable; struct dri_screen *screen = dri_screen(drawable->sPriv); struct kopper_screen *kscreen = (struct kopper_screen *)screen; struct pipe_screen *pscreen = kscreen->screen; @@ -982,10 +983,13 @@ kopperSetSwapInterval(__DRIdrawable *dPriv, int interval) drawable->textures[ST_ATTACHMENT_BACK_LEFT] : drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; - // the conditional is because we can be called before buffer allocation, though - // this is almost certainly not the right fix. + /* the conditional is because we can be called before buffer allocation. If + * we're before allocation, then the initial_swap_interval will be used when + * the swapchain is eventually created. + */ if (ptex) zink_kopper_set_swap_interval(pscreen, ptex, interval); + cdraw->info.initial_swap_interval = interval; } const __DRIkopperExtension driKopperExtension = {