[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:
parent
b2f62609d0
commit
101abee6c4
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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() */
|
||||
|
|
Loading…
Reference in New Issue