Browse Source

Cell: basic batch buffer working

tags/mesa_20090313
Brian 17 years ago
parent
commit
8dd678208e

+ 3
- 11
src/mesa/pipe/cell/common.h View File

@@ -70,6 +70,7 @@
*/
struct cell_command_framebuffer
{
uint opcode;
int width, height;
void *color_start, *depth_start;
enum pipe_format color_format, depth_format;
@@ -81,6 +82,7 @@ struct cell_command_framebuffer
*/
struct cell_command_clear_surface
{
uint opcode;
uint surface; /**< Temporary: 0=color, 1=Z */
uint value;
} ALIGN16_ATTRIB;
@@ -91,6 +93,7 @@ struct cell_command_clear_surface
#define CELL_MAX_ATTRIBS 2 /* temporary! */
struct cell_command_render
{
uint opcode;
uint prim_type;
uint num_verts, num_attribs;
uint num_indexes;
@@ -100,23 +103,12 @@ struct cell_command_render
} ALIGN16_ATTRIB;


/**
* Execute a command/batch buffer.
*/
struct cell_command_batch
{
ushort buffer; /**< which buffer [0, CELL_NUM_CMD_BUFFFERS-1] */
ushort length; /**< in bytes */
} ALIGN16_ATTRIB;


/** XXX unions don't seem to work */
struct cell_command
{
struct cell_command_framebuffer fb;
struct cell_command_clear_surface clear;
struct cell_command_render render;
struct cell_command_batch batch;
} ALIGN16_ATTRIB;



+ 26
- 1
src/mesa/pipe/cell/ppu/cell_batch.c View File

@@ -43,7 +43,7 @@ cell_batch_flush(struct cell_context *cell)

assert(batch < CELL_NUM_BATCH_BUFFERS);

printf("cell_batch_dispatch: buf %u, size %u\n", batch, size);
/*printf("cell_batch_dispatch: buf %u, size %u\n", batch, size);*/
cmd_word = CELL_CMD_BATCH | (batch << 8) | (size << 16);

@@ -83,3 +83,28 @@ cell_batch_append(struct cell_context *cell, const void *cmd, uint length)

cell->batch_buffer_size[cell->cur_batch] = size + length;
}


void *
cell_batch_alloc(struct cell_context *cell, uint bytes)
{
void *pos;
uint size;

assert(cell->cur_batch >= 0);

size = cell->batch_buffer_size[cell->cur_batch];

if (size + bytes > CELL_BATCH_BUFFER_SIZE) {
cell_batch_flush(cell);
size = 0;
}

assert(size + bytes <= CELL_BATCH_BUFFER_SIZE);

pos = (void *) (cell->batch_buffer[cell->cur_batch] + size);

cell->batch_buffer_size[cell->cur_batch] = size + bytes;

return pos;
}

+ 6
- 0
src/mesa/pipe/cell/ppu/cell_batch.h View File

@@ -30,11 +30,17 @@
#define CELL_BATCH_H


struct cell_context;


extern void
cell_batch_flush(struct cell_context *cell);

extern void
cell_batch_append(struct cell_context *cell, const void *cmd, uint length);

extern void *
cell_batch_alloc(struct cell_context *cell, uint bytes);


#endif /* CELL_BATCH_H */

+ 14
- 5
src/mesa/pipe/cell/ppu/cell_flush.c View File

@@ -38,16 +38,25 @@ cell_flush(struct pipe_context *pipe, unsigned flags)
struct cell_context *cell = cell_context(pipe);
uint i;

cell_flush_prim_buffer(cell);
if (flags & PIPE_FLUSH_WAIT) {
uint *cmd = (uint *) cell_batch_alloc(cell, sizeof(uint));
*cmd = CELL_CMD_FINISH;
}

cell_batch_flush(cell);

#if 0
/* Send CMD_FINISH to all SPUs */
for (i = 0; i < cell->num_spus; i++) {
send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FINISH);
}
#endif

/* Wait for ack */
for (i = 0; i < cell->num_spus; i++) {
uint k = wait_mbox_message(cell_global.spe_contexts[i]);
assert(k == CELL_CMD_FINISH);
if (flags & PIPE_FLUSH_WAIT) {
/* Wait for ack */
for (i = 0; i < cell->num_spus; i++) {
uint k = wait_mbox_message(cell_global.spe_contexts[i]);
assert(k == CELL_CMD_FINISH);
}
}
}

+ 19
- 1
src/mesa/pipe/cell/ppu/cell_state_surface.c View File

@@ -27,6 +27,7 @@


#include "pipe/p_inlines.h"
#include "cell_batch.h"
#include "cell_context.h"
#include "cell_state.h"
#include "cell_spu.h"
@@ -68,8 +69,10 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
if (zsurf && !zsurf->map)
pipe_surface_map(zsurf);

#if 0
for (i = 0; i < cell->num_spus; i++) {
struct cell_command_framebuffer *fb = &cell_global.command[i].fb;
fb->opcode = CELL_CMD_FRAMEBUFFER;
fb->color_start = csurf->map;
fb->color_format = csurf->format;
fb->depth_start = zsurf ? zsurf->map : NULL;
@@ -78,7 +81,22 @@ cell_set_framebuffer_state(struct pipe_context *pipe,
fb->height = csurf->height;
send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FRAMEBUFFER);
}

#endif
#if 1
{
struct cell_command_framebuffer *fb
= cell_batch_alloc(cell, sizeof(*fb));
fb->opcode = CELL_CMD_FRAMEBUFFER;
fb->color_start = csurf->map;
fb->color_format = csurf->format;
fb->depth_start = zsurf ? zsurf->map : NULL;
fb->depth_format = zsurf ? zsurf->format : PIPE_FORMAT_NONE;
fb->width = csurf->width;
fb->height = csurf->height;
/*cell_batch_flush(cell);*/
/*cell_flush(&cell->pipe, 0x0);*/
}
#endif
cell->dirty |= CELL_NEW_FRAMEBUFFER;
}


+ 12
- 0
src/mesa/pipe/cell/ppu/cell_surface.c View File

@@ -37,6 +37,7 @@
#include "pipe/p_util.h"
#include "pipe/cell/common.h"
#include "cell_context.h"
#include "cell_batch.h"
#include "cell_surface.h"
#include "cell_spu.h"

@@ -59,6 +60,7 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
surfIndex = 0;
}

#if 0
for (i = 0; i < cell->num_spus; i++) {
#if 1
uint clr = clearValue;
@@ -80,6 +82,16 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
cell_global.command[i].clear.surface = surfIndex;
send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE);
}
#else
{
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *)
cell_batch_alloc(cell, sizeof(*clr));
clr->opcode = CELL_CMD_CLEAR_SURFACE;
clr->surface = surfIndex;
clr->value = clearValue;
}
#endif

/* XXX temporary */
cell_flush(&cell->pipe, 0x0);

+ 26
- 1
src/mesa/pipe/cell/ppu/cell_vbuf.c View File

@@ -130,8 +130,10 @@ cell_vbuf_draw(struct vbuf_render *vbr,
if (prim != PIPE_PRIM_TRIANGLES)
return; /* only render tris for now */

#if 0
for (i = 0; i < cell->num_spus; i++) {
struct cell_command_render *render = &cell_global.command[i].render;
render->opcode = CELL_CMD_RENDER;
render->prim_type = prim;
render->num_verts = nr_vertices;
render->num_attribs = CELL_MAX_ATTRIBS; /* XXX fix */
@@ -147,9 +149,32 @@ cell_vbuf_draw(struct vbuf_render *vbr,
ASSERT_ALIGN16(render->index_data);
send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_RENDER);
}
#else
{
struct cell_command_render *render
= (struct cell_command_render *)
cell_batch_alloc(cell, sizeof(*render));
render->opcode = CELL_CMD_RENDER;
render->prim_type = prim;
render->num_verts = nr_vertices;
render->num_attribs = CELL_MAX_ATTRIBS; /* XXX fix */
render->vertex_data = vertices;
render->index_data = indices;
render->num_indexes = nr_indices;
render->xmin = xmin;
render->ymin = ymin;
render->xmax = xmax;
render->ymax = ymax;

ASSERT_ALIGN16(render->vertex_data);
ASSERT_ALIGN16(render->index_data);
}
#endif

#if 01
/* XXX this is temporary */
cell_flush(&cell->pipe, 0x0);
cell_flush(&cell->pipe, PIPE_FLUSH_WAIT);
#endif
}



+ 123
- 52
src/mesa/pipe/cell/spu/main.c View File

@@ -115,11 +115,15 @@ really_clear_tiles(uint surfaceIndex)


static void
clear_surface(const struct cell_command_clear_surface *clear)
cmd_clear_surface(const struct cell_command_clear_surface *clear)
{
const uint num_tiles = fb.width_tiles * fb.height_tiles;
uint i, j;

if (Debug)
printf("SPU %u: CLEAR SURF %u to 0x%08x\n", init.id,
clear->surface, clear->value);

#define CLEAR_OPT 1
#if CLEAR_OPT
/* set all tile's status to CLEAR */
@@ -206,7 +210,7 @@ tile_bounding_box(const struct cell_command_render *render,


static void
render(const struct cell_command_render *render)
cmd_render(const struct cell_command_render *render)
{
/* we'll DMA into these buffers */
ubyte vertex_data[CELL_MAX_VBUF_SIZE] ALIGN16_ATTRIB;
@@ -214,6 +218,14 @@ render(const struct cell_command_render *render)

uint i, j, vertex_size, vertex_bytes, index_bytes;

if (Debug)
printf("SPU %u: RENDER prim %u, indices: %u, nr_vert: %u\n",
init.id,
render->prim_type,
render->num_verts,
render->num_indexes);


ASSERT_ALIGN16(render->vertex_data);
ASSERT_ALIGN16(render->index_data);

@@ -321,13 +333,115 @@ render(const struct cell_command_render *render)
}


static void
cmd_framebuffer(const struct cell_command_framebuffer *cmd)
{
if (Debug)
printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n",
init.id,
cmd->width,
cmd->height,
cmd->color_start,
cmd->color_format,
cmd->depth_format);

fb.color_start = cmd->color_start;
fb.depth_start = cmd->depth_start;
fb.color_format = cmd->color_format;
fb.depth_format = cmd->depth_format;
fb.width = cmd->width;
fb.height = cmd->height;
fb.width_tiles = (fb.width + TILE_SIZE - 1) / TILE_SIZE;
fb.height_tiles = (fb.height + TILE_SIZE - 1) / TILE_SIZE;
}


static void
batch(const struct cell_command_batch *batch)
cmd_finish(void)
{
if (Debug)
printf("SPU %u: FINISH\n", init.id);
really_clear_tiles(0);
/* wait for all outstanding DMAs to finish */
mfc_write_tag_mask(~0);
mfc_read_tag_status_all();
/* send mbox message to PPU */
spu_write_out_mbox(CELL_CMD_FINISH);
}


/**
* Execute a batch of commands
* The opcode param encodes the location of the buffer and its size.
*/
static void
cmd_batch(uint opcode)
{
const uint buf = (opcode >> 8) & 0xff;
uint size = (opcode >> 16);
uint buffer[CELL_BATCH_BUFFER_SIZE / 4] ALIGN16_ATTRIB;
const uint usize = size / sizeof(uint);
uint pos;

if (Debug)
printf("SPU %u: BATCH buffer %u, len %u, from %p\n",
init.id, buf, size, init.batch_buffers[buf]);

ASSERT((opcode & CELL_CMD_OPCODE_MASK) == CELL_CMD_BATCH);

ASSERT_ALIGN16(init.batch_buffers[buf]);

size = (size + 0xf) & ~0xf;

mfc_get(buffer, /* dest */
(unsigned int) init.batch_buffers[buf], /* src */
size,
TAG_BATCH_BUFFER,
0, /* tid */
0 /* rid */);
wait_on_mask(1 << TAG_BATCH_BUFFER);

for (pos = 0; pos < usize; /* no incr */) {
switch (buffer[pos]) {
case CELL_CMD_FRAMEBUFFER:
{
struct cell_command_framebuffer *fb
= (struct cell_command_framebuffer *) &buffer[pos];
cmd_framebuffer(fb);
pos += sizeof(*fb) / 4;
}
break;
case CELL_CMD_CLEAR_SURFACE:
{
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *) &buffer[pos];
cmd_clear_surface(clr);
pos += sizeof(*clr) / 4;
}
break;
case CELL_CMD_RENDER:
{
struct cell_command_render *render
= (struct cell_command_render *) &buffer[pos];
cmd_render(render);
pos += sizeof(*render) / 4;
}
break;
case CELL_CMD_FINISH:
cmd_finish();
pos += 1;
break;
default:
printf("SPU %u: bad opcode: 0x%x\n", init.id, buffer[pos]);
ASSERT(0);
break;
}
}

if (Debug)
printf("SPU %u: BATCH complete\n", init.id);
}


/**
* Temporary/simple main loop for SPEs: Get a command, execute it, repeat.
@@ -355,7 +469,7 @@ main_loop(void)
opcode = (unsigned int) spu_read_in_mbox();

if (Debug)
printf("SPU %u: got cmd %u\n", init.id, opcode);
printf("SPU %u: got cmd 0x%x\n", init.id, opcode);

/* command payload */
mfc_get(&cmd, /* dest */
@@ -373,62 +487,19 @@ main_loop(void)
exitFlag = 1;
break;
case CELL_CMD_FRAMEBUFFER:
if (Debug)
printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n",
init.id,
cmd.fb.width,
cmd.fb.height,
cmd.fb.color_start,
cmd.fb.color_format,
cmd.fb.depth_format);
fb.color_start = cmd.fb.color_start;
fb.depth_start = cmd.fb.depth_start;
fb.color_format = cmd.fb.color_format;
fb.depth_format = cmd.fb.depth_format;
fb.width = cmd.fb.width;
fb.height = cmd.fb.height;
fb.width_tiles = (fb.width + TILE_SIZE - 1) / TILE_SIZE;
fb.height_tiles = (fb.height + TILE_SIZE - 1) / TILE_SIZE;
/*
printf("SPU %u: %u x %u tiles\n",
init.id, fb.width_tiles, fb.height_tiles);
*/
cmd_framebuffer(&cmd.fb);
break;
case CELL_CMD_CLEAR_SURFACE:
if (Debug)
printf("SPU %u: CLEAR SURF %u to 0x%08x\n", init.id,
cmd.clear.surface, cmd.clear.value);
clear_surface(&cmd.clear);
cmd_clear_surface(&cmd.clear);
break;
case CELL_CMD_RENDER:
if (Debug)
printf("SPU %u: RENDER prim %u, indices: %u, nr_vert: %u\n",
init.id,
cmd.render.prim_type,
cmd.render.num_verts,
cmd.render.num_indexes);
render(&cmd.render);
cmd_render(&cmd.render);
break;

case CELL_CMD_BATCH:
/* execute a batch buffer */
if (Debug)
printf("SPU %u: BATCH buffer %u, len %u\n",
init.id,
cmd.batch.buffer,
cmd.batch.length);
batch(&cmd.batch);
cmd_batch(opcode);
break;

case CELL_CMD_FINISH:
if (Debug)
printf("SPU %u: FINISH\n", init.id);
really_clear_tiles(0);
/* wait for all outstanding DMAs to finish */
mfc_write_tag_mask(~0);
mfc_read_tag_status_all();
/* send mbox message to PPU */
spu_write_out_mbox(CELL_CMD_FINISH);
cmd_finish();
break;
default:
printf("Bad opcode!\n");

+ 2
- 2
src/mesa/pipe/cell/spu/main.h View File

@@ -55,12 +55,12 @@ extern struct framebuffer fb;

#define TAG_SURFACE_CLEAR 10
#define TAG_VERTEX_BUFFER 11
#define TAG_INDEX_BUFFER 16
#define TAG_READ_TILE_COLOR 12
#define TAG_READ_TILE_Z 13
#define TAG_WRITE_TILE_COLOR 14
#define TAG_WRITE_TILE_Z 15

#define TAG_INDEX_BUFFER 16
#define TAG_BATCH_BUFFER 17

/** The standard assert macro doesn't seem to work on SPUs */
#define ASSERT(x) \

Loading…
Cancel
Save