summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/ilo/ilo_shader.c42
-rw-r--r--src/gallium/drivers/ilo/ilo_shader.h5
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c92
-rw-r--r--src/gallium/drivers/ilo/shader/ilo_shader_internal.h2
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 0f22ebb4dd8..4d63ec69098 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 5e457b91e11..4413c59e119 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 69fe3833793..58894f288ff 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 a73b3393fe3..1723bd19ded 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;