* \param curOffset points to the offset at which the image is to be stored
* and is updated by this function according to the size of the image.
*/
-static void compute_tex_image_offset(radeon_mipmap_tree *mt,
+static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree *mt,
GLuint face, GLuint level, GLuint* curOffset)
{
radeon_mipmap_level *lvl = &mt->levels[level];
+ uint32_t row_align;
/* Find image size in bytes */
if (mt->compressed) {
/* TODO: Is this correct? Need test cases for compressed textures! */
- GLuint align;
-
- lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
+ row_align = rmesa->texture_compressed_row_align - 1;
+ lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx,
lvl->width, lvl->height, lvl->depth, mt->compressed);
} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
- lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
+ row_align = rmesa->texture_rect_row_align - 1;
+ lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
lvl->size = lvl->rowstride * lvl->height;
} else if (mt->tilebits & RADEON_TXO_MICRO_TILE) {
/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31;
lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
} else {
- lvl->rowstride = (lvl->width * mt->bpp + 31) & ~31;
+ row_align = rmesa->texture_row_align - 1;
+ lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
lvl->size = lvl->rowstride * lvl->height * lvl->depth;
}
assert(lvl->size > 0);
lvl->faces[face].offset = *curOffset;
*curOffset += lvl->size;
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr,
"level %d, face %d: rs:%d %dx%d at %d\n",
level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset);
return size;
}
-static void calculate_miptree_layout(radeon_mipmap_tree *mt)
+
+static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
+{
+ GLuint curOffset;
+ GLuint numLevels;
+ GLuint i;
+ GLuint face;
+
+ numLevels = mt->lastLevel - mt->firstLevel + 1;
+ assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
+
+ curOffset = 0;
+ for(face = 0; face < mt->faces; face++) {
+
+ for(i = 0; i < numLevels; i++) {
+ mt->levels[i].width = minify(mt->width0, i);
+ mt->levels[i].height = minify(mt->height0, i);
+ mt->levels[i].depth = minify(mt->depth0, i);
+ compute_tex_image_offset(rmesa, mt, face, i, &curOffset);
+ }
+ }
+
+ /* Note the required size in memory */
+ mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
+}
+
+static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
{
GLuint curOffset;
GLuint numLevels;
GLuint i;
numLevels = mt->lastLevel - mt->firstLevel + 1;
- assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
+ assert(numLevels <= rmesa->glCtx->Const.MaxTextureLevels);
curOffset = 0;
for(i = 0; i < numLevels; i++) {
mt->levels[i].depth = minify(mt->depth0, i);
for(face = 0; face < mt->faces; face++)
- compute_tex_image_offset(mt, face, i, &curOffset);
+ compute_tex_image_offset(rmesa, mt, face, i, &curOffset);
}
/* Note the required size in memory */
mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
}
-
/**
* Create a new mipmap tree, calculate its layout and allocate memory.
*/
radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
- GLenum target, GLuint firstLevel, GLuint lastLevel,
+ GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
GLuint width0, GLuint height0, GLuint depth0,
GLuint bpp, GLuint tilebits, GLuint compressed)
{
radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
mt->radeon = rmesa;
+ mt->internal_format = internal_format;
mt->refcount = 1;
mt->t = t;
mt->target = target;
mt->tilebits = tilebits;
mt->compressed = compressed;
- calculate_miptree_layout(mt);
+ if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R300)
+ calculate_miptree_layout_r300(rmesa, mt);
+ else
+ calculate_miptree_layout_r100(rmesa, mt);
mt->bo = radeon_bo_open(rmesa->radeonScreen->bom,
0, mt->totalsize, 1024,
if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
return GL_FALSE;
- if (texImage->IsCompressed != mt->compressed)
+ if (texImage->InternalFormat != mt->internal_format ||
+ texImage->IsCompressed != mt->compressed)
return GL_FALSE;
if (!texImage->IsCompressed &&
!mt->compressed &&
- texImage->TexFormat->TexelBytes != mt->bpp)
+ _mesa_get_format_bytes(texImage->TexFormat->MesaFormat) != mt->bpp)
return GL_FALSE;
lvl = &mt->levels[level - mt->firstLevel];
mt->width0 == firstImage->Width &&
mt->height0 == firstImage->Height &&
mt->depth0 == firstImage->Depth &&
- mt->bpp == firstImage->TexFormat->TexelBytes &&
- mt->compressed == compressed);
+ mt->compressed == compressed &&
+ (!mt->compressed ? (mt->bpp == firstImage->TexFormat->TexelBytes) : 1));
}
* given image in the given position.
*/
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
- struct gl_texture_image *texImage, GLuint face, GLuint level)
+ radeon_texture_image *image, GLuint face, GLuint level)
{
- GLuint compressed = texImage->IsCompressed ? texImage->TexFormat->MesaFormat : 0;
+ GLuint compressed = image->base.IsCompressed ? image->base.TexFormat->MesaFormat : 0;
GLuint numfaces = 1;
GLuint firstLevel, lastLevel;
return;
t->mt = radeon_miptree_create(rmesa, t, t->base.Target,
+ image->base.InternalFormat,
firstLevel, lastLevel,
- texImage->Width, texImage->Height, texImage->Depth,
- texImage->TexFormat->TexelBytes, t->tile_bits, compressed);
+ image->base.Width, image->base.Height, image->base.Depth,
+ image->base.TexFormat->TexelBytes, t->tile_bits, compressed);
}
/* Although we use the image_offset[] array to store relative offsets
*
* These functions present that view to mesa:
*/
-const GLuint *
-radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level)
+void
+radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets)
{
- static const GLuint zero = 0;
if (mt->target != GL_TEXTURE_3D || mt->faces == 1)
- return &zero;
- else
- return mt->levels[level].faces[0].offset;
+ offsets[0] = 0;
+ else {
+ int i;
+ for (i = 0; i < 6; i++)
+ offsets[i] = mt->levels[level].faces[i].offset;
+ }
}
GLuint