From b1da110b71b20509e4689475e82e88750f69b8fc Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 30 Nov 2015 10:45:19 +1000 Subject: [PATCH] r600: add shader key entries for tcs and tes. with tessellation vs can now run on ls, and tes can run on vs or es, tcs runs on hs. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/r600_hw_context.c | 4 ++++ src/gallium/drivers/r600/r600_pipe.h | 4 ++++ src/gallium/drivers/r600/r600_shader.c | 13 +++++++++++-- src/gallium/drivers/r600/r600_shader.h | 20 ++++++++++++++++++++ src/gallium/drivers/r600/r600_state_common.c | 11 ++++++++++- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 13b6918..b7845b5 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -321,6 +321,10 @@ void r600_begin_new_cs(struct r600_context *ctx) r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_GS].atom); r600_mark_atom_dirty(ctx, &ctx->gs_rings.atom); } + if (ctx->tes_shader) { + r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[EG_HW_STAGE_HS].atom); + r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[EG_HW_STAGE_LS].atom); + } r600_mark_atom_dirty(ctx, &ctx->hw_shader_stages[R600_HW_STAGE_VS].atom); r600_mark_atom_dirty(ctx, &ctx->b.streamout.enable_atom); r600_mark_atom_dirty(ctx, &ctx->b.render_cond_atom); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 041803d..83f104a 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -500,6 +500,10 @@ struct r600_context { struct r600_pipe_shader_selector *ps_shader; struct r600_pipe_shader_selector *vs_shader; struct r600_pipe_shader_selector *gs_shader; + + struct r600_pipe_shader_selector *tcs_shader; + struct r600_pipe_shader_selector *tes_shader; + struct r600_rasterizer_state *rasterizer; bool alpha_to_one; bool force_blend_disable; diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 4142c3e..84bacb2 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -1933,12 +1933,21 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, case TGSI_PROCESSOR_VERTEX: shader->vs_as_gs_a = key.vs.as_gs_a; shader->vs_as_es = key.vs.as_es; + shader->vs_as_ls = key.vs.as_ls; if (shader->vs_as_es) ring_outputs = true; break; case TGSI_PROCESSOR_GEOMETRY: ring_outputs = true; break; + case TGSI_PROCESSOR_TESS_CTRL: + shader->tcs_prim_mode = key.tcs.prim_mode; + break; + case TGSI_PROCESSOR_TESS_EVAL: + shader->tes_as_es = key.tes.as_es; + if (shader->tes_as_es) + ring_outputs = true; + break; case TGSI_PROCESSOR_FRAGMENT: shader->two_side = key.ps.color_two_side; break; @@ -1946,7 +1955,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, break; } - if (shader->vs_as_es) { + if (shader->vs_as_es || shader->tes_as_es) { ctx.gs_for_vs = &rctx->gs_shader->current->shader; } else { ctx.gs_for_vs = NULL; @@ -2357,7 +2366,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx, convert_edgeflag_to_int(&ctx); if (ring_outputs) { - if (shader->vs_as_es) { + if (shader->vs_as_es || shader->tes_as_es) { ctx.gs_export_gpr_tregs[0] = r600_get_temp(&ctx); ctx.gs_export_gpr_tregs[1] = -1; ctx.gs_export_gpr_tregs[2] = -1; diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 2040f73..398e7da 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -30,6 +30,16 @@ extern "C" { #endif +/* Valid shader configurations: + * + * API shaders VS | TCS | TES | GS |pass| PS + * are compiled as: | | | |thru| + * | | | | | + * Only VS & PS: VS | -- | -- | -- | -- | PS + * With GS: ES | -- | -- | GS | VS | PS + * With Tessel.: LS | HS | VS | -- | -- | PS + * With both: LS | HS | ES | GS | VS | PS + */ struct r600_shader_io { unsigned name; @@ -86,7 +96,10 @@ struct r600_shader { unsigned max_arrays; unsigned num_arrays; unsigned vs_as_es; + unsigned vs_as_ls; unsigned vs_as_gs_a; + unsigned tes_as_es; + unsigned tcs_prim_mode; unsigned ps_prim_id_input; struct r600_shader_array * arrays; @@ -102,8 +115,15 @@ union r600_shader_key { struct { unsigned prim_id_out:8; unsigned as_es:1; /* export shader */ + unsigned as_ls:1; /* local shader */ unsigned as_gs_a:1; } vs; + struct { + unsigned as_es:1; + } tes; + struct { + unsigned prim_mode:3; + } tcs; }; struct r600_shader_array { diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 05afa23..961609a 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -743,7 +743,10 @@ static inline union r600_shader_key r600_shader_selector_key(struct pipe_context switch (sel->type) { case PIPE_SHADER_VERTEX: { - key.vs.as_es = (rctx->gs_shader != NULL); + key.vs.as_ls = (rctx->tes_shader != NULL); + if (!key.vs.as_ls) + key.vs.as_es = (rctx->gs_shader != NULL); + if (rctx->ps_shader->current->shader.gs_prim_id_input && !rctx->gs_shader) { key.vs.as_gs_a = true; key.vs.prim_id_out = rctx->ps_shader->current->shader.input[rctx->ps_shader->current->shader.ps_prim_id_input].spi_sid; @@ -763,6 +766,12 @@ static inline union r600_shader_key r600_shader_selector_key(struct pipe_context key.ps.nr_cbufs = 2; break; } + case PIPE_SHADER_TESS_EVAL: + key.tes.as_es = (rctx->gs_shader != NULL); + break; + case PIPE_SHADER_TESS_CTRL: + key.tcs.prim_mode = rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE]; + break; default: assert(0); } -- 2.7.4