etnaviv: add etna_shader_key and generate variants if needed

Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
Christian Gmeiner 2017-03-19 17:19:10 +01:00
parent 9da54fdcb5
commit 7d2a806266
8 changed files with 97 additions and 29 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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 {

View File

@ -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");

View File

@ -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;

View File

@ -80,6 +80,7 @@ struct etna_vertexbuf_state {
};
struct etna_shader_state {
void *bind_vs, *bind_fs;
struct etna_shader_variant *vs, *fs;
};

View File

@ -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;
}

View File

@ -32,6 +32,23 @@
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)
{
STATIC_ASSERT(sizeof(struct etna_shader_key) <= sizeof(a->global));
return a->global == b->global;
}
struct etna_shader {
/* shader id (for debug): */
uint32_t id;
@ -49,6 +66,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);