Go to the source code of this file.
Functions | |
void | cell_emit_state (struct cell_context *cell) |
For state marked as 'dirty', construct a state-update command block and insert it into the current batch buffer. |
void cell_emit_state | ( | struct cell_context * | cell | ) |
For state marked as 'dirty', construct a state-update command block and insert it into the current batch buffer.
Definition at line 56 of file cell_state_emit.c.
References cell_texture::base, cell_blend_state::base, cell_depth_stencil_alpha_state::base, cell_context::blend, cell_command_fragment_ops::blend, cell_context::cbuf_map, pipe_framebuffer_state::cbufs, cell_batch_alloc(), 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_VERTEX_INFO, cell_gen_fragment_function(), CELL_MAX_SAMPLERS, CELL_NEW_BLEND, CELL_NEW_DEPTH_STENCIL, CELL_NEW_FRAMEBUFFER, CELL_NEW_FS, CELL_NEW_SAMPLER, CELL_NEW_TEXTURE, CELL_NEW_VERTEX_INFO, CELL_NEW_VS, cell_command_fragment_ops::code, cell_command_fragment_program::code, cell_fragment_shader_state::code, cell_command_framebuffer::color_start, tgsi_exec_machine::Declarations, cell_shader_info::declarations, cell_command_framebuffer::depth_format, cell_command_framebuffer::depth_start, cell_context::depth_stencil, cell_context::dirty, cell_context::draw, draw, draw_num_vs_outputs(), cell_command_fragment_ops::dsa, emit_state_cmd(), pipe_surface::format, cell_context::framebuffer, cell_context::fs, pipe_texture::height, cell_command_texture::height, pipe_framebuffer_state::height, cell_command_framebuffer::height, cell_shader_info::immediates, tgsi_exec_machine::ImmLimit, tgsi_exec_machine::Imms, tgsi_exec_machine::Instructions, cell_shader_info::instructions, draw_context::machine, cell_shader_info::num_declarations, cell_shader_info::num_immediates, spe_function::num_inst, cell_command_fragment_program::num_inst, cell_shader_info::num_instructions, cell_shader_info::num_outputs, tgsi_exec_machine::NumDeclarations, tgsi_exec_machine::NumInstructions, cell_command_texture::opcode, cell_command_sampler::opcode, cell_command_fragment_ops::opcode, cell_command_fragment_program::opcode, cell_command_framebuffer::opcode, pf_name(), PIPE_FORMAT_NONE, cell_context::sampler, SPE_INST_SIZE, spe_release_func(), SPU_MAX_FRAGMENT_OPS_INSTS, SPU_MAX_FRAGMENT_PROGRAM_INSTS, cell_command_texture::start, cell_command_sampler::state, spe_function::store, cell_context::texture, cell_texture::tiled_data, cell_command_texture::unit, cell_command_sampler::unit, cell_context::vertex_info, draw_context::vs, pipe_texture::width, cell_command_texture::width, pipe_framebuffer_state::width, cell_command_framebuffer::width, pipe_framebuffer_state::zsbuf, and cell_context::zsbuf_map.
00057 { 00058 if (cell->dirty & CELL_NEW_FRAMEBUFFER) { 00059 struct pipe_surface *cbuf = cell->framebuffer.cbufs[0]; 00060 struct pipe_surface *zbuf = cell->framebuffer.zsbuf; 00061 struct cell_command_framebuffer *fb 00062 = cell_batch_alloc(cell, sizeof(*fb)); 00063 fb->opcode = CELL_CMD_STATE_FRAMEBUFFER; 00064 fb->color_start = cell->cbuf_map[0]; 00065 fb->color_format = cbuf->format; 00066 fb->depth_start = cell->zsbuf_map; 00067 fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE; 00068 fb->width = cell->framebuffer.width; 00069 fb->height = cell->framebuffer.height; 00070 #if 0 00071 printf("EMIT color format %s\n", pf_name(fb->color_format)); 00072 printf("EMIT depth format %s\n", pf_name(fb->depth_format)); 00073 #endif 00074 } 00075 00076 if (cell->dirty & (CELL_NEW_FS)) { 00077 /* Send new fragment program to SPUs */ 00078 struct cell_command_fragment_program *fp 00079 = cell_batch_alloc(cell, sizeof(*fp)); 00080 fp->opcode = CELL_CMD_STATE_FRAGMENT_PROGRAM; 00081 fp->num_inst = cell->fs->code.num_inst; 00082 memcpy(&fp->code, cell->fs->code.store, 00083 SPU_MAX_FRAGMENT_PROGRAM_INSTS * SPE_INST_SIZE); 00084 if (0) { 00085 int i; 00086 printf("PPU Emit CELL_CMD_STATE_FRAGMENT_PROGRAM:\n"); 00087 for (i = 0; i < fp->num_inst; i++) { 00088 printf(" %3d: 0x%08x\n", i, fp->code[i]); 00089 } 00090 } 00091 } 00092 00093 if (cell->dirty & (CELL_NEW_FRAMEBUFFER | 00094 CELL_NEW_DEPTH_STENCIL | 00095 CELL_NEW_BLEND)) { 00096 /* XXX we don't want to always do codegen here. We should have 00097 * a hash/lookup table to cache previous results... 00098 */ 00099 struct cell_command_fragment_ops *fops 00100 = cell_batch_alloc(cell, sizeof(*fops)); 00101 struct spe_function spe_code; 00102 00103 /* generate new code */ 00104 cell_gen_fragment_function(cell, &spe_code); 00105 /* put the new code into the batch buffer */ 00106 fops->opcode = CELL_CMD_STATE_FRAGMENT_OPS; 00107 memcpy(&fops->code, spe_code.store, 00108 SPU_MAX_FRAGMENT_OPS_INSTS * SPE_INST_SIZE); 00109 fops->dsa = cell->depth_stencil->base; 00110 fops->blend = cell->blend->base; 00111 /* free codegen buffer */ 00112 spe_release_func(&spe_code); 00113 } 00114 00115 if (cell->dirty & CELL_NEW_SAMPLER) { 00116 uint i; 00117 for (i = 0; i < CELL_MAX_SAMPLERS; i++) { 00118 if (cell->sampler[i]) { 00119 struct cell_command_sampler *sampler 00120 = cell_batch_alloc(cell, sizeof(*sampler)); 00121 sampler->opcode = CELL_CMD_STATE_SAMPLER; 00122 sampler->unit = i; 00123 sampler->state = *cell->sampler[i]; 00124 } 00125 } 00126 } 00127 00128 if (cell->dirty & CELL_NEW_TEXTURE) { 00129 uint i; 00130 for (i = 0;i < CELL_MAX_SAMPLERS; i++) { 00131 struct cell_command_texture *texture 00132 = cell_batch_alloc(cell, sizeof(*texture)); 00133 texture->opcode = CELL_CMD_STATE_TEXTURE; 00134 texture->unit = i; 00135 if (cell->texture[i]) { 00136 texture->start = cell->texture[i]->tiled_data; 00137 texture->width = cell->texture[i]->base.width[0]; 00138 texture->height = cell->texture[i]->base.height[0]; 00139 } 00140 else { 00141 texture->start = NULL; 00142 texture->width = 1; 00143 texture->height = 1; 00144 } 00145 } 00146 } 00147 00148 if (cell->dirty & CELL_NEW_VERTEX_INFO) { 00149 emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO, 00150 &cell->vertex_info, sizeof(struct vertex_info)); 00151 } 00152 00153 #if 0 00154 if (cell->dirty & CELL_NEW_VS) { 00155 const struct draw_context *const draw = cell->draw; 00156 struct cell_shader_info info; 00157 00158 info.num_outputs = draw_num_vs_outputs(draw); 00159 info.declarations = (uintptr_t) draw->vs.machine.Declarations; 00160 info.num_declarations = draw->vs.machine.NumDeclarations; 00161 info.instructions = (uintptr_t) draw->vs.machine.Instructions; 00162 info.num_instructions = draw->vs.machine.NumInstructions; 00163 info.immediates = (uintptr_t) draw->vs.machine.Imms; 00164 info.num_immediates = draw->vs.machine.ImmLimit / 4; 00165 00166 emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS, &info, sizeof(info)); 00167 } 00168 #endif 00169 }