/** * This is the software fallback for Driver.GetCompressedTexImage(). * All error checking will have been done before this routine is called. */ void _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, GLvoid *img, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { GLuint size; if (ctx->Pack.BufferObj->Name) { /* pack texture image into a PBO */ GLubyte *buf; if ((const GLubyte *) img + texImage->CompressedSize > (const GLubyte *) ctx->Pack.BufferObj->Size) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImage(invalid PBO access)"); return; } buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); if (!buf) { /* buffer is already mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImage(PBO is mapped)"); return; } img = ADD_POINTERS(buf, img); } else if (!img) { /* not an error */ return; } /* don't use texImage->CompressedSize since that may be padded out */ size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height, texImage->Depth, texImage->TexFormat->MesaFormat); /* just memcpy, no pixelstore or pixel transfer */ _mesa_memcpy(img, texImage->Data, size); if (ctx->Pack.BufferObj->Name) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, ctx->Pack.BufferObj); } }
/** * As above, but format is specified by a GLenum (GL_COMPRESSED_*) token. * * Note: This function CAN NOT return a padded hardware texture size. * That's why we don't call the ctx->Driver.CompressedTextureSize() function. * * We use this function to validate the <imageSize> parameter * of glCompressedTex[Sub]Image1/2/3D(), which must be an exact match. */ GLuint _mesa_compressed_texture_size_glenum(GLcontext *ctx, GLsizei width, GLsizei height, GLsizei depth, GLenum glformat) { GLuint mesaFormat; switch (glformat) { case GL_COMPRESSED_RGB_FXT1_3DFX: mesaFormat = MESA_FORMAT_RGB_FXT1; break; case GL_COMPRESSED_RGBA_FXT1_3DFX: mesaFormat = MESA_FORMAT_RGBA_FXT1; break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_RGB_S3TC: mesaFormat = MESA_FORMAT_RGB_DXT1; break; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_RGB4_S3TC: mesaFormat = MESA_FORMAT_RGBA_DXT1; break; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_RGBA_S3TC: mesaFormat = MESA_FORMAT_RGBA_DXT3; break; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: case GL_RGBA4_S3TC: mesaFormat = MESA_FORMAT_RGBA_DXT5; break; default: return 0; } return _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat); }
void GLAPIENTRY _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ) { const struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; const struct gl_texture_image *img = NULL; GLuint dimensions; GLboolean isProxy; GLint maxLevels; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexLevelParameteriv(current unit)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; /* this will catch bad target values */ dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */ if (dimensions == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)"); return; } maxLevels = _mesa_max_texture_levels(ctx, target); if (maxLevels == 0) { /* should not happen since <target> was just checked above */ _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter"); return; } if (level < 0 || level >= maxLevels) { _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); return; } texObj = _mesa_select_tex_object(ctx, texUnit, target); _mesa_lock_texture(ctx, texObj); img = _mesa_select_tex_image(ctx, texObj, target, level); if (!img || !img->TexFormat) { /* undefined texture image */ if (pname == GL_TEXTURE_COMPONENTS) *params = 1; else *params = 0; goto out; } isProxy = _mesa_is_proxy_texture(target); switch (pname) { case GL_TEXTURE_WIDTH: *params = img->Width; break; case GL_TEXTURE_HEIGHT: *params = img->Height; break; case GL_TEXTURE_DEPTH: *params = img->Depth; break; case GL_TEXTURE_INTERNAL_FORMAT: *params = img->InternalFormat; break; case GL_TEXTURE_BORDER: *params = img->Border; break; case GL_TEXTURE_RED_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->RedBits; else *params = 0; break; case GL_TEXTURE_GREEN_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->GreenBits; else *params = 0; break; case GL_TEXTURE_BLUE_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->BlueBits; else *params = 0; break; case GL_TEXTURE_ALPHA_SIZE: if (img->_BaseFormat == GL_ALPHA || img->_BaseFormat == GL_LUMINANCE_ALPHA || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->AlphaBits; else *params = 0; break; case GL_TEXTURE_INTENSITY_SIZE: if (img->_BaseFormat != GL_INTENSITY) *params = 0; else if (img->TexFormat->IntensityBits > 0) *params = img->TexFormat->IntensityBits; else /* intensity probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); break; case GL_TEXTURE_LUMINANCE_SIZE: if (img->_BaseFormat != GL_LUMINANCE && img->_BaseFormat != GL_LUMINANCE_ALPHA) *params = 0; else if (img->TexFormat->LuminanceBits > 0) *params = img->TexFormat->LuminanceBits; else /* luminance probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); break; case GL_TEXTURE_INDEX_SIZE_EXT: if (img->_BaseFormat == GL_COLOR_INDEX) *params = img->TexFormat->IndexBits; else *params = 0; break; case GL_TEXTURE_DEPTH_SIZE_ARB: if (ctx->Extensions.ARB_depth_texture) *params = img->TexFormat->DepthBits; else _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); break; case GL_TEXTURE_STENCIL_SIZE_EXT: if (ctx->Extensions.EXT_packed_depth_stencil) { *params = img->TexFormat->StencilBits; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: if (ctx->Extensions.ARB_texture_compression) { if (img->IsCompressed && !isProxy) { /* Don't use ctx->Driver.CompressedTextureSize() since that * may returned a padded hardware size. */ *params = _mesa_compressed_texture_size(ctx, img->Width, img->Height, img->Depth, img->TexFormat->MesaFormat); } else { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexLevelParameter[if]v(pname)"); } } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_COMPRESSED: if (ctx->Extensions.ARB_texture_compression) { *params = (GLint) img->IsCompressed; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; /* GL_ARB_texture_float */ case GL_TEXTURE_RED_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_GREEN_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_BLUE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_ALPHA_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_LUMINANCE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_INTENSITY_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; case GL_TEXTURE_DEPTH_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } out: _mesa_unlock_texture(ctx, texObj); }