etnaviv: add etna_shader_key and generate variants if needed
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
parent
9da54fdcb5
commit
7d2a806266
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -80,6 +80,7 @@ struct etna_vertexbuf_state {
|
|||
};
|
||||
|
||||
struct etna_shader_state {
|
||||
void *bind_vs, *bind_fs;
|
||||
struct etna_shader_variant *vs, *fs;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue