mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
cell: implement TGSI immediates in SPE code generator
This commit is contained in:
parent
af2ca5dc38
commit
5f3ec82338
1 changed files with 63 additions and 12 deletions
|
|
@ -52,7 +52,11 @@
|
|||
|
||||
|
||||
/** Set to 1 to enable debug/disassembly printfs */
|
||||
#define DISASSEM 01
|
||||
#define DISASSEM 0
|
||||
|
||||
|
||||
#define MAX_TEMPS 16
|
||||
#define MAX_IMMED 8
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -63,7 +67,10 @@ struct codegen
|
|||
int inputs_reg; /**< 1st function parameter */
|
||||
int outputs_reg; /**< 2nd function parameter */
|
||||
int constants_reg; /**< 3rd function parameter */
|
||||
int temp_regs[8][4]; /**< maps TGSI temps to SPE registers */
|
||||
int temp_regs[MAX_TEMPS][4]; /**< maps TGSI temps to SPE registers */
|
||||
int imm_regs[MAX_IMMED][4]; /**< maps TGSI immediates to SPE registers */
|
||||
|
||||
int num_imm; /**< number of immediates */
|
||||
|
||||
int one_reg; /**< register containing {1.0, 1.0, 1.0, 1.0} */
|
||||
|
||||
|
|
@ -191,7 +198,8 @@ get_src_reg(struct codegen *gen,
|
|||
}
|
||||
break;
|
||||
case TGSI_FILE_IMMEDIATE:
|
||||
/* xxx fall-through for now / fix */
|
||||
reg = gen->imm_regs[src->SrcRegister.Index][channel];
|
||||
break;
|
||||
case TGSI_FILE_CONSTANT:
|
||||
/* xxx fall-through for now / fix */
|
||||
default:
|
||||
|
|
@ -558,12 +566,53 @@ emit_instruction(struct codegen *gen,
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Emit code for a TGSI immediate value (vector of four floats).
|
||||
* This involves register allocation and initialization.
|
||||
* XXX the initialization should be done by a "prepare" stage, not
|
||||
* per quad execution!
|
||||
*/
|
||||
static boolean
|
||||
emit_immediate(struct codegen *gen, const struct tgsi_full_immediate *immed)
|
||||
{
|
||||
int ch;
|
||||
|
||||
assert(gen->num_imm < MAX_TEMPS);
|
||||
|
||||
#if DISASSEM
|
||||
printf("IMMEDIATE %d:\n", gen->num_imm);
|
||||
#endif
|
||||
|
||||
for (ch = 0; ch < 4; ch++) {
|
||||
float val = immed->u.ImmediateFloat32[ch].Float;
|
||||
int reg = spe_allocate_available_register(gen->f);
|
||||
|
||||
if (reg < 0)
|
||||
return false;
|
||||
|
||||
/* update immediate map */
|
||||
gen->imm_regs[gen->num_imm][ch] = reg;
|
||||
|
||||
/* emit initializer instruction */
|
||||
spe_load_float(gen->f, reg, val);
|
||||
#if DISASSEM
|
||||
printf("\tload\tr%d, %f\n", reg, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
gen->num_imm++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Emit "code" for a TGSI declaration.
|
||||
* We only care about TGSI TEMPORARY register declarations at this time.
|
||||
* For each TGSI TEMPORARY we allocate four SPE registers.
|
||||
*/
|
||||
static void
|
||||
static boolean
|
||||
emit_declaration(struct codegen *gen, const struct tgsi_full_declaration *decl)
|
||||
{
|
||||
int i, ch;
|
||||
|
|
@ -578,8 +627,11 @@ emit_declaration(struct codegen *gen, const struct tgsi_full_declaration *decl)
|
|||
for (i = decl->DeclarationRange.First;
|
||||
i <= decl->DeclarationRange.Last;
|
||||
i++) {
|
||||
assert(i < MAX_TEMPS);
|
||||
for (ch = 0; ch < 4; ch++) {
|
||||
gen->temp_regs[i][ch] = spe_allocate_available_register(gen->f);
|
||||
if (gen->temp_regs[i][ch] < 0)
|
||||
return false; /* out of regs */
|
||||
}
|
||||
|
||||
/* XXX if we run out of SPE registers, we need to spill
|
||||
|
|
@ -598,6 +650,8 @@ emit_declaration(struct codegen *gen, const struct tgsi_full_declaration *decl)
|
|||
default:
|
||||
; /* ignore */
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -642,25 +696,22 @@ cell_gen_fragment_program(struct cell_context *cell,
|
|||
|
||||
switch (parse.FullToken.Token.Type) {
|
||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
||||
#if 0
|
||||
if (!note_immediate(&gen, &parse.FullToken.FullImmediate ))
|
||||
goto fail;
|
||||
#endif
|
||||
if (!emit_immediate(&gen, &parse.FullToken.FullImmediate))
|
||||
gen.error = true;
|
||||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_DECLARATION:
|
||||
emit_declaration(&gen, &parse.FullToken.FullDeclaration);
|
||||
if (!emit_declaration(&gen, &parse.FullToken.FullDeclaration))
|
||||
gen.error = true;
|
||||
break;
|
||||
|
||||
case TGSI_TOKEN_TYPE_INSTRUCTION:
|
||||
if (!emit_instruction(&gen, &parse.FullToken.FullInstruction )) {
|
||||
if (!emit_instruction(&gen, &parse.FullToken.FullInstruction))
|
||||
gen.error = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue