[Mesa-dev] [PATCH 3/4] i965/state: Create separate dirty state bits for each pipeline
Kristian Høgsberg
krh at bitplanet.net
Tue Mar 10 16:11:08 PDT 2015
On Tue, Mar 10, 2015 at 10:49 AM, Jordan Justen
<jordan.l.justen at intel.com> wrote:
> When uploading state for a pipeline, we will save changed state for
> the other pipelines.
>
> Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
> ---
> src/mesa/drivers/dri/i965/brw_context.h | 1 +
> src/mesa/drivers/dri/i965/brw_state_upload.c | 41 ++++++++++++++++++++++------
> 2 files changed, 34 insertions(+), 8 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
> index fd43b07..902de18 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -1101,6 +1101,7 @@ struct brw_context
> GLuint NewGLState;
> struct {
> struct brw_state_flags dirty;
> + struct brw_state_flags pipelines[BRW_NUM_PIPELINES];
> } state;
>
> struct brw_cache cache;
> diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
> index dbfdc92..6966f06 100644
> --- a/src/mesa/drivers/dri/i965/brw_state_upload.c
> +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
> @@ -580,15 +580,16 @@ brw_upload_programs(struct brw_context *brw)
> brw_upload_wm_prog(brw);
> }
>
> -/***********************************************************************
> - * Emit all state:
> - */
> -void brw_upload_render_state(struct brw_context *brw)
> +static inline void
> +brw_upload_pipeline_state(struct brw_context *brw,
> + enum brw_pipeline pipeline)
> {
> struct gl_context *ctx = &brw->ctx;
> struct brw_state_flags *state = &brw->state.dirty;
> int i;
> static int dirty_count = 0;
> + struct brw_state_flags *pipeline_state =
> + &brw->state.pipelines[pipeline];
>
> state->mesa |= brw->NewGLState;
> brw->NewGLState = 0;
> @@ -627,6 +628,12 @@ void brw_upload_render_state(struct brw_context *brw)
> brw->state.dirty.brw |= BRW_NEW_NUM_SAMPLES;
> }
>
> + if ((pipeline_state->mesa | pipeline_state->brw) != 0) {
> + state->mesa |= pipeline_state->mesa;
> + state->brw |= pipeline_state->brw;
> + memset(pipeline_state, 0, sizeof(struct brw_state_flags));
> + }
> +
> if ((state->mesa | state->brw) == 0)
> return;
>
> @@ -636,6 +643,9 @@ void brw_upload_render_state(struct brw_context *brw)
>
> brw_upload_programs(brw);
>
> + const struct brw_tracked_state *atoms =
> + brw_pipeline_first_atom(brw, pipeline);
Instead of looping over num_atoms[] to determine the start of the
compute pipeline atoms, I think it'd be simpler to just have the
compute atoms be a separate array in struct brw_context.
> if (unlikely(INTEL_DEBUG)) {
> /* Debug version which enforces various sanity checks on the
> * state flags which are generated and checked to help ensure
> @@ -645,8 +655,8 @@ void brw_upload_render_state(struct brw_context *brw)
> memset(&examined, 0, sizeof(examined));
> prev = *state;
>
> - for (i = 0; i < brw->num_atoms[BRW_RENDER_PIPELINE]; i++) {
> - const struct brw_tracked_state *atom = &brw->atoms[i];
> + for (i = 0; i < brw->num_atoms[pipeline]; i++) {
This makes the loop condition a more complex expression. I don't
think gcc computes and caches brw->num_atoms[pipeline] outside the
loop so this adds a bit of code to this very hot loop. I'd try
something like
int num_atoms = brw->num_atoms[pipeline]
and use num_atoms in the loop condition instead. It may be the source
of the slight performance regression on OglBatch7.
> + const struct brw_tracked_state *atom = &atoms[i];
> struct brw_state_flags generated;
>
> if (check_state(state, &atom->dirty)) {
> @@ -665,8 +675,8 @@ void brw_upload_render_state(struct brw_context *brw)
> }
> }
> else {
> - for (i = 0; i < brw->num_atoms[BRW_RENDER_PIPELINE]; i++) {
> - const struct brw_tracked_state *atom = &brw->atoms[i];
> + for (i = 0; i < brw->num_atoms[pipeline]; i++) {
> + const struct brw_tracked_state *atom = &atoms[i];
>
> if (check_state(state, &atom->dirty)) {
> atom->emit(brw);
> @@ -685,8 +695,23 @@ void brw_upload_render_state(struct brw_context *brw)
> fprintf(stderr, "\n");
> }
> }
> +
> + /* Save all dirty state into the other pipelines */
> + for (int i = 0; i < BRW_NUM_PIPELINES; i++) {
> + if (i != pipeline) {
> + brw->state.pipelines[i].mesa |= state->mesa;
> + brw->state.pipelines[i].brw |= state->brw;
> + }
> + }
> }
>
> +/***********************************************************************
> + * Emit all state:
> + */
> +void brw_upload_render_state(struct brw_context *brw)
> +{
> + brw_upload_pipeline_state(brw, BRW_RENDER_PIPELINE);
> +}
>
> /**
> * Clear dirty bits to account for the fact that the state emitted by
> --
> 2.1.4
>
More information about the mesa-dev
mailing list