static void
cell_set_framebuffer_state(struct pipe_context *pipe,
                           const struct pipe_framebuffer_state *fb)
{
   struct cell_context *cell = cell_context(pipe);

   if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) {
      uint i;

      /* unmap old surfaces */
      cell_unmap_surfaces(cell);

      /* Finish any pending rendering to the current surface before
       * installing a new surface!
       */
      cell_flush_int(cell, CELL_FLUSH_WAIT);

      /* update my state
       * (this is also where old surfaces will finally get freed)
       */
      cell->framebuffer.width = fb->width;
      cell->framebuffer.height = fb->height;
      cell->framebuffer.nr_cbufs = fb->nr_cbufs;
      for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
         pipe_surface_reference(&cell->framebuffer.cbufs[i], fb->cbufs[i]);
      }
      pipe_surface_reference(&cell->framebuffer.zsbuf, fb->zsbuf);

      /* map new surfaces */
      cell_map_surfaces(cell);

      cell->dirty |= CELL_NEW_FRAMEBUFFER;
   }
}
/**
 * Create vertex shader state.
 * Called via pipe->create_vs_state()
 */
static void *
cell_create_vs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct cell_context *cell = cell_context(pipe);
   struct cell_vertex_shader_state *cvs;

   cvs = CALLOC_STRUCT(cell_vertex_shader_state);
   if (!cvs)
      return NULL;

   cvs->shader.tokens = tgsi_dup_tokens(templ->tokens);
   if (!cvs->shader.tokens) {
      FREE(cvs);
      return NULL;
   }

   tgsi_scan_shader(templ->tokens, &cvs->info);

   cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader);
   if (cvs->draw_data == NULL) {
      FREE( (void *) cvs->shader.tokens );
      FREE( cvs );
      return NULL;
   }

   return cvs;
}
static void
cell_set_sampler_textures(struct pipe_context *pipe,
                          unsigned num, struct pipe_texture **texture)
{
   struct cell_context *cell = cell_context(pipe);
   uint i, changed = 0x0;

   assert(num <= CELL_MAX_SAMPLERS);

   for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
      struct cell_texture *new_tex = cell_texture(i < num ? texture[i] : NULL);
      struct cell_texture *old_tex = cell->texture[i];
      if (old_tex != new_tex) {

         pipe_texture_reference((struct pipe_texture **) &cell->texture[i],
                                (struct pipe_texture *) new_tex);

         changed |= (1 << i);
      }
   }

   cell->num_textures = num;

   if (changed) {
      cell->dirty |= CELL_NEW_TEXTURE;
      cell->dirty_textures |= changed;
   }
}
static void
cell_set_polygon_stipple( struct pipe_context *pipe,
                          const struct pipe_poly_stipple *stipple )
{
   struct cell_context *cell = cell_context(pipe);

   memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) );
   cell->dirty |= CELL_NEW_STIPPLE;
}
static void
cell_set_scissor_state( struct pipe_context *pipe,
                        const struct pipe_scissor_state *scissor )
{
   struct cell_context *cell = cell_context(pipe);

   memcpy( &cell->scissor, scissor, sizeof(*scissor) );
   cell->dirty |= CELL_NEW_SCISSOR;
}
static void
cell_set_clip_state(struct pipe_context *pipe,
                    const struct pipe_clip_state *clip)
{
   struct cell_context *cell = cell_context(pipe);

   /* pass the clip state to the draw module */
   draw_set_clip_state(cell->draw, clip);
}
/**
 * Called via pipe->bind_fs_state()
 */
static void
cell_bind_fs_state(struct pipe_context *pipe, void *fs)
{
   struct cell_context *cell = cell_context(pipe);

   cell->fs = cell_fragment_shader_state(fs);

   cell->dirty |= CELL_NEW_FS;
}
/**
 * Called via pipe->delete_vs_state()
 */
static void
cell_delete_vs_state(struct pipe_context *pipe, void *vs)
{
   struct cell_context *cell = cell_context(pipe);
   struct cell_vertex_shader_state *cvs = cell_vertex_shader_state(vs);

   draw_delete_vertex_shader(cell->draw, cvs->draw_data);
   FREE( (void *) cvs->shader.tokens );
   FREE( cvs );
}
static void
cell_bind_blend_state(struct pipe_context *pipe, void *blend)
{
   struct cell_context *cell = cell_context(pipe);

   draw_flush(cell->draw);

   cell->blend = (struct pipe_blend_state *) blend;
   cell->dirty |= CELL_NEW_BLEND;
}
Example #10
0
static void
cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
                                    void *dsa)
{
   struct cell_context *cell = cell_context(pipe);

   draw_flush(cell->draw);

   cell->depth_stencil = (struct pipe_depth_stencil_alpha_state *) dsa;
   cell->dirty |= CELL_NEW_DEPTH_STENCIL;
}
Example #11
0
static void
cell_set_blend_color(struct pipe_context *pipe,
                     const struct pipe_blend_color *blend_color)
{
   struct cell_context *cell = cell_context(pipe);

   draw_flush(cell->draw);

   cell->blend_color = *blend_color;

   cell->dirty |= CELL_NEW_BLEND;
}
/**
 * Called via pipe->bind_vs_state()
 */
static void
cell_bind_vs_state(struct pipe_context *pipe, void *vs)
{
   struct cell_context *cell = cell_context(pipe);

   cell->vs = cell_vertex_shader_state(vs);

   draw_bind_vertex_shader(cell->draw,
                           (cell->vs ? cell->vs->draw_data : NULL));

   cell->dirty |= CELL_NEW_VS;
}
Example #13
0
static void
cell_bind_rasterizer_state(struct pipe_context *pipe, void *rast)
{
   struct pipe_rasterizer_state *rasterizer =
      (struct pipe_rasterizer_state *) rast;
   struct cell_context *cell = cell_context(pipe);

   /* pass-through to draw module */
   draw_set_rasterizer_state(cell->draw, rasterizer);

   cell->rasterizer = rasterizer;

   cell->dirty |= CELL_NEW_RASTERIZER;
}
Example #14
0
/**
 * Called via pipe->flush()
 */
void
cell_flush(struct pipe_context *pipe,
           struct pipe_fence_handle **fence)
{
   struct cell_context *cell = cell_context(pipe);

   if (fence) {
      *fence = NULL;
   }

   flags |= CELL_FLUSH_WAIT;

   draw_flush( cell->draw );
   cell_flush_int(cell, flags);
}
/**
 * Draw vertex arrays, with optional indexing.
 * Basically, map the vertex buffers (and drawing surfaces), then hand off
 * the drawing to the 'draw' module.
 *
 * XXX should the element buffer be specified/bound with a separate function?
 */
static void
cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
   struct cell_context *cell = cell_context(pipe);
   struct draw_context *draw = cell->draw;
   void *mapped_indices = NULL;
   unsigned i;

   if (cell->dirty)
      cell_update_derived( cell );

#if 0
   cell_map_surfaces(cell);
#endif

   /*
    * Map vertex buffers
    */
   for (i = 0; i < cell->num_vertex_buffers; i++) {
      void *buf = cell_resource(cell->vertex_buffer[i].buffer)->data;
      draw_set_mapped_vertex_buffer(draw, i, buf);
   }
   /* Map index buffer, if present */
   if (info->indexed && cell->index_buffer.buffer)
      mapped_indices = cell_resource(cell->index_buffer.buffer)->data;

   draw_set_mapped_index_buffer(draw, mapped_indices);

   /* draw! */
   draw_vbo(draw, info);

   /*
    * unmap vertex/index buffers - will cause draw module to flush
    */
   for (i = 0; i < cell->num_vertex_buffers; i++) {
      draw_set_mapped_vertex_buffer(draw, i, NULL);
   }
   if (mapped_indices) {
      draw_set_mapped_index_buffer(draw, NULL);
   }

   /*
    * TODO: Flush only when a user vertex/index buffer is present
    * (or even better, modify draw module to do this
    * internally when this condition is seen?)
    */
   draw_flush(draw);
}
Example #16
0
/* Called when driver state tracker notices changes to the viewport
 * matrix:
 */
static void
cell_set_viewport_state( struct pipe_context *pipe,
                         const struct pipe_viewport_state *viewport )
{
   struct cell_context *cell = cell_context(pipe);

   cell->viewport = *viewport; /* struct copy */
   cell->dirty |= CELL_NEW_VIEWPORT;

   /* pass the viewport info to the draw module */
   draw_set_viewport_state(cell->draw, viewport);

   /* Using tnl/ and vf/ modules is temporary while getting started.
    * Full pipe will have vertex shader, vertex fetch of its own.
    */
}
Example #17
0
static void
cell_set_vertex_buffers(struct pipe_context *pipe,
                        unsigned count,
                        const struct pipe_vertex_buffer *buffers)
{
   struct cell_context *cell = cell_context(pipe);

   assert(count <= PIPE_MAX_ATTRIBS);

   memcpy(cell->vertex_buffer, buffers, count * sizeof(buffers[0]));
   cell->num_vertex_buffers = count;

   cell->dirty |= CELL_NEW_VERTEX;

   draw_set_vertex_buffers(cell->draw, count, buffers);
}
Example #18
0
static void
cell_destroy_context( struct pipe_context *pipe )
{
   struct cell_context *cell = cell_context(pipe);
   unsigned i;

   for (i = 0; i < cell->num_vertex_buffers; i++) {
      pipe_resource_reference(&cell->vertex_buffer[i].buffer, NULL);
   }

   util_delete_keymap(cell->fragment_ops_cache, NULL);

   cell_spu_exit(cell);

   align_free(cell);
}
/**
 * Called via pipe->set_constant_buffer()
 */
static void
cell_set_constant_buffer(struct pipe_context *pipe,
                         uint shader, uint index,
                         const struct pipe_constant_buffer *buf)
{
   struct cell_context *cell = cell_context(pipe);

   assert(shader < PIPE_SHADER_TYPES);
   assert(index == 0);

   draw_flush(cell->draw);

   /* note: reference counting */
   pipe_buffer_reference(&cell->constants[shader].buffer, buf->buffer);

   if (shader == PIPE_SHADER_VERTEX)
      cell->dirty |= CELL_NEW_VS_CONSTANTS;
   else if (shader == PIPE_SHADER_FRAGMENT)
      cell->dirty |= CELL_NEW_FS_CONSTANTS;
}
/**
 * Create fragment shader state.
 * Called via pipe->create_fs_state()
 */
static void *
cell_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct cell_context *cell = cell_context(pipe);
   struct cell_fragment_shader_state *cfs;

   cfs = CALLOC_STRUCT(cell_fragment_shader_state);
   if (!cfs)
      return NULL;

   cfs->shader.tokens = tgsi_dup_tokens(templ->tokens);
   if (!cfs->shader.tokens) {
      FREE(cfs);
      return NULL;
   }

   tgsi_scan_shader(templ->tokens, &cfs->info);

   cell_gen_fragment_program(cell, cfs->shader.tokens, &cfs->code);

   return cfs;
}
Example #21
0
static void
cell_bind_sampler_states(struct pipe_context *pipe,
                         unsigned num, void **samplers)
{
   struct cell_context *cell = cell_context(pipe);
   uint i, changed = 0x0;

   assert(num <= CELL_MAX_SAMPLERS);

   draw_flush(cell->draw);

   for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
      struct pipe_sampler_state *new_samp = i < num ? samplers[i] : NULL;
      if (cell->sampler[i] != new_samp) {
         cell->sampler[i] = new_samp;
         changed |= (1 << i);
      }
   }

   if (changed) {
      cell->dirty |= CELL_NEW_SAMPLER;
      cell->dirty_samplers |= changed;
   }
}
static void
cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
{
   struct cell_context *cell = cell_context(pipe);
   draw_set_edgeflags(cell->draw, edgeflags);
}
/**
 * Draw vertex arrays, with optional indexing.
 * Basically, map the vertex buffers (and drawing surfaces), then hand off
 * the drawing to the 'draw' module.
 *
 * XXX should the element buffer be specified/bound with a separate function?
 */
static boolean
cell_draw_range_elements(struct pipe_context *pipe,
                         struct pipe_buffer *indexBuffer,
                         unsigned indexSize,
                         unsigned min_index,
                         unsigned max_index,
                         unsigned mode, unsigned start, unsigned count)
{
   struct cell_context *sp = cell_context(pipe);
   struct draw_context *draw = sp->draw;
   unsigned i;

   if (sp->dirty)
      cell_update_derived( sp );

#if 0
   cell_map_surfaces(sp);
#endif
   cell_map_constant_buffers(sp);

   /*
    * Map vertex buffers
    */
   for (i = 0; i < sp->num_vertex_buffers; i++) {
      void *buf = pipe_buffer_map(pipe->screen,
                                           sp->vertex_buffer[i].buffer,
                                           PIPE_BUFFER_USAGE_CPU_READ);
      cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
      draw_set_mapped_vertex_buffer(draw, i, buf);
   }
   /* Map index buffer, if present */
   if (indexBuffer) {
      void *mapped_indexes = pipe_buffer_map(pipe->screen,
                                                      indexBuffer,
                                                      PIPE_BUFFER_USAGE_CPU_READ);
      draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
   }
   else {
      /* no index/element buffer */
      draw_set_mapped_element_buffer(draw, 0, NULL);
   }


   /* draw! */
   draw_arrays(draw, mode, start, count);

   /*
    * unmap vertex/index buffers - will cause draw module to flush
    */
   for (i = 0; i < sp->num_vertex_buffers; i++) {
      draw_set_mapped_vertex_buffer(draw, i, NULL);
      pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
   }
   if (indexBuffer) {
      draw_set_mapped_element_buffer(draw, 0, NULL);
      pipe_buffer_unmap(pipe->screen, indexBuffer);
   }

   /* Note: leave drawing surfaces mapped */
   cell_unmap_constant_buffers(sp);

   return TRUE;
}