---
 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

_______________________________________________
xorg-devel mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to