cell_state_emit.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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       /* 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 }

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