spu_main.c File Reference

Include dependency graph for spu_main.c:

Go to the source code of this file.

Defines

#define CLEAR_OPT   1

Typedefs

typedef unsigned long main_param_t

Functions

static void release_buffer (uint buffer)
 Tell the PPU that this SPU has finished copying a buffer to local store and that it may be reused by the PPU.
static void really_clear_tiles (uint surfaceIndex)
 For tiles whose status is TILE_STATUS_CLEAR, write solid-filled tiles back to the main framebuffer.
static void cmd_clear_surface (const struct cell_command_clear_surface *clear)
static void cmd_release_verts (const struct cell_command_release_verts *release)
static void cmd_state_fragment_ops (const struct cell_command_fragment_ops *fops)
 Process a CELL_CMD_STATE_FRAGMENT_OPS command.
static void cmd_state_fragment_program (const struct cell_command_fragment_program *fp)
static void cmd_state_framebuffer (const struct cell_command_framebuffer *cmd)
static void cmd_state_sampler (const struct cell_command_sampler *sampler)
static void cmd_state_texture (const struct cell_command_texture *texture)
static void cmd_state_vertex_info (const struct vertex_info *vinfo)
static void cmd_state_vs_array_info (const struct cell_array_info *vs_info)
static void cmd_state_attrib_fetch (const struct cell_attribute_fetch_code *code)
static void cmd_finish (void)
static void cmd_batch (uint opcode)
 Execute a batch of commands which was sent to us by the PPU.
static void main_loop (void)
 Temporary/simple main loop for SPEs: Get a command, execute it, repeat.
static void one_time_init (void)
int main (main_param_t speid, main_param_t argp)
 SPE entrypoint.

Variables

boolean Debug = FALSE
struct spu_global spu
struct spu_vs_context draw
static unsigned char
attribute_fetch_code_buffer[136
*PIPE_MAX_ATTRIBS] 
ALIGN16_ATTRIB
 Buffers containing dynamically generated SPU code:.


Define Documentation

#define CLEAR_OPT   1


Typedef Documentation

typedef unsigned long main_param_t

Definition at line 669 of file spu_main.c.


Function Documentation

static void cmd_batch ( uint  opcode  )  [static]

Execute a batch of commands which was sent to us by the PPU.

See the cell_emit_state.c code to see where the commands come from.

The opcode param encodes the location of the buffer and its size.

Definition at line 413 of file spu_main.c.

References ALIGN16_ATTRIB, ASSERT, ASSERT_ALIGN16, cell_buffer_range::base, cell_init_info::buffers, CELL_BUFFER_SIZE, CELL_CMD_BATCH, CELL_CMD_CLEAR_SURFACE, CELL_CMD_FINISH, CELL_CMD_FLUSH_BUFFER_RANGE, CELL_CMD_OPCODE_MASK, CELL_CMD_RELEASE_VERTS, CELL_CMD_RENDER, CELL_CMD_STATE_ATTRIB_FETCH, CELL_CMD_STATE_BIND_VS, CELL_CMD_STATE_FRAGMENT_OPS, CELL_CMD_STATE_FRAGMENT_PROGRAM, CELL_CMD_STATE_FRAMEBUFFER, CELL_CMD_STATE_SAMPLER, CELL_CMD_STATE_TEXTURE, CELL_CMD_STATE_UNIFORMS, CELL_CMD_STATE_VERTEX_INFO, CELL_CMD_STATE_VIEWPORT, CELL_CMD_STATE_VS_ARRAY_INFO, cmd_clear_surface(), cmd_finish(), cmd_release_verts(), cmd_render(), cmd_state_attrib_fetch(), cmd_state_fragment_ops(), cmd_state_fragment_program(), cmd_state_framebuffer(), cmd_state_sampler(), cmd_state_texture(), cmd_state_vertex_info(), cmd_state_vs_array_info(), spu_vs_context::constants, Debug, draw, cell_init_info::id, spu_global::init, release_buffer(), ROUNDUP16, ROUNDUP8, cell_buffer_range::size, spu_vs_context::size, spu, spu_bind_vertex_shader(), spu_dcache_mark_dirty(), TAG_BATCH_BUFFER, spu_vs_context::viewport, and wait_on_mask().

00415 {
00416    const uint buf = (opcode >> 8) & 0xff;
00417    uint size = (opcode >> 16);
00418    uint64_t buffer[CELL_BUFFER_SIZE / 8] ALIGN16_ATTRIB;
00419    const unsigned usize = size / sizeof(buffer[0]);
00420    uint pos;
00421 
00422    if (Debug)
00423       printf("SPU %u: BATCH buffer %u, len %u, from %p\n",
00424              spu.init.id, buf, size, spu.init.buffers[buf]);
00425 
00426    ASSERT((opcode & CELL_CMD_OPCODE_MASK) == CELL_CMD_BATCH);
00427 
00428    ASSERT_ALIGN16(spu.init.buffers[buf]);
00429 
00430    size = ROUNDUP16(size);
00431 
00432    ASSERT_ALIGN16(spu.init.buffers[buf]);
00433 
00434    mfc_get(buffer,  /* dest */
00435            (unsigned int) spu.init.buffers[buf],  /* src */
00436            size,
00437            TAG_BATCH_BUFFER,
00438            0, /* tid */
00439            0  /* rid */);
00440    wait_on_mask(1 << TAG_BATCH_BUFFER);
00441 
00442    /* Tell PPU we're done copying the buffer to local store */
00443    if (Debug)
00444       printf("SPU %u: release batch buf %u\n", spu.init.id, buf);
00445    release_buffer(buf);
00446 
00447    /*
00448     * Loop over commands in the batch buffer
00449     */
00450    for (pos = 0; pos < usize; /* no incr */) {
00451       switch (buffer[pos]) {
00452       /*
00453        * rendering commands
00454        */
00455       case CELL_CMD_CLEAR_SURFACE:
00456          {
00457             struct cell_command_clear_surface *clr
00458                = (struct cell_command_clear_surface *) &buffer[pos];
00459             cmd_clear_surface(clr);
00460             pos += sizeof(*clr) / 8;
00461          }
00462          break;
00463       case CELL_CMD_RENDER:
00464          {
00465             struct cell_command_render *render
00466                = (struct cell_command_render *) &buffer[pos];
00467             uint pos_incr;
00468             cmd_render(render, &pos_incr);
00469             pos += pos_incr;
00470          }
00471          break;
00472       /*
00473        * state-update commands
00474        */
00475       case CELL_CMD_STATE_FRAMEBUFFER:
00476          {
00477             struct cell_command_framebuffer *fb
00478                = (struct cell_command_framebuffer *) &buffer[pos];
00479             cmd_state_framebuffer(fb);
00480             pos += sizeof(*fb) / 8;
00481          }
00482          break;
00483       case CELL_CMD_STATE_FRAGMENT_OPS:
00484          {
00485             struct cell_command_fragment_ops *fops
00486                = (struct cell_command_fragment_ops *) &buffer[pos];
00487             cmd_state_fragment_ops(fops);
00488             pos += sizeof(*fops) / 8;
00489          }
00490          break;
00491       case CELL_CMD_STATE_FRAGMENT_PROGRAM:
00492          {
00493             struct cell_command_fragment_program *fp
00494                = (struct cell_command_fragment_program *) &buffer[pos];
00495             cmd_state_fragment_program(fp);
00496             pos += sizeof(*fp) / 8;
00497          }
00498          break;
00499       case CELL_CMD_STATE_SAMPLER:
00500          {
00501             struct cell_command_sampler *sampler
00502                = (struct cell_command_sampler *) &buffer[pos];
00503             cmd_state_sampler(sampler);
00504             pos += sizeof(*sampler) / 8;
00505          }
00506          break;
00507       case CELL_CMD_STATE_TEXTURE:
00508          {
00509             struct cell_command_texture *texture
00510                = (struct cell_command_texture *) &buffer[pos];
00511             cmd_state_texture(texture);
00512             pos += sizeof(*texture) / 8;
00513          }
00514          break;
00515       case CELL_CMD_STATE_VERTEX_INFO:
00516          cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
00517          pos += (1 + ROUNDUP8(sizeof(struct vertex_info)) / 8);
00518          break;
00519       case CELL_CMD_STATE_VIEWPORT:
00520          (void) memcpy(& draw.viewport, &buffer[pos+1],
00521                        sizeof(struct pipe_viewport_state));
00522          pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8);
00523          break;
00524       case CELL_CMD_STATE_UNIFORMS:
00525          draw.constants = (const float (*)[4]) (uintptr_t) buffer[pos + 1];
00526          pos += 2;
00527          break;
00528       case CELL_CMD_STATE_VS_ARRAY_INFO:
00529          cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]);
00530          pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
00531          break;
00532       case CELL_CMD_STATE_BIND_VS:
00533 #if 0
00534          spu_bind_vertex_shader(&draw,
00535                                 (struct cell_shader_info *) &buffer[pos+1]);
00536 #endif
00537          pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
00538          break;
00539       case CELL_CMD_STATE_ATTRIB_FETCH:
00540          cmd_state_attrib_fetch((struct cell_attribute_fetch_code *)
00541                                 &buffer[pos+1]);
00542          pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
00543          break;
00544       /*
00545        * misc commands
00546        */
00547       case CELL_CMD_FINISH:
00548          cmd_finish();
00549          pos += 1;
00550          break;
00551       case CELL_CMD_RELEASE_VERTS:
00552          {
00553             struct cell_command_release_verts *release
00554                = (struct cell_command_release_verts *) &buffer[pos];
00555             cmd_release_verts(release);
00556             pos += sizeof(*release) / 8;
00557          }
00558          break;
00559       case CELL_CMD_FLUSH_BUFFER_RANGE: {
00560          struct cell_buffer_range *br = (struct cell_buffer_range *)
00561              &buffer[pos+1];
00562 
00563          spu_dcache_mark_dirty((unsigned) br->base, br->size);
00564          pos += (1 + ROUNDUP8(sizeof(struct cell_buffer_range)) / 8);
00565          break;
00566       }
00567       default:
00568          printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]);
00569          ASSERT(0);
00570          break;
00571       }
00572    }
00573 
00574    if (Debug)
00575       printf("SPU %u: BATCH complete\n", spu.init.id);

static void cmd_clear_surface ( const struct cell_command_clear_surface clear  )  [static]

Definition at line 134 of file spu_main.c.

References CELL_DEBUG_CHECKER, CELL_DEBUG_SYNC, clear_c_tile(), clear_z_tile(), spu_framebuffer::color_clear_value, Debug, cell_init_info::debug_flags, spu_framebuffer::depth_clear_value, spu_global::fb, spu_framebuffer::height_tiles, cell_init_info::id, spu_global::init, cell_init_info::num_spus, put_tile(), spu, cell_command_clear_surface::surface, TAG_SURFACE_CLEAR, TILE_STATUS_CLEAR, cell_command_clear_surface::value, wait_on_mask(), and spu_framebuffer::width_tiles.

00135 {
00136    if (Debug)
00137       printf("SPU %u: CLEAR SURF %u to 0x%08x\n", spu.init.id,
00138              clear->surface, clear->value);
00139 
00140    if (clear->surface == 0) {
00141       spu.fb.color_clear_value = clear->value;
00142       if (spu.init.debug_flags & CELL_DEBUG_CHECKER) {
00143          uint x = (spu.init.id << 4) | (spu.init.id << 12) |
00144             (spu.init.id << 20) | (spu.init.id << 28);
00145          spu.fb.color_clear_value ^= x;
00146       }
00147    }
00148    else {
00149       spu.fb.depth_clear_value = clear->value;
00150    }
00151 
00152 #define CLEAR_OPT 1
00153 #if CLEAR_OPT
00154 
00155    /* Simply set all tiles' status to CLEAR.
00156     * When we actually begin rendering into a tile, we'll initialize it to
00157     * the clear value.  If any tiles go untouched during the frame,
00158     * really_clear_tiles() will set them to the clear value.
00159     */
00160    if (clear->surface == 0) {
00161       memset(spu.ctile_status, TILE_STATUS_CLEAR, sizeof(spu.ctile_status));
00162    }
00163    else {
00164       memset(spu.ztile_status, TILE_STATUS_CLEAR, sizeof(spu.ztile_status));
00165    }
00166 
00167 #else
00168 
00169    /*
00170     * This path clears the whole framebuffer to the clear color right now.
00171     */
00172 
00173    /*
00174    printf("SPU: %s num=%d w=%d h=%d\n",
00175           __FUNCTION__, num_tiles, spu.fb.width_tiles, spu.fb.height_tiles);
00176    */
00177 
00178    /* init a single tile to the clear value */
00179    if (clear->surface == 0) {
00180       clear_c_tile(&spu.ctile);
00181    }
00182    else {
00183       clear_z_tile(&spu.ztile);
00184    }
00185 
00186    /* walk over my tiles, writing the 'clear' tile's data */
00187    {
00188       const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
00189       uint i;
00190       for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
00191          uint tx = i % spu.fb.width_tiles;
00192          uint ty = i / spu.fb.width_tiles;
00193          if (clear->surface == 0)
00194             put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0);
00195          else
00196             put_tile(tx, ty, &spu.ztile, TAG_SURFACE_CLEAR, 1);
00197       }
00198    }
00199 
00200    if (spu.init.debug_flags & CELL_DEBUG_SYNC) {
00201       wait_on_mask(1 << TAG_SURFACE_CLEAR);
00202    }
00203 
00204 #endif /* CLEAR_OPT */
00205 
00206    if (Debug)
00207       printf("SPU %u: CLEAR SURF done\n", spu.init.id);

static void cmd_finish ( void   )  [static]

Definition at line 393 of file spu_main.c.

References CELL_CMD_FINISH, Debug, cell_init_info::id, spu_global::init, really_clear_tiles(), and spu.

00395 {
00396    if (Debug)
00397       printf("SPU %u: FINISH\n", spu.init.id);
00398    really_clear_tiles(0);
00399    /* wait for all outstanding DMAs to finish */
00400    mfc_write_tag_mask(~0);
00401    mfc_read_tag_status_all();
00402    /* send mbox message to PPU */
00403    spu_write_out_mbox(CELL_CMD_FINISH);

static void cmd_release_verts ( const struct cell_command_release_verts release  )  [static]

Definition at line 211 of file spu_main.c.

References ASSERT, Debug, cell_init_info::id, spu_global::init, release_buffer(), spu, and cell_command_release_verts::vertex_buf.

00213 {
00214    if (Debug)
00215       printf("SPU %u: RELEASE VERTS %u\n",
00216              spu.init.id, release->vertex_buf);
00217    ASSERT(release->vertex_buf != ~0U);
00218    release_buffer(release->vertex_buf);

static void cmd_state_attrib_fetch ( const struct cell_attribute_fetch_code code  )  [static]

Definition at line 378 of file spu_main.c.

References cell_attribute_fetch_code::base, spu_vs_context::code, draw, cell_attribute_fetch_code::size, TAG_BATCH_BUFFER, spu_vs_context::vertex_fetch, and wait_on_mask().

00380 {
00381    mfc_get(attribute_fetch_code_buffer,
00382            (unsigned int) code->base,  /* src */
00383            code->size,
00384            TAG_BATCH_BUFFER,
00385            0, /* tid */
00386            0  /* rid */);
00387    wait_on_mask(1 << TAG_BATCH_BUFFER);
00388 
00389    draw.vertex_fetch.code = attribute_fetch_code_buffer;

static void cmd_state_fragment_ops ( const struct cell_command_fragment_ops fops  )  [static]

Process a CELL_CMD_STATE_FRAGMENT_OPS command.

This involves installing new fragment ops SPU code. If this function is never called, we'll use a regular C fallback function for fragment processing.

Definition at line 228 of file spu_main.c.

References cell_command_fragment_ops::blend, spu_global::blend, cell_command_fragment_ops::code, Debug, pipe_depth_stencil_alpha_state::depth, spu_global::depth_stencil_alpha, cell_command_fragment_ops::dsa, pipe_stencil_state::enabled, pipe_depth_state::enabled, spu_global::fragment_ops, spu_global::fragment_ops_code, cell_init_info::id, spu_global::init, spu_global::read_depth, spu_global::read_stencil, spu, SPU_MAX_FRAGMENT_OPS_INSTS, and pipe_depth_stencil_alpha_state::stencil.

00230 {
00231    if (Debug)
00232       printf("SPU %u: CMD_STATE_FRAGMENT_OPS\n", spu.init.id);
00233    /* Copy SPU code from batch buffer to spu buffer */
00234    memcpy(spu.fragment_ops_code, fops->code, SPU_MAX_FRAGMENT_OPS_INSTS * 4);
00235    /* Copy state info (for fallback case only) */
00236    memcpy(&spu.depth_stencil_alpha, &fops->dsa, sizeof(fops->dsa));
00237    memcpy(&spu.blend, &fops->blend, sizeof(fops->blend));
00238 
00239    /* Point function pointer at new code */
00240    spu.fragment_ops = (spu_fragment_ops_func) spu.fragment_ops_code;
00241 
00242    spu.read_depth = spu.depth_stencil_alpha.depth.enabled;
00243    spu.read_stencil = spu.depth_stencil_alpha.stencil[0].enabled;

static void cmd_state_fragment_program ( const struct cell_command_fragment_program fp  )  [static]

Definition at line 247 of file spu_main.c.

References cell_command_fragment_program::code, Debug, spu_global::fragment_program, spu_global::fragment_program_code, cell_init_info::id, spu_global::init, spu, and SPU_MAX_FRAGMENT_PROGRAM_INSTS.

00249 {
00250    if (Debug)
00251       printf("SPU %u: CMD_STATE_FRAGMENT_PROGRAM\n", spu.init.id);
00252    /* Copy SPU code from batch buffer to spu buffer */
00253    memcpy(spu.fragment_program_code, fp->code,
00254           SPU_MAX_FRAGMENT_PROGRAM_INSTS * 4);
00255 #if 01
00256    /* Point function pointer at new code */
00257    spu.fragment_program = (spu_fragment_program_func)spu.fragment_program_code;
00258 #endif

static void cmd_state_framebuffer ( const struct cell_command_framebuffer cmd  )  [static]

Definition at line 262 of file spu_main.c.

References ASSERT_ALIGN16, spu_framebuffer::color_format, spu_framebuffer::color_start, cell_command_framebuffer::color_start, Debug, spu_framebuffer::depth_format, cell_command_framebuffer::depth_format, spu_framebuffer::depth_start, cell_command_framebuffer::depth_start, spu_global::fb, spu_framebuffer::height, cell_command_framebuffer::height, spu_framebuffer::height_tiles, cell_init_info::id, spu_global::init, PIPE_FORMAT_S8Z24_UNORM, PIPE_FORMAT_X8Z24_UNORM, PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z24S8_UNORM, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z32_UNORM, spu, TILE_SIZE, spu_framebuffer::width, cell_command_framebuffer::width, spu_framebuffer::width_tiles, spu_framebuffer::zscale, and spu_framebuffer::zsize.

00264 {
00265    if (Debug)
00266       printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x  zformat 0x%x\n",
00267              spu.init.id,
00268              cmd->width,
00269              cmd->height,
00270              cmd->color_start,
00271              cmd->color_format,
00272              cmd->depth_format);
00273 
00274    ASSERT_ALIGN16(cmd->color_start);
00275    ASSERT_ALIGN16(cmd->depth_start);
00276 
00277    spu.fb.color_start = cmd->color_start;
00278    spu.fb.depth_start = cmd->depth_start;
00279    spu.fb.color_format = cmd->color_format;
00280    spu.fb.depth_format = cmd->depth_format;
00281    spu.fb.width = cmd->width;
00282    spu.fb.height = cmd->height;
00283    spu.fb.width_tiles = (spu.fb.width + TILE_SIZE - 1) / TILE_SIZE;
00284    spu.fb.height_tiles = (spu.fb.height + TILE_SIZE - 1) / TILE_SIZE;
00285 
00286    switch (spu.fb.depth_format) {
00287    case PIPE_FORMAT_Z32_UNORM:
00288       spu.fb.zsize = 4;
00289       spu.fb.zscale = (float) 0xffffffffu;
00290       break;
00291    case PIPE_FORMAT_Z24S8_UNORM:
00292    case PIPE_FORMAT_S8Z24_UNORM:
00293    case PIPE_FORMAT_Z24X8_UNORM:
00294    case PIPE_FORMAT_X8Z24_UNORM:
00295       spu.fb.zsize = 4;
00296       spu.fb.zscale = (float) 0x00ffffffu;
00297       break;
00298    case PIPE_FORMAT_Z16_UNORM:
00299       spu.fb.zsize = 2;
00300       spu.fb.zscale = (float) 0xffffu;
00301       break;
00302    default:
00303       spu.fb.zsize = 0;
00304       break;
00305    }

static void cmd_state_sampler ( const struct cell_command_sampler sampler  )  [static]

Definition at line 309 of file spu_main.c.

References Debug, cell_init_info::id, spu_global::init, pipe_sampler_state::min_img_filter, PIPE_TEX_FILTER_LINEAR, spu_global::sample_texture, sample_texture_bilinear(), sample_texture_nearest(), spu_global::sampler, spu, cell_command_sampler::state, and cell_command_sampler::unit.

00311 {
00312    if (Debug)
00313       printf("SPU %u: SAMPLER [%u]\n",
00314              spu.init.id, sampler->unit);
00315 
00316    spu.sampler[sampler->unit] = sampler->state;
00317    if (spu.sampler[sampler->unit].min_img_filter == PIPE_TEX_FILTER_LINEAR)
00318       spu.sample_texture[sampler->unit] = sample_texture_bilinear;
00319    else
00320       spu.sample_texture[sampler->unit] = sample_texture_nearest;

static void cmd_state_texture ( const struct cell_command_texture texture  )  [static]

Definition at line 324 of file spu_main.c.

References Debug, spu_texture::height, cell_command_texture::height, cell_init_info::id, spu_global::init, spu, spu_texture::start, cell_command_texture::start, spu_texture::tex_size, spu_texture::tex_size_mask, spu_texture::tex_size_x_mask, spu_texture::tex_size_y_mask, spu_global::texture, TILE_SIZE, spu_texture::tiles_per_row, cell_command_texture::unit, spu_texture::width, and cell_command_texture::width.

00326 {
00327    const uint unit = texture->unit;
00328    const uint width = texture->width;
00329    const uint height = texture->height;
00330 
00331    if (Debug) {
00332       printf("SPU %u: TEXTURE [%u] at %p  size %u x %u\n", spu.init.id,
00333              texture->unit, texture->start,
00334              texture->width, texture->height);
00335    }
00336 
00337    spu.texture[unit].start = texture->start;
00338    spu.texture[unit].width = width;
00339    spu.texture[unit].height = height;
00340 
00341    spu.texture[unit].tiles_per_row = width / TILE_SIZE;
00342 
00343    spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0};
00344    spu.texture[unit].tex_size_mask = (vector unsigned int)
00345          { width - 1, height - 1, 0, 0 };
00346    spu.texture[unit].tex_size_x_mask = spu_splats(width - 1);
00347    spu.texture[unit].tex_size_y_mask = spu_splats(height - 1);

static void cmd_state_vertex_info ( const struct vertex_info vinfo  )  [static]

Definition at line 351 of file spu_main.c.

References ASSERT, Debug, cell_init_info::id, spu_global::init, vertex_info::num_attribs, spu, and spu_global::vertex_info.

00353 {
00354    if (Debug) {
00355       printf("SPU %u: VERTEX_INFO num_attribs=%u\n", spu.init.id,
00356              vinfo->num_attribs);
00357    }
00358    ASSERT(vinfo->num_attribs >= 1);
00359    ASSERT(vinfo->num_attribs <= 8);
00360    memcpy(&spu.vertex_info, vinfo, sizeof(*vinfo));

static void cmd_state_vs_array_info ( const struct cell_array_info vs_info  )  [static]

Definition at line 364 of file spu_main.c.

References ASSERT, cell_array_info::attr, cell_array_info::base, spu_vs_context::code_offset, spu_vs_context::dirty, draw, cell_array_info::function_offset, PIPE_MAX_ATTRIBS, cell_array_info::pitch, spu_vs_context::pitch, cell_array_info::size, spu_vs_context::size, spu_vs_context::src_ptr, and spu_vs_context::vertex_fetch.

00366 {
00367    const unsigned attr = vs_info->attr;
00368 
00369    ASSERT(attr < PIPE_MAX_ATTRIBS);
00370    draw.vertex_fetch.src_ptr[attr] = vs_info->base;
00371    draw.vertex_fetch.pitch[attr] = vs_info->pitch;
00372    draw.vertex_fetch.size[attr] = vs_info->size;
00373    draw.vertex_fetch.code_offset[attr] = vs_info->function_offset;
00374    draw.vertex_fetch.dirty = 1;

int main ( main_param_t  speid,
main_param_t  argp 
)

SPE entrypoint.

Definition at line 676 of file spu_main.c.

References ASSERT, Debug, cell_init_info::id, spu_global::init, main_loop(), one_time_init(), spu, TILE_SIZE, and wait_on_mask().

00678 {
00679    int tag = 0;
00680 
00681    (void) speid;
00682 
00683    ASSERT(sizeof(tile_t) == TILE_SIZE * TILE_SIZE * 4);
00684    ASSERT(sizeof(struct cell_command_render) % 8 == 0);
00685 
00686    one_time_init();
00687 
00688    if (Debug)
00689       printf("SPU: main() speid=%lu\n", (unsigned long) speid);
00690 
00691    mfc_get(&spu.init,  /* dest */
00692            (unsigned int) argp, /* src */
00693            sizeof(struct cell_init_info), /* bytes */
00694            tag,
00695            0, /* tid */
00696            0  /* rid */);
00697    wait_on_mask( 1 << tag );
00698 
00699 #if 0
00700    if (spu.init.id==0)
00701       spu_test_misc();
00702 #endif
00703 
00704    main_loop();
00705 
00706    return 0;

static void main_loop ( void   )  [static]

Temporary/simple main loop for SPEs: Get a command, execute it, repeat.

Definition at line 582 of file spu_main.c.

References ASSERT, ASSERT_ALIGN16, CELL_CMD_BATCH, CELL_CMD_EXIT, CELL_CMD_OPCODE_MASK, CELL_CMD_VS_EXECUTE, cell_init_info::cmd, cmd_batch(), Debug, draw, cell_init_info::id, spu_global::init, spu, spu_dcache_report(), spu_execute_vertex_shader(), cell_command::vs, and wait_on_mask().

00584 {
00585    struct cell_command cmd;
00586    int exitFlag = 0;
00587 
00588    if (Debug)
00589       printf("SPU %u: Enter main loop\n", spu.init.id);
00590 
00591    ASSERT((sizeof(struct cell_command) & 0xf) == 0);
00592    ASSERT_ALIGN16(&cmd);
00593 
00594    while (!exitFlag) {
00595       unsigned opcode;
00596       int tag = 0;
00597 
00598       if (Debug)
00599          printf("SPU %u: Wait for cmd...\n", spu.init.id);
00600 
00601       /* read/wait from mailbox */
00602       opcode = (unsigned int) spu_read_in_mbox();
00603 
00604       if (Debug)
00605          printf("SPU %u: got cmd 0x%x\n", spu.init.id, opcode);
00606 
00607       /* command payload */
00608       mfc_get(&cmd,  /* dest */
00609               (unsigned int) spu.init.cmd, /* src */
00610               sizeof(struct cell_command), /* bytes */
00611               tag,
00612               0, /* tid */
00613               0  /* rid */);
00614       wait_on_mask( 1 << tag );
00615 
00616       /*
00617        * NOTE: most commands should be contained in a batch buffer
00618        */
00619 
00620       switch (opcode & CELL_CMD_OPCODE_MASK) {
00621       case CELL_CMD_EXIT:
00622          if (Debug)
00623             printf("SPU %u: EXIT\n", spu.init.id);
00624          exitFlag = 1;
00625          break;
00626       case CELL_CMD_VS_EXECUTE:
00627 #if 0
00628          spu_execute_vertex_shader(&draw, &cmd.vs);
00629 #endif
00630          break;
00631       case CELL_CMD_BATCH:
00632          cmd_batch(opcode);
00633          break;
00634       default:
00635          printf("Bad opcode!\n");
00636       }
00637 
00638    }
00639 
00640    if (Debug)
00641       printf("SPU %u: Exit main loop\n", spu.init.id);
00642 
00643    spu_dcache_report();

static void one_time_init ( void   )  [static]

< defined in FB, but not in local store

< defined in FB, but not in local store

Definition at line 648 of file spu_main.c.

References spu_global::fragment_ops, invalidate_tex_cache(), spu, spu_fallback_fragment_ops(), and TILE_STATUS_DEFINED.

00650 {
00651    memset(spu.ctile_status, TILE_STATUS_DEFINED, sizeof(spu.ctile_status));
00652    memset(spu.ztile_status, TILE_STATUS_DEFINED, sizeof(spu.ztile_status));
00653    invalidate_tex_cache();
00654 
00655    /* Install default/fallback fragment processing function.
00656     * This will normally be overriden by a code-gen'd function.
00657     */
00658    spu.fragment_ops = spu_fallback_fragment_ops;

static void really_clear_tiles ( uint  surfaceIndex  )  [static]

For tiles whose status is TILE_STATUS_CLEAR, write solid-filled tiles back to the main framebuffer.

Definition at line 100 of file spu_main.c.

References clear_c_tile(), clear_z_tile(), spu_global::fb, spu_framebuffer::height_tiles, cell_init_info::id, spu_global::init, cell_init_info::num_spus, put_tile(), spu, TAG_SURFACE_CLEAR, TILE_STATUS_CLEAR, wait_on_mask(), and spu_framebuffer::width_tiles.

00101 {
00102    const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles;
00103    uint i;
00104 
00105    if (surfaceIndex == 0) {
00106       clear_c_tile(&spu.ctile);
00107 
00108       for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
00109          uint tx = i % spu.fb.width_tiles;
00110          uint ty = i / spu.fb.width_tiles;
00111          if (spu.ctile_status[ty][tx] == TILE_STATUS_CLEAR) {
00112             put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0);
00113          }
00114       }
00115    }
00116    else {
00117       clear_z_tile(&spu.ztile);
00118 
00119       for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) {
00120          uint tx = i % spu.fb.width_tiles;
00121          uint ty = i / spu.fb.width_tiles;
00122          if (spu.ztile_status[ty][tx] == TILE_STATUS_CLEAR)
00123             put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 1);
00124       }
00125    }
00126 
00127 #if 0
00128    wait_on_mask(1 << TAG_SURFACE_CLEAR);
00129 #endif
00130 }

static void release_buffer ( uint  buffer  )  [static]

Tell the PPU that this SPU has finished copying a buffer to local store and that it may be reused by the PPU.

This is done by writting a 16-byte batch-buffer-status block back into main memory (in cell_context->buffer_status[]).

Definition at line 75 of file spu_main.c.

References ALIGN16_ATTRIB, ASSERT, cell_init_info::buffer_status, CELL_BUFFER_STATUS_FREE, CELL_NUM_BUFFERS, cell_init_info::id, spu_global::init, spu, and TAG_MISC.

00076 {
00077    /* Evidently, using less than a 16-byte status doesn't work reliably */
00078    static const uint status[4] ALIGN16_ATTRIB
00079       = {CELL_BUFFER_STATUS_FREE, 0, 0, 0};
00080 
00081    const uint index = 4 * (spu.init.id * CELL_NUM_BUFFERS + buffer);
00082    uint *dst = spu.init.buffer_status + index;
00083 
00084    ASSERT(buffer < CELL_NUM_BUFFERS);
00085 
00086    mfc_put((void *) &status,    /* src in local memory */
00087            (unsigned int) dst,  /* dst in main memory */
00088            sizeof(status),      /* size */
00089            TAG_MISC,            /* tag is unimportant */
00090            0, /* tid */
00091            0  /* rid */);
00092 }


Variable Documentation

unsigned char attribute_fetch_code_buffer [136 * PIPE_MAX_ATTRIBS] ALIGN16_ATTRIB [static]

Buffers containing dynamically generated SPU code:.

Definition at line 64 of file spu_main.c.

boolean Debug = FALSE

Definition at line 53 of file spu_main.c.

struct spu_vs_context draw

Definition at line 57 of file spu_main.c.

struct spu_global spu

Definition at line 55 of file spu_main.c.


Generated on Tue Sep 29 06:25:32 2009 for Gallium3D by  doxygen 1.5.4