From: Marek Olšák Date: Thu, 29 Nov 2012 01:55:01 +0000 (+0100) Subject: gallium/postprocess: share pipe_context and cso_context with the state tracker X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3e163a137be7f9a80ec720903c4bda028de5681f;p=mesa.git 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 --- diff --git a/src/gallium/auxiliary/postprocess/postprocess.h b/src/gallium/auxiliary/postprocess/postprocess.h index dfa15f713ac..52ebeb92f73 100644 --- a/src/gallium/auxiliary/postprocess/postprocess.h +++ b/src/gallium/auxiliary/postprocess/postprocess.h @@ -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 */ diff --git a/src/gallium/auxiliary/postprocess/pp_init.c b/src/gallium/auxiliary/postprocess/pp_init.c index 2dc29ac5b4b..e059be6e9bc 100644 --- a/src/gallium/auxiliary/postprocess/pp_init.c +++ b/src/gallium/auxiliary/postprocess/pp_init.c @@ -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); diff --git a/src/gallium/auxiliary/postprocess/pp_program.c b/src/gallium/auxiliary/postprocess/pp_program.c index 31e2bee7696..c25078df6f1 100644 --- a/src/gallium/auxiliary/postprocess/pp_program.c +++ b/src/gallium/auxiliary/postprocess/pp_program.c @@ -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; } diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c index 4e6d6750f0b..6f063246562 100644 --- a/src/gallium/auxiliary/postprocess/pp_run.c +++ b/src/gallium/auxiliary/postprocess/pp_run.c @@ -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. */ diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h index 85de1c2af85..91c5529a1f5 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -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. */ diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c index 360174b056d..e77c43f140c 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.c +++ b/src/gallium/state_trackers/dri/common/dri_context.c @@ -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; diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index 5576a0d6cb3..b58c1a358b4 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -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;