--- This driver isn't in master yet, but I thought that maybe this patch could be interesting.
src/mesa/drivers/dri/nouveau/nouveau_context.c | 38 +++++++++++++++------- src/mesa/drivers/dri/nouveau/nouveau_context.h | 3 ++ src/mesa/drivers/dri/nouveau/nouveau_driver.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_render_t.c | 2 + src/mesa/drivers/dri/nouveau/nouveau_screen.c | 19 +++++++++++ src/mesa/drivers/dri/nouveau/nouveau_state.c | 2 - src/mesa/drivers/dri/nouveau/nv10_context.c | 2 + 7 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 9312ec7..e679a6d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -127,7 +127,8 @@ nouveau_context_destroy(__DRIcontext *dri_ctx) } static void -nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + unsigned int *stamp) { struct nouveau_context *nctx = context->driverPrivate; GLcontext *ctx = &nctx->base; @@ -137,6 +138,8 @@ nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) __DRIbuffer *buffers = NULL; int i = 0, count, ret; + *stamp = *drawable->pStamp; + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; if (fb->Visual.doubleBufferMode) attachments[i++] = __DRI_BUFFER_BACK_LEFT; @@ -217,15 +220,18 @@ nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw, struct nouveau_context *nctx = dri_ctx->driverPrivate; GLcontext *ctx = &nctx->base; - if (nctx->screen->context != nctx) { - nctx->screen->context = nctx; - nctx->dirty = ~0; - } + if (nctx->screen->context == nctx) + return GL_TRUE; + + nctx->screen->context = nctx; + nctx->dirty = ~0; /* Ask the X server for new renderbuffers. */ - nouveau_update_renderbuffers(dri_ctx, dri_draw); + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable_stamp); if (dri_draw != dri_read) - nouveau_update_renderbuffers(dri_ctx, dri_read); + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->readable_stamp); /* Pass it down to mesa. */ _mesa_make_current(ctx, dri_draw->driverPrivate, @@ -260,17 +266,25 @@ nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode) void nouveau_validate_framebuffer(GLcontext *ctx) { + struct nouveau_context *nctx = to_nouveau_context(ctx); __DRIcontext *dri_ctx = to_nouveau_context(ctx)->dri_context; + __DRIdrawable *dri_draw = dri_ctx->driDrawablePriv; + __DRIdrawable *dri_read = dri_ctx->driReadablePriv; - if (ctx->DrawBuffer->Name) + if ((ctx->DrawBuffer->Name || + nctx->drawable_stamp == *dri_draw->pStamp) && + (dri_draw == dri_read || ctx->ReadBuffer->Name || + nctx->readable_stamp == *dri_read->pStamp)) return; ctx->Driver.Flush(ctx); - /* Make sure our renderbuffers are up-to-date. */ - nouveau_update_renderbuffers(dri_ctx, dri_ctx->driDrawablePriv); - if (dri_ctx->driDrawablePriv != dri_ctx->driReadablePriv) - nouveau_update_renderbuffers(dri_ctx, dri_ctx->driReadablePriv); + /* Ask the X server for new renderbuffers. */ + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable_stamp); + if (dri_draw != dri_read) + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->readable_stamp); FIRE_RING(context_chan(ctx)); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 4171249..7382cac 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -48,6 +48,9 @@ struct nouveau_context { struct nouveau_bo_state bo; struct nouveau_render_state render; + + unsigned int drawable_stamp; + unsigned int readable_stamp; }; #define to_nouveau_context(ctx) ((struct nouveau_context *)(ctx)) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index 12df30a..eb259ab 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -82,6 +82,7 @@ nouveau_clear(GLcontext *ctx, GLbitfield buffers) int x, y, w, h; int i, buf; + nouveau_validate_framebuffer(ctx); get_scissors(fb, &x, &y, &w, &h); for (i = 0; i < BUFFER_COUNT; i++) { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render_t.c b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c index 8c551de..6fc2668 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_render_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c @@ -218,6 +218,8 @@ render_prims(GLcontext *ctx, const struct gl_client_array **arrays, { struct nouveau_context *nctx = to_nouveau_context(ctx); + nouveau_validate_framebuffer(ctx); + if (nctx->fallback == HWTNL) TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib, index_bounds_valid, min_index, max_index); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index fbb0d75..b70d1f3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -35,6 +35,8 @@ #include "main/framebuffer.h" #include "main/renderbuffer.h" +static const __DRIextension *nouveau_screen_extensions[]; + static void nouveau_destroy_screen(__DRIscreen *dri_screen); @@ -104,6 +106,7 @@ nouveau_init_screen2(__DRIscreen *dri_screen) return NULL; dri_screen->private = screen; + dri_screen->extensions = nouveau_screen_extensions; screen->dri_screen = dri_screen; /* Open the DRM device. */ @@ -243,6 +246,22 @@ nouveau_destroy_buffer(__DRIdrawable *drawable) (struct gl_framebuffer **)&drawable->driverPrivate, NULL); } +static void +nouveau_drawable_flush(__DRIdrawable *draw) +{ +} + +static const struct __DRI2flushExtensionRec nouveau_flush_extension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + nouveau_drawable_flush, + dri2InvalidateDrawable, +}; + +static const __DRIextension *nouveau_screen_extensions[] = { + &nouveau_flush_extension.base, + NULL +}; + const struct __DriverAPIRec driDriverAPI = { .InitScreen2 = nouveau_init_screen2, .DestroyScreen = nouveau_destroy_screen, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 01f924c..7c5f7f2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -366,8 +366,6 @@ nouveau_update_state(GLcontext *ctx, GLbitfield new_state) context_dirty(ctx, PROJECTION); if (new_state & _NEW_MODELVIEW) context_dirty(ctx, MODELVIEW); - if (new_state & _NEW_VIEWPORT) - nouveau_validate_framebuffer(ctx); _swrast_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c index b2ef800..d1afa87 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_context.c +++ b/src/mesa/drivers/dri/nouveau/nv10_context.c @@ -39,6 +39,8 @@ nv10_clear(GLcontext *ctx, GLbitfield buffers) struct nouveau_framebuffer *nfb = to_nouveau_framebuffer( ctx->DrawBuffer); + nouveau_validate_framebuffer(ctx); + /* Clear the LMA depth buffer, if present. */ if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask && nfb->lma_bo) { -- 1.6.4.4 ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev