From 96e2133e72ec0fb6173b79838f1a7d153b8f25b6 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 20 Jun 2013 12:57:42 +0800 Subject: [PATCH] ilo: clean up finalize_shader_states() Add ilo_shader_select_kernel() to replace the dependency table, ilo_shader_variant_init(), and ilo_shader_state_use_variant(). With the changes, we no longer need to include ilo_shader_internal.h in ilo_state.c. --- src/gallium/drivers/ilo/ilo_shader.c | 42 ++++++++++ src/gallium/drivers/ilo/ilo_shader.h | 5 ++ src/gallium/drivers/ilo/ilo_state.c | 92 +++++++--------------- .../drivers/ilo/shader/ilo_shader_internal.h | 2 + 4 files changed, 79 insertions(+), 62 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c index 0f22ebb..4d63ec6 100644 --- a/src/gallium/drivers/ilo/ilo_shader.c +++ b/src/gallium/drivers/ilo/ilo_shader.c @@ -29,6 +29,7 @@ #include "intel_winsys.h" #include "shader/ilo_shader_internal.h" +#include "ilo_state.h" #include "ilo_shader.h" struct ilo_shader_cache { @@ -687,6 +688,10 @@ ilo_shader_create_vs(const struct ilo_dev_info *dev, shader = ilo_shader_state_create(precompile, PIPE_SHADER_VERTEX, state); + /* states used in ilo_shader_variant_init() */ + shader->info.non_orthogonal_states = ILO_DIRTY_VERTEX_SAMPLER_VIEWS | + ILO_DIRTY_RASTERIZER; + return shader; } @@ -699,6 +704,11 @@ ilo_shader_create_gs(const struct ilo_dev_info *dev, shader = ilo_shader_state_create(precompile, PIPE_SHADER_GEOMETRY, state); + /* states used in ilo_shader_variant_init() */ + shader->info.non_orthogonal_states = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS | + ILO_DIRTY_VS | + ILO_DIRTY_RASTERIZER; + return shader; } @@ -711,6 +721,11 @@ ilo_shader_create_fs(const struct ilo_dev_info *dev, shader = ilo_shader_state_create(precompile, PIPE_SHADER_FRAGMENT, state); + /* states used in ilo_shader_variant_init() */ + shader->info.non_orthogonal_states = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS | + ILO_DIRTY_RASTERIZER | + ILO_DIRTY_FRAMEBUFFER; + return shader; } @@ -723,6 +738,8 @@ ilo_shader_create_cs(const struct ilo_dev_info *dev, shader = ilo_shader_state_create(precompile, PIPE_SHADER_COMPUTE, state); + shader->info.non_orthogonal_states = 0; + return shader; } @@ -740,3 +757,28 @@ ilo_shader_destroy(struct ilo_shader_state *shader) FREE((struct tgsi_token *) shader->info.tokens); FREE(shader); } + +/** + * Select a kernel for the given context. This will compile a new kernel if + * none of the existing kernels work with the context. + * + * \param ilo the context + * \param dirty states of the context that are considered changed + * \return true if a different kernel is selected + */ +bool +ilo_shader_select_kernel(struct ilo_shader_state *shader, + const struct ilo_context *ilo, + uint32_t dirty) +{ + const struct ilo_shader * const cur = shader->shader; + struct ilo_shader_variant variant; + + if (!(shader->info.non_orthogonal_states & dirty)) + return false; + + ilo_shader_variant_init(&variant, &shader->info, ilo); + ilo_shader_state_use_variant(shader, &variant); + + return (shader->shader != cur); +} diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h index 5e457b9..4413c59 100644 --- a/src/gallium/drivers/ilo/ilo_shader.h +++ b/src/gallium/drivers/ilo/ilo_shader.h @@ -77,4 +77,9 @@ ilo_shader_create_cs(const struct ilo_dev_info *dev, void ilo_shader_destroy(struct ilo_shader_state *shader); +bool +ilo_shader_select_kernel(struct ilo_shader_state *shader, + const struct ilo_context *ilo, + uint32_t dirty); + #endif /* ILO_SHADER_H */ diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 69fe383..58894f2 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -28,82 +28,50 @@ #include "util/u_framebuffer.h" #include "util/u_helpers.h" -#include "shader/ilo_shader_internal.h" #include "ilo_context.h" #include "ilo_resource.h" #include "ilo_shader.h" #include "ilo_state.h" -/* - * We simply remember the pipe states here and derive HW commands/states from - * them later. We could do better by deriving (some of the) HW - * commands/states directly. - */ - static void finalize_shader_states(struct ilo_context *ilo) { - /* this table is ugly and is a burden to maintain.. */ - const struct { - struct ilo_shader_state *state; - struct ilo_shader *prev_shader; - uint32_t dirty; - uint32_t deps; - } sh[PIPE_SHADER_TYPES] = { - [PIPE_SHADER_VERTEX] = { - .state = ilo->vs, - .prev_shader = (ilo->vs) ? ilo->vs->shader : NULL, - .dirty = ILO_DIRTY_VS, - .deps = ILO_DIRTY_VERTEX_SAMPLER_VIEWS | - ILO_DIRTY_RASTERIZER, - }, - [PIPE_SHADER_FRAGMENT] = { - .state = ilo->fs, - .prev_shader = (ilo->fs) ? ilo->fs->shader : NULL, - .dirty = ILO_DIRTY_FS, - .deps = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS | - ILO_DIRTY_RASTERIZER | - ILO_DIRTY_FRAMEBUFFER, - }, - [PIPE_SHADER_GEOMETRY] = { - .state = ilo->gs, - .prev_shader = (ilo->gs) ? ilo->gs->shader : NULL, - .dirty = ILO_DIRTY_GS, - .deps = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS | - ILO_DIRTY_VS | - ILO_DIRTY_RASTERIZER, - }, - [PIPE_SHADER_COMPUTE] = { - .state = NULL, - .prev_shader = NULL, - .dirty = 0, - .deps = 0, - }, - }; - int i; - - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - /* no state bound */ - if (!sh[i].state) - continue; + unsigned type; - /* switch variant if the shader or the states it depends on changed */ - if (ilo->dirty & (sh[i].dirty | sh[i].deps)) { - struct ilo_shader_variant variant; + for (type = 0; type < PIPE_SHADER_TYPES; type++) { + struct ilo_shader_state *shader; + uint32_t state; - ilo_shader_variant_init(&variant, &sh[i].state->info, ilo); - ilo_shader_state_use_variant(sh[i].state, &variant); + switch (type) { + case PIPE_SHADER_VERTEX: + shader = ilo->vs; + state = ILO_DIRTY_VS; + break; + case PIPE_SHADER_GEOMETRY: + shader = ilo->gs; + state = ILO_DIRTY_GS; + break; + case PIPE_SHADER_FRAGMENT: + shader = ilo->fs; + state = ILO_DIRTY_FS; + break; + default: + shader = NULL; + state = 0; + break; } - } - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - /* no state bound */ - if (!sh[i].state) + if (!shader) continue; - /* mark the shader state dirty if new variant is selected */ - if (sh[i].state->shader != sh[i].prev_shader) - ilo->dirty |= sh[i].dirty; + /* compile if the shader or the states it depends on changed */ + if (ilo->dirty & state) { + ilo_shader_select_kernel(shader, ilo, ILO_DIRTY_ALL); + } + else if (ilo_shader_select_kernel(shader, ilo, ilo->dirty)) { + /* mark the state dirty if a new kernel is selected */ + ilo->dirty |= state; + } } } diff --git a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h index a73b339..1723bd1 100644 --- a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h +++ b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h @@ -138,6 +138,8 @@ struct ilo_shader_info { unsigned req_input_mem; } compute; + uint32_t non_orthogonal_states; + bool has_color_interp; bool has_pos; bool has_vertexid; -- 2.7.4