kopper: Implement {EGL,GLX}_EXT_buffer_age
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17527>
This commit is contained in:
parent
81d83e81db
commit
c123ab2137
|
@ -75,6 +75,7 @@ struct __DRIkopperExtensionRec {
|
|||
int pixmap);
|
||||
int64_t (*swapBuffers)(__DRIdrawable *draw);
|
||||
void (*setSwapInterval)(__DRIdrawable *drawable, int interval);
|
||||
int (*queryBufferAge)(__DRIdrawable *drawable);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1230,6 +1230,19 @@ dri2_kopper_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
|
|||
return surf;
|
||||
}
|
||||
|
||||
static EGLint
|
||||
dri2_kopper_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surf)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
|
||||
|
||||
/* This can legitimately be null for lavapipe */
|
||||
if (dri2_dpy->kopper)
|
||||
return dri2_dpy->kopper->queryBufferAge(dri2_surf->dri_drawable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = {
|
||||
.authenticate = NULL,
|
||||
.create_window_surface = dri2_x11_create_window_surface,
|
||||
|
@ -1258,6 +1271,7 @@ static const struct dri2_egl_display_vtbl dri2_x11_kopper_display_vtbl = {
|
|||
.swap_buffers_region = dri2_x11_swap_buffers_region,
|
||||
.post_sub_buffer = dri2_x11_post_sub_buffer,
|
||||
.copy_buffers = dri2_x11_copy_buffers,
|
||||
.query_buffer_age = dri2_kopper_query_buffer_age,
|
||||
/* XXX: should really implement this since X11 has pixmaps */
|
||||
.query_surface = dri2_query_surface,
|
||||
.get_dri_drawable = dri2_surface_get_dri_drawable,
|
||||
|
|
|
@ -736,6 +736,22 @@ zink_kopper_present_queue(struct zink_screen *screen, struct zink_resource *res)
|
|||
cpi->info.pImageIndices = &cpi->image;
|
||||
cpi->info.pResults = NULL;
|
||||
res->obj->present = VK_NULL_HANDLE;
|
||||
/* Ex GLX_EXT_buffer_age:
|
||||
*
|
||||
* Buffers' ages are initialized to 0 at buffer creation time.
|
||||
* When a frame boundary is reached, the following occurs before
|
||||
* any exchanging or copying of color buffers:
|
||||
*
|
||||
* * The current back buffer's age is set to 1.
|
||||
* * Any other color buffers' ages are incremented by 1 if
|
||||
* their age was previously greater than 0.
|
||||
*/
|
||||
for (int i = 0; i < cdt->swapchain->num_images; i++) {
|
||||
if (i == res->obj->dt_idx)
|
||||
cdt->swapchain->images[i].age = 1;
|
||||
else if (cdt->swapchain->images[i].age > 0)
|
||||
cdt->swapchain->images[i].age += 1;
|
||||
}
|
||||
if (util_queue_is_initialized(&screen->flush_queue)) {
|
||||
p_atomic_inc(&cpi->swapchain->async_presents);
|
||||
util_queue_add_job(&screen->flush_queue, cpi, &cdt->present_fence,
|
||||
|
@ -904,3 +920,23 @@ zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource
|
|||
if (old_present_mode != cdt->present_mode)
|
||||
update_swapchain(screen, cdt, cdt->caps.currentExtent.width, cdt->caps.currentExtent.height);
|
||||
}
|
||||
|
||||
int
|
||||
zink_kopper_query_buffer_age(struct pipe_context *pctx, struct pipe_resource *pres)
|
||||
{
|
||||
struct zink_context *ctx = zink_context(pctx);
|
||||
struct zink_resource *res = zink_resource(pres);
|
||||
assert(res->obj->dt);
|
||||
struct kopper_displaytarget *cdt = res->obj->dt;
|
||||
|
||||
ctx = zink_tc_context_unwrap(pctx);
|
||||
|
||||
/* Returning 0 here isn't ideal (yes, the buffer is undefined, because you
|
||||
* lost it) but threading the error up is more hassle than it's worth.
|
||||
*/
|
||||
if (!zink_kopper_acquired(res->obj->dt, res->obj->dt_idx))
|
||||
if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
|
||||
return 0;
|
||||
|
||||
return cdt->swapchain->images[res->obj->dt_idx].age;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ struct kopper_swapchain_image {
|
|||
bool init;
|
||||
bool acquired;
|
||||
bool dt_has_data;
|
||||
int age;
|
||||
VkImage image;
|
||||
VkSemaphore acquire;
|
||||
};
|
||||
|
@ -137,4 +138,6 @@ bool
|
|||
zink_kopper_check(struct pipe_resource *pres);
|
||||
void
|
||||
zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource *pres, int interval);
|
||||
int
|
||||
zink_kopper_query_buffer_age(struct pipe_context *pctx, struct pipe_resource *pres);
|
||||
#endif
|
||||
|
|
|
@ -992,11 +992,24 @@ kopperSetSwapInterval(__DRIdrawable *dPriv, int interval)
|
|||
cdraw->info.initial_swap_interval = interval;
|
||||
}
|
||||
|
||||
static int
|
||||
kopperQueryBufferAge(__DRIdrawable *dPriv)
|
||||
{
|
||||
struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ?
|
||||
drawable->textures[ST_ATTACHMENT_BACK_LEFT] :
|
||||
drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
|
||||
|
||||
return zink_kopper_query_buffer_age(ctx->st->pipe, ptex);
|
||||
}
|
||||
|
||||
const __DRIkopperExtension driKopperExtension = {
|
||||
.base = { __DRI_KOPPER, 1 },
|
||||
.createNewDrawable = kopperCreateNewDrawable,
|
||||
.swapBuffers = kopperSwapBuffers,
|
||||
.setSwapInterval = kopperSetSwapInterval,
|
||||
.queryBufferAge = kopperQueryBufferAge,
|
||||
};
|
||||
|
||||
const struct __DriverAPIRec galliumvk_driver_api = {
|
||||
|
|
|
@ -528,6 +528,20 @@ drisw_release_tex_image(__GLXDRIdrawable *base, int buffer)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
kopper_get_buffer_age(__GLXDRIdrawable *pdraw)
|
||||
{
|
||||
struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
|
||||
|
||||
if (pdp) {
|
||||
struct drisw_screen *psc = (struct drisw_screen *) pdraw->psc;
|
||||
|
||||
if (psc->kopper)
|
||||
return psc->kopper->queryBufferAge(pdp->driDrawable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct glx_context_vtable drisw_context_vtable = {
|
||||
.destroy = drisw_destroy_context,
|
||||
.bind = drisw_bind_context,
|
||||
|
@ -854,6 +868,7 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
|
|||
}
|
||||
|
||||
if (psc->kopper) {
|
||||
__glXEnableDirectExtension(&psc->base, "GLX_EXT_buffer_age");
|
||||
__glXEnableDirectExtension(&psc->base, "GLX_EXT_swap_control");
|
||||
__glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
|
||||
__glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
|
||||
|
@ -1014,6 +1029,7 @@ driswCreateScreenDriver(int screen, struct glx_display *priv,
|
|||
psp->copySubBuffer = driswCopySubBuffer;
|
||||
|
||||
if (psc->kopper) {
|
||||
psp->getBufferAge = kopper_get_buffer_age;
|
||||
psp->setSwapInterval = kopperSetSwapInterval;
|
||||
psp->getSwapInterval = kopperGetSwapInterval;
|
||||
psp->maxSwapInterval = 1;
|
||||
|
|
Loading…
Reference in New Issue