brw_tex_layout.c File Reference

Include dependency graph for brw_tex_layout.c:

Go to the source code of this file.

Defines

#define FILE_DEBUG_FLAG   DEBUG_TEXTURE

Functions

static unsigned minify (unsigned d)
static void intel_miptree_set_image_offset (struct brw_texture *tex, unsigned level, unsigned img, unsigned x, unsigned y)
static void intel_miptree_set_level_info (struct brw_texture *tex, unsigned level, unsigned nr_images, unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
static void i945_miptree_layout_2d (struct brw_texture *tex)
static boolean brw_miptree_layout (struct brw_texture *tex)
static struct pipe_texturebrw_texture_create_screen (struct pipe_screen *screen, const struct pipe_texture *templat)
static void brw_texture_release_screen (struct pipe_screen *screen, struct pipe_texture **pt)
static struct pipe_surfacebrw_get_tex_surface_screen (struct pipe_screen *screen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice)
void brw_init_texture_functions (struct brw_context *brw)
void brw_init_screen_texture_funcs (struct pipe_screen *screen)


Define Documentation

#define FILE_DEBUG_FLAG   DEBUG_TEXTURE

Definition at line 47 of file brw_tex_layout.c.


Function Documentation

static struct pipe_surface* brw_get_tex_surface_screen ( struct pipe_screen screen,
struct pipe_texture pt,
unsigned  face,
unsigned  level,
unsigned  zslice 
) [static, read]

Definition at line 346 of file brw_tex_layout.c.

References assert, pipe_texture::block, pipe_surface::block, brw_texture::buffer, pipe_surface::buffer, pipe_texture::format, pipe_surface::format, pipe_texture::height, pipe_surface::height, brw_texture::image_offset, brw_texture::level_offset, pipe_texture::nblocksx, pipe_surface::nblocksx, pipe_texture::nblocksy, pipe_surface::nblocksy, pipe_surface::offset, offset(), PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, pipe_surface::refcount, brw_texture::stride, pipe_surface::stride, pipe_winsys::surface_alloc, pipe_texture::target, pipe_texture::width, pipe_surface::width, pipe_screen::winsys, and winsys_buffer_reference().

00349 {
00350    struct pipe_winsys *ws = screen->winsys;
00351    struct brw_texture *tex = (struct brw_texture *)pt;
00352    struct pipe_surface *ps;
00353    unsigned offset;  /* in bytes */
00354 
00355    offset = tex->level_offset[level];
00356 
00357    if (pt->target == PIPE_TEXTURE_CUBE) {
00358       offset += tex->image_offset[level][face];
00359    }
00360    else if (pt->target == PIPE_TEXTURE_3D) {
00361       offset += tex->image_offset[level][zslice];
00362    }
00363    else {
00364       assert(face == 0);
00365       assert(zslice == 0);
00366    }
00367 
00368    ps = ws->surface_alloc(ws);
00369    if (ps) {
00370       assert(ps->format);
00371       assert(ps->refcount);
00372       winsys_buffer_reference(ws, &ps->buffer, tex->buffer);
00373       ps->format = pt->format;
00374       ps->width = pt->width[level];
00375       ps->height = pt->height[level];
00376       ps->block = pt->block;
00377       ps->nblocksx = pt->nblocksx[level];
00378       ps->nblocksy = pt->nblocksy[level];
00379       ps->stride = tex->stride;
00380       ps->offset = offset;
00381    }
00382    return ps;
00383 }

void brw_init_screen_texture_funcs ( struct pipe_screen screen  ) 

Definition at line 394 of file brw_tex_layout.c.

References brw_get_tex_surface_screen(), brw_texture_create_screen(), brw_texture_release_screen(), pipe_screen::get_tex_surface, pipe_screen::texture_create, and pipe_screen::texture_release.

void brw_init_texture_functions ( struct brw_context brw  ) 

Definition at line 387 of file brw_tex_layout.c.

00388 {
00389 //   brw->pipe.texture_update = brw_texture_update;
00390 }

static boolean brw_miptree_layout ( struct brw_texture tex  )  [static]

Definition at line 186 of file brw_tex_layout.c.

References align(), assert, brw_texture::base, pipe_texture::block, pipe_texture::compressed, pipe_texture::depth, pipe_texture::height, i945_miptree_layout_2d(), intel_miptree_set_image_offset(), intel_miptree_set_level_info(), pipe_texture::last_level, minify(), pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, PRINT, pipe_format_block::size, brw_texture::stride, pipe_texture::target, brw_texture::total_nblocksy, TRUE, and pipe_texture::width.

00187 {
00188    struct pipe_texture *pt = &tex->base;
00189    /* XXX: these vary depending on image format:
00190     */
00191 /*    int align_w = 4; */
00192 
00193    switch (pt->target) {
00194    case PIPE_TEXTURE_CUBE:
00195    case PIPE_TEXTURE_3D: {
00196       unsigned width  = pt->width[0];
00197       unsigned height = pt->height[0];
00198       unsigned depth = pt->depth[0];
00199       unsigned nblocksx = pt->nblocksx[0];
00200       unsigned nblocksy = pt->nblocksy[0];
00201       unsigned pack_x_pitch, pack_x_nr;
00202       unsigned pack_y_pitch;
00203       unsigned level;
00204       unsigned align_h = 2;
00205       unsigned align_w = 4;
00206 
00207       tex->total_nblocksy = 0;
00208 
00209       tex->stride = align(pt->nblocksx[0], 4);
00210       pack_y_pitch = align(pt->nblocksy[0], align_h);
00211 
00212       pack_x_pitch = tex->stride / pt->block.size;
00213       pack_x_nr = 1;
00214 
00215       for (level = 0; level <= pt->last_level; level++) {
00216          unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
00217          int x = 0;
00218          int y = 0;
00219          uint q, j;
00220 
00221          intel_miptree_set_level_info(tex, level, nr_images,
00222                                       0, tex->total_nblocksy,
00223                                       width, height, depth);
00224 
00225          for (q = 0; q < nr_images;) {
00226             for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
00227                intel_miptree_set_image_offset(tex, level, q, x, y);
00228                x += pack_x_pitch;
00229             }
00230 
00231             x = 0;
00232             y += pack_y_pitch;
00233          }
00234 
00235 
00236          tex->total_nblocksy += y;
00237          width  = minify(width);
00238          height = minify(height);
00239          depth  = minify(depth);
00240          nblocksx = pf_get_nblocksx(&pt->block, width);
00241          nblocksy = pf_get_nblocksy(&pt->block, height);
00242 
00243          if (pt->compressed) {
00244             pack_y_pitch = (height + 3) / 4;
00245 
00246             if (pack_x_pitch > align(width, align_w)) {
00247                pack_x_pitch = align(width, align_w);
00248                pack_x_nr <<= 1;
00249             }
00250          } else {
00251             if (pack_x_pitch > 4) {
00252                pack_x_pitch >>= 1;
00253                pack_x_nr <<= 1;
00254                assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
00255             }
00256 
00257             if (pack_y_pitch > 2) {
00258                pack_y_pitch >>= 1;
00259                pack_y_pitch = align(pack_y_pitch, align_h);
00260             }
00261          }
00262 
00263       }
00264       break;
00265    }
00266 
00267    default:
00268       i945_miptree_layout_2d(tex);
00269       break;
00270    }
00271 #if 0
00272    PRINT("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
00273        pt->pitch,
00274        pt->total_nblocksy,
00275        pt->block.size,
00276        pt->stride * pt->total_nblocksy );
00277 #endif
00278 
00279    return TRUE;
00280 }

static struct pipe_texture* brw_texture_create_screen ( struct pipe_screen screen,
const struct pipe_texture templat 
) [static, read]

Definition at line 284 of file brw_tex_layout.c.

References brw_texture::base, pipe_texture::block, brw_miptree_layout(), brw_texture::buffer, pipe_winsys::buffer_create, CALLOC_STRUCT, FREE, pipe_texture::height, pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_BUFFER_USAGE_PIXEL, pipe_texture::refcount, brw_texture::stride, brw_texture::total_nblocksy, pipe_texture::width, and pipe_screen::winsys.

00286 {
00287    struct pipe_winsys *ws = screen->winsys;
00288    struct brw_texture *tex = CALLOC_STRUCT(brw_texture);
00289 
00290    if (tex) {
00291       tex->base = *templat;
00292       tex->base.refcount = 1;
00293 
00294       tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
00295       tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
00296    
00297       if (brw_miptree_layout(tex))
00298          tex->buffer = ws->buffer_create(ws, 64,
00299                                          PIPE_BUFFER_USAGE_PIXEL,
00300                                          tex->stride *
00301                                          tex->total_nblocksy);
00302 
00303       if (!tex->buffer) {
00304          FREE(tex);
00305          return NULL;
00306       }
00307    }
00308 
00309    return &tex->base;
00310 }

static void brw_texture_release_screen ( struct pipe_screen screen,
struct pipe_texture **  pt 
) [static]

Definition at line 314 of file brw_tex_layout.c.

References brw_texture::buffer, brw_texture::image_offset, PIPE_MAX_TEXTURE_LEVELS, pipe_screen::winsys, and winsys_buffer_reference().

00316 {
00317    if (!*pt)
00318       return;
00319 
00320    /*
00321    DBG("%s %p refcount will be %d\n",
00322        __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
00323    */
00324    if (--(*pt)->refcount <= 0) {
00325       struct pipe_winsys *ws = screen->winsys;
00326       struct brw_texture *tex = (struct brw_texture *)*pt;
00327       uint i;
00328 
00329       /*
00330       DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
00331       */
00332 
00333       winsys_buffer_reference(ws, &tex->buffer, NULL);
00334 
00335       for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
00336          if (tex->image_offset[i])
00337             free(tex->image_offset[i]);
00338 
00339       free(tex);
00340    }
00341    *pt = NULL;
00342 }

static void i945_miptree_layout_2d ( struct brw_texture tex  )  [static]

Definition at line 126 of file brw_tex_layout.c.

References align(), brw_texture::base, pipe_texture::block, pipe_texture::height, intel_miptree_set_level_info(), pipe_texture::last_level, MAX2, minify(), pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), pipe_format_block::size, brw_texture::stride, brw_texture::total_nblocksy, and pipe_texture::width.

00127 {
00128    struct pipe_texture *pt = &tex->base;
00129    const int align_x = 2, align_y = 4;
00130    unsigned level;
00131    unsigned x = 0;
00132    unsigned y = 0;
00133    unsigned width = pt->width[0];
00134    unsigned height = pt->height[0];
00135    unsigned nblocksx = pt->nblocksx[0];
00136    unsigned nblocksy = pt->nblocksy[0];
00137 
00138    tex->stride = align(pt->nblocksx[0] * pt->block.size, 4);
00139 
00140    /* May need to adjust pitch to accomodate the placement of
00141     * the 2nd mipmap level.  This occurs when the alignment
00142     * constraints of mipmap placement push the right edge of the
00143     * 2nd mipmap level out past the width of its parent.
00144     */
00145    if (pt->last_level > 0) {
00146       unsigned mip1_nblocksx 
00147          = align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
00148          + pf_get_nblocksx(&pt->block, minify(minify(width)));
00149 
00150       if (mip1_nblocksx > nblocksx)
00151          tex->stride = mip1_nblocksx * pt->block.size;
00152    }
00153 
00154    /* Pitch must be a whole number of dwords
00155     */
00156    tex->stride = align(tex->stride, 64);
00157    tex->total_nblocksy = 0;
00158 
00159    for (level = 0; level <= pt->last_level; level++) {
00160       intel_miptree_set_level_info(tex, level, 1, x, y, width,
00161                                    height, 1);
00162 
00163       nblocksy = align(nblocksy, align_y);
00164 
00165       /* Because the images are packed better, the final offset
00166        * might not be the maximal one:
00167        */
00168       tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy);
00169 
00170       /* Layout_below: step right after second mipmap level.
00171        */
00172       if (level == 1) {
00173          x += align(nblocksx, align_x);
00174       }
00175       else {
00176          y += nblocksy;
00177       }
00178 
00179       width  = minify(width);
00180       height = minify(height);
00181       nblocksx = pf_get_nblocksx(&pt->block, width);
00182       nblocksy = pf_get_nblocksy(&pt->block, height);
00183    }
00184 }

static void intel_miptree_set_image_offset ( struct brw_texture tex,
unsigned  level,
unsigned  img,
unsigned  x,
unsigned  y 
) [static]

Definition at line 74 of file brw_tex_layout.c.

References assert, brw_texture::base, pipe_texture::block, brw_texture::image_offset, pipe_format_block::size, and brw_texture::stride.

00078 {
00079    struct pipe_texture *pt = &tex->base;
00080    if (img == 0 && level == 0)
00081       assert(x == 0 && y == 0);
00082    assert(img < tex->nr_images[level]);
00083 
00084    tex->image_offset[level][img] = y * tex->stride + x * pt->block.size;
00085 }

static void intel_miptree_set_level_info ( struct brw_texture tex,
unsigned  level,
unsigned  nr_images,
unsigned  x,
unsigned  y,
unsigned  w,
unsigned  h,
unsigned  d 
) [static]

Definition at line 87 of file brw_tex_layout.c.

References assert, brw_texture::base, pipe_texture::block, pipe_texture::depth, FREE, pipe_texture::height, brw_texture::image_offset, brw_texture::level_offset, MALLOC, pipe_texture::nblocksx, pipe_texture::nblocksy, brw_texture::nr_images, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_MAX_TEXTURE_LEVELS, pipe_format_block::size, brw_texture::stride, and pipe_texture::width.

00092 {
00093    struct pipe_texture *pt = &tex->base;
00094 
00095    assert(level < PIPE_MAX_TEXTURE_LEVELS);
00096 
00097    pt->width[level] = w;
00098    pt->height[level] = h;
00099    pt->depth[level] = d;
00100    
00101    pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w);
00102    pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h);
00103 
00104    tex->level_offset[level] = y * tex->stride + x * tex->base.block.size;
00105    tex->nr_images[level] = nr_images;
00106 
00107    /*
00108    DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
00109        level, w, h, d, x, y, tex->level_offset[level]);
00110    */
00111 
00112    /* Not sure when this would happen, but anyway: 
00113     */
00114    if (tex->image_offset[level]) {
00115       FREE(tex->image_offset[level]);
00116       tex->image_offset[level] = NULL;
00117    }
00118 
00119    assert(nr_images);
00120    assert(!tex->image_offset[level]);
00121 
00122    tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
00123    tex->image_offset[level][0] = 0;
00124 }

static unsigned minify ( unsigned  d  )  [static]

Definition at line 68 of file brw_tex_layout.c.

References MAX2.

00069 {
00070    return MAX2(1, d>>1);
00071 }


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