summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a3xx
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-02-23 14:40:41 -0500
committerRob Clark <[email protected]>2014-03-02 11:26:35 -0500
commit26530716ab9398703f91285381033073f47e8bd4 (patch)
treeb7d4c19fd40f508083ca0a9a86a9c07bac8ff122 /src/gallium/drivers/freedreno/a3xx
parent8dd70125fc5ea45b206df50bac00f15d6e5da38c (diff)
freedreno/lowering: two-sided-color
Add option to generate fragment shader to emulate two sided color. Additional inputs are added to shader for BCOLOR's (on corresponding to each COLOR input). CMP instructions are used to select whether to use COLOR or BCOLOR. Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_compiler.c47
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c2
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c13
3 files changed, 46 insertions, 16 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
index ae88d6ef54d..7450fac23c1 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
@@ -152,6 +152,7 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_variant *so,
unsigned ret;
struct tgsi_shader_info *info = &ctx->info;
const struct fd_lowering_config lconfig = {
+ .color_two_side = so->key.color_two_side,
.lower_DST = true,
.lower_XPD = true,
.lower_SCS = true,
@@ -2003,6 +2004,7 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
so->writes_psize = true;
break;
case TGSI_SEMANTIC_COLOR:
+ case TGSI_SEMANTIC_BCOLOR:
case TGSI_SEMANTIC_GENERIC:
case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_TEXCOORD:
@@ -2059,24 +2061,31 @@ fixup_frag_inputs(struct fd3_compile_context *ctx)
{
struct fd3_shader_variant *so = ctx->so;
struct ir3_block *block = ctx->block;
+ struct ir3_instruction **inputs;
struct ir3_instruction *instr;
- int regid = 0;
+ int n, regid = 0;
block->ninputs = 0;
+ n = 4; /* always have frag_pos */
+ n += COND(so->frag_face, 4);
+ n += COND(so->frag_coord, 4);
+
+ inputs = ir3_alloc(ctx->ir, n * (sizeof(struct ir3_instruction *)));
+
if (so->frag_face) {
/* this ultimately gets assigned to hr0.x so doesn't conflict
* with frag_coord/frag_pos..
*/
- block->inputs[block->ninputs++] = ctx->frag_face;
+ inputs[block->ninputs++] = ctx->frag_face;
ctx->frag_face->regs[0]->num = 0;
/* remaining channels not used, but let's avoid confusing
* other parts that expect inputs to come in groups of vec4
*/
- block->inputs[block->ninputs++] = NULL;
- block->inputs[block->ninputs++] = NULL;
- block->inputs[block->ninputs++] = NULL;
+ inputs[block->ninputs++] = NULL;
+ inputs[block->ninputs++] = NULL;
+ inputs[block->ninputs++] = NULL;
}
/* since we don't know where to set the regid for frag_coord,
@@ -2090,10 +2099,10 @@ fixup_frag_inputs(struct fd3_compile_context *ctx)
ctx->frag_coord[2]->regs[0]->num = regid++;
ctx->frag_coord[3]->regs[0]->num = regid++;
- block->inputs[block->ninputs++] = ctx->frag_coord[0];
- block->inputs[block->ninputs++] = ctx->frag_coord[1];
- block->inputs[block->ninputs++] = ctx->frag_coord[2];
- block->inputs[block->ninputs++] = ctx->frag_coord[3];
+ inputs[block->ninputs++] = ctx->frag_coord[0];
+ inputs[block->ninputs++] = ctx->frag_coord[1];
+ inputs[block->ninputs++] = ctx->frag_coord[2];
+ inputs[block->ninputs++] = ctx->frag_coord[3];
}
/* we always have frag_pos: */
@@ -2102,14 +2111,16 @@ fixup_frag_inputs(struct fd3_compile_context *ctx)
/* r0.x */
instr = create_input(block, NULL, block->ninputs);
instr->regs[0]->num = regid++;
- block->inputs[block->ninputs++] = instr;
+ inputs[block->ninputs++] = instr;
ctx->frag_pos->regs[1]->instr = instr;
/* r0.y */
instr = create_input(block, NULL, block->ninputs);
instr->regs[0]->num = regid++;
- block->inputs[block->ninputs++] = instr;
+ inputs[block->ninputs++] = instr;
ctx->frag_pos->regs[2]->instr = instr;
+
+ block->inputs = inputs;
}
static void
@@ -2189,10 +2200,6 @@ compile_instructions(struct fd3_compile_context *ctx)
break;
}
}
-
- /* fixup actual inputs for frag shader: */
- if (ctx->type == TGSI_PROCESSOR_FRAGMENT)
- fixup_frag_inputs(ctx);
}
static void
@@ -2217,6 +2224,7 @@ fd3_compile_shader(struct fd3_shader_variant *so,
{
struct fd3_compile_context ctx;
struct ir3_block *block;
+ struct ir3_instruction **inputs;
unsigned i, j, actual_in;
int ret = 0;
@@ -2235,6 +2243,13 @@ fd3_compile_shader(struct fd3_shader_variant *so,
block = ctx.block;
+ /* keep track of the inputs from TGSI perspective.. */
+ inputs = block->inputs;
+
+ /* but fixup actual inputs for frag shader: */
+ if (ctx.type == TGSI_PROCESSOR_FRAGMENT)
+ fixup_frag_inputs(&ctx);
+
/* at this point, for binning pass, throw away unneeded outputs: */
if (key.binning_pass) {
for (i = 0, j = 0; i < so->outputs_count; i++) {
@@ -2320,7 +2335,7 @@ fd3_compile_shader(struct fd3_shader_variant *so,
for (i = 0; i < so->inputs_count; i++) {
unsigned j, regid = ~0, compmask = 0;
for (j = 0; j < 4; j++) {
- struct ir3_instruction *in = block->inputs[(i*4) + j];
+ struct ir3_instruction *in = inputs[(i*4) + j];
if (in) {
compmask |= (1 << j);
regid = in->regs[0]->num - j;
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c
index 9a0bbb5edff..76de287b163 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c
@@ -126,6 +126,7 @@ compile_init(struct fd3_compile_context *ctx, struct fd3_shader_variant *so,
unsigned ret, base = 0;
struct tgsi_shader_info *info = &ctx->info;
const struct fd_lowering_config lconfig = {
+ .color_two_side = so->key.color_two_side,
.lower_DST = true,
.lower_XPD = true,
.lower_SCS = true,
@@ -1383,6 +1384,7 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
so->writes_psize = true;
break;
case TGSI_SEMANTIC_COLOR:
+ case TGSI_SEMANTIC_BCOLOR:
case TGSI_SEMANTIC_GENERIC:
case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_TEXCOORD:
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
index 4cdd9387f9d..a84351ae887 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
@@ -284,9 +284,22 @@ static int
find_output(const struct fd3_shader_variant *so, fd3_semantic semantic)
{
int j;
+
for (j = 0; j < so->outputs_count; j++)
if (so->outputs[j].semantic == semantic)
return j;
+
+ /* it seems optional to have a OUT.BCOLOR[n] for each OUT.COLOR[n]
+ * in the vertex shader.. but the fragment shader doesn't know this
+ * so it will always have both IN.COLOR[n] and IN.BCOLOR[n]. So
+ * at link time if there is no matching OUT.BCOLOR[n], we must map
+ * OUT.COLOR[n] to IN.BCOLOR[n].
+ */
+ if (sem2name(semantic) == TGSI_SEMANTIC_BCOLOR) {
+ unsigned idx = sem2idx(semantic);
+ return find_output(so, fd3_semantic_name(TGSI_SEMANTIC_COLOR, idx));
+ }
+
return 0;
}