From: Francisco J. <cur...@ri...> - 2010-01-22 14:31:19
|
--- src/mesa/drivers/dri/nouveau/nouveau_context.c | 49 ++++++++++++++++------- src/mesa/drivers/dri/nouveau/nouveau_context.h | 7 +++ src/mesa/drivers/dri/nouveau/nouveau_driver.c | 3 + src/mesa/drivers/dri/nouveau/nouveau_render_t.c | 2 + src/mesa/drivers/dri/nouveau/nouveau_screen.c | 20 +++++++++ src/mesa/drivers/dri/nouveau/nouveau_state.c | 2 - src/mesa/drivers/dri/nouveau/nv10_context.c | 2 + 7 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 9312ec7..e526b6d 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.d_stamp); if (dri_draw != dri_read) - nouveau_update_renderbuffers(dri_ctx, dri_read); + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->drawable.r_stamp); /* Pass it down to mesa. */ _mesa_make_current(ctx, dri_draw->driverPrivate, @@ -260,17 +266,30 @@ 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) - return; + if ((ctx->DrawBuffer->Name == 0 && + nctx->drawable.d_stamp != *dri_draw->pStamp) || + (dri_draw != dri_read && + ctx->ReadBuffer->Name == 0 && + nctx->drawable.r_stamp != *dri_read->pStamp)) { + if (nctx->drawable.dirty) + ctx->Driver.Flush(ctx); - ctx->Driver.Flush(ctx); + /* Ask the X server for new renderbuffers. */ + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable.d_stamp); + if (dri_draw != dri_read) + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->drawable.r_stamp); - /* 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); + if (nctx->dirty) + FIRE_RING(context_chan(ctx)); + } - FIRE_RING(context_chan(ctx)); + /* Someone's planning to draw something really soon. */ + nctx->drawable.dirty = GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 4171249..891fca0 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -38,6 +38,12 @@ enum nouveau_fallback { SWRAST, }; +struct nouveau_drawable_state { + GLboolean dirty; + unsigned int d_stamp; + unsigned int r_stamp; +}; + struct nouveau_context { GLcontext base; __DRIcontext *dri_context; @@ -48,6 +54,7 @@ struct nouveau_context { struct nouveau_bo_state bo; struct nouveau_render_state render; + struct nouveau_drawable_state drawable; }; #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..bf0e20c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -67,6 +67,8 @@ nouveau_flush(GLcontext *ctx) dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); } + + nctx->drawable.dirty = GL_FALSE; } static void @@ -82,6 +84,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..9a19144 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,23 @@ 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, + NULL, + 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 |