diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_compiler.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_shader.c | 49 | ||||
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_shader.h | 12 |
3 files changed, 60 insertions, 4 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler.h b/src/gallium/drivers/etnaviv/etnaviv_compiler.h index 2a3b4f4f4ee..8de01264a9b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler.h +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler.h @@ -92,6 +92,9 @@ struct etna_shader_variant { /* unknown input property (XX_INPUT_COUNT, field UNK8) */ uint32_t input_count_unk8; + + /* shader variants form a linked list */ + struct etna_shader_variant *next; }; struct etna_varying { diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.c b/src/gallium/drivers/etnaviv/etnaviv_shader.c index 35084e54848..0ef611fdff9 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_shader.c +++ b/src/gallium/drivers/etnaviv/etnaviv_shader.c @@ -31,6 +31,7 @@ #include "etnaviv_debug.h" #include "etnaviv_util.h" +#include "tgsi/tgsi_parse.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -266,25 +267,65 @@ etna_shader_update_vertex(struct etna_context *ctx) ctx->vertex_elements); } +static struct etna_shader_variant * +create_variant(struct etna_shader *shader) +{ + struct etna_shader_variant *v; + + v = etna_compile_shader(shader->specs, shader->tokens); + if (!v) { + debug_error("compile failed!"); + return NULL; + } + + v->id = ++shader->variant_count; + + return v; +} + static void * etna_create_shader_state(struct pipe_context *pctx, const struct pipe_shader_state *pss) { struct etna_context *ctx = etna_context(pctx); - struct etna_shader_variant *shader = etna_compile_shader(&ctx->specs, pss->tokens); + struct etna_shader *shader = CALLOC_STRUCT(etna_shader); + + if (!shader) + return NULL; static uint32_t id; shader->id = id++; + shader->specs = &ctx->specs; + shader->tokens = tgsi_dup_tokens(pss->tokens); - dump_shader_info(shader, &ctx->debug); + /* compile new variant */ + struct etna_shader_variant *v; - return shader; + v = create_variant(shader); + if (v) { + v->next = shader->variants; + shader->variants = v; + dump_shader_info(v, &ctx->debug); + } + + return v; } static void etna_delete_shader_state(struct pipe_context *pctx, void *ss) { - etna_destroy_shader(ss); + struct etna_shader *shader = ss; + struct etna_shader_variant *v, *t; + + v = shader->variants; + while (v) { + t = v; + v = v->next; + etna_destroy_shader(t); + } + + FREE(shader->tokens); + FREE(shader); } static void diff --git a/src/gallium/drivers/etnaviv/etnaviv_shader.h b/src/gallium/drivers/etnaviv/etnaviv_shader.h index 1dbd2006579..c613c17df0a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_shader.h +++ b/src/gallium/drivers/etnaviv/etnaviv_shader.h @@ -30,6 +30,18 @@ #include "pipe/p_state.h" struct etna_context; +struct etna_shader_variant; + +struct etna_shader { + /* shader id (for debug): */ + uint32_t id; + uint32_t variant_count; + + struct tgsi_token *tokens; + struct etna_specs *specs; + + struct etna_shader_variant *variants; +}; bool etna_shader_link(struct etna_context *ctx); |