#include <unistd.h>
#include "main/simple_list.h"
-#include "main/texcompress.h"
#include "main/teximage.h"
#include "main/texobj.h"
+#include "main/enums.h"
#include "radeon_texture.h"
+#include "radeon_tile.h"
static unsigned get_aligned_compressed_row_stride(
gl_format format,
unsigned width,
unsigned minStride)
{
- const unsigned blockSize = _mesa_get_format_bytes(format);
- unsigned blockWidth, blockHeight, numXBlocks;
+ const unsigned blockBytes = _mesa_get_format_bytes(format);
+ unsigned blockWidth, blockHeight;
+ unsigned stride;
_mesa_get_format_block_size(format, &blockWidth, &blockHeight);
- numXBlocks = (width + blockWidth - 1) / blockWidth;
-
- while (numXBlocks * blockSize < minStride)
- {
- ++numXBlocks;
- }
- return numXBlocks * blockSize;
+ /* Count number of blocks required to store the given width.
+ * And then multiple it with bytes required to store a block.
+ */
+ stride = (width + blockWidth - 1) / blockWidth * blockBytes;
+
+ /* Round the given minimum stride to the next full blocksize.
+ * (minStride + blockBytes - 1) / blockBytes * blockBytes
+ */
+ if ( stride < minStride )
+ stride = (minStride + blockBytes - 1) / blockBytes * blockBytes;
+
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "%s width %u, minStride %u, block(bytes %u, width %u):"
+ "stride %u\n",
+ __func__, width, minStride,
+ blockBytes, blockWidth,
+ stride);
+
+ return stride;
}
-static unsigned get_compressed_image_size(
+unsigned get_texture_image_size(
gl_format format,
unsigned rowStride,
- unsigned height)
+ unsigned height,
+ unsigned depth,
+ unsigned tiling)
{
- unsigned blockWidth, blockHeight;
+ if (_mesa_is_format_compressed(format)) {
+ unsigned blockWidth, blockHeight;
- _mesa_get_format_block_size(format, &blockWidth, &blockHeight);
+ _mesa_get_format_block_size(format, &blockWidth, &blockHeight);
+
+ return rowStride * ((height + blockHeight - 1) / blockHeight) * depth;
+ } else if (tiling) {
+ /* Need to align height to tile height */
+ unsigned tileWidth, tileHeight;
- return rowStride * ((height + blockHeight - 1) / blockHeight);
+ get_tile_size(format, &tileWidth, &tileHeight);
+ tileHeight--;
+
+ height = (height + tileHeight) & ~tileHeight;
+ }
+
+ return rowStride * height * depth;
}
-static int find_next_power_of_two(GLuint value)
+unsigned get_texture_image_row_stride(radeonContextPtr rmesa, gl_format format, unsigned width, unsigned tiling)
{
- int i, tmp;
+ if (_mesa_is_format_compressed(format)) {
+ return get_aligned_compressed_row_stride(format, width, rmesa->texture_compressed_row_align);
+ } else {
+ unsigned row_align;
+
+ if (!_mesa_is_pow_two(width)) {
+ row_align = rmesa->texture_rect_row_align - 1;
+ } else if (tiling) {
+ unsigned tileWidth, tileHeight;
+ get_tile_size(format, &tileWidth, &tileHeight);
+ row_align = tileWidth * _mesa_get_format_bytes(format) - 1;
+ } else {
+ row_align = rmesa->texture_row_align - 1;
+ }
- i = 0;
- tmp = value - 1;
- while (tmp) {
- tmp >>= 1;
- i++;
+ return (_mesa_format_row_stride(format, width) + row_align) & ~row_align;
}
- return (1 << i);
}
/**
GLuint face, GLuint level, GLuint* curOffset)
{
radeon_mipmap_level *lvl = &mt->levels[level];
- uint32_t row_align;
GLuint height;
- height = find_next_power_of_two(lvl->height);
-
- /* Find image size in bytes */
- if (_mesa_is_format_compressed(mt->mesaFormat)) {
- lvl->rowstride = get_aligned_compressed_row_stride(mt->mesaFormat, lvl->width, rmesa->texture_compressed_row_align);
- lvl->size = get_compressed_image_size(mt->mesaFormat, lvl->rowstride, height);
- } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
- row_align = rmesa->texture_rect_row_align - 1;
- lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
- lvl->size = lvl->rowstride * height;
- } else if (mt->tilebits & RADEON_TXO_MICRO_TILE) {
- /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
- * though the actual offset may be different (if texture is less than
- * 32 bytes width) to the untiled case */
- lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) * 2 + 31) & ~31;
- lvl->size = lvl->rowstride * ((height + 1) / 2) * lvl->depth;
- } else {
- row_align = rmesa->texture_row_align - 1;
- lvl->rowstride = (_mesa_format_row_stride(mt->mesaFormat, lvl->width) + row_align) & ~row_align;
- lvl->size = lvl->rowstride * height * lvl->depth;
- }
+ height = _mesa_next_pow_two_32(lvl->height);
+
+ lvl->rowstride = get_texture_image_row_stride(rmesa, mt->mesaFormat, lvl->width, mt->tilebits);
+ lvl->size = get_texture_image_size(mt->mesaFormat, lvl->rowstride, lvl->height, lvl->depth, mt->tilebits);
+
assert(lvl->size > 0);
- /* All images are aligned to a 32-byte offset */
- *curOffset = (*curOffset + 0x1f) & ~0x1f;
lvl->faces[face].offset = *curOffset;
*curOffset += lvl->size;
- if (RADEON_DEBUG & RADEON_TEXTURE)
- fprintf(stderr,
- "level %d, face %d: rs:%d %dx%d at %d\n",
- level, face, lvl->rowstride, lvl->width, height, lvl->faces[face].offset);
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "%s(%p) level %d, face %d: rs:%d %dx%d at %d\n",
+ __func__, rmesa,
+ level, face,
+ lvl->rowstride, lvl->width, height, lvl->faces[face].offset);
}
static GLuint minify(GLuint size, GLuint levels)
/* Note the required size in memory */
mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
+
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "%s(%p, %p) total size %d\n",
+ __func__, rmesa, mt, mt->totalsize);
}
static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_tree *mt)
/* Note the required size in memory */
mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
+
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "%s(%p, %p) total size %d\n",
+ __func__, rmesa, mt, mt->totalsize);
}
/**
{
radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
+ "%s(%p) new tree is %p.\n",
+ __func__, rmesa, mt);
+
mt->mesaFormat = mesaFormat;
mt->refcount = 1;
mt->target = target;
return;
}
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "%s(%p) target %s, min %d, max %d.\n",
+ __func__, tObj,
+ _mesa_lookup_enum_by_nr(tObj->Target),
+ minLod, maxLod);
+
/* save these values */
*pminLod = minLod;
*pmaxLod = maxLod;
firstImage = texObj->Image[0][texObj->BaseLevel];
numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1);
- if (RADEON_DEBUG & RADEON_TEXTURE) {
+ if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) {
fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj);
fprintf(stderr, "target %d vs %d\n", mt->target, texObj->Target);
fprintf(stderr, "format %d vs %d\n", mt->mesaFormat, firstImage->TexFormat);
assert(!t->mt);
- if (!texImg)
+ if (!texImg) {
+ radeon_warning("%s(%p) No image in given texture object(%p).\n",
+ __func__, rmesa, t);
return;
+ }
+
numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, texImg->MaxLog2 + 1);
assert(dstlvl->height == image->base.Height);
assert(dstlvl->depth == image->base.Depth);
+ radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
+ "%s miptree %p, image %p, face %d, level %d.\n",
+ __func__, mt, image, face, level);
+
radeon_bo_map(mt->bo, GL_TRUE);
dest = mt->bo->ptr + dstlvl->faces[face].offset;
radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
- /* TODO: bring back these assertions once the FBOs are fixed */
-#if 0
assert(image->mtlevel == level);
assert(srclvl->size == dstlvl->size);
assert(srclvl->rowstride == dstlvl->rowstride);
-#endif
radeon_bo_map(image->mt->bo, GL_FALSE);
/* This condition should be removed, it's here to workaround
* a segfault when mapping textures during software fallbacks.
*/
+ radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT,
+ "%s Trying to map texture in sowftware fallback.\n",
+ __func__);
const uint32_t srcrowstride = _mesa_format_row_stride(image->base.TexFormat, image->base.Width);
uint32_t rows = image->base.Height * image->base.Depth;
}
if (mtCount == 0) {
+ free(mtSizes);
+ free(mts);
return NULL;
}
calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod);
- if (RADEON_DEBUG & RADEON_TEXTURE)
- fprintf(stderr, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
- __FUNCTION__, texObj ,t->minLod, t->maxLod);
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
+ "%s: Validating texture %p now, minLod = %d, maxLod = %d\n",
+ __FUNCTION__, texObj ,t->minLod, t->maxLod);
radeon_mipmap_tree *dst_miptree;
dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod);
radeon_miptree_unreference(&t->mt);
radeon_try_alloc_miptree(rmesa, t);
dst_miptree = t->mt;
- if (RADEON_DEBUG & RADEON_TEXTURE) {
- fprintf(stderr, "%s: No matching miptree found, allocated new one %p\n", __FUNCTION__, t->mt);
- }
- } else if (RADEON_DEBUG & RADEON_TEXTURE) {
- fprintf(stderr, "%s: Using miptree %p\n", __FUNCTION__, t->mt);
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
+ "%s: No matching miptree found, allocated new one %p\n",
+ __FUNCTION__, t->mt);
+
+ } else {
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
+ "%s: Using miptree %p\n", __FUNCTION__, t->mt);
}
const unsigned faces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
for (level = t->minLod; level <= t->maxLod; ++level) {
img = get_radeon_texture_image(texObj->Image[face][level]);
- if (RADEON_DEBUG & RADEON_TEXTURE) {
- fprintf(stderr, "Checking image level %d, face %d, mt %p ... ", level, face, img->mt);
- }
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "Checking image level %d, face %d, mt %p ... ",
+ level, face, img->mt);
if (img->mt != dst_miptree) {
- if (RADEON_DEBUG & RADEON_TEXTURE) {
- fprintf(stderr, "MIGRATING\n");
- }
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE,
+ "MIGRATING\n");
+
struct radeon_bo *src_bo = (img->mt) ? img->mt->bo : img->bo;
if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) {
radeon_firevertices(rmesa);
}
migrate_image_to_miptree(dst_miptree, img, face, level);
- } else if (RADEON_DEBUG & RADEON_TEXTURE) {
- fprintf(stderr, "OK\n");
- }
+ } else
+ radeon_print(RADEON_TEXTURE, RADEON_TRACE, "OK\n");
}
}