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 CLEAR_OPT 1 |
typedef unsigned long main_param_t |
Definition at line 669 of file spu_main.c.
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 }
unsigned char attribute_fetch_code_buffer [136 * PIPE_MAX_ATTRIBS] ALIGN16_ATTRIB [static] |
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.