i915_texture.c File Reference

Include dependency graph for i915_texture.c:

Go to the source code of this file.

Functions

static unsigned minify (unsigned d)
static unsigned power_of_two (unsigned x)
static unsigned round_up (unsigned n, unsigned multiple)
static void i915_miptree_set_level_info (struct i915_texture *tex, unsigned level, unsigned nr_images, unsigned w, unsigned h, unsigned d)
static void i915_miptree_set_image_offset (struct i915_texture *tex, unsigned level, unsigned img, unsigned x, unsigned y)
static boolean i915_displaytarget_layout (struct i915_texture *tex)
 Special case to deal with display targets.
static void i945_miptree_layout_2d (struct i915_texture *tex)
static void i945_miptree_layout_cube (struct i915_texture *tex)
static boolean i915_miptree_layout (struct i915_texture *tex)
static boolean i945_miptree_layout (struct i915_texture *tex)
static struct pipe_texturei915_texture_create (struct pipe_screen *screen, const struct pipe_texture *templat)
static void i915_texture_release (struct pipe_screen *screen, struct pipe_texture **pt)
static struct pipe_surfacei915_get_tex_surface (struct pipe_screen *screen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags)
static struct pipe_texturei915_texture_blanket (struct pipe_screen *screen, const struct pipe_texture *base, const unsigned *stride, struct pipe_buffer *buffer)
void i915_init_texture_functions (struct i915_context *i915)
static void i915_tex_surface_release (struct pipe_screen *screen, struct pipe_surface **surface)
void i915_init_screen_texture_functions (struct pipe_screen *screen)

Variables

static const int initial_offsets [6][2]
 Initial offset for Cube map.
static const int step_offsets [6][2]
 Step offsets for Cube map.


Function Documentation

static boolean i915_displaytarget_layout ( struct i915_texture tex  )  [static]

Special case to deal with display targets.

Definition at line 165 of file i915_texture.c.

References i915_texture::base, pipe_texture::block, pipe_texture::height, i915_miptree_set_image_offset(), i915_miptree_set_level_info(), pipe_texture::last_level, pipe_texture::nblocksx, pipe_texture::nblocksy, power_of_two(), round_up(), pipe_format_block::size, i915_texture::stride, i915_texture::tiled, i915_texture::total_nblocksy, and pipe_texture::width.

00166 {
00167    struct pipe_texture *pt = &tex->base;
00168 
00169    if (pt->last_level > 0 || pt->block.size != 4)
00170       return 0;
00171 
00172    i915_miptree_set_level_info( tex, 0, 1,
00173                                 tex->base.width[0],
00174                                 tex->base.height[0],
00175                                 1 );
00176    i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
00177 
00178    if (tex->base.width[0] >= 128) {
00179       tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
00180       tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
00181       tex->tiled = 1;
00182    } else {
00183       tex->stride = round_up(tex->base.nblocksx[0] * pt->block.size, 64);
00184       tex->total_nblocksy = tex->base.nblocksy[0];
00185    }
00186 
00187    /*
00188    printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
00189       tex->base.width[0], tex->base.height[0], pt->block.size,
00190       tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
00191    */
00192 
00193    return 1;
00194 }

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

Definition at line 660 of file i915_texture.c.

References assert, pipe_texture::block, pipe_surface::block, i915_texture::buffer, pipe_surface::buffer, CALLOC_STRUCT, pipe_texture::format, pipe_surface::format, pipe_texture::height, pipe_surface::height, i915_texture::image_offset, pipe_texture::nblocksx, pipe_surface::nblocksx, pipe_texture::nblocksy, pipe_surface::nblocksy, pipe_surface::offset, offset(), pipe_buffer_reference(), PIPE_SURFACE_STATUS_DEFINED, PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, pipe_texture_reference(), pipe_surface::refcount, pipe_surface::status, i915_texture::stride, pipe_surface::stride, pipe_texture::target, pipe_surface::texture, pipe_surface::usage, pipe_texture::width, pipe_surface::width, pipe_surface::winsys, and pipe_screen::winsys.

00664 {
00665    struct i915_texture *tex = (struct i915_texture *)pt;
00666    struct pipe_winsys *ws = screen->winsys;
00667    struct pipe_surface *ps;
00668    unsigned offset;  /* in bytes */
00669 
00670    if (pt->target == PIPE_TEXTURE_CUBE) {
00671       offset = tex->image_offset[level][face];
00672    }
00673    else if (pt->target == PIPE_TEXTURE_3D) {
00674       offset = tex->image_offset[level][zslice];
00675    }
00676    else {
00677       offset = tex->image_offset[level][0];
00678       assert(face == 0);
00679       assert(zslice == 0);
00680    }
00681 
00682    ps = CALLOC_STRUCT(pipe_surface);
00683    if (ps) {
00684       ps->refcount = 1;
00685       ps->winsys = ws;
00686       pipe_texture_reference(&ps->texture, pt);
00687       pipe_buffer_reference(screen, &ps->buffer, tex->buffer);
00688       ps->format = pt->format;
00689       ps->width = pt->width[level];
00690       ps->height = pt->height[level];
00691       ps->block = pt->block;
00692       ps->nblocksx = pt->nblocksx[level];
00693       ps->nblocksy = pt->nblocksy[level];
00694       ps->stride = tex->stride;
00695       ps->offset = offset;
00696       ps->usage = flags;
00697       ps->status = PIPE_SURFACE_STATUS_DEFINED;
00698    }
00699    return ps;
00700 }

void i915_init_screen_texture_functions ( struct pipe_screen screen  ) 

Definition at line 767 of file i915_texture.c.

References pipe_screen::get_tex_surface, i915_get_tex_surface(), i915_tex_surface_release(), i915_texture_blanket(), i915_texture_create(), i915_texture_release(), pipe_screen::tex_surface_release, pipe_screen::texture_blanket, pipe_screen::texture_create, and pipe_screen::texture_release.

void i915_init_texture_functions ( struct i915_context i915  ) 

Definition at line 737 of file i915_texture.c.

00738 {
00739 //   i915->pipe.texture_update = i915_texture_update;
00740 }

static boolean i915_miptree_layout ( struct i915_texture tex  )  [static]

Definition at line 365 of file i915_texture.c.

References assert, i915_texture::base, pipe_texture::block, pipe_texture::depth, pipe_texture::height, i915_miptree_set_image_offset(), i915_miptree_set_level_info(), initial_offsets, pipe_texture::last_level, MAX2, minify(), pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, round_up(), pipe_format_block::size, step_offsets, i915_texture::stride, pipe_texture::target, i915_texture::total_nblocksy, TRUE, and pipe_texture::width.

00366 {
00367    struct pipe_texture *pt = &tex->base;
00368    unsigned level;
00369 
00370    switch (pt->target) {
00371    case PIPE_TEXTURE_CUBE: {
00372          const unsigned nblocks = pt->nblocksx[0];
00373          unsigned face;
00374          unsigned width = pt->width[0], height = pt->height[0];
00375 
00376          assert(width == height); /* cubemap images are square */
00377 
00378          /* double pitch for cube layouts */
00379          tex->stride = round_up(nblocks * pt->block.size * 2, 4);
00380          tex->total_nblocksy = nblocks * 4;
00381 
00382          for (level = 0; level <= pt->last_level; level++) {
00383             i915_miptree_set_level_info(tex, level, 6,
00384                                          width, height,
00385                                          1);
00386             width /= 2;
00387             height /= 2;
00388          }
00389 
00390          for (face = 0; face < 6; face++) {
00391             unsigned x = initial_offsets[face][0] * nblocks;
00392             unsigned y = initial_offsets[face][1] * nblocks;
00393             unsigned d = nblocks;
00394 
00395             for (level = 0; level <= pt->last_level; level++) {
00396                i915_miptree_set_image_offset(tex, level, face, x, y);
00397                d >>= 1;
00398                x += step_offsets[face][0] * d;
00399                y += step_offsets[face][1] * d;
00400             }
00401          }
00402          break;
00403       }
00404    case PIPE_TEXTURE_3D:{
00405          unsigned width = pt->width[0];
00406          unsigned height = pt->height[0];
00407          unsigned depth = pt->depth[0];
00408          unsigned nblocksx = pt->nblocksx[0];
00409          unsigned nblocksy = pt->nblocksy[0];
00410          unsigned stack_nblocksy = 0;
00411 
00412          /* Calculate the size of a single slice. 
00413           */
00414          tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
00415 
00416          /* XXX: hardware expects/requires 9 levels at minimum.
00417           */
00418          for (level = 0; level <= MAX2(8, pt->last_level);
00419               level++) {
00420             i915_miptree_set_level_info(tex, level, depth,
00421                                         width, height, depth);
00422 
00423 
00424             stack_nblocksy += MAX2(2, nblocksy);
00425 
00426             width = minify(width);
00427             height = minify(height);
00428             depth = minify(depth);
00429             nblocksx = pf_get_nblocksx(&pt->block, width);
00430             nblocksy = pf_get_nblocksy(&pt->block, height);
00431          }
00432 
00433          /* Fixup depth image_offsets: 
00434           */
00435          depth = pt->depth[0];
00436          for (level = 0; level <= pt->last_level; level++) {
00437             unsigned i;
00438             for (i = 0; i < depth; i++) 
00439                i915_miptree_set_image_offset(tex, level, i,
00440                                              0, i * stack_nblocksy);
00441 
00442             depth = minify(depth);
00443          }
00444 
00445 
00446          /* Multiply slice size by texture depth for total size.  It's
00447           * remarkable how wasteful of memory the i915 texture layouts
00448           * are.  They are largely fixed in the i945.
00449           */
00450          tex->total_nblocksy = stack_nblocksy * pt->depth[0];
00451          break;
00452       }
00453 
00454    default:{
00455          unsigned width = pt->width[0];
00456          unsigned height = pt->height[0];
00457          unsigned nblocksx = pt->nblocksx[0];
00458          unsigned nblocksy = pt->nblocksy[0];
00459 
00460          tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
00461          tex->total_nblocksy = 0;
00462 
00463          for (level = 0; level <= pt->last_level; level++) {
00464             i915_miptree_set_level_info(tex, level, 1,
00465                                         width, height, 1);
00466             i915_miptree_set_image_offset(tex, level, 0,
00467                                           0, tex->total_nblocksy);
00468 
00469             nblocksy = round_up(MAX2(2, nblocksy), 2);
00470 
00471             tex->total_nblocksy += nblocksy;
00472 
00473             width = minify(width);
00474             height = minify(height);
00475             nblocksx = pf_get_nblocksx(&pt->block, width);
00476             nblocksy = pf_get_nblocksy(&pt->block, height);
00477          }
00478          break;
00479       }
00480    }
00481    /*
00482    DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
00483        tex->pitch,
00484        tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
00485    */
00486 
00487    return TRUE;
00488 }

static void i915_miptree_set_image_offset ( struct i915_texture tex,
unsigned  level,
unsigned  img,
unsigned  x,
unsigned  y 
) [static]

Definition at line 139 of file i915_texture.c.

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

00141 {
00142    if (img == 0 && level == 0)
00143       assert(x == 0 && y == 0);
00144 
00145    assert(img < tex->nr_images[level]);
00146 
00147    tex->image_offset[level][img] = y * tex->stride + x * tex->base.block.size;
00148 
00149    /*
00150    printf("%s level %d img %d pos %d,%d image_offset %x\n",
00151        __FUNCTION__, level, img, x, y, tex->image_offset[level][img]);
00152    */
00153 }

static void i915_miptree_set_level_info ( struct i915_texture tex,
unsigned  level,
unsigned  nr_images,
unsigned  w,
unsigned  h,
unsigned  d 
) [static]

Definition at line 101 of file i915_texture.c.

References assert, i915_texture::base, pipe_texture::block, pipe_texture::depth, FREE, pipe_texture::height, i915_texture::image_offset, MALLOC, pipe_texture::nblocksx, pipe_texture::nblocksy, i915_texture::nr_images, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_MAX_TEXTURE_LEVELS, and pipe_texture::width.

00105 {
00106    struct pipe_texture *pt = &tex->base;
00107 
00108    assert(level < PIPE_MAX_TEXTURE_LEVELS);
00109 
00110    pt->width[level] = w;
00111    pt->height[level] = h;
00112    pt->depth[level] = d;
00113    
00114    pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w);
00115    pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h);
00116 
00117    tex->nr_images[level] = nr_images;
00118 
00119    /*
00120    DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
00121        level, w, h, d, x, y, tex->level_offset[level]);
00122    */
00123 
00124    /* Not sure when this would happen, but anyway: 
00125     */
00126    if (tex->image_offset[level]) {
00127       FREE(tex->image_offset[level]);
00128       tex->image_offset[level] = NULL;
00129    }
00130 
00131    assert(nr_images);
00132    assert(!tex->image_offset[level]);
00133 
00134    tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
00135    tex->image_offset[level][0] = 0;
00136 }

static void i915_tex_surface_release ( struct pipe_screen screen,
struct pipe_surface **  surface 
) [static]

Definition at line 743 of file i915_texture.c.

References assert, pipe_surface::buffer, debug_printf(), FREE, pipe_buffer_reference(), PIPE_SURFACE_STATUS_CLEAR, pipe_texture_reference(), pipe_surface::refcount, pipe_surface::status, and pipe_surface::texture.

00745 {
00746    struct pipe_surface *surf = *surface;
00747 
00748    if (--surf->refcount == 0) {
00749 
00750       /* This really should not be possible, but it's actually
00751        * happening quite a bit...  Will fix.
00752        */
00753       if (surf->status == PIPE_SURFACE_STATUS_CLEAR) {
00754          debug_printf("XXX destroying a surface with pending clears...\n");
00755          assert(0);
00756       }
00757 
00758       pipe_texture_reference(&surf->texture, NULL);
00759       pipe_buffer_reference(screen, &surf->buffer, NULL);
00760       FREE(surf);
00761    }
00762 
00763    *surface = NULL;
00764 }

static struct pipe_texture* i915_texture_blanket ( struct pipe_screen screen,
const struct pipe_texture base,
const unsigned *  stride,
struct pipe_buffer buffer 
) [static, read]

Definition at line 703 of file i915_texture.c.

References assert, i915_texture::base, i915_texture::buffer, CALLOC_STRUCT, pipe_texture::depth, pipe_texture::height, i915_miptree_set_image_offset(), i915_miptree_set_level_info(), pipe_texture::last_level, pipe_buffer_reference(), PIPE_TEXTURE_2D, pipe_texture::refcount, pipe_texture::screen, i915_texture::stride, pipe_texture::target, and pipe_texture::width.

00707 {
00708    struct i915_texture *tex;
00709    assert(screen);
00710 
00711    /* Only supports one type */
00712    if (base->target != PIPE_TEXTURE_2D ||
00713        base->last_level != 0 ||
00714        base->depth[0] != 1) {
00715       return NULL;
00716    }
00717 
00718    tex = CALLOC_STRUCT(i915_texture);
00719    if (!tex)
00720       return NULL;
00721 
00722    tex->base = *base;
00723    tex->base.refcount = 1;
00724    tex->base.screen = screen;
00725 
00726    tex->stride = stride[0];
00727 
00728    i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
00729    i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
00730 
00731    pipe_buffer_reference(screen, &tex->buffer, buffer);
00732 
00733    return &tex->base;
00734 }

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

Definition at line 579 of file i915_texture.c.

References i915_texture::base, pipe_texture::block, i915_texture::buffer, pipe_winsys::buffer_create, pipe_winsys::buffer_map, pipe_winsys::buffer_unmap, CALLOC_STRUCT, FREE, pipe_texture::height, i915_miptree_layout(), i915_screen(), i945_miptree_layout(), i915_screen::is_i945, pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_BUFFER_USAGE_CPU_WRITE, PIPE_BUFFER_USAGE_PIXEL, pipe_texture::refcount, pipe_texture::screen, i915_texture::stride, i915_texture::total_nblocksy, pipe_texture::width, and pipe_screen::winsys.

00581 {
00582    struct i915_screen *i915screen = i915_screen(screen);
00583    struct pipe_winsys *ws = screen->winsys;
00584    struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
00585    size_t tex_size;
00586 
00587    if (!tex)
00588       return NULL;
00589 
00590    tex->base = *templat;
00591    tex->base.refcount = 1;
00592    tex->base.screen = screen;
00593 
00594    tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
00595    tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
00596    
00597    if (i915screen->is_i945) {
00598       if (!i945_miptree_layout(tex))
00599          goto fail;
00600    } else {
00601       if (!i915_miptree_layout(tex))
00602          goto fail;
00603    }
00604 
00605    tex_size = tex->stride * tex->total_nblocksy;
00606 
00607    tex->buffer = ws->buffer_create(ws, 64,
00608                                    PIPE_BUFFER_USAGE_PIXEL,
00609                                    tex_size);
00610 
00611    if (!tex->buffer)
00612       goto fail;
00613 
00614 #if 0
00615    void *ptr = ws->buffer_map(ws, tex->buffer,
00616       PIPE_BUFFER_USAGE_CPU_WRITE);
00617    memset(ptr, 0x80, tex_size);
00618    ws->buffer_unmap(ws, tex->buffer);
00619 #endif
00620 
00621    return &tex->base;
00622 
00623 fail:
00624    FREE(tex);
00625    return NULL;
00626 }

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

Definition at line 630 of file i915_texture.c.

References i915_texture::buffer, FREE, i915_texture::image_offset, pipe_buffer_reference(), and PIPE_MAX_TEXTURE_LEVELS.

00632 {
00633    if (!*pt)
00634       return;
00635 
00636    /*
00637    DBG("%s %p refcount will be %d\n",
00638        __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
00639    */
00640    if (--(*pt)->refcount <= 0) {
00641       struct i915_texture *tex = (struct i915_texture *)*pt;
00642       uint i;
00643 
00644       /*
00645       DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
00646       */
00647 
00648       pipe_buffer_reference(screen, &tex->buffer, NULL);
00649 
00650       for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
00651          if (tex->image_offset[i])
00652             FREE(tex->image_offset[i]);
00653 
00654       FREE(tex);
00655    }
00656    *pt = NULL;
00657 }

static boolean i945_miptree_layout ( struct i915_texture tex  )  [static]

Definition at line 492 of file i915_texture.c.

References assert, i915_texture::base, pipe_texture::block, pipe_texture::depth, FALSE, pipe_texture::height, i915_miptree_set_image_offset(), i915_miptree_set_level_info(), i945_miptree_layout_2d(), i945_miptree_layout_cube(), pipe_texture::last_level, MAX2, minify(), pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), PIPE_TEXTURE_1D, PIPE_TEXTURE_2D, PIPE_TEXTURE_3D, PIPE_TEXTURE_CUBE, round_up(), pipe_format_block::size, i915_texture::stride, pipe_texture::target, i915_texture::total_nblocksy, TRUE, and pipe_texture::width.

00493 {
00494    struct pipe_texture *pt = &tex->base;
00495    unsigned level;
00496 
00497    switch (pt->target) {
00498    case PIPE_TEXTURE_CUBE:
00499       i945_miptree_layout_cube(tex);
00500       break;
00501    case PIPE_TEXTURE_3D:{
00502          unsigned width = pt->width[0];
00503          unsigned height = pt->height[0];
00504          unsigned depth = pt->depth[0];
00505          unsigned nblocksx = pt->nblocksx[0];
00506          unsigned nblocksy = pt->nblocksy[0];
00507          unsigned pack_x_pitch, pack_x_nr;
00508          unsigned pack_y_pitch;
00509 
00510          tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
00511          tex->total_nblocksy = 0;
00512 
00513          pack_y_pitch = MAX2(pt->nblocksy[0], 2);
00514          pack_x_pitch = tex->stride / pt->block.size;
00515          pack_x_nr = 1;
00516 
00517          for (level = 0; level <= pt->last_level; level++) {
00518             unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
00519             int x = 0;
00520             int y = 0;
00521             unsigned q, j;
00522 
00523             i915_miptree_set_level_info(tex, level, nr_images,
00524                                         width, height, depth);
00525 
00526             for (q = 0; q < nr_images;) {
00527                for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
00528                   i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
00529                   x += pack_x_pitch;
00530                }
00531 
00532                x = 0;
00533                y += pack_y_pitch;
00534             }
00535 
00536 
00537             tex->total_nblocksy += y;
00538 
00539             if (pack_x_pitch > 4) {
00540                pack_x_pitch >>= 1;
00541                pack_x_nr <<= 1;
00542                assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
00543             }
00544 
00545             if (pack_y_pitch > 2) {
00546                pack_y_pitch >>= 1;
00547             }
00548 
00549             width = minify(width);
00550             height = minify(height);
00551             depth = minify(depth);
00552             nblocksx = pf_get_nblocksx(&pt->block, width);
00553             nblocksy = pf_get_nblocksy(&pt->block, height);
00554          }
00555          break;
00556       }
00557 
00558    case PIPE_TEXTURE_1D:
00559    case PIPE_TEXTURE_2D:
00560 //   case PIPE_TEXTURE_RECTANGLE:
00561          i945_miptree_layout_2d(tex);
00562          break;
00563    default:
00564       assert(0);
00565       return FALSE;
00566    }
00567 
00568    /*
00569    DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
00570        tex->pitch,
00571        tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
00572    */
00573 
00574    return TRUE;
00575 }

static void i945_miptree_layout_2d ( struct i915_texture tex  )  [static]

Definition at line 197 of file i915_texture.c.

References align(), i915_texture::base, pipe_texture::block, pipe_texture::height, i915_displaytarget_layout(), i915_miptree_set_image_offset(), i915_miptree_set_level_info(), pipe_texture::last_level, MAX2, minify(), pipe_texture::nblocksx, pipe_texture::nblocksy, pf_get_nblocksx(), pf_get_nblocksy(), round_up(), pipe_format_block::size, i915_texture::stride, i915_texture::total_nblocksy, and pipe_texture::width.

00198 {
00199    struct pipe_texture *pt = &tex->base;
00200    const int align_x = 2, align_y = 4;
00201    unsigned level;
00202    unsigned x = 0;
00203    unsigned y = 0;
00204    unsigned width = pt->width[0];
00205    unsigned height = pt->height[0];
00206    unsigned nblocksx = pt->nblocksx[0];
00207    unsigned nblocksy = pt->nblocksy[0];
00208 
00209 #if 0 /* used for tiled display targets */
00210    if (pt->last_level == 0 && pt->block.size == 4)
00211       if (i915_displaytarget_layout(tex))
00212          return;
00213 #endif
00214 
00215    tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
00216 
00217    /* May need to adjust pitch to accomodate the placement of
00218     * the 2nd mipmap level.  This occurs when the alignment
00219     * constraints of mipmap placement push the right edge of the
00220     * 2nd mipmap level out past the width of its parent.
00221     */
00222    if (pt->last_level > 0) {
00223       unsigned mip1_nblocksx 
00224          = align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
00225          + pf_get_nblocksx(&pt->block, minify(minify(width)));
00226 
00227       if (mip1_nblocksx > nblocksx)
00228          tex->stride = mip1_nblocksx * pt->block.size;
00229    }
00230 
00231    /* Pitch must be a whole number of dwords
00232     */
00233    tex->stride = align(tex->stride, 64);
00234    tex->total_nblocksy = 0;
00235 
00236    for (level = 0; level <= pt->last_level; level++) {
00237       i915_miptree_set_level_info(tex, level, 1, width, height, 1);
00238       i915_miptree_set_image_offset(tex, level, 0, x, y);
00239 
00240       nblocksy = align(nblocksy, align_y);
00241 
00242       /* Because the images are packed better, the final offset
00243        * might not be the maximal one:
00244        */
00245       tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy);
00246 
00247       /* Layout_below: step right after second mipmap level.
00248        */
00249       if (level == 1) {
00250          x += align(nblocksx, align_x);
00251       }
00252       else {
00253          y += nblocksy;
00254       }
00255 
00256       width  = minify(width);
00257       height = minify(height);
00258       nblocksx = pf_get_nblocksx(&pt->block, width);
00259       nblocksy = pf_get_nblocksy(&pt->block, height);
00260    }
00261 }

static void i945_miptree_layout_cube ( struct i915_texture tex  )  [static]

Definition at line 264 of file i915_texture.c.

References assert, i915_texture::base, pipe_texture::block, pipe_texture::height, i915_miptree_set_image_offset(), i915_miptree_set_level_info(), initial_offsets, pipe_texture::last_level, pipe_texture::nblocksx, PIPE_TEX_FACE_NEG_X, PIPE_TEX_FACE_NEG_Y, PIPE_TEX_FACE_NEG_Z, PIPE_TEX_FACE_POS_X, PIPE_TEX_FACE_POS_Y, PIPE_TEX_FACE_POS_Z, round_up(), pipe_format_block::size, step_offsets, i915_texture::stride, i915_texture::total_nblocksy, and pipe_texture::width.

00265 {
00266    struct pipe_texture *pt = &tex->base;
00267    unsigned level;
00268 
00269    const unsigned nblocks = pt->nblocksx[0];
00270    unsigned face;
00271    unsigned width = pt->width[0];
00272    unsigned height = pt->height[0];
00273 
00274    /*
00275    printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]);
00276    */
00277 
00278    assert(width == height); /* cubemap images are square */
00279 
00280    /*
00281     * XXX Should only be used for compressed formats. But lets
00282     * keep this code active just in case.
00283     *
00284     * Depending on the size of the largest images, pitch can be
00285     * determined either by the old-style packing of cubemap faces,
00286     * or the final row of 4x4, 2x2 and 1x1 faces below this.
00287     */
00288    if (nblocks > 32)
00289       tex->stride = round_up(nblocks * pt->block.size * 2, 4);
00290    else
00291       tex->stride = 14 * 8 * pt->block.size;
00292 
00293    tex->total_nblocksy = nblocks * 4;
00294 
00295    /* Set all the levels to effectively occupy the whole rectangular region.
00296    */
00297    for (level = 0; level <= pt->last_level; level++) {
00298       i915_miptree_set_level_info(tex, level, 6, width, height, 1);
00299       width /= 2;
00300       height /= 2;
00301    }
00302 
00303    for (face = 0; face < 6; face++) {
00304       unsigned x = initial_offsets[face][0] * nblocks;
00305       unsigned y = initial_offsets[face][1] * nblocks;
00306       unsigned d = nblocks;
00307 
00308 #if 0 /* Fix and enable this code for compressed formats */
00309       if (nblocks == 4 && face >= 4) {
00310          y = tex->total_height - 4;
00311          x = (face - 4) * 8;
00312       }
00313       else if (nblocks < 4 && (face > 0)) {
00314          y = tex->total_height - 4;
00315          x = face * 8;
00316       }
00317 #endif
00318 
00319       for (level = 0; level <= pt->last_level; level++) {
00320          i915_miptree_set_image_offset(tex, level, face, x, y);
00321 
00322          d >>= 1;
00323 
00324 #if 0 /* Fix and enable this code for compressed formats */
00325          switch (d) {
00326             case 4:
00327                switch (face) {
00328                   case PIPE_TEX_FACE_POS_X:
00329                   case PIPE_TEX_FACE_NEG_X:
00330                      x += step_offsets[face][0] * d;
00331                      y += step_offsets[face][1] * d;
00332                      break;
00333                   case PIPE_TEX_FACE_POS_Y:
00334                   case PIPE_TEX_FACE_NEG_Y:
00335                      y += 12;
00336                      x -= 8;
00337                      break;
00338                   case PIPE_TEX_FACE_POS_Z:
00339                   case PIPE_TEX_FACE_NEG_Z:
00340                      y = tex->total_height - 4;
00341                      x = (face - 4) * 8;
00342                      break;
00343                }
00344             case 2:
00345                y = tex->total_height - 4;
00346                x = 16 + face * 8;
00347                break;
00348 
00349             case 1:
00350                x += 48;
00351                break;
00352             default:
00353 #endif
00354                x += step_offsets[face][0] * d;
00355                y += step_offsets[face][1] * d;
00356 #if 0
00357                break;
00358          }
00359 #endif
00360       }
00361    }
00362 }

static unsigned minify ( unsigned  d  )  [static]

Definition at line 74 of file i915_texture.c.

References MAX2.

00075 {
00076    return MAX2(1, d>>1);
00077 }

static unsigned power_of_two ( unsigned  x  )  [static]

Definition at line 80 of file i915_texture.c.

00081 {
00082    unsigned value = 1;
00083    while (value < x)
00084       value = value << 1;
00085    return value;
00086 }

static unsigned round_up ( unsigned  n,
unsigned  multiple 
) [static]

Definition at line 89 of file i915_texture.c.

00090 {
00091    return (n + multiple - 1) & ~(multiple - 1);
00092 }


Variable Documentation

const int initial_offsets[6][2] [static]

Initial value:

 {
   {0, 0},
   {0, 2},
   {1, 0},
   {1, 2},
   {1, 1},
   {1, 3}
}
Initial offset for Cube map.

Definition at line 53 of file i915_texture.c.

const int step_offsets[6][2] [static]

Initial value:

 {
   {0, 2},
   {0, 2},
   {-1, 2},
   {-1, 2},
   {-1, 1},
   {-1, 1}
}
Step offsets for Cube map.

Definition at line 65 of file i915_texture.c.


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