diff options
author | Rob Clark <[email protected]> | 2014-02-23 14:40:41 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2014-03-02 11:26:35 -0500 |
commit | 26530716ab9398703f91285381033073f47e8bd4 (patch) | |
tree | b7d4c19fd40f508083ca0a9a86a9c07bac8ff122 /src/gallium/drivers/freedreno/a3xx | |
parent | 8dd70125fc5ea45b206df50bac00f15d6e5da38c (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.c | 47 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_compiler_old.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_program.c | 13 |
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; } |