Mesa (staging/22.1): kopper: Grow a swap interval API
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu May 5 17:57:46 UTC 2022
Module: Mesa
Branch: staging/22.1
Commit: 450fef83fccbd13d83eb80069ee0956004d7bbf7
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=450fef83fccbd13d83eb80069ee0956004d7bbf7
Author: Adam Jackson <ajax at redhat.com>
Date: Thu Apr 28 17:03:23 2022 -0400
kopper: Grow a swap interval API
We take a slight liberty here by allowing 0 to mean either MAILBOX or
IMMEDIATE, since Wayland (at least) doesn't have a true IMMEDIATE mode
at least MAILBOX won't throttle to vblank.
This only correctly handles intervals of 0 or 1 at the moment.
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15800>
---
include/kopper_interface.h | 1 +
src/gallium/drivers/zink/zink_kopper.c | 34 ++++++++++++++++++++++++++++++++--
src/gallium/drivers/zink/zink_kopper.h | 3 +++
src/gallium/frontends/dri/kopper.c | 21 +++++++++++++++++++++
4 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/include/kopper_interface.h b/include/kopper_interface.h
index 8852252578d..584214e113a 100644
--- a/include/kopper_interface.h
+++ b/include/kopper_interface.h
@@ -74,6 +74,7 @@ struct __DRIkopperExtensionRec {
void *loaderPrivate,
int pixmap);
int64_t (*swapBuffers)(__DRIdrawable *draw);
+ void (*setSwapInterval)(__DRIdrawable *drawable, int interval);
};
/**
diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c
index 099d17b711b..1882795dec1 100644
--- a/src/gallium/drivers/zink/zink_kopper.c
+++ b/src/gallium/drivers/zink/zink_kopper.c
@@ -54,6 +54,13 @@ 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
@@ -196,10 +203,9 @@ kopper_CreateSwapchain(struct zink_screen *screen, struct kopper_displaytarget *
cswap->scci.queueFamilyIndexCount = 0;
cswap->scci.pQueueFamilyIndices = NULL;
cswap->scci.compositeAlpha = has_alpha ? VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- // TODO: This is where you'd hook up GLX_EXT_swap_interval and friends
- cswap->scci.presentMode = cdt->type == KOPPER_WAYLAND ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR;
cswap->scci.clipped = VK_TRUE;
}
+ cswap->scci.presentMode = cdt->present_mode;
cswap->scci.minImageCount = cdt->caps.minImageCount;
cswap->scci.preTransform = cdt->caps.currentTransform;
if (cdt->formats[1])
@@ -791,3 +797,27 @@ zink_kopper_check(struct pipe_resource *pres)
struct kopper_displaytarget *cdt = kopper_displaytarget(res->obj->dt);
return !cdt->is_kill;
}
+
+void
+zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource *pres, int interval)
+{
+ struct zink_resource *res = zink_resource(pres);
+ struct zink_screen *screen = zink_screen(pscreen);
+ assert(res->obj->dt);
+ struct kopper_displaytarget *cdt = kopper_displaytarget(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));
+
+ if (old_present_mode != cdt->present_mode)
+ update_swapchain(screen, cdt, cdt->caps.currentExtent.width, cdt->caps.currentExtent.height);
+}
diff --git a/src/gallium/drivers/zink/zink_kopper.h b/src/gallium/drivers/zink/zink_kopper.h
index a96f431ed83..42a21a08c82 100644
--- a/src/gallium/drivers/zink/zink_kopper.h
+++ b/src/gallium/drivers/zink/zink_kopper.h
@@ -69,6 +69,7 @@ struct kopper_displaytarget
VkImageFormatListCreateInfoKHR format_list;
enum kopper_type type;
bool is_kill;
+ VkPresentModeKHR present_mode;
};
struct zink_context;
@@ -118,4 +119,6 @@ void
zink_kopper_fixup_depth_buffer(struct zink_context *ctx);
bool
zink_kopper_check(struct pipe_resource *pres);
+void
+zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource *pres, int interval);
#endif
diff --git a/src/gallium/frontends/dri/kopper.c b/src/gallium/frontends/dri/kopper.c
index 2917c3c1650..452daf087ef 100644
--- a/src/gallium/frontends/dri/kopper.c
+++ b/src/gallium/frontends/dri/kopper.c
@@ -31,6 +31,7 @@
#include "state_tracker/st_context.h"
#include "os/os_process.h"
#include "zink/zink_public.h"
+#include "zink/zink_instance.h"
#include "zink/zink_kopper.h"
#include "driver_trace/tr_screen.h"
@@ -98,6 +99,8 @@ static const __DRIrobustnessExtension dri2Robustness = {
.base = { __DRI2_ROBUSTNESS, 1 }
};
+const __DRIkopperExtension driKopperExtension;
+
static const __DRIextension *drivk_screen_extensions[] = {
&driTexBufferExtension.base,
&dri2RendererQueryExtension.base,
@@ -107,6 +110,7 @@ static const __DRIextension *drivk_screen_extensions[] = {
&driVkImageExtension.base,
&dri2FlushControlExtension.base,
&driVkFlushExtension.base,
+ &driKopperExtension.base,
NULL
};
@@ -965,11 +969,28 @@ kopperCreateNewDrawable(__DRIscreen *screen,
return pdraw;
}
+static void
+kopperSetSwapInterval(__DRIdrawable *dPriv, int interval)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct kopper_screen *kscreen = (struct kopper_screen *)screen;
+ struct pipe_screen *pscreen = kscreen->screen;
+ struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ?
+ 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.
+ if (ptex)
+ zink_kopper_set_swap_interval(pscreen, ptex, interval);
+}
const __DRIkopperExtension driKopperExtension = {
.base = { __DRI_KOPPER, 1 },
.createNewDrawable = kopperCreateNewDrawable,
.swapBuffers = kopperSwapBuffers,
+ .setSwapInterval = kopperSetSwapInterval,
};
const struct __DriverAPIRec galliumvk_driver_api = {
More information about the mesa-commit
mailing list