summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/cell/spu
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-09-11 17:59:52 -0600
committerBrian Paul <[email protected]>2008-09-11 17:59:52 -0600
commitaa66f08a21b791f338b519f0c2162cd8f7b3aeb0 (patch)
tree1e8c8e2e01f98759b9ab073d340daca837b65932 /src/gallium/drivers/cell/spu
parentdbbbc333442c160b2801062e92c6c5931b64390a (diff)
cell: initial support for fragment shader code generation.
TGSI shaders are translated into SPE instructions which are then sent to the SPEs for execution. Only a few opcodes work, no swizzling yet, no support for constants/immediates, etc.
Diffstat (limited to 'src/gallium/drivers/cell/spu')
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c25
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h15
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c35
3 files changed, 74 insertions, 1 deletions
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index 2a7cb75f592..78260c4259c 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -232,7 +232,7 @@ cmd_state_fragment_ops(const struct cell_command_fragment_ops *fops)
printf("SPU %u: CMD_STATE_FRAGMENT_OPS\n", spu.init.id);
/* Copy SPU code from batch buffer to spu buffer */
memcpy(spu.fragment_ops_code, fops->code, SPU_MAX_FRAGMENT_OPS_INSTS * 4);
- /* Copy state info */
+ /* Copy state info (for fallback case only) */
memcpy(&spu.depth_stencil_alpha, &fops->dsa, sizeof(fops->dsa));
memcpy(&spu.blend, &fops->blend, sizeof(fops->blend));
@@ -245,6 +245,21 @@ cmd_state_fragment_ops(const struct cell_command_fragment_ops *fops)
static void
+cmd_state_fragment_program(const struct cell_command_fragment_program *fp)
+{
+ if (Debug)
+ printf("SPU %u: CMD_STATE_FRAGMENT_PROGRAM\n", spu.init.id);
+ /* Copy SPU code from batch buffer to spu buffer */
+ memcpy(spu.fragment_program_code, fp->code,
+ SPU_MAX_FRAGMENT_PROGRAM_INSTS * 4);
+#if 01
+ /* Point function pointer at new code */
+ spu.fragment_program = (spu_fragment_program_func)spu.fragment_program_code;
+#endif
+}
+
+
+static void
cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
{
if (Debug)
@@ -473,6 +488,14 @@ cmd_batch(uint opcode)
pos += sizeof(*fops) / 8;
}
break;
+ case CELL_CMD_STATE_FRAGMENT_PROGRAM:
+ {
+ struct cell_command_fragment_program *fp
+ = (struct cell_command_fragment_program *) &buffer[pos];
+ cmd_state_fragment_program(fp);
+ pos += sizeof(*fp) / 8;
+ }
+ break;
case CELL_CMD_STATE_SAMPLER:
{
struct cell_command_sampler *sampler
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index d40539da83b..2c7b6258402 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -75,6 +75,12 @@ typedef void (*spu_fragment_ops_func)(uint x, uint y,
vector float fragAlpha,
vector unsigned int mask);
+/** Function for running fragment program */
+typedef void (*spu_fragment_program_func)(vector float *inputs,
+ vector float *outputs,
+ vector float *constants);
+
+
struct spu_framebuffer
{
void *color_start; /**< addr of color surface in main memory */
@@ -142,9 +148,18 @@ struct spu_global
/** Current fragment ops function */
spu_fragment_ops_func fragment_ops;
+ /** Current fragment program machine code */
+ uint fragment_program_code[SPU_MAX_FRAGMENT_PROGRAM_INSTS];
+ /** Current fragment ops function */
+ spu_fragment_program_func fragment_program;
+
/** Current texture sampler function */
spu_sample_texture_func sample_texture[CELL_MAX_SAMPLERS];
+ /** Fragment program constants (XXX preliminary/used) */
+#define MAX_CONSTANTS 32
+ vector float constants[MAX_CONSTANTS];
+
} ALIGN16_ATTRIB;
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index f02cdd1f763..8b938781920 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -314,7 +314,42 @@ emit_quad( int x, int y, mask_t mask )
}
else {
/* simple shading */
+#if 0
eval_coeff(1, (float) x, (float) y, colors);
+
+#else
+ /* XXX new fragment program code */
+
+ if (spu.fragment_program) {
+ vector float inputs[4*4], outputs[2*4];
+
+ /* setup inputs */
+ eval_coeff(1, (float) x, (float) y, inputs);
+
+ /* Execute the current fragment program */
+ spu.fragment_program(inputs, outputs, spu.constants);
+
+ /* Copy outputs */
+ colors[0] = outputs[0*4+0];
+ colors[1] = outputs[0*4+1];
+ colors[2] = outputs[0*4+2];
+ colors[3] = outputs[0*4+3];
+
+ if (0 && spu.init.id==0 && y == 48) {
+ printf("colors[0] = %f %f %f %f\n",
+ spu_extract(colors[0], 0),
+ spu_extract(colors[0], 1),
+ spu_extract(colors[0], 2),
+ spu_extract(colors[0], 3));
+ printf("colors[1] = %f %f %f %f\n",
+ spu_extract(colors[1], 0),
+ spu_extract(colors[1], 1),
+ spu_extract(colors[1], 2),
+ spu_extract(colors[1], 3));
+ }
+
+ }
+#endif
}