cell: more work for multi-texture support
authorBrian <brian.paul@tungstengraphics.com>
Tue, 1 Apr 2008 03:09:02 +0000 (21:09 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Tue, 1 Apr 2008 03:16:48 +0000 (21:16 -0600)
src/gallium/drivers/cell/common.h
src/gallium/drivers/cell/ppu/cell_state_emit.c
src/gallium/drivers/cell/spu/spu_main.c
src/gallium/drivers/cell/spu/spu_main.h
src/gallium/drivers/cell/spu/spu_texture.c
src/gallium/drivers/cell/spu/spu_tri.c

index 298812f..f430e88 100644 (file)
@@ -36,6 +36,7 @@
 #include "pipe/p_compiler.h"
 #include "pipe/p_util.h"
 #include "pipe/p_format.h"
+#include "pipe/p_state.h"
 
 
 /** The standard assert macro doesn't seem to work reliably */
@@ -228,12 +229,20 @@ struct cell_command_release_verts
 };
 
 
+struct cell_command_sampler
+{
+   uint64_t opcode;         /**< CELL_CMD_STATE_SAMPLER */
+   uint unit;
+   struct pipe_sampler_state state;
+};
+
+
 struct cell_command_texture
 {
-   struct {
-      void *start;         /**< Address in main memory */
-      ushort width, height;
-   } texture[CELL_MAX_SAMPLERS];
+   uint64_t opcode;     /**< CELL_CMD_STATE_TEXTURE */
+   uint unit;
+   void *start;         /**< Address in main memory */
+   ushort width, height;
 };
 
 
index 4fbe1a2..9cae67f 100644 (file)
@@ -121,25 +121,36 @@ cell_emit_state(struct cell_context *cell)
    }
 
    if (cell->dirty & CELL_NEW_SAMPLER) {
-      if (cell->sampler[0]) {
-         emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER,
-                        cell->sampler[0], sizeof(struct pipe_sampler_state));
+      uint i;
+      for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
+         if (cell->sampler[i]) {
+            struct cell_command_sampler *sampler
+               = cell_batch_alloc(cell, sizeof(*sampler));
+            sampler->opcode = CELL_CMD_STATE_SAMPLER;
+            sampler->unit = i;
+            sampler->state = *cell->sampler[i];
+         }
       }
    }
 
    if (cell->dirty & CELL_NEW_TEXTURE) {
-      struct cell_command_texture texture;
       uint i;
-      memset(&texture, 0, sizeof(texture));
       for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
+         struct cell_command_texture *texture
+            =  cell_batch_alloc(cell, sizeof(*texture));
+         texture->opcode = CELL_CMD_STATE_TEXTURE;
+         texture->unit = i;
          if (cell->texture[i]) {
-            texture.texture[i].start = cell->texture[i]->tiled_data;
-            texture.texture[i].width = cell->texture[i]->base.width[0];
-            texture.texture[i].height = cell->texture[i]->base.height[0];
+            texture->start = cell->texture[i]->tiled_data;
+            texture->width = cell->texture[i]->base.width[0];
+            texture->height = cell->texture[i]->base.height[0];
+         }
+         else {
+            texture->start = NULL;
+            texture->width = 1;
+            texture->height = 1;
          }
       }
-      emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE,
-                     &texture, sizeof(struct cell_command_texture));
    }
 
    if (cell->dirty & CELL_NEW_VERTEX_INFO) {
index 80fa5f7..7f0473d 100644 (file)
@@ -312,13 +312,13 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat
 
 
 static void
-cmd_state_sampler(const struct pipe_sampler_state *state)
+cmd_state_sampler(const struct cell_command_sampler *sampler)
 {
    if (Debug)
-      printf("SPU %u: SAMPLER\n",
-             spu.init.id);
+      printf("SPU %u: SAMPLER [%u]\n",
+             spu.init.id, sampler->unit);
 
-   memcpy(&spu.sampler[0], state, sizeof(*state));
+   spu.sampler[sampler->unit] = sampler->state;
    if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR)
       spu.sample_texture = sample_texture_bilinear;
    else
@@ -329,26 +329,25 @@ cmd_state_sampler(const struct pipe_sampler_state *state)
 static void
 cmd_state_texture(const struct cell_command_texture *texture)
 {
-   uint i;
+   const uint unit = texture->unit;
+   const uint width = texture->width;
+   const uint height = texture->height;
 
-   if (1||Debug) {
-      printf("SPU %u: TEXTURE\n", spu.init.id);
-      for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
-         printf("  %d: at %p  size %u x %u\n", i, texture->texture[i].start,
-                texture->texture[i].width, texture->texture[i].height);
-      }
+   if (Debug) {
+      printf("SPU %u: TEXTURE [%u] at %p  size %u x %u\n", spu.init.id,
+             texture->unit, texture->start,
+             texture->width, texture->height);
    }
 
-   memcpy(&spu.texture, texture, sizeof(*texture));
-   for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
-      const uint width = texture->texture[i].width;
-      const uint height = texture->texture[i].height;
-      spu.tex_size[i] = (vector float) { width, height, 0.0, 0.0};
-      spu.tex_size_mask[i] = (vector unsigned int)
+   spu.texture[unit].start = texture->start;
+   spu.texture[unit].width = width;
+   spu.texture[unit].height = height;
+
+   spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0};
+   spu.texture[unit].tex_size_mask = (vector unsigned int)
          { width - 1, height - 1, 0, 0 };
-      spu.tex_size_x_mask[i] = spu_splats(width - 1);
-      spu.tex_size_y_mask[i] = spu_splats(height - 1);
-   }
+   spu.texture[unit].tex_size_x_mask = spu_splats(width - 1);
+   spu.texture[unit].tex_size_y_mask = spu_splats(height - 1);
 }
 
 
@@ -480,12 +479,20 @@ cmd_batch(uint opcode)
          pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8);
          break;
       case CELL_CMD_STATE_SAMPLER:
-         cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
-         pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8);
+         {
+            struct cell_command_sampler *sampler
+               = (struct cell_command_sampler *) &buffer[pos];
+            cmd_state_sampler(sampler);
+            pos += sizeof(*sampler) / 8;
+         }
          break;
       case CELL_CMD_STATE_TEXTURE:
-         cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]);
-         pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8);
+         {
+            struct cell_command_texture *texture
+               = (struct cell_command_texture *) &buffer[pos];
+            cmd_state_texture(texture);
+            pos += sizeof(*texture) / 8;
+         }
          break;
       case CELL_CMD_STATE_VERTEX_INFO:
          cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
index 8a87787..2bfad35 100644 (file)
@@ -100,6 +100,17 @@ struct spu_framebuffer {
 } ALIGN16_ATTRIB;
 
 
+struct spu_texture
+{
+   void *start;
+   uint width, height;
+   vector float tex_size;
+   vector unsigned int tex_size_mask; /**< == int(size - 1) */
+   vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
+   vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
+} ALIGN16_ATTRIB;
+
+
 /**
  * All SPU global/context state will be in singleton object of this type:
  */
@@ -119,7 +130,7 @@ struct spu_global
    logicop_func logicop;
 
    struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
-   struct cell_command_texture texture;
+   struct spu_texture texture[PIPE_MAX_SAMPLERS];
 
    struct vertex_info vertex_info;
 
@@ -141,11 +152,6 @@ struct spu_global
    /** for converting RGBA to PIPE_FORMAT_x colors */
    vector unsigned char color_shuffle;
 
-   vector float tex_size[CELL_MAX_SAMPLERS];
-   vector unsigned int tex_size_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */
-   vector unsigned int tex_size_x_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */
-   vector unsigned int tex_size_y_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */
-
    vector float (*sample_texture)(vector float texcoord);
 
 } ALIGN16_ATTRIB;
index 91a6aec..4612501 100644 (file)
@@ -41,10 +41,10 @@ void
 invalidate_tex_cache(void)
 {
    uint unit = 0;
-   uint bytes = 4 * spu.texture.texture[unit].width
-      * spu.texture.texture[unit].height;
+   uint bytes = 4 * spu.texture[unit].width
+      * spu.texture[unit].height;
 
-   spu_dcache_mark_dirty((unsigned) spu.texture.texture[unit].start, bytes);
+   spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes);
 }
 
 
@@ -55,14 +55,14 @@ get_texel(vec_uint4 coordinate)
    vec_uint4 tmp;
    unsigned x = spu_extract(coordinate, 0);
    unsigned y = spu_extract(coordinate, 1);
-   const unsigned tiles_per_row = spu.texture.texture[unit].width / TILE_SIZE;
+   const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE;
    unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) 
                                             + (x / TILE_SIZE));
    unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE)
                                 + (x % TILE_SIZE));
 
    spu_dcache_fetch_unaligned((qword *) & tmp,
-                              spu.texture.texture[unit].start + tile_offset + texel_offset,
+                              spu.texture[unit].start + tile_offset + texel_offset,
                               4);
    return spu_extract(tmp, 0);
 }
@@ -72,13 +72,13 @@ static void
 get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
 {
    const uint unit = 0;
-   const unsigned texture_ea = (uintptr_t) spu.texture.texture[unit].start;
+   const unsigned texture_ea = (uintptr_t) spu.texture[unit].start;
    vec_uint4 tile_x = spu_rlmask(x, -5);
    vec_uint4 tile_y = spu_rlmask(y, -5);
    const qword offset_x = si_andi((qword) x, 0x1f);
    const qword offset_y = si_andi((qword) y, 0x1f);
 
-   const qword tiles_per_row = (qword) spu_splats(spu.texture.texture[unit].width / TILE_SIZE);
+   const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE);
    const qword tile_size = (qword) spu_splats(sizeof(tile_t));
 
    qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x);
@@ -107,9 +107,9 @@ vector float
 sample_texture_nearest(vector float texcoord)
 {
    const uint unit = 0;
-   vector float tc = spu_mul(texcoord, spu.tex_size[unit]);
+   vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
    vector unsigned int itc = spu_convtu(tc, 0);  /* convert to int */
-   itc = spu_and(itc, spu.tex_size_mask[unit]);        /* mask (GL_REPEAT) */
+   itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */
    uint texel = get_texel(itc);
    return spu_unpack_A8R8G8B8(texel);
 }
@@ -122,7 +122,7 @@ sample_texture_bilinear(vector float texcoord)
    static const vec_uint4 offset_x = {0, 0, 1, 1};
    static const vec_uint4 offset_y = {0, 1, 0, 1};
 
-   vector float tc = spu_mul(texcoord, spu.tex_size[unit]);
+   vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
    tc = spu_add(tc, spu_splats(-0.5f));  /* half texel bias */
 
    /* integer texcoords S,T: */
@@ -136,8 +136,8 @@ sample_texture_bilinear(vector float texcoord)
    x = spu_add(x, offset_x);
    y = spu_add(y, offset_y);
 
-   x = spu_and(x, spu.tex_size_x_mask[unit]);
-   y = spu_and(y, spu.tex_size_y_mask[unit]);
+   x = spu_and(x, spu.texture[unit].tex_size_x_mask);
+   y = spu_and(y, spu.texture[unit].tex_size_y_mask);
 
    get_four_texels(x, y, texels);
 
index 9f63317..17e337b 100644 (file)
@@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask )
 
       spu.cur_ctile_status = TILE_STATUS_DIRTY;
 
-      if (spu.texture.texture[0].start) {
+      if (spu.texture[0].start) {
          /* texture mapping */
          vector float texcoords[4];
          eval_coeff(2, (float) x, (float) y, texcoords);