summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2015-11-30 10:45:19 +1000
committerDave Airlie <[email protected]>2015-12-07 09:58:59 +1000
commitb1da110b71b20509e4689475e82e88750f69b8fc (patch)
tree078bd6fd8dd3b5ce39ba61d270d957c2892142de /src/gallium/drivers
parenta131ac73e6e653962723669dd5403fff061aa90f (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c4
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h4
-rw-r--r--src/gallium/drivers/r600/r600_shader.c13
-rw-r--r--src/gallium/drivers/r600/r600_shader.h20
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c11
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 13b69184a5b..b7845b5c19d 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 041803df2ee..83f104ad3b5 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 4142c3e30e5..84bacb20368 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 2040f732bf5..398e7da7666 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 05afa23907a..961609a2e5f 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);
}