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>
``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
^^^^^^^^^^^^^^^^^^^^^
return true;
}
+static void
+fd_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
+{
+}
+
void
fd_resource_screen_init(struct pipe_screen *pscreen)
{
pctx->surface_destroy = fd_surface_destroy;
pctx->resource_copy_region = fd_resource_copy_region;
pctx->blit = fd_blit;
+ pctx->flush_resource = fd_flush_resource;
}
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,
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);
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,
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;
}
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,
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;
ilo_blitter_pipe_blit(ilo->blitter, info);
}
+static void
+ilo_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
+{
+}
+
/**
* Initialize blit-related functions.
*/
{
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;
}
+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,
/* 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;
}
}
+static void
+noop_flush_resource(struct pipe_context *ctx,
+ struct pipe_resource *resource)
+{
+}
+
+
/*
* context
*/
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;
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,
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;
}
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
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)
{
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;
}
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)
{
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;
}
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;
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;
}
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;
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;
}
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;
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;
}
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,
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;
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,
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;
}
}
+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;
}
}
+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,
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);
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);
};
/* 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. */
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;
{
__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);
}