diff options
Diffstat (limited to 'mesalib/src')
-rw-r--r-- | mesalib/src/mesa/main/texgetimage.c | 1820 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.c | 3030 |
2 files changed, 2207 insertions, 2643 deletions
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index 6060e5b3d..97d101225 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -1,951 +1,869 @@ -/*
- * Mesa 3-D graphics library
- * Version: 7.7
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * Code for glGetTexImage() and glGetCompressedTexImage().
- */
-
-
-#include "glheader.h"
-#include "bufferobj.h"
-#include "enums.h"
-#include "context.h"
-#include "formats.h"
-#include "image.h"
-#include "mfeatures.h"
-#include "mtypes.h"
-#include "pack.h"
-#include "pbo.h"
-#include "texgetimage.h"
-#include "teximage.h"
-
-
-
-/**
- * Can the given type represent negative values?
- */
-static INLINE GLboolean
-type_with_negative_values(GLenum type)
-{
- switch (type) {
- case GL_BYTE:
- case GL_SHORT:
- case GL_INT:
- case GL_FLOAT:
- case GL_HALF_FLOAT_ARB:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * glGetTexImage for color index pixels.
- */
-static void
-get_tex_color_index(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- const GLint rowstride = texImage->RowStride;
- const GLuint indexBits =
- _mesa_get_format_bits(texImage->TexFormat, GL_TEXTURE_INDEX_SIZE_EXT);
- const GLbitfield transferOps = 0x0;
- GLint img, row, col;
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- GLuint indexRow[MAX_WIDTH] = { 0 };
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
- assert(dest);
-
- if (indexBits == 8) {
- const GLubyte *src = (const GLubyte *) texImage->Data;
- src += rowstride * (img * height + row);
- for (col = 0; col < width; col++) {
- indexRow[col] = src[col];
- }
- }
- else if (indexBits == 16) {
- const GLushort *src = (const GLushort *) texImage->Data;
- src += rowstride * (img * height + row);
- for (col = 0; col < width; col++) {
- indexRow[col] = src[col];
- }
- }
- else {
- _mesa_problem(ctx, "Color index problem in _mesa_GetTexImage");
- }
- _mesa_pack_index_span(ctx, width, type, dest,
- indexRow, &ctx->Pack, transferOps);
- }
- }
-}
-
-
-/**
- * glGetTexImage for depth/Z pixels.
- */
-static void
-get_tex_depth(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- GLint img, row, col;
- GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat));
-
- if (!depthRow) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- return;
- }
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
- assert(dest);
-
- for (col = 0; col < width; col++) {
- texImage->FetchTexelf(texImage, col, row, img, depthRow + col);
- }
- _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack);
- }
- }
-
- free(depthRow);
-}
-
-
-/**
- * glGetTexImage for depth/stencil pixels.
- */
-static void
-get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- const GLint rowstride = texImage->RowStride;
- const GLuint *src = (const GLuint *) texImage->Data;
- GLint img, row;
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
- memcpy(dest, src, width * sizeof(GLuint));
- if (ctx->Pack.SwapBytes) {
- _mesa_swap4((GLuint *) dest, width);
- }
-
- src += rowstride;
- }
- }
-}
-
-
-/**
- * glGetTexImage for YCbCr pixels.
- */
-static void
-get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- const GLint rowstride = texImage->RowStride;
- const GLushort *src = (const GLushort *) texImage->Data;
- GLint img, row;
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
- memcpy(dest, src, width * sizeof(GLushort));
-
- /* check for byte swapping */
- if ((texImage->TexFormat == MESA_FORMAT_YCBCR
- && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
- (texImage->TexFormat == MESA_FORMAT_YCBCR_REV
- && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
- if (!ctx->Pack.SwapBytes)
- _mesa_swap2((GLushort *) dest, width);
- }
- else if (ctx->Pack.SwapBytes) {
- _mesa_swap2((GLushort *) dest, width);
- }
-
- src += rowstride;
- }
- }
-}
-
-
-#if FEATURE_EXT_texture_sRGB
-
-
-/**
- * Convert a float value from linear space to a
- * non-linear sRGB value in [0, 255].
- * Not terribly efficient.
- */
-static INLINE GLfloat
-linear_to_nonlinear(GLfloat cl)
-{
- /* can't have values outside [0, 1] */
- GLfloat cs;
- if (cl < 0.0031308f) {
- cs = 12.92f * cl;
- }
- else {
- cs = (GLfloat)(1.055 * pow(cl, 0.41666) - 0.055);
- }
- return cs;
-}
-
-
-/**
- * glGetTexImagefor sRGB pixels;
- */
-static void
-get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- const GLbitfield transferOps = 0x0;
- GLint img, row;
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
-
- if (!rgba) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- return;
- }
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
-
- GLint col;
-
- /* convert row to RGBA format */
- for (col = 0; col < width; col++) {
- texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
- if (texImage->_BaseFormat == GL_LUMINANCE) {
- rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
- rgba[col][GCOMP] = 0.0;
- rgba[col][BCOMP] = 0.0;
- }
- else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
- rgba[col][GCOMP] = 0.0;
- rgba[col][BCOMP] = 0.0;
- }
- else if (texImage->_BaseFormat == GL_RGB ||
- texImage->_BaseFormat == GL_RGBA) {
- rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
- rgba[col][GCOMP] = linear_to_nonlinear(rgba[col][GCOMP]);
- rgba[col][BCOMP] = linear_to_nonlinear(rgba[col][BCOMP]);
- }
- }
- _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
- format, type, dest,
- &ctx->Pack, transferOps);
- }
- }
-
- free(rgba);
-}
-
-
-#else /* FEATURE_EXT_texture_sRGB */
-
-
-static INLINE void
-get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- ASSERT_NO_FEATURE();
-}
-
-
-#endif /* FEATURE_EXT_texture_sRGB */
-
-
-/**
- * glGetTexImagefor RGBA, Luminance, etc. pixels.
- * This is the slow way since we use texture sampling.
- */
-static void
-get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- /* Normally, no pixel transfer ops are performed during glGetTexImage.
- * The only possible exception is component clamping to [0,1].
- */
- GLbitfield transferOps = 0x0;
- GLint img, row;
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
-
- if (!rgba) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- return;
- }
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
- GLint col;
- GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat);
-
- /* clamp does not apply to GetTexImage (final conversion)?
- * Looks like we need clamp though when going from format
- * containing negative values to unsigned format.
- */
- if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
- else if (!type_with_negative_values(type) &&
- (dataType == GL_FLOAT ||
- dataType == GL_SIGNED_NORMALIZED)) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
-
- for (col = 0; col < width; col++) {
- texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
- if (texImage->_BaseFormat == GL_ALPHA) {
- rgba[col][RCOMP] = 0.0F;
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- }
- else if (texImage->_BaseFormat == GL_LUMINANCE) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- rgba[col][ACOMP] = 1.0F;
- }
- else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- }
- else if (texImage->_BaseFormat == GL_INTENSITY) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- rgba[col][ACOMP] = 1.0F;
- }
- }
- _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
- format, type, dest,
- &ctx->Pack, transferOps);
- }
- }
-
- free(rgba);
-}
-
-
-/**
- * Try to do glGetTexImage() with simple memcpy().
- * \return GL_TRUE if done, GL_FALSE otherwise
- */
-static GLboolean
-get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_object *texObj,
- const struct gl_texture_image *texImage)
-{
- GLboolean memCopy = GL_FALSE;
-
- /* Texture image should have been mapped already */
- assert(texImage->Data);
-
- /*
- * Check if the src/dst formats are compatible.
- * Also note that GL's pixel transfer ops don't apply to glGetTexImage()
- * so we don't have to worry about those.
- * XXX more format combinations could be supported here.
- */
- if ((texObj->Target == GL_TEXTURE_1D ||
- texObj->Target == GL_TEXTURE_2D ||
- texObj->Target == GL_TEXTURE_RECTANGLE ||
- (texObj->Target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
- texObj->Target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) {
- if ((texImage->TexFormat == MESA_FORMAT_ARGB8888 ||
- texImage->TexFormat == MESA_FORMAT_SARGB8) &&
- format == GL_BGRA &&
- (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
- !ctx->Pack.SwapBytes &&
- _mesa_little_endian()) {
- memCopy = GL_TRUE;
- }
- else if ((texImage->TexFormat == MESA_FORMAT_AL88 ||
- texImage->TexFormat == MESA_FORMAT_SLA8) &&
- format == GL_LUMINANCE_ALPHA &&
- type == GL_UNSIGNED_BYTE &&
- !ctx->Pack.SwapBytes &&
- _mesa_little_endian()) {
- memCopy = GL_TRUE;
- }
- else if ((texImage->TexFormat == MESA_FORMAT_L8 ||
- texImage->TexFormat == MESA_FORMAT_SL8) &&
- format == GL_LUMINANCE &&
- type == GL_UNSIGNED_BYTE) {
- memCopy = GL_TRUE;
- }
- else if (texImage->TexFormat == MESA_FORMAT_L16 &&
- format == GL_LUMINANCE &&
- type == GL_UNSIGNED_SHORT) {
- memCopy = GL_TRUE;
- }
- else if (texImage->TexFormat == MESA_FORMAT_A8 &&
- format == GL_ALPHA &&
- type == GL_UNSIGNED_BYTE) {
- memCopy = GL_TRUE;
- }
- else if (texImage->TexFormat == MESA_FORMAT_A16 &&
- format == GL_ALPHA &&
- type == GL_UNSIGNED_SHORT) {
- memCopy = GL_TRUE;
- }
- }
-
- if (memCopy) {
- const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat);
- const GLuint bytesPerRow = texImage->Width * bpp;
- GLubyte *dst =
- _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width,
- texImage->Height, format, type, 0, 0);
- const GLint dstRowStride =
- _mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type);
- const GLubyte *src = texImage->Data;
- const GLint srcRowStride = texImage->RowStride * bpp;
- GLuint row;
-
- if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) {
- memcpy(dst, src, bytesPerRow * texImage->Height);
- }
- else {
- for (row = 0; row < texImage->Height; row++) {
- memcpy(dst, src, bytesPerRow);
- dst += dstRowStride;
- src += srcRowStride;
- }
- }
- }
-
- return memCopy;
-}
-
-
-/**
- * This is the software fallback for Driver.GetTexImage().
- * All error checking will have been done before this routine is called.
- * The texture image must be mapped.
- */
-void
-_mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- GLuint dimensions;
-
- /* If we get here, the texture image should be mapped */
- assert(texImage->Data);
-
- switch (target) {
- case GL_TEXTURE_1D:
- dimensions = 1;
- break;
- case GL_TEXTURE_3D:
- dimensions = 3;
- break;
- default:
- dimensions = 2;
- }
-
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- /* Packing texture image into a PBO.
- * Map the (potentially) VRAM-based buffer into our process space so
- * we can write into it with the code below.
- * A hardware driver might use a sophisticated blit to move the
- * texture data to the PBO if the PBO is in VRAM along with the texture.
- */
- GLubyte *buf = (GLubyte *)
- ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
- if (!buf) {
- /* out of memory or other unexpected error */
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)");
- return;
- }
- /* <pixels> was an offset into the PBO.
- * Now make it a real, client-side pointer inside the mapped region.
- */
- pixels = ADD_POINTERS(buf, pixels);
- }
-
- if (get_tex_memcpy(ctx, format, type, pixels, texObj, texImage)) {
- /* all done */
- }
- else if (format == GL_COLOR_INDEX) {
- get_tex_color_index(ctx, dimensions, format, type, pixels, texImage);
- }
- else if (format == GL_DEPTH_COMPONENT) {
- get_tex_depth(ctx, dimensions, format, type, pixels, texImage);
- }
- else if (format == GL_DEPTH_STENCIL_EXT) {
- get_tex_depth_stencil(ctx, dimensions, format, type, pixels, texImage);
- }
- else if (format == GL_YCBCR_MESA) {
- get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage);
- }
- else if (_mesa_get_format_color_encoding(texImage->TexFormat) == GL_SRGB) {
- get_tex_srgb(ctx, dimensions, format, type, pixels, texImage);
- }
- else {
- get_tex_rgba(ctx, dimensions, format, type, pixels, texImage);
- }
-
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
-}
-
-
-
-/**
- * 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(struct gl_context *ctx, GLenum target, GLint level,
- GLvoid *img,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- const GLuint row_stride = _mesa_format_row_stride(texImage->TexFormat,
- texImage->Width);
- const GLuint row_stride_stored = _mesa_format_row_stride(texImage->TexFormat,
- texImage->RowStride);
- GLuint i;
-
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- /* pack texture image into a PBO */
- GLubyte *buf = (GLubyte *)
- ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
- if (!buf) {
- /* out of memory or other unexpected error */
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
- "glGetCompresssedTexImage(map PBO failed)");
- return;
- }
- img = ADD_POINTERS(buf, img);
- }
-
- /* no pixelstore or pixel transfer, but respect stride */
-
- if (row_stride == row_stride_stored) {
- const GLuint size = _mesa_format_image_size(texImage->TexFormat,
- texImage->Width,
- texImage->Height,
- texImage->Depth);
- memcpy(img, texImage->Data, size);
- }
- else {
- GLuint bw, bh;
- _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
- for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) {
- memcpy((GLubyte *)img + i * row_stride,
- (GLubyte *)texImage->Data + i * row_stride_stored,
- row_stride);
- }
- }
-
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
-}
-
-
-
-/**
- * Do error checking for a glGetTexImage() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
- */
-static GLboolean
-getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
- GLenum format, GLenum type, GLsizei clientMemSize,
- GLvoid *pixels )
-{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
- const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- GLenum baseFormat;
-
- if (maxLevels == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target);
- return GL_TRUE;
- }
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
- return GL_TRUE;
- }
-
- if (_mesa_sizeof_packed_type(type) <= 0) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
- return GL_TRUE;
- }
-
- if (_mesa_components_in_format(format) <= 0 ||
- format == GL_STENCIL_INDEX) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.MESA_ycbcr_texture && _mesa_is_ycbcr_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.EXT_packed_depth_stencil
- && _mesa_is_depthstencil_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- if (!ctx->Extensions.ATI_envmap_bumpmap
- && _mesa_is_dudv_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return GL_TRUE;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
-
- if (!texObj || _mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
- return GL_TRUE;
- }
-
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* out of memory */
- return GL_TRUE;
- }
-
- baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
-
- /* Make sure the requested image format is compatible with the
- * texture's format. Note that a color index texture can be converted
- * to RGBA so that combo is allowed.
- */
- if (_mesa_is_color_format(format)
- && !_mesa_is_color_format(baseFormat)
- && !_mesa_is_index_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (_mesa_is_index_format(format)
- && !_mesa_is_index_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (_mesa_is_depth_format(format)
- && !_mesa_is_depth_format(baseFormat)
- && !_mesa_is_depthstencil_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (_mesa_is_ycbcr_format(format)
- && !_mesa_is_ycbcr_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (_mesa_is_depthstencil_format(format)
- && !_mesa_is_depthstencil_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
- else if (_mesa_is_dudv_format(format)
- && !_mesa_is_dudv_format(baseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- return GL_TRUE;
- }
-
- if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
- texImage->Height, texImage->Depth,
- format, type, clientMemSize, pixels)) {
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexImage(out of bounds PBO access)");
- } else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetnTexImageARB(out of bounds access:"
- " bufSize (%d) is too small)", clientMemSize);
- }
- return GL_TRUE;
- }
-
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- /* PBO should not be mapped */
- if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexImage(PBO is mapped)");
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
-}
-
-
-
-/**
- * Get texture image. Called by glGetTexImage.
- *
- * \param target texture target.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param bufSize size of the pixels data buffer.
- * \param pixels returned pixel data.
- */
-void GLAPIENTRY
-_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format,
- GLenum type, GLsizei bufSize, GLvoid *pixels )
-{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (getteximage_error_check(ctx, target, level, format, type,
- bufSize, pixels)) {
- return;
- }
-
- if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) {
- /* not an error, do nothing */
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
- _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);
- {
- ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
- texObj, texImage);
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
-void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels )
-{
- _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels);
-}
-
-
-/**
- * Do error checking for a glGetCompressedTexImage() call.
- * \return GL_TRUE if any error, GL_FALSE if no errors.
- */
-static GLboolean
-getcompressedteximage_error_check(struct gl_context *ctx, GLenum target,
- GLint level, GLsizei clientMemSize, GLvoid *img)
-{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
- GLuint compressedSize;
-
- if (maxLevels == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)",
- target);
- return GL_TRUE;
- }
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTexImageARB(bad level = %d)", level);
- return GL_TRUE;
- }
-
- if (_mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetCompressedTexImageARB(bad target = %s)",
- _mesa_lookup_enum_by_nr(target));
- return GL_TRUE;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
- return GL_TRUE;
- }
-
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (!texImage) {
- /* probably invalid mipmap level */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTexImageARB(level)");
- return GL_TRUE;
- }
-
- if (!_mesa_is_format_compressed(texImage->TexFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTexImageARB(texture is not compressed)");
- return GL_TRUE;
- }
-
- compressedSize = _mesa_format_image_size(texImage->TexFormat,
- texImage->Width,
- texImage->Height,
- texImage->Depth);
-
- if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- /* do bounds checking on writing to client memory */
- if (clientMemSize < compressedSize) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetnCompressedTexImageARB(out of bounds access:"
- " bufSize (%d) is too small)", clientMemSize);
- }
- } else {
- /* do bounds checking on PBO write */
- if ((const GLubyte *) img + compressedSize >
- (const GLubyte *) ctx->Pack.BufferObj->Size) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTexImage(out of bounds PBO access)");
- return GL_TRUE;
- }
-
- /* 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;
- }
- }
-
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize,
- GLvoid *img)
-{
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) {
- return;
- }
-
- if (_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) {
- /* not an error, do nothing */
- return;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
-
- if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
- _mesa_debug(ctx,
- "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);
- {
- ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
- texObj, texImage);
- }
- _mesa_unlock_texture(ctx, texObj);
-}
-
-void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
-{
- _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img);
-}
+/* + * Mesa 3-D graphics library + * Version: 7.7 + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (c) 2009 VMware, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Code for glGetTexImage() and glGetCompressedTexImage(). + */ + + +#include "glheader.h" +#include "bufferobj.h" +#include "enums.h" +#include "context.h" +#include "formats.h" +#include "image.h" +#include "mfeatures.h" +#include "mtypes.h" +#include "pack.h" +#include "pbo.h" +#include "texgetimage.h" +#include "texfetch.h" +#include "teximage.h" + + + +/** + * Can the given type represent negative values? + */ +static INLINE GLboolean +type_with_negative_values(GLenum type) +{ + switch (type) { + case GL_BYTE: + case GL_SHORT: + case GL_INT: + case GL_FLOAT: + case GL_HALF_FLOAT_ARB: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * glGetTexImage for color index pixels. + */ +static void +get_tex_color_index(struct gl_context *ctx, GLuint dimensions, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_image *texImage) +{ + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + const GLint rowstride = texImage->RowStride; + const GLuint indexBits = + _mesa_get_format_bits(texImage->TexFormat, GL_TEXTURE_INDEX_SIZE_EXT); + const GLbitfield transferOps = 0x0; + GLint img, row, col; + + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + GLuint indexRow[MAX_WIDTH] = { 0 }; + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, row, 0); + assert(dest); + + if (indexBits == 8) { + const GLubyte *src = (const GLubyte *) texImage->Data; + src += rowstride * (img * height + row); + for (col = 0; col < width; col++) { + indexRow[col] = src[col]; + } + } + else if (indexBits == 16) { + const GLushort *src = (const GLushort *) texImage->Data; + src += rowstride * (img * height + row); + for (col = 0; col < width; col++) { + indexRow[col] = src[col]; + } + } + else { + _mesa_problem(ctx, "Color index problem in _mesa_GetTexImage"); + } + _mesa_pack_index_span(ctx, width, type, dest, + indexRow, &ctx->Pack, transferOps); + } + } +} + + +/** + * glGetTexImage for depth/Z pixels. + */ +static void +get_tex_depth(struct gl_context *ctx, GLuint dimensions, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_image *texImage) +{ + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + GLint img, row, col; + GLfloat *depthRow = (GLfloat *) malloc(width * sizeof(GLfloat)); + + if (!depthRow) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + return; + } + + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, row, 0); + assert(dest); + + for (col = 0; col < width; col++) { + texImage->FetchTexelf(texImage, col, row, img, depthRow + col); + } + _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack); + } + } + + free(depthRow); +} + + +/** + * glGetTexImage for depth/stencil pixels. + */ +static void +get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_image *texImage) +{ + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + const GLint rowstride = texImage->RowStride; + const GLuint *src = (const GLuint *) texImage->Data; + GLint img, row; + + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, row, 0); + memcpy(dest, src, width * sizeof(GLuint)); + if (ctx->Pack.SwapBytes) { + _mesa_swap4((GLuint *) dest, width); + } + + src += rowstride; + } + } +} + + +/** + * glGetTexImage for YCbCr pixels. + */ +static void +get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_image *texImage) +{ + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + const GLint rowstride = texImage->RowStride; + const GLushort *src = (const GLushort *) texImage->Data; + GLint img, row; + + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, row, 0); + memcpy(dest, src, width * sizeof(GLushort)); + + /* check for byte swapping */ + if ((texImage->TexFormat == MESA_FORMAT_YCBCR + && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || + (texImage->TexFormat == MESA_FORMAT_YCBCR_REV + && type == GL_UNSIGNED_SHORT_8_8_MESA)) { + if (!ctx->Pack.SwapBytes) + _mesa_swap2((GLushort *) dest, width); + } + else if (ctx->Pack.SwapBytes) { + _mesa_swap2((GLushort *) dest, width); + } + + src += rowstride; + } + } +} + + +/** + * glGetTexImage for (s)RGBA, Luminance, etc. pixels. + * This is the slow way since we use texture sampling. + */ +static void +get_tex_rgba(struct gl_context *ctx, GLuint dimensions, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_image *texImage) +{ + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + /* Normally, no pixel transfer ops are performed during glGetTexImage. + * The only possible exception is component clamping to [0,1]. + */ + GLbitfield transferOps = 0x0; + GLint img, row; + GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat)); + const GLboolean is_sampler_srgb_decode = + _mesa_get_format_color_encoding(texImage->TexFormat) == GL_SRGB && + texImage->TexObject->Sampler.sRGBDecode == GL_DECODE_EXT; + + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + return; + } + + /* glGetTexImage always returns sRGB data for sRGB textures. Make sure the + * fetch functions return sRGB data without linearizing it. + */ + if (is_sampler_srgb_decode) { + texImage->TexObject->Sampler.sRGBDecode = GL_SKIP_DECODE_EXT; + _mesa_set_fetch_functions(texImage, dimensions); + } + + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, row, 0); + GLint col; + GLenum dataType = _mesa_get_format_datatype(texImage->TexFormat); + + /* clamp does not apply to GetTexImage (final conversion)? + * Looks like we need clamp though when going from format + * containing negative values to unsigned format. + */ + if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { + transferOps |= IMAGE_CLAMP_BIT; + } + else if (!type_with_negative_values(type) && + (dataType == GL_FLOAT || + dataType == GL_SIGNED_NORMALIZED)) { + transferOps |= IMAGE_CLAMP_BIT; + } + + for (col = 0; col < width; col++) { + texImage->FetchTexelf(texImage, col, row, img, rgba[col]); + if (texImage->_BaseFormat == GL_ALPHA) { + rgba[col][RCOMP] = 0.0F; + rgba[col][GCOMP] = 0.0F; + rgba[col][BCOMP] = 0.0F; + } + else if (texImage->_BaseFormat == GL_LUMINANCE) { + rgba[col][GCOMP] = 0.0F; + rgba[col][BCOMP] = 0.0F; + rgba[col][ACOMP] = 1.0F; + } + else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) { + rgba[col][GCOMP] = 0.0F; + rgba[col][BCOMP] = 0.0F; + } + else if (texImage->_BaseFormat == GL_INTENSITY) { + rgba[col][GCOMP] = 0.0F; + rgba[col][BCOMP] = 0.0F; + rgba[col][ACOMP] = 1.0F; + } + } + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, + format, type, dest, + &ctx->Pack, transferOps); + } + } + + if (is_sampler_srgb_decode) { + texImage->TexObject->Sampler.sRGBDecode = GL_DECODE_EXT; + _mesa_set_fetch_functions(texImage, dimensions); + } + + free(rgba); +} + + +/** + * Try to do glGetTexImage() with simple memcpy(). + * \return GL_TRUE if done, GL_FALSE otherwise + */ +static GLboolean +get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage) +{ + GLboolean memCopy = GL_FALSE; + + /* Texture image should have been mapped already */ + assert(texImage->Data); + + /* + * Check if the src/dst formats are compatible. + * Also note that GL's pixel transfer ops don't apply to glGetTexImage() + * so we don't have to worry about those. + * XXX more format combinations could be supported here. + */ + if ((texObj->Target == GL_TEXTURE_1D || + texObj->Target == GL_TEXTURE_2D || + texObj->Target == GL_TEXTURE_RECTANGLE || + (texObj->Target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && + texObj->Target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { + if ((texImage->TexFormat == MESA_FORMAT_ARGB8888 || + texImage->TexFormat == MESA_FORMAT_SARGB8) && + format == GL_BGRA && + (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) && + !ctx->Pack.SwapBytes && + _mesa_little_endian()) { + memCopy = GL_TRUE; + } + else if ((texImage->TexFormat == MESA_FORMAT_AL88 || + texImage->TexFormat == MESA_FORMAT_SLA8) && + format == GL_LUMINANCE_ALPHA && + type == GL_UNSIGNED_BYTE && + !ctx->Pack.SwapBytes && + _mesa_little_endian()) { + memCopy = GL_TRUE; + } + else if ((texImage->TexFormat == MESA_FORMAT_L8 || + texImage->TexFormat == MESA_FORMAT_SL8) && + format == GL_LUMINANCE && + type == GL_UNSIGNED_BYTE) { + memCopy = GL_TRUE; + } + else if (texImage->TexFormat == MESA_FORMAT_L16 && + format == GL_LUMINANCE && + type == GL_UNSIGNED_SHORT) { + memCopy = GL_TRUE; + } + else if (texImage->TexFormat == MESA_FORMAT_A8 && + format == GL_ALPHA && + type == GL_UNSIGNED_BYTE) { + memCopy = GL_TRUE; + } + else if (texImage->TexFormat == MESA_FORMAT_A16 && + format == GL_ALPHA && + type == GL_UNSIGNED_SHORT) { + memCopy = GL_TRUE; + } + } + + if (memCopy) { + const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat); + const GLuint bytesPerRow = texImage->Width * bpp; + GLubyte *dst = + _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width, + texImage->Height, format, type, 0, 0); + const GLint dstRowStride = + _mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type); + const GLubyte *src = texImage->Data; + const GLint srcRowStride = texImage->RowStride * bpp; + GLuint row; + + if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) { + memcpy(dst, src, bytesPerRow * texImage->Height); + } + else { + for (row = 0; row < texImage->Height; row++) { + memcpy(dst, src, bytesPerRow); + dst += dstRowStride; + src += srcRowStride; + } + } + } + + return memCopy; +} + + +/** + * This is the software fallback for Driver.GetTexImage(). + * All error checking will have been done before this routine is called. + * The texture image must be mapped. + */ +void +_mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLuint dimensions; + + /* If we get here, the texture image should be mapped */ + assert(texImage->Data); + + switch (target) { + case GL_TEXTURE_1D: + dimensions = 1; + break; + case GL_TEXTURE_3D: + dimensions = 3; + break; + default: + dimensions = 2; + } + + if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + /* Packing texture image into a PBO. + * Map the (potentially) VRAM-based buffer into our process space so + * we can write into it with the code below. + * A hardware driver might use a sophisticated blit to move the + * texture data to the PBO if the PBO is in VRAM along with the texture. + */ + GLubyte *buf = (GLubyte *) + ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); + if (!buf) { + /* out of memory or other unexpected error */ + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)"); + return; + } + /* <pixels> was an offset into the PBO. + * Now make it a real, client-side pointer inside the mapped region. + */ + pixels = ADD_POINTERS(buf, pixels); + } + + if (get_tex_memcpy(ctx, format, type, pixels, texObj, texImage)) { + /* all done */ + } + else if (format == GL_COLOR_INDEX) { + get_tex_color_index(ctx, dimensions, format, type, pixels, texImage); + } + else if (format == GL_DEPTH_COMPONENT) { + get_tex_depth(ctx, dimensions, format, type, pixels, texImage); + } + else if (format == GL_DEPTH_STENCIL_EXT) { + get_tex_depth_stencil(ctx, dimensions, format, type, pixels, texImage); + } + else if (format == GL_YCBCR_MESA) { + get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage); + } + else { + get_tex_rgba(ctx, dimensions, format, type, pixels, texImage); + } + + if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + ctx->Pack.BufferObj); + } +} + + + +/** + * 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(struct gl_context *ctx, GLenum target, GLint level, + GLvoid *img, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + const GLuint row_stride = _mesa_format_row_stride(texImage->TexFormat, + texImage->Width); + const GLuint row_stride_stored = _mesa_format_row_stride(texImage->TexFormat, + texImage->RowStride); + GLuint i; + + if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + /* pack texture image into a PBO */ + GLubyte *buf = (GLubyte *) + ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); + if (!buf) { + /* out of memory or other unexpected error */ + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glGetCompresssedTexImage(map PBO failed)"); + return; + } + img = ADD_POINTERS(buf, img); + } + + /* no pixelstore or pixel transfer, but respect stride */ + + if (row_stride == row_stride_stored) { + const GLuint size = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, + texImage->Depth); + memcpy(img, texImage->Data, size); + } + else { + GLuint bw, bh; + _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); + for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) { + memcpy((GLubyte *)img + i * row_stride, + (GLubyte *)texImage->Data + i * row_stride_stored, + row_stride); + } + } + + if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + ctx->Pack.BufferObj); + } +} + + + +/** + * Do error checking for a glGetTexImage() call. + * \return GL_TRUE if any error, GL_FALSE if no errors. + */ +static GLboolean +getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLsizei clientMemSize, + GLvoid *pixels ) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + const GLint maxLevels = _mesa_max_texture_levels(ctx, target); + const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; + GLenum baseFormat; + + if (maxLevels == 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target); + return GL_TRUE; + } + + if (level < 0 || level >= maxLevels) { + _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); + return GL_TRUE; + } + + if (_mesa_sizeof_packed_type(type) <= 0) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" ); + return GL_TRUE; + } + + if (_mesa_components_in_format(format) <= 0 || + format == GL_STENCIL_INDEX) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" ); + return GL_TRUE; + } + + if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + return GL_TRUE; + } + + if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + return GL_TRUE; + } + + if (!ctx->Extensions.MESA_ycbcr_texture && _mesa_is_ycbcr_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + return GL_TRUE; + } + + if (!ctx->Extensions.EXT_packed_depth_stencil + && _mesa_is_depthstencil_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + return GL_TRUE; + } + + if (!ctx->Extensions.ATI_envmap_bumpmap + && _mesa_is_dudv_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + return GL_TRUE; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + + if (!texObj || _mesa_is_proxy_texture(target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); + return GL_TRUE; + } + + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (!texImage) { + /* out of memory */ + return GL_TRUE; + } + + baseFormat = _mesa_get_format_base_format(texImage->TexFormat); + + /* Make sure the requested image format is compatible with the + * texture's format. Note that a color index texture can be converted + * to RGBA so that combo is allowed. + */ + if (_mesa_is_color_format(format) + && !_mesa_is_color_format(baseFormat) + && !_mesa_is_index_format(baseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return GL_TRUE; + } + else if (_mesa_is_index_format(format) + && !_mesa_is_index_format(baseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return GL_TRUE; + } + else if (_mesa_is_depth_format(format) + && !_mesa_is_depth_format(baseFormat) + && !_mesa_is_depthstencil_format(baseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return GL_TRUE; + } + else if (_mesa_is_ycbcr_format(format) + && !_mesa_is_ycbcr_format(baseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return GL_TRUE; + } + else if (_mesa_is_depthstencil_format(format) + && !_mesa_is_depthstencil_format(baseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return GL_TRUE; + } + else if (_mesa_is_dudv_format(format) + && !_mesa_is_dudv_format(baseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + return GL_TRUE; + } + + if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, + texImage->Height, texImage->Depth, + format, type, clientMemSize, pixels)) { + if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexImage(out of bounds PBO access)"); + } else { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetnTexImageARB(out of bounds access:" + " bufSize (%d) is too small)", clientMemSize); + } + return GL_TRUE; + } + + if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + /* PBO should not be mapped */ + if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexImage(PBO is mapped)"); + return GL_TRUE; + } + } + + return GL_FALSE; +} + + + +/** + * Get texture image. Called by glGetTexImage. + * + * \param target texture target. + * \param level image level. + * \param format pixel data format for returned image. + * \param type pixel data type for returned image. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels ) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (getteximage_error_check(ctx, target, level, format, type, + bufSize, pixels)) { + return; + } + + if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { + /* not an error, do nothing */ + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { + _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); + { + ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, + texObj, texImage); + } + _mesa_unlock_texture(ctx, texObj); +} + + +void GLAPIENTRY +_mesa_GetTexImage( GLenum target, GLint level, GLenum format, + GLenum type, GLvoid *pixels ) +{ + _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels); +} + + +/** + * Do error checking for a glGetCompressedTexImage() call. + * \return GL_TRUE if any error, GL_FALSE if no errors. + */ +static GLboolean +getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, + GLint level, GLsizei clientMemSize, GLvoid *img) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + const GLint maxLevels = _mesa_max_texture_levels(ctx, target); + GLuint compressedSize; + + if (maxLevels == 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)", + target); + return GL_TRUE; + } + + if (level < 0 || level >= maxLevels) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetCompressedTexImageARB(bad level = %d)", level); + return GL_TRUE; + } + + if (_mesa_is_proxy_texture(target)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetCompressedTexImageARB(bad target = %s)", + _mesa_lookup_enum_by_nr(target)); + return GL_TRUE; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); + return GL_TRUE; + } + + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (!texImage) { + /* probably invalid mipmap level */ + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetCompressedTexImageARB(level)"); + return GL_TRUE; + } + + if (!_mesa_is_format_compressed(texImage->TexFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetCompressedTexImageARB(texture is not compressed)"); + return GL_TRUE; + } + + compressedSize = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, + texImage->Depth); + + if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) { + /* do bounds checking on writing to client memory */ + if (clientMemSize < compressedSize) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetnCompressedTexImageARB(out of bounds access:" + " bufSize (%d) is too small)", clientMemSize); + } + } else { + /* do bounds checking on PBO write */ + if ((const GLubyte *) img + compressedSize > + (const GLubyte *) ctx->Pack.BufferObj->Size) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetCompressedTexImage(out of bounds PBO access)"); + return GL_TRUE; + } + + /* 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; + } + } + + return GL_FALSE; +} + + +void GLAPIENTRY +_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, + GLvoid *img) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) { + return; + } + + if (_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) { + /* not an error, do nothing */ + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { + _mesa_debug(ctx, + "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); + { + ctx->Driver.GetCompressedTexImage(ctx, target, level, img, + texObj, texImage); + } + _mesa_unlock_texture(ctx, texObj); +} + +void GLAPIENTRY +_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) +{ + _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img); +} diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 8568c68e1..de30b4fc6 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1,1692 +1,1338 @@ -/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * Copyright (c) 2008-2010 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * Mesa / Gallium format conversion and format selection code.
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "main/texstore.h"
-#include "main/image.h"
-#include "main/macros.h"
-#include "main/mfeatures.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_screen.h"
-#include "util/u_format.h"
-#include "st_context.h"
-#include "st_format.h"
-
-
-static GLuint
-format_max_bits(enum pipe_format format)
-{
- GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
-
- size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1));
- size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2));
- size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3));
- size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0));
- size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1));
- return size;
-}
-
-
-/**
- * Return basic GL datatype for the given gallium format.
- */
-GLenum
-st_format_datatype(enum pipe_format format)
-{
- const struct util_format_description *desc;
-
- desc = util_format_description(format);
- assert(desc);
-
- if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
- if (format == PIPE_FORMAT_B5G5R5A1_UNORM ||
- format == PIPE_FORMAT_B5G6R5_UNORM) {
- return GL_UNSIGNED_SHORT;
- }
- else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
- format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
- format == PIPE_FORMAT_Z24X8_UNORM ||
- format == PIPE_FORMAT_X8Z24_UNORM) {
- return GL_UNSIGNED_INT_24_8;
- }
- else {
- const GLuint size = format_max_bits(format);
- if (size == 8) {
- if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
- return GL_UNSIGNED_BYTE;
- else
- return GL_BYTE;
- }
- else if (size == 16) {
- if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
- return GL_UNSIGNED_SHORT;
- else
- return GL_SHORT;
- }
- else {
- assert( size <= 32 );
- if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
- return GL_UNSIGNED_INT;
- else
- return GL_INT;
- }
- }
- }
- else if (format == PIPE_FORMAT_UYVY) {
- return GL_UNSIGNED_SHORT;
- }
- else if (format == PIPE_FORMAT_YUYV) {
- return GL_UNSIGNED_SHORT;
- }
- else {
- /* probably a compressed format, unsupported anyway */
- return GL_NONE;
- }
-}
-
-
-/**
- * Translate Mesa format to Gallium format.
- */
-enum pipe_format
-st_mesa_format_to_pipe_format(gl_format mesaFormat)
-{
- switch (mesaFormat) {
- case MESA_FORMAT_RGBA8888:
- return PIPE_FORMAT_A8B8G8R8_UNORM;
- case MESA_FORMAT_RGBA8888_REV:
- return PIPE_FORMAT_R8G8B8A8_UNORM;
- case MESA_FORMAT_ARGB8888:
- return PIPE_FORMAT_B8G8R8A8_UNORM;
- case MESA_FORMAT_ARGB8888_REV:
- return PIPE_FORMAT_A8R8G8B8_UNORM;
- case MESA_FORMAT_XRGB8888:
- return PIPE_FORMAT_B8G8R8X8_UNORM;
- case MESA_FORMAT_XRGB8888_REV:
- return PIPE_FORMAT_X8R8G8B8_UNORM;
- case MESA_FORMAT_ARGB1555:
- return PIPE_FORMAT_B5G5R5A1_UNORM;
- case MESA_FORMAT_ARGB4444:
- return PIPE_FORMAT_B4G4R4A4_UNORM;
- case MESA_FORMAT_RGB565:
- return PIPE_FORMAT_B5G6R5_UNORM;
- case MESA_FORMAT_RGB332:
- return PIPE_FORMAT_B2G3R3_UNORM;
- case MESA_FORMAT_ARGB2101010:
- return PIPE_FORMAT_B10G10R10A2_UNORM;
- case MESA_FORMAT_AL44:
- return PIPE_FORMAT_L4A4_UNORM;
- case MESA_FORMAT_AL88:
- return PIPE_FORMAT_L8A8_UNORM;
- case MESA_FORMAT_AL1616:
- return PIPE_FORMAT_L16A16_UNORM;
- case MESA_FORMAT_A8:
- return PIPE_FORMAT_A8_UNORM;
- case MESA_FORMAT_A16:
- return PIPE_FORMAT_A16_UNORM;
- case MESA_FORMAT_L8:
- return PIPE_FORMAT_L8_UNORM;
- case MESA_FORMAT_L16:
- return PIPE_FORMAT_L16_UNORM;
- case MESA_FORMAT_I8:
- return PIPE_FORMAT_I8_UNORM;
- case MESA_FORMAT_I16:
- return PIPE_FORMAT_I16_UNORM;
- case MESA_FORMAT_Z16:
- return PIPE_FORMAT_Z16_UNORM;
- case MESA_FORMAT_Z32:
- return PIPE_FORMAT_Z32_UNORM;
- case MESA_FORMAT_Z24_S8:
- return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
- case MESA_FORMAT_S8_Z24:
- return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
- case MESA_FORMAT_Z24_X8:
- return PIPE_FORMAT_X8Z24_UNORM;
- case MESA_FORMAT_X8_Z24:
- return PIPE_FORMAT_Z24X8_UNORM;
- case MESA_FORMAT_S8:
- return PIPE_FORMAT_S8_USCALED;
- case MESA_FORMAT_YCBCR:
- return PIPE_FORMAT_UYVY;
-#if FEATURE_texture_s3tc
- case MESA_FORMAT_RGB_DXT1:
- return PIPE_FORMAT_DXT1_RGB;
- case MESA_FORMAT_RGBA_DXT1:
- return PIPE_FORMAT_DXT1_RGBA;
- case MESA_FORMAT_RGBA_DXT3:
- return PIPE_FORMAT_DXT3_RGBA;
- case MESA_FORMAT_RGBA_DXT5:
- return PIPE_FORMAT_DXT5_RGBA;
-#if FEATURE_EXT_texture_sRGB
- case MESA_FORMAT_SRGB_DXT1:
- return PIPE_FORMAT_DXT1_SRGB;
- case MESA_FORMAT_SRGBA_DXT1:
- return PIPE_FORMAT_DXT1_SRGBA;
- case MESA_FORMAT_SRGBA_DXT3:
- return PIPE_FORMAT_DXT3_SRGBA;
- case MESA_FORMAT_SRGBA_DXT5:
- return PIPE_FORMAT_DXT5_SRGBA;
-#endif
-#endif
-#if FEATURE_EXT_texture_sRGB
- case MESA_FORMAT_SLA8:
- return PIPE_FORMAT_L8A8_SRGB;
- case MESA_FORMAT_SL8:
- return PIPE_FORMAT_L8_SRGB;
- case MESA_FORMAT_SRGB8:
- return PIPE_FORMAT_R8G8B8_SRGB;
- case MESA_FORMAT_SRGBA8:
- return PIPE_FORMAT_A8B8G8R8_SRGB;
- case MESA_FORMAT_SARGB8:
- return PIPE_FORMAT_B8G8R8A8_SRGB;
-#endif
- case MESA_FORMAT_RGBA_FLOAT32:
- return PIPE_FORMAT_R32G32B32A32_FLOAT;
- case MESA_FORMAT_RGBA_FLOAT16:
- return PIPE_FORMAT_R16G16B16A16_FLOAT;
- case MESA_FORMAT_RGB_FLOAT32:
- return PIPE_FORMAT_R32G32B32_FLOAT;
- case MESA_FORMAT_RGB_FLOAT16:
- return PIPE_FORMAT_R16G16B16_FLOAT;
- case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
- return PIPE_FORMAT_L32A32_FLOAT;
- case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
- return PIPE_FORMAT_L16A16_FLOAT;
- case MESA_FORMAT_LUMINANCE_FLOAT32:
- return PIPE_FORMAT_L32_FLOAT;
- case MESA_FORMAT_LUMINANCE_FLOAT16:
- return PIPE_FORMAT_L16_FLOAT;
- case MESA_FORMAT_ALPHA_FLOAT32:
- return PIPE_FORMAT_A32_FLOAT;
- case MESA_FORMAT_ALPHA_FLOAT16:
- return PIPE_FORMAT_A16_FLOAT;
- case MESA_FORMAT_INTENSITY_FLOAT32:
- return PIPE_FORMAT_I32_FLOAT;
- case MESA_FORMAT_INTENSITY_FLOAT16:
- return PIPE_FORMAT_I16_FLOAT;
- case MESA_FORMAT_R_FLOAT32:
- return PIPE_FORMAT_R32_FLOAT;
- case MESA_FORMAT_R_FLOAT16:
- return PIPE_FORMAT_R16_FLOAT;
- case MESA_FORMAT_RG_FLOAT32:
- return PIPE_FORMAT_R32G32_FLOAT;
- case MESA_FORMAT_RG_FLOAT16:
- return PIPE_FORMAT_R16G16_FLOAT;
-
- case MESA_FORMAT_R8:
- return PIPE_FORMAT_R8_UNORM;
- case MESA_FORMAT_R16:
- return PIPE_FORMAT_R16_UNORM;
- case MESA_FORMAT_RG88:
- return PIPE_FORMAT_R8G8_UNORM;
- case MESA_FORMAT_RG1616:
- return PIPE_FORMAT_R16G16_UNORM;
- case MESA_FORMAT_RGBA_16:
- return PIPE_FORMAT_R16G16B16A16_UNORM;
-
- /* signed int formats */
- case MESA_FORMAT_RGBA_INT8:
- return PIPE_FORMAT_R8G8B8A8_SSCALED;
- case MESA_FORMAT_RGBA_INT16:
- return PIPE_FORMAT_R16G16B16A16_SSCALED;
- case MESA_FORMAT_RGBA_INT32:
- return PIPE_FORMAT_R32G32B32A32_SSCALED;
-
- /* unsigned int formats */
- case MESA_FORMAT_RGBA_UINT8:
- return PIPE_FORMAT_R8G8B8A8_USCALED;
- case MESA_FORMAT_RGBA_UINT16:
- return PIPE_FORMAT_R16G16B16A16_USCALED;
- case MESA_FORMAT_RGBA_UINT32:
- return PIPE_FORMAT_R32G32B32A32_USCALED;
-
- case MESA_FORMAT_RED_RGTC1:
- return PIPE_FORMAT_RGTC1_UNORM;
- case MESA_FORMAT_SIGNED_RED_RGTC1:
- return PIPE_FORMAT_RGTC1_SNORM;
- case MESA_FORMAT_RG_RGTC2:
- return PIPE_FORMAT_RGTC2_UNORM;
- case MESA_FORMAT_SIGNED_RG_RGTC2:
- return PIPE_FORMAT_RGTC2_SNORM;
-
- case MESA_FORMAT_L_LATC1:
- return PIPE_FORMAT_LATC1_UNORM;
- case MESA_FORMAT_SIGNED_L_LATC1:
- return PIPE_FORMAT_LATC1_SNORM;
- case MESA_FORMAT_LA_LATC2:
- return PIPE_FORMAT_LATC2_UNORM;
- case MESA_FORMAT_SIGNED_LA_LATC2:
- return PIPE_FORMAT_LATC2_SNORM;
-
- /* signed normalized formats */
- case MESA_FORMAT_SIGNED_R8:
- return PIPE_FORMAT_R8_SNORM;
- case MESA_FORMAT_SIGNED_RG88_REV:
- return PIPE_FORMAT_R8G8_SNORM;
- case MESA_FORMAT_SIGNED_RGBA8888_REV:
- return PIPE_FORMAT_R8G8B8A8_SNORM;
-
- case MESA_FORMAT_SIGNED_A8:
- return PIPE_FORMAT_A8_SNORM;
- case MESA_FORMAT_SIGNED_L8:
- return PIPE_FORMAT_L8_SNORM;
- case MESA_FORMAT_SIGNED_AL88:
- return PIPE_FORMAT_L8A8_SNORM;
- case MESA_FORMAT_SIGNED_I8:
- return PIPE_FORMAT_I8_SNORM;
-
- case MESA_FORMAT_SIGNED_R16:
- return PIPE_FORMAT_R16_SNORM;
- case MESA_FORMAT_SIGNED_GR1616:
- return PIPE_FORMAT_R16G16_SNORM;
- case MESA_FORMAT_SIGNED_RGBA_16:
- return PIPE_FORMAT_R16G16B16A16_SNORM;
-
- case MESA_FORMAT_SIGNED_A16:
- return PIPE_FORMAT_A16_SNORM;
- case MESA_FORMAT_SIGNED_L16:
- return PIPE_FORMAT_L16_SNORM;
- case MESA_FORMAT_SIGNED_AL1616:
- return PIPE_FORMAT_L16A16_SNORM;
- case MESA_FORMAT_SIGNED_I16:
- return PIPE_FORMAT_I16_SNORM;
-
- case MESA_FORMAT_RGB9_E5_FLOAT:
- return PIPE_FORMAT_R9G9B9E5_FLOAT;
- case MESA_FORMAT_R11_G11_B10_FLOAT:
- return PIPE_FORMAT_R11G11B10_FLOAT;
-
- default:
- assert(0);
- return PIPE_FORMAT_NONE;
- }
-}
-
-
-/**
- * Translate Gallium format to Mesa format.
- */
-gl_format
-st_pipe_format_to_mesa_format(enum pipe_format format)
-{
- switch (format) {
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- return MESA_FORMAT_RGBA8888;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return MESA_FORMAT_RGBA8888_REV;
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- return MESA_FORMAT_ARGB8888;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- return MESA_FORMAT_ARGB8888_REV;
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- return MESA_FORMAT_XRGB8888;
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- return MESA_FORMAT_XRGB8888_REV;
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- return MESA_FORMAT_ARGB1555;
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- return MESA_FORMAT_ARGB4444;
- case PIPE_FORMAT_B5G6R5_UNORM:
- return MESA_FORMAT_RGB565;
- case PIPE_FORMAT_B2G3R3_UNORM:
- return MESA_FORMAT_RGB332;
- case PIPE_FORMAT_B10G10R10A2_UNORM:
- return MESA_FORMAT_ARGB2101010;
- case PIPE_FORMAT_L4A4_UNORM:
- return MESA_FORMAT_AL44;
- case PIPE_FORMAT_L8A8_UNORM:
- return MESA_FORMAT_AL88;
- case PIPE_FORMAT_L16A16_UNORM:
- return MESA_FORMAT_AL1616;
- case PIPE_FORMAT_A8_UNORM:
- return MESA_FORMAT_A8;
- case PIPE_FORMAT_A16_UNORM:
- return MESA_FORMAT_A16;
- case PIPE_FORMAT_L8_UNORM:
- return MESA_FORMAT_L8;
- case PIPE_FORMAT_L16_UNORM:
- return MESA_FORMAT_L16;
- case PIPE_FORMAT_I8_UNORM:
- return MESA_FORMAT_I8;
- case PIPE_FORMAT_I16_UNORM:
- return MESA_FORMAT_I16;
- case PIPE_FORMAT_S8_USCALED:
- return MESA_FORMAT_S8;
-
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- return MESA_FORMAT_RGBA_16;
-
- case PIPE_FORMAT_Z16_UNORM:
- return MESA_FORMAT_Z16;
- case PIPE_FORMAT_Z32_UNORM:
- return MESA_FORMAT_Z32;
- case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
- return MESA_FORMAT_Z24_S8;
- case PIPE_FORMAT_X8Z24_UNORM:
- return MESA_FORMAT_Z24_X8;
- case PIPE_FORMAT_Z24X8_UNORM:
- return MESA_FORMAT_X8_Z24;
- case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
- return MESA_FORMAT_S8_Z24;
-
- case PIPE_FORMAT_UYVY:
- return MESA_FORMAT_YCBCR;
- case PIPE_FORMAT_YUYV:
- return MESA_FORMAT_YCBCR_REV;
-
-#if FEATURE_texture_s3tc
- case PIPE_FORMAT_DXT1_RGB:
- return MESA_FORMAT_RGB_DXT1;
- case PIPE_FORMAT_DXT1_RGBA:
- return MESA_FORMAT_RGBA_DXT1;
- case PIPE_FORMAT_DXT3_RGBA:
- return MESA_FORMAT_RGBA_DXT3;
- case PIPE_FORMAT_DXT5_RGBA:
- return MESA_FORMAT_RGBA_DXT5;
-#if FEATURE_EXT_texture_sRGB
- case PIPE_FORMAT_DXT1_SRGB:
- return MESA_FORMAT_SRGB_DXT1;
- case PIPE_FORMAT_DXT1_SRGBA:
- return MESA_FORMAT_SRGBA_DXT1;
- case PIPE_FORMAT_DXT3_SRGBA:
- return MESA_FORMAT_SRGBA_DXT3;
- case PIPE_FORMAT_DXT5_SRGBA:
- return MESA_FORMAT_SRGBA_DXT5;
-#endif
-#endif
-
-#if FEATURE_EXT_texture_sRGB
- case PIPE_FORMAT_L8A8_SRGB:
- return MESA_FORMAT_SLA8;
- case PIPE_FORMAT_L8_SRGB:
- return MESA_FORMAT_SL8;
- case PIPE_FORMAT_R8G8B8_SRGB:
- return MESA_FORMAT_SRGB8;
- case PIPE_FORMAT_A8B8G8R8_SRGB:
- return MESA_FORMAT_SRGBA8;
- case PIPE_FORMAT_B8G8R8A8_SRGB:
- return MESA_FORMAT_SARGB8;
-#endif
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return MESA_FORMAT_RGBA_FLOAT32;
- case PIPE_FORMAT_R16G16B16A16_FLOAT:
- return MESA_FORMAT_RGBA_FLOAT16;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- return MESA_FORMAT_RGB_FLOAT32;
- case PIPE_FORMAT_R16G16B16_FLOAT:
- return MESA_FORMAT_RGB_FLOAT16;
- case PIPE_FORMAT_L32A32_FLOAT:
- return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
- case PIPE_FORMAT_L16A16_FLOAT:
- return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
- case PIPE_FORMAT_L32_FLOAT:
- return MESA_FORMAT_LUMINANCE_FLOAT32;
- case PIPE_FORMAT_L16_FLOAT:
- return MESA_FORMAT_LUMINANCE_FLOAT16;
- case PIPE_FORMAT_A32_FLOAT:
- return MESA_FORMAT_ALPHA_FLOAT32;
- case PIPE_FORMAT_A16_FLOAT:
- return MESA_FORMAT_ALPHA_FLOAT16;
- case PIPE_FORMAT_I32_FLOAT:
- return MESA_FORMAT_INTENSITY_FLOAT32;
- case PIPE_FORMAT_I16_FLOAT:
- return MESA_FORMAT_INTENSITY_FLOAT16;
- case PIPE_FORMAT_R32_FLOAT:
- return MESA_FORMAT_R_FLOAT32;
- case PIPE_FORMAT_R16_FLOAT:
- return MESA_FORMAT_R_FLOAT16;
- case PIPE_FORMAT_R32G32_FLOAT:
- return MESA_FORMAT_RG_FLOAT32;
- case PIPE_FORMAT_R16G16_FLOAT:
- return MESA_FORMAT_RG_FLOAT16;
-
- case PIPE_FORMAT_R8_UNORM:
- return MESA_FORMAT_R8;
- case PIPE_FORMAT_R16_UNORM:
- return MESA_FORMAT_R16;
- case PIPE_FORMAT_R8G8_UNORM:
- return MESA_FORMAT_RG88;
- case PIPE_FORMAT_R16G16_UNORM:
- return MESA_FORMAT_RG1616;
-
- /* signed int formats */
- case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return MESA_FORMAT_RGBA_INT8;
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return MESA_FORMAT_RGBA_INT16;
- case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return MESA_FORMAT_RGBA_INT32;
-
- /* unsigned int formats */
- case PIPE_FORMAT_R8G8B8A8_USCALED:
- return MESA_FORMAT_RGBA_UINT8;
- case PIPE_FORMAT_R16G16B16A16_USCALED:
- return MESA_FORMAT_RGBA_UINT16;
- case PIPE_FORMAT_R32G32B32A32_USCALED:
- return MESA_FORMAT_RGBA_UINT32;
-
- case PIPE_FORMAT_RGTC1_UNORM:
- return MESA_FORMAT_RED_RGTC1;
- case PIPE_FORMAT_RGTC1_SNORM:
- return MESA_FORMAT_SIGNED_RED_RGTC1;
- case PIPE_FORMAT_RGTC2_UNORM:
- return MESA_FORMAT_RG_RGTC2;
- case PIPE_FORMAT_RGTC2_SNORM:
- return MESA_FORMAT_SIGNED_RG_RGTC2;
-
- case PIPE_FORMAT_LATC1_UNORM:
- return MESA_FORMAT_L_LATC1;
- case PIPE_FORMAT_LATC1_SNORM:
- return MESA_FORMAT_SIGNED_L_LATC1;
- case PIPE_FORMAT_LATC2_UNORM:
- return MESA_FORMAT_LA_LATC2;
- case PIPE_FORMAT_LATC2_SNORM:
- return MESA_FORMAT_SIGNED_LA_LATC2;
-
- /* signed normalized formats */
- case PIPE_FORMAT_R8_SNORM:
- return MESA_FORMAT_SIGNED_R8;
- case PIPE_FORMAT_R8G8_SNORM:
- return MESA_FORMAT_SIGNED_RG88_REV;
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- return MESA_FORMAT_SIGNED_RGBA8888_REV;
-
- case PIPE_FORMAT_A8_SNORM:
- return MESA_FORMAT_SIGNED_A8;
- case PIPE_FORMAT_L8_SNORM:
- return MESA_FORMAT_SIGNED_L8;
- case PIPE_FORMAT_L8A8_SNORM:
- return MESA_FORMAT_SIGNED_AL88;
- case PIPE_FORMAT_I8_SNORM:
- return MESA_FORMAT_SIGNED_I8;
-
- case PIPE_FORMAT_R16_SNORM:
- return MESA_FORMAT_SIGNED_R16;
- case PIPE_FORMAT_R16G16_SNORM:
- return MESA_FORMAT_SIGNED_GR1616;
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- return MESA_FORMAT_SIGNED_RGBA_16;
-
- case PIPE_FORMAT_A16_SNORM:
- return MESA_FORMAT_SIGNED_A16;
- case PIPE_FORMAT_L16_SNORM:
- return MESA_FORMAT_SIGNED_L16;
- case PIPE_FORMAT_L16A16_SNORM:
- return MESA_FORMAT_SIGNED_AL1616;
- case PIPE_FORMAT_I16_SNORM:
- return MESA_FORMAT_SIGNED_I16;
-
- case PIPE_FORMAT_R9G9B9E5_FLOAT:
- return MESA_FORMAT_RGB9_E5_FLOAT;
- case PIPE_FORMAT_R11G11B10_FLOAT:
- return MESA_FORMAT_R11_G11_B10_FLOAT;
-
- default:
- assert(0);
- return MESA_FORMAT_NONE;
- }
-}
-
-
-/**
- * Return first supported format from the given list.
- */
-static enum pipe_format
-find_supported_format(struct pipe_screen *screen,
- const enum pipe_format formats[],
- uint num_formats,
- enum pipe_texture_target target,
- unsigned sample_count,
- unsigned tex_usage)
-{
- uint i;
- for (i = 0; i < num_formats; i++) {
- if (screen->is_format_supported(screen, formats[i], target,
- sample_count, tex_usage)) {
- return formats[i];
- }
- }
- return PIPE_FORMAT_NONE;
-}
-
-
-/**
- * Find an RGBA format supported by the context/winsys.
- */
-static enum pipe_format
-default_rgba_format(struct pipe_screen *screen,
- enum pipe_texture_target target,
- unsigned sample_count,
- unsigned tex_usage)
-{
- static const enum pipe_format colorFormats[] = {
- PIPE_FORMAT_B8G8R8A8_UNORM,
- PIPE_FORMAT_A8R8G8B8_UNORM,
- PIPE_FORMAT_A8B8G8R8_UNORM,
- PIPE_FORMAT_B5G6R5_UNORM
- };
- return find_supported_format(screen, colorFormats, Elements(colorFormats),
- target, sample_count, tex_usage);
-}
-
-
-/**
- * Find an RGB format supported by the context/winsys.
- */
-static enum pipe_format
-default_rgb_format(struct pipe_screen *screen,
- enum pipe_texture_target target,
- unsigned sample_count,
- unsigned tex_usage)
-{
- static const enum pipe_format colorFormats[] = {
- PIPE_FORMAT_B8G8R8X8_UNORM,
- PIPE_FORMAT_X8R8G8B8_UNORM,
- PIPE_FORMAT_X8B8G8R8_UNORM,
- PIPE_FORMAT_B8G8R8A8_UNORM,
- PIPE_FORMAT_A8R8G8B8_UNORM,
- PIPE_FORMAT_A8B8G8R8_UNORM,
- PIPE_FORMAT_B5G6R5_UNORM
- };
- return find_supported_format(screen, colorFormats, Elements(colorFormats),
- target, sample_count, tex_usage);
-}
-
-/**
- * Find an sRGBA format supported by the context/winsys.
- */
-static enum pipe_format
-default_srgba_format(struct pipe_screen *screen,
- enum pipe_texture_target target,
- unsigned sample_count,
- unsigned tex_usage)
-{
- static const enum pipe_format colorFormats[] = {
- PIPE_FORMAT_B8G8R8A8_SRGB,
- PIPE_FORMAT_A8R8G8B8_SRGB,
- PIPE_FORMAT_A8B8G8R8_SRGB,
- };
- return find_supported_format(screen, colorFormats, Elements(colorFormats),
- target, sample_count, tex_usage);
-}
-
-
-/**
- * Given an OpenGL internalFormat value for a texture or surface, return
- * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
- * This is called during glTexImage2D, for example.
- *
- * The bindings parameter typically has PIPE_BIND_SAMPLER_VIEW set, plus
- * either PIPE_BINDING_RENDER_TARGET or PIPE_BINDING_DEPTH_STENCIL if
- * we want render-to-texture ability.
- *
- * \param internalFormat the user value passed to glTexImage2D
- * \param target one of PIPE_TEXTURE_x
- * \param bindings bitmask of PIPE_BIND_x flags.
- */
-enum pipe_format
-st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
- enum pipe_texture_target target, unsigned sample_count,
- unsigned bindings)
-{
-
- switch (internalFormat) {
- case GL_RGB10:
- case GL_RGB10_A2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B10G10R10A2_UNORM;
- /* Pass through. */
- case 4:
- case GL_RGBA:
- case GL_RGBA8:
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_BGRA:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B8G8R8A8_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B8G8R8A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case 3:
- case GL_RGB:
- case GL_RGB8:
- return default_rgb_format( screen, target, sample_count, bindings);
-
- case GL_RGB12:
- case GL_RGB16:
- case GL_RGBA12:
- case GL_RGBA16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_R16G16B16A16_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_R16G16B16A16_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_RGBA4:
- case GL_RGBA2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B4G4R4A4_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_RGB5_A1:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B5G5R5A1_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_R3_G3_B2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B2G3R3_UNORM;
- /* Pass through. */
- case GL_RGB5:
- case GL_RGB4:
- if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B5G6R5_UNORM;
- if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_B5G5R5A1_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_ALPHA12:
- case GL_ALPHA16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_A16_UNORM;
- /* Pass through. */
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_COMPRESSED_ALPHA:
- if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L16_UNORM;
- /* Pass through. */
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L16A16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L16A16_UNORM;
- /* Pass through. */
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_LUMINANCE4_ALPHA4:
- if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L4A4_UNORM;
- if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_I16_UNORM;
- /* Pass through. */
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_COMPRESSED_INTENSITY:
- if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_I8_UNORM;
- return default_rgba_format( screen, target, sample_count, bindings);
-
- case GL_YCBCR_MESA:
- if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target,
- sample_count, bindings)) {
- return PIPE_FORMAT_UYVY;
- }
- if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target,
- sample_count, bindings)) {
- return PIPE_FORMAT_YUYV;
- }
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RGB:
- /* can only sample from compressed formats */
- if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
- return PIPE_FORMAT_NONE;
- else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
- target, sample_count, bindings))
- return PIPE_FORMAT_DXT1_RGB;
- else
- return default_rgb_format(screen, target, sample_count, bindings);
-
- case GL_COMPRESSED_RGBA:
- /* can only sample from compressed formats */
- if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
- return PIPE_FORMAT_NONE;
- else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
- target, sample_count, bindings))
- return PIPE_FORMAT_DXT3_RGBA;
- else
- return default_rgba_format(screen, target, sample_count, bindings);
-
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
- target, sample_count, bindings))
- return PIPE_FORMAT_DXT1_RGB;
- else
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGBA,
- target, sample_count, bindings))
- return PIPE_FORMAT_DXT1_RGBA;
- else
- return PIPE_FORMAT_NONE;
-
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
- target, sample_count, bindings))
- return PIPE_FORMAT_DXT3_RGBA;
- else
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
- target, sample_count, bindings))
- return PIPE_FORMAT_DXT5_RGBA;
- else
- return PIPE_FORMAT_NONE;
-
-#if 0
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- return PIPE_FORMAT_RGB_FXT1;
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- return PIPE_FORMAT_RGB_FXT1;
-#endif
-
- case GL_DEPTH_COMPONENT16:
- if (screen->is_format_supported(screen, PIPE_FORMAT_Z16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_Z16_UNORM;
- /* fall-through */
- case GL_DEPTH_COMPONENT24:
- if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- target, sample_count, bindings))
- return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
- if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- target, sample_count, bindings))
- return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
- /* fall-through */
- case GL_DEPTH_COMPONENT32:
- if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_Z32_UNORM;
- /* fall-through */
- case GL_DEPTH_COMPONENT:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_Z32_UNORM,
- PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- PIPE_FORMAT_Z16_UNORM
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_STENCIL_INDEX:
- case GL_STENCIL_INDEX1_EXT:
- case GL_STENCIL_INDEX4_EXT:
- case GL_STENCIL_INDEX8_EXT:
- case GL_STENCIL_INDEX16_EXT:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_S8_USCALED,
- PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_FORMAT_S8_USCALED_Z24_UNORM
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_DEPTH_STENCIL_EXT:
- case GL_DEPTH24_STENCIL8_EXT:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_FORMAT_S8_USCALED_Z24_UNORM
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_SRGB_EXT:
- case GL_SRGB8_EXT:
- case GL_SRGB_ALPHA_EXT:
- case GL_SRGB8_ALPHA8_EXT:
- return default_srgba_format( screen, target, sample_count, bindings);
-
- case GL_COMPRESSED_SRGB_EXT:
- case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGB, target,
- sample_count, bindings))
- return PIPE_FORMAT_DXT1_SRGB;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
- return PIPE_FORMAT_DXT1_SRGBA;
-
- case GL_COMPRESSED_SRGB_ALPHA_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_SRGBA, target,
- sample_count, bindings))
- return PIPE_FORMAT_DXT3_SRGBA;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
- return PIPE_FORMAT_DXT5_SRGBA;
-
- case GL_SLUMINANCE_ALPHA_EXT:
- case GL_SLUMINANCE8_ALPHA8_EXT:
- case GL_COMPRESSED_SLUMINANCE_EXT:
- case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_SRGB;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- case GL_SLUMINANCE_EXT:
- case GL_SLUMINANCE8_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8_SRGB;
- return default_srgba_format( screen, target, sample_count, bindings);
-
- /* prefer formats in order of data size, choosing 16-bit ones if equal sized */
- case GL_RGBA16F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_RGB16F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16G16B16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_R32G32B32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_LUMINANCE_ALPHA16F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_ALPHA16F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_A16_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_A32_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_INTENSITY16F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_I16_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_I32_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_LUMINANCE16F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L16_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_L32_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_R16F:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16_FLOAT,
- PIPE_FORMAT_R16G16_FLOAT,
- PIPE_FORMAT_R32_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_R32G32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_RG16F:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16G16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT,
- PIPE_FORMAT_R32G32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- /* try a 32-bit format if available, otherwise fallback to a 16-bit one */
- case GL_RGBA32F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_RGB32F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R32G32B32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_LUMINANCE_ALPHA32F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_ALPHA32F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_A32_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_A16_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_INTENSITY32F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_I32_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_I16_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_LUMINANCE32F_ARB:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L32_FLOAT,
- PIPE_FORMAT_L32A32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_L16_FLOAT,
- PIPE_FORMAT_L16A16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_R32F:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R32_FLOAT,
- PIPE_FORMAT_R32G32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_R16_FLOAT,
- PIPE_FORMAT_R16G16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
- case GL_RG32F:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R32G32_FLOAT,
- PIPE_FORMAT_R32G32B32A32_FLOAT,
- PIPE_FORMAT_R16G16_FLOAT,
- PIPE_FORMAT_R16G16B16A16_FLOAT
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_RED:
- case GL_R8:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R8_UNORM;
- return PIPE_FORMAT_NONE;
- case GL_RG:
- case GL_RG8:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R8G8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_R16:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R16_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_RG16:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R16G16_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RED:
- case GL_COMPRESSED_RED_RGTC1:
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_RGTC1_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_SIGNED_RED_RGTC1:
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_SNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_RGTC1_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_RG:
- case GL_COMPRESSED_RG_RGTC2:
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_RGTC2_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_R8G8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_SIGNED_RG_RGTC2:
- if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_SNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_RGTC2_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_LUMINANCE:
- case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC1_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC1_SNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC1_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
- case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC2_UNORM;
- if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_UNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_L8A8_UNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_LATC2_SNORM, target,
- sample_count, bindings))
- return PIPE_FORMAT_LATC2_SNORM;
- return PIPE_FORMAT_NONE;
-
- /* signed/unsigned integer formats.
- * XXX Mesa only has formats for RGBA signed/unsigned integer formats.
- * If/when new formats are added this code should be updated.
- */
- case GL_RED_INTEGER_EXT:
- case GL_GREEN_INTEGER_EXT:
- case GL_BLUE_INTEGER_EXT:
- case GL_ALPHA_INTEGER_EXT:
- case GL_RGB_INTEGER_EXT:
- case GL_RGBA_INTEGER_EXT:
- case GL_BGR_INTEGER_EXT:
- case GL_BGRA_INTEGER_EXT:
- case GL_LUMINANCE_INTEGER_EXT:
- case GL_LUMINANCE_ALPHA_INTEGER_EXT:
- /* fall-through */
- case GL_RGBA8I_EXT:
- case GL_RGB8I_EXT:
- case GL_ALPHA8I_EXT:
- case GL_INTENSITY8I_EXT:
- case GL_LUMINANCE8I_EXT:
- case GL_LUMINANCE_ALPHA8I_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SSCALED,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R8G8B8A8_SSCALED;
- return PIPE_FORMAT_NONE;
- case GL_RGBA16I_EXT:
- case GL_RGB16I_EXT:
- case GL_ALPHA16I_EXT:
- case GL_INTENSITY16I_EXT:
- case GL_LUMINANCE16I_EXT:
- case GL_LUMINANCE_ALPHA16I_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_SSCALED,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R16G16B16A16_SSCALED;
- return PIPE_FORMAT_NONE;
- case GL_RGBA32I_EXT:
- case GL_RGB32I_EXT:
- case GL_ALPHA32I_EXT:
- case GL_INTENSITY32I_EXT:
- case GL_LUMINANCE32I_EXT:
- case GL_LUMINANCE_ALPHA32I_EXT:
- /* xxx */
- if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_SSCALED,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R32G32B32A32_SSCALED;
- return PIPE_FORMAT_NONE;
-
- case GL_RGBA8UI_EXT:
- case GL_RGB8UI_EXT:
- case GL_ALPHA8UI_EXT:
- case GL_INTENSITY8UI_EXT:
- case GL_LUMINANCE8UI_EXT:
- case GL_LUMINANCE_ALPHA8UI_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_USCALED,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R8G8B8A8_USCALED;
- return PIPE_FORMAT_NONE;
-
- case GL_RGBA16UI_EXT:
- case GL_RGB16UI_EXT:
- case GL_ALPHA16UI_EXT:
- case GL_INTENSITY16UI_EXT:
- case GL_LUMINANCE16UI_EXT:
- case GL_LUMINANCE_ALPHA16UI_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_USCALED,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R16G16B16A16_USCALED;
- return PIPE_FORMAT_NONE;
-
- case GL_RGBA32UI_EXT:
- case GL_RGB32UI_EXT:
- case GL_ALPHA32UI_EXT:
- case GL_INTENSITY32UI_EXT:
- case GL_LUMINANCE32UI_EXT:
- case GL_LUMINANCE_ALPHA32UI_EXT:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_USCALED,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R32G32B32A32_USCALED;
- return PIPE_FORMAT_NONE;
-
- /* signed normalized formats */
- case GL_RED_SNORM:
- case GL_R8_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R8_SNORM,
- PIPE_FORMAT_R8G8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_R16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16_SNORM,
- PIPE_FORMAT_R16G16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_R8_SNORM,
- PIPE_FORMAT_R8G8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_RG_SNORM:
- case GL_RG8_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R8G8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_RG16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16G16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_R8G8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_RGB_SNORM:
- case GL_RGB8_SNORM:
- case GL_RGBA_SNORM:
- case GL_RGBA8_SNORM:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SNORM,
- target,
- sample_count, bindings))
- return PIPE_FORMAT_R8G8B8A8_SNORM;
- return PIPE_FORMAT_NONE;
-
- case GL_RGB16_SNORM:
- case GL_RGBA16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
-
- case GL_ALPHA_SNORM:
- case GL_ALPHA8_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_A8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_ALPHA16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_A16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_A8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_LUMINANCE_SNORM:
- case GL_LUMINANCE8_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_LUMINANCE16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_L8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_LUMINANCE_ALPHA_SNORM:
- case GL_LUMINANCE8_ALPHA8_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L8A8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_LUMINANCE16_ALPHA16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_L16A16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_L8A8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_INTENSITY_SNORM:
- case GL_INTENSITY8_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_I8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_INTENSITY16_SNORM:
- {
- static const enum pipe_format formats[] = {
- PIPE_FORMAT_I16_SNORM,
- PIPE_FORMAT_R16G16B16A16_SNORM,
- PIPE_FORMAT_I8_SNORM,
- PIPE_FORMAT_R8G8B8A8_SNORM,
- };
- return find_supported_format(screen, formats, Elements(formats),
- target, sample_count, bindings);
- }
-
- case GL_RGB9_E5:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R9G9B9E5_FLOAT, target,
- sample_count, bindings)) {
- return PIPE_FORMAT_R9G9B9E5_FLOAT;
- }
- return PIPE_FORMAT_NONE;
-
- case GL_R11F_G11F_B10F:
- if (screen->is_format_supported(screen, PIPE_FORMAT_R11G11B10_FLOAT, target,
- sample_count, bindings)) {
- return PIPE_FORMAT_R11G11B10_FLOAT;
- }
- return PIPE_FORMAT_NONE;
-
- default:
- return PIPE_FORMAT_NONE;
- }
-}
-
-
-/**
- * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
- */
-enum pipe_format
-st_choose_renderbuffer_format(struct pipe_screen *screen,
- GLenum internalFormat, unsigned sample_count)
-{
- uint usage;
- if (_mesa_is_depth_or_stencil_format(internalFormat))
- usage = PIPE_BIND_DEPTH_STENCIL;
- else
- usage = PIPE_BIND_RENDER_TARGET;
- return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D,
- sample_count, usage);
-}
-
-
-/**
- * Called via ctx->Driver.chooseTextureFormat().
- */
-gl_format
-st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
- GLenum format, GLenum type, GLboolean renderable)
-{
- struct pipe_screen *screen = st_context(ctx)->pipe->screen;
- enum pipe_format pFormat;
- uint bindings;
-
- (void) format;
- (void) type;
-
- /* GL textures may wind up being render targets, but we don't know
- * that in advance. Specify potential render target flags now.
- */
- bindings = PIPE_BIND_SAMPLER_VIEW;
- if (renderable == GL_TRUE) {
- if (_mesa_is_depth_format(internalFormat) ||
- _mesa_is_depth_or_stencil_format(internalFormat))
- bindings |= PIPE_BIND_DEPTH_STENCIL;
- else
- bindings |= PIPE_BIND_RENDER_TARGET;
- }
-
- pFormat = st_choose_format(screen, internalFormat,
- PIPE_TEXTURE_2D, 0, bindings);
-
- if (pFormat == PIPE_FORMAT_NONE) {
- /* try choosing format again, this time without render target bindings */
- pFormat = st_choose_format(screen, internalFormat,
- PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
- }
-
- if (pFormat == PIPE_FORMAT_NONE) {
- /* no luck at all */
- return MESA_FORMAT_NONE;
- }
-
- return st_pipe_format_to_mesa_format(pFormat);
-}
-
-gl_format
-st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
- GLenum format, GLenum type)
-{
- boolean want_renderable =
- internalFormat == 3 || internalFormat == 4 ||
- internalFormat == GL_RGB || internalFormat == GL_RGBA ||
- internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 ||
- internalFormat == GL_BGRA;
-
- return st_ChooseTextureFormat_renderable(ctx, internalFormat,
- format, type, want_renderable);
-}
-
-/**
- * Test if a gallium format is equivalent to a GL format/type.
- */
-GLboolean
-st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type)
-{
- switch (pFormat) {
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- return format == GL_RGBA && type == GL_UNSIGNED_BYTE;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- return format == GL_BGRA && type == GL_UNSIGNED_BYTE;
- case PIPE_FORMAT_B5G6R5_UNORM:
- return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5;
- /* XXX more combos... */
- default:
- return GL_FALSE;
- }
-}
-
-GLboolean
-st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
-{
- if (format1 == format2)
- return GL_TRUE;
-
- if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM &&
- format2 == PIPE_FORMAT_B8G8R8X8_UNORM)
- return GL_TRUE;
-
- if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM &&
- format2 == PIPE_FORMAT_B8G8R8A8_UNORM)
- return GL_TRUE;
-
- if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM &&
- format2 == PIPE_FORMAT_X8B8G8R8_UNORM)
- return GL_TRUE;
-
- if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM &&
- format2 == PIPE_FORMAT_A8B8G8R8_UNORM)
- return GL_TRUE;
-
- if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM &&
- format2 == PIPE_FORMAT_X8R8G8B8_UNORM)
- return GL_TRUE;
-
- if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM &&
- format2 == PIPE_FORMAT_A8R8G8B8_UNORM)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-
-/**
- * This is used for translating texture border color and the clear
- * color. For example, the clear color is interpreted according to
- * the renderbuffer's base format. For example, if clearing a
- * GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] =
- * alpha. Similarly for texture border colors.
- */
-void
-st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
- GLfloat colorOut[4])
-{
- switch (baseFormat) {
- case GL_RED:
- colorOut[0] = colorIn[0];
- colorOut[1] = 0.0F;
- colorOut[2] = 0.0F;
- colorOut[3] = 1.0F;
- break;
- case GL_RG:
- colorOut[0] = colorIn[0];
- colorOut[1] = colorIn[1];
- colorOut[2] = 0.0F;
- colorOut[3] = 1.0F;
- break;
- case GL_RGB:
- colorOut[0] = colorIn[0];
- colorOut[1] = colorIn[1];
- colorOut[2] = colorIn[2];
- colorOut[3] = 1.0F;
- break;
- case GL_ALPHA:
- colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
- colorOut[3] = colorIn[3];
- break;
- case GL_LUMINANCE:
- colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
- colorOut[3] = 1.0;
- break;
- case GL_LUMINANCE_ALPHA:
- colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
- colorOut[3] = colorIn[3];
- break;
- case GL_INTENSITY:
- colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
- break;
- default:
- COPY_4V(colorOut, colorIn);
- }
-}
+/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright (c) 2008-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Mesa / Gallium format conversion and format selection code. + * \author Brian Paul + */ + +#include "main/imports.h" +#include "main/context.h" +#include "main/texstore.h" +#include "main/image.h" +#include "main/macros.h" +#include "main/mfeatures.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" +#include "util/u_format.h" +#include "st_context.h" +#include "st_format.h" + + +static GLuint +format_max_bits(enum pipe_format format) +{ + GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0); + + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)); + size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)); + return size; +} + + +/** + * Return basic GL datatype for the given gallium format. + */ +GLenum +st_format_datatype(enum pipe_format format) +{ + const struct util_format_description *desc; + + desc = util_format_description(format); + assert(desc); + + if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) { + if (format == PIPE_FORMAT_B5G5R5A1_UNORM || + format == PIPE_FORMAT_B5G6R5_UNORM) { + return GL_UNSIGNED_SHORT; + } + else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || + format == PIPE_FORMAT_S8_USCALED_Z24_UNORM || + format == PIPE_FORMAT_Z24X8_UNORM || + format == PIPE_FORMAT_X8Z24_UNORM) { + return GL_UNSIGNED_INT_24_8; + } + else { + const GLuint size = format_max_bits(format); + if (size == 8) { + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) + return GL_UNSIGNED_BYTE; + else + return GL_BYTE; + } + else if (size == 16) { + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) + return GL_UNSIGNED_SHORT; + else + return GL_SHORT; + } + else { + assert( size <= 32 ); + if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) + return GL_UNSIGNED_INT; + else + return GL_INT; + } + } + } + else if (format == PIPE_FORMAT_UYVY) { + return GL_UNSIGNED_SHORT; + } + else if (format == PIPE_FORMAT_YUYV) { + return GL_UNSIGNED_SHORT; + } + else { + /* probably a compressed format, unsupported anyway */ + return GL_NONE; + } +} + + +/** + * Translate Mesa format to Gallium format. + */ +enum pipe_format +st_mesa_format_to_pipe_format(gl_format mesaFormat) +{ + switch (mesaFormat) { + case MESA_FORMAT_RGBA8888: + return PIPE_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_RGBA8888_REV: + return PIPE_FORMAT_R8G8B8A8_UNORM; + case MESA_FORMAT_ARGB8888: + return PIPE_FORMAT_B8G8R8A8_UNORM; + case MESA_FORMAT_ARGB8888_REV: + return PIPE_FORMAT_A8R8G8B8_UNORM; + case MESA_FORMAT_XRGB8888: + return PIPE_FORMAT_B8G8R8X8_UNORM; + case MESA_FORMAT_XRGB8888_REV: + return PIPE_FORMAT_X8R8G8B8_UNORM; + case MESA_FORMAT_ARGB1555: + return PIPE_FORMAT_B5G5R5A1_UNORM; + case MESA_FORMAT_ARGB4444: + return PIPE_FORMAT_B4G4R4A4_UNORM; + case MESA_FORMAT_RGB565: + return PIPE_FORMAT_B5G6R5_UNORM; + case MESA_FORMAT_RGB332: + return PIPE_FORMAT_B2G3R3_UNORM; + case MESA_FORMAT_ARGB2101010: + return PIPE_FORMAT_B10G10R10A2_UNORM; + case MESA_FORMAT_AL44: + return PIPE_FORMAT_L4A4_UNORM; + case MESA_FORMAT_AL88: + return PIPE_FORMAT_L8A8_UNORM; + case MESA_FORMAT_AL1616: + return PIPE_FORMAT_L16A16_UNORM; + case MESA_FORMAT_A8: + return PIPE_FORMAT_A8_UNORM; + case MESA_FORMAT_A16: + return PIPE_FORMAT_A16_UNORM; + case MESA_FORMAT_L8: + return PIPE_FORMAT_L8_UNORM; + case MESA_FORMAT_L16: + return PIPE_FORMAT_L16_UNORM; + case MESA_FORMAT_I8: + return PIPE_FORMAT_I8_UNORM; + case MESA_FORMAT_I16: + return PIPE_FORMAT_I16_UNORM; + case MESA_FORMAT_Z16: + return PIPE_FORMAT_Z16_UNORM; + case MESA_FORMAT_Z32: + return PIPE_FORMAT_Z32_UNORM; + case MESA_FORMAT_Z24_S8: + return PIPE_FORMAT_S8_USCALED_Z24_UNORM; + case MESA_FORMAT_S8_Z24: + return PIPE_FORMAT_Z24_UNORM_S8_USCALED; + case MESA_FORMAT_Z24_X8: + return PIPE_FORMAT_X8Z24_UNORM; + case MESA_FORMAT_X8_Z24: + return PIPE_FORMAT_Z24X8_UNORM; + case MESA_FORMAT_S8: + return PIPE_FORMAT_S8_USCALED; + case MESA_FORMAT_YCBCR: + return PIPE_FORMAT_UYVY; +#if FEATURE_texture_s3tc + case MESA_FORMAT_RGB_DXT1: + return PIPE_FORMAT_DXT1_RGB; + case MESA_FORMAT_RGBA_DXT1: + return PIPE_FORMAT_DXT1_RGBA; + case MESA_FORMAT_RGBA_DXT3: + return PIPE_FORMAT_DXT3_RGBA; + case MESA_FORMAT_RGBA_DXT5: + return PIPE_FORMAT_DXT5_RGBA; +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SRGB_DXT1: + return PIPE_FORMAT_DXT1_SRGB; + case MESA_FORMAT_SRGBA_DXT1: + return PIPE_FORMAT_DXT1_SRGBA; + case MESA_FORMAT_SRGBA_DXT3: + return PIPE_FORMAT_DXT3_SRGBA; + case MESA_FORMAT_SRGBA_DXT5: + return PIPE_FORMAT_DXT5_SRGBA; +#endif +#endif +#if FEATURE_EXT_texture_sRGB + case MESA_FORMAT_SLA8: + return PIPE_FORMAT_L8A8_SRGB; + case MESA_FORMAT_SL8: + return PIPE_FORMAT_L8_SRGB; + case MESA_FORMAT_SRGB8: + return PIPE_FORMAT_R8G8B8_SRGB; + case MESA_FORMAT_SRGBA8: + return PIPE_FORMAT_A8B8G8R8_SRGB; + case MESA_FORMAT_SARGB8: + return PIPE_FORMAT_B8G8R8A8_SRGB; +#endif + case MESA_FORMAT_RGBA_FLOAT32: + return PIPE_FORMAT_R32G32B32A32_FLOAT; + case MESA_FORMAT_RGBA_FLOAT16: + return PIPE_FORMAT_R16G16B16A16_FLOAT; + case MESA_FORMAT_RGB_FLOAT32: + return PIPE_FORMAT_R32G32B32_FLOAT; + case MESA_FORMAT_RGB_FLOAT16: + return PIPE_FORMAT_R16G16B16_FLOAT; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + return PIPE_FORMAT_L32A32_FLOAT; + case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + return PIPE_FORMAT_L16A16_FLOAT; + case MESA_FORMAT_LUMINANCE_FLOAT32: + return PIPE_FORMAT_L32_FLOAT; + case MESA_FORMAT_LUMINANCE_FLOAT16: + return PIPE_FORMAT_L16_FLOAT; + case MESA_FORMAT_ALPHA_FLOAT32: + return PIPE_FORMAT_A32_FLOAT; + case MESA_FORMAT_ALPHA_FLOAT16: + return PIPE_FORMAT_A16_FLOAT; + case MESA_FORMAT_INTENSITY_FLOAT32: + return PIPE_FORMAT_I32_FLOAT; + case MESA_FORMAT_INTENSITY_FLOAT16: + return PIPE_FORMAT_I16_FLOAT; + case MESA_FORMAT_R_FLOAT32: + return PIPE_FORMAT_R32_FLOAT; + case MESA_FORMAT_R_FLOAT16: + return PIPE_FORMAT_R16_FLOAT; + case MESA_FORMAT_RG_FLOAT32: + return PIPE_FORMAT_R32G32_FLOAT; + case MESA_FORMAT_RG_FLOAT16: + return PIPE_FORMAT_R16G16_FLOAT; + + case MESA_FORMAT_R8: + return PIPE_FORMAT_R8_UNORM; + case MESA_FORMAT_R16: + return PIPE_FORMAT_R16_UNORM; + case MESA_FORMAT_RG88: + return PIPE_FORMAT_R8G8_UNORM; + case MESA_FORMAT_RG1616: + return PIPE_FORMAT_R16G16_UNORM; + case MESA_FORMAT_RGBA_16: + return PIPE_FORMAT_R16G16B16A16_UNORM; + + /* signed int formats */ + case MESA_FORMAT_RGBA_INT8: + return PIPE_FORMAT_R8G8B8A8_SSCALED; + case MESA_FORMAT_RGBA_INT16: + return PIPE_FORMAT_R16G16B16A16_SSCALED; + case MESA_FORMAT_RGBA_INT32: + return PIPE_FORMAT_R32G32B32A32_SSCALED; + + /* unsigned int formats */ + case MESA_FORMAT_RGBA_UINT8: + return PIPE_FORMAT_R8G8B8A8_USCALED; + case MESA_FORMAT_RGBA_UINT16: + return PIPE_FORMAT_R16G16B16A16_USCALED; + case MESA_FORMAT_RGBA_UINT32: + return PIPE_FORMAT_R32G32B32A32_USCALED; + + case MESA_FORMAT_RED_RGTC1: + return PIPE_FORMAT_RGTC1_UNORM; + case MESA_FORMAT_SIGNED_RED_RGTC1: + return PIPE_FORMAT_RGTC1_SNORM; + case MESA_FORMAT_RG_RGTC2: + return PIPE_FORMAT_RGTC2_UNORM; + case MESA_FORMAT_SIGNED_RG_RGTC2: + return PIPE_FORMAT_RGTC2_SNORM; + + case MESA_FORMAT_L_LATC1: + return PIPE_FORMAT_LATC1_UNORM; + case MESA_FORMAT_SIGNED_L_LATC1: + return PIPE_FORMAT_LATC1_SNORM; + case MESA_FORMAT_LA_LATC2: + return PIPE_FORMAT_LATC2_UNORM; + case MESA_FORMAT_SIGNED_LA_LATC2: + return PIPE_FORMAT_LATC2_SNORM; + + /* signed normalized formats */ + case MESA_FORMAT_SIGNED_R8: + return PIPE_FORMAT_R8_SNORM; + case MESA_FORMAT_SIGNED_RG88_REV: + return PIPE_FORMAT_R8G8_SNORM; + case MESA_FORMAT_SIGNED_RGBA8888_REV: + return PIPE_FORMAT_R8G8B8A8_SNORM; + + case MESA_FORMAT_SIGNED_A8: + return PIPE_FORMAT_A8_SNORM; + case MESA_FORMAT_SIGNED_L8: + return PIPE_FORMAT_L8_SNORM; + case MESA_FORMAT_SIGNED_AL88: + return PIPE_FORMAT_L8A8_SNORM; + case MESA_FORMAT_SIGNED_I8: + return PIPE_FORMAT_I8_SNORM; + + case MESA_FORMAT_SIGNED_R16: + return PIPE_FORMAT_R16_SNORM; + case MESA_FORMAT_SIGNED_GR1616: + return PIPE_FORMAT_R16G16_SNORM; + case MESA_FORMAT_SIGNED_RGBA_16: + return PIPE_FORMAT_R16G16B16A16_SNORM; + + case MESA_FORMAT_SIGNED_A16: + return PIPE_FORMAT_A16_SNORM; + case MESA_FORMAT_SIGNED_L16: + return PIPE_FORMAT_L16_SNORM; + case MESA_FORMAT_SIGNED_AL1616: + return PIPE_FORMAT_L16A16_SNORM; + case MESA_FORMAT_SIGNED_I16: + return PIPE_FORMAT_I16_SNORM; + + case MESA_FORMAT_RGB9_E5_FLOAT: + return PIPE_FORMAT_R9G9B9E5_FLOAT; + case MESA_FORMAT_R11_G11_B10_FLOAT: + return PIPE_FORMAT_R11G11B10_FLOAT; + + default: + assert(0); + return PIPE_FORMAT_NONE; + } +} + + +/** + * Translate Gallium format to Mesa format. + */ +gl_format +st_pipe_format_to_mesa_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A8B8G8R8_UNORM: + return MESA_FORMAT_RGBA8888; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return MESA_FORMAT_RGBA8888_REV; + case PIPE_FORMAT_B8G8R8A8_UNORM: + return MESA_FORMAT_ARGB8888; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return MESA_FORMAT_ARGB8888_REV; + case PIPE_FORMAT_B8G8R8X8_UNORM: + return MESA_FORMAT_XRGB8888; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return MESA_FORMAT_XRGB8888_REV; + case PIPE_FORMAT_B5G5R5A1_UNORM: + return MESA_FORMAT_ARGB1555; + case PIPE_FORMAT_B4G4R4A4_UNORM: + return MESA_FORMAT_ARGB4444; + case PIPE_FORMAT_B5G6R5_UNORM: + return MESA_FORMAT_RGB565; + case PIPE_FORMAT_B2G3R3_UNORM: + return MESA_FORMAT_RGB332; + case PIPE_FORMAT_B10G10R10A2_UNORM: + return MESA_FORMAT_ARGB2101010; + case PIPE_FORMAT_L4A4_UNORM: + return MESA_FORMAT_AL44; + case PIPE_FORMAT_L8A8_UNORM: + return MESA_FORMAT_AL88; + case PIPE_FORMAT_L16A16_UNORM: + return MESA_FORMAT_AL1616; + case PIPE_FORMAT_A8_UNORM: + return MESA_FORMAT_A8; + case PIPE_FORMAT_A16_UNORM: + return MESA_FORMAT_A16; + case PIPE_FORMAT_L8_UNORM: + return MESA_FORMAT_L8; + case PIPE_FORMAT_L16_UNORM: + return MESA_FORMAT_L16; + case PIPE_FORMAT_I8_UNORM: + return MESA_FORMAT_I8; + case PIPE_FORMAT_I16_UNORM: + return MESA_FORMAT_I16; + case PIPE_FORMAT_S8_USCALED: + return MESA_FORMAT_S8; + + case PIPE_FORMAT_R16G16B16A16_UNORM: + return MESA_FORMAT_RGBA_16; + + case PIPE_FORMAT_Z16_UNORM: + return MESA_FORMAT_Z16; + case PIPE_FORMAT_Z32_UNORM: + return MESA_FORMAT_Z32; + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return MESA_FORMAT_Z24_S8; + case PIPE_FORMAT_X8Z24_UNORM: + return MESA_FORMAT_Z24_X8; + case PIPE_FORMAT_Z24X8_UNORM: + return MESA_FORMAT_X8_Z24; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return MESA_FORMAT_S8_Z24; + + case PIPE_FORMAT_UYVY: + return MESA_FORMAT_YCBCR; + case PIPE_FORMAT_YUYV: + return MESA_FORMAT_YCBCR_REV; + +#if FEATURE_texture_s3tc + case PIPE_FORMAT_DXT1_RGB: + return MESA_FORMAT_RGB_DXT1; + case PIPE_FORMAT_DXT1_RGBA: + return MESA_FORMAT_RGBA_DXT1; + case PIPE_FORMAT_DXT3_RGBA: + return MESA_FORMAT_RGBA_DXT3; + case PIPE_FORMAT_DXT5_RGBA: + return MESA_FORMAT_RGBA_DXT5; +#if FEATURE_EXT_texture_sRGB + case PIPE_FORMAT_DXT1_SRGB: + return MESA_FORMAT_SRGB_DXT1; + case PIPE_FORMAT_DXT1_SRGBA: + return MESA_FORMAT_SRGBA_DXT1; + case PIPE_FORMAT_DXT3_SRGBA: + return MESA_FORMAT_SRGBA_DXT3; + case PIPE_FORMAT_DXT5_SRGBA: + return MESA_FORMAT_SRGBA_DXT5; +#endif +#endif + +#if FEATURE_EXT_texture_sRGB + case PIPE_FORMAT_L8A8_SRGB: + return MESA_FORMAT_SLA8; + case PIPE_FORMAT_L8_SRGB: + return MESA_FORMAT_SL8; + case PIPE_FORMAT_R8G8B8_SRGB: + return MESA_FORMAT_SRGB8; + case PIPE_FORMAT_A8B8G8R8_SRGB: + return MESA_FORMAT_SRGBA8; + case PIPE_FORMAT_B8G8R8A8_SRGB: + return MESA_FORMAT_SARGB8; +#endif + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return MESA_FORMAT_RGBA_FLOAT32; + case PIPE_FORMAT_R16G16B16A16_FLOAT: + return MESA_FORMAT_RGBA_FLOAT16; + case PIPE_FORMAT_R32G32B32_FLOAT: + return MESA_FORMAT_RGB_FLOAT32; + case PIPE_FORMAT_R16G16B16_FLOAT: + return MESA_FORMAT_RGB_FLOAT16; + case PIPE_FORMAT_L32A32_FLOAT: + return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; + case PIPE_FORMAT_L16A16_FLOAT: + return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; + case PIPE_FORMAT_L32_FLOAT: + return MESA_FORMAT_LUMINANCE_FLOAT32; + case PIPE_FORMAT_L16_FLOAT: + return MESA_FORMAT_LUMINANCE_FLOAT16; + case PIPE_FORMAT_A32_FLOAT: + return MESA_FORMAT_ALPHA_FLOAT32; + case PIPE_FORMAT_A16_FLOAT: + return MESA_FORMAT_ALPHA_FLOAT16; + case PIPE_FORMAT_I32_FLOAT: + return MESA_FORMAT_INTENSITY_FLOAT32; + case PIPE_FORMAT_I16_FLOAT: + return MESA_FORMAT_INTENSITY_FLOAT16; + case PIPE_FORMAT_R32_FLOAT: + return MESA_FORMAT_R_FLOAT32; + case PIPE_FORMAT_R16_FLOAT: + return MESA_FORMAT_R_FLOAT16; + case PIPE_FORMAT_R32G32_FLOAT: + return MESA_FORMAT_RG_FLOAT32; + case PIPE_FORMAT_R16G16_FLOAT: + return MESA_FORMAT_RG_FLOAT16; + + case PIPE_FORMAT_R8_UNORM: + return MESA_FORMAT_R8; + case PIPE_FORMAT_R16_UNORM: + return MESA_FORMAT_R16; + case PIPE_FORMAT_R8G8_UNORM: + return MESA_FORMAT_RG88; + case PIPE_FORMAT_R16G16_UNORM: + return MESA_FORMAT_RG1616; + + /* signed int formats */ + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return MESA_FORMAT_RGBA_INT8; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return MESA_FORMAT_RGBA_INT16; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return MESA_FORMAT_RGBA_INT32; + + /* unsigned int formats */ + case PIPE_FORMAT_R8G8B8A8_USCALED: + return MESA_FORMAT_RGBA_UINT8; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return MESA_FORMAT_RGBA_UINT16; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return MESA_FORMAT_RGBA_UINT32; + + case PIPE_FORMAT_RGTC1_UNORM: + return MESA_FORMAT_RED_RGTC1; + case PIPE_FORMAT_RGTC1_SNORM: + return MESA_FORMAT_SIGNED_RED_RGTC1; + case PIPE_FORMAT_RGTC2_UNORM: + return MESA_FORMAT_RG_RGTC2; + case PIPE_FORMAT_RGTC2_SNORM: + return MESA_FORMAT_SIGNED_RG_RGTC2; + + case PIPE_FORMAT_LATC1_UNORM: + return MESA_FORMAT_L_LATC1; + case PIPE_FORMAT_LATC1_SNORM: + return MESA_FORMAT_SIGNED_L_LATC1; + case PIPE_FORMAT_LATC2_UNORM: + return MESA_FORMAT_LA_LATC2; + case PIPE_FORMAT_LATC2_SNORM: + return MESA_FORMAT_SIGNED_LA_LATC2; + + /* signed normalized formats */ + case PIPE_FORMAT_R8_SNORM: + return MESA_FORMAT_SIGNED_R8; + case PIPE_FORMAT_R8G8_SNORM: + return MESA_FORMAT_SIGNED_RG88_REV; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return MESA_FORMAT_SIGNED_RGBA8888_REV; + + case PIPE_FORMAT_A8_SNORM: + return MESA_FORMAT_SIGNED_A8; + case PIPE_FORMAT_L8_SNORM: + return MESA_FORMAT_SIGNED_L8; + case PIPE_FORMAT_L8A8_SNORM: + return MESA_FORMAT_SIGNED_AL88; + case PIPE_FORMAT_I8_SNORM: + return MESA_FORMAT_SIGNED_I8; + + case PIPE_FORMAT_R16_SNORM: + return MESA_FORMAT_SIGNED_R16; + case PIPE_FORMAT_R16G16_SNORM: + return MESA_FORMAT_SIGNED_GR1616; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return MESA_FORMAT_SIGNED_RGBA_16; + + case PIPE_FORMAT_A16_SNORM: + return MESA_FORMAT_SIGNED_A16; + case PIPE_FORMAT_L16_SNORM: + return MESA_FORMAT_SIGNED_L16; + case PIPE_FORMAT_L16A16_SNORM: + return MESA_FORMAT_SIGNED_AL1616; + case PIPE_FORMAT_I16_SNORM: + return MESA_FORMAT_SIGNED_I16; + + case PIPE_FORMAT_R9G9B9E5_FLOAT: + return MESA_FORMAT_RGB9_E5_FLOAT; + case PIPE_FORMAT_R11G11B10_FLOAT: + return MESA_FORMAT_R11_G11_B10_FLOAT; + + default: + assert(0); + return MESA_FORMAT_NONE; + } +} + + +/** + * Map GL texture formats to Gallium pipe formats. + */ +struct format_mapping +{ + GLenum glFormats[18]; /**< list of GLenum formats, 0-terminated */ + enum pipe_format pipeFormats[10]; /**< list of pipe formats, 0-terminated */ +}; + + +#define DEFAULT_RGBA_FORMATS \ + PIPE_FORMAT_B8G8R8A8_UNORM, \ + PIPE_FORMAT_A8R8G8B8_UNORM, \ + PIPE_FORMAT_A8B8G8R8_UNORM, \ + PIPE_FORMAT_B5G6R5_UNORM, \ + 0 + +#define DEFAULT_RGB_FORMATS \ + PIPE_FORMAT_B8G8R8X8_UNORM, \ + PIPE_FORMAT_X8R8G8B8_UNORM, \ + PIPE_FORMAT_X8B8G8R8_UNORM, \ + PIPE_FORMAT_B8G8R8A8_UNORM, \ + PIPE_FORMAT_A8R8G8B8_UNORM, \ + PIPE_FORMAT_A8B8G8R8_UNORM, \ + PIPE_FORMAT_B5G6R5_UNORM, \ + 0 + +#define DEFAULT_SRGBA_FORMATS \ + PIPE_FORMAT_B8G8R8A8_SRGB, \ + PIPE_FORMAT_A8R8G8B8_SRGB, \ + PIPE_FORMAT_A8B8G8R8_SRGB, \ + 0 + +/** + * This table maps OpenGL texture format enums to Gallium pipe_format enums. + * Multiple GL enums might map to multiple pipe_formats. + * The first pipe format in the list that's supported is the one that's chosen. + */ +static struct format_mapping format_map[] = { + /* Basic RGB, RGBA formats */ + { + { GL_RGB10, GL_RGB10_A2, 0 }, + { PIPE_FORMAT_B10G10R10A2_UNORM, 0 } + }, + { + { 4, GL_RGBA, GL_RGBA8, 0 }, + { DEFAULT_RGBA_FORMATS, 0 } + }, + { + { GL_BGRA, 0 }, + { PIPE_FORMAT_B8G8R8A8_UNORM, DEFAULT_RGB_FORMATS, 0 } + }, + { + { 3, GL_RGB, GL_RGB8, 0 }, + { DEFAULT_RGB_FORMATS, 0 } + }, + { + { GL_RGB12, GL_RGB16, GL_RGBA12, GL_RGBA16, 0 }, + { PIPE_FORMAT_R16G16B16A16_UNORM, DEFAULT_RGB_FORMATS, 0 } + }, + { + { GL_RGBA4, GL_RGBA2, 0 }, + { PIPE_FORMAT_B4G4R4A4_UNORM, DEFAULT_RGBA_FORMATS } + }, + { + { GL_RGB5_A1, 0 }, + { PIPE_FORMAT_B5G5R5A1_UNORM, DEFAULT_RGBA_FORMATS, 0 } + }, + { + { GL_R3_G3_B2, 0 }, + { PIPE_FORMAT_B2G3R3_UNORM, PIPE_FORMAT_B5G6R5_UNORM, + PIPE_FORMAT_B5G5R5A1_UNORM, DEFAULT_RGBA_FORMATS } + }, + { + { GL_RGB5, GL_RGB4 }, + { PIPE_FORMAT_B5G6R5_UNORM, PIPE_FORMAT_B5G5R5A1_UNORM, + DEFAULT_RGBA_FORMATS } + }, + + /* basic Alpha formats */ + { + { GL_ALPHA12, GL_ALPHA16, 0 }, + { PIPE_FORMAT_A16_UNORM, PIPE_FORMAT_A8_UNORM, + DEFAULT_RGBA_FORMATS } + }, + { + { GL_ALPHA, GL_ALPHA4, GL_ALPHA8, GL_COMPRESSED_ALPHA, 0 }, + { PIPE_FORMAT_A8_UNORM, DEFAULT_RGBA_FORMATS } + }, + + /* basic Luminance formats */ + { + { GL_LUMINANCE12, GL_LUMINANCE16, 0 }, + { PIPE_FORMAT_L16_UNORM, PIPE_FORMAT_L8_UNORM, DEFAULT_RGBA_FORMATS, 0 } + }, + { + { 1, GL_LUMINANCE, GL_LUMINANCE4, GL_LUMINANCE8, 0 }, + { PIPE_FORMAT_L8_UNORM, DEFAULT_RGBA_FORMATS } + }, + + /* basic Luminance/Alpha formats */ + { + { GL_LUMINANCE12_ALPHA4, GL_LUMINANCE12_ALPHA12, + GL_LUMINANCE16_ALPHA16, 0}, + { PIPE_FORMAT_L16A16_UNORM, PIPE_FORMAT_L8A8_UNORM, + PIPE_FORMAT_L8A8_UNORM, DEFAULT_RGBA_FORMATS } + }, + { + { 2, GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2, GL_LUMINANCE8_ALPHA8, 0 }, + { PIPE_FORMAT_L8A8_UNORM, DEFAULT_RGBA_FORMATS } + }, + { + { GL_LUMINANCE4_ALPHA4, 0 }, + { PIPE_FORMAT_L4A4_UNORM, PIPE_FORMAT_L4A4_UNORM, + DEFAULT_RGBA_FORMATS } + }, + + /* basic Intensity formats */ + { + { GL_INTENSITY12, GL_INTENSITY16, 0 }, + { PIPE_FORMAT_I16_UNORM, PIPE_FORMAT_I8_UNORM, DEFAULT_RGBA_FORMATS } + }, + { + { GL_INTENSITY, GL_INTENSITY4, GL_INTENSITY8, + GL_COMPRESSED_INTENSITY, 0 }, + { PIPE_FORMAT_I8_UNORM, DEFAULT_RGBA_FORMATS } + }, + + /* YCbCr */ + { + { GL_YCBCR_MESA, 0 }, + { PIPE_FORMAT_UYVY, PIPE_FORMAT_YUYV, 0 } + }, + + /* compressed formats */ /* XXX PIPE_BIND_SAMPLER_VIEW only */ + { + { GL_COMPRESSED_RGB, 0 }, + { PIPE_FORMAT_DXT1_RGB, 0 } + }, + { + { GL_COMPRESSED_RGBA, 0 }, + { PIPE_FORMAT_DXT5_RGBA, 0 } + }, + { + { GL_RGB_S3TC, GL_RGB4_S3TC, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0 }, + { PIPE_FORMAT_DXT1_RGB, 0 } + }, + { + { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0 }, + { PIPE_FORMAT_DXT1_RGBA, 0 } + }, + { + { GL_RGBA_S3TC, GL_RGBA4_S3TC, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0 }, + { PIPE_FORMAT_DXT3_RGBA, 0 } + }, + { + { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0 }, + { PIPE_FORMAT_DXT5_RGBA, 0 } + }, + +#if 0 + { + { GL_COMPRESSED_RGB_FXT1_3DFX, 0 }, + { PIPE_FORMAT_RGB_FXT1, 0 } + }, + { + { GL_COMPRESSED_RGBA_FXT1_3DFX, 0 }, + { PIPE_FORMAT_RGB_FXT1, 0 } + }, +#endif + + /* Depth formats */ + { + { GL_DEPTH_COMPONENT16, 0 }, + { PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z24_UNORM_S8_USCALED, + PIPE_FORMAT_S8_USCALED_Z24_UNORM, PIPE_FORMAT_Z32_UNORM, 0 } + }, + { + { GL_DEPTH_COMPONENT24, 0 }, + { PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM, + PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM, + PIPE_FORMAT_Z32_UNORM, 0 } + }, + { + { GL_DEPTH_COMPONENT32, 0 }, + { PIPE_FORMAT_Z32_UNORM, 0 } + }, + { + { GL_DEPTH_COMPONENT, 0 }, + { PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM, + PIPE_FORMAT_Z32_UNORM, PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0 } + }, + + /* stencil formats */ + { + { GL_STENCIL_INDEX, GL_STENCIL_INDEX1_EXT, GL_STENCIL_INDEX4_EXT, + GL_STENCIL_INDEX8_EXT, GL_STENCIL_INDEX16_EXT, 0 }, + { + PIPE_FORMAT_S8_USCALED, PIPE_FORMAT_Z24_UNORM_S8_USCALED, + PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0 + } + }, + + /* Depth / Stencil formats */ + { + { GL_DEPTH_STENCIL_EXT, GL_DEPTH24_STENCIL8_EXT, 0 }, + { PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0 } + }, + + /* sRGB formats */ + { + { GL_SRGB_EXT, GL_SRGB8_EXT, GL_SRGB_ALPHA_EXT, GL_SRGB8_ALPHA8_EXT, 0 }, + { DEFAULT_SRGBA_FORMATS } + }, + { + { GL_COMPRESSED_SRGB_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 0 }, + { PIPE_FORMAT_DXT1_SRGB, DEFAULT_SRGBA_FORMATS } + }, + { + { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0 }, + { PIPE_FORMAT_DXT1_SRGBA, 0 } + }, + { + { GL_COMPRESSED_SRGB_ALPHA_EXT, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0 }, + { PIPE_FORMAT_DXT3_SRGBA, DEFAULT_SRGBA_FORMATS } + }, + { + { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0 }, + { PIPE_FORMAT_DXT5_SRGBA, 0 } + }, + { + { GL_SLUMINANCE_ALPHA_EXT, GL_SLUMINANCE8_ALPHA8_EXT, + GL_COMPRESSED_SLUMINANCE_EXT, GL_COMPRESSED_SLUMINANCE_ALPHA_EXT, 0 }, + { PIPE_FORMAT_L8A8_SRGB, DEFAULT_SRGBA_FORMATS } + }, + { + { GL_SLUMINANCE_EXT, GL_SLUMINANCE8_EXT, 0 }, + { PIPE_FORMAT_L8_SRGB, DEFAULT_SRGBA_FORMATS } + }, + + /* 16-bit float formats */ + { + { GL_RGBA16F_ARB, 0 }, + { PIPE_FORMAT_R16G16B16A16_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_RGB16F_ARB, 0 }, + { PIPE_FORMAT_R16G16B16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_LUMINANCE_ALPHA16F_ARB, 0 }, + { PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_ALPHA16F_ARB, 0 }, + { PIPE_FORMAT_A16_FLOAT, PIPE_FORMAT_L16A16_FLOAT, + PIPE_FORMAT_A32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_INTENSITY16F_ARB, 0 }, + { PIPE_FORMAT_I16_FLOAT, PIPE_FORMAT_L16A16_FLOAT, + PIPE_FORMAT_I32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_LUMINANCE16F_ARB, 0 }, + { PIPE_FORMAT_L16_FLOAT, PIPE_FORMAT_L16A16_FLOAT, + PIPE_FORMAT_L32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_R16F, 0 }, + { PIPE_FORMAT_R16_FLOAT, PIPE_FORMAT_R16G16_FLOAT, + PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + { + { GL_RG16F, 0 }, + { PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 } + }, + + /* 32-bit float formats */ + { + { GL_RGBA32F_ARB, 0 }, + { PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_RGB32F_ARB, 0 }, + { PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, + PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_LUMINANCE_ALPHA32F_ARB, 0 }, + { PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, + PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_ALPHA32F_ARB, 0 }, + { PIPE_FORMAT_A32_FLOAT, PIPE_FORMAT_L32A32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_A16_FLOAT, + PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_INTENSITY32F_ARB, 0 }, + { PIPE_FORMAT_I32_FLOAT, PIPE_FORMAT_L32A32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_I16_FLOAT, + PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_LUMINANCE32F_ARB, 0 }, + { PIPE_FORMAT_L32_FLOAT, PIPE_FORMAT_L32A32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_L16_FLOAT, + PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_R32F, 0 }, + { PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_R16_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + { + { GL_RG32F, 0 }, + { PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 } + }, + + /* R, RG formats */ + { + { GL_RED, GL_R8, 0 }, + { PIPE_FORMAT_R8_UNORM, 0 } + }, + { + { GL_RG, GL_RG8, 0 }, + { PIPE_FORMAT_R8G8_UNORM, 0 } + }, + { + { GL_R16, 0 }, + { PIPE_FORMAT_R16_UNORM, 0 } + }, + { + { GL_RG16, 0 }, + { PIPE_FORMAT_R16G16_UNORM, 0 } + }, + + /* compressed R, RG formats */ + { + { GL_COMPRESSED_RED, GL_COMPRESSED_RED_RGTC1, 0 }, + { PIPE_FORMAT_RGTC1_UNORM, PIPE_FORMAT_R8_UNORM, 0 } + }, + { + { GL_COMPRESSED_SIGNED_RED_RGTC1, 0 }, + { PIPE_FORMAT_RGTC1_SNORM, 0 } + }, + { + { GL_COMPRESSED_RG, GL_COMPRESSED_RG_RGTC2, 0 }, + { PIPE_FORMAT_RGTC2_UNORM, PIPE_FORMAT_R8G8_UNORM, 0 } + }, + { + { GL_COMPRESSED_SIGNED_RG_RGTC2, 0 }, + { PIPE_FORMAT_RGTC2_SNORM, 0 } + }, + { + { GL_COMPRESSED_LUMINANCE, GL_COMPRESSED_LUMINANCE_LATC1_EXT, 0 }, + { PIPE_FORMAT_LATC1_UNORM, PIPE_FORMAT_L8_UNORM, 0 } + }, + { + { GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT, 0 }, + { PIPE_FORMAT_LATC1_SNORM, 0 } + }, + { + { GL_COMPRESSED_LUMINANCE_ALPHA, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, + GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0 }, + { PIPE_FORMAT_LATC2_UNORM, PIPE_FORMAT_L8A8_UNORM, 0 } + }, + { + { GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT, 0 }, + { PIPE_FORMAT_LATC2_SNORM, 0 } + }, + + /* signed/unsigned integer formats. + * XXX Mesa only has formats for RGBA signed/unsigned integer formats. + * If/when new formats are added this code should be updated. + */ + { + { GL_RED_INTEGER_EXT, + GL_GREEN_INTEGER_EXT, + GL_BLUE_INTEGER_EXT, + GL_ALPHA_INTEGER_EXT, + GL_RGB_INTEGER_EXT, + GL_RGBA_INTEGER_EXT, + GL_BGR_INTEGER_EXT, + GL_BGRA_INTEGER_EXT, + GL_LUMINANCE_INTEGER_EXT, + GL_LUMINANCE_ALPHA_INTEGER_EXT, + GL_RGBA8I_EXT, + GL_RGB8I_EXT, + GL_ALPHA8I_EXT, + GL_INTENSITY8I_EXT, + GL_LUMINANCE8I_EXT, + GL_LUMINANCE_ALPHA8I_EXT, 0 }, + { PIPE_FORMAT_R8G8B8A8_SSCALED, 0 } + }, + { + { + GL_RGBA16I_EXT, + GL_RGB16I_EXT, + GL_ALPHA16I_EXT, + GL_INTENSITY16I_EXT, + GL_LUMINANCE16I_EXT, + GL_LUMINANCE_ALPHA16I_EXT, 0 }, + { PIPE_FORMAT_R16G16B16A16_SSCALED, 0 }, + }, + { + { + GL_RGBA32I_EXT, + GL_RGB32I_EXT, + GL_ALPHA32I_EXT, + GL_INTENSITY32I_EXT, + GL_LUMINANCE32I_EXT, + GL_LUMINANCE_ALPHA32I_EXT, 0 }, + { PIPE_FORMAT_R32G32B32A32_SSCALED, 0 } + }, + { + { + GL_RGBA8UI_EXT, + GL_RGB8UI_EXT, + GL_ALPHA8UI_EXT, + GL_INTENSITY8UI_EXT, + GL_LUMINANCE8UI_EXT, + GL_LUMINANCE_ALPHA8UI_EXT, 0 }, + { PIPE_FORMAT_R8G8B8A8_USCALED, 0 } + }, + { + { + GL_RGBA16UI_EXT, + GL_RGB16UI_EXT, + GL_ALPHA16UI_EXT, + GL_INTENSITY16UI_EXT, + GL_LUMINANCE16UI_EXT, + GL_LUMINANCE_ALPHA16UI_EXT, 0 }, + { PIPE_FORMAT_R16G16B16A16_USCALED, 0 } + }, + { + { + GL_RGBA32UI_EXT, + GL_RGB32UI_EXT, + GL_ALPHA32UI_EXT, + GL_INTENSITY32UI_EXT, + GL_LUMINANCE32UI_EXT, + GL_LUMINANCE_ALPHA32UI_EXT, 0 }, + { PIPE_FORMAT_R32G32B32A32_USCALED, 0 } + }, + + /* signed normalized formats */ + { + { GL_RED_SNORM, GL_R8_SNORM, 0 }, + { PIPE_FORMAT_R8_SNORM, PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_R16_SNORM, 0 }, + { PIPE_FORMAT_R16_SNORM, + PIPE_FORMAT_R16G16_SNORM, + PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_R8_SNORM, + PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_RG_SNORM, GL_RG8_SNORM, 0 }, + { PIPE_FORMAT_R8G8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_RG16_SNORM, 0 }, + { PIPE_FORMAT_R16G16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_R8G8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_RGB_SNORM, GL_RGB8_SNORM, GL_RGBA_SNORM, GL_RGBA8_SNORM, 0 }, + { PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_RGB16_SNORM, GL_RGBA16_SNORM, 0 }, + { PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_ALPHA_SNORM, GL_ALPHA8_SNORM, 0 }, + { PIPE_FORMAT_A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_ALPHA16_SNORM, 0 }, + { PIPE_FORMAT_A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_LUMINANCE_SNORM, GL_LUMINANCE8_SNORM, 0 }, + { PIPE_FORMAT_L8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_LUMINANCE16_SNORM, 0 }, + { PIPE_FORMAT_L16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_L8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_LUMINANCE_ALPHA_SNORM, GL_LUMINANCE8_ALPHA8_SNORM, 0 }, + { PIPE_FORMAT_L8A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_LUMINANCE16_ALPHA16_SNORM, 0 }, + { PIPE_FORMAT_L16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_L8A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_INTENSITY_SNORM, GL_INTENSITY8_SNORM, 0 }, + { PIPE_FORMAT_I8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + }, + { + { GL_INTENSITY16_SNORM, 0 }, + { PIPE_FORMAT_I16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_I8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 } + } +}; + + +/** + * Return first supported format from the given list. + */ +static enum pipe_format +find_supported_format(struct pipe_screen *screen, + const enum pipe_format formats[], + enum pipe_texture_target target, + unsigned sample_count, + unsigned tex_usage) +{ + uint i; + for (i = 0; formats[i]; i++) { + if (screen->is_format_supported(screen, formats[i], target, + sample_count, tex_usage)) { + return formats[i]; + } + } + return PIPE_FORMAT_NONE; +} + + +/** + * Given an OpenGL internalFormat value for a texture or surface, return + * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match. + * This is called during glTexImage2D, for example. + * + * The bindings parameter typically has PIPE_BIND_SAMPLER_VIEW set, plus + * either PIPE_BINDING_RENDER_TARGET or PIPE_BINDING_DEPTH_STENCIL if + * we want render-to-texture ability. + * + * \param internalFormat the user value passed to glTexImage2D + * \param target one of PIPE_TEXTURE_x + * \param bindings bitmask of PIPE_BIND_x flags. + */ +enum pipe_format +st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + enum pipe_texture_target target, unsigned sample_count, + unsigned bindings) +{ + GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */ + int i, j; + + /* can't render to compressed formats at this time */ + if (_mesa_is_compressed_format(ctx, internalFormat) + && (bindings & ~PIPE_BIND_SAMPLER_VIEW)) { + return PIPE_FORMAT_NONE; + } + + /* search table for internalFormat */ + for (i = 0; i < Elements(format_map); i++) { + const struct format_mapping *mapping = &format_map[i]; + for (j = 0; mapping->glFormats[j]; j++) { + if (mapping->glFormats[j] == internalFormat) { + /* Found the desired internal format. Find first pipe format + * which is supported by the driver. + */ + return find_supported_format(screen, mapping->pipeFormats, + target, sample_count, bindings); + } + } + } + + _mesa_problem(NULL, "unhandled format!\n"); + return PIPE_FORMAT_NONE; +} + + +/** + * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces. + */ +enum pipe_format +st_choose_renderbuffer_format(struct pipe_screen *screen, + GLenum internalFormat, unsigned sample_count) +{ + uint usage; + if (_mesa_is_depth_or_stencil_format(internalFormat)) + usage = PIPE_BIND_DEPTH_STENCIL; + else + usage = PIPE_BIND_RENDER_TARGET; + return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, + sample_count, usage); +} + + +/** + * Called via ctx->Driver.chooseTextureFormat(). + */ +gl_format +st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, + GLenum format, GLenum type, GLboolean renderable) +{ + struct pipe_screen *screen = st_context(ctx)->pipe->screen; + enum pipe_format pFormat; + uint bindings; + + (void) format; + (void) type; + + /* GL textures may wind up being render targets, but we don't know + * that in advance. Specify potential render target flags now. + */ + bindings = PIPE_BIND_SAMPLER_VIEW; + if (renderable == GL_TRUE) { + if (_mesa_is_depth_format(internalFormat) || + _mesa_is_depth_or_stencil_format(internalFormat)) + bindings |= PIPE_BIND_DEPTH_STENCIL; + else + bindings |= PIPE_BIND_RENDER_TARGET; + } + + pFormat = st_choose_format(screen, internalFormat, + PIPE_TEXTURE_2D, 0, bindings); + + if (pFormat == PIPE_FORMAT_NONE) { + /* try choosing format again, this time without render target bindings */ + pFormat = st_choose_format(screen, internalFormat, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); + } + + if (pFormat == PIPE_FORMAT_NONE) { + /* no luck at all */ + return MESA_FORMAT_NONE; + } + + return st_pipe_format_to_mesa_format(pFormat); +} + +gl_format +st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat, + GLenum format, GLenum type) +{ + boolean want_renderable = + internalFormat == 3 || internalFormat == 4 || + internalFormat == GL_RGB || internalFormat == GL_RGBA || + internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 || + internalFormat == GL_BGRA; + + return st_ChooseTextureFormat_renderable(ctx, internalFormat, + format, type, want_renderable); +} + +/** + * Test if a gallium format is equivalent to a GL format/type. + */ +GLboolean +st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type) +{ + switch (pFormat) { + case PIPE_FORMAT_A8B8G8R8_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_BYTE; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_BYTE; + case PIPE_FORMAT_B5G6R5_UNORM: + return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5; + /* XXX more combos... */ + default: + return GL_FALSE; + } +} + +GLboolean +st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2) +{ + if (format1 == format2) + return GL_TRUE; + + if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM && + format2 == PIPE_FORMAT_B8G8R8X8_UNORM) + return GL_TRUE; + + if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM && + format2 == PIPE_FORMAT_B8G8R8A8_UNORM) + return GL_TRUE; + + if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM && + format2 == PIPE_FORMAT_X8B8G8R8_UNORM) + return GL_TRUE; + + if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM && + format2 == PIPE_FORMAT_A8B8G8R8_UNORM) + return GL_TRUE; + + if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM && + format2 == PIPE_FORMAT_X8R8G8B8_UNORM) + return GL_TRUE; + + if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM && + format2 == PIPE_FORMAT_A8R8G8B8_UNORM) + return GL_TRUE; + + return GL_FALSE; +} + + + +/** + * This is used for translating texture border color and the clear + * color. For example, the clear color is interpreted according to + * the renderbuffer's base format. For example, if clearing a + * GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] = + * alpha. Similarly for texture border colors. + */ +void +st_translate_color(const GLfloat colorIn[4], GLenum baseFormat, + GLfloat colorOut[4]) +{ + switch (baseFormat) { + case GL_RED: + colorOut[0] = colorIn[0]; + colorOut[1] = 0.0F; + colorOut[2] = 0.0F; + colorOut[3] = 1.0F; + break; + case GL_RG: + colorOut[0] = colorIn[0]; + colorOut[1] = colorIn[1]; + colorOut[2] = 0.0F; + colorOut[3] = 1.0F; + break; + case GL_RGB: + colorOut[0] = colorIn[0]; + colorOut[1] = colorIn[1]; + colorOut[2] = colorIn[2]; + colorOut[3] = 1.0F; + break; + case GL_ALPHA: + colorOut[0] = colorOut[1] = colorOut[2] = 0.0; + colorOut[3] = colorIn[3]; + break; + case GL_LUMINANCE: + colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0]; + colorOut[3] = 1.0; + break; + case GL_LUMINANCE_ALPHA: + colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0]; + colorOut[3] = colorIn[3]; + break; + case GL_INTENSITY: + colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0]; + break; + default: + COPY_4V(colorOut, colorIn); + } +} |