[Mesa-dev] [PATCH 9/9] loader_dri3: Make sure we have an updated back v2
Thomas Hellstrom
thellstrom at vmware.com
Tue Aug 15 18:32:01 UTC 2017
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.
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
---
src/loader/loader_dri3_helper.c | 62 ++++++++++++++++++++++++++++++++++-------
src/loader/loader_dri3_helper.h | 1 +
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 55e1471..a2885ac 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -59,6 +59,9 @@ static struct loader_dri3_blit_context blit_context = {
static void
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?
*
@@ -269,6 +272,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn,
draw->first_init = true;
draw->cur_blit_source = -1;
+ draw->back_format = __DRI_IMAGE_FORMAT_NONE;
if (draw->ext->config)
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;
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;
if (draw->is_different_gpu) {
@@ -641,7 +648,7 @@ loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
loader_dri3_swapbuffer_barrier(draw);
dri3_fence_reset(draw->conn, back);
dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
draw->drawable,
dri3_drawable_gc(draw),
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) {
dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
dri3_copy_area(draw->conn,
- dri3_back_buffer(draw)->pixmap,
+ back->pixmap,
dri3_fake_front_buffer(draw)->pixmap,
dri3_drawable_gc(draw),
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);
- back = draw->buffers[dri3_find_back(draw)];
+ back = dri3_find_back_alloc(draw);
+
if (draw->is_different_gpu && back) {
/* Update the linear buffer before presenting the pixmap */
(void) loader_dri3_blit_image(draw,
@@ -892,15 +900,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
int
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;
- if (draw->buffers[back_id]->last_swap != 0)
- return draw->send_sbc - draw->buffers[back_id]->last_swap + 1;
- else
- return 0;
+ return draw->send_sbc - back->last_swap + 1;
}
/** loader_dri3_open
@@ -1334,6 +1339,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
int buf_id;
if (buffer_type == loader_dri3_buffer_back) {
+ draw->back_format = format;
+
buf_id = dri3_find_back(draw);
if (buf_id < 0)
@@ -1620,3 +1627,38 @@ loader_dri3_close_screen(__DRIscreen *dri_screen)
}
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 && draw->back_format != __DRI_IMAGE_FORMAT_NONE) {
+ (void) dri3_get_buffer(draw->dri_drawable,
+ draw->back_format,
+ loader_dri3_buffer_back,
+ draw);
+ } else if (back) {
+ /* Make sure any server side operations are flushed.
+ * For example glXSwapBuffers server side fake-front-to-back copy
+ * followed by glXCopyBuffers
+ */
+ dri3_fence_await(draw->conn, back);
+ }
+
+ return back;
+}
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 1a7d44d..d3f4b0c 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -158,6 +158,7 @@ struct loader_dri3_drawable {
const struct loader_dri3_vtable *vtable;
unsigned int swap_method;
+ unsigned int back_format;
};
void
--
2.7.4
More information about the mesa-dev
mailing list