static inline void
brw_upload_pipeline_state(struct brw_context *brw,
                          enum brw_pipeline pipeline)
{
   struct gl_context *ctx = &brw->ctx;
   int i;
   static int dirty_count = 0;
   struct brw_state_flags state = brw->state.pipelines[pipeline];
   unsigned int fb_samples = _mesa_geometric_samples(ctx->DrawBuffer);

   brw_select_pipeline(brw, pipeline);

   if (0) {
      /* Always re-emit all state. */
      brw->NewGLState = ~0;
      ctx->NewDriverState = ~0ull;
   }

   if (pipeline == BRW_RENDER_PIPELINE) {
      if (brw->fragment_program != ctx->FragmentProgram._Current) {
         brw->fragment_program = ctx->FragmentProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_FRAGMENT_PROGRAM;
      }

      if (brw->tess_eval_program != ctx->TessEvalProgram._Current) {
         brw->tess_eval_program = ctx->TessEvalProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_TESS_PROGRAMS;
      }

      if (brw->tess_ctrl_program != ctx->TessCtrlProgram._Current) {
         brw->tess_ctrl_program = ctx->TessCtrlProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_TESS_PROGRAMS;
      }

      if (brw->geometry_program != ctx->GeometryProgram._Current) {
         brw->geometry_program = ctx->GeometryProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_GEOMETRY_PROGRAM;
      }

      if (brw->vertex_program != ctx->VertexProgram._Current) {
         brw->vertex_program = ctx->VertexProgram._Current;
         brw->ctx.NewDriverState |= BRW_NEW_VERTEX_PROGRAM;
      }
   }

   if (brw->compute_program != ctx->ComputeProgram._Current) {
      brw->compute_program = ctx->ComputeProgram._Current;
      brw->ctx.NewDriverState |= BRW_NEW_COMPUTE_PROGRAM;
   }

   if (brw->meta_in_progress != _mesa_meta_in_progress(ctx)) {
      brw->meta_in_progress = _mesa_meta_in_progress(ctx);
      brw->ctx.NewDriverState |= BRW_NEW_META_IN_PROGRESS;
   }

   if (brw->num_samples != fb_samples) {
      brw->num_samples = fb_samples;
      brw->ctx.NewDriverState |= BRW_NEW_NUM_SAMPLES;
   }

   /* Exit early if no state is flagged as dirty */
   merge_ctx_state(brw, &state);
   if ((state.mesa | state.brw) == 0)
      return;

   /* Emit Sandybridge workaround flushes on every primitive, for safety. */
   if (brw->gen == 6)
      brw_emit_post_sync_nonzero_flush(brw);

   brw_upload_programs(brw, pipeline);
   merge_ctx_state(brw, &state);

   const struct brw_tracked_state *atoms =
      brw_get_pipeline_atoms(brw, pipeline);
   const int num_atoms = brw->num_atoms[pipeline];

   if (unlikely(INTEL_DEBUG)) {
      /* Debug version which enforces various sanity checks on the
       * state flags which are generated and checked to help ensure
       * state atoms are ordered correctly in the list.
       */
      struct brw_state_flags examined, prev;
      memset(&examined, 0, sizeof(examined));
      prev = state;

      for (i = 0; i < num_atoms; i++) {
	 const struct brw_tracked_state *atom = &atoms[i];
	 struct brw_state_flags generated;

         check_and_emit_atom(brw, &state, atom);

	 accumulate_state(&examined, &atom->dirty);

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, &state);
	 assert(!check_state(&examined, &generated));
	 prev = state;
      }
   }
   else {
      for (i = 0; i < num_atoms; i++) {
	 const struct brw_tracked_state *atom = &atoms[i];

         check_and_emit_atom(brw, &state, atom);
      }
   }

   if (unlikely(INTEL_DEBUG & DEBUG_STATE)) {
      STATIC_ASSERT(ARRAY_SIZE(brw_bits) == BRW_NUM_STATE_BITS + 1);

      brw_update_dirty_count(mesa_bits, state.mesa);
      brw_update_dirty_count(brw_bits, state.brw);
      if (dirty_count++ % 1000 == 0) {
	 brw_print_dirty_count(mesa_bits);
	 brw_print_dirty_count(brw_bits);
	 fprintf(stderr, "\n");
      }
   }
}
/***********************************************************************
 * Emit all state:
 */
void brw_upload_state(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->intel.ctx;
   struct intel_context *intel = &brw->intel;
   struct brw_state_flags *state = &brw->state.dirty;
   int i;
   static int dirty_count = 0;

   state->mesa |= brw->intel.NewGLState;
   brw->intel.NewGLState = 0;

   if (brw->emit_state_always) {
      state->mesa |= ~0;
      state->brw |= ~0;
      state->cache |= ~0;
   }

   if (brw->fragment_program != ctx->FragmentProgram._Current) {
      brw->fragment_program = ctx->FragmentProgram._Current;
      brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
   }

   if (brw->vertex_program != ctx->VertexProgram._Current) {
      brw->vertex_program = ctx->VertexProgram._Current;
      brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
   }

   if ((state->mesa | state->cache | state->brw) == 0)
      return;

   intel_check_front_buffer_rendering(intel);

   if (unlikely(INTEL_DEBUG)) {
      /* Debug version which enforces various sanity checks on the
       * state flags which are generated and checked to help ensure
       * state atoms are ordered correctly in the list.
       */
      struct brw_state_flags examined, prev;      
      memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < brw->num_atoms; i++) {
	 const struct brw_tracked_state *atom = brw->atoms[i];
	 struct brw_state_flags generated;

	 if (check_state(state, &atom->dirty)) {
	    atom->emit(brw);
	 }

	 accumulate_state(&examined, &atom->dirty);

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
   }
   else {
      for (i = 0; i < brw->num_atoms; i++) {
	 const struct brw_tracked_state *atom = brw->atoms[i];

	 if (check_state(state, &atom->dirty)) {
	    atom->emit(brw);
	 }
      }
   }

   if (unlikely(INTEL_DEBUG & DEBUG_STATE)) {
      brw_update_dirty_count(mesa_bits, state->mesa);
      brw_update_dirty_count(brw_bits, state->brw);
      brw_update_dirty_count(cache_bits, state->cache);
      if (dirty_count++ % 1000 == 0) {
	 brw_print_dirty_count(mesa_bits, state->mesa);
	 brw_print_dirty_count(brw_bits, state->brw);
	 brw_print_dirty_count(cache_bits, state->cache);
	 fprintf(stderr, "\n");
      }
   }

   memset(state, 0, sizeof(*state));
}
/***********************************************************************
 * Emit all state:
 */
void brw_upload_state(struct brw_context *brw)
{
   struct gl_context *ctx = &brw->ctx;
   struct brw_state_flags *state = &brw->state.dirty;
   int i;
   static int dirty_count = 0;

   state->mesa |= brw->NewGLState;
   brw->NewGLState = 0;

   state->brw |= ctx->NewDriverState;
   ctx->NewDriverState = 0;

   if (0) {
      /* Always re-emit all state. */
      state->mesa |= ~0;
      state->brw |= ~0ull;
   }

   if (brw->fragment_program != ctx->FragmentProgram._Current) {
      brw->fragment_program = ctx->FragmentProgram._Current;
      brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
   }

   if (brw->geometry_program != ctx->GeometryProgram._Current) {
      brw->geometry_program = ctx->GeometryProgram._Current;
      brw->state.dirty.brw |= BRW_NEW_GEOMETRY_PROGRAM;
   }

   if (brw->vertex_program != ctx->VertexProgram._Current) {
      brw->vertex_program = ctx->VertexProgram._Current;
      brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
   }

   if (brw->meta_in_progress != _mesa_meta_in_progress(ctx)) {
      brw->meta_in_progress = _mesa_meta_in_progress(ctx);
      brw->state.dirty.brw |= BRW_NEW_META_IN_PROGRESS;
   }

   if (brw->num_samples != ctx->DrawBuffer->Visual.samples) {
      brw->num_samples = ctx->DrawBuffer->Visual.samples;
      brw->state.dirty.brw |= BRW_NEW_NUM_SAMPLES;
   }

   if ((state->mesa | state->brw) == 0)
      return;

   if (unlikely(INTEL_DEBUG)) {
      /* Debug version which enforces various sanity checks on the
       * state flags which are generated and checked to help ensure
       * state atoms are ordered correctly in the list.
       */
      struct brw_state_flags examined, prev;
      memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < brw->num_atoms; i++) {
	 const struct brw_tracked_state *atom = brw->atoms[i];
	 struct brw_state_flags generated;

	 if (check_state(state, &atom->dirty)) {
	    atom->emit(brw);
	 }

	 accumulate_state(&examined, &atom->dirty);

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
   }
   else {
      for (i = 0; i < brw->num_atoms; i++) {
	 const struct brw_tracked_state *atom = brw->atoms[i];

	 if (check_state(state, &atom->dirty)) {
	    atom->emit(brw);
	 }
      }
   }

   if (unlikely(INTEL_DEBUG & DEBUG_STATE)) {
      STATIC_ASSERT(ARRAY_SIZE(brw_bits) == BRW_NUM_STATE_BITS + 1);

      brw_update_dirty_count(mesa_bits, state->mesa);
      brw_update_dirty_count(brw_bits, state->brw);
      if (dirty_count++ % 1000 == 0) {
	 brw_print_dirty_count(mesa_bits);
	 brw_print_dirty_count(brw_bits);
	 fprintf(stderr, "\n");
      }
   }
}