#include "main/glheader.h"
#include "main/imports.h"
#include "main/context.h"
+#include "main/convolve.h"
#include "main/mipmap.h"
+#include "main/texcompress.h"
#include "main/texformat.h"
#include "main/texstore.h"
#include "main/teximage.h"
#include "radeon_mipmap_tree.h"
+
+static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
+ GLuint numrows, GLuint rowsize)
+{
+ assert(rowsize <= dststride);
+ assert(rowsize <= srcstride);
+
+ if (rowsize == srcstride && rowsize == dststride) {
+ memcpy(dst, src, numrows*rowsize);
+ } else {
+ GLuint i;
+ for(i = 0; i < numrows; ++i) {
+ memcpy(dst, src, rowsize);
+ dst += dststride;
+ src += srcstride;
+ }
+ }
+}
+
/* textures */
/**
* Allocate an empty texture image object.
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 */
radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
+ if (t->mt &&
+ t->mt->firstLevel == level &&
+ t->mt->lastLevel == level &&
+ t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
+ !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+ radeon_miptree_unreference(t->mt);
+ t->mt = NULL;
+ }
+
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) {
} 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,
static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize,
GLenum format, GLenum type,
const GLvoid * pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
- int compressed)
+ int compressed)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
radeonTexObj* t = radeon_tex_obj(texObj);
radeon_firevertices(rmesa);
t->validated = GL_FALSE;
- pixels = _mesa_validate_pbo_teximage(ctx, dims,
- width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
+ if (compressed) {
+ pixels = _mesa_validate_pbo_compressed_teximage(
+ ctx, imageSize, pixels, packing, "glCompressedTexImage");
+ } else {
+ pixels = _mesa_validate_pbo_teximage(ctx, dims,
+ width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
+ }
if (pixels) {
GLint dstRowStride;
dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
}
- if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat, texImage->Data,
- xoffset, yoffset, zoffset,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing))
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
-
+ if (compressed) {
+ uint32_t srcRowStride, bytesPerRow, rows;
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+ srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+ bytesPerRow = srcRowStride;
+ rows = height / 4;
+
+ copy_rows(texImage->Data, dstRowStride, image->base.Data, srcRowStride, rows,
+ bytesPerRow);
+
+ } else {
+ if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat, texImage->Data,
+ xoffset, yoffset, zoffset,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing))
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+ }
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
+ radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0,
format, type, pixels, packing, texObj, texImage, 0);
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height,
- 1, format, type, pixels, packing, texObj, texImage,
+ radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+ 0, format, type, pixels, packing, texObj, texImage,
0);
}
struct gl_texture_image *texImage)
{
radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
- format, 0, data, 0, texObj, texImage, 1);
+ imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
+ radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0,
format, type, pixels, packing, texObj, texImage, 0);
}
-static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
- GLuint numrows, GLuint rowsize)
-{
- assert(rowsize <= dststride);
- assert(rowsize <= srcstride);
-
- if (rowsize == srcstride && rowsize == dststride) {
- memcpy(dst, src, numrows*rowsize);
- } else {
- GLuint i;
- for(i = 0; i < numrows; ++i) {
- memcpy(dst, src, rowsize);
- dst += dststride;
- src += srcstride;
- }
- }
-}
/**
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;
return GL_TRUE;
}
+
+
+/**
+ * Need to map texture image into memory before copying image data,
+ * then unmap it.
+ */
+static void
+radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid * pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage, int compressed)
+{
+ radeon_texture_image *image = get_radeon_texture_image(texImage);
+
+ if (image->mt) {
+ /* Map the texture image read-only */
+ radeon_teximage_map(image, GL_FALSE);
+ } else {
+ /* Image hasn't been uploaded to a miptree yet */
+ assert(image->base.Data);
+ }
+
+ if (compressed) {
+ _mesa_get_compressed_teximage(ctx, target, level, pixels,
+ texObj, texImage);
+ } else {
+ _mesa_get_teximage(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+ }
+
+ if (image->mt) {
+ radeon_teximage_unmap(image);
+ }
+}
+
+void
+radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid * pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_get_tex_image(ctx, target, level, format, type, pixels,
+ texObj, texImage, 0);
+}
+
+void
+radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
+ GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
+ texObj, texImage, 1);
+}