gallium: Make sure we flush before some texture / buffer operations.
authorThomas Hellstrom <thellstrom-at-vmware-dot-com>
Wed, 15 Apr 2009 13:53:34 +0000 (15:53 +0200)
committerThomas Hellstrom <thellstrom-at-vmware-dot-com>
Wed, 15 Apr 2009 15:16:58 +0000 (17:16 +0200)
Also implement context member functions to optimize away those
flushes whenever possible.

Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
22 files changed:
src/gallium/drivers/cell/ppu/cell_context.c
src/gallium/drivers/failover/fo_context.c
src/gallium/drivers/i915simple/i915_context.c
src/gallium/drivers/i965simple/brw_context.c
src/gallium/drivers/nv04/nv04_context.c
src/gallium/drivers/nv10/nv10_context.c
src/gallium/drivers/nv20/nv20_context.c
src/gallium/drivers/nv30/nv30_context.c
src/gallium/drivers/nv40/nv40_context.c
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/trace/tr_context.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_cb_accum.c
src/mesa/state_tracker/st_cb_bufferobjects.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_gen_mipmap.c
src/mesa/state_tracker/st_texture.c
src/mesa/state_tracker/st_texture.h

index 808be589bd9f2ccbb90569834898a1b1ca91cb53..ebb7a7acc446bd6d3d1f627c12d4c483c13feca9 100644 (file)
@@ -99,6 +99,28 @@ static const struct debug_named_value cell_debug_flags[] = {
    {NULL, 0}
 };
 
+static unsigned int
+cell_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+cell_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
 
 struct pipe_context *
 cell_create_context(struct pipe_screen *screen,
@@ -122,6 +144,9 @@ cell_create_context(struct pipe_screen *screen,
    cell->pipe.clear = cell_clear;
    cell->pipe.flush = cell_flush;
 
+   cell->pipe.is_texture_referenced = cell_is_texture_referenced;
+   cell->pipe.is_buffer_referenced = cell_is_buffer_referenced;
+
 #if 0
    cell->pipe.begin_query = cell_begin_query;
    cell->pipe.end_query = cell_end_query;
index fcad717cf8349b16c0e154ae9cbd3e933b2ae38e..37184eac7b17522b6862d6c6bf5680fab3c15b9f 100644 (file)
@@ -105,7 +105,28 @@ static boolean failover_draw_arrays( struct pipe_context *pipe,
    return failover_draw_elements(pipe, NULL, 0, prim, start, count);
 }
 
+static unsigned int
+failover_is_texture_referenced( struct pipe_context *_pipe,
+                               struct pipe_texture *texture,
+                               unsigned face, unsigned level)
+{
+   struct failover_context *failover = failover_context( _pipe );
+   struct pipe_context *pipe = (failover->mode == FO_HW) ?
+      failover->hw : failover->sw;
+
+   return pipe->is_texture_referenced(pipe, texture, face, level);
+}
 
+static unsigned int
+failover_is_buffer_referenced( struct pipe_context *_pipe,
+                              struct pipe_buffer *buf)
+{
+   struct failover_context *failover = failover_context( _pipe );
+   struct pipe_context *pipe = (failover->mode == FO_HW) ?
+      failover->hw : failover->sw;
+
+   return pipe->is_buffer_referenced(pipe, buf);
+}
 
 struct pipe_context *failover_create( struct pipe_context *hw,
                                      struct pipe_context *sw )
@@ -151,6 +172,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
 #endif
 
    failover->pipe.flush = hw->flush;
+   failover->pipe.is_texture_referenced = failover_is_texture_referenced;
+   failover->pipe.is_buffer_referenced = failover_is_buffer_referenced;
 
    failover->dirty = 0;
 
index 3e3a59688494dbded287cde1edce82b4c2eba865..ccf9bb31fb02fdeddcdab07dcdde348240c97853 100644 (file)
@@ -136,6 +136,29 @@ static boolean i915_draw_arrays( struct pipe_context *pipe,
 }
 
 
+static unsigned int
+i915_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+i915_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 
 struct pipe_context *i915_create_context( struct pipe_screen *screen,
                                           struct pipe_winsys *pipe_winsys,
@@ -160,6 +183,9 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
    i915->pipe.draw_elements = i915_draw_elements;
    i915->pipe.draw_range_elements = i915_draw_range_elements;
 
+   i915->pipe.is_texture_referenced = i915_is_texture_referenced;
+   i915->pipe.is_buffer_referenced = i915_is_buffer_referenced;
+
    /*
     * Create drawing context and plug our rendering stage into it.
     */
index c74cbf8d73edd99e7f43e04a3cc15478f916af8b..9b33285bc73052c03015823ef142b5176ca12d2b 100644 (file)
@@ -73,6 +73,28 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps,
    pipe->surface_fill(pipe, ps, x, y, w, h, clearValue);
 }
 
+static unsigned int
+brw_is_texture_referenced( struct pipe_context *pipe,
+                          struct pipe_texture *texture,
+                          unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+brw_is_buffer_referenced( struct pipe_context *pipe,
+                         struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
 
 struct pipe_context *brw_create(struct pipe_screen *screen,
                                 struct brw_winsys *brw_winsys,
@@ -94,6 +116,9 @@ struct pipe_context *brw_create(struct pipe_screen *screen,
    brw->pipe.destroy = brw_destroy;
    brw->pipe.clear = brw_clear;
 
+   brw->pipe.is_texture_referenced = brw_is_texture_referenced;
+   brw->pipe.is_buffer_referenced = brw_is_buffer_referenced;
+
    brw_init_surface_functions(brw);
    brw_init_texture_functions(brw);
    brw_init_state_functions(brw);
index d6710cd892475d78ed4b3ea6d33a41542526d811..17166c9f51de49f07281928fa3ae33ac09d07871 100644 (file)
@@ -64,6 +64,30 @@ nv04_init_hwctx(struct nv04_context *nv04)
        return TRUE;
 }
 
+static unsigned int
+nv04_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv04_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+
 struct pipe_context *
 nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -89,6 +113,9 @@ nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
        nv04->pipe.clear = nv04_clear;
        nv04->pipe.flush = nv04_flush;
 
+       nv04->pipe.is_texture_referenced = nv04_is_texture_referenced;
+       nv04->pipe.is_buffer_referenced = nv04_is_buffer_referenced;
+
        nv04_init_surface_functions(nv04);
        nv04_init_state_functions(nv04);
 
index ef2c0c5d9fd2974ce98c64d470a63c683ff8f64c..3da8d2f568f7f331c52be549491f188594f18cc3 100644 (file)
@@ -257,6 +257,29 @@ nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
 {
 }
 
+static unsigned int
+nv10_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv10_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 struct pipe_context *
 nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -282,6 +305,9 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
        nv10->pipe.clear = nv10_clear;
        nv10->pipe.flush = nv10_flush;
 
+       nv10->pipe.is_texture_referenced = nv10_is_texture_referenced;
+       nv10->pipe.is_buffer_referenced = nv10_is_buffer_referenced;
+
        nv10_init_surface_functions(nv10);
        nv10_init_state_functions(nv10);
 
index 1659aec8fab77c224b1c85cc2d4f3b51e214664f..cbc41707d54c037752fb506e4ee49175b36b034d 100644 (file)
@@ -380,6 +380,30 @@ nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
 {
 }
 
+
+static unsigned int
+nv20_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv20_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 struct pipe_context *
 nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -405,6 +429,9 @@ nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
        nv20->pipe.clear = nv20_clear;
        nv20->pipe.flush = nv20_flush;
 
+       nv20->pipe.is_texture_referenced = nv20_is_texture_referenced;
+       nv20->pipe.is_buffer_referenced = nv20_is_buffer_referenced;
+
        nv20_init_surface_functions(nv20);
        nv20_init_state_functions(nv20);
 
index 61654f8756a8fc2c084b746d156ae11b1d324e6a..f827bdc78b1f3ae9bee54ee45f1afa368f2cb738 100644 (file)
@@ -31,6 +31,29 @@ nv30_destroy(struct pipe_context *pipe)
        FREE(nv30);
 }
 
+static unsigned int
+nv30_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv30_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 struct pipe_context *
 nv30_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -55,6 +78,9 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id)
        nv30->pipe.clear = nv30_clear;
        nv30->pipe.flush = nv30_flush;
 
+       nv30->pipe.is_texture_referenced = nv30_is_texture_referenced;
+       nv30->pipe.is_buffer_referenced = nv30_is_buffer_referenced;
+
        nv30_init_query_functions(nv30);
        nv30_init_surface_functions(nv30);
        nv30_init_state_functions(nv30);
index 5d325f5067fb805b78fbbb73f2b7cd5e799eed25..8eba6a43ef95338432b628380f57f15676c501cf 100644 (file)
@@ -31,6 +31,29 @@ nv40_destroy(struct pipe_context *pipe)
        FREE(nv40);
 }
 
+static unsigned int
+nv40_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv40_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 struct pipe_context *
 nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -55,6 +78,9 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
        nv40->pipe.clear = nv40_clear;
        nv40->pipe.flush = nv40_flush;
 
+       nv40->pipe.is_texture_referenced = nv40_is_texture_referenced;
+       nv40->pipe.is_buffer_referenced = nv40_is_buffer_referenced;
+
        nv40_init_query_functions(nv40);
        nv40_init_surface_functions(nv40);
        nv40_init_state_functions(nv40);
index 565a5da668cb9f3368087ff34b46db8a0eee2a6e..a511f655c19e1c4c0e27fc846c5bc5a93446f182 100644 (file)
@@ -51,6 +51,29 @@ nv50_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
 {
 }
 
+static unsigned int
+nv50_is_texture_referenced( struct pipe_context *pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv50_is_buffer_referenced( struct pipe_context *pipe,
+                          struct pipe_buffer *buf)
+{
+   /**
+    * FIXME: Optimize.
+    */
+
+   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
 struct pipe_context *
 nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
 {
@@ -76,6 +99,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
 
        nv50->pipe.flush = nv50_flush;
 
+       nv50->pipe.is_texture_referenced = nv50_is_texture_referenced;
+       nv50->pipe.is_buffer_referenced = nv50_is_buffer_referenced;
+
        nv50_init_surface_functions(nv50);
        nv50_init_state_functions(nv50);
        nv50_init_query_functions(nv50);
index 06ace27d14b0299421b2d97a2c8ce653aa5453c9..6ae4d1ad7beaeb4751be9793f2b1971a0cb8b2fb 100644 (file)
@@ -121,6 +121,21 @@ static void softpipe_destroy( struct pipe_context *pipe )
    FREE( softpipe );
 }
 
+static unsigned int
+softpipe_is_texture_referenced( struct pipe_context *pipe,
+                               struct pipe_texture *texture,
+                               unsigned face, unsigned level,
+                               unsigned zslice)
+{
+   return PIPE_UNREFERENCED;
+}
+
+static unsigned int
+softpipe_is_buffer_referenced( struct pipe_context *pipe,
+                              struct pipe_buffer *buf)
+{
+   return PIPE_UNREFERENCED;
+}
 
 struct pipe_context *
 softpipe_create( struct pipe_screen *screen,
@@ -190,6 +205,9 @@ softpipe_create( struct pipe_screen *screen,
    softpipe->pipe.clear = softpipe_clear;
    softpipe->pipe.flush = softpipe_flush;
 
+   softpipe->pipe.is_texture_referenced = softpipe_is_texture_referenced;
+   softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced;
+
    softpipe_init_query_funcs( softpipe );
    softpipe_init_texture_funcs( softpipe );
 
index d8d5821a1d16478d3dc3a33ea1ef33fa9154ef86..556b5e003ffddf1938f0cb613d76d45bb018599e 100644 (file)
@@ -1030,6 +1030,48 @@ trace_context_destroy(struct pipe_context *_pipe)
    FREE(tr_ctx);
 }
 
+static unsigned int
+trace_is_texture_referenced( struct pipe_context *_pipe,
+                           struct pipe_texture *texture,
+                           unsigned face, unsigned level)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+   unsigned int referenced;
+
+   trace_dump_call_begin("pipe_context", "is_texture_referenced");
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(ptr, texture);
+   trace_dump_arg(uint, face);
+   trace_dump_arg(uint, level);
+
+   referenced = pipe->is_texture_referenced(pipe, texture, face, level);
+
+   trace_dump_ret(uint, referenced);
+   trace_dump_call_end();
+
+   return referenced;
+}
+
+static unsigned int
+trace_is_buffer_referenced( struct pipe_context *_pipe,
+                           struct pipe_buffer *buf)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+   unsigned int referenced;
+
+   trace_dump_call_begin("pipe_context", "is_buffer_referenced");
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(ptr, buf);
+
+   referenced = pipe->is_buffer_referenced(pipe, buf);
+
+   trace_dump_ret(uint, referenced);
+   trace_dump_call_end();
+
+   return referenced;
+}
 
 struct pipe_context *
 trace_context_create(struct pipe_screen *_screen,
@@ -1096,6 +1138,8 @@ trace_context_create(struct pipe_screen *_screen,
    tr_ctx->base.surface_fill = trace_context_surface_fill;
    tr_ctx->base.clear = trace_context_clear;
    tr_ctx->base.flush = trace_context_flush;
+   tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
+   tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
 
    tr_ctx->pipe = pipe;
 
index c5c839799ea2a25b1733d858645ff687fc458159..57e966ac3b04b42043da066b9125c3be2922edab 100644 (file)
@@ -42,7 +42,6 @@ struct pipe_state_cache;
 struct pipe_query;
 struct pipe_winsys;
 
-
 /**
  * Gallium rendering context.  Basically:
  *  - state setting functions
@@ -231,6 +230,34 @@ struct pipe_context {
    void (*flush)( struct pipe_context *pipe,
                   unsigned flags,
                   struct pipe_fence_handle **fence );
+
+   /**
+    * Check whether a texture is referenced by an unflushed hw command.
+    * The state-tracker uses this function to optimize away unnecessary
+    * flushes. It is safe (but wasteful) to always return.
+    * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
+    * \param pipe  The pipe context whose unflushed hw commands will be
+    *              checked.
+    * \param level  mipmap level.
+    * \param texture  texture to check.
+    * \param face  cubemap face. Use 0 for non-cubemap texture.
+    */
+
+   unsigned int (*is_texture_referenced) (struct pipe_context *pipe,
+                                         struct pipe_texture *texture,
+                                         unsigned face, unsigned level);
+   /**
+    * Check whether a buffer is referenced by an unflushed hw command.
+    * The state-tracker uses this function to optimize away unnecessary
+    * flushes. It is safe (but wasteful) to always return
+    * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
+    * \param pipe  The pipe context whose unflushed hw commands will be
+    *              checked.
+    * \param buf  Buffer to check.
+    */
+
+   unsigned int (*is_buffer_referenced) (struct pipe_context *pipe,
+                                        struct pipe_buffer *buf);
 };
 
 
index 1d2aa109495e7a7f3bb5bba85d7fefb89cd5411a..82e23c413c813222cd1fd9d99c97ccfe08f493d1 100644 (file)
@@ -312,6 +312,13 @@ enum pipe_transfer_usage {
 #define PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS 26
 
 
+/**
+ * Referenced query flags.
+ */
+
+#define PIPE_UNREFERENCED         0
+#define PIPE_REFERENCED_FOR_READ  (1 << 0)
+#define PIPE_REFERENCED_FOR_WRITE (1 << 1)
 
 #ifdef __cplusplus
 }
index 3f9a825a153e938d651cf92ae6d5c5abcdcdc7d0..1510a1e23619f26fd71a00b7068c311965a660c0 100644 (file)
@@ -40,6 +40,7 @@
 #include "st_draw.h"
 #include "st_public.h"
 #include "st_format.h"
+#include "st_texture.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
@@ -118,6 +119,9 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
    const GLint height = ctx->DrawBuffer->_Ymax - ypos;
    GLubyte *map;
 
+   st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0,
+                               PIPE_TRANSFER_WRITE);
+
    acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,
                                      PIPE_TRANSFER_WRITE, xpos, ypos,
                                      width, height);
@@ -163,6 +167,9 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
    struct pipe_transfer *acc_pt;
    GLubyte *map;
 
+   st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ_WRITE);
+
    acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,
                                      PIPE_TRANSFER_READ_WRITE, xpos, ypos,
                                      width, height);
@@ -192,20 +199,27 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
 
 
 static void
-accum_accum(struct pipe_context *pipe, GLfloat value,
+accum_accum(struct st_context *st, GLfloat value,
             GLint xpos, GLint ypos, GLint width, GLint height,
             struct st_renderbuffer *acc_strb,
             struct st_renderbuffer *color_strb)
 {
+   struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_transfer *acc_trans, *color_trans;
    GLfloat *colorBuf, *accBuf;
    GLint i;
 
+   st_teximage_flush_before_map(st, acc_strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ);
+
    acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,
                                         PIPE_TRANSFER_READ, xpos, ypos,
                                         width, height);
 
+   st_teximage_flush_before_map(st, color_strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ);
+
    color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0,
                                           PIPE_TRANSFER_READ, xpos, ypos,
                                           width, height);
@@ -235,20 +249,27 @@ accum_accum(struct pipe_context *pipe, GLfloat value,
 
 
 static void
-accum_load(struct pipe_context *pipe, GLfloat value,
+accum_load(struct st_context *st, GLfloat value,
            GLint xpos, GLint ypos, GLint width, GLint height,
            struct st_renderbuffer *acc_strb,
            struct st_renderbuffer *color_strb)
 {
+   struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_transfer *acc_trans, *color_trans;
    GLfloat *buf;
    GLint i;
 
+   st_teximage_flush_before_map(st, acc_strb->texture, 0, 0,
+                               PIPE_TRANSFER_WRITE);
+
    acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,
                                         PIPE_TRANSFER_WRITE, xpos, ypos,
                                         width, height);
 
+   st_teximage_flush_before_map(st, color_strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ);
+
    color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0,
                                         PIPE_TRANSFER_READ, xpos, ypos,
                                         width, height);
@@ -284,10 +305,16 @@ accum_return(GLcontext *ctx, GLfloat value,
 
    abuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
 
+   st_teximage_flush_before_map(ctx->st, acc_strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ);
+
    acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0,
                                         PIPE_TRANSFER_READ, xpos, ypos,
                                         width, height);
 
+   st_teximage_flush_before_map(ctx->st, color_strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ_WRITE);
+
    color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0,
                                           PIPE_TRANSFER_READ_WRITE, xpos, ypos,
                                           width, height);
@@ -325,7 +352,6 @@ static void
 st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
 {
    struct st_context *st = ctx->st;
-   struct pipe_context *pipe = st->pipe;
    struct st_renderbuffer *acc_strb
      = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);
    struct st_renderbuffer *color_strb
@@ -352,11 +378,11 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
       break;
    case GL_ACCUM:
       if (value != 0.0F) {
-         accum_accum(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
+         accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb);
       }
       break;
    case GL_LOAD:
-      accum_load(pipe, value, xpos, ypos, width, height, acc_strb, color_strb);
+      accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb);
       break;
    case GL_RETURN:
       accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb);
index 3651e4ae7dcb611b445bedebbda3b0f5e4b38cd2..fdb800fbd0f06a9f6b19c6581b62f33b969ef261 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "st_context.h"
 #include "st_cb_bufferobjects.h"
+#include "st_public.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -103,6 +104,9 @@ st_bufferobj_subdata(GLcontext *ctx,
    if (offset >= st_obj->size || size > (st_obj->size - offset))
       return;
 
+   if (pipe->is_buffer_referenced(pipe, st_obj->buffer))
+      st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL);
+
    pipe_buffer_write(pipe->screen, st_obj->buffer, offset, size, data);
 }
 
@@ -123,6 +127,10 @@ st_bufferobj_get_subdata(GLcontext *ctx,
    if (offset >= st_obj->size || size > (st_obj->size - offset))
       return;
 
+   if (pipe->is_buffer_referenced(pipe, st_obj->buffer) &
+       PIPE_REFERENCED_FOR_WRITE)
+      st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL);
+
    pipe_buffer_read(pipe->screen, st_obj->buffer, offset, size, data);
 }
 
@@ -171,7 +179,7 @@ st_bufferobj_data(GLcontext *ctx,
    st_obj->size = size;
 
    if (data)
-      st_bufferobj_subdata(ctx, target, 0, size, data, obj);
+      pipe_buffer_write(pipe->screen, st_obj->buffer, 0, size, data);
 }
 
 
@@ -185,6 +193,7 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
    struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_buffer_object *st_obj = st_buffer_object(obj);
    GLuint flags;
+   unsigned referenced;
 
    switch (access) {
    case GL_WRITE_ONLY:
@@ -200,6 +209,11 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
       break;      
    }
 
+   referenced = pipe->is_buffer_referenced(pipe, st_obj->buffer);
+   if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
+                     (flags & PIPE_BUFFER_USAGE_CPU_WRITE)))
+      st_flush(st_context(ctx), PIPE_FLUSH_RENDER_CACHE, NULL);
+
    obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags);
    if(obj->Pointer) {
       obj->Offset = 0;
index 0a4430501f9dc84b5244f1bfaab841646990dac8..c67b026413eebbf232c047c118c98c76b89dca20 100644 (file)
@@ -631,8 +631,6 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    GLint skipPixels;
    ubyte *stmap;
 
-   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
    strb = st_renderbuffer(ctx->DrawBuffer->
                           Attachment[BUFFER_STENCIL].Renderbuffer);
 
@@ -640,6 +638,9 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
       y = ctx->DrawBuffer->Height - y - height;
    }
 
+   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0,
+                               PIPE_TRANSFER_WRITE);
+
    pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,
                                  PIPE_TRANSFER_WRITE, x, y,
                                  width, height);
@@ -825,6 +826,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
                           GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
                           &ctx->DefaultPacking, buffer);
 
+   st_teximage_flush_before_map(ctx->st, rbDraw->texture, 0, 0,
+                               PIPE_TRANSFER_WRITE);
+
    ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0,
                                      PIPE_TRANSFER_WRITE, dstx, dsty,
                                      width, height);
index 9ce5f3fe84cb8cece4198c5b7702135306d1d50b..519ad6660f64f98c40d89968427a4a7c326d8868 100644 (file)
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
 #include "util/u_tile.h"
+
 #include "st_context.h"
 #include "st_cb_bitmap.h"
 #include "st_cb_readpixels.h"
 #include "st_cb_fbo.h"
 #include "st_format.h"
 #include "st_public.h"
-
+#include "st_texture.h"
 
 /**
  * Special case for reading stencil buffer.
@@ -73,6 +74,10 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
    }
 
    /* Create a read transfer from the renderbuffer's texture */
+
+   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ);
+
    pt = screen->get_tex_transfer(screen, strb->texture,  0, 0, 0,
                                  PIPE_TRANSFER_READ, x, y, width, height);
 
@@ -240,6 +245,9 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
          y = strb->texture->height[0] - y - height;
       }
 
+      st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0,
+                                  PIPE_TRANSFER_READ);
+
       trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,
                                        PIPE_TRANSFER_READ, x, y, width, height);
       if (!trans) {
index 1f14b3705d500293eda0f8024edb3502bf0172e0..727432d7dedeb0168c870da81116ce4f8a33df0b 100644 (file)
@@ -700,6 +700,10 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
       /* Image is stored in hardware format in a buffer managed by the
        * kernel.  Need to explicitly map and unmap it.
        */
+
+      st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level,
+                                  PIPE_TRANSFER_READ);
+
       texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
                                             PIPE_TRANSFER_READ, 0, 0,
                                             stImage->base.Width,
@@ -808,6 +812,8 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
     * from uploading the buffer under us.
     */
    if (stImage->pt) {
+      st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level,
+                                  PIPE_TRANSFER_WRITE);
       texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, 
                                             PIPE_TRANSFER_WRITE,
                                             xoffset, yoffset,
@@ -932,6 +938,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
       srcY = strb->Base.Height - srcY - height;
    }
 
+   st_teximage_flush_before_map(ctx->st, strb->texture, 0, 0,
+                               PIPE_TRANSFER_READ);
+
    src_trans = screen->get_tex_transfer( screen,
                                          strb->texture,
                                          0, 0, 0,
@@ -939,6 +948,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
                                          srcX, srcY,
                                          width, height);
 
+   st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0,
+                               PIPE_TRANSFER_WRITE);
+
    texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE,
                                   destX, destY, width, height);
 
@@ -1318,6 +1330,11 @@ copy_image_data_to_texture(struct st_context *st,
 
       /* More straightforward upload.  
        */
+
+      st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel,
+                                  PIPE_TRANSFER_WRITE);
+
+
       st_texture_image_data(st->pipe,
                             stObj->pt,
                             stImage->face,
index 9cc2176d5e47ef04b6003e936952eba1d64f5229..6e9aa5245e236c50ae9205ad8b907ae58b7553c8 100644 (file)
@@ -123,10 +123,17 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
       const ubyte *srcData;
       ubyte *dstData;
 
+      st_teximage_flush_before_map(ctx->st, pt, face, srcLevel,
+                                  PIPE_TRANSFER_READ);
+
       srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
                                           PIPE_TRANSFER_READ, 0, 0,
                                           pt->width[srcLevel],
                                           pt->height[srcLevel]);
+
+      st_teximage_flush_before_map(ctx->st, pt, face, dstLevel,
+                                  PIPE_TRANSFER_WRITE);
+
       dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
                                           PIPE_TRANSFER_WRITE, 0, 0,
                                           pt->width[dstLevel],
index 19eb7e2f69c6e31623c0b9533989ea8072039af3..fcbaeb69894999f73728cbc325b6f94cea4af2b8 100644 (file)
@@ -188,8 +188,10 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
                     GLuint zoffset, enum pipe_transfer_usage usage,
                      GLuint x, GLuint y, GLuint w, GLuint h)
 {
-   struct pipe_screen *screen = st->pipe->screen;
+   struct pipe_context *pipe = st->pipe;
+   struct pipe_screen *screen = pipe->screen;
    struct pipe_texture *pt = stImage->pt;
+
    DBG("%s \n", __FUNCTION__);
 
    stImage->transfer = screen->get_tex_transfer(screen, pt, stImage->face,
@@ -265,6 +267,7 @@ st_texture_image_data(struct pipe_context *pipe,
    struct pipe_transfer *dst_transfer;
 
    DBG("%s\n", __FUNCTION__);
+
    for (i = 0; i < depth; i++) {
       dst_transfer = screen->get_tex_transfer(screen, dst, face, level, i,
                                               PIPE_TRANSFER_WRITE, 0, 0,
@@ -481,3 +484,20 @@ st_release_teximage(struct st_framebuffer *stfb, uint surfIndex,
 
    return 1;
 }
+
+void
+st_teximage_flush_before_map(struct st_context *st,
+                            struct pipe_texture *pt,
+                            unsigned int face,
+                            unsigned int level,
+                            enum pipe_transfer_usage usage)
+{
+   struct pipe_context *pipe = st->pipe;
+   unsigned referenced =
+      pipe->is_texture_referenced(pipe, pt, face, level);
+
+   if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
+                     usage == PIPE_TRANSFER_WRITE ||
+                     usage == PIPE_TRANSFER_READ_WRITE))
+      st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
+}
index 60c000115e89093fa2a61b0b875382fb8693f4f0..a392e3d57cd0f9ac15301395c6c92cc29c8fdb5f 100644 (file)
@@ -170,5 +170,10 @@ st_texture_image_copy(struct pipe_context *pipe,
                       struct pipe_texture *src,
                       GLuint face);
 
-
+extern void
+st_teximage_flush_before_map(struct st_context *st,
+                            struct pipe_texture *pt,
+                            unsigned int face,
+                            unsigned int level,
+                            enum pipe_transfer_usage usage);
 #endif