[mesa patch v3 2/3] dri/nouveau: Use event driven buffer validation.
Francisco Jerez
currojerez at riseup.net
Fri Jan 22 06:30:57 PST 2010
---
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
More information about the xorg-devel
mailing list