[Mesa-dev] [PATCH 3/9] st/mesa: completely rewrite state atoms

Rob Clark robdclark at gmail.com
Tue Jul 19 13:58:33 UTC 2016


()

On Mon, Jul 18, 2016 at 9:11 AM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> The goal is to do this in st_validate_state:
>    while (dirty)
>       atoms[u_bit_scan(&dirty)]->update(st);
>
> That implies that atoms can't specify which flags they consume.
> There is exactly one ST_NEW_* flag for each atom. (58 flags in total)
>
> There are macros that combine multiple flags into one for easier use.
>
> All _NEW_* flags are translated into ST_NEW_* flags in st_invalidate_state.
> st/mesa doesn't keep the _NEW_* flags after that.
>
> torcs is 2% faster between the previous patch and the end of this series.
> ---
>  src/mesa/state_tracker/st_atom.c               | 153 +++++-------------
>  src/mesa/state_tracker/st_atom.h               | 210 +++++++++++++++++--------
>  src/mesa/state_tracker/st_atom_array.c         |   4 -
>  src/mesa/state_tracker/st_atom_atomicbuf.c     |  24 ---
>  src/mesa/state_tracker/st_atom_blend.c         |   4 -
>  src/mesa/state_tracker/st_atom_clip.c          |   4 -
>  src/mesa/state_tracker/st_atom_constbuf.c      |  48 ------
>  src/mesa/state_tracker/st_atom_depth.c         |   4 -
>  src/mesa/state_tracker/st_atom_framebuffer.c   |   4 -
>  src/mesa/state_tracker/st_atom_image.c         |  24 ---
>  src/mesa/state_tracker/st_atom_list.h          |  75 +++++++++
>  src/mesa/state_tracker/st_atom_msaa.c          |   8 -
>  src/mesa/state_tracker/st_atom_pixeltransfer.c |   4 -
>  src/mesa/state_tracker/st_atom_rasterizer.c    |  16 --
>  src/mesa/state_tracker/st_atom_sampler.c       |   4 -
>  src/mesa/state_tracker/st_atom_scissor.c       |   8 -
>  src/mesa/state_tracker/st_atom_shader.c        |  24 ---
>  src/mesa/state_tracker/st_atom_stipple.c       |   5 -
>  src/mesa/state_tracker/st_atom_storagebuf.c    |  24 ---
>  src/mesa/state_tracker/st_atom_tess.c          |   4 -
>  src/mesa/state_tracker/st_atom_texture.c       |  24 ---
>  src/mesa/state_tracker/st_atom_viewport.c      |   4 -
>  src/mesa/state_tracker/st_cb_bitmap.c          |  10 +-
>  src/mesa/state_tracker/st_cb_bufferobjects.c   |  10 +-
>  src/mesa/state_tracker/st_cb_compute.c         |   2 +-
>  src/mesa/state_tracker/st_cb_feedback.c        |   2 +-
>  src/mesa/state_tracker/st_cb_program.c         |  38 ++---
>  src/mesa/state_tracker/st_cb_texture.c         |   2 +-
>  src/mesa/state_tracker/st_context.c            | 100 ++++++++++--
>  src/mesa/state_tracker/st_context.h            |  42 +----
>  src/mesa/state_tracker/st_draw.c               |   4 +-
>  src/mesa/state_tracker/st_manager.c            |   4 +-
>  32 files changed, 377 insertions(+), 516 deletions(-)
>  create mode 100644 src/mesa/state_tracker/st_atom_list.h
>
> diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
> index 9d5cc0f..5843d2a 100644
> --- a/src/mesa/state_tracker/st_atom.c
> +++ b/src/mesa/state_tracker/st_atom.c
> @@ -37,87 +37,18 @@
>  #include "st_manager.h"
>
>
> -/**
> - * This is used to initialize st->render_atoms[].
> - */
> -static const struct st_tracked_state *render_atoms[] =
> -{
> -   &st_update_depth_stencil_alpha,
> -   &st_update_clip,
> -
> -   &st_update_fp,
> -   &st_update_gp,
> -   &st_update_tep,
> -   &st_update_tcp,
> -   &st_update_vp,
> -
> -   &st_update_rasterizer,
> -   &st_update_polygon_stipple,
> -   &st_update_viewport,
> -   &st_update_scissor,
> -   &st_update_window_rectangles,
> -   &st_update_blend,
> -   &st_update_vertex_texture,
> -   &st_update_fragment_texture,
> -   &st_update_geometry_texture,
> -   &st_update_tessctrl_texture,
> -   &st_update_tesseval_texture,
> -   &st_update_sampler, /* depends on update_*_texture for swizzle */
> -   &st_bind_vs_images,
> -   &st_bind_tcs_images,
> -   &st_bind_tes_images,
> -   &st_bind_gs_images,
> -   &st_bind_fs_images,
> -   &st_update_framebuffer, /* depends on update_*_texture and bind_*_images */
> -   &st_update_msaa,
> -   &st_update_sample_shading,
> -   &st_update_vs_constants,
> -   &st_update_tcs_constants,
> -   &st_update_tes_constants,
> -   &st_update_gs_constants,
> -   &st_update_fs_constants,
> -   &st_bind_vs_ubos,
> -   &st_bind_tcs_ubos,
> -   &st_bind_tes_ubos,
> -   &st_bind_fs_ubos,
> -   &st_bind_gs_ubos,
> -   &st_bind_vs_atomics,
> -   &st_bind_tcs_atomics,
> -   &st_bind_tes_atomics,
> -   &st_bind_fs_atomics,
> -   &st_bind_gs_atomics,
> -   &st_bind_vs_ssbos,
> -   &st_bind_tcs_ssbos,
> -   &st_bind_tes_ssbos,
> -   &st_bind_fs_ssbos,
> -   &st_bind_gs_ssbos,
> -   &st_update_pixel_transfer,
> -   &st_update_tess,
> -
> -   /* this must be done after the vertex program update */
> -   &st_update_array
> -};
> -
> -
> -/**
> - * This is used to initialize st->compute_atoms[].
> - */
> -static const struct st_tracked_state *compute_atoms[] =
> +/* The list state update functions. */
> +static const struct st_tracked_state *atoms[] =
>  {
> -   &st_update_cp,
> -   &st_update_compute_texture,
> -   &st_update_sampler, /* depends on update_compute_texture for swizzle */
> -   &st_update_cs_constants,
> -   &st_bind_cs_ubos,
> -   &st_bind_cs_atomics,
> -   &st_bind_cs_ssbos,
> -   &st_bind_cs_images,
> +#define ST_STATE(FLAG, st_update) &st_update,
> +#include "st_atom_list.h"
> +#undef ST_STATE
>  };
>
>
>  void st_init_atoms( struct st_context *st )
>  {
> -   /* no-op */
> +   STATIC_ASSERT(ARRAY_SIZE(atoms) <= 64);
>  }
>
>
> @@ -127,13 +58,6 @@ void st_destroy_atoms( struct st_context *st )
>  }
>
>
> -
> -static bool
> -check_state(const struct st_state_flags *a, const struct st_state_flags *b)
> -{
> -   return (a->mesa & b->mesa) || (a->st & b->st);
> -}
> -
>  /* Too complex to figure out, just check every time:
>   */
>  static void check_program_state( struct st_context *st )
> @@ -141,13 +65,13 @@ static void check_program_state( struct st_context *st )
>     struct gl_context *ctx = st->ctx;
>
>     if (ctx->VertexProgram._Current != &st->vp->Base)
> -      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> +      st->dirty |= ST_NEW_VERTEX_PROGRAM;
>
>     if (ctx->FragmentProgram._Current != &st->fp->Base)
> -      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
> +      st->dirty |= ST_NEW_FRAGMENT_PROGRAM;
>
>     if (ctx->GeometryProgram._Current != &st->gp->Base)
> -      st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
> +      st->dirty |= ST_NEW_GEOMETRY_PROGRAM;
>  }
>
>  static void check_attrib_edgeflag(struct st_context *st)
> @@ -165,14 +89,14 @@ static void check_attrib_edgeflag(struct st_context *st)
>                          arrays[VERT_ATTRIB_EDGEFLAG]->StrideB != 0;
>     if (vertdata_edgeflags != st->vertdata_edgeflags) {
>        st->vertdata_edgeflags = vertdata_edgeflags;
> -      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> +      st->dirty |= ST_NEW_VERTEX_PROGRAM;
>     }
>
>     edgeflag_culls_prims = edgeflags_enabled && !vertdata_edgeflags &&
>                            !st->ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0];
>     if (edgeflag_culls_prims != st->edgeflag_culls_prims) {
>        st->edgeflag_culls_prims = edgeflag_culls_prims;
> -      st->dirty.st |= ST_NEW_RASTERIZER;
> +      st->dirty |= ST_NEW_RASTERIZER;
>     }
>  }
>
> @@ -183,49 +107,42 @@ static void check_attrib_edgeflag(struct st_context *st)
>
>  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;
> +   uint64_t dirty, pipeline_mask;
> +   uint32_t dirty_lo, dirty_hi;
> +
> +   /* Get Mesa driver state. */
> +   st->dirty |= st->ctx->NewDriverState & ST_ALL_STATES_MASK;
> +   st->ctx->NewDriverState = 0;
>
>     /* Get pipeline state. */
>     switch (pipeline) {
> -    case ST_PIPELINE_RENDER:
> -      atoms     = render_atoms;
> -      num_atoms = ARRAY_SIZE(render_atoms);
> -      state     = &st->dirty;
> +   case ST_PIPELINE_RENDER:
> +      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:
> -      atoms     = compute_atoms;
> -      num_atoms = ARRAY_SIZE(compute_atoms);
> -      state     = &st->dirty_cp;
> +      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK;
>        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)
> +   dirty = st->dirty & pipeline_mask;
> +   if (!dirty)
>        return;
>
> -   /*printf("%s %x/%x\n", __func__, state->mesa, state->st);*/
> +   dirty_lo = dirty;
> +   dirty_hi = dirty >> 32;
>
> -   for (i = 0; i < num_atoms; i++) {
> -      if (check_state(state, &atoms[i]->dirty))
> -         atoms[i]->update( st );
> -   }
> +   /* Update states. */
> +   while (dirty_lo)
> +      atoms[u_bit_scan(&dirty_lo)]->update(st);
> +   while (dirty_hi)
> +      atoms[32 + u_bit_scan(&dirty_hi)]->update(st);
>

drive-by comment, but why not u_bit_scan64()?

BR,
-R

> -   memset(state, 0, sizeof(*state));
> +   /* Clear the render or compute state bits. */
> +   st->dirty &= ~pipeline_mask;
>  }
> diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
> index d5fb941..871afc6 100644
> --- a/src/mesa/state_tracker/st_atom.h
> +++ b/src/mesa/state_tracker/st_atom.h
> @@ -36,82 +36,160 @@
>
>  #include "main/glheader.h"
>
> -#include "state_tracker/st_api.h"
> -#include "state_tracker/st_context.h"
> -
>  struct st_context;
> -struct st_tracked_state;
> +
> +/**
> + * Enumeration of state tracker pipelines.
> + */
> +enum st_pipeline {
> +   ST_PIPELINE_RENDER,
> +   ST_PIPELINE_COMPUTE,
> +};
> +
> +struct st_tracked_state {
> +   void (*update)( struct st_context *st );
> +};
> +
>
>  void st_init_atoms( struct st_context *st );
>  void st_destroy_atoms( struct st_context *st );
> +void st_validate_state( struct st_context *st, enum st_pipeline pipeline );
> +GLuint st_compare_func_to_pipe(GLenum func);
>
> +enum pipe_format
> +st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
> +                      GLboolean normalized, GLboolean integer);
>
> -void st_validate_state( struct st_context *st, enum st_pipeline pipeline );
>
> +/* Define ST_NEW_xxx_INDEX */
> +enum {
> +#define ST_STATE(FLAG, st_update) FLAG##_INDEX,
> +#include "st_atom_list.h"
> +#undef ST_STATE
> +};
>
> -extern const struct st_tracked_state st_update_array;
> -extern const struct st_tracked_state st_update_framebuffer;
> -extern const struct st_tracked_state st_update_clip;
> -extern const struct st_tracked_state st_update_depth_stencil_alpha;
> -extern const struct st_tracked_state st_update_fp;
> -extern const struct st_tracked_state st_update_gp;
> -extern const struct st_tracked_state st_update_tep;
> -extern const struct st_tracked_state st_update_tcp;
> -extern const struct st_tracked_state st_update_vp;
> -extern const struct st_tracked_state st_update_cp;
> -extern const struct st_tracked_state st_update_rasterizer;
> -extern const struct st_tracked_state st_update_polygon_stipple;
> -extern const struct st_tracked_state st_update_viewport;
> -extern const struct st_tracked_state st_update_scissor;
> -extern const struct st_tracked_state st_update_window_rectangles;
> -extern const struct st_tracked_state st_update_blend;
> -extern const struct st_tracked_state st_update_msaa;
> -extern const struct st_tracked_state st_update_sample_shading;
> -extern const struct st_tracked_state st_update_sampler;
> -extern const struct st_tracked_state st_update_fragment_texture;
> -extern const struct st_tracked_state st_update_vertex_texture;
> -extern const struct st_tracked_state st_update_geometry_texture;
> -extern const struct st_tracked_state st_update_tessctrl_texture;
> -extern const struct st_tracked_state st_update_tesseval_texture;
> -extern const struct st_tracked_state st_update_compute_texture;
> -extern const struct st_tracked_state st_update_fs_constants;
> -extern const struct st_tracked_state st_update_gs_constants;
> -extern const struct st_tracked_state st_update_tes_constants;
> -extern const struct st_tracked_state st_update_tcs_constants;
> -extern const struct st_tracked_state st_update_vs_constants;
> -extern const struct st_tracked_state st_update_cs_constants;
> -extern const struct st_tracked_state st_bind_fs_ubos;
> -extern const struct st_tracked_state st_bind_vs_ubos;
> -extern const struct st_tracked_state st_bind_gs_ubos;
> -extern const struct st_tracked_state st_bind_tcs_ubos;
> -extern const struct st_tracked_state st_bind_tes_ubos;
> -extern const struct st_tracked_state st_bind_cs_ubos;
> -extern const struct st_tracked_state st_bind_fs_atomics;
> -extern const struct st_tracked_state st_bind_vs_atomics;
> -extern const struct st_tracked_state st_bind_gs_atomics;
> -extern const struct st_tracked_state st_bind_tcs_atomics;
> -extern const struct st_tracked_state st_bind_tes_atomics;
> -extern const struct st_tracked_state st_bind_cs_atomics;
> -extern const struct st_tracked_state st_bind_fs_ssbos;
> -extern const struct st_tracked_state st_bind_vs_ssbos;
> -extern const struct st_tracked_state st_bind_gs_ssbos;
> -extern const struct st_tracked_state st_bind_tcs_ssbos;
> -extern const struct st_tracked_state st_bind_tes_ssbos;
> -extern const struct st_tracked_state st_bind_cs_ssbos;
> -extern const struct st_tracked_state st_bind_fs_images;
> -extern const struct st_tracked_state st_bind_vs_images;
> -extern const struct st_tracked_state st_bind_gs_images;
> -extern const struct st_tracked_state st_bind_tcs_images;
> -extern const struct st_tracked_state st_bind_tes_images;
> -extern const struct st_tracked_state st_bind_cs_images;
> -extern const struct st_tracked_state st_update_pixel_transfer;
> -extern const struct st_tracked_state st_update_tess;
> +/* Define ST_NEW_xxx */
> +enum {
> +#define ST_STATE(FLAG, st_update) FLAG = 1llu << FLAG##_INDEX,
> +#include "st_atom_list.h"
> +#undef ST_STATE
> +};
>
> +/* Add extern struct declarations. */
> +#define ST_STATE(FLAG, st_update) extern const struct st_tracked_state st_update;
> +#include "st_atom_list.h"
> +#undef ST_STATE
>
> -GLuint st_compare_func_to_pipe(GLenum func);
> +/* Combined state flags. */
> +#define ST_NEW_SAMPLERS         (ST_NEW_RENDER_SAMPLERS | \
> +                                 ST_NEW_CS_SAMPLERS)
>
> -enum pipe_format
> -st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
> -                      GLboolean normalized, GLboolean integer);
> +#define ST_NEW_FRAMEBUFFER      (ST_NEW_FB_STATE | \
> +                                 ST_NEW_SAMPLE_MASK | \
> +                                 ST_NEW_SAMPLE_SHADING)
> +
> +#define ST_NEW_VERTEX_PROGRAM   (ST_NEW_VS_STATE | \
> +                                 ST_NEW_VS_SAMPLER_VIEWS | \
> +                                 ST_NEW_VS_IMAGES | \
> +                                 ST_NEW_VS_CONSTANTS | \
> +                                 ST_NEW_VS_UBOS | \
> +                                 ST_NEW_VS_ATOMICS | \
> +                                 ST_NEW_VS_SSBOS | \
> +                                 ST_NEW_VERTEX_ARRAYS | \
> +                                 ST_NEW_CLIP_STATE | \
> +                                 ST_NEW_RASTERIZER)
> +
> +#define ST_NEW_TESSCTRL_PROGRAM (ST_NEW_TCS_STATE | \
> +                                 ST_NEW_TCS_SAMPLER_VIEWS | \
> +                                 ST_NEW_TCS_IMAGES | \
> +                                 ST_NEW_TCS_CONSTANTS | \
> +                                 ST_NEW_TCS_UBOS | \
> +                                 ST_NEW_TCS_ATOMICS | \
> +                                 ST_NEW_TCS_SSBOS)
> +
> +#define ST_NEW_TESSEVAL_PROGRAM (ST_NEW_TES_STATE | \
> +                                 ST_NEW_TES_SAMPLER_VIEWS | \
> +                                 ST_NEW_TES_IMAGES | \
> +                                 ST_NEW_TES_CONSTANTS | \
> +                                 ST_NEW_TES_UBOS | \
> +                                 ST_NEW_TES_ATOMICS | \
> +                                 ST_NEW_TES_SSBOS | \
> +                                 ST_NEW_RASTERIZER)
> +
> +#define ST_NEW_GEOMETRY_PROGRAM (ST_NEW_GS_STATE | \
> +                                 ST_NEW_GS_SAMPLER_VIEWS | \
> +                                 ST_NEW_GS_IMAGES | \
> +                                 ST_NEW_GS_CONSTANTS | \
> +                                 ST_NEW_GS_UBOS | \
> +                                 ST_NEW_GS_ATOMICS | \
> +                                 ST_NEW_GS_SSBOS | \
> +                                 ST_NEW_RASTERIZER)
> +
> +#define ST_NEW_FRAGMENT_PROGRAM (ST_NEW_FS_STATE | \
> +                                 ST_NEW_FS_SAMPLER_VIEWS | \
> +                                 ST_NEW_FS_IMAGES | \
> +                                 ST_NEW_FS_CONSTANTS | \
> +                                 ST_NEW_FS_UBOS | \
> +                                 ST_NEW_FS_ATOMICS | \
> +                                 ST_NEW_FS_SSBOS | \
> +                                 ST_NEW_SAMPLE_SHADING)
> +
> +#define ST_NEW_COMPUTE_PROGRAM  (ST_NEW_CS_STATE | \
> +                                 ST_NEW_CS_SAMPLER_VIEWS | \
> +                                 ST_NEW_CS_IMAGES | \
> +                                 ST_NEW_CS_CONSTANTS | \
> +                                 ST_NEW_CS_UBOS | \
> +                                 ST_NEW_CS_ATOMICS | \
> +                                 ST_NEW_CS_SSBOS)
> +
> +#define ST_NEW_CONSTANTS        (ST_NEW_VS_CONSTANTS | \
> +                                 ST_NEW_TCS_CONSTANTS | \
> +                                 ST_NEW_TES_CONSTANTS | \
> +                                 ST_NEW_FS_CONSTANTS | \
> +                                 ST_NEW_GS_CONSTANTS | \
> +                                 ST_NEW_CS_CONSTANTS)
> +
> +#define ST_NEW_UNIFORM_BUFFER   (ST_NEW_VS_UBOS | \
> +                                 ST_NEW_TCS_UBOS | \
> +                                 ST_NEW_TES_UBOS | \
> +                                 ST_NEW_FS_UBOS | \
> +                                 ST_NEW_GS_UBOS | \
> +                                 ST_NEW_CS_UBOS)
> +
> +#define ST_NEW_SAMPLER_VIEWS    (ST_NEW_VS_SAMPLER_VIEWS | \
> +                                 ST_NEW_FS_SAMPLER_VIEWS | \
> +                                 ST_NEW_GS_SAMPLER_VIEWS | \
> +                                 ST_NEW_TCS_SAMPLER_VIEWS | \
> +                                 ST_NEW_TES_SAMPLER_VIEWS | \
> +                                 ST_NEW_CS_SAMPLER_VIEWS)
> +
> +#define ST_NEW_ATOMIC_BUFFER    (ST_NEW_VS_ATOMICS | \
> +                                 ST_NEW_TCS_ATOMICS | \
> +                                 ST_NEW_TES_ATOMICS | \
> +                                 ST_NEW_FS_ATOMICS | \
> +                                 ST_NEW_GS_ATOMICS | \
> +                                 ST_NEW_CS_ATOMICS)
> +
> +#define ST_NEW_STORAGE_BUFFER   (ST_NEW_VS_SSBOS | \
> +                                 ST_NEW_TCS_SSBOS | \
> +                                 ST_NEW_TES_SSBOS | \
> +                                 ST_NEW_FS_SSBOS | \
> +                                 ST_NEW_GS_SSBOS | \
> +                                 ST_NEW_CS_SSBOS)
> +
> +#define ST_NEW_IMAGE_UNITS      (ST_NEW_VS_IMAGES | \
> +                                 ST_NEW_TCS_IMAGES | \
> +                                 ST_NEW_TES_IMAGES | \
> +                                 ST_NEW_GS_IMAGES | \
> +                                 ST_NEW_FS_IMAGES | \
> +                                 ST_NEW_CS_IMAGES)
> +
> +/* All state flags within each group: */
> +#define ST_PIPELINE_RENDER_STATE_MASK  (ST_NEW_CS_STATE - 1)
> +#define ST_PIPELINE_COMPUTE_STATE_MASK (ST_NEW_COMPUTE_PROGRAM | \
> +                                        ST_NEW_CS_SAMPLERS)
> +
> +#define ST_ALL_STATES_MASK (ST_PIPELINE_RENDER_STATE_MASK | \
> +                            ST_PIPELINE_COMPUTE_STATE_MASK)
>
>  #endif
> diff --git a/src/mesa/state_tracker/st_atom_array.c b/src/mesa/state_tracker/st_atom_array.c
> index 992d6a9..dcead27 100644
> --- a/src/mesa/state_tracker/st_atom_array.c
> +++ b/src/mesa/state_tracker/st_atom_array.c
> @@ -690,9 +690,5 @@ static void update_array(struct st_context *st)
>
>
>  const struct st_tracked_state st_update_array = {
> -   {                                                   /* dirty */
> -      _NEW_CURRENT_ATTRIB,                              /* mesa */
> -      ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM,     /* st */
> -   },
>     update_array                                                /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_atomicbuf.c b/src/mesa/state_tracker/st_atom_atomicbuf.c
> index d438071..7dde76a 100644
> --- a/src/mesa/state_tracker/st_atom_atomicbuf.c
> +++ b/src/mesa/state_tracker/st_atom_atomicbuf.c
> @@ -79,10 +79,6 @@ bind_vs_atomics(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_vs_atomics = {
> -   {
> -      0,
> -      ST_NEW_VERTEX_PROGRAM | ST_NEW_ATOMIC_BUFFER,
> -   },
>     bind_vs_atomics
>  };
>
> @@ -96,10 +92,6 @@ bind_fs_atomics(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_fs_atomics = {
> -   {
> -      0,
> -      ST_NEW_FRAGMENT_PROGRAM | ST_NEW_ATOMIC_BUFFER,
> -   },
>     bind_fs_atomics
>  };
>
> @@ -113,10 +105,6 @@ bind_gs_atomics(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_gs_atomics = {
> -   {
> -      0,
> -      ST_NEW_GEOMETRY_PROGRAM | ST_NEW_ATOMIC_BUFFER,
> -   },
>     bind_gs_atomics
>  };
>
> @@ -130,10 +118,6 @@ bind_tcs_atomics(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tcs_atomics = {
> -   {
> -      0,
> -      ST_NEW_TESSCTRL_PROGRAM | ST_NEW_ATOMIC_BUFFER,
> -   },
>     bind_tcs_atomics
>  };
>
> @@ -147,10 +131,6 @@ bind_tes_atomics(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tes_atomics = {
> -   {
> -      0,
> -      ST_NEW_TESSEVAL_PROGRAM | ST_NEW_ATOMIC_BUFFER,
> -   },
>     bind_tes_atomics
>  };
>
> @@ -164,9 +144,5 @@ bind_cs_atomics(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_cs_atomics = {
> -   {
> -      0,
> -      ST_NEW_COMPUTE_PROGRAM | ST_NEW_ATOMIC_BUFFER,
> -   },
>     bind_cs_atomics
>  };
> diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
> index 8adda10..65de67b 100644
> --- a/src/mesa/state_tracker/st_atom_blend.c
> +++ b/src/mesa/state_tracker/st_atom_blend.c
> @@ -283,9 +283,5 @@ update_blend( struct st_context *st )
>
>
>  const struct st_tracked_state st_update_blend = {
> -   {                                                   /* dirty */
> -      (_NEW_COLOR | _NEW_MULTISAMPLE),  /* XXX _NEW_BLEND someday? */  /* mesa */
> -      0,                                               /* st */
> -   },
>     update_blend,                                       /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_clip.c b/src/mesa/state_tracker/st_atom_clip.c
> index 657aa84..9d2870f 100644
> --- a/src/mesa/state_tracker/st_atom_clip.c
> +++ b/src/mesa/state_tracker/st_atom_clip.c
> @@ -71,9 +71,5 @@ static void update_clip( struct st_context *st )
>
>
>  const struct st_tracked_state st_update_clip = {
> -   {                                                   /* dirty */
> -      _NEW_TRANSFORM | _NEW_PROJECTION,                 /* mesa */
> -      ST_NEW_VERTEX_PROGRAM,                           /* st */
> -   },
>     update_clip                                         /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
> index a9ec195..8ffb6c3 100644
> --- a/src/mesa/state_tracker/st_atom_constbuf.c
> +++ b/src/mesa/state_tracker/st_atom_constbuf.c
> @@ -145,10 +145,6 @@ static void update_vs_constants(struct st_context *st )
>
>
>  const struct st_tracked_state st_update_vs_constants = {
> -   {                                                   /* dirty */
> -      _NEW_PROGRAM_CONSTANTS,                           /* mesa */
> -      ST_NEW_VERTEX_PROGRAM,                           /* st */
> -   },
>     update_vs_constants                                 /* update */
>  };
>
> @@ -167,10 +163,6 @@ static void update_fs_constants(struct st_context *st )
>
>
>  const struct st_tracked_state st_update_fs_constants = {
> -   {                                                   /* dirty */
> -      _NEW_PROGRAM_CONSTANTS,                           /* mesa */
> -      ST_NEW_FRAGMENT_PROGRAM,                         /* st */
> -   },
>     update_fs_constants                                 /* update */
>  };
>
> @@ -188,10 +180,6 @@ static void update_gs_constants(struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_gs_constants = {
> -   {                                                   /* dirty */
> -      _NEW_PROGRAM_CONSTANTS,                           /* mesa */
> -      ST_NEW_GEOMETRY_PROGRAM,                         /* st */
> -   },
>     update_gs_constants                                 /* update */
>  };
>
> @@ -209,10 +197,6 @@ static void update_tcs_constants(struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_tcs_constants = {
> -   {                                                   /* dirty */
> -      _NEW_PROGRAM_CONSTANTS,                           /* mesa */
> -      ST_NEW_TESSCTRL_PROGRAM,                         /* st */
> -   },
>     update_tcs_constants                                        /* update */
>  };
>
> @@ -230,10 +214,6 @@ static void update_tes_constants(struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_tes_constants = {
> -   {                                                   /* dirty */
> -      _NEW_PROGRAM_CONSTANTS,                           /* mesa */
> -      ST_NEW_TESSEVAL_PROGRAM,                         /* st */
> -   },
>     update_tes_constants                                        /* update */
>  };
>
> @@ -251,10 +231,6 @@ static void update_cs_constants(struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_cs_constants = {
> -   {                                                   /* dirty */
> -      _NEW_PROGRAM_CONSTANTS,                           /* mesa */
> -      ST_NEW_COMPUTE_PROGRAM,                          /* st */
> -   },
>     update_cs_constants                                 /* update */
>  };
>
> @@ -308,10 +284,6 @@ static void bind_vs_ubos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_vs_ubos = {
> -   {
> -      0,
> -      ST_NEW_VERTEX_PROGRAM | ST_NEW_UNIFORM_BUFFER,
> -   },
>     bind_vs_ubos
>  };
>
> @@ -327,10 +299,6 @@ static void bind_fs_ubos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_fs_ubos = {
> -   {
> -      0,
> -      ST_NEW_FRAGMENT_PROGRAM | ST_NEW_UNIFORM_BUFFER,
> -   },
>     bind_fs_ubos
>  };
>
> @@ -346,10 +314,6 @@ static void bind_gs_ubos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_gs_ubos = {
> -   {
> -      0,
> -      ST_NEW_GEOMETRY_PROGRAM | ST_NEW_UNIFORM_BUFFER,
> -   },
>     bind_gs_ubos
>  };
>
> @@ -365,10 +329,6 @@ static void bind_tcs_ubos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tcs_ubos = {
> -   {
> -      0,
> -      ST_NEW_TESSCTRL_PROGRAM | ST_NEW_UNIFORM_BUFFER,
> -   },
>     bind_tcs_ubos
>  };
>
> @@ -384,10 +344,6 @@ static void bind_tes_ubos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tes_ubos = {
> -   {
> -      0,
> -      ST_NEW_TESSEVAL_PROGRAM | ST_NEW_UNIFORM_BUFFER,
> -   },
>     bind_tes_ubos
>  };
>
> @@ -404,9 +360,5 @@ static void bind_cs_ubos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_cs_ubos = {
> -   {
> -      0,
> -      ST_NEW_COMPUTE_PROGRAM | ST_NEW_UNIFORM_BUFFER,
> -   },
>     bind_cs_ubos
>  };
> diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c
> index ec8480b..267b42c 100644
> --- a/src/mesa/state_tracker/st_atom_depth.c
> +++ b/src/mesa/state_tracker/st_atom_depth.c
> @@ -161,9 +161,5 @@ update_depth_stencil_alpha(struct st_context *st)
>
>
>  const struct st_tracked_state st_update_depth_stencil_alpha = {
> -   {                                                   /* dirty */
> -      (_NEW_DEPTH|_NEW_STENCIL|_NEW_COLOR|_NEW_BUFFERS),/* mesa */
> -      0,                                               /* st */
> -   },
>     update_depth_stencil_alpha                          /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
> index 5d91704..ea41d9d 100644
> --- a/src/mesa/state_tracker/st_atom_framebuffer.c
> +++ b/src/mesa/state_tracker/st_atom_framebuffer.c
> @@ -215,10 +215,6 @@ update_framebuffer_state( struct st_context *st )
>
>
>  const struct st_tracked_state st_update_framebuffer = {
> -   {                                                   /* dirty */
> -      _NEW_BUFFERS,                                    /* mesa */
> -      ST_NEW_FRAMEBUFFER,                              /* st */
> -   },
>     update_framebuffer_state                            /* update */
>  };
>
> diff --git a/src/mesa/state_tracker/st_atom_image.c b/src/mesa/state_tracker/st_atom_image.c
> index a170de0..e80fc14 100644
> --- a/src/mesa/state_tracker/st_atom_image.c
> +++ b/src/mesa/state_tracker/st_atom_image.c
> @@ -146,10 +146,6 @@ static void bind_vs_images(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_vs_images = {
> -   {
> -      _NEW_TEXTURE,
> -      ST_NEW_VERTEX_PROGRAM | ST_NEW_IMAGE_UNITS,
> -   },
>     bind_vs_images
>  };
>
> @@ -165,10 +161,6 @@ static void bind_fs_images(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_fs_images = {
> -   {
> -      _NEW_TEXTURE,
> -      ST_NEW_FRAGMENT_PROGRAM | ST_NEW_IMAGE_UNITS,
> -   },
>     bind_fs_images
>  };
>
> @@ -184,10 +176,6 @@ static void bind_gs_images(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_gs_images = {
> -   {
> -      _NEW_TEXTURE,
> -      ST_NEW_GEOMETRY_PROGRAM | ST_NEW_IMAGE_UNITS,
> -   },
>     bind_gs_images
>  };
>
> @@ -203,10 +191,6 @@ static void bind_tcs_images(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tcs_images = {
> -   {
> -      _NEW_TEXTURE,
> -      ST_NEW_TESSCTRL_PROGRAM | ST_NEW_IMAGE_UNITS,
> -   },
>     bind_tcs_images
>  };
>
> @@ -222,10 +206,6 @@ static void bind_tes_images(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tes_images = {
> -   {
> -      _NEW_TEXTURE,
> -      ST_NEW_TESSEVAL_PROGRAM | ST_NEW_IMAGE_UNITS,
> -   },
>     bind_tes_images
>  };
>
> @@ -241,9 +221,5 @@ static void bind_cs_images(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_cs_images = {
> -   {
> -      _NEW_TEXTURE,
> -      ST_NEW_COMPUTE_PROGRAM | ST_NEW_IMAGE_UNITS,
> -   },
>     bind_cs_images
>  };
> diff --git a/src/mesa/state_tracker/st_atom_list.h b/src/mesa/state_tracker/st_atom_list.h
> new file mode 100644
> index 0000000..d0d5a05
> --- /dev/null
> +++ b/src/mesa/state_tracker/st_atom_list.h
> @@ -0,0 +1,75 @@
> +/* Render (non-compute) states must be first. */
> +ST_STATE(ST_NEW_DSA, st_update_depth_stencil_alpha)
> +ST_STATE(ST_NEW_CLIP_STATE, st_update_clip)
> +
> +ST_STATE(ST_NEW_FS_STATE, st_update_fp)
> +ST_STATE(ST_NEW_GS_STATE, st_update_gp)
> +ST_STATE(ST_NEW_TES_STATE, st_update_tep)
> +ST_STATE(ST_NEW_TCS_STATE, st_update_tcp)
> +ST_STATE(ST_NEW_VS_STATE, st_update_vp)
> +
> +ST_STATE(ST_NEW_RASTERIZER, st_update_rasterizer)
> +ST_STATE(ST_NEW_POLY_STIPPLE, st_update_polygon_stipple)
> +ST_STATE(ST_NEW_VIEWPORT, st_update_viewport)
> +ST_STATE(ST_NEW_SCISSOR, st_update_scissor)
> +ST_STATE(ST_NEW_WINDOW_RECTANGLES, st_update_window_rectangles)
> +ST_STATE(ST_NEW_BLEND, st_update_blend)
> +
> +ST_STATE(ST_NEW_VS_SAMPLER_VIEWS, st_update_vertex_texture)
> +ST_STATE(ST_NEW_FS_SAMPLER_VIEWS, st_update_fragment_texture)
> +ST_STATE(ST_NEW_GS_SAMPLER_VIEWS, st_update_geometry_texture)
> +ST_STATE(ST_NEW_TCS_SAMPLER_VIEWS, st_update_tessctrl_texture)
> +ST_STATE(ST_NEW_TES_SAMPLER_VIEWS, st_update_tesseval_texture)
> +
> +/* Non-compute samplers. */
> +ST_STATE(ST_NEW_RENDER_SAMPLERS, st_update_sampler) /* depends on update_*_texture for swizzle */
> +
> +ST_STATE(ST_NEW_VS_IMAGES, st_bind_vs_images)
> +ST_STATE(ST_NEW_TCS_IMAGES, st_bind_tcs_images)
> +ST_STATE(ST_NEW_TES_IMAGES, st_bind_tes_images)
> +ST_STATE(ST_NEW_GS_IMAGES, st_bind_gs_images)
> +ST_STATE(ST_NEW_FS_IMAGES, st_bind_fs_images)
> +
> +ST_STATE(ST_NEW_FB_STATE, st_update_framebuffer) /* depends on update_*_texture and bind_*_images */
> +ST_STATE(ST_NEW_SAMPLE_MASK, st_update_msaa)
> +ST_STATE(ST_NEW_SAMPLE_SHADING, st_update_sample_shading)
> +
> +ST_STATE(ST_NEW_VS_CONSTANTS, st_update_vs_constants)
> +ST_STATE(ST_NEW_TCS_CONSTANTS, st_update_tcs_constants)
> +ST_STATE(ST_NEW_TES_CONSTANTS, st_update_tes_constants)
> +ST_STATE(ST_NEW_GS_CONSTANTS, st_update_gs_constants)
> +ST_STATE(ST_NEW_FS_CONSTANTS, st_update_fs_constants)
> +
> +ST_STATE(ST_NEW_VS_UBOS, st_bind_vs_ubos)
> +ST_STATE(ST_NEW_TCS_UBOS, st_bind_tcs_ubos)
> +ST_STATE(ST_NEW_TES_UBOS, st_bind_tes_ubos)
> +ST_STATE(ST_NEW_FS_UBOS, st_bind_fs_ubos)
> +ST_STATE(ST_NEW_GS_UBOS, st_bind_gs_ubos)
> +
> +ST_STATE(ST_NEW_VS_ATOMICS, st_bind_vs_atomics)
> +ST_STATE(ST_NEW_TCS_ATOMICS, st_bind_tcs_atomics)
> +ST_STATE(ST_NEW_TES_ATOMICS, st_bind_tes_atomics)
> +ST_STATE(ST_NEW_FS_ATOMICS, st_bind_fs_atomics)
> +ST_STATE(ST_NEW_GS_ATOMICS, st_bind_gs_atomics)
> +
> +ST_STATE(ST_NEW_VS_SSBOS, st_bind_vs_ssbos)
> +ST_STATE(ST_NEW_TCS_SSBOS, st_bind_tcs_ssbos)
> +ST_STATE(ST_NEW_TES_SSBOS, st_bind_tes_ssbos)
> +ST_STATE(ST_NEW_FS_SSBOS, st_bind_fs_ssbos)
> +ST_STATE(ST_NEW_GS_SSBOS, st_bind_gs_ssbos)
> +
> +ST_STATE(ST_NEW_PIXEL_TRANSFER, st_update_pixel_transfer)
> +ST_STATE(ST_NEW_TESS_STATE, st_update_tess)
> +
> +/* this must be done after the vertex program update */
> +ST_STATE(ST_NEW_VERTEX_ARRAYS, st_update_array)
> +
> +/* Compute states must be last. */
> +ST_STATE(ST_NEW_CS_STATE, st_update_cp)
> +ST_STATE(ST_NEW_CS_SAMPLER_VIEWS, st_update_compute_texture)
> +ST_STATE(ST_NEW_CS_SAMPLERS, st_update_sampler) /* depends on update_compute_texture for swizzle */
> +ST_STATE(ST_NEW_CS_CONSTANTS, st_update_cs_constants)
> +ST_STATE(ST_NEW_CS_UBOS, st_bind_cs_ubos)
> +ST_STATE(ST_NEW_CS_ATOMICS, st_bind_cs_atomics)
> +ST_STATE(ST_NEW_CS_SSBOS, st_bind_cs_ssbos)
> +ST_STATE(ST_NEW_CS_IMAGES, st_bind_cs_images)
> diff --git a/src/mesa/state_tracker/st_atom_msaa.c b/src/mesa/state_tracker/st_atom_msaa.c
> index 3025534..8442a28 100644
> --- a/src/mesa/state_tracker/st_atom_msaa.c
> +++ b/src/mesa/state_tracker/st_atom_msaa.c
> @@ -86,17 +86,9 @@ static void update_sample_shading( struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_msaa = {
> -   {                                                   /* dirty */
> -      (_NEW_MULTISAMPLE | _NEW_BUFFERS),               /* mesa */
> -      ST_NEW_FRAMEBUFFER,                              /* st */
> -   },
>     update_sample_mask                                  /* update */
>  };
>
>  const struct st_tracked_state st_update_sample_shading = {
> -   {                                                   /* dirty */
> -      (_NEW_MULTISAMPLE | _NEW_PROGRAM | _NEW_BUFFERS),        /* mesa */
> -      ST_NEW_FRAGMENT_PROGRAM | ST_NEW_FRAMEBUFFER,    /* st */
> -   },
>     update_sample_shading                               /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
> index a56ff10..26d8ade 100644
> --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
> +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
> @@ -102,9 +102,5 @@ update_pixel_transfer(struct st_context *st)
>
>
>  const struct st_tracked_state st_update_pixel_transfer = {
> -   {                                                   /* dirty */
> -      _NEW_PIXEL,                                      /* mesa */
> -      0,                                               /* st */
> -   },
>     update_pixel_transfer                               /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
> index 463a210..ca975aa 100644
> --- a/src/mesa/state_tracker/st_atom_rasterizer.c
> +++ b/src/mesa/state_tracker/st_atom_rasterizer.c
> @@ -290,21 +290,5 @@ static void update_raster_state( struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_rasterizer = {
> -   {
> -      (_NEW_BUFFERS |
> -       _NEW_LIGHT |
> -       _NEW_LINE |
> -       _NEW_MULTISAMPLE |
> -       _NEW_POINT |
> -       _NEW_POLYGON |
> -       _NEW_PROGRAM |
> -       _NEW_SCISSOR |
> -       _NEW_FRAG_CLAMP |
> -       _NEW_TRANSFORM),     /* mesa state dependencies*/
> -      (ST_NEW_VERTEX_PROGRAM |
> -       ST_NEW_TESSEVAL_PROGRAM |
> -       ST_NEW_GEOMETRY_PROGRAM |
> -       ST_NEW_RASTERIZER),  /* state tracker dependencies */
> -   },
>     update_raster_state     /* update function */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
> index a9e14f8..88ae7a0 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -334,9 +334,5 @@ update_samplers(struct st_context *st)
>
>
>  const struct st_tracked_state st_update_sampler = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      0,                                               /* st */
> -   },
>     update_samplers                                     /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
> index fb13077..fb478a3 100644
> --- a/src/mesa/state_tracker/st_atom_scissor.c
> +++ b/src/mesa/state_tracker/st_atom_scissor.c
> @@ -141,17 +141,9 @@ update_window_rectangles(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_update_scissor = {
> -   {                                                   /* dirty */
> -      (_NEW_SCISSOR | _NEW_BUFFERS),                   /* mesa */
> -      0,                                               /* st */
> -   },
>     update_scissor                                      /* update */
>  };
>
>  const struct st_tracked_state st_update_window_rectangles = {
> -   {                                                   /* dirty */
> -      (_NEW_SCISSOR | _NEW_BUFFERS),                   /* mesa */
> -      0,                                               /* st */
> -   },
>     update_window_rectangles                            /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
> index 0bb2295..b3401c4 100644
> --- a/src/mesa/state_tracker/st_atom_shader.c
> +++ b/src/mesa/state_tracker/st_atom_shader.c
> @@ -152,10 +152,6 @@ update_fp( struct st_context *st )
>
>
>  const struct st_tracked_state st_update_fp = {
> -   {                                                   /* dirty */
> -      _NEW_BUFFERS | _NEW_MULTISAMPLE | _NEW_FOG,      /* mesa */
> -      ST_NEW_FRAGMENT_PROGRAM                           /* st */
> -   },
>     update_fp                                   /* update */
>  };
>
> @@ -209,10 +205,6 @@ update_vp( struct st_context *st )
>
>
>  const struct st_tracked_state st_update_vp = {
> -   {                                                   /* dirty */
> -      0,                                                /* mesa */
> -      ST_NEW_VERTEX_PROGRAM                             /* st */
> -   },
>     update_vp                                           /* update */
>  };
>
> @@ -241,10 +233,6 @@ update_gp( struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_gp = {
> -   {                                   /* dirty */
> -      0,                               /* mesa */
> -      ST_NEW_GEOMETRY_PROGRAM           /* st */
> -   },
>     update_gp                           /* update */
>  };
>
> @@ -273,10 +261,6 @@ update_tcp( struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_tcp = {
> -   {                                   /* dirty */
> -      0,                               /* mesa */
> -      ST_NEW_TESSCTRL_PROGRAM           /* st */
> -   },
>     update_tcp                                  /* update */
>  };
>
> @@ -305,10 +289,6 @@ update_tep( struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_tep = {
> -   {                                   /* dirty */
> -      0,                               /* mesa */
> -      ST_NEW_TESSEVAL_PROGRAM           /* st */
> -   },
>     update_tep                                  /* update */
>  };
>
> @@ -336,9 +316,5 @@ update_cp( struct st_context *st )
>  }
>
>  const struct st_tracked_state st_update_cp = {
> -   {                                   /* dirty */
> -      0,                               /* mesa */
> -      ST_NEW_COMPUTE_PROGRAM           /* st */
> -   },
>     update_cp                           /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_stipple.c b/src/mesa/state_tracker/st_atom_stipple.c
> index b059ca9..a30215f 100644
> --- a/src/mesa/state_tracker/st_atom_stipple.c
> +++ b/src/mesa/state_tracker/st_atom_stipple.c
> @@ -84,10 +84,5 @@ update_stipple( struct st_context *st )
>
>  /** Update the stipple when the pattern or window height changes */
>  const struct st_tracked_state st_update_polygon_stipple = {
> -   {                                                   /* dirty */
> -      (_NEW_POLYGONSTIPPLE |
> -       _NEW_BUFFERS),                                  /* mesa */
> -      0,                                               /* st */
> -   },
>     update_stipple                                      /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_storagebuf.c b/src/mesa/state_tracker/st_atom_storagebuf.c
> index 2ee5765..a5a760e 100644
> --- a/src/mesa/state_tracker/st_atom_storagebuf.c
> +++ b/src/mesa/state_tracker/st_atom_storagebuf.c
> @@ -103,10 +103,6 @@ static void bind_vs_ssbos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_vs_ssbos = {
> -   {
> -      0,
> -      ST_NEW_VERTEX_PROGRAM | ST_NEW_STORAGE_BUFFER,
> -   },
>     bind_vs_ssbos
>  };
>
> @@ -123,10 +119,6 @@ static void bind_fs_ssbos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_fs_ssbos = {
> -   {
> -      0,
> -      ST_NEW_FRAGMENT_PROGRAM | ST_NEW_STORAGE_BUFFER,
> -   },
>     bind_fs_ssbos
>  };
>
> @@ -143,10 +135,6 @@ static void bind_gs_ssbos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_gs_ssbos = {
> -   {
> -      0,
> -      ST_NEW_GEOMETRY_PROGRAM | ST_NEW_STORAGE_BUFFER,
> -   },
>     bind_gs_ssbos
>  };
>
> @@ -163,10 +151,6 @@ static void bind_tcs_ssbos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tcs_ssbos = {
> -   {
> -      0,
> -      ST_NEW_TESSCTRL_PROGRAM | ST_NEW_STORAGE_BUFFER,
> -   },
>     bind_tcs_ssbos
>  };
>
> @@ -183,10 +167,6 @@ static void bind_tes_ssbos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_tes_ssbos = {
> -   {
> -      0,
> -      ST_NEW_TESSEVAL_PROGRAM | ST_NEW_STORAGE_BUFFER,
> -   },
>     bind_tes_ssbos
>  };
>
> @@ -203,9 +183,5 @@ static void bind_cs_ssbos(struct st_context *st)
>  }
>
>  const struct st_tracked_state st_bind_cs_ssbos = {
> -   {
> -      0,
> -      ST_NEW_COMPUTE_PROGRAM | ST_NEW_STORAGE_BUFFER,
> -   },
>     bind_cs_ssbos
>  };
> diff --git a/src/mesa/state_tracker/st_atom_tess.c b/src/mesa/state_tracker/st_atom_tess.c
> index 5c1e3a9..103e41d 100644
> --- a/src/mesa/state_tracker/st_atom_tess.c
> +++ b/src/mesa/state_tracker/st_atom_tess.c
> @@ -53,9 +53,5 @@ update_tess(struct st_context *st)
>
>
>  const struct st_tracked_state st_update_tess = {
> -   {                           /* dirty */
> -      0,                       /* mesa */
> -      ST_NEW_TESS_STATE,       /* st */
> -   },
>     update_tess                  /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
> index ed8c2d3..923cb93 100644
> --- a/src/mesa/state_tracker/st_atom_texture.c
> +++ b/src/mesa/state_tracker/st_atom_texture.c
> @@ -565,54 +565,30 @@ update_compute_textures(struct st_context *st)
>
>
>  const struct st_tracked_state st_update_fragment_texture = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      ST_NEW_FRAGMENT_PROGRAM | ST_NEW_SAMPLER_VIEWS,  /* st */
> -   },
>     update_fragment_textures                            /* update */
>  };
>
>
>  const struct st_tracked_state st_update_vertex_texture = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      ST_NEW_VERTEX_PROGRAM | ST_NEW_SAMPLER_VIEWS,    /* st */
> -   },
>     update_vertex_textures                              /* update */
>  };
>
>
>  const struct st_tracked_state st_update_geometry_texture = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      ST_NEW_GEOMETRY_PROGRAM | ST_NEW_SAMPLER_VIEWS,  /* st */
> -   },
>     update_geometry_textures                            /* update */
>  };
>
>
>  const struct st_tracked_state st_update_tessctrl_texture = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      ST_NEW_TESSCTRL_PROGRAM | ST_NEW_SAMPLER_VIEWS,  /* st */
> -   },
>     update_tessctrl_textures                            /* update */
>  };
>
>
>  const struct st_tracked_state st_update_tesseval_texture = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      ST_NEW_TESSEVAL_PROGRAM | ST_NEW_SAMPLER_VIEWS,  /* st */
> -   },
>     update_tesseval_textures                            /* update */
>  };
>
>
>  const struct st_tracked_state st_update_compute_texture = {
> -   {                                                   /* dirty */
> -      _NEW_TEXTURE,                                    /* mesa */
> -      ST_NEW_COMPUTE_PROGRAM | ST_NEW_SAMPLER_VIEWS,   /* st */
> -   },
>     update_compute_textures                             /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c
> index f5e09e2..8f750a9 100644
> --- a/src/mesa/state_tracker/st_atom_viewport.c
> +++ b/src/mesa/state_tracker/st_atom_viewport.c
> @@ -83,9 +83,5 @@ update_viewport( struct st_context *st )
>
>
>  const struct st_tracked_state st_update_viewport = {
> -   {                                                   /* dirty */
> -      _NEW_BUFFERS | _NEW_VIEWPORT,                    /* mesa */
> -      0,                                               /* st */
> -   },
>     update_viewport                                     /* update */
>  };
> diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
> index a109120..5765ed2 100644
> --- a/src/mesa/state_tracker/st_cb_bitmap.c
> +++ b/src/mesa/state_tracker/st_cb_bitmap.c
> @@ -347,7 +347,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
>     restore_render_state(ctx);
>
>     /* We uploaded modified constants, need to invalidate them. */
> -   st->dirty.mesa |= _NEW_PROGRAM_CONSTANTS;
> +   st->dirty |= ST_NEW_FS_CONSTANTS;
>  }
>
>
> @@ -642,12 +642,12 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
>        init_bitmap_state(st);
>     }
>
> -   /* We only need to validate state of the st dirty flags are set or
> -    * any non-_NEW_PROGRAM_CONSTANTS mesa flags are set.  The VS we use
> +   /* We only need to validate any non-ST_NEW_CONSTANTS state. The VS we use
>      * for bitmap drawing uses no constants and the FS constants are
>      * explicitly uploaded in the draw_bitmap_quad() function.
>      */
> -   if ((st->dirty.mesa & ~_NEW_PROGRAM_CONSTANTS) || st->dirty.st) {
> +   if ((st->dirty | ctx->NewDriverState) & ~ST_NEW_CONSTANTS &
> +       ST_PIPELINE_RENDER_STATE_MASK) {
>        st_validate_state(st, ST_PIPELINE_RENDER);
>     }
>
> @@ -803,7 +803,7 @@ st_DrawAtlasBitmaps(struct gl_context *ctx,
>     pipe_sampler_view_reference(&sv, NULL);
>
>     /* We uploaded modified constants, need to invalidate them. */
> -   st->dirty.mesa |= _NEW_PROGRAM_CONSTANTS;
> +   st->dirty |= ST_NEW_FS_CONSTANTS;
>  }
>
>
> diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
> index 2d4c821..6d54326 100644
> --- a/src/mesa/state_tracker/st_cb_bufferobjects.c
> +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
> @@ -333,15 +333,15 @@ st_bufferobj_data(struct gl_context *ctx,
>      * might be using it.
>      */
>     /* TODO: Add arrays to usage history */
> -   st->dirty.st |= ST_NEW_VERTEX_ARRAYS;
> +   st->dirty |= ST_NEW_VERTEX_ARRAYS;
>     if (st_obj->Base.UsageHistory & USAGE_UNIFORM_BUFFER)
> -      st->dirty.st |= ST_NEW_UNIFORM_BUFFER;
> +      st->dirty |= ST_NEW_UNIFORM_BUFFER;
>     if (st_obj->Base.UsageHistory & USAGE_SHADER_STORAGE_BUFFER)
> -      st->dirty.st |= ST_NEW_STORAGE_BUFFER;
> +      st->dirty |= ST_NEW_STORAGE_BUFFER;
>     if (st_obj->Base.UsageHistory & USAGE_TEXTURE_BUFFER)
> -      st->dirty.st |= ST_NEW_SAMPLER_VIEWS | ST_NEW_IMAGE_UNITS;
> +      st->dirty |= ST_NEW_SAMPLER_VIEWS | ST_NEW_IMAGE_UNITS;
>     if (st_obj->Base.UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER)
> -      st->dirty.st |= ST_NEW_ATOMIC_BUFFER;
> +      st->dirty |= ST_NEW_ATOMIC_BUFFER;
>
>     return GL_TRUE;
>  }
> diff --git a/src/mesa/state_tracker/st_cb_compute.c b/src/mesa/state_tracker/st_cb_compute.c
> index c057a78..677507d 100644
> --- a/src/mesa/state_tracker/st_cb_compute.c
> +++ b/src/mesa/state_tracker/st_cb_compute.c
> @@ -51,7 +51,7 @@ static void st_dispatch_compute_common(struct gl_context *ctx,
>     if (ctx->NewState)
>        _mesa_update_state(ctx);
>
> -   if (st->dirty_cp.st || st->dirty_cp.mesa || ctx->NewDriverState)
> +   if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_COMPUTE_STATE_MASK)
>        st_validate_state(st, ST_PIPELINE_COMPUTE);
>
>     for (unsigned i = 0; i < 3; i++) {
> diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c
> index c541088..735e268 100644
> --- a/src/mesa/state_tracker/st_cb_feedback.c
> +++ b/src/mesa/state_tracker/st_cb_feedback.c
> @@ -294,7 +294,7 @@ st_RenderMode(struct gl_context *ctx, GLenum newMode )
>        /* Plug in new vbo draw function */
>        vbo_set_draw_func(ctx, st_feedback_draw_vbo);
>        /* need to generate/use a vertex program that emits pos/color/tex */
> -      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> +      st->dirty |= ST_NEW_VERTEX_PROGRAM;
>     }
>  }
>
> diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
> index d79cfe2..6264896 100644
> --- a/src/mesa/state_tracker/st_cb_program.c
> +++ b/src/mesa/state_tracker/st_cb_program.c
> @@ -61,22 +61,22 @@ st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog)
>
>     switch (target) {
>     case GL_VERTEX_PROGRAM_ARB:
> -      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> +      st->dirty |= ST_NEW_VERTEX_PROGRAM;
>        break;
>     case GL_FRAGMENT_PROGRAM_ARB:
> -      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
> +      st->dirty |= ST_NEW_FRAGMENT_PROGRAM;
>        break;
>     case GL_GEOMETRY_PROGRAM_NV:
> -      st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
> +      st->dirty |= ST_NEW_GEOMETRY_PROGRAM;
>        break;
>     case GL_TESS_CONTROL_PROGRAM_NV:
> -      st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM;
> +      st->dirty |= ST_NEW_TESSCTRL_PROGRAM;
>        break;
>     case GL_TESS_EVALUATION_PROGRAM_NV:
> -      st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
> +      st->dirty |= ST_NEW_TESSEVAL_PROGRAM;
>        break;
>     case GL_COMPUTE_PROGRAM_NV:
> -      st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
> +      st->dirty |= ST_NEW_COMPUTE_PROGRAM;
>        break;
>     }
>  }
> @@ -91,12 +91,12 @@ st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
>  {
>     struct st_context *st = st_context(ctx);
>
> -   st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
> -   st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> -   st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
> -   st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM;
> -   st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
> -   st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
> +   st->dirty |= ST_NEW_FRAGMENT_PROGRAM;
> +   st->dirty |= ST_NEW_VERTEX_PROGRAM;
> +   st->dirty |= ST_NEW_GEOMETRY_PROGRAM;
> +   st->dirty |= ST_NEW_TESSCTRL_PROGRAM;
> +   st->dirty |= ST_NEW_TESSEVAL_PROGRAM;
> +   st->dirty |= ST_NEW_COMPUTE_PROGRAM;
>  }
>
>
> @@ -245,7 +245,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->fp == stfp)
> -        st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
> +        st->dirty |= ST_NEW_FRAGMENT_PROGRAM;
>     }
>     else if (target == GL_GEOMETRY_PROGRAM_NV) {
>        struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
> @@ -256,7 +256,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->gp == stgp)
> -        st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
> +        st->dirty |= ST_NEW_GEOMETRY_PROGRAM;
>     }
>     else if (target == GL_VERTEX_PROGRAM_ARB) {
>        struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
> @@ -266,7 +266,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->vp == stvp)
> -        st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> +        st->dirty |= ST_NEW_VERTEX_PROGRAM;
>     }
>     else if (target == GL_TESS_CONTROL_PROGRAM_NV) {
>        struct st_tessctrl_program *sttcp =
> @@ -278,7 +278,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->tcp == sttcp)
> -         st->dirty.st |= ST_NEW_TESSCTRL_PROGRAM;
> +         st->dirty |= ST_NEW_TESSCTRL_PROGRAM;
>     }
>     else if (target == GL_TESS_EVALUATION_PROGRAM_NV) {
>        struct st_tesseval_program *sttep =
> @@ -290,7 +290,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->tep == sttep)
> -         st->dirty.st |= ST_NEW_TESSEVAL_PROGRAM;
> +         st->dirty |= ST_NEW_TESSEVAL_PROGRAM;
>     }
>     else if (target == GL_COMPUTE_PROGRAM_NV) {
>        struct st_compute_program *stcp =
> @@ -301,7 +301,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->cp == stcp)
> -         st->dirty_cp.st |= ST_NEW_COMPUTE_PROGRAM;
> +         st->dirty |= ST_NEW_COMPUTE_PROGRAM;
>     }
>     else if (target == GL_FRAGMENT_SHADER_ATI) {
>        assert(prog);
> @@ -317,7 +317,7 @@ st_program_string_notify( struct gl_context *ctx,
>           return false;
>
>        if (st->fp == stfp)
> -         st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
> +         st->dirty |= ST_NEW_FRAGMENT_PROGRAM;
>     }
>
>     if (ST_DEBUG & DEBUG_PRECOMPILE ||
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index d2acc71..ab06195 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -2540,7 +2540,7 @@ st_finalize_texture(struct gl_context *ctx,
>            */
>           pipe_resource_reference(&stObj->pt, NULL);
>           st_texture_release_all_sampler_views(st, stObj);
> -         st->dirty.st |= ST_NEW_FRAMEBUFFER;
> +         st->dirty |= ST_NEW_FRAMEBUFFER;
>        }
>     }
>
> diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
> index f1d2084..911bec6 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -130,20 +130,94 @@ void st_invalidate_state(struct gl_context * ctx, GLbitfield new_state)
>  {
>     struct st_context *st = st_context(ctx);
>
> -   /* Replace _NEW_FRAG_CLAMP with ST_NEW_FRAGMENT_PROGRAM for the fallback. */
> -   if (st->clamp_frag_color_in_shader && (new_state & _NEW_FRAG_CLAMP)) {
> -      new_state &= ~_NEW_FRAG_CLAMP;
> -      st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
> +   if (new_state & _NEW_BUFFERS) {
> +      st->dirty |= ST_NEW_DSA |
> +                   ST_NEW_FB_STATE |
> +                   ST_NEW_SAMPLE_MASK |
> +                   ST_NEW_SAMPLE_SHADING |
> +                   ST_NEW_FS_STATE |
> +                   ST_NEW_POLY_STIPPLE |
> +                   ST_NEW_VIEWPORT |
> +                   ST_NEW_RASTERIZER |
> +                   ST_NEW_SCISSOR |
> +                   ST_NEW_WINDOW_RECTANGLES;
> +   } else {
> +      /* These set a subset of flags set by _NEW_BUFFERS, so we only have to
> +       * check them when _NEW_BUFFERS isn't set.
> +       */
> +      if (new_state & (_NEW_DEPTH |
> +                       _NEW_STENCIL))
> +         st->dirty |= ST_NEW_DSA;
> +
> +      if (new_state & _NEW_PROGRAM)
> +         st->dirty |= ST_NEW_SAMPLE_SHADING |
> +                      ST_NEW_RASTERIZER;
> +
> +      if (new_state & _NEW_SCISSOR)
> +         st->dirty |= ST_NEW_RASTERIZER |
> +                      ST_NEW_SCISSOR |
> +                      ST_NEW_WINDOW_RECTANGLES;
> +
> +      if (new_state & _NEW_FOG)
> +         st->dirty |= ST_NEW_FS_STATE;
> +
> +      if (new_state & _NEW_POLYGONSTIPPLE)
> +         st->dirty |= ST_NEW_POLY_STIPPLE;
> +
> +      if (new_state & _NEW_VIEWPORT)
> +         st->dirty |= ST_NEW_VIEWPORT;
> +
> +      if (new_state & _NEW_FRAG_CLAMP) {
> +         if (st->clamp_frag_color_in_shader)
> +            st->dirty |= ST_NEW_FS_STATE;
> +         else
> +            st->dirty |= ST_NEW_RASTERIZER;
> +      }
>     }
>
> -   /* Update the vertex shader if ctx->Light._ClampVertexColor was changed. */
> -   if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT)) {
> -      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
> +   if (new_state & _NEW_MULTISAMPLE) {
> +      st->dirty |= ST_NEW_BLEND |
> +                   ST_NEW_SAMPLE_MASK |
> +                   ST_NEW_SAMPLE_SHADING |
> +                   ST_NEW_RASTERIZER |
> +                   ST_NEW_FS_STATE;
> +   } else {
> +      /* These set a subset of flags set by _NEW_MULTISAMPLE, so we only
> +       * have to check them when _NEW_MULTISAMPLE isn't set.
> +       */
> +      if (new_state & (_NEW_LIGHT |
> +                       _NEW_LINE |
> +                       _NEW_POINT |
> +                       _NEW_POLYGON |
> +                       _NEW_TRANSFORM))
> +         st->dirty |= ST_NEW_RASTERIZER;
>     }
>
> -   /* Invalidate render and compute pipelines. */
> -   st->dirty.mesa |= new_state;
> -   st->dirty_cp.mesa |= new_state;
> +   if (new_state & (_NEW_PROJECTION |
> +                    _NEW_TRANSFORM))
> +      st->dirty |= ST_NEW_CLIP_STATE;
> +
> +   if (new_state & _NEW_COLOR)
> +      st->dirty |= ST_NEW_BLEND |
> +                   ST_NEW_DSA;
> +
> +   if (new_state & _NEW_PIXEL)
> +      st->dirty |= ST_NEW_PIXEL_TRANSFER;
> +
> +   if (new_state & _NEW_TEXTURE)
> +      st->dirty |= ST_NEW_SAMPLER_VIEWS |
> +                   ST_NEW_SAMPLERS |
> +                   ST_NEW_IMAGE_UNITS;
> +
> +   if (new_state & _NEW_CURRENT_ATTRIB)
> +      st->dirty |= ST_NEW_VERTEX_ARRAYS;
> +
> +   if (new_state & _NEW_PROGRAM_CONSTANTS)
> +      st->dirty |= ST_NEW_CONSTANTS;
> +
> +   /* Update the vertex shader if ctx->Light._ClampVertexColor was changed. */
> +   if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT))
> +      st->dirty |= ST_NEW_VS_STATE;
>
>     /* This is the only core Mesa module we depend upon.
>      * No longer use swrast, swsetup, tnl.
> @@ -214,11 +288,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
>     /* state tracker needs the VBO module */
>     _vbo_CreateContext(ctx);
>
> -   /* Initialize render and compute pipelines flags */
> -   st->dirty.mesa = ~0;
> -   st->dirty.st = ~0;
> -   st->dirty_cp.mesa = ~0;
> -   st->dirty_cp.st = ~0;
> +   st->dirty = ST_ALL_STATES_MASK;
>
>     /* Create upload manager for vertex data for glBitmap, glDrawPixels,
>      * glClear, etc.
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index b3cf285..b9ad2a9 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -32,6 +32,7 @@
>  #include "pipe/p_state.h"
>  #include "state_tracker/st_api.h"
>  #include "main/fbobject.h"
> +#include "state_tracker/st_atom.h"
>
>
>  #ifdef __cplusplus
> @@ -50,44 +51,6 @@ struct st_perf_monitor_group;
>  struct u_upload_mgr;
>
>
> -/* gap  */
> -#define ST_NEW_FRAGMENT_PROGRAM        (1 << 1)
> -#define ST_NEW_VERTEX_PROGRAM          (1 << 2)
> -#define ST_NEW_FRAMEBUFFER             (1 << 3)
> -#define ST_NEW_TESS_STATE              (1 << 4)
> -#define ST_NEW_GEOMETRY_PROGRAM        (1 << 5)
> -#define ST_NEW_VERTEX_ARRAYS           (1 << 6)
> -#define ST_NEW_RASTERIZER              (1 << 7)
> -#define ST_NEW_UNIFORM_BUFFER          (1 << 8)
> -#define ST_NEW_TESSCTRL_PROGRAM        (1 << 9)
> -#define ST_NEW_TESSEVAL_PROGRAM        (1 << 10)
> -#define ST_NEW_SAMPLER_VIEWS           (1 << 11)
> -#define ST_NEW_ATOMIC_BUFFER           (1 << 12)
> -#define ST_NEW_STORAGE_BUFFER          (1 << 13)
> -#define ST_NEW_COMPUTE_PROGRAM         (1 << 14)
> -#define ST_NEW_IMAGE_UNITS             (1 << 15)
> -
> -
> -struct st_state_flags {
> -   GLbitfield mesa;  /**< Mask of _NEW_x flags */
> -   uint32_t st;      /**< Mask of ST_NEW_x flags */
> -};
> -
> -struct st_tracked_state {
> -   struct st_state_flags dirty;
> -   void (*update)( struct st_context *st );
> -};
> -
> -
> -/**
> - * Enumeration of state tracker pipelines.
> - */
> -enum st_pipeline {
> -   ST_PIPELINE_RENDER,
> -   ST_PIPELINE_COMPUTE,
> -};
> -
> -
>  /** For drawing quads for glClear, glDraw/CopyPixels, glBitmap, etc. */
>  struct st_util_vertex
>  {
> @@ -175,8 +138,7 @@ struct st_context
>     char vendor[100];
>     char renderer[100];
>
> -   struct st_state_flags dirty;
> -   struct st_state_flags dirty_cp;
> +   uint64_t dirty; /**< dirty states */
>
>     GLboolean vertdata_edgeflags;
>     GLboolean edgeflag_culls_prims;
> diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
> index d12d77f..92eb4a3 100644
> --- a/src/mesa/state_tracker/st_draw.c
> +++ b/src/mesa/state_tracker/st_draw.c
> @@ -173,7 +173,7 @@ st_draw_vbo(struct gl_context *ctx,
>     st_invalidate_readpix_cache(st);
>
>     /* Validate state. */
> -   if (st->dirty.st || st->dirty.mesa || ctx->NewDriverState) {
> +   if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK) {
>        st_validate_state(st, ST_PIPELINE_RENDER);
>     }
>
> @@ -278,7 +278,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
>     assert(stride);
>
>     /* Validate state. */
> -   if (st->dirty.st || st->dirty.mesa || ctx->NewDriverState) {
> +   if ((st->dirty | ctx->NewDriverState) & ST_PIPELINE_RENDER_STATE_MASK) {
>        st_validate_state(st, ST_PIPELINE_RENDER);
>     }
>
> diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
> index d323c87..e2da054 100644
> --- a/src/mesa/state_tracker/st_manager.c
> +++ b/src/mesa/state_tracker/st_manager.c
> @@ -153,7 +153,7 @@ st_context_validate(struct st_context *st,
>                      struct st_framebuffer *stread)
>  {
>      if (stdraw && stdraw->stamp != st->draw_stamp) {
> -       st->dirty.st |= ST_NEW_FRAMEBUFFER;
> +       st->dirty |= ST_NEW_FRAMEBUFFER;
>         _mesa_resize_framebuffer(st->ctx, &stdraw->Base,
>                                  stdraw->Base.Width,
>                                  stdraw->Base.Height);
> @@ -162,7 +162,7 @@ st_context_validate(struct st_context *st,
>
>      if (stread && stread->stamp != st->read_stamp) {
>         if (stread != stdraw) {
> -          st->dirty.st |= ST_NEW_FRAMEBUFFER;
> +          st->dirty |= ST_NEW_FRAMEBUFFER;
>            _mesa_resize_framebuffer(st->ctx, &stread->Base,
>                                     stread->Base.Width,
>                                     stread->Base.Height);
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list