00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "util/u_memory.h"
00029 #include "cell_context.h"
00030 #include "cell_gen_fragment.h"
00031 #include "cell_state.h"
00032 #include "cell_state_emit.h"
00033 #include "cell_state_per_fragment.h"
00034 #include "cell_batch.h"
00035 #include "cell_texture.h"
00036 #include "draw/draw_context.h"
00037 #include "draw/draw_private.h"
00038
00039
00040 static void
00041 emit_state_cmd(struct cell_context *cell, uint cmd,
00042 const void *state, uint state_size)
00043 {
00044 uint64_t *dst = (uint64_t *)
00045 cell_batch_alloc(cell, ROUNDUP8(sizeof(uint64_t) + state_size));
00046 *dst = cmd;
00047 memcpy(dst + 1, state, state_size);
00048 }
00049
00050
00055 void
00056 cell_emit_state(struct cell_context *cell)
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
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
00097
00098
00099 struct cell_command_fragment_ops *fops
00100 = cell_batch_alloc(cell, sizeof(*fops));
00101 struct spe_function spe_code;
00102
00103
00104 cell_gen_fragment_function(cell, &spe_code);
00105
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
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 }