summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c152
1 files changed, 85 insertions, 67 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index 033f26db2a..cd843d965e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -32,9 +32,9 @@
#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"
static unsigned get_aligned_compressed_row_stride(
@@ -42,18 +42,31 @@ static unsigned get_aligned_compressed_row_stride(
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(
@@ -68,19 +81,6 @@ static unsigned get_compressed_image_size(
return rowStride * ((height + blockHeight - 1) / blockHeight);
}
-static int find_next_power_of_two(GLuint value)
-{
- int i, tmp;
-
- i = 0;
- tmp = value - 1;
- while (tmp) {
- tmp >>= 1;
- i++;
- }
- return (1 << i);
-}
-
/**
* Compute sizes and fill in offset and blit information for the given
* image (determined by \p face and \p level).
@@ -95,7 +95,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
uint32_t row_align;
GLuint height;
- height = find_next_power_of_two(lvl->height);
+ height = _mesa_next_pow_two_32(lvl->height);
/* Find image size in bytes */
if (_mesa_is_format_compressed(mt->mesaFormat)) {
@@ -123,10 +123,11 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
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)
@@ -158,6 +159,10 @@ static void calculate_miptree_layout_r100(radeonContextPtr rmesa, radeon_mipmap_
/* 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)
@@ -177,10 +182,20 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_
for(face = 0; face < mt->faces; face++)
compute_tex_image_offset(rmesa, mt, face, level, &curOffset);
+ /* r600 cube levels seems to be aligned to 8 faces but
+ * we have separate register for 1'st level offset so add
+ * 2 image alignment after 1'st mip level */
+ if(rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R600 &&
+ mt->target == GL_TEXTURE_CUBE_MAP && level >= 1)
+ curOffset += 2 * mt->levels[level].size;
}
/* 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);
}
/**
@@ -192,6 +207,10 @@ static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa,
{
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;
@@ -282,6 +301,12 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj,
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;
@@ -328,7 +353,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g
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);
@@ -369,8 +394,12 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
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);
@@ -380,25 +409,6 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t)
texImg->Depth, t->tile_bits);
}
-/* Although we use the image_offset[] array to store relative offsets
- * to cube faces, Mesa doesn't know anything about this and expects
- * each cube face to be treated as a separate image.
- *
- * These functions present that view to mesa:
- */
-void
-radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets)
-{
- if (mt->target != GL_TEXTURE_3D || mt->faces == 1) {
- offsets[0] = 0;
- } else {
- int i;
- for (i = 0; i < 6; i++) {
- offsets[i] = mt->levels[level].faces[i].offset;
- }
- }
-}
-
GLuint
radeon_miptree_image_offset(radeon_mipmap_tree *mt,
GLuint face, GLuint level)
@@ -425,6 +435,10 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
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;
@@ -456,6 +470,9 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt,
/* 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;
@@ -562,9 +579,9 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
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);
@@ -573,11 +590,13 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
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;
@@ -588,22 +607,21 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
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");
}
}
@@ -619,4 +637,4 @@ uint32_t get_base_teximage_offset(radeonTexObj *texObj)
} else {
return radeon_miptree_image_offset(texObj->mt, 0, texObj->minLod);
}
-} \ No newline at end of file
+}