Re: [Mesa-dev] [PATCH 4/8] st/mesa: determine states used or affected by shaders at compile time

2016-08-10 Thread Marek Olšák
On Wed, Aug 10, 2016 at 4:34 PM, Nicolai Hähnle  wrote:
> On 10.08.2016 13:05, Marek Olšák wrote:
>>
>> On Tue, Aug 9, 2016 at 12:56 PM, Nicolai Hähnle 
>> wrote:
>>>
>>> On 07.08.2016 03:12, Marek Olšák wrote:


 From: Marek Olšák 

 At compile time, each shader determines which ST_NEW flags should be set
 at shader bind time.

 This just sets the new field for all shaders. The next commit will use
 it.
 ---
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 175
 -
  src/mesa/state_tracker/st_program.c|  37 +-
  src/mesa/state_tracker/st_program.h|   6 +
  3 files changed, 215 insertions(+), 3 deletions(-)

 diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 index 362559f..fd14766 100644
 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 @@ -,31 +,202 @@ get_mesa_program_tgsi(struct gl_context *ctx,

  static struct gl_program *
  get_mesa_program(struct gl_context *ctx,
   struct gl_shader_program *shader_program,
   struct gl_linked_shader *shader)
  {
 struct pipe_screen *pscreen = ctx->st->pipe->screen;
 unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
 enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
pscreen->get_shader_param(pscreen, ptarget,
 PIPE_SHADER_CAP_PREFERRED_IR);
 +   struct gl_program *prog = NULL;
 +
 if (preferred_ir == PIPE_SHADER_IR_NIR) {
/* TODO only for GLSL VS/FS for now: */
switch (shader->Stage) {
case MESA_SHADER_VERTEX:
case MESA_SHADER_FRAGMENT:
 - return st_nir_get_mesa_program(ctx, shader_program, shader);
 + prog = st_nir_get_mesa_program(ctx, shader_program, shader);
default:
   break;
}
 +   } else {
 +  prog = get_mesa_program_tgsi(ctx, shader_program, shader);
 +   }
 +
 +   if (prog) {
 +  uint64_t *states;
 +
 +  /* This determines which states will be updated when the shader
 is
 +   * bound.
 +   */
 +  switch (shader->Stage) {
 +  case MESA_SHADER_VERTEX:
 + states = &((struct st_vertex_program*)prog)->affected_states;
 +
 + *states = ST_NEW_VS_STATE |
 +   ST_NEW_RASTERIZER |
 +   ST_NEW_VERTEX_ARRAYS;
 +
 + if (prog->Parameters->NumParameters)
 +*states |= ST_NEW_VS_CONSTANTS;
 +
 + if (shader->num_samplers)
 +*states |= ST_NEW_VS_SAMPLER_VIEWS |
 +   ST_NEW_RENDER_SAMPLERS;
 +
 + if (shader->NumImages)
 +*states |= ST_NEW_VS_IMAGES;
 +
 + if (shader->NumUniformBlocks)
 +*states |= ST_NEW_VS_UBOS;
 +
 + if (shader->NumShaderStorageBlocks)
 +*states |= ST_NEW_VS_SSBOS;
 +
 + if (shader->NumAtomicBuffers)
 +*states |= ST_NEW_VS_ATOMICS;
>>>
>>>
>>>
>>> I'm not overly fond of the code duplication here. Perhaps these could all
>>> be
>>> expressed relative to a stage-specific base flag?
>>
>>
>> Not really. It shouldn't rely on the order the flags are declared. I
>> can't make it better than this:
>
>
> I don't know why we can't just say we should be able to rely on the order,
> but the alternative below is indeed not really any better.

We could rely on the order, but as with system value enumerations,
we'd need a lot of assertions to prevent a breakage if somebody
changes the order and we don't notice.

I'll still amend the diff, because it makes the code a little shorter.

Marek
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 4/8] st/mesa: determine states used or affected by shaders at compile time

2016-08-10 Thread Nicolai Hähnle

On 10.08.2016 13:05, Marek Olšák wrote:

On Tue, Aug 9, 2016 at 12:56 PM, Nicolai Hähnle  wrote:

On 07.08.2016 03:12, Marek Olšák wrote:


From: Marek Olšák 

At compile time, each shader determines which ST_NEW flags should be set
at shader bind time.

This just sets the new field for all shaders. The next commit will use it.
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 175
-
 src/mesa/state_tracker/st_program.c|  37 +-
 src/mesa/state_tracker/st_program.h|   6 +
 3 files changed, 215 insertions(+), 3 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 362559f..fd14766 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -,31 +,202 @@ get_mesa_program_tgsi(struct gl_context *ctx,

 static struct gl_program *
 get_mesa_program(struct gl_context *ctx,
  struct gl_shader_program *shader_program,
  struct gl_linked_shader *shader)
 {
struct pipe_screen *pscreen = ctx->st->pipe->screen;
unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
   pscreen->get_shader_param(pscreen, ptarget,
PIPE_SHADER_CAP_PREFERRED_IR);
+   struct gl_program *prog = NULL;
+
if (preferred_ir == PIPE_SHADER_IR_NIR) {
   /* TODO only for GLSL VS/FS for now: */
   switch (shader->Stage) {
   case MESA_SHADER_VERTEX:
   case MESA_SHADER_FRAGMENT:
- return st_nir_get_mesa_program(ctx, shader_program, shader);
+ prog = st_nir_get_mesa_program(ctx, shader_program, shader);
   default:
  break;
   }
+   } else {
+  prog = get_mesa_program_tgsi(ctx, shader_program, shader);
+   }
+
+   if (prog) {
+  uint64_t *states;
+
+  /* This determines which states will be updated when the shader is
+   * bound.
+   */
+  switch (shader->Stage) {
+  case MESA_SHADER_VERTEX:
+ states = &((struct st_vertex_program*)prog)->affected_states;
+
+ *states = ST_NEW_VS_STATE |
+   ST_NEW_RASTERIZER |
+   ST_NEW_VERTEX_ARRAYS;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_VS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_VS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_VS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_VS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_VS_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_VS_ATOMICS;



I'm not overly fond of the code duplication here. Perhaps these could all be
expressed relative to a stage-specific base flag?


Not really. It shouldn't rely on the order the flags are declared. I
can't make it better than this:


I don't know why we can't just say we should be able to rely on the 
order, but the alternative below is indeed not really any better.


Cheers,
Nicolai


diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index fd14766..3e5b322 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -6664,6 +6664,37 @@ get_mesa_program_tgsi(struct gl_context *ctx,
return prog;
 }

+static void
+set_affected_state_flags(uint64_t *states,
+ struct gl_program *prog,
+ struct gl_linked_shader *shader,
+ uint64_t new_constants,
+ uint64_t new_sampler_views,
+ uint64_t new_samplers,
+ uint64_t new_images,
+ uint64_t new_ubos,
+ uint64_t new_ssbos,
+ uint64_t new_atomics)
+{
+   if (prog->Parameters->NumParameters)
+  *states |= new_constants;
+
+   if (shader->num_samplers)
+  *states |= new_sampler_views | new_samplers;
+
+   if (shader->NumImages)
+  *states |= new_images;
+
+   if (shader->NumUniformBlocks)
+  *states |= new_ubos;
+
+   if (shader->NumShaderStorageBlocks)
+  *states |= new_ssbos;
+
+   if (shader->NumAtomicBuffers)
+  *states |= new_atomics;
+}
+
 static struct gl_program *
 get_mesa_program(struct gl_context *ctx,
  struct gl_shader_program *shader_program,
@@ -6702,24 +6733,14 @@ get_mesa_program(struct gl_context *ctx,
ST_NEW_RASTERIZER |
ST_NEW_VERTEX_ARRAYS;

- if (prog->Parameters->NumParameters)
-*states |= ST_NEW_VS_CONSTANTS;
-
- if (shader->num_samplers)
-*states |= ST_NEW_VS_SAMPLER_VIEWS |
-   ST_NEW_RENDER_SAMPLERS;
-
- if (shader->NumImages)
-*states |

Re: [Mesa-dev] [PATCH 4/8] st/mesa: determine states used or affected by shaders at compile time

2016-08-10 Thread Marek Olšák
On Tue, Aug 9, 2016 at 12:56 PM, Nicolai Hähnle  wrote:
> On 07.08.2016 03:12, Marek Olšák wrote:
>>
>> From: Marek Olšák 
>>
>> At compile time, each shader determines which ST_NEW flags should be set
>> at shader bind time.
>>
>> This just sets the new field for all shaders. The next commit will use it.
>> ---
>>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 175
>> -
>>  src/mesa/state_tracker/st_program.c|  37 +-
>>  src/mesa/state_tracker/st_program.h|   6 +
>>  3 files changed, 215 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> index 362559f..fd14766 100644
>> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> @@ -,31 +,202 @@ get_mesa_program_tgsi(struct gl_context *ctx,
>>
>>  static struct gl_program *
>>  get_mesa_program(struct gl_context *ctx,
>>   struct gl_shader_program *shader_program,
>>   struct gl_linked_shader *shader)
>>  {
>> struct pipe_screen *pscreen = ctx->st->pipe->screen;
>> unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
>> enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
>>pscreen->get_shader_param(pscreen, ptarget,
>> PIPE_SHADER_CAP_PREFERRED_IR);
>> +   struct gl_program *prog = NULL;
>> +
>> if (preferred_ir == PIPE_SHADER_IR_NIR) {
>>/* TODO only for GLSL VS/FS for now: */
>>switch (shader->Stage) {
>>case MESA_SHADER_VERTEX:
>>case MESA_SHADER_FRAGMENT:
>> - return st_nir_get_mesa_program(ctx, shader_program, shader);
>> + prog = st_nir_get_mesa_program(ctx, shader_program, shader);
>>default:
>>   break;
>>}
>> +   } else {
>> +  prog = get_mesa_program_tgsi(ctx, shader_program, shader);
>> +   }
>> +
>> +   if (prog) {
>> +  uint64_t *states;
>> +
>> +  /* This determines which states will be updated when the shader is
>> +   * bound.
>> +   */
>> +  switch (shader->Stage) {
>> +  case MESA_SHADER_VERTEX:
>> + states = &((struct st_vertex_program*)prog)->affected_states;
>> +
>> + *states = ST_NEW_VS_STATE |
>> +   ST_NEW_RASTERIZER |
>> +   ST_NEW_VERTEX_ARRAYS;
>> +
>> + if (prog->Parameters->NumParameters)
>> +*states |= ST_NEW_VS_CONSTANTS;
>> +
>> + if (shader->num_samplers)
>> +*states |= ST_NEW_VS_SAMPLER_VIEWS |
>> +   ST_NEW_RENDER_SAMPLERS;
>> +
>> + if (shader->NumImages)
>> +*states |= ST_NEW_VS_IMAGES;
>> +
>> + if (shader->NumUniformBlocks)
>> +*states |= ST_NEW_VS_UBOS;
>> +
>> + if (shader->NumShaderStorageBlocks)
>> +*states |= ST_NEW_VS_SSBOS;
>> +
>> + if (shader->NumAtomicBuffers)
>> +*states |= ST_NEW_VS_ATOMICS;
>
>
> I'm not overly fond of the code duplication here. Perhaps these could all be
> expressed relative to a stage-specific base flag?

Not really. It shouldn't rely on the order the flags are declared. I
can't make it better than this:

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index fd14766..3e5b322 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -6664,6 +6664,37 @@ get_mesa_program_tgsi(struct gl_context *ctx,
return prog;
 }

+static void
+set_affected_state_flags(uint64_t *states,
+ struct gl_program *prog,
+ struct gl_linked_shader *shader,
+ uint64_t new_constants,
+ uint64_t new_sampler_views,
+ uint64_t new_samplers,
+ uint64_t new_images,
+ uint64_t new_ubos,
+ uint64_t new_ssbos,
+ uint64_t new_atomics)
+{
+   if (prog->Parameters->NumParameters)
+  *states |= new_constants;
+
+   if (shader->num_samplers)
+  *states |= new_sampler_views | new_samplers;
+
+   if (shader->NumImages)
+  *states |= new_images;
+
+   if (shader->NumUniformBlocks)
+  *states |= new_ubos;
+
+   if (shader->NumShaderStorageBlocks)
+  *states |= new_ssbos;
+
+   if (shader->NumAtomicBuffers)
+  *states |= new_atomics;
+}
+
 static struct gl_program *
 get_mesa_program(struct gl_context *ctx,
  struct gl_shader_program *shader_program,
@@ -6702,24 +6733,14 @@ get_mesa_program(struct gl_context *ctx,
ST_NEW_RASTERIZER |
ST_NEW_VERTEX_ARRAYS;

- if (prog->Parameters->NumParameters)
-*states |= ST_NEW_VS_CONSTANTS;
-
- if (shader->num_samplers)
-*states |= ST_NEW_VS_SAMPLER_VIEWS |
-   ST_NEW_RENDER_SAMPLERS;
-
- if (sha

Re: [Mesa-dev] [PATCH 4/8] st/mesa: determine states used or affected by shaders at compile time

2016-08-09 Thread Nicolai Hähnle

On 07.08.2016 03:12, Marek Olšák wrote:

From: Marek Olšák 

At compile time, each shader determines which ST_NEW flags should be set
at shader bind time.

This just sets the new field for all shaders. The next commit will use it.
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 175 -
 src/mesa/state_tracker/st_program.c|  37 +-
 src/mesa/state_tracker/st_program.h|   6 +
 3 files changed, 215 insertions(+), 3 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 362559f..fd14766 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -,31 +,202 @@ get_mesa_program_tgsi(struct gl_context *ctx,

 static struct gl_program *
 get_mesa_program(struct gl_context *ctx,
  struct gl_shader_program *shader_program,
  struct gl_linked_shader *shader)
 {
struct pipe_screen *pscreen = ctx->st->pipe->screen;
unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
   pscreen->get_shader_param(pscreen, ptarget, 
PIPE_SHADER_CAP_PREFERRED_IR);
+   struct gl_program *prog = NULL;
+
if (preferred_ir == PIPE_SHADER_IR_NIR) {
   /* TODO only for GLSL VS/FS for now: */
   switch (shader->Stage) {
   case MESA_SHADER_VERTEX:
   case MESA_SHADER_FRAGMENT:
- return st_nir_get_mesa_program(ctx, shader_program, shader);
+ prog = st_nir_get_mesa_program(ctx, shader_program, shader);
   default:
  break;
   }
+   } else {
+  prog = get_mesa_program_tgsi(ctx, shader_program, shader);
+   }
+
+   if (prog) {
+  uint64_t *states;
+
+  /* This determines which states will be updated when the shader is
+   * bound.
+   */
+  switch (shader->Stage) {
+  case MESA_SHADER_VERTEX:
+ states = &((struct st_vertex_program*)prog)->affected_states;
+
+ *states = ST_NEW_VS_STATE |
+   ST_NEW_RASTERIZER |
+   ST_NEW_VERTEX_ARRAYS;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_VS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_VS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_VS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_VS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_VS_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_VS_ATOMICS;


I'm not overly fond of the code duplication here. Perhaps these could 
all be expressed relative to a stage-specific base flag?


Nicolai



+ break;
+
+  case MESA_SHADER_TESS_CTRL:
+ states = &((struct st_tessctrl_program*)prog)->affected_states;
+
+ *states = ST_NEW_TCS_STATE;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_TCS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_TCS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_TCS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_TCS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_TCS_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_TCS_ATOMICS;
+ break;
+
+  case MESA_SHADER_TESS_EVAL:
+ states = &((struct st_tesseval_program*)prog)->affected_states;
+
+ *states = ST_NEW_TES_STATE |
+   ST_NEW_RASTERIZER;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_TES_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_TES_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_TES_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_TES_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_TES_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_TES_ATOMICS;
+ break;
+
+  case MESA_SHADER_GEOMETRY:
+ states = &((struct st_geometry_program*)prog)->affected_states;
+
+ *states = ST_NEW_GS_STATE |
+   ST_NEW_RASTERIZER;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_GS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_GS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_GS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_GS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+ 

[Mesa-dev] [PATCH 4/8] st/mesa: determine states used or affected by shaders at compile time

2016-08-06 Thread Marek Olšák
From: Marek Olšák 

At compile time, each shader determines which ST_NEW flags should be set
at shader bind time.

This just sets the new field for all shaders. The next commit will use it.
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 175 -
 src/mesa/state_tracker/st_program.c|  37 +-
 src/mesa/state_tracker/st_program.h|   6 +
 3 files changed, 215 insertions(+), 3 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 362559f..fd14766 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -,31 +,202 @@ get_mesa_program_tgsi(struct gl_context *ctx,
 
 static struct gl_program *
 get_mesa_program(struct gl_context *ctx,
  struct gl_shader_program *shader_program,
  struct gl_linked_shader *shader)
 {
struct pipe_screen *pscreen = ctx->st->pipe->screen;
unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage);
enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir)
   pscreen->get_shader_param(pscreen, ptarget, 
PIPE_SHADER_CAP_PREFERRED_IR);
+   struct gl_program *prog = NULL;
+
if (preferred_ir == PIPE_SHADER_IR_NIR) {
   /* TODO only for GLSL VS/FS for now: */
   switch (shader->Stage) {
   case MESA_SHADER_VERTEX:
   case MESA_SHADER_FRAGMENT:
- return st_nir_get_mesa_program(ctx, shader_program, shader);
+ prog = st_nir_get_mesa_program(ctx, shader_program, shader);
   default:
  break;
   }
+   } else {
+  prog = get_mesa_program_tgsi(ctx, shader_program, shader);
+   }
+
+   if (prog) {
+  uint64_t *states;
+
+  /* This determines which states will be updated when the shader is
+   * bound.
+   */
+  switch (shader->Stage) {
+  case MESA_SHADER_VERTEX:
+ states = &((struct st_vertex_program*)prog)->affected_states;
+
+ *states = ST_NEW_VS_STATE |
+   ST_NEW_RASTERIZER |
+   ST_NEW_VERTEX_ARRAYS;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_VS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_VS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_VS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_VS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_VS_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_VS_ATOMICS;
+ break;
+
+  case MESA_SHADER_TESS_CTRL:
+ states = &((struct st_tessctrl_program*)prog)->affected_states;
+
+ *states = ST_NEW_TCS_STATE;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_TCS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_TCS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_TCS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_TCS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_TCS_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_TCS_ATOMICS;
+ break;
+
+  case MESA_SHADER_TESS_EVAL:
+ states = &((struct st_tesseval_program*)prog)->affected_states;
+
+ *states = ST_NEW_TES_STATE |
+   ST_NEW_RASTERIZER;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_TES_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_TES_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_TES_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_TES_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_TES_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_TES_ATOMICS;
+ break;
+
+  case MESA_SHADER_GEOMETRY:
+ states = &((struct st_geometry_program*)prog)->affected_states;
+
+ *states = ST_NEW_GS_STATE |
+   ST_NEW_RASTERIZER;
+
+ if (prog->Parameters->NumParameters)
+*states |= ST_NEW_GS_CONSTANTS;
+
+ if (shader->num_samplers)
+*states |= ST_NEW_GS_SAMPLER_VIEWS |
+   ST_NEW_RENDER_SAMPLERS;
+
+ if (shader->NumImages)
+*states |= ST_NEW_GS_IMAGES;
+
+ if (shader->NumUniformBlocks)
+*states |= ST_NEW_GS_UBOS;
+
+ if (shader->NumShaderStorageBlocks)
+*states |= ST_NEW_GS_SSBOS;
+
+ if (shader->NumAtomicBuffers)
+*states |= ST_NEW_GS_ATOMICS;
+ break;
+
+  case MESA_SHADER_FRAGMENT:
+