struct cell_command_fragment_ops
{
uint64_t opcode; /**< CELL_CMD_STATE_FRAGMENT_OPS */
+ struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_blend_state blend;
unsigned code[SPU_MAX_FRAGMENT_OPS_INSTS];
};
cell_gen_fragment.c \
cell_state_derived.c \
cell_state_emit.c \
- cell_state_per_fragment.c \
cell_state_shader.c \
cell_pipe_state.c \
cell_screen.c \
void
cell_emit_state(struct cell_context *cell)
{
- if (cell->dirty & (CELL_NEW_FRAMEBUFFER | CELL_NEW_BLEND)) {
- struct cell_command_logicop logicop;
-
- if (cell->logic_op.store != NULL) {
- spe_release_func(& cell->logic_op);
- }
-
- cell_generate_logic_op(& cell->logic_op,
- & cell->blend->base,
- cell->framebuffer.cbufs[0]);
-
- logicop.base = (intptr_t) cell->logic_op.store;
- logicop.size = 64 * 4;
- emit_state_cmd(cell, CELL_CMD_STATE_LOGICOP, &logicop,
- sizeof(logicop));
- }
-
if (cell->dirty & CELL_NEW_FRAMEBUFFER) {
struct pipe_surface *cbuf = cell->framebuffer.cbufs[0];
struct pipe_surface *zbuf = cell->framebuffer.zsbuf;
}
- if (cell->dirty & (CELL_NEW_FRAMEBUFFER | CELL_NEW_DEPTH_STENCIL)) {
+ if (cell->dirty & (CELL_NEW_FRAMEBUFFER |
+ CELL_NEW_DEPTH_STENCIL |
+ CELL_NEW_BLEND)) {
/* XXX we don't want to always do codegen here. We should have
* a hash/lookup table to cache previous results...
*/
fops->opcode = CELL_CMD_STATE_FRAGMENT_OPS;
memcpy(&fops->code, spe_code.store,
SPU_MAX_FRAGMENT_OPS_INSTS * SPE_INST_SIZE);
+ fops->dsa = cell->depth_stencil->base;
+ fops->blend = cell->blend->base;
/* free codegen buffer */
spe_release_func(&spe_code);
}
- if (cell->dirty & CELL_NEW_BLEND) {
- struct cell_command_blend blend;
-
- if (cell->blend != NULL) {
- blend.base = (intptr_t) cell->blend->code.store;
- blend.size = cell->blend->code.num_inst * SPE_INST_SIZE;
- blend.read_fb = TRUE;
- }
- else {
- blend.base = 0;
- blend.size = 0;
- blend.read_fb = FALSE;
- }
-
- emit_state_cmd(cell, CELL_CMD_STATE_BLEND, &blend, sizeof(blend));
- }
-
- if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
- struct cell_command_depth_stencil_alpha_test dsat;
-
- if (cell->depth_stencil != NULL) {
- dsat.base = (intptr_t) cell->depth_stencil->code.store;
- dsat.size = cell->depth_stencil->code.num_inst * SPE_INST_SIZE;
- dsat.read_depth = TRUE;
- dsat.read_stencil = FALSE;
- dsat.state = cell->depth_stencil->base;
- }
- else {
- dsat.base = 0;
- dsat.size = 0;
- dsat.read_depth = FALSE;
- dsat.read_stencil = FALSE;
- }
-
- emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat, sizeof(dsat));
- }
-
if (cell->dirty & CELL_NEW_SAMPLER) {
uint i;
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
static unsigned char attribute_fetch_code_buffer[136 * PIPE_MAX_ATTRIBS]
ALIGN16_ATTRIB;
-static unsigned char depth_stencil_code_buffer[4 * 64]
- ALIGN16_ATTRIB;
-
-static unsigned char fb_blend_code_buffer[4 * 64]
- ALIGN16_ATTRIB;
-
-static unsigned char logicop_code_buffer[4 * 64]
- ALIGN16_ATTRIB;
/**
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 */
+ memcpy(&spu.depth_stencil_alpha, &fops->dsa, sizeof(fops->dsa));
+ memcpy(&spu.blend, &fops->blend, sizeof(fops->blend));
+
/* Point function pointer at new code */
spu.fragment_ops.func = (spu_fragment_ops_func) spu.fragment_ops.code;
+
+ spu.read_depth = spu.depth_stencil_alpha.depth.enabled;
+ spu.read_stencil = spu.depth_stencil_alpha.stencil[0].enabled;
}
}
-#define NEW_FRAGMENT_FUNCTION 01
-
-static void
-cmd_state_blend(const struct cell_command_blend *state)
-{
- if (Debug)
- printf("SPU %u: BLEND: enabled %d\n",
- spu.init.id,
- (state->size != 0));
-
- ASSERT_ALIGN16(state->base);
-
- if (state->size != 0) {
- mfc_get(fb_blend_code_buffer,
- (unsigned int) state->base, /* src */
- ROUNDUP16(state->size),
- TAG_BATCH_BUFFER,
- 0, /* tid */
- 0 /* rid */);
- wait_on_mask(1 << TAG_BATCH_BUFFER);
- spu.blend = (blend_func) fb_blend_code_buffer;
- spu.read_fb = state->read_fb;
- }
- else
- {
- spu.read_fb = FALSE;
- }
-}
-
-
-static void
-cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *state)
-{
- if (Debug)
- printf("SPU %u: DEPTH_STENCIL: ztest %d\n",
- spu.init.id,
- state->read_depth);
-
- ASSERT_ALIGN16(state->base);
-
- if (state->size != 0) {
- mfc_get(depth_stencil_code_buffer,
- (unsigned int) state->base, /* src */
- ROUNDUP16(state->size),
- TAG_BATCH_BUFFER,
- 0, /* tid */
- 0 /* rid */);
- wait_on_mask(1 << TAG_BATCH_BUFFER);
- }
- else
- {
- /* If there is no code, emit a return instruction.
- */
- depth_stencil_code_buffer[0] = 0x35;
- depth_stencil_code_buffer[1] = 0x00;
- depth_stencil_code_buffer[2] = 0x00;
- depth_stencil_code_buffer[3] = 0x00;
- }
-
- spu.frag_test = (frag_test_func) depth_stencil_code_buffer;
- spu.read_depth = state->read_depth;
- spu.read_stencil = state->read_stencil;
- spu.depth_stencil_alpha = state->state;
-}
-
-
-static void
-cmd_state_logicop(const struct cell_command_logicop * code)
-{
-#if !NEW_FRAGMENT_FUNCTION
- mfc_get(logicop_code_buffer,
- (unsigned int) code->base, /* src */
- code->size,
- TAG_BATCH_BUFFER,
- 0, /* tid */
- 0 /* rid */);
- wait_on_mask(1 << TAG_BATCH_BUFFER);
-
- spu.logicop = (logicop_func) logicop_code_buffer;
-#endif
-}
-
-
static void
cmd_state_sampler(const struct cell_command_sampler *sampler)
{
cmd_finish();
pos += 1;
break;
- case CELL_CMD_STATE_BLEND:
- cmd_state_blend((struct cell_command_blend *) &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct cell_command_blend)) / 8);
- break;
- case CELL_CMD_STATE_DEPTH_STENCIL:
- cmd_state_depth_stencil((struct cell_command_depth_stencil_alpha_test *)
- &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8);
- break;
case CELL_CMD_STATE_SAMPLER:
{
struct cell_command_sampler *sampler
pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
break;
case CELL_CMD_STATE_BIND_VS:
+#if 01
spu_bind_vertex_shader(&draw,
(struct cell_shader_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
+#endif
break;
case CELL_CMD_STATE_ATTRIB_FETCH:
cmd_state_attrib_fetch((struct cell_attribute_fetch_code *)
&buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
break;
- case CELL_CMD_STATE_LOGICOP:
- cmd_state_logicop((struct cell_command_logicop *) &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct cell_command_logicop)) / 8);
- break;
case CELL_CMD_FLUSH_BUFFER_RANGE: {
struct cell_buffer_range *br = (struct cell_buffer_range *)
&buffer[pos+1];
exitFlag = 1;
break;
case CELL_CMD_VS_EXECUTE:
+#if 01
spu_execute_vertex_shader(&draw, &cmd.vs);
+#endif
break;
case CELL_CMD_BATCH:
cmd_batch(opcode);
#define TILE_STATUS_GETTING 5 /**< mfc_get() called but not yet arrived */
-struct spu_frag_test_results {
- qword mask;
- qword depth;
- qword stencil;
-};
-
-typedef struct spu_frag_test_results (*frag_test_func)(qword frag_mask,
- qword pixel_depth, qword pixel_stencil, qword frag_depth,
- qword frag_alpha, qword facing);
-
-
-struct spu_blend_results {
- qword r;
- qword g;
- qword b;
- qword a;
-};
-
-typedef struct spu_blend_results (*blend_func)(
- qword frag_r, qword frag_g, qword frag_b, qword frag_a,
- qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
- qword const_r, qword const_g, qword const_b, qword const_a);
-
-typedef struct spu_blend_results (*logicop_func)(
- qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
- qword frag_r, qword frag_g, qword frag_b, qword frag_a,
- qword frag_mask);
-
-
typedef vector float (*sample_texture_func)(uint unit, vector float texcoord);
struct spu_framebuffer fb;
struct pipe_depth_stencil_alpha_state depth_stencil_alpha;
+ struct pipe_blend_state blend;
boolean read_depth;
boolean read_stencil;
- frag_test_func frag_test; /**< Current depth/stencil test code */
-
- boolean read_fb; /**< Does current blend mode require framebuffer read? */
- blend_func blend; /**< Current blend code */
- qword const_blend_color[4] ALIGN16_ATTRIB;
-
- logicop_func logicop; /**< Current logicop code **/
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct spu_texture texture[PIPE_MAX_SAMPLERS];