[PATCH 07/11] etnaviv: add etna_shader_key and generate variants if needed
Christian Gmeiner
christian.gmeiner at gmail.com
Sun Mar 26 14:13:11 UTC 2017
Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
---
src/gallium/drivers/etnaviv/etnaviv_clear_blit.c | 4 +-
src/gallium/drivers/etnaviv/etnaviv_compiler.c | 4 +-
src/gallium/drivers/etnaviv/etnaviv_compiler.h | 2 +
.../drivers/etnaviv/etnaviv_compiler_cmdline.c | 2 +
src/gallium/drivers/etnaviv/etnaviv_context.c | 38 +++++++++++++++
src/gallium/drivers/etnaviv/etnaviv_context.h | 1 +
src/gallium/drivers/etnaviv/etnaviv_shader.c | 54 +++++++++++-----------
src/gallium/drivers/etnaviv/etnaviv_shader.h | 19 ++++++++
8 files changed, 95 insertions(+), 29 deletions(-)
diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
index 35d635f..4a03d82 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
@@ -49,11 +49,11 @@ etna_blit_save_state(struct etna_context *ctx)
{
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertex_buffer.vb);
util_blitter_save_vertex_elements(ctx->blitter, ctx->vertex_elements);
- util_blitter_save_vertex_shader(ctx->blitter, ctx->shader.vs);
+ util_blitter_save_vertex_shader(ctx->blitter, ctx->shader.bind_vs);
util_blitter_save_rasterizer(ctx->blitter, ctx->rasterizer);
util_blitter_save_viewport(ctx->blitter, &ctx->viewport_s);
util_blitter_save_scissor(ctx->blitter, &ctx->scissor_s);
- util_blitter_save_fragment_shader(ctx->blitter, ctx->shader.fs);
+ util_blitter_save_fragment_shader(ctx->blitter, ctx->shader.bind_fs);
util_blitter_save_blend(ctx->blitter, ctx->blend);
util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->zsa);
util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref_s);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.c b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
index 7552a8f..ce8a651 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.c
@@ -54,7 +54,6 @@
#include "etnaviv_context.h"
#include "etnaviv_debug.h"
#include "etnaviv_disasm.h"
-#include "etnaviv_shader.h"
#include "etnaviv_uniforms.h"
#include "etnaviv_util.h"
@@ -197,6 +196,8 @@ struct etna_compile {
/* GPU hardware specs */
const struct etna_specs *specs;
+
+ const struct etna_shader_key *key;
};
static struct etna_reg_desc *
@@ -2287,6 +2288,7 @@ etna_compile_shader(struct etna_shader_variant *v)
const struct tgsi_token *tokens = v->shader->tokens;
c->specs = specs;
+ c->key = &v->key;
c->tokens = tgsi_transform_lowering(&lconfig, tokens, &c->info);
c->free_tokens = !!c->tokens;
if (!c->tokens) {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.h b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
index 8582e30..88a093f 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.h
@@ -29,6 +29,7 @@
#include "etnaviv_context.h"
#include "etnaviv_internal.h"
+#include "etnaviv_shader.h"
#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
@@ -98,6 +99,7 @@ struct etna_shader_variant {
/* replicated here to avoid passing extra ptrs everywhere */
struct etna_shader *shader;
+ struct etna_shader_key key;
};
struct etna_varying {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_cmdline.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_cmdline.c
index 035ee86..1fea2d1 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_compiler_cmdline.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_cmdline.c
@@ -102,6 +102,7 @@ main(int argc, char **argv)
struct tgsi_token toks[65536];
struct tgsi_parse_context parse;
struct etna_shader s = {};
+ struct etna_shader_key key = {};
void *ptr;
size_t size;
@@ -147,6 +148,7 @@ main(int argc, char **argv)
s.tokens = toks;
v->shader = &s;
+ v->key = key;
if (!etna_compile_shader(v)) {
fprintf(stderr, "compiler failed!\n");
diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c
index dfd9e1f..d673440 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -106,6 +106,37 @@ etna_update_state_for_draw(struct etna_context *ctx, const struct pipe_draw_info
}
}
+static bool
+etna_get_vs(struct etna_context *ctx, struct etna_shader_key key)
+{
+ const struct etna_shader_variant *old = ctx->shader.vs;
+
+ ctx->shader.vs = etna_shader_variant(ctx->shader.bind_vs, key, &ctx->debug);
+
+ if (!ctx->shader.vs)
+ return false;
+
+ if (old != ctx->shader.vs)
+ ctx->dirty |= ETNA_DIRTY_SHADER;
+
+ return true;
+}
+
+static bool
+etna_get_fs(struct etna_context *ctx, struct etna_shader_key key)
+{
+ const struct etna_shader_variant *old = ctx->shader.fs;
+
+ ctx->shader.fs = etna_shader_variant(ctx->shader.bind_fs, key, &ctx->debug);
+
+ if (!ctx->shader.fs)
+ return false;
+
+ if (old != ctx->shader.fs)
+ ctx->dirty |= ETNA_DIRTY_SHADER;
+
+ return true;
+}
static void
etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
@@ -152,6 +183,13 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
return;
}
+ struct etna_shader_key key = {};
+
+ if (!etna_get_vs(ctx, key) || !etna_get_fs(ctx, key)) {
+ BUG("compiled shaders are not okay");
+ return;
+ }
+
/* Update any derived state */
if (!etna_state_update(ctx))
return;
diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.h b/src/gallium/drivers/etnaviv/etnaviv_context.h
index b847b65..9e00d34 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.h
@@ -80,6 +80,7 @@ struct etna_vertexbuf_state {
};
struct etna_shader_state {
+ void *bind_vs, *bind_fs;
struct etna_shader_variant *vs, *fs;
};
diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.c b/src/gallium/drivers/etnaviv/etnaviv_shader.c
index 8132bc8..a5f9315 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_shader.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_shader.c
@@ -268,7 +268,7 @@ etna_shader_update_vertex(struct etna_context *ctx)
}
static struct etna_shader_variant *
-create_variant(struct etna_shader *shader)
+create_variant(struct etna_shader *shader, struct etna_shader_key key)
{
struct etna_shader_variant *v = CALLOC_STRUCT(etna_shader_variant);
int ret;
@@ -277,6 +277,7 @@ create_variant(struct etna_shader *shader)
return NULL;
v->shader = shader;
+ v->key = key;
ret = etna_compile_shader(v);
if (!ret) {
@@ -293,6 +294,27 @@ fail:
return NULL;
}
+struct etna_shader_variant *
+etna_shader_variant(struct etna_shader *shader, struct etna_shader_key key,
+ struct pipe_debug_callback *debug)
+{
+ struct etna_shader_variant *v;
+
+ for (v = shader->variants; v; v = v->next)
+ if (etna_shader_key_equal(&key, &v->key))
+ return v;
+
+ /* compile new variant if it doesn't exist already */
+ v = create_variant(shader, key);
+ if (v) {
+ v->next = shader->variants;
+ shader->variants = v;
+ dump_shader_info(v, debug);
+ }
+
+ return v;
+}
+
static void *
etna_create_shader_state(struct pipe_context *pctx,
const struct pipe_shader_state *pss)
@@ -308,17 +330,7 @@ etna_create_shader_state(struct pipe_context *pctx,
shader->specs = &ctx->specs;
shader->tokens = tgsi_dup_tokens(pss->tokens);
- /* compile new variant */
- struct etna_shader_variant *v;
-
- v = create_variant(shader);
- if (v) {
- v->next = shader->variants;
- shader->variants = v;
- dump_shader_info(v, &ctx->debug);
- }
-
- return v;
+ return shader;
}
static void
@@ -339,30 +351,20 @@ etna_delete_shader_state(struct pipe_context *pctx, void *ss)
}
static void
-etna_bind_fs_state(struct pipe_context *pctx, void *fss_)
+etna_bind_fs_state(struct pipe_context *pctx, void *hwcso)
{
struct etna_context *ctx = etna_context(pctx);
- struct etna_shader_variant *fss = fss_;
-
- if (ctx->shader.fs == fss) /* skip if already bound */
- return;
- assert(fss == NULL || fss->processor == PIPE_SHADER_FRAGMENT);
- ctx->shader.fs = fss;
+ ctx->shader.bind_fs = hwcso;
ctx->dirty |= ETNA_DIRTY_SHADER;
}
static void
-etna_bind_vs_state(struct pipe_context *pctx, void *vss_)
+etna_bind_vs_state(struct pipe_context *pctx, void *hwcso)
{
struct etna_context *ctx = etna_context(pctx);
- struct etna_shader_variant *vss = vss_;
-
- if (ctx->shader.vs == vss) /* skip if already bound */
- return;
- assert(vss == NULL || vss->processor == PIPE_SHADER_VERTEX);
- ctx->shader.vs = vss;
+ ctx->shader.bind_vs = hwcso;
ctx->dirty |= ETNA_DIRTY_SHADER;
}
diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.h b/src/gallium/drivers/etnaviv/etnaviv_shader.h
index 9f26bef..b0d97a7 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_shader.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_shader.h
@@ -32,6 +32,21 @@
struct etna_context;
struct etna_shader_variant;
+struct etna_shader_key
+{
+ union {
+ struct {
+ };
+ uint32_t global;
+ };
+};
+
+static inline bool
+etna_shader_key_equal(struct etna_shader_key *a, struct etna_shader_key *b)
+{
+ return a->global == b->global;
+}
+
struct etna_shader {
/* shader id (for debug): */
uint32_t id;
@@ -49,6 +64,10 @@ etna_shader_link(struct etna_context *ctx);
bool
etna_shader_update_vertex(struct etna_context *ctx);
+struct etna_shader_variant *
+etna_shader_variant(struct etna_shader *shader, struct etna_shader_key key,
+ struct pipe_debug_callback *debug);
+
void
etna_shader_init(struct pipe_context *pctx);
--
2.9.3
More information about the etnaviv
mailing list