gallium/postprocess: share pipe_context and cso_context with the state tracker
Using one context instead of two is more efficient and we can skip another context flush. Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
parent
135fe907a0
commit
3e163a137b
|
@ -65,13 +65,15 @@ struct pp_queue_t
|
|||
|
||||
/* Main functions */
|
||||
|
||||
struct pp_queue_t *pp_init(struct pipe_screen *, const unsigned int *);
|
||||
struct pp_queue_t *pp_init(struct pipe_context *pipe, const unsigned int *,
|
||||
struct cso_context *);
|
||||
void pp_run(struct pp_queue_t *, struct pipe_resource *,
|
||||
struct pipe_resource *, struct pipe_resource *);
|
||||
void pp_free(struct pp_queue_t *);
|
||||
void pp_free_fbos(struct pp_queue_t *);
|
||||
void pp_debug(const char *, ...);
|
||||
struct program *pp_init_prog(struct pp_queue_t *, struct pipe_screen *);
|
||||
struct program *pp_init_prog(struct pp_queue_t *, struct pipe_context *pipe,
|
||||
struct cso_context *);
|
||||
void pp_init_fbos(struct pp_queue_t *, unsigned int, unsigned int);
|
||||
|
||||
/* The filters */
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
|
||||
/** Initialize the post-processing queue. */
|
||||
struct pp_queue_t *
|
||||
pp_init(struct pipe_screen *pscreen, const unsigned int *enabled)
|
||||
pp_init(struct pipe_context *pipe, const unsigned int *enabled,
|
||||
struct cso_context *cso)
|
||||
{
|
||||
|
||||
unsigned int curpos = 0, i, tmp_req = 0;
|
||||
|
@ -64,7 +65,7 @@ pp_init(struct pipe_screen *pscreen, const unsigned int *enabled)
|
|||
if (!tmp_q || !ppq || !ppq->shaders || !ppq->verts)
|
||||
goto error;
|
||||
|
||||
ppq->p = pp_init_prog(ppq, pscreen);
|
||||
ppq->p = pp_init_prog(ppq, pipe, cso);
|
||||
if (!ppq->p)
|
||||
goto error;
|
||||
|
||||
|
@ -89,7 +90,7 @@ pp_init(struct pipe_screen *pscreen, const unsigned int *enabled)
|
|||
}
|
||||
}
|
||||
|
||||
ppq->p->blitctx = util_create_blit(ppq->p->pipe, ppq->p->cso);
|
||||
ppq->p->blitctx = util_create_blit(ppq->p->pipe, cso);
|
||||
if (!ppq->p->blitctx)
|
||||
goto error;
|
||||
|
||||
|
@ -152,9 +153,6 @@ pp_free(struct pp_queue_t *ppq)
|
|||
|
||||
util_destroy_blit(ppq->p->blitctx);
|
||||
|
||||
cso_set_sampler_views(ppq->p->cso, PIPE_SHADER_FRAGMENT, 0, NULL);
|
||||
cso_release_all(ppq->p->cso);
|
||||
|
||||
for (i = 0; i < ppq->n_filters; i++) {
|
||||
for (j = 0; j < PP_MAX_PASSES && ppq->shaders[i][j]; j++) {
|
||||
if (j >= ppq->verts[i]) {
|
||||
|
@ -168,9 +166,6 @@ pp_free(struct pp_queue_t *ppq)
|
|||
}
|
||||
}
|
||||
|
||||
cso_destroy_context(ppq->p->cso);
|
||||
ppq->p->pipe->destroy(ppq->p->pipe);
|
||||
|
||||
FREE(ppq->p);
|
||||
FREE(ppq->pp_queue);
|
||||
FREE(ppq);
|
||||
|
|
|
@ -38,26 +38,22 @@
|
|||
|
||||
/** Initialize the internal details */
|
||||
struct program *
|
||||
pp_init_prog(struct pp_queue_t *ppq, struct pipe_screen *pscreen)
|
||||
pp_init_prog(struct pp_queue_t *ppq, struct pipe_context *pipe,
|
||||
struct cso_context *cso)
|
||||
{
|
||||
|
||||
struct program *p;
|
||||
|
||||
pp_debug("Initializing program\n");
|
||||
if (!pscreen)
|
||||
if (!pipe)
|
||||
return NULL;
|
||||
|
||||
p = CALLOC(1, sizeof(struct program));
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->screen = pscreen;
|
||||
p->pipe = pscreen->context_create(pscreen, NULL);
|
||||
|
||||
/* XXX this doesn't use the cso_context of the state tracker, but creates
|
||||
* its own. Having 2 existing cso_contexts use 1 pipe_context may cause
|
||||
* undefined behavior! */
|
||||
p->cso = cso_create_context(p->pipe);
|
||||
p->screen = pipe->screen;
|
||||
p->pipe = pipe;
|
||||
p->cso = cso;
|
||||
|
||||
{
|
||||
static const float verts[4][2][4] = {
|
||||
|
@ -79,7 +75,7 @@ pp_init_prog(struct pp_queue_t *ppq, struct pipe_screen *pscreen)
|
|||
}
|
||||
};
|
||||
|
||||
p->vbuf = pipe_buffer_create(pscreen, PIPE_BIND_VERTEX_BUFFER,
|
||||
p->vbuf = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER,
|
||||
PIPE_USAGE_STATIC, sizeof(verts));
|
||||
pipe_buffer_write(p->pipe, p->vbuf, 0, sizeof(verts), verts);
|
||||
}
|
||||
|
@ -140,7 +136,5 @@ pp_init_prog(struct pp_queue_t *ppq, struct pipe_screen *pscreen)
|
|||
p->surf.usage = PIPE_BIND_RENDER_TARGET;
|
||||
p->surf.format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
p->pipe->set_sample_mask(p->pipe, ~0);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||
{
|
||||
struct pipe_resource *refin = NULL, *refout = NULL;
|
||||
unsigned int i;
|
||||
struct cso_context *cso = ppq->p->cso;
|
||||
|
||||
if (in->width0 != ppq->p->framebuffer.width ||
|
||||
in->height0 != ppq->p->framebuffer.height) {
|
||||
|
@ -65,6 +66,28 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||
in = ppq->tmp[0];
|
||||
}
|
||||
|
||||
/* save state (restored below) */
|
||||
cso_save_blend(cso);
|
||||
cso_save_depth_stencil_alpha(cso);
|
||||
cso_save_fragment_shader(cso);
|
||||
cso_save_framebuffer(cso);
|
||||
cso_save_geometry_shader(cso);
|
||||
cso_save_rasterizer(cso);
|
||||
cso_save_sample_mask(cso);
|
||||
cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
|
||||
cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
|
||||
cso_save_stencil_ref(cso);
|
||||
cso_save_stream_outputs(cso);
|
||||
cso_save_vertex_elements(cso);
|
||||
cso_save_vertex_shader(cso);
|
||||
cso_save_viewport(cso);
|
||||
cso_save_aux_vertex_buffer_slot(cso);
|
||||
|
||||
/* set default state */
|
||||
cso_set_sample_mask(cso, ~0);
|
||||
cso_set_stream_outputs(cso, 0, NULL, 0);
|
||||
cso_set_geometry_shader_handle(cso, NULL);
|
||||
|
||||
// Kept only for this frame.
|
||||
pipe_resource_reference(&ppq->depth, indepth);
|
||||
pipe_resource_reference(&refin, in);
|
||||
|
@ -100,6 +123,23 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
|
|||
break;
|
||||
}
|
||||
|
||||
/* restore state we changed */
|
||||
cso_restore_blend(cso);
|
||||
cso_restore_depth_stencil_alpha(cso);
|
||||
cso_restore_fragment_shader(cso);
|
||||
cso_restore_framebuffer(cso);
|
||||
cso_restore_geometry_shader(cso);
|
||||
cso_restore_rasterizer(cso);
|
||||
cso_restore_sample_mask(cso);
|
||||
cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
|
||||
cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
|
||||
cso_restore_stencil_ref(cso);
|
||||
cso_restore_stream_outputs(cso);
|
||||
cso_restore_vertex_elements(cso);
|
||||
cso_restore_vertex_shader(cso);
|
||||
cso_restore_viewport(cso);
|
||||
cso_restore_aux_vertex_buffer_slot(cso);
|
||||
|
||||
pipe_resource_reference(&ppq->depth, NULL);
|
||||
pipe_resource_reference(&refin, NULL);
|
||||
pipe_resource_reference(&refout, NULL);
|
||||
|
@ -180,7 +220,6 @@ pp_filter_draw(struct program *p)
|
|||
{
|
||||
util_draw_vertex_buffer(p->pipe, p->cso, p->vbuf, 0, 0,
|
||||
PIPE_PRIM_QUADS, 4, 2);
|
||||
p->pipe->flush(p->pipe, NULL);
|
||||
}
|
||||
|
||||
/** Set the framebuffer as active. */
|
||||
|
|
|
@ -352,6 +352,17 @@ struct st_context_iface
|
|||
void *st_context_private;
|
||||
void *st_manager_private;
|
||||
|
||||
/**
|
||||
* The CSO context associated with this context in case we need to draw
|
||||
* something before swap buffers.
|
||||
*/
|
||||
struct cso_context *cso_context;
|
||||
|
||||
/**
|
||||
* The gallium context.
|
||||
*/
|
||||
struct pipe_context *pipe;
|
||||
|
||||
/**
|
||||
* Destroy the context.
|
||||
*/
|
||||
|
|
|
@ -152,7 +152,9 @@ dri_create_context(gl_api api, const struct gl_config * visual,
|
|||
// Context successfully created. See if post-processing is requested.
|
||||
dri_pp_query(ctx);
|
||||
|
||||
ctx->pp = pp_init(screen->base.screen, ctx->pp_enabled);
|
||||
if (ctx->st->cso_context) {
|
||||
ctx->pp = pp_init(ctx->st->pipe, ctx->pp_enabled, ctx->st->cso_context);
|
||||
}
|
||||
|
||||
*error = __DRI_CTX_ERROR_SUCCESS;
|
||||
return GL_TRUE;
|
||||
|
|
|
@ -673,6 +673,8 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
|
|||
st->iface.copy = st_context_copy;
|
||||
st->iface.share = st_context_share;
|
||||
st->iface.st_context_private = (void *) smapi;
|
||||
st->iface.cso_context = st->cso_context;
|
||||
st->iface.pipe = st->pipe;
|
||||
|
||||
*error = ST_CONTEXT_SUCCESS;
|
||||
return &st->iface;
|
||||
|
|
Loading…
Reference in New Issue