loader_dri3: Make sure we have an updated back v3
With GLX_SWAP_COPY_OML and GLX_SWAP_EXCHANGE_OML it may happen in situations when glXSwapBuffers() is immediately followed by for example another glXSwapBuffers() or glXCopyBuffers() or back buffer age querying, that we haven't yet allocated and initialized a new back buffer because there was no GL rendering in between. Make sure that we have a back buffer in those situations. v2: Eliminate the drawable have_back_format member. v3: Make sure we re-initialize the back even if it exists. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
7c3e3c0faf
commit
0cc4c7e33e
|
@ -59,6 +59,9 @@ static struct loader_dri3_blit_context blit_context = {
|
||||||
static void
|
static void
|
||||||
dri3_flush_present_events(struct loader_dri3_drawable *draw);
|
dri3_flush_present_events(struct loader_dri3_drawable *draw);
|
||||||
|
|
||||||
|
static struct loader_dri3_buffer *
|
||||||
|
dri3_find_back_alloc(struct loader_dri3_drawable *draw);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do we have blit functionality in the image blit extension?
|
* Do we have blit functionality in the image blit extension?
|
||||||
*
|
*
|
||||||
|
@ -269,6 +272,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
|
||||||
draw->first_init = true;
|
draw->first_init = true;
|
||||||
|
|
||||||
draw->cur_blit_source = -1;
|
draw->cur_blit_source = -1;
|
||||||
|
draw->back_format = __DRI_IMAGE_FORMAT_NONE;
|
||||||
|
|
||||||
if (draw->ext->config)
|
if (draw->ext->config)
|
||||||
draw->ext->config->configQueryi(draw->dri_screen,
|
draw->ext->config->configQueryi(draw->dri_screen,
|
||||||
|
@ -616,7 +620,10 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
|
||||||
flags |= __DRI2_FLUSH_CONTEXT;
|
flags |= __DRI2_FLUSH_CONTEXT;
|
||||||
loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
|
loader_dri3_flush(draw, flags, __DRI2_THROTTLE_SWAPBUFFER);
|
||||||
|
|
||||||
back = dri3_back_buffer(draw);
|
back = dri3_find_back_alloc(draw);
|
||||||
|
if (!back)
|
||||||
|
return;
|
||||||
|
|
||||||
y = draw->height - y - height;
|
y = draw->height - y - height;
|
||||||
|
|
||||||
if (draw->is_different_gpu) {
|
if (draw->is_different_gpu) {
|
||||||
|
@ -641,7 +648,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
|
||||||
loader_dri3_swapbuffer_barrier(draw);
|
loader_dri3_swapbuffer_barrier(draw);
|
||||||
dri3_fence_reset(draw->conn, back);
|
dri3_fence_reset(draw->conn, back);
|
||||||
dri3_copy_area(draw->conn,
|
dri3_copy_area(draw->conn,
|
||||||
dri3_back_buffer(draw)->pixmap,
|
back->pixmap,
|
||||||
draw->drawable,
|
draw->drawable,
|
||||||
dri3_drawable_gc(draw),
|
dri3_drawable_gc(draw),
|
||||||
x, y, x, y, width, height);
|
x, y, x, y, width, height);
|
||||||
|
@ -652,7 +659,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
|
||||||
if (draw->have_fake_front && !draw->is_different_gpu) {
|
if (draw->have_fake_front && !draw->is_different_gpu) {
|
||||||
dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
|
dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
|
||||||
dri3_copy_area(draw->conn,
|
dri3_copy_area(draw->conn,
|
||||||
dri3_back_buffer(draw)->pixmap,
|
back->pixmap,
|
||||||
dri3_fake_front_buffer(draw)->pixmap,
|
dri3_fake_front_buffer(draw)->pixmap,
|
||||||
dri3_drawable_gc(draw),
|
dri3_drawable_gc(draw),
|
||||||
x, y, x, y, width, height);
|
x, y, x, y, width, height);
|
||||||
|
@ -763,7 +770,8 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
|
||||||
|
|
||||||
draw->vtable->flush_drawable(draw, flush_flags);
|
draw->vtable->flush_drawable(draw, flush_flags);
|
||||||
|
|
||||||
back = draw->buffers[dri3_find_back(draw)];
|
back = dri3_find_back_alloc(draw);
|
||||||
|
|
||||||
if (draw->is_different_gpu && back) {
|
if (draw->is_different_gpu && back) {
|
||||||
/* Update the linear buffer before presenting the pixmap */
|
/* Update the linear buffer before presenting the pixmap */
|
||||||
(void) loader_dri3_blit_image(draw,
|
(void) loader_dri3_blit_image(draw,
|
||||||
|
@ -892,15 +900,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
|
||||||
int
|
int
|
||||||
loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
|
loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw)
|
||||||
{
|
{
|
||||||
int back_id = LOADER_DRI3_BACK_ID(dri3_find_back(draw));
|
struct loader_dri3_buffer *back = dri3_find_back_alloc(draw);
|
||||||
|
|
||||||
if (back_id < 0 || !draw->buffers[back_id])
|
if (!back || back->last_swap == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (draw->buffers[back_id]->last_swap != 0)
|
return draw->send_sbc - back->last_swap + 1;
|
||||||
return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** loader_dri3_open
|
/** loader_dri3_open
|
||||||
|
@ -1334,6 +1339,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
|
||||||
int buf_id;
|
int buf_id;
|
||||||
|
|
||||||
if (buffer_type == loader_dri3_buffer_back) {
|
if (buffer_type == loader_dri3_buffer_back) {
|
||||||
|
draw->back_format = format;
|
||||||
|
|
||||||
buf_id = dri3_find_back(draw);
|
buf_id = dri3_find_back(draw);
|
||||||
|
|
||||||
if (buf_id < 0)
|
if (buf_id < 0)
|
||||||
|
@ -1620,3 +1627,35 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
|
||||||
}
|
}
|
||||||
mtx_unlock(&blit_context.mtx);
|
mtx_unlock(&blit_context.mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a backbuffer slot - potentially allocating a back buffer
|
||||||
|
*
|
||||||
|
* \param draw[in,out] Pointer to the drawable for which to find back.
|
||||||
|
* \return Pointer to a new back buffer or NULL if allocation failed or was
|
||||||
|
* not mandated.
|
||||||
|
*
|
||||||
|
* Find a potentially new back buffer, and if it's not been allocated yet and
|
||||||
|
* in addition needs initializing, then try to allocate and initialize it.
|
||||||
|
*/
|
||||||
|
static struct loader_dri3_buffer *
|
||||||
|
dri3_find_back_alloc(struct loader_dri3_drawable *draw)
|
||||||
|
{
|
||||||
|
struct loader_dri3_buffer *back;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
id = dri3_find_back(draw);
|
||||||
|
back = (id >= 0) ? draw->buffers[id] : NULL;
|
||||||
|
|
||||||
|
if (back || (id >= 0 && draw->back_format != __DRI_IMAGE_FORMAT_NONE)) {
|
||||||
|
if (dri3_update_drawable(draw->dri_drawable, draw)) {
|
||||||
|
(void) dri3_get_buffer(draw->dri_drawable,
|
||||||
|
draw->back_format,
|
||||||
|
loader_dri3_buffer_back,
|
||||||
|
draw);
|
||||||
|
back = (id >= 0) ? draw->buffers[id] : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return back;
|
||||||
|
}
|
||||||
|
|
|
@ -158,6 +158,7 @@ struct loader_dri3_drawable {
|
||||||
const struct loader_dri3_vtable *vtable;
|
const struct loader_dri3_vtable *vtable;
|
||||||
|
|
||||||
unsigned int swap_method;
|
unsigned int swap_method;
|
||||||
|
unsigned int back_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue