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:
@@ -75,6 +75,7 @@ struct __DRIkopperExtensionRec {
|
|||||||
int pixmap);
|
int pixmap);
|
||||||
int64_t (*swapBuffers)(__DRIdrawable *draw);
|
int64_t (*swapBuffers)(__DRIdrawable *draw);
|
||||||
void (*setSwapInterval)(__DRIdrawable *drawable, int interval);
|
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;
|
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 = {
|
static const struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = {
|
||||||
.authenticate = NULL,
|
.authenticate = NULL,
|
||||||
.create_window_surface = dri2_x11_create_window_surface,
|
.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,
|
.swap_buffers_region = dri2_x11_swap_buffers_region,
|
||||||
.post_sub_buffer = dri2_x11_post_sub_buffer,
|
.post_sub_buffer = dri2_x11_post_sub_buffer,
|
||||||
.copy_buffers = dri2_x11_copy_buffers,
|
.copy_buffers = dri2_x11_copy_buffers,
|
||||||
|
.query_buffer_age = dri2_kopper_query_buffer_age,
|
||||||
/* XXX: should really implement this since X11 has pixmaps */
|
/* XXX: should really implement this since X11 has pixmaps */
|
||||||
.query_surface = dri2_query_surface,
|
.query_surface = dri2_query_surface,
|
||||||
.get_dri_drawable = dri2_surface_get_dri_drawable,
|
.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.pImageIndices = &cpi->image;
|
||||||
cpi->info.pResults = NULL;
|
cpi->info.pResults = NULL;
|
||||||
res->obj->present = VK_NULL_HANDLE;
|
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)) {
|
if (util_queue_is_initialized(&screen->flush_queue)) {
|
||||||
p_atomic_inc(&cpi->swapchain->async_presents);
|
p_atomic_inc(&cpi->swapchain->async_presents);
|
||||||
util_queue_add_job(&screen->flush_queue, cpi, &cdt->present_fence,
|
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)
|
if (old_present_mode != cdt->present_mode)
|
||||||
update_swapchain(screen, cdt, cdt->caps.currentExtent.width, cdt->caps.currentExtent.height);
|
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 init;
|
||||||
bool acquired;
|
bool acquired;
|
||||||
bool dt_has_data;
|
bool dt_has_data;
|
||||||
|
int age;
|
||||||
VkImage image;
|
VkImage image;
|
||||||
VkSemaphore acquire;
|
VkSemaphore acquire;
|
||||||
};
|
};
|
||||||
@@ -137,4 +138,6 @@ bool
|
|||||||
zink_kopper_check(struct pipe_resource *pres);
|
zink_kopper_check(struct pipe_resource *pres);
|
||||||
void
|
void
|
||||||
zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource *pres, int interval);
|
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
|
#endif
|
||||||
|
@@ -992,11 +992,24 @@ kopperSetSwapInterval(__DRIdrawable *dPriv, int interval)
|
|||||||
cdraw->info.initial_swap_interval = 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 = {
|
const __DRIkopperExtension driKopperExtension = {
|
||||||
.base = { __DRI_KOPPER, 1 },
|
.base = { __DRI_KOPPER, 1 },
|
||||||
.createNewDrawable = kopperCreateNewDrawable,
|
.createNewDrawable = kopperCreateNewDrawable,
|
||||||
.swapBuffers = kopperSwapBuffers,
|
.swapBuffers = kopperSwapBuffers,
|
||||||
.setSwapInterval = kopperSetSwapInterval,
|
.setSwapInterval = kopperSetSwapInterval,
|
||||||
|
.queryBufferAge = kopperQueryBufferAge,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct __DriverAPIRec galliumvk_driver_api = {
|
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 = {
|
static const struct glx_context_vtable drisw_context_vtable = {
|
||||||
.destroy = drisw_destroy_context,
|
.destroy = drisw_destroy_context,
|
||||||
.bind = drisw_bind_context,
|
.bind = drisw_bind_context,
|
||||||
@@ -854,6 +868,7 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (psc->kopper) {
|
if (psc->kopper) {
|
||||||
|
__glXEnableDirectExtension(&psc->base, "GLX_EXT_buffer_age");
|
||||||
__glXEnableDirectExtension(&psc->base, "GLX_EXT_swap_control");
|
__glXEnableDirectExtension(&psc->base, "GLX_EXT_swap_control");
|
||||||
__glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
|
__glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
|
||||||
__glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
|
__glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
|
||||||
@@ -1014,6 +1029,7 @@ driswCreateScreenDriver(int screen, struct glx_display *priv,
|
|||||||
psp->copySubBuffer = driswCopySubBuffer;
|
psp->copySubBuffer = driswCopySubBuffer;
|
||||||
|
|
||||||
if (psc->kopper) {
|
if (psc->kopper) {
|
||||||
|
psp->getBufferAge = kopper_get_buffer_age;
|
||||||
psp->setSwapInterval = kopperSetSwapInterval;
|
psp->setSwapInterval = kopperSetSwapInterval;
|
||||||
psp->getSwapInterval = kopperGetSwapInterval;
|
psp->getSwapInterval = kopperGetSwapInterval;
|
||||||
psp->maxSwapInterval = 1;
|
psp->maxSwapInterval = 1;
|
||||||
|
Reference in New Issue
Block a user