diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2008-10-14 10:55:38 -0600 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2008-10-14 12:54:30 -0600 | 
| commit | 0bee156d8518419befb50ba57d22fed4037797ce (patch) | |
| tree | 0aafaa3dbebd083f10b27e51082a282e64486ece /src/gallium/drivers | |
| parent | b7609be0f1cc8d7a822a29a2ecc165cd848df2b3 (diff) | |
cell: now do texture twiddling in the right way, at the right time.
Also handles images smaller than 32x32 now.
Diffstat (limited to 'src/gallium/drivers')
| -rw-r--r-- | src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/ppu/cell_state_emit.c | 4 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/ppu/cell_texture.c | 221 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/ppu/cell_texture.h | 4 | 
4 files changed, 83 insertions, 148 deletions
| diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 02721e8f38..2e3086c4fa 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -258,8 +258,6 @@ cell_set_sampler_textures(struct pipe_context *pipe,     }     cell->num_textures = num; -   cell_update_texture_mapping(cell); /* XXX temporary! */ -     cell->dirty |= CELL_NEW_TEXTURE;  } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 7090b4c99f..cae546b700 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -222,8 +222,8 @@ cell_emit_state(struct cell_context *cell)              uint level;              for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {                 texture->start[level] = NULL; -               texture->width[level] = 1; -               texture->height[level] = 1; +               texture->width[level] = 0; +               texture->height[level] = 0;              }           }        } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index ad3344aacd..4bd87590cb 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -150,15 +150,77 @@ cell_texture_release(struct pipe_screen *screen,  } -#if 0 + +/** + * Convert image from linear layout to tiled layout.  4-byte pixels. + */ +static void +swizzle_image_uint(uint w, uint h, uint tile_size, uint *dst, const uint *src) +{ +   const uint tile_size2 = tile_size * tile_size; +   const uint h_t = (h + tile_size - 1) / tile_size; +   const uint w_t = (w + tile_size - 1) / tile_size; + +   uint it, jt;  /* tile counters */ +   uint i, j;    /* intra-tile counters */ + +   /* loop over dest tiles */ +   for (it = 0; it < h_t; it++) { +      for (jt = 0; jt < w_t; jt++) { +         /* start of dest tile: */ +         uint *tdst = dst + (it * w_t + jt) * tile_size2; +         /* loop over texels in the tile */ +         uint tile_width = MIN2(tile_size, w); +         uint tile_height = MIN2(tile_size, h); +         for (i = 0; i < tile_height; i++) { +            for (j = 0; j < tile_width; j++) { +               const uint srci = it * tile_size + i; +               const uint srcj = jt * tile_size + j; +               ASSERT(srci < w); +               ASSERT(srcj < h); +               tdst[i * TILE_SIZE + j] = src[srci * w + srcj]; +            } +         } +      } +   } +} + + +/** + * Convert linear texture image data to tiled format for SPU usage. + */  static void -cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, -                    uint face, uint levelsMask) +cell_twiddle_texture(struct pipe_screen *screen, +                     struct pipe_surface *surface)  { -   /* XXX TO DO:  re-tile the texture data ... */ +   struct cell_texture *texture = cell_texture(surface->texture); +   const uint level = surface->level; +   const uint texWidth = texture->base.width[level]; +   const uint texHeight = texture->base.height[level]; +   const uint bufWidth = MAX2(texWidth, TILE_SIZE); +   const uint bufHeight = MAX2(texHeight, TILE_SIZE); +   const uint *src = +      (const uint *) pipe_buffer_map(screen, surface->buffer, +                                     PIPE_BUFFER_USAGE_CPU_READ); + +   switch (texture->base.format) { +   case PIPE_FORMAT_A8R8G8B8_UNORM: +      /* free old tiled data */ +      if (texture->tiled_data[level]) { +         align_free(texture->tiled_data[level]); +      } +      /* alloc new tiled data */ +      texture->tiled_data[level] = align_malloc(bufWidth * bufHeight * 4, 16); +      swizzle_image_uint(texWidth, texHeight, TILE_SIZE, +                         texture->tiled_data[level], src); +      break; +   default: +      printf("Unsupported texture format\n"); +      ; +   } +   pipe_buffer_unmap(screen, surface->buffer);  } -#endif  static struct pipe_surface * @@ -207,129 +269,12 @@ cell_get_tex_surface(struct pipe_screen *screen,  } - -/** - * Copy tile data from linear layout to tiled layout. - * XXX this should be rolled into the future surface-creation code. - * XXX also need "untile" code... - */ -static void -tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src) -{ -   const uint tile_size2 = tile_size * tile_size; -   const uint h_t = h / tile_size, w_t = w / tile_size; - -   uint it, jt;  /* tile counters */ -   uint i, j;    /* intra-tile counters */ - -   /* loop over dest tiles */ -   for (it = 0; it < h_t; it++) { -      for (jt = 0; jt < w_t; jt++) { -         /* start of dest tile: */ -         uint *tdst = dst + (it * w_t + jt) * tile_size2; -         /* loop over texels in the tile */ -         for (i = 0; i < tile_size; i++) { -            for (j = 0; j < tile_size; j++) { -               const uint srci = it * tile_size + i; -               const uint srcj = jt * tile_size + j; -               *tdst++ = src[srci * w + srcj]; -            } -         } -      } -   } -} - - - -/** - * Convert linear texture image data to tiled format for SPU usage. - * XXX recast this in terms of pipe_surfaces (aka texture views). - */ -static void -cell_tile_texture(struct cell_context *cell, -                  struct cell_texture *texture) -{ -   struct pipe_screen *screen = cell->pipe.screen; -   uint face = 0, level, zslice = 0; -   const uint *src; - -   for (level = 0; level <= texture->base.last_level; level++) { -      if (!texture->tiled_data[level]) { -         struct pipe_surface *surf; - -         const uint w = texture->base.width[level], h = texture->base.height[level]; - -         if (w < 32 || h < 32) -            continue; -         /* temporary restrictions: */ -         assert(w >= TILE_SIZE); -         assert(h >= TILE_SIZE); -         assert(w % TILE_SIZE == 0); -         assert(h % TILE_SIZE == 0); - -         surf = screen->get_tex_surface(screen, &texture->base, face, -                                        level, zslice, -                                        PIPE_BUFFER_USAGE_CPU_WRITE); -         ASSERT(surf); -          -         src = (const uint *) pipe_surface_map(surf, -                                               PIPE_BUFFER_USAGE_CPU_WRITE); - -         if (texture->tiled_data[level]) { -            align_free(texture->tiled_data[level]); -         } -         texture->tiled_data[level] = align_malloc(w * h * 4, 16); - -         tile_copy_data(w, h, TILE_SIZE, texture->tiled_data[level], src); - -         pipe_surface_unmap(surf); - -         pipe_surface_reference(&surf, NULL); -      } -   } -} - - -/** XXX temporary hack */ -void -cell_update_texture_mapping(struct cell_context *cell) -{ -#if 0 -   uint face = 0, level = 0, zslice = 0; -#endif -   uint i; - -   for (i = 0; i < CELL_MAX_SAMPLERS; i++) { -      if (cell->texture[i]) -         cell_tile_texture(cell, cell->texture[i]); -   } - -#if 0 -   if (cell->tex_surf && cell->tex_map) { -      pipe_surface_unmap(cell->tex_surf); -      cell->tex_map = NULL; -   } - -   /* XXX free old surface */ - -   cell->tex_surf = cell_get_tex_surface(&cell->pipe, -                                         &cell->texture[0]->base, -                                         face, level, zslice); - -   cell->tex_map = pipe_surface_map(cell->tex_surf); -#endif -} - -  static void   cell_tex_surface_release(struct pipe_screen *screen,                            struct pipe_surface **s)  { -   /* Effectively do the texture_update work here - if texture images -    * needed post-processing to put them into hardware layout, this is -    * where it would happen.  For softpipe, nothing to do. -    */ -   assert ((*s)->texture); +   /* XXX if done rendering to teximage, re-tile */ +     pipe_texture_reference(&(*s)->texture, NULL);      screen->winsys->surface_release(screen->winsys, s); @@ -351,22 +296,8 @@ cell_surface_map(struct pipe_screen *screen,     map = pipe_buffer_map( screen, surface->buffer, flags );     if (map == NULL)        return NULL; - -   /* May want to different things here depending on read/write nature -    * of the map: -    */ -   if (surface->texture && -       (flags & PIPE_BUFFER_USAGE_CPU_WRITE))  -   { -      /* Do something to notify sharing contexts of a texture change. -       * In softpipe, that would mean flushing the texture cache. -       */ -#if 0 -      cell_screen(screen)->timestamp++; -#endif -   } -    -   return (void *) (map + surface->offset); +   else +      return (void *) (map + surface->offset);  } @@ -374,6 +305,16 @@ static void  cell_surface_unmap(struct pipe_screen *screen,                     struct pipe_surface *surface)  { +   struct cell_texture *ct = cell_texture(surface->texture); + +   assert(ct); + +   if ((ct->base.tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) && +       (surface->usage & PIPE_BUFFER_USAGE_CPU_WRITE)) { +      /* convert from linear to tiled layout */ +      cell_twiddle_texture(screen, surface); +   } +     pipe_buffer_unmap( screen, surface->buffer );  } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 4647509743..a0757091b0 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -62,10 +62,6 @@ cell_texture(struct pipe_texture *pt)  extern void -cell_update_texture_mapping(struct cell_context *cell); - - -extern void  cell_init_screen_texture_funcs(struct pipe_screen *screen); | 
