return size;
}
+
+static int radeon_compressed_num_bytes(GLuint mesaFormat)
+{
+ int bytes = 0;
+ switch(mesaFormat) {
+
+ case MESA_FORMAT_RGB_FXT1:
+ case MESA_FORMAT_RGBA_FXT1:
+ case MESA_FORMAT_RGB_DXT1:
+ case MESA_FORMAT_RGBA_DXT1:
+ bytes = 2;
+ break;
+
+ case MESA_FORMAT_RGBA_DXT3:
+ case MESA_FORMAT_RGBA_DXT5:
+ bytes = 4;
+ default:
+ break;
+ }
+
+ return bytes;
+}
+
/**
* Compute sizes and fill in offset and blit information for the given
* image (determined by \p face and \p level).
/* TODO: Is this correct? Need test cases for compressed textures! */
GLuint align;
- if (mt->target == GL_TEXTURE_RECTANGLE_NV)
- align = 64 / mt->bpp;
- else
- align = 32 / mt->bpp;
- lvl->rowstride = (lvl->width + align - 1) & ~(align - 1);
+ lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx,
- lvl->width, lvl->height, lvl->depth, mt->compressed);
+ lvl->width, lvl->height, lvl->depth, mt->compressed);
} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
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,
+ /* 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 = (lvl->width * mt->bpp * 2 + 31) & ~31;
mt->width0 = width0;
mt->height0 = height0;
mt->depth0 = depth0;
- mt->bpp = bpp;
+ mt->bpp = compressed ? radeon_compressed_num_bytes(compressed) : bpp;
mt->tilebits = tilebits;
mt->compressed = compressed;
if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
return GL_FALSE;
- if (texImage->TexFormat->TexelBytes != mt->bpp)
+ if (texImage->IsCompressed != mt->compressed)
+ return GL_FALSE;
+
+ if (!texImage->IsCompressed &&
+ !mt->compressed &&
+ texImage->TexFormat->TexelBytes != mt->bpp)
return GL_FALSE;
lvl = &mt->levels[level - mt->firstLevel];
#include "main/imports.h"
#include "main/context.h"
#include "main/mipmap.h"
+#include "main/texcompress.h"
#include "main/texformat.h"
#include "main/texstore.h"
#include "main/teximage.h"
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
radeonTexObj* t = radeon_tex_obj(texObj);
radeon_texture_image* image = get_radeon_texture_image(texImage);
+ GLuint dstRowStride;
+ GLint postConvWidth = width;
+ GLint postConvHeight = height;
+ GLuint texelBytes;
radeon_firevertices(rmesa);
t->validated = GL_FALSE;
+ if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+ _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
+ &postConvHeight);
+ }
+
/* Choose and fill in the texture format for this image */
texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
_mesa_set_fetch_functions(texImage, dims);
if (texImage->TexFormat->TexelBytes == 0) {
+ texelBytes = 0;
texImage->IsCompressed = GL_TRUE;
texImage->CompressedSize =
ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
} else {
texImage->IsCompressed = GL_FALSE;
texImage->CompressedSize = 0;
+
+ texelBytes = texImage->TexFormat->TexelBytes;
+ /* Minimum pitch of 32 bytes */
+ if (postConvWidth * texelBytes < 32) {
+ postConvWidth = 32 / texelBytes;
+ texImage->RowStride = postConvWidth;
+ }
+ if (!image->mt) {
+ assert(texImage->RowStride == postConvWidth);
+ }
}
/* Allocate memory for image */
if (!t->mt)
radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+ radeon_mipmap_level *lvl;
image->mt = t->mt;
image->mtlevel = level - t->mt->firstLevel;
image->mtface = face;
radeon_miptree_reference(t->mt);
+ lvl = &image->mt->levels[image->mtlevel];
+ dstRowStride = lvl->rowstride;
} else {
int size;
if (texImage->IsCompressed) {
size = texImage->CompressedSize;
+ dstRowStride =
+ _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
} else {
size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
+ dstRowStride = postConvWidth * texelBytes;
}
texImage->Data = _mesa_alloc_texmemory(size);
}
if (compressed) {
memcpy(texImage->Data, pixels, imageSize);
} else {
- GLuint dstRowStride;
- if (image->mt) {
- radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
- dstRowStride = lvl->rowstride;
- } else {
- dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
- }
if (!texImage->TexFormat->StoreImage(ctx, dims,
texImage->_BaseFormat,
texImage->TexFormat,
radeon_generate_mipmap(ctx, texObj->Target, texObj);
}
- if (pixels)
- radeon_teximage_unmap(image);
-
_mesa_unmap_teximage_pbo(ctx, packing);
+ if (pixels)
+ radeon_teximage_unmap(image);
+
}
GLuint face = radeon_face_for_target(target);
radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
- imageSize, 0, 0, data, 0, texObj, texImage, 1);
+ imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
}
void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
radeon_miptree_unreference(image->mt);
} else {
- uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
+ uint32_t srcrowstride;
+ uint32_t height;
+ /* need to confirm this value is correct */
+ if (mt->compressed) {
+ height = image->base.Height / 4;
+ srcrowstride = image->base.RowStride * mt->bpp;
+ } else {
+ height = image->base.Height * image->base.Depth;
+ srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
+ }
// if (mt->tilebits)
// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
- image->base.Height * image->base.Depth, srcrowstride);
+ height, srcrowstride);
_mesa_free_texmemory(image->base.Data);
image->base.Data = 0;