Am Sonntag, den 26.03.2017, 16:13 +0200 schrieb Christian Gmeiner: > Signed-off-by: Christian Gmeiner <christian.gmei...@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; > + }; > +};
There should probably be an assert somewhere in the code, which checks that sizeof(struct etna_shader_key) <= sizeof(etna_shader_key.global), to avoid the key getting ambiguous by overflowing global size. > + > +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); > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev