i915g: Fix cubemap layouts

This commit is contained in:
Jakob Bornecrantz
2010-04-17 14:55:23 +01:00
parent 762ed4db47
commit ed94e744d3

View File

@@ -55,26 +55,39 @@
* Initial offset for Cube map.
*/
static const int initial_offsets[6][2] = {
{0, 0},
{0, 2},
{1, 0},
{1, 2},
{1, 1},
{1, 3}
[PIPE_TEX_FACE_POS_X] = {0, 0},
[PIPE_TEX_FACE_POS_Y] = {1, 0},
[PIPE_TEX_FACE_POS_Z] = {1, 1},
[PIPE_TEX_FACE_NEG_X] = {0, 2},
[PIPE_TEX_FACE_NEG_Y] = {1, 2},
[PIPE_TEX_FACE_NEG_Z] = {1, 3},
};
/**
* Step offsets for Cube map.
*/
static const int step_offsets[6][2] = {
{0, 2},
{0, 2},
{-1, 2},
{-1, 2},
{-1, 1},
{-1, 1}
[PIPE_TEX_FACE_POS_X] = { 0, 2},
[PIPE_TEX_FACE_POS_Y] = {-1, 2},
[PIPE_TEX_FACE_POS_Z] = {-1, 1},
[PIPE_TEX_FACE_NEG_X] = { 0, 2},
[PIPE_TEX_FACE_NEG_Y] = {-1, 2},
[PIPE_TEX_FACE_NEG_Z] = {-1, 1},
};
/**
* For compressed level 2
*/
static const int bottom_offsets[6] = {
[PIPE_TEX_FACE_POS_X] = 16 + 0 * 8,
[PIPE_TEX_FACE_POS_Y] = 16 + 1 * 8,
[PIPE_TEX_FACE_POS_Z] = 16 + 2 * 8,
[PIPE_TEX_FACE_NEG_X] = 16 + 3 * 8,
[PIPE_TEX_FACE_NEG_Y] = 16 + 4 * 8,
[PIPE_TEX_FACE_NEG_Z] = 16 + 5 * 8,
};
/* XXX really need twice the size if x is already pot?
Otherwise just use util_next_power_of_two?
*/
@@ -221,6 +234,40 @@ i9x5_special_layout(struct i915_texture *tex)
return FALSE;
}
/**
* Cube layout used on i915 and for non-compressed textures on i945.
*/
static void
i9x5_texture_layout_cube(struct i915_texture *tex)
{
struct pipe_resource *pt = &tex->b.b;
const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
unsigned level;
unsigned face;
assert(pt->width0 == pt->height0); /* cubemap images are square */
/* double pitch for cube layouts */
tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
tex->total_nblocksy = nblocks * 4;
for (level = 0; level <= pt->last_level; level++)
i915_texture_set_level_info(tex, level, 6);
for (face = 0; face < 6; face++) {
unsigned x = initial_offsets[face][0] * nblocks;
unsigned y = initial_offsets[face][1] * nblocks;
unsigned d = nblocks;
for (level = 0; level <= pt->last_level; level++) {
i915_texture_set_image_offset(tex, level, face, x, y);
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
}
}
/*
* i915 layout functions
@@ -300,37 +347,6 @@ i915_texture_layout_3d(struct i915_texture *tex)
tex->total_nblocksy = stack_nblocksy * pt->depth0;
}
static void
i915_texture_layout_cube(struct i915_texture *tex)
{
struct pipe_resource *pt = &tex->b.b;
const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
unsigned level;
unsigned face;
assert(pt->width0 == pt->height0); /* cubemap images are square */
/* double pitch for cube layouts */
tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
tex->total_nblocksy = nblocks * 4;
for (level = 0; level <= pt->last_level; level++)
i915_texture_set_level_info(tex, level, 6);
for (face = 0; face < 6; face++) {
unsigned x = initial_offsets[face][0] * nblocks;
unsigned y = initial_offsets[face][1] * nblocks;
unsigned d = nblocks;
for (level = 0; level <= pt->last_level; level++) {
i915_texture_set_image_offset(tex, level, face, x, y);
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
}
}
}
static boolean
i915_texture_layout(struct i915_texture * tex)
{
@@ -346,7 +362,7 @@ i915_texture_layout(struct i915_texture * tex)
i915_texture_layout_3d(tex);
break;
case PIPE_TEXTURE_CUBE:
i915_texture_layout_cube(tex);
i9x5_texture_layout_cube(tex);
break;
default:
assert(0);
@@ -484,93 +500,94 @@ static void
i945_texture_layout_cube(struct i915_texture *tex)
{
struct pipe_resource *pt = &tex->b.b;
unsigned level;
const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
const unsigned dim = pt->width0;
unsigned level;
unsigned face;
/*
printf("%s %i, %i\n", __FUNCTION__, pt->width0, pt->height0);
*/
assert(pt->width0 == pt->height0); /* cubemap images are square */
assert(util_next_power_of_two(pt->width0) == pt->width0); /* npot only */
assert(util_format_is_s3tc(pt->format)); /* compressed only */
/*
* XXX Should only be used for compressed formats. But lets
* keep this code active just in case.
*
* Depending on the size of the largest images, pitch can be
* determined either by the old-style packing of cubemap faces,
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*
* 64 * 2 / 4 = 32
* 14 * 2 = 28
*/
if (nblocks > 32)
tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
if (pt->width0 >= 64)
tex->stride = nblocks * 2 * util_format_get_blocksize(pt->format);
else
tex->stride = 14 * 8 * util_format_get_blocksize(pt->format);
tex->stride = 14 * 2 * util_format_get_blocksize(pt->format);
tex->total_nblocksy = nblocks * 4;
/*
* Something similary apply for height as well.
*/
if (pt->width0 >= 4)
tex->total_nblocksy = nblocks * 4 + 1;
else
tex->total_nblocksy = 1;
/* Set all the levels to effectively occupy the whole rectangular region.
*/
/* Set all the levels to effectively occupy the whole rectangular region */
for (level = 0; level <= pt->last_level; level++)
i915_texture_set_level_info(tex, level, 6);
for (face = 0; face < 6; face++) {
unsigned x = initial_offsets[face][0] * nblocks;
unsigned y = initial_offsets[face][1] * nblocks;
unsigned d = nblocks;
/* all calculations in pixels */
unsigned total_height = tex->total_nblocksy * 4;
unsigned x = initial_offsets[face][0] * dim;
unsigned y = initial_offsets[face][1] * dim;
unsigned d = dim;
#if 0 /* Fix and enable this code for compressed formats */
if (nblocks == 4 && face >= 4) {
y = tex->total_height - 4;
if (dim == 4 && face >= 4) {
x = (face - 4) * 8;
}
else if (nblocks < 4 && (face > 0)) {
y = tex->total_height - 4;
y = tex->total_nblocksy * 4 - 4; /* 4 = 1 block */
} else if (dim < 4 && (face > 0)) {
x = face * 8;
y = total_height - 4;
}
#endif
for (level = 0; level <= pt->last_level; level++) {
i915_texture_set_image_offset(tex, level, face, x, y);
i915_texture_set_image_offset(tex, level, face,
util_format_get_nblocksx(pt->format, x),
util_format_get_nblocksy(pt->format, y));
d >>= 1;
#if 0 /* Fix and enable this code for compressed formats */
switch (d) {
case 4:
switch (face) {
case PIPE_TEX_FACE_POS_X:
case PIPE_TEX_FACE_NEG_X:
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
break;
case PIPE_TEX_FACE_POS_Y:
case PIPE_TEX_FACE_NEG_Y:
y += 12;
x -= 8;
break;
case PIPE_TEX_FACE_POS_Z:
case PIPE_TEX_FACE_NEG_Z:
y = tex->total_height - 4;
x = (face - 4) * 8;
break;
}
case 2:
y = tex->total_height - 4;
x = 16 + face * 8;
break;
case 1:
x += 48;
break;
default:
#endif
case 4:
switch (face) {
case PIPE_TEX_FACE_POS_X:
case PIPE_TEX_FACE_NEG_X:
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
#if 0
break;
case PIPE_TEX_FACE_POS_Y:
case PIPE_TEX_FACE_NEG_Y:
y += 12;
x -= 8;
break;
case PIPE_TEX_FACE_POS_Z:
case PIPE_TEX_FACE_NEG_Z:
y = total_height - 4;
x = (face - 4) * 8;
break;
}
break;
case 2:
y = total_height - 4;
x = bottom_offsets[face];
break;
case 1:
x += 48;
break;
default:
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
break;
}
#endif
}
}
}
@@ -590,7 +607,10 @@ i945_texture_layout(struct i915_texture * tex)
i945_texture_layout_3d(tex);
break;
case PIPE_TEXTURE_CUBE:
i945_texture_layout_cube(tex);
if (!util_format_is_s3tc(pt->format))
i9x5_texture_layout_cube(tex);
else
i945_texture_layout_cube(tex);
break;
default:
assert(0);