kopper: implement to get sync values.

v1. Makes special_event a member of struct dri_drawable to be re-used.
(Michel Dänzer @daenzer)

v2. Guard with VK_USE_PLATFORM_XCB_KHR and clean-up.
(Mike Blumenkrantz @zmike)

Signed-off-by: Hyunjun Ko <zzoon@igalia.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31474>
This commit is contained in:
Hyunjun Ko 2025-02-03 09:12:17 +09:00 committed by Marge Bot
parent e8d335d496
commit bf88b9b324
6 changed files with 126 additions and 0 deletions

View file

@ -212,6 +212,9 @@ dri_destroy_drawable(struct dri_drawable *drawable)
/* Notify the st manager that this drawable is no longer valid */
st_api_destroy_drawable(&drawable->base);
if (screen->type == DRI_SCREEN_KOPPER)
kopper_destroy_drawable(drawable);
FREE(drawable->damage_rects);
FREE(drawable);
}

View file

@ -33,6 +33,10 @@
#include "frontend/api.h"
#include "dri_util.h"
#ifdef VK_USE_PLATFORM_XCB_KHR
#include <xcb/xcb.h>
#endif
struct pipe_context;
struct dri_context;
struct dri_screen;
@ -93,6 +97,9 @@ struct dri_drawable
struct dri_image *image; //texture_from_pixmap
bool is_window;
bool window_valid;
#ifdef VK_USE_PLATFORM_XCB_KHR
xcb_special_event_t *special_event;
#endif
/* hooks filled in by dri2 & drisw */
void (*allocate_textures)(struct dri_context *ctx,
@ -161,6 +168,8 @@ void
drisw_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits);
void
dri2_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits);
void
kopper_destroy_drawable(struct dri_drawable *drawable);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -167,6 +167,10 @@ kopperQueryBufferAge(struct dri_drawable *drawable);
PUBLIC void
driswCopySubBuffer(struct dri_drawable *drawable, int x, int y, int w, int h);
PUBLIC int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
PUBLIC void
dri_set_tex_buffer2(struct dri_context *ctx, GLint target,
GLint format, struct dri_drawable *drawable);

View file

@ -523,6 +523,34 @@ kopper_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits
screen->kopper_loader->SetSurfaceCreateInfo(drawable->loaderPrivate,
&drawable->info);
drawable->is_window = !isPixmap && drawable->info.bos.sType != 0;
#ifdef VK_USE_PLATFORM_XCB_KHR
if (drawable->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&drawable->info.bos;
xcb_connection_t *conn = xcb->connection;
int32_t eid = xcb_generate_id(conn);
if (drawable->is_window) {
xcb_present_select_input(conn, eid, xcb->window,
XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY);
}
drawable->special_event =
xcb_register_for_special_xge(conn, &xcb_present_id, eid, NULL);
}
#endif
}
void
kopper_destroy_drawable(struct dri_drawable *drawable)
{
#ifdef VK_USE_PLATFORM_XCB_KHR
if (drawable->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR) {
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&drawable->info.bos;
xcb_connection_t *conn = xcb->connection;
xcb_unregister_for_special_event(conn, drawable->special_event);
}
#endif
}
int64_t
@ -639,5 +667,55 @@ kopperQueryBufferAge(struct dri_drawable *drawable)
return zink_kopper_query_buffer_age(ctx->st->pipe, ptex);
}
int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
{
#ifdef VK_USE_PLATFORM_XCB_KHR
struct kopper_loader_info *info = &drawable->info;
assert(info->bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR);
VkXcbSurfaceCreateInfoKHR *xcb = (VkXcbSurfaceCreateInfoKHR *)&info->bos;
xcb_connection_t *conn = xcb->connection;
xcb_void_cookie_t cookie =
xcb_present_notify_msc(conn, xcb->window, 0, target_msc, divisor, remainder);
xcb_generic_event_t *event;
int ret = 0;
xcb_flush(conn);
while ((event = xcb_wait_for_special_event(conn, drawable->special_event)) != NULL) {
xcb_present_generic_event_t *ev = (xcb_present_generic_event_t *)event;
if (ev->evtype == XCB_PRESENT_COMPLETE_NOTIFY) {
xcb_present_complete_notify_event_t *ce =
(xcb_present_complete_notify_event_t *) event;
if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC) {
*ust = ce->ust;
*msc = ce->msc;
*sbc = ce->serial;
if (event->full_sequence != cookie.sequence) {
free(event);
continue;
}
ret = 1;
free(event);
break;
}
}
free(event);
}
return ret;
#else
return 0;
#endif
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: MIT */
#include "dri_drawable.h"
#include "dri_util.h"
int64_t
@ -25,6 +26,13 @@ kopperQueryBufferAge(struct dri_drawable *dPriv)
return 0;
}
int
kopperGetSyncValues(struct dri_drawable *drawable, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
{
return 0;
}
const struct dri_config **
kopper_init_screen(struct dri_screen *screen, bool driver_name_is_inferred);
const struct dri_config **
@ -40,3 +48,10 @@ void
kopper_init_drawable(struct dri_drawable *drawable, bool isPixmap, int alphaBits)
{
}
void
kopper_destroy_drawable(struct dri_drawable *drawable);
void
kopper_destroy_drawable(struct dri_drawable *drawable)
{
}

View file

@ -619,6 +619,21 @@ kopperGetSwapInterval(__GLXDRIdrawable *pdraw)
return pdp->swapInterval;
}
static int
kopperWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
{
return kopperGetSyncValues(pdraw->dri_drawable, target_msc, divisor, remainder, ust, msc, sbc);
}
static int
kopperGetDrawableMSC(struct glx_screen *psc, __GLXDRIdrawable *pdraw,
int64_t *ust, int64_t *msc, int64_t *sbc)
{
return kopperGetSyncValues(pdraw->dri_drawable, 0, 0, 0, ust, msc, sbc);
}
struct glx_screen *
driswCreateScreen(int screen, struct glx_display *priv, enum glx_driver glx_driver, bool driver_name_is_inferred)
{
@ -670,6 +685,8 @@ driswCreateScreen(int screen, struct glx_display *priv, enum glx_driver glx_driv
psp->setSwapInterval = driswKopperSetSwapInterval;
psp->getSwapInterval = kopperGetSwapInterval;
psp->maxSwapInterval = 1;
psp->getDrawableMSC = kopperGetDrawableMSC;
psp->waitForMSC = kopperWaitForMSC;
}
return &psc->base;