r600: add shader key entries for tcs and tes.
authorDave Airlie <airlied@redhat.com>
Mon, 30 Nov 2015 00:45:19 +0000 (10:45 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 6 Dec 2015 23:58:59 +0000 (09:58 +1000)
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 <airlied@redhat.com>
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h
src/gallium/drivers/r600/r600_state_common.c

index 13b6918..b7845b5 100644 (file)
@@ -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);
index 041803d..83f104a 100644 (file)
@@ -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;
index 4142c3e..84bacb2 100644 (file)
@@ -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;
index 2040f73..398e7da 100644 (file)
 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 {
index 05afa23..961609a 100644 (file)
@@ -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);
        }