diff options
Diffstat (limited to 'src/mesa/state_tracker/st_program.c')
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index b2d15863b19..3795f25a74e 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -62,6 +62,147 @@ +static void +set_affected_state_flags(uint64_t *states, + struct gl_program *prog, + 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 (prog->info.num_textures) + *states |= new_sampler_views | new_samplers; + + if (prog->info.num_images) + *states |= new_images; + + if (prog->info.num_ubos) + *states |= new_ubos; + + if (prog->info.num_ssbos) + *states |= new_ssbos; + + if (prog->info.num_abos) + *states |= new_atomics; +} + +/** + * This determines which states will be updated when the shader is bound. + */ +void +st_set_prog_affected_state_flags(struct gl_program *prog) +{ + uint64_t *states; + + switch (prog->info.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; + + set_affected_state_flags(states, prog, + ST_NEW_VS_CONSTANTS, + ST_NEW_VS_SAMPLER_VIEWS, + ST_NEW_RENDER_SAMPLERS, + ST_NEW_VS_IMAGES, + ST_NEW_VS_UBOS, + ST_NEW_VS_SSBOS, + ST_NEW_VS_ATOMICS); + break; + + case MESA_SHADER_TESS_CTRL: + states = &((struct st_tessctrl_program*)prog)->affected_states; + + *states = ST_NEW_TCS_STATE; + + set_affected_state_flags(states, prog, + ST_NEW_TCS_CONSTANTS, + ST_NEW_TCS_SAMPLER_VIEWS, + ST_NEW_RENDER_SAMPLERS, + ST_NEW_TCS_IMAGES, + ST_NEW_TCS_UBOS, + ST_NEW_TCS_SSBOS, + 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; + + set_affected_state_flags(states, prog, + ST_NEW_TES_CONSTANTS, + ST_NEW_TES_SAMPLER_VIEWS, + ST_NEW_RENDER_SAMPLERS, + ST_NEW_TES_IMAGES, + ST_NEW_TES_UBOS, + ST_NEW_TES_SSBOS, + 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; + + set_affected_state_flags(states, prog, + ST_NEW_GS_CONSTANTS, + ST_NEW_GS_SAMPLER_VIEWS, + ST_NEW_RENDER_SAMPLERS, + ST_NEW_GS_IMAGES, + ST_NEW_GS_UBOS, + ST_NEW_GS_SSBOS, + ST_NEW_GS_ATOMICS); + break; + + case MESA_SHADER_FRAGMENT: + states = &((struct st_fragment_program*)prog)->affected_states; + + /* gl_FragCoord and glDrawPixels always use constants. */ + *states = ST_NEW_FS_STATE | + ST_NEW_SAMPLE_SHADING | + ST_NEW_FS_CONSTANTS; + + set_affected_state_flags(states, prog, + ST_NEW_FS_CONSTANTS, + ST_NEW_FS_SAMPLER_VIEWS, + ST_NEW_RENDER_SAMPLERS, + ST_NEW_FS_IMAGES, + ST_NEW_FS_UBOS, + ST_NEW_FS_SSBOS, + ST_NEW_FS_ATOMICS); + break; + + case MESA_SHADER_COMPUTE: + states = &((struct st_compute_program*)prog)->affected_states; + + *states = ST_NEW_CS_STATE; + + set_affected_state_flags(states, prog, + ST_NEW_CS_CONSTANTS, + ST_NEW_CS_SAMPLER_VIEWS, + ST_NEW_CS_SAMPLERS, + ST_NEW_CS_IMAGES, + ST_NEW_CS_UBOS, + ST_NEW_CS_SSBOS, + ST_NEW_CS_ATOMICS); + break; + + default: + unreachable("unhandled shader stage"); + } +} + /** * Delete a vertex program variant. Note the caller must unlink * the variant from the linked list. |