gallium: add flush_resource context function
authorMarek Olšák <marek.olsak@amd.com>
Fri, 20 Sep 2013 13:08:29 +0000 (15:08 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 20 Sep 2013 18:35:55 +0000 (20:35 +0200)
r600g needs explicit flushing before DRI2 buffers are presented on the screen.

v2: add (stub) implementations for all drivers, fix frontbuffer flushing
v3: fix galahad

Signed-off-by: Marek Olšák <marek.olsak@amd.com>
23 files changed:
src/gallium/docs/source/context.rst
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/galahad/glhd_context.c
src/gallium/drivers/i915/i915_surface.c
src/gallium/drivers/identity/id_context.c
src/gallium/drivers/ilo/ilo_blit.c
src/gallium/drivers/llvmpipe/lp_surface.c
src/gallium/drivers/noop/noop_pipe.c
src/gallium/drivers/nouveau/nv30/nv30_miptree.c
src/gallium/drivers/nouveau/nv30/nv30_resource.c
src/gallium/drivers/nouveau/nv30/nv30_resource.h
src/gallium/drivers/nouveau/nv50/nv50_surface.c
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/radeonsi/r600_blit.c
src/gallium/drivers/rbug/rbug_context.c
src/gallium/drivers/softpipe/sp_surface.c
src/gallium/drivers/svga/svga_pipe_blit.c
src/gallium/drivers/trace/tr_context.c
src/gallium/include/pipe/p_context.h
src/gallium/state_trackers/dri/common/dri_drawable.c
src/gallium/state_trackers/dri/drm/dri2.c

index 95f6b228fa220a56d608fe3d46e623acaeae04e7..d5b4d77fc12d2801aa33db7881a9c029833b5c0a 100644 (file)
@@ -423,6 +423,19 @@ Flushing
 ``flush``
 
 
+``flush_resource``
+
+Flush the resource cache, so that the resource can be used
+by an external client. Possible usage:
+- flushing a resource before presenting it on the screen
+- flushing a resource if some other process or device wants to use it
+This shouldn't be used to flush caches if the resource is only managed
+by a single pipe_screen and is not shared with another process.
+(i.e. you shouldn't use it to flush caches explicitly if you want to e.g.
+use the resource for texturing)
+
+
+
 Resource Busy Queries
 ^^^^^^^^^^^^^^^^^^^^^
 
index bae1874ed3d4be2e7aea33e67751c8ce28f240ae..197a5a00e0922ad2e587cd79ad88a4af6ffd5581 100644 (file)
@@ -394,6 +394,11 @@ render_blit(struct pipe_context *pctx, struct pipe_blit_info *info)
        return true;
 }
 
+static void
+fd_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
+{
+}
+
 void
 fd_resource_screen_init(struct pipe_screen *pscreen)
 {
@@ -414,4 +419,5 @@ fd_resource_context_init(struct pipe_context *pctx)
        pctx->surface_destroy = fd_surface_destroy;
        pctx->resource_copy_region = fd_resource_copy_region;
        pctx->blit = fd_blit;
+       pctx->flush_resource = fd_flush_resource;
 }
index ee9de058bb03aeef8e53e8d4650284197211e78c..3df22ce332eee6c5a1981076fa88ff3e1769caa3 100644 (file)
@@ -782,6 +782,18 @@ galahad_context_blit(struct pipe_context *_pipe,
    pipe->blit(pipe, &info);
 }
 
+static void
+galahad_context_flush_resource(struct pipe_context *_pipe,
+                               struct pipe_resource *_res)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource_res = galahad_resource(_res);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_resource *res = glhd_resource_res->resource;
+
+   pipe->flush_resource(pipe, res);
+}
+
 static void
 galahad_context_clear(struct pipe_context *_pipe,
                unsigned buffers,
@@ -1096,6 +1108,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    GLHD_PIPE_INIT(set_stream_output_targets);
    GLHD_PIPE_INIT(resource_copy_region);
    GLHD_PIPE_INIT(blit);
+   GLHD_PIPE_INIT(flush_resource);
    GLHD_PIPE_INIT(clear);
    GLHD_PIPE_INIT(clear_render_target);
    GLHD_PIPE_INIT(clear_depth_stencil);
index b8eef89ecd4a0aa10d500bfa48b7e7b40099faac..48d4857563a23a72f7055da0778ffcab8fe4f5aa 100644 (file)
@@ -239,6 +239,11 @@ i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info)
    util_blitter_blit(i915->blitter, &info);
 }
 
+static void
+i915_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
+{
+}
+
 static void
 i915_clear_render_target_blitter(struct pipe_context *pipe,
                                  struct pipe_surface *dst,
@@ -359,6 +364,7 @@ i915_init_surface_functions(struct i915_context *i915)
       i915->base.clear_depth_stencil = i915_clear_depth_stencil_render;
    }
    i915->base.blit = i915_blit;
+   i915->base.flush_resource = i915_flush_resource;
    i915->base.create_surface = i915_create_surface;
    i915->base.surface_destroy = i915_surface_destroy;
 }
index 6b342ebd1466873f194de952494801d44f4d5bbb..6cb7bdfa1171ee678d7561a2c429d63cd8cf4ce4 100644 (file)
@@ -648,6 +648,16 @@ identity_blit(struct pipe_context *_pipe,
    pipe->blit(pipe, &blit);
 }
 
+static void
+identity_flush_resource(struct pipe_context *_pipe,
+                        struct pipe_resource *resource)
+{
+   struct identity_context *id_pipe = identity_context(_pipe);
+   struct pipe_context *pipe = id_pipe->pipe;
+
+   pipe->flush_resource(pipe, resource);
+}
+
 static void
 identity_clear(struct pipe_context *_pipe,
                unsigned buffers,
@@ -936,6 +946,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    id_pipe->base.transfer_flush_region = identity_context_transfer_flush_region;
    id_pipe->base.transfer_inline_write = identity_context_transfer_inline_write;
    id_pipe->base.blit = identity_blit;
+   id_pipe->base.flush_resource = identity_flush_resource;
 
    id_pipe->pipe = pipe;
 
index ff8e5869658897b41004253e1e463a7d80f6585d..692224932b38d67658f255ed5e050a2c924d453c 100644 (file)
@@ -128,6 +128,11 @@ ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
    ilo_blitter_pipe_blit(ilo->blitter, info);
 }
 
+static void
+ilo_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
+{
+}
+
 /**
  * Initialize blit-related functions.
  */
@@ -136,6 +141,7 @@ ilo_init_blit_functions(struct ilo_context *ilo)
 {
    ilo->base.resource_copy_region = ilo_resource_copy_region;
    ilo->base.blit = ilo_blit;
+   ilo->base.flush_resource = ilo_flush_resource;
 
    ilo->base.clear = ilo_clear;
    ilo->base.clear_render_target = ilo_clear_render_target;
index c1eeaf566dd4de4dc17280a94269ffb18dfab479..f033c46ee84777061c725492467a4cb8ebaf5327 100644 (file)
@@ -233,6 +233,12 @@ static void lp_blit(struct pipe_context *pipe,
 }
 
 
+static void
+lp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
+{
+}
+
+
 static struct pipe_surface *
 llvmpipe_create_surface(struct pipe_context *pipe,
                         struct pipe_resource *pt,
@@ -334,4 +340,5 @@ llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
    /* These two are not actually functions dealing with surfaces */
    lp->pipe.resource_copy_region = lp_resource_copy;
    lp->pipe.blit = lp_blit;
+   lp->pipe.flush_resource = lp_flush_resource;
 }
index ac837b18fe8f40b229471ebc57628ebdd6857007..889e95ee76f9ea169594cca3107cf14dc69f26e5 100644 (file)
@@ -238,6 +238,13 @@ static void noop_blit(struct pipe_context *ctx,
 }
 
 
+static void
+noop_flush_resource(struct pipe_context *ctx,
+                    struct pipe_resource *resource)
+{
+}
+
+
 /*
  * context
  */
@@ -267,6 +274,7 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, void
        ctx->clear_depth_stencil = noop_clear_depth_stencil;
        ctx->resource_copy_region = noop_resource_copy_region;
        ctx->blit = noop_blit;
+       ctx->flush_resource = noop_flush_resource;
        ctx->create_query = noop_create_query;
        ctx->destroy_query = noop_destroy_query;
        ctx->begin_query = noop_begin_query;
index 4c237f615cd39b049a1a8e88d6abf818454997d1..1a4b8929c0f78977029dd7387be1a026e1f74e05 100644 (file)
@@ -217,6 +217,12 @@ nv30_blit(struct pipe_context *pipe,
    util_blitter_blit(nv30->blitter, &info);
 }
 
+void
+nv30_flush_resource(struct pipe_context *pipe,
+                    struct pipe_resource *resource)
+{
+}
+
 static void *
 nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_resource *pt,
                           unsigned level, unsigned usage,
index c99db1ce91bd52d8a4e0756f3ba38116b08dfe67..f56ca315ff48e50f9fe697a6545562c2583af95b 100644 (file)
@@ -74,4 +74,5 @@ nv30_resource_init(struct pipe_context *pipe)
    pipe->surface_destroy = nv30_miptree_surface_del;
    pipe->resource_copy_region = nv30_resource_copy_region;
    pipe->blit = nv30_blit;
+   pipe->flush_resource = nv30_flush_resource;
 }
index aff41966b3c9993bfa8d4f150f31da434f30bce3..1981c8d9ab94067e329b0bb6789cf5a11047268f 100644 (file)
@@ -72,4 +72,8 @@ void
 nv30_blit(struct pipe_context *pipe,
           const struct pipe_blit_info *blit_info);
 
+void
+nv30_flush_resource(struct pipe_context *pipe,
+                    struct pipe_resource *resource);
+
 #endif
index dcc1fce41c595a9e15e39559b88f14e7f1a8b225..358f57aa6fbba458f8b13dfb195b416e53f81c22 100644 (file)
@@ -1288,6 +1288,12 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
       nv50_blit_3d(nv50, info);
 }
 
+static void
+nv50_flush_resource(struct pipe_context *ctx,
+                    struct pipe_resource *resource)
+{
+}
+
 boolean
 nv50_blitter_create(struct nv50_screen *screen)
 {
@@ -1348,6 +1354,7 @@ nv50_init_surface_functions(struct nv50_context *nv50)
 
    pipe->resource_copy_region = nv50_resource_copy_region;
    pipe->blit = nv50_blit;
+   pipe->flush_resource = nv50_flush_resource;
    pipe->clear_render_target = nv50_clear_render_target;
    pipe->clear_depth_stencil = nv50_clear_depth_stencil;
 }
index 5070df80671369d5223341aa71ec4ab11fe36df1..5375bd42546cc50934ea7e4ef38f390eb3b88a1c 100644 (file)
@@ -1192,6 +1192,12 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
    NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_blit_count, 1);
 }
 
+static void
+nvc0_flush_resource(struct pipe_context *ctx,
+                    struct pipe_resource *resource)
+{
+}
+
 boolean
 nvc0_blitter_create(struct nvc0_screen *screen)
 {
@@ -1260,6 +1266,7 @@ nvc0_init_surface_functions(struct nvc0_context *nvc0)
 
    pipe->resource_copy_region = nvc0_resource_copy_region;
    pipe->blit = nvc0_blit;
+   pipe->flush_resource = nvc0_flush_resource;
    pipe->clear_render_target = nvc0_clear_render_target;
    pipe->clear_depth_stencil = nvc0_clear_depth_stencil;
 }
index 7802594bbb822334c0522ff39122c8ba767a26ac..4ec68ae6e1c1256210cb05a5fa39a625f1bd2683 100644 (file)
@@ -853,6 +853,11 @@ static void r300_blit(struct pipe_context *pipe,
     r300_blitter_end(r300);
 }
 
+static void r300_flush_resource(struct pipe_context *ctx,
+                               struct pipe_resource *resource)
+{
+}
+
 void r300_init_blit_functions(struct r300_context *r300)
 {
     r300->context.clear = r300_clear;
@@ -860,4 +865,5 @@ void r300_init_blit_functions(struct r300_context *r300)
     r300->context.clear_depth_stencil = r300_clear_depth_stencil;
     r300->context.resource_copy_region = r300_resource_copy_region;
     r300->context.blit = r300_blit;
+    r300->context.flush_resource = r300_flush_resource;
 }
index 60dda28e1845671f15967f029c32c6e2e9ed0a97..f87ce4c6b7aa8431fedb6409a5695bffac3cf758 100644 (file)
@@ -900,6 +900,11 @@ static void r600_blit(struct pipe_context *ctx,
        r600_blitter_end(ctx);
 }
 
+static void r600_flush_resource(struct pipe_context *ctx,
+                               struct pipe_resource *resource)
+{
+}
+
 void r600_init_blit_functions(struct r600_context *rctx)
 {
        rctx->b.b.clear = r600_clear;
@@ -907,4 +912,5 @@ void r600_init_blit_functions(struct r600_context *rctx)
        rctx->b.b.clear_depth_stencil = r600_clear_depth_stencil;
        rctx->b.b.resource_copy_region = r600_resource_copy_region;
        rctx->b.b.blit = r600_blit;
+       rctx->b.b.flush_resource = r600_flush_resource;
 }
index 9d7c73805554958e57a750f6c0862b462f2055c8..fef4cccb8e6383baaaaa17d464a9cd526ccc4fc8 100644 (file)
@@ -720,6 +720,11 @@ static void si_blit(struct pipe_context *ctx,
        r600_blitter_end(ctx);
 }
 
+static void si_flush_resource(struct pipe_context *ctx,
+                             struct pipe_resource *resource)
+{
+}
+
 void si_init_blit_functions(struct r600_context *rctx)
 {
        rctx->b.b.clear = r600_clear;
@@ -727,4 +732,5 @@ void si_init_blit_functions(struct r600_context *rctx)
        rctx->b.b.clear_depth_stencil = r600_clear_depth_stencil;
        rctx->b.b.resource_copy_region = r600_resource_copy_region;
        rctx->b.b.blit = si_blit;
+       rctx->b.b.flush_resource = si_flush_resource;
 }
index 721419750bb3236f2b43775c8a3ec53f61a17ebe..a103dfb5a7eaa841c88bf296f461c372e5ac2286 100644 (file)
@@ -872,6 +872,20 @@ rbug_resource_copy_region(struct pipe_context *_pipe,
    pipe_mutex_unlock(rb_pipe->call_mutex);
 }
 
+static void
+rbug_flush_resource(struct pipe_context *_pipe,
+                    struct pipe_resource *_res)
+{
+   struct rbug_context *rb_pipe = rbug_context(_pipe);
+   struct rbug_resource *rb_resource_res = rbug_resource(_res);
+   struct pipe_context *pipe = rb_pipe->pipe;
+   struct pipe_resource *res = rb_resource_res->resource;
+
+   pipe_mutex_lock(rb_pipe->call_mutex);
+   pipe->flush_resource(pipe, res);
+   pipe_mutex_unlock(rb_pipe->call_mutex);
+}
+
 static void
 rbug_clear(struct pipe_context *_pipe,
            unsigned buffers,
@@ -1181,6 +1195,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    rb_pipe->base.set_index_buffer = rbug_set_index_buffer;
    rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
    rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
+   rb_pipe->base.flush_resource = rbug_flush_resource;
    rb_pipe->base.clear = rbug_clear;
    rb_pipe->base.clear_render_target = rbug_clear_render_target;
    rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil;
index 9e1523fcf3ef74fccd8df7d4df6688ec8783f589..41f512dff4e67d4f1209870ea9cbdc54e97cf6b3 100644 (file)
@@ -83,6 +83,12 @@ static void sp_blit(struct pipe_context *pipe,
    util_blitter_blit(sp->blitter, info);
 }
 
+static void
+sp_flush_resource(struct pipe_context *pipe,
+                  struct pipe_resource *resource)
+{
+}
+
 static void
 softpipe_clear_render_target(struct pipe_context *pipe,
                              struct pipe_surface *dst,
@@ -127,4 +133,5 @@ sp_init_surface_functions(struct softpipe_context *sp)
    sp->pipe.clear_render_target = softpipe_clear_render_target;
    sp->pipe.clear_depth_stencil = softpipe_clear_depth_stencil;
    sp->pipe.blit = sp_blit;
+   sp->pipe.flush_resource = sp_flush_resource;
 }
index 05930d0ec519d01d69fd8002cdfb8a6fd3308440..ff1017c75b3028b5acbced74ddd32a70726b831f 100644 (file)
@@ -211,9 +211,17 @@ static void svga_blit(struct pipe_context *pipe,
 }
 
 
+static void
+svga_flush_resource(struct pipe_context *pipe,
+                    struct pipe_resource *resource)
+{
+}
+
+
 void
 svga_init_blit_functions(struct svga_context *svga)
 {
    svga->pipe.resource_copy_region = svga_surface_copy;
    svga->pipe.blit = svga_blit;
+   svga->pipe.flush_resource = svga_flush_resource;
 }
index 26df37132084b5d3a2386133a9f8e6b6bf57bd6c..fdd5a7a12857f4855f9adf53919acf1bb60e766f 100644 (file)
@@ -1206,6 +1206,26 @@ trace_context_blit(struct pipe_context *_pipe,
 }
 
 
+static void
+trace_context_flush_resource(struct pipe_context *_pipe,
+                             struct pipe_resource *resource)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+
+   resource = trace_resource_unwrap(tr_ctx, resource);
+
+   trace_dump_call_begin("pipe_context", "flush_resource");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(ptr, resource);
+
+   pipe->flush_resource(pipe, resource);
+
+   trace_dump_call_end();
+}
+
+
 static INLINE void
 trace_context_clear(struct pipe_context *_pipe,
                     unsigned buffers,
@@ -1604,6 +1624,7 @@ trace_context_create(struct trace_screen *tr_scr,
    TR_CTX_INIT(set_stream_output_targets);
    TR_CTX_INIT(resource_copy_region);
    TR_CTX_INIT(blit);
+   TR_CTX_INIT(flush_resource);
    TR_CTX_INIT(clear);
    TR_CTX_INIT(clear_render_target);
    TR_CTX_INIT(clear_depth_stencil);
index 69352f7260f0470aae4611a7f262c25097994783..7d09ce4b19a47387d46eb5f9e899f8c2789559fa 100644 (file)
@@ -537,6 +537,19 @@ struct pipe_context {
                                unsigned sample_count,
                                unsigned sample_index,
                                float *out_value);
+
+   /**
+    * Flush the resource cache, so that the resource can be used
+    * by an external client. Possible usage:
+    * - flushing a resource before presenting it on the screen
+    * - flushing a resource if some other process or device wants to use it
+    * This shouldn't be used to flush caches if the resource is only managed
+    * by a single pipe_screen and is not shared with another process.
+    * (i.e. you shouldn't use it to flush caches explicitly if you want to e.g.
+    * use the resource for texturing)
+    */
+   void (*flush_resource)(struct pipe_context *ctx,
+                          struct pipe_resource *resource);
 };
 
 
index ddf940048cfd6288dddf7ce04ec260476f48a94e..f255108dabedbbe8177473015ad11e2ebea89b5d 100644 (file)
@@ -438,6 +438,8 @@ dri_flush(__DRIcontext *cPriv,
    /* Flush the drawable. */
    if ((flags & __DRI2_FLUSH_DRAWABLE) &&
        drawable->textures[ST_ATTACHMENT_BACK_LEFT]) {
+      struct pipe_context *pipe = ctx->st->pipe;
+
       if (drawable->stvis.samples > 1 &&
           reason == __DRI2_THROTTLE_SWAPBUFFER) {
          /* Resolve the MSAA back buffer. */
@@ -458,6 +460,8 @@ dri_flush(__DRIcontext *cPriv,
       if (ctx->hud) {
          hud_draw(ctx->hud, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
       }
+
+      pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
    }
 
    flush_flags = 0;
index fea1c8dfe52ef553d1ef35852167209727c4a328..919ba6dc2a047533383c706cdc9464b31b0bcb62 100644 (file)
@@ -479,20 +479,24 @@ dri2_flush_frontbuffer(struct dri_context *ctx,
 {
    __DRIdrawable *dri_drawable = drawable->dPriv;
    struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+   struct pipe_context *pipe = ctx->st->pipe;
 
    if (statt != ST_ATTACHMENT_FRONT_LEFT)
       return;
 
    if (drawable->stvis.samples > 1) {
-      struct pipe_context *pipe = ctx->st->pipe;
-
       /* Resolve the front buffer. */
       dri_pipe_blit(ctx->st->pipe,
                     drawable->textures[ST_ATTACHMENT_FRONT_LEFT],
                     drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]);
-      pipe->flush(pipe, NULL, 0);
    }
 
+   if (drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) {
+      pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]);
+   }
+
+   pipe->flush(pipe, NULL, 0);
+
    if (loader->flushFrontBuffer) {
       loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
    }