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_texture * | i915_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_surface * | i915_get_tex_surface (struct pipe_screen *screen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) |
static struct pipe_texture * | i915_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. |
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.
00768 { 00769 screen->texture_create = i915_texture_create; 00770 screen->texture_release = i915_texture_release; 00771 screen->get_tex_surface = i915_get_tex_surface; 00772 screen->texture_blanket = i915_texture_blanket; 00773 screen->tex_surface_release = i915_tex_surface_release; 00774 }
void i915_init_texture_functions | ( | struct i915_context * | i915 | ) |
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] |
const int initial_offsets[6][2] [static] |
Initial value:
{ {0, 0}, {0, 2}, {1, 0}, {1, 2}, {1, 1}, {1, 3} }
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} }
Definition at line 65 of file i915_texture.c.