}
- if (!baseImage || baseImage->IsCompressed) {
+/**
+ * Check if the call to _mesa_meta_GenerateMipmap() will require a
+ * software fallback. The fallback path will require that the texture
+ * images are mapped.
+ * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise
+ */
+GLboolean
+_mesa_meta_check_generate_mipmap_fallback(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj)
+{
+ const GLuint fboSave = ctx->DrawBuffer->Name;
+ struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
+ struct gl_texture_image *baseImage;
+ GLuint srcLevel;
+ GLenum status;
+
+ /* check for fallbacks */
+ if (!ctx->Extensions.EXT_framebuffer_object ||
+ target == GL_TEXTURE_3D) {
+ return GL_TRUE;
+ }
+
+ srcLevel = texObj->BaseLevel;
+ baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
++ if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) {
+ return GL_TRUE;
+ }
+
+ /*
+ * Test that we can actually render in the texture's format.
+ */
+ if (!mipmap->FBO)
+ _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
+ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
+
+ if (target == GL_TEXTURE_1D) {
+ _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target, texObj->Name, srcLevel);
+ }
+ else if (target == GL_TEXTURE_3D) {
+ GLint zoffset = 0;
+ _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target, texObj->Name, srcLevel, zoffset);
+ }
+ else {
+ /* 2D / cube */
+ _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target, texObj->Name, srcLevel);
+ }
+
+ status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+
+ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
/**
* Called via ctx->Driver.GenerateMipmap()
* Note: texture borders and 3D texture support not yet complete.
return;
}
- if (texImage->TexFormat == &_mesa_null_texformat)
- texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx,
- internalFormat,
- format,
- type);
++ if (texImage->TexFormat == MESA_FORMAT_NONE)
++ texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx,
++ internalFormat,
++ format,
++ type);
+
_mesa_unlock_texture(ctx, texObj); /* need to unlock first */
/*
pitch = intelObj->pitchOverride;
} else {
+ GLuint dst_x, dst_y;
+
+ intel_miptree_get_image_offset(intelObj->mt, intelObj->firstLevel, 0, 0,
+ &dst_x, &dst_y);
+
dri_bo_reference(intelObj->mt->region->buffer);
i830->state.tex_buffer[unit] = intelObj->mt->region->buffer;
- i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt,
- 0, intelObj->
- firstLevel);
+ /* XXX: This calculation is probably broken for tiled images with
+ * a non-page-aligned offset.
+ */
+ i830->state.tex_offset[unit] = (dst_x + dst_y * intelObj->mt->pitch) *
+ intelObj->mt->cpp;
- format = translate_texture_format(firstImage->TexFormat->MesaFormat,
+ format = translate_texture_format(firstImage->TexFormat,
firstImage->InternalFormat);
pitch = intelObj->mt->pitch * intelObj->mt->cpp;
}
pitch = intelObj->pitchOverride;
} else {
+ GLuint dst_x, dst_y;
+
+ intel_miptree_get_image_offset(intelObj->mt, intelObj->firstLevel, 0, 0,
+ &dst_x, &dst_y);
+
dri_bo_reference(intelObj->mt->region->buffer);
i915->state.tex_buffer[unit] = intelObj->mt->region->buffer;
- i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt,
- 0, intelObj->
- firstLevel);
+ /* XXX: This calculation is probably broken for tiled images with
+ * a non-page-aligned offset.
+ */
+ i915->state.tex_offset[unit] = (dst_x + dst_y * intelObj->mt->pitch) *
+ intelObj->mt->cpp;
- format = translate_texture_format(firstImage->TexFormat->MesaFormat,
+ format = translate_texture_format(firstImage->TexFormat,
firstImage->InternalFormat,
tObj->DepthMode);
pitch = intelObj->mt->pitch * intelObj->mt->cpp;
#include "attrib.h"
#include "colormac.h"
#include "context.h"
+#include "enums.h"
++#include "formats.h"
#include "hash.h"
#include "imports.h"
#include "debug.h"
static void
-dump_texture_cb(GLuint id, void *data, void *userData)
+dump_texture(struct gl_texture_object *texObj, GLuint writeImages)
{
- struct gl_texture_object *texObj = (struct gl_texture_object *) data;
- int i;
+ const GLuint numFaces = texObj->Target == GL_TEXTURE_CUBE_MAP ? 6 : 1;
GLboolean written = GL_FALSE;
- (void) userData;
+ GLuint i, j;
_mesa_printf("Texture %u\n", texObj->Name);
- _mesa_printf(" Target 0x%x\n", texObj->Target);
+ _mesa_printf(" Target %s\n", tex_target_name(texObj->Target));
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
- struct gl_texture_image *texImg = texObj->Image[0][i];
- if (texImg) {
- _mesa_printf(" Image %u: %d x %d x %d, format %u at %p\n", i,
- texImg->Width, texImg->Height, texImg->Depth,
- texImg->TexFormat, texImg->Data);
- if (DumpImages && !written) {
- GLuint face = 0;
- write_texture_image(texObj, face, i);
- written = GL_TRUE;
+ for (j = 0; j < numFaces; j++) {
+ struct gl_texture_image *texImg = texObj->Image[j][i];
+ if (texImg) {
- _mesa_printf(" Face %u level %u: %d x %d x %d, format %u at %p\n",
++ _mesa_printf(" Face %u level %u: %d x %d x %d, format %s at %p\n",
+ j, i,
+ texImg->Width, texImg->Height, texImg->Depth,
- texImg->TexFormat->MesaFormat, texImg->Data);
++ _mesa_get_format_name(texImg->TexFormat),
++ texImg->Data);
+ if (writeImages == WRITE_ALL ||
+ (writeImages == WRITE_ONE && !written)) {
+ write_texture_image(texObj, j, i);
+ written = GL_TRUE;
+ }
}
}
}
#include "buffers.h"
#include "context.h"
+#include "enums.h"
#include "fbobject.h"
+ #include "formats.h"
#include "framebuffer.h"
#include "hash.h"
#include "macros.h"
ASSERT(maxLevels > 0); /* bad target */
/* Find convertFormat - the format that do_row() will process */
- if (srcImage->IsCompressed) {
++
+ if (_mesa_is_format_compressed(srcImage->TexFormat)) {
- /* setup for compressed textures */
+ /* setup for compressed textures - need to allocate temporary
+ * image buffers to hold uncompressed images.
+ */
GLuint row;
GLint components, size;
GLchan *dst;
*/
GLubyte *
_mesa_compressed_image_address(GLint col, GLint row, GLint img,
- GLuint mesaFormat,
+ gl_format mesaFormat,
GLsizei width, const GLubyte *image)
{
- GLubyte *addr;
+ /* XXX only 2D images implemented, not 3D */
+ const GLuint blockSize = _mesa_get_format_bytes(mesaFormat);
+ GLuint bw, bh;
+ GLint offset;
- (void) img;
+ _mesa_get_format_block_size(mesaFormat, &bw, &bh);
- /* We try to spot a "complete" subtexture "above" ROW, COL;
- * this texture is given by appropriate rounding of WIDTH x ROW.
- * Then we just add the amount left (usually on the left).
- *
- * Example for X*Y microtiles (Z bytes each)
- * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X);
- */
+ ASSERT(col % bw == 0);
+ ASSERT(row % bh == 0);
- switch (mesaFormat) {
- #if FEATURE_texture_fxt1
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
- addr = (GLubyte *) image + 16 * (((width + 7) / 8) * (row / 4) + col / 8);
- break;
- #endif
- #if FEATURE_texture_s3tc
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- #if FEATURE_EXT_texture_sRGB
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- #endif
- addr = (GLubyte *) image + 8 * (((width + 3) / 4) * (row / 4) + col / 4);
- break;
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- #if FEATURE_EXT_texture_sRGB
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- #endif
- addr = (GLubyte *) image + 16 * (((width + 3) / 4) * (row / 4) + col / 4);
- break;
- #endif
- default:
- _mesa_problem(NULL, "bad mesaFormat in _mesa_compressed_image_address");
- addr = NULL;
- }
+ offset = ((width + bw - 1) / bw) * (row / bh) + col / bw;
+ offset *= blockSize;
- return addr;
+ return (GLubyte *) image + offset;
}
+
+
+/**
+ * Given a compressed MESA_FORMAT_x value, return the corresponding
+ * GLenum for that format.
+ * This is needed for glGetTexLevelParameter(GL_TEXTURE_INTERNAL_FORMAT)
+ * which must return the specific texture format used when the user might
+ * have originally specified a generic compressed format in their
+ * glTexImage2D() call.
+ * For non-compressed textures, we always return the user-specified
+ * internal format unchanged.
+ */
+GLenum
+_mesa_compressed_format_to_glenum(GLcontext *ctx, GLuint mesaFormat)
+{
+ switch (mesaFormat) {
+#if FEATURE_texture_fxt1
+ case MESA_FORMAT_RGB_FXT1:
+ return GL_COMPRESSED_RGB_FXT1_3DFX;
+ case MESA_FORMAT_RGBA_FXT1:
+ return GL_COMPRESSED_RGBA_FXT1_3DFX;
+#endif
+#if FEATURE_texture_s3tc
+ case MESA_FORMAT_RGB_DXT1:
+ return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ case MESA_FORMAT_RGBA_DXT1:
+ return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case MESA_FORMAT_RGBA_DXT3:
+ return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ case MESA_FORMAT_RGBA_DXT5:
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+#if FEATURE_EXT_texture_sRGB
+ case MESA_FORMAT_SRGB_DXT1:
+ return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
+ case MESA_FORMAT_SRGBA_DXT1:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
+ case MESA_FORMAT_SRGBA_DXT3:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
+ case MESA_FORMAT_SRGBA_DXT5:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
+#endif
+#endif
+ default:
+ _mesa_problem(ctx, "Unexpected mesa texture format in"
+ " _mesa_compressed_format_to_glenum()");
+ return 0;
+ }
+}
+
+
switch (internalFormat) {
case GL_COMPRESSED_ALPHA_ARB:
- return &_mesa_texformat_alpha;
+ return MESA_FORMAT_A8;
case GL_COMPRESSED_LUMINANCE_ARB:
- return &_mesa_texformat_luminance;
+ return MESA_FORMAT_L8;
case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
- return &_mesa_texformat_luminance_alpha;
+ return MESA_FORMAT_AL88;
case GL_COMPRESSED_INTENSITY_ARB:
- return &_mesa_texformat_intensity;
+ return MESA_FORMAT_I8;
case GL_COMPRESSED_RGB_ARB:
-#if FEATURE_texture_fxt1
- if (ctx->Extensions.TDFX_texture_compression_FXT1)
- return MESA_FORMAT_RGB_FXT1;
-#endif
--#if FEATURE_texture_s3tc
if (ctx->Extensions.EXT_texture_compression_s3tc ||
ctx->Extensions.S3_s3tc)
- return &_mesa_texformat_rgb_dxt1;
- #endif
- #if FEATURE_texture_fxt1
+ return MESA_FORMAT_RGB_DXT1;
-#endif
+ if (ctx->Extensions.TDFX_texture_compression_FXT1)
- return &_mesa_texformat_rgb_fxt1;
- #endif
- return &_mesa_texformat_rgb;
++ return MESA_FORMAT_RGB_FXT1;
+ return MESA_FORMAT_RGB888;
case GL_COMPRESSED_RGBA_ARB:
-#if FEATURE_texture_fxt1
- if (ctx->Extensions.TDFX_texture_compression_FXT1)
- return MESA_FORMAT_RGBA_FXT1;
-#endif
--#if FEATURE_texture_s3tc
if (ctx->Extensions.EXT_texture_compression_s3tc ||
ctx->Extensions.S3_s3tc)
- return &_mesa_texformat_rgba_dxt5; /* Not rgba_dxt1, see spec */
- #endif
- #if FEATURE_texture_fxt1
+ return MESA_FORMAT_RGBA_DXT3; /* Not rgba_dxt1, see spec */
-#endif
+ if (ctx->Extensions.TDFX_texture_compression_FXT1)
- return &_mesa_texformat_rgba_fxt1;
- #endif
- return &_mesa_texformat_rgba;
++ return MESA_FORMAT_RGBA_FXT1;
+ return MESA_FORMAT_RGBA8888;
default:
; /* fallthrough */
}
#include "glheader.h"
#include "bufferobj.h"
+#include "enums.h"
#include "context.h"
+ #include "formats.h"
#include "image.h"
#include "texcompress.h"
- #include "texformat.h"
#include "texgetimage.h"
#include "teximage.h"
#include "texstate.h"
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- _mesa_debug(ctx, "glGetTexImage(tex %u) format = %d, w=%d, h=%d,"
+ if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
- texImage->TexFormat->MesaFormat,
++ _mesa_debug(ctx, "glGetTexImage(tex %u) format = %s, w=%d, h=%d,"
+ " dstFmt=0x%x, dstType=0x%x\n",
+ texObj->Name,
++ _mesa_get_format_name(texImage->TexFormat),
+ texImage->Width, texImage->Height,
+ format, type);
+ }
+
_mesa_lock_texture(ctx, texObj);
{
struct gl_texture_image *texImage =
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
if (!texObj) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
- return;
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+ return GL_TRUE;
}
- maxLevels = _mesa_max_texture_levels(ctx, target);
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
- return;
+ if (!texImage) {
+ /* probably invalid mipmap level */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetCompressedTexImageARB(level)");
+ return GL_TRUE;
}
- if (!texImage->IsCompressed) {
- if (_mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
++ if (!_mesa_is_format_compressed(texImage->TexFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImageARB(texture is not compressed)");
+ return GL_TRUE;
+ }
+
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
++ GLuint compressedSize;
++
+ /* make sure PBO is not mapped */
+ if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImage(PBO is mapped)");
+ return GL_TRUE;
+ }
+
++ compressedSize = _mesa_format_image_size(texImage->TexFormat,
++ texImage->Width,
++ texImage->Height,
++ texImage->Depth);
++
+ /* do bounds checking on PBO write */
- if ((const GLubyte *) img + texImage->CompressedSize >
++ if ((const GLubyte *) img + compressedSize >
+ (const GLubyte *) ctx->Pack.BufferObj->Size) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImage(out of bounds PBO write)");
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (getcompressedteximage_error_check(ctx, target, level, img)) {
return;
}
- "glGetCompressedTexImage(tex %u) format = %d, w=%d, h=%d\n",
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+ _mesa_debug(ctx,
- texImage->TexFormat->MesaFormat,
++ "glGetCompressedTexImage(tex %u) format = %s, w=%d, h=%d\n",
+ texObj->Name,
++ _mesa_get_format_name(texImage->TexFormat),
+ texImage->Width, texImage->Height);
+ }
+
_mesa_lock_texture(ctx, texObj);
{
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (texImage) {
- if (_mesa_is_format_compressed(texImage->TexFormat)) {
- /* this typically calls _mesa_get_compressed_teximage() */
- ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
- texObj, texImage);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTexImageARB");
- }
- }
- else {
- /* probably invalid mipmap level */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTexImageARB(level)");
- }
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+
+ /* this typically calls _mesa_get_compressed_teximage() */
+ ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
+ texObj, texImage);
}
_mesa_unlock_texture(ctx, texObj);
}
*params = img->Depth;
break;
case GL_TEXTURE_INTERNAL_FORMAT:
- if (img->IsCompressed) {
- *params = img->InternalFormat;
++ if (_mesa_is_format_compressed(img->TexFormat)) {
+ /* need to return the actual compressed format */
- *params = _mesa_compressed_format_to_glenum(ctx,
- img->TexFormat->MesaFormat);
++ *params = _mesa_compressed_format_to_glenum(ctx, img->TexFormat);
+ }
+ else {
+ /* return the user's requested internal format */
+ *params = img->InternalFormat;
+ }
break;
case GL_TEXTURE_BORDER:
*params = img->Border;
(void) format;
(void) type;
- pFormat = st_choose_format(ctx->st->pipe, internalFormat, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_SAMPLER);
+ pFormat = st_choose_format(ctx->st->pipe->screen, internalFormat,
+ PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER);
if (pFormat == PIPE_FORMAT_NONE)
- return NULL;
+ return MESA_FORMAT_NONE;
return translate_gallium_format_to_mesa_format(pFormat);
}
enum pipe_texture_target target, unsigned tex_usage);
extern enum pipe_format
-st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat);
+st_choose_renderbuffer_format(struct pipe_screen *screen,
+ GLenum internalFormat);
- extern const struct gl_texture_format *
+ extern gl_format
st_ChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
GLenum format, GLenum type);
_swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb,
GLint n, GLint x, GLint y, GLuint depth[] )
{
+ GLuint depthBits;
+
if (!rb) {
/* really only doing this to prevent FP exceptions later */
- _mesa_bzero(depth, n * sizeof(GLfloat));
+ _mesa_bzero(depth, n * sizeof(GLuint));
+ return;
}
+ depthBits = _mesa_get_format_bits(rb->Format, GL_DEPTH_BITS);
+
ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
if (y < 0 || y >= (GLint) rb->Height ||