void st_validate_state( struct st_context *st )
{
   struct st_state_flags *state = &st->dirty;
   GLuint i;

   /* Get Mesa driver state. */
   st->dirty.st |= st->ctx->NewDriverState;
   st->ctx->NewDriverState = 0;

   check_attrib_edgeflag(st);

   /* The bitmap cache is immune to pixel unpack changes.
    * Note that GLUT makes several calls to glPixelStore for each
    * bitmap char it draws so this is an important check.
    */
   if (state->mesa & ~_NEW_PACKUNPACK)
      st_flush_bitmap_cache(st);

   check_program_state( st );

   st_manager_validate_framebuffers(st);

   if (state->st == 0)
      return;

   /*printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/

#ifdef DEBUG
   if (1) {
#else
   if (0) {
#endif
      /* 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 st_state_flags examined, prev;      
      memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < Elements(atoms); i++) {	 
	 const struct st_tracked_state *atom = atoms[i];
	 struct st_state_flags generated;
	 
	 /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/

	 if (!(atom->dirty.mesa || atom->dirty.st) ||
	     !atom->update) {
	    printf("malformed atom %s\n", atom->name);
	    assert(0);
	 }

	 if (check_state(state, &atom->dirty)) {
	    atoms[i]->update( st );
	    /*printf("after: %x\n", atom->dirty.mesa);*/
	 }

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

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
      /*printf("\n");*/

   }
   else {
      for (i = 0; i < Elements(atoms); i++) {	 
	 if (check_state(state, &atoms[i]->dirty))
	    atoms[i]->update( st );
      }
   }

   memset(state, 0, sizeof(*state));
}
Exemplo n.º 2
0
void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
{
   struct gl_context *ctx = st->ctx;
   uint64_t dirty, pipeline_mask;
   uint32_t dirty_lo, dirty_hi;

   /* Get Mesa driver state.
    *
    * Inactive states are shader states not used by shaders at the moment.
    */
   st->dirty |= ctx->NewDriverState & st->active_states & ST_ALL_STATES_MASK;
   ctx->NewDriverState = 0;

   /* Get pipeline state. */
   switch (pipeline) {
   case ST_PIPELINE_RENDER:
      if (st->ctx->API == API_OPENGL_COMPAT)
         check_attrib_edgeflag(st);

      check_program_state(st);
      st_manager_validate_framebuffers(st);

      pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
      break;

   case ST_PIPELINE_COMPUTE: {
      struct st_compute_program *old_cp = st->cp;
      struct gl_compute_program *new_cp = ctx->ComputeProgram._Current;

      if (new_cp != &old_cp->Base) {
         if (old_cp)
            st->dirty |= old_cp->affected_states;
         assert(new_cp);
         st->dirty |= st_compute_program(new_cp)->affected_states;
      }

      st->compute_shader_may_be_dirty = false;
      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK;
      break;
   }

   default:
      unreachable("Invalid pipeline specified");
   }

   dirty = st->dirty & pipeline_mask;
   if (!dirty)
      return;

   dirty_lo = dirty;
   dirty_hi = dirty >> 32;

   /* Update states.
    *
    * Don't use u_bit_scan64, it may be slower on 32-bit.
    */
   while (dirty_lo)
      atoms[u_bit_scan(&dirty_lo)]->update(st);
   while (dirty_hi)
      atoms[32 + u_bit_scan(&dirty_hi)]->update(st);

   /* Clear the render or compute state bits. */
   st->dirty &= ~pipeline_mask;
}
Exemplo n.º 3
0
void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
{
   const struct st_tracked_state **atoms;
   struct st_state_flags *state;
   GLuint num_atoms;
   GLuint i;

   /* Get pipeline state. */
   switch (pipeline) {
    case ST_PIPELINE_RENDER:
      atoms     = render_atoms;
      num_atoms = ARRAY_SIZE(render_atoms);
      state     = &st->dirty;
      break;
   case ST_PIPELINE_COMPUTE:
      atoms     = compute_atoms;
      num_atoms = ARRAY_SIZE(compute_atoms);
      state     = &st->dirty_cp;
      break;
   default:
      unreachable("Invalid pipeline specified");
   }

   /* Get Mesa driver state. */
   st->dirty.st |= st->ctx->NewDriverState;
   st->dirty_cp.st |= st->ctx->NewDriverState;
   st->ctx->NewDriverState = 0;

   if (pipeline == ST_PIPELINE_RENDER) {
      check_attrib_edgeflag(st);

      check_program_state(st);

      st_manager_validate_framebuffers(st);
   }

   if (state->st == 0 && state->mesa == 0)
      return;

   /*printf("%s %x/%x\n", __func__, state->mesa, state->st);*/

#ifdef DEBUG
   if (1) {
#else
   if (0) {
#endif
      /* 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 st_state_flags examined, prev;      
      memset(&examined, 0, sizeof(examined));
      prev = *state;

      for (i = 0; i < num_atoms; i++) {
	 const struct st_tracked_state *atom = atoms[i];
	 struct st_state_flags generated;
	 
	 /*printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/

	 if (!(atom->dirty.mesa || atom->dirty.st) ||
	     !atom->update) {
	    printf("malformed atom %s\n", atom->name);
	    assert(0);
	 }

	 if (check_state(state, &atom->dirty)) {
	    atoms[i]->update( st );
	    /*printf("after: %x\n", atom->dirty.mesa);*/
	 }

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

	 /* generated = (prev ^ state)
	  * if (examined & generated)
	  *     fail;
	  */
	 xor_states(&generated, &prev, state);
	 assert(!check_state(&examined, &generated));
	 prev = *state;
      }
      /*printf("\n");*/

   }
   else {
      for (i = 0; i < num_atoms; i++) {
	 if (check_state(state, &atoms[i]->dirty))
	    atoms[i]->update( st );
      }
   }

   memset(state, 0, sizeof(*state));
}
Exemplo n.º 4
0
void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
{
   struct gl_context *ctx = st->ctx;
   uint64_t dirty, pipeline_mask;
   uint32_t dirty_lo, dirty_hi;

   /* Get Mesa driver state.
    *
    * Inactive states are shader states not used by shaders at the moment.
    */
   st->dirty |= ctx->NewDriverState & st->active_states & ST_ALL_STATES_MASK;
   ctx->NewDriverState = 0;

   /* Get pipeline state. */
   switch (pipeline) {
   case ST_PIPELINE_RENDER:
      if (st->ctx->API == API_OPENGL_COMPAT)
         check_attrib_edgeflag(st);

      if (st->gfx_shaders_may_be_dirty) {
         check_program_state(st);
         st->gfx_shaders_may_be_dirty = false;
      }

      st_manager_validate_framebuffers(st);

      pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK;
      break;

   case ST_PIPELINE_CLEAR:
      st_manager_validate_framebuffers(st);
      pipeline_mask = ST_PIPELINE_CLEAR_STATE_MASK;
      break;

   case ST_PIPELINE_META:
      if (st->gfx_shaders_may_be_dirty) {
         check_program_state(st);
         st->gfx_shaders_may_be_dirty = false;
      }

      st_manager_validate_framebuffers(st);
      pipeline_mask = ST_PIPELINE_META_STATE_MASK;
      break;

   case ST_PIPELINE_UPDATE_FRAMEBUFFER:
      st_manager_validate_framebuffers(st);
      pipeline_mask = ST_PIPELINE_UPDATE_FB_STATE_MASK;
      break;

   case ST_PIPELINE_COMPUTE: {
      struct st_compute_program *old_cp = st->cp;
      struct gl_program *new_cp = ctx->ComputeProgram._Current;

      if (new_cp != &old_cp->Base) {
         if (old_cp)
            st->dirty |= old_cp->affected_states;
         assert(new_cp);
         st->dirty |= st_compute_program(new_cp)->affected_states;
      }

      st->compute_shader_may_be_dirty = false;

      /*
       * We add the ST_NEW_FB_STATE bit here as well, because glBindFramebuffer
       * acts as a barrier that breaks feedback loops between the framebuffer
       * and textures bound to the framebuffer, even when those textures are
       * accessed by compute shaders; so we must inform the driver of new
       * framebuffer state.
       */
      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK | ST_NEW_FB_STATE;
      break;
   }

   default:
      unreachable("Invalid pipeline specified");
   }

   dirty = st->dirty & pipeline_mask;
   if (!dirty)
      return;

   dirty_lo = dirty;
   dirty_hi = dirty >> 32;

   /* Update states.
    *
    * Don't use u_bit_scan64, it may be slower on 32-bit.
    */
   while (dirty_lo)
      update_functions[u_bit_scan(&dirty_lo)](st);
   while (dirty_hi)
      update_functions[32 + u_bit_scan(&dirty_hi)](st);

   /* Clear the render or compute state bits. */
   st->dirty &= ~pipeline_mask;
}