[intel] Fix and reenable (software) SGIS_generate_mipmap

The core problem was that _mesa_generate_mipmap was not respecting RowStride
of the source image.  Additionally, the intel private data associated with the
images (level and face) was not being initialized for the
_mesa_generate_mipmap-generated images.
This commit is contained in:
Eric Anholt 2007-12-19 14:26:14 -08:00
parent b2f62609d0
commit 101abee6c4
10 changed files with 117 additions and 67 deletions

View File

@ -202,7 +202,7 @@ const struct dri_extension card_extensions[] = {
{"GL_NV_blend_square", NULL},
{"GL_NV_vertex_program", GL_NV_vertex_program_functions},
{"GL_NV_vertex_program1_1", NULL},
/* { "GL_SGIS_generate_mipmap", NULL }, */
{ "GL_SGIS_generate_mipmap", NULL },
{NULL, NULL}
};

View File

@ -351,7 +351,7 @@ intel_miptree_image_data(struct intel_context *intel,
GLuint i;
GLuint height = 0;
DBG("%s\n", __FUNCTION__);
DBG("%s: %d/%d\n", __FUNCTION__, face, level);
for (i = 0; i < depth; i++) {
height = dst->level[level].height;
if(dst->compressed)

View File

@ -1,5 +1,6 @@
#include "swrast/swrast.h"
#include "texobj.h"
#include "mipmap.h"
#include "intel_context.h"
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
@ -156,6 +157,46 @@ timed_memcpy(void *dest, const void *src, size_t n)
}
#endif /* DO_DEBUG */
/**
* Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap
* level).
*
* The texture object's miptree must be mapped.
*
* It would be really nice if this was just called by Mesa whenever mipmaps
* needed to be regenerated, rather than us having to remember to do so in
* each texture image modification path.
*
* This function should also include an accelerated path.
*/
void
intel_generate_mipmap(GLcontext *ctx, GLenum target,
const struct gl_texture_unit *texUnit,
struct gl_texture_object *texObj)
{
struct intel_texture_object *intelObj = intel_texture_object(texObj);
GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
int face, i;
_mesa_generate_mipmap(ctx, target, texUnit, texObj);
/* Update the level information in our private data in the new images, since
* it didn't get set as part of a normal TexImage path.
*/
for (face = 0; face < nr_faces; face++) {
for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
struct intel_texture_image *intelImage;
intelImage = intel_texture_image(texObj->Image[face][i]);
if (intelImage == NULL)
break;
intelImage->level = i;
intelImage->face = face;
}
}
}
void
intelInitTextureFuncs(struct dd_function_table *functions)

View File

@ -148,4 +148,8 @@ void intel_tex_unmap_images(struct intel_context *intel,
int intel_compressed_num_bytes(GLuint mesaFormat);
void intel_generate_mipmap(GLcontext *ctx, GLenum target,
const struct gl_texture_unit *texUnit,
struct gl_texture_object *texObj);
#endif

View File

@ -29,6 +29,7 @@
#include "enums.h"
#include "image.h"
#include "teximage.h"
#include "mipmap.h"
#include "swrast/swrast.h"
#include "intel_screen.h"
@ -85,12 +86,14 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat)
static GLboolean
do_copy_texsubimage(struct intel_context *intel,
GLenum target,
struct intel_texture_image *intelImage,
GLenum internalFormat,
GLint dstx, GLint dsty,
GLint x, GLint y, GLsizei width, GLsizei height)
{
GLcontext *ctx = &intel->ctx;
struct gl_texture_object *texObj = intelImage->base.TexObject;
const struct intel_region *src =
get_teximage_source(intel, internalFormat);
@ -156,16 +159,12 @@ do_copy_texsubimage(struct intel_context *intel,
UNLOCK_HARDWARE(intel);
#if 0
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
* XXX Add a ctx->Driver.GenerateMipmaps() function?
*/
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
/* GL_SGIS_generate_mipmap */
if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) {
intel_generate_mipmap(ctx, target,
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
#endif
return GL_TRUE;
}
@ -197,7 +196,7 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
GL_RGBA, CHAN_TYPE, NULL,
&ctx->DefaultPacking, texObj, texImage);
if (!do_copy_texsubimage(intel_context(ctx),
if (!do_copy_texsubimage(intel_context(ctx), target,
intel_texture_image(texImage),
internalFormat, 0, 0, x, y, width, 1))
goto fail;
@ -234,7 +233,7 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
&ctx->DefaultPacking, texObj, texImage);
if (!do_copy_texsubimage(intel_context(ctx),
if (!do_copy_texsubimage(intel_context(ctx), target,
intel_texture_image(texImage),
internalFormat, 0, 0, x, y, width, height))
goto fail;
@ -264,7 +263,7 @@ intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
/* Need to check texture is compatible with source format.
*/
if (!do_copy_texsubimage(intel_context(ctx),
if (!do_copy_texsubimage(intel_context(ctx), target,
intel_texture_image(texImage),
internalFormat, xoffset, 0, x, y, width, 1)) {
_swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width);
@ -290,7 +289,7 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
/* Need to check texture is compatible with source format.
*/
if (!do_copy_texsubimage(intel_context(ctx),
if (!do_copy_texsubimage(intel_context(ctx), target,
intel_texture_image(texImage),
internalFormat,
xoffset, yoffset, x, y, width, height)) {

View File

@ -466,6 +466,7 @@ intelTexImage(GLcontext * ctx,
intelImage->level,
&dstRowStride,
intelImage->base.ImageOffsets);
texImage->RowStride = dstRowStride / intelImage->mt->cpp;
}
else {
/* Allocate regular memory and store the image there temporarily. */
@ -483,8 +484,8 @@ intelTexImage(GLcontext * ctx,
texImage->Data = malloc(sizeInBytes);
}
DBG("Upload image %dx%dx%d row_len %x "
"pitch %x\n",
DBG("Upload image %dx%dx%d row_len %d "
"pitch %d\n",
width, height, depth, width * texelBytes, dstRowStride);
/* Copy data. Would like to know when it's ok for us to eg. use
@ -504,6 +505,13 @@ intelTexImage(GLcontext * ctx,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
}
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
intel_generate_mipmap(ctx, target,
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
_mesa_unmap_teximage_pbo(ctx, unpack);
if (intelImage->mt) {
@ -512,16 +520,6 @@ intelTexImage(GLcontext * ctx,
}
UNLOCK_HARDWARE(intel);
#if 0
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
*/
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
intel_generate_mipmap(ctx, target,
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
#endif
}
void

View File

@ -90,14 +90,12 @@ intelTexSubimage(GLcontext * ctx,
_mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
}
#if 0
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target,
intel_generate_mipmap(ctx, target,
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
texObj);
}
#endif
_mesa_unmap_teximage_pbo(ctx, packing);

View File

@ -75,6 +75,10 @@ intel_calculate_first_last_level(struct intel_texture_object *intelObj)
intelObj->lastLevel = lastLevel;
}
/**
* Copies the image's contents at its level into the object's miptree,
* and updates the image to point at the object's miptree.
*/
static void
copy_image_data_to_tree(struct intel_context *intel,
struct intel_texture_object *intelObj,

View File

@ -531,20 +531,19 @@ make_1d_mipmap(const struct gl_texture_format *format, GLint border,
}
/**
* XXX need to use the tex image's row stride!
*/
static void
make_2d_mipmap(const struct gl_texture_format *format, GLint border,
GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
GLint srcWidth, GLint srcHeight,
const GLubyte *srcPtr, GLint srcRowStride,
GLint dstWidth, GLint dstHeight,
GLubyte *dstPtr, GLint dstRowStride)
{
const GLint bpt = format->TexelBytes;
const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
const GLint dstWidthNB = dstWidth - 2 * border;
const GLint dstHeightNB = dstHeight - 2 * border;
const GLint srcRowStride = bpt * srcWidth;
const GLint dstRowStride = bpt * dstWidth;
const GLint srcRowBytes = bpt * srcRowStride;
const GLint dstRowBytes = bpt * dstRowStride;
const GLubyte *srcA, *srcB;
GLubyte *dst;
GLint row;
@ -552,7 +551,7 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border,
/* Compute src and dst pointers, skipping any border */
srcA = srcPtr + border * ((srcWidth + 1) * bpt);
if (srcHeight > 1)
srcB = srcA + srcRowStride;
srcB = srcA + srcRowBytes;
else
srcB = srcA;
dst = dstPtr + border * ((dstWidth + 1) * bpt);
@ -560,9 +559,9 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border,
for (row = 0; row < dstHeightNB; row++) {
do_row(format, srcWidthNB, srcA, srcB,
dstWidthNB, dst);
srcA += 2 * srcRowStride;
srcB += 2 * srcRowStride;
dst += dstRowStride;
srcA += 2 * srcRowBytes;
srcB += 2 * srcRowBytes;
dst += dstRowBytes;
}
/* This is ugly but probably won't be used much */
@ -620,9 +619,9 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border,
static void
make_3d_mipmap(const struct gl_texture_format *format, GLint border,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
const GLubyte *srcPtr,
const GLubyte *srcPtr, GLint srcRowStride,
GLint dstWidth, GLint dstHeight, GLint dstDepth,
GLubyte *dstPtr)
GLubyte *dstPtr, GLint dstRowStride)
{
const GLint bpt = format->TexelBytes;
const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
@ -717,13 +716,13 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border,
/* Luckily we can leverage the make_2d_mipmap() function here! */
if (border > 0) {
/* do front border image */
make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
dstWidth, dstHeight, dstPtr);
make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, srcRowStride,
dstWidth, dstHeight, dstPtr, dstRowStride);
/* do back border image */
make_2d_mipmap(format, 1, srcWidth, srcHeight,
srcPtr + bytesPerSrcImage * (srcDepth - 1),
srcPtr + bytesPerSrcImage * (srcDepth - 1), srcRowStride,
dstWidth, dstHeight,
dstPtr + bytesPerDstImage * (dstDepth - 1));
dstPtr + bytesPerDstImage * (dstDepth - 1), dstRowStride);
/* do four remaining border edges that span the image slices */
if (srcDepth == dstDepth) {
/* just copy border pixels from src to dst */
@ -798,15 +797,16 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border,
static void
make_1d_stack_mipmap(const struct gl_texture_format *format, GLint border,
GLint srcWidth, const GLubyte *srcPtr,
GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
GLint srcWidth, const GLubyte *srcPtr, GLuint srcRowStride,
GLint dstWidth, GLint dstHeight,
GLubyte *dstPtr, GLuint dstRowStride )
{
const GLint bpt = format->TexelBytes;
const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
const GLint dstWidthNB = dstWidth - 2 * border;
const GLint dstHeightNB = dstHeight - 2 * border;
const GLint srcRowStride = bpt * srcWidth;
const GLint dstRowStride = bpt * dstWidth;
const GLint srcRowBytes = bpt * srcRowStride;
const GLint dstRowBytes = bpt * dstRowStride;
const GLubyte *src;
GLubyte *dst;
GLint row;
@ -818,8 +818,8 @@ make_1d_stack_mipmap(const struct gl_texture_format *format, GLint border,
for (row = 0; row < dstHeightNB; row++) {
do_row(format, srcWidthNB, src, src,
dstWidthNB, dst);
src += srcRowStride;
dst += dstRowStride;
src += srcRowBytes;
dst += dstRowBytes;
}
if (border) {
@ -840,17 +840,18 @@ make_1d_stack_mipmap(const struct gl_texture_format *format, GLint border,
*/
static void
make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border,
GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
GLint srcWidth, GLint srcHeight,
const GLubyte *srcPtr, GLint srcRowStride,
GLint dstWidth, GLint dstHeight, GLint dstDepth,
GLubyte *dstPtr)
GLubyte *dstPtr, GLint dstRowStride)
{
const GLint bpt = format->TexelBytes;
const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
const GLint dstWidthNB = dstWidth - 2 * border;
const GLint dstHeightNB = dstHeight - 2 * border;
const GLint dstDepthNB = dstDepth - 2 * border;
const GLint srcRowStride = bpt * srcWidth;
const GLint dstRowStride = bpt * dstWidth;
const GLint srcRowBytes = bpt * srcRowStride;
const GLint dstRowBytes = bpt * dstRowStride;
const GLubyte *srcA, *srcB;
GLubyte *dst;
GLint layer;
@ -859,7 +860,7 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border,
/* Compute src and dst pointers, skipping any border */
srcA = srcPtr + border * ((srcWidth + 1) * bpt);
if (srcHeight > 1)
srcB = srcA + srcRowStride;
srcB = srcA + srcRowBytes;
else
srcB = srcA;
dst = dstPtr + border * ((dstWidth + 1) * bpt);
@ -868,9 +869,9 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border,
for (row = 0; row < dstHeightNB; row++) {
do_row(format, srcWidthNB, srcA, srcB,
dstWidthNB, dst);
srcA += 2 * srcRowStride;
srcB += 2 * srcRowStride;
dst += dstRowStride;
srcA += 2 * srcRowBytes;
srcB += 2 * srcRowBytes;
dst += dstRowBytes;
}
/* This is ugly but probably won't be used much */
@ -1132,23 +1133,28 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
make_2d_mipmap(convertFormat, border,
srcWidth, srcHeight, srcData,
dstWidth, dstHeight, dstData);
srcWidth, srcHeight, srcData, srcImage->RowStride,
dstWidth, dstHeight, dstData, dstImage->RowStride);
break;
case GL_TEXTURE_3D:
make_3d_mipmap(convertFormat, border,
srcWidth, srcHeight, srcDepth, srcData,
dstWidth, dstHeight, dstDepth, dstData);
srcWidth, srcHeight, srcDepth,
srcData, srcImage->RowStride,
dstWidth, dstHeight, dstDepth,
dstData, dstImage->RowStride);
break;
case GL_TEXTURE_1D_ARRAY_EXT:
make_1d_stack_mipmap(convertFormat, border,
srcWidth, srcData,
dstWidth, dstHeight, dstData);
srcWidth, srcData, srcImage->RowStride,
dstWidth, dstHeight,
dstData, dstImage->RowStride);
break;
case GL_TEXTURE_2D_ARRAY_EXT:
make_2d_stack_mipmap(convertFormat, border,
srcWidth, srcHeight, srcData,
dstWidth, dstHeight, dstDepth, dstData);
srcWidth, srcHeight,
srcData, srcImage->RowStride,
dstWidth, dstHeight,
dstDepth, dstData, dstImage->RowStride);
break;
case GL_TEXTURE_RECTANGLE_NV:
/* no mipmaps, do nothing */

View File

@ -1365,7 +1365,7 @@ struct gl_texture_image
GLboolean IsCompressed; /**< GL_ARB_texture_compression */
GLuint CompressedSize; /**< GL_ARB_texture_compression */
GLuint RowStride; /**< == Width unless IsClientData and padded */
GLuint RowStride; /**< Padded width in units of texels */
GLuint *ImageOffsets; /**< if 3D texture: array [Depth] of offsets to
each 2D slice in 'Data', in texels */
GLvoid *Data; /**< Image data, accessed via FetchTexel() */