diff options
author | Marek Olšák <[email protected]> | 2013-09-20 15:08:29 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2013-09-20 20:35:55 +0200 |
commit | 419cd5f2a24b87d31a2fd9dd9b7d0025b4f5515c (patch) | |
tree | 517df295a28d5fc0f0542de5e6f2552886b32e5b | |
parent | d2bd63433a252c84488023e9877e70d69223da42 (diff) |
gallium: add flush_resource context function
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 <[email protected]>
23 files changed, 188 insertions, 3 deletions
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 95f6b228fa2..d5b4d77fc12 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -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 ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index bae1874ed3d..197a5a00e09 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -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; } diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c index ee9de058bb0..3df22ce332e 100644 --- a/src/gallium/drivers/galahad/glhd_context.c +++ b/src/gallium/drivers/galahad/glhd_context.c @@ -783,6 +783,18 @@ galahad_context_blit(struct pipe_context *_pipe, } 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, const union pipe_color_union *color, @@ -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); diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index b8eef89ecd4..48d4857563a 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -240,6 +240,11 @@ i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_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, const union pipe_color_union *color, @@ -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; } diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 6b342ebd146..6cb7bdfa117 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -649,6 +649,16 @@ identity_blit(struct pipe_context *_pipe, } 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, const union pipe_color_union *color, @@ -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; diff --git a/src/gallium/drivers/ilo/ilo_blit.c b/src/gallium/drivers/ilo/ilo_blit.c index ff8e5869658..692224932b3 100644 --- a/src/gallium/drivers/ilo/ilo_blit.c +++ b/src/gallium/drivers/ilo/ilo_blit.c @@ -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; diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index c1eeaf566dd..f033c46ee84 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -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; } diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c index ac837b18fe8..889e95ee76f 100644 --- a/src/gallium/drivers/noop/noop_pipe.c +++ b/src/gallium/drivers/noop/noop_pipe.c @@ -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; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c index 4c237f615cd..1a4b8929c0f 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c @@ -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, diff --git a/src/gallium/drivers/nouveau/nv30/nv30_resource.c b/src/gallium/drivers/nouveau/nv30/nv30_resource.c index c99db1ce91b..f56ca315ff4 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_resource.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_resource.c @@ -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; } diff --git a/src/gallium/drivers/nouveau/nv30/nv30_resource.h b/src/gallium/drivers/nouveau/nv30/nv30_resource.h index aff41966b3c..1981c8d9ab9 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_resource.h +++ b/src/gallium/drivers/nouveau/nv30/nv30_resource.h @@ -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 diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c index dcc1fce41c5..358f57aa6fb 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c @@ -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; } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c index 5070df80671..5375bd42546 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c @@ -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; } diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 7802594bbb8..4ec68ae6e1c 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -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; } diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 60dda28e184..f87ce4c6b7a 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -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; } diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c index 9d7c7380555..fef4cccb8e6 100644 --- a/src/gallium/drivers/radeonsi/r600_blit.c +++ b/src/gallium/drivers/radeonsi/r600_blit.c @@ -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; } diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index 721419750bb..a103dfb5a7e 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -873,6 +873,20 @@ rbug_resource_copy_region(struct pipe_context *_pipe, } 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, const union pipe_color_union *color, @@ -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; diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 9e1523fcf3e..41f512dff4e 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -84,6 +84,12 @@ static void sp_blit(struct pipe_context *pipe, } 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, const union pipe_color_union *color, @@ -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; } diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c index 05930d0ec51..ff1017c75b3 100644 --- a/src/gallium/drivers/svga/svga_pipe_blit.c +++ b/src/gallium/drivers/svga/svga_pipe_blit.c @@ -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; } diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 26df3713208..fdd5a7a1285 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -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); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 69352f7260f..7d09ce4b19a 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -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); }; diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c index ddf940048cf..f255108dabe 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.c +++ b/src/gallium/state_trackers/dri/common/dri_drawable.c @@ -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; diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index fea1c8dfe52..919ba6dc2a0 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -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); } |