diff options
Diffstat (limited to 'mesalib/src/mesa/main')
49 files changed, 3567 insertions, 5213 deletions
diff --git a/mesalib/src/mesa/main/.gitignore b/mesalib/src/mesa/main/.gitignore index b1b83f102..328aaf570 100644..100755 --- a/mesalib/src/mesa/main/.gitignore +++ b/mesalib/src/mesa/main/.gitignore @@ -8,4 +8,5 @@ git_sha1.h.tmp remap_helper.h
get_hash.h
get_hash.h.tmp
+format_info.c
glapitable.h
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 2a5ffc3e6..c29a8c777 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -31,6 +31,7 @@ */ #include <stdbool.h> +#include <inttypes.h> /* for PRId64 macro */ #include "glheader.h" #include "enums.h" #include "hash.h" @@ -832,6 +833,9 @@ _mesa_init_buffer_objects( struct gl_context *ctx ) _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, ctx->Shared->NullBufferObj); + _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, + ctx->Shared->NullBufferObj); + _mesa_reference_buffer_object(ctx, &ctx->DrawIndirectBuffer, ctx->Shared->NullBufferObj); @@ -842,6 +846,14 @@ _mesa_init_buffer_objects( struct gl_context *ctx ) ctx->UniformBufferBindings[i].Offset = -1; ctx->UniformBufferBindings[i].Size = -1; } + + for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) { + _mesa_reference_buffer_object(ctx, + &ctx->AtomicBufferBindings[i].BufferObject, + ctx->Shared->NullBufferObj); + ctx->AtomicBufferBindings[i].Offset = -1; + ctx->AtomicBufferBindings[i].Size = -1; + } } @@ -857,6 +869,8 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, NULL); + _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, NULL); + _mesa_reference_buffer_object(ctx, &ctx->DrawIndirectBuffer, NULL); for (i = 0; i < MAX_COMBINED_UNIFORM_BUFFERS; i++) { @@ -864,6 +878,13 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) &ctx->UniformBufferBindings[i].BufferObject, NULL); } + + for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) { + _mesa_reference_buffer_object(ctx, + &ctx->AtomicBufferBindings[i].BufferObject, + NULL); + } + } bool @@ -1200,6 +1221,17 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) _mesa_BindBuffer( GL_UNIFORM_BUFFER, 0 ); } + /* unbind Atomci Buffer binding points */ + for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) { + if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) { + _mesa_BindBufferBase( GL_ATOMIC_COUNTER_BUFFER, j, 0 ); + } + } + + if (ctx->UniformBuffer == bufObj) { + _mesa_BindBuffer( GL_ATOMIC_COUNTER_BUFFER, 0 ); + } + /* unbind any pixel pack/unpack pointers bound to this buffer */ if (ctx->Pack.BufferObj == bufObj) { _mesa_BindBuffer( GL_PIXEL_PACK_BUFFER_EXT, 0 ); @@ -2793,8 +2825,8 @@ bind_buffers_check_offset_and_size(struct gl_context *ctx, * value in <offsets> is less than zero (per binding)." */ _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBuffersRange(offsets[%u]=%lld < 0)", - index, (long long int) offsets[index]); + "glBindBuffersRange(offsets[%u]=%" PRId64 " < 0)", + index, (int64_t) offsets[index]); return false; } @@ -2805,8 +2837,8 @@ bind_buffers_check_offset_and_size(struct gl_context *ctx, * value in <sizes> is less than or equal to zero (per binding)." */ _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBuffersRange(sizes[%u]=%lld <= 0)", - index, (long long int) sizes[index]); + "glBindBuffersRange(sizes[%u]=%" PRId64 " <= 0)", + index, (int64_t) sizes[index]); return false; } @@ -3001,11 +3033,11 @@ bind_uniform_buffers_range(struct gl_context *ctx, GLuint first, GLsizei count, */ if (offsets[i] & (ctx->Const.UniformBufferOffsetAlignment - 1)) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBuffersRange(offsets[%u]=%lld is misaligned; " - "it must be a multiple of the value of " + "glBindBuffersRange(offsets[%u]=%" PRId64 + " is misaligned; it must be a multiple of the value of " "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT=%u when " "target=GL_UNIFORM_BUFFER)", - i, (long long int) offsets[i], + i, (int64_t) offsets[i], ctx->Const.UniformBufferOffsetAlignment); continue; } @@ -3239,19 +3271,19 @@ bind_xfb_buffers_range(struct gl_context *ctx, */ if (offsets[i] & 0x3) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBuffersRange(offsets[%u]=%lld is misaligned; " - "it must be a multiple of 4 when " + "glBindBuffersRange(offsets[%u]=%" PRId64 + " is misaligned; it must be a multiple of 4 when " "target=GL_TRANSFORM_FEEDBACK_BUFFER)", - i, (long long int) offsets[i]); + i, (int64_t) offsets[i]); continue; } if (sizes[i] & 0x3) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBuffersRange(sizes[%u]=%lld is misaligned; " - "it must be a multiple of 4 when " + "glBindBuffersRange(sizes[%u]=%" PRId64 + " is misaligned; it must be a multiple of 4 when " "target=GL_TRANSFORM_FEEDBACK_BUFFER)", - i, (long long int) sizes[i]); + i, (int64_t) sizes[i]); continue; } @@ -3457,10 +3489,10 @@ bind_atomic_buffers_range(struct gl_context *ctx, */ if (offsets[i] & (ATOMIC_COUNTER_SIZE - 1)) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBuffersRange(offsets[%u]=%lld is misaligned; " - "it must be a multiple of %d when " + "glBindBuffersRange(offsets[%u]=%" PRId64 + " is misaligned; it must be a multiple of %d when " "target=GL_ATOMIC_COUNTER_BUFFER)", - i, (long long int) offsets[i], ATOMIC_COUNTER_SIZE); + i, (int64_t) offsets[i], ATOMIC_COUNTER_SIZE); continue; } diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c index b13a7af65..140cf6e82 100644 --- a/mesalib/src/mesa/main/buffers.c +++ b/mesalib/src/mesa/main/buffers.c @@ -494,10 +494,11 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, } /* - * If n==1, destMask[0] may have up to four bits set. + * destMask[0] may have up to four bits set + * (ex: glDrawBuffer(GL_FRONT_AND_BACK)). * Otherwise, destMask[x] can only have one bit set. */ - if (n == 1) { + if (_mesa_bitcount(destMask[0]) > 1) { GLuint count = 0, destMask0 = destMask[0]; while (destMask0) { GLint bufIndex = ffs(destMask0) - 1; @@ -566,16 +567,11 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers, void _mesa_update_draw_buffers(struct gl_context *ctx) { - GLenum buffers[MAX_DRAW_BUFFERS]; - GLuint i; - /* should be a window system FBO */ assert(_mesa_is_winsys_fbo(ctx->DrawBuffer)); - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) - buffers[i] = ctx->Color.DrawBuffer[i]; - - _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL); + _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, + ctx->Color.DrawBuffer, NULL); } diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 79d8740e5..35160223e 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -44,6 +44,8 @@ #include <float.h> #include <stdarg.h> +#include "util/macros.h" + #include "c99_compat.h" /* inline, __func__, etc. */ @@ -130,23 +132,6 @@ extern "C" { #endif -/** - * __builtin_expect macros - */ -#if !defined(__GNUC__) -# define __builtin_expect(x, y) (x) -#endif - -#ifndef likely -# ifdef __GNUC__ -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -# else -# define likely(x) (x) -# define unlikely(x) (x) -# endif -#endif - /* XXX: Use standard `__func__` instead */ #ifndef __FUNCTION__ # define __FUNCTION__ __func__ @@ -238,65 +223,16 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) #endif -/** - * Static (compile-time) assertion. - * Basically, use COND to dimension an array. If COND is false/zero the - * array size will be -1 and we'll get a compilation error. - */ -#define STATIC_ASSERT(COND) \ - do { \ - (void) sizeof(char [1 - 2*!(COND)]); \ - } while (0) - -/** - * Unreachable macro. Useful for suppressing "control reaches end of non-void - * function" warnings. - */ -#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 5 -#define unreachable(str) \ -do { \ - assert(!str); \ - __builtin_unreachable(); \ -} while (0) -#elif (defined(__clang__) && defined(__has_builtin)) -# if __has_builtin(__builtin_unreachable) -# define unreachable(str) \ -do { \ - assert(!str); \ - __builtin_unreachable(); \ -} while (0) -# endif -#endif - -#ifndef unreachable -#define unreachable(str) -#endif - /* * A trick to suppress uninitialized variable warning without generating any * code */ #define uninitialized_var(x) x = x -#if (__GNUC__ >= 3) -#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a))) -#else -#define PRINTFLIKE(f, a) -#endif - #ifndef NULL #define NULL 0 #endif -/* Used to optionally mark structures with misaligned elements or size as - * packed, to trade off performance for space. - */ -#if (__GNUC__ >= 3) -#define PACKED __attribute__((__packed__)) -#else -#define PACKED -#endif - /** * LONGSTRING macro @@ -329,25 +265,7 @@ do { \ #define FLT_MAX_EXP 128 #endif - -/** - * USE_IEEE: Determine if we're using IEEE floating point - */ -#if defined(__i386__) || defined(__386__) || defined(__sparc__) || \ - defined(__s390__) || defined(__s390x__) || defined(__powerpc__) || \ - defined(__x86_64__) || \ - defined(__m68k__) || \ - defined(ia64) || defined(__ia64__) || \ - defined(__hppa__) || defined(hpux) || \ - defined(__mips) || defined(_MIPS_ARCH) || \ - defined(__arm__) || defined(__aarch64__) || \ - defined(__sh__) || defined(__m32r__) || \ - (defined(__sun) && defined(_IEEE_754)) || \ - defined(__alpha__) -#define USE_IEEE #define IEEE_ONE 0x3f800000 -#endif - /** * START/END_FAST_MATH macros: @@ -433,30 +351,6 @@ do { \ #endif #ifdef __cplusplus -/** - * Macro function that evaluates to true if T is a trivially - * destructible type -- that is, if its (non-virtual) destructor - * performs no action and all member variables and base classes are - * trivially destructible themselves. - */ -# if defined(__GNUC__) -# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) -# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) -# endif -# elif (defined(__clang__) && defined(__has_feature)) -# if __has_feature(has_trivial_destructor) -# define HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) -# endif -# endif -# ifndef HAS_TRIVIAL_DESTRUCTOR - /* It's always safe (if inefficient) to assume that a - * destructor is non-trivial. - */ -# define HAS_TRIVIAL_DESTRUCTOR(T) (false) -# endif -#endif - -#ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/copyimage.c b/mesalib/src/mesa/main/copyimage.c new file mode 100644 index 000000000..dcbc83de6 --- /dev/null +++ b/mesalib/src/mesa/main/copyimage.c @@ -0,0 +1,356 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2014 Intel Corporation. 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, 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Jason Ekstrand <jason.ekstrand@intel.com> + */ + +#include "glheader.h" +#include "errors.h" +#include "enums.h" +#include "copyimage.h" +#include "teximage.h" +#include "texobj.h" +#include "fbobject.h" +#include "textureview.h" + +static bool +prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level, + struct gl_texture_object **tex_obj, + struct gl_texture_image **tex_image, GLuint *tmp_tex, + const char *dbg_prefix) +{ + struct gl_renderbuffer *rb; + + if (name == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sName = %d)", dbg_prefix, name); + return false; + } + + /* + * INVALID_ENUM is generated + * * if either <srcTarget> or <dstTarget> + * - is not RENDERBUFFER or a valid non-proxy texture target + * - is TEXTURE_BUFFER, or + * - is one of the cubemap face selectors described in table 3.17, + */ + switch (*target) { + case GL_RENDERBUFFER: + /* Not a texture target, but valid */ + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_RECTANGLE: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + /* These are all valid */ + break; + case GL_TEXTURE_EXTERNAL_OES: + /* Only exists in ES */ + case GL_TEXTURE_BUFFER: + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glCopyImageSubData(%sTarget = %s)", dbg_prefix, + _mesa_lookup_enum_by_nr(*target)); + return false; + } + + if (*target == GL_RENDERBUFFER) { + rb = _mesa_lookup_renderbuffer(ctx, name); + if (!rb) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sName = %u)", dbg_prefix, name); + return false; + } + + if (!rb->Name) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyImageSubData(%sName incomplete)", dbg_prefix); + return false; + } + + if (level != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level); + return false; + } + + if (rb->NumSamples > 1) + *target = GL_TEXTURE_2D_MULTISAMPLE; + else + *target = GL_TEXTURE_2D; + + *tmp_tex = 0; + _mesa_GenTextures(1, tmp_tex); + if (*tmp_tex == 0) + return false; /* Error already set by GenTextures */ + + _mesa_BindTexture(*target, *tmp_tex); + *tex_obj = _mesa_lookup_texture(ctx, *tmp_tex); + *tex_image = _mesa_get_tex_image(ctx, *tex_obj, *target, 0); + + if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, *tex_image)) { + _mesa_problem(ctx, "Failed to create texture from renderbuffer"); + return false; + } + + if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) { + rb->NeedsFinishRenderTexture = true; + ctx->Driver.FinishRenderTexture(ctx, rb); + } + } else { + *tex_obj = _mesa_lookup_texture(ctx, name); + if (!*tex_obj) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sName = %u)", dbg_prefix, name); + return false; + } + + _mesa_test_texobj_completeness(ctx, *tex_obj); + if (!(*tex_obj)->_BaseComplete || + (level != 0 && !(*tex_obj)->_MipmapComplete)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyImageSubData(%sName incomplete)", dbg_prefix); + return false; + } + + if ((*tex_obj)->Target != *target) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glCopyImageSubData(%sTarget = %s)", dbg_prefix, + _mesa_lookup_enum_by_nr(*target)); + return false; + } + + if (level < 0 || level >= MAX_TEXTURE_LEVELS) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sLevel = %d)", dbg_prefix, level); + return false; + } + + *tex_image = _mesa_select_tex_image(ctx, *tex_obj, *target, level); + if (!*tex_image) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level); + return false; + } + } + + return true; +} + +static bool +check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image, + int x, int y, int z, int width, int height, int depth, + const char *dbg_prefix) +{ + if (width < 0 || height < 0 || depth < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sWidth, %sHeight, or %sDepth is negative)", + dbg_prefix, dbg_prefix, dbg_prefix); + return false; + } + + if (x < 0 || y < 0 || z < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sX, %sY, or %sZ is negative)", + dbg_prefix, dbg_prefix, dbg_prefix); + return false; + } + + if (x + width > tex_image->Width) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sX or %sWidth exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + + switch (tex_image->TexObject->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + if (y != 0 || height != 1) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sY or %sHeight exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + break; + default: + if (y + height > tex_image->Height) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sY or %sHeight exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + break; + } + + switch (tex_image->TexObject->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_RECTANGLE: + if (z != 0 || depth != 1) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + break; + case GL_TEXTURE_CUBE_MAP: + if (z < 0 || z + depth > 6) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + break; + case GL_TEXTURE_1D_ARRAY: + if (z < 0 || z + depth > tex_image->Height) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + break; + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case GL_TEXTURE_3D: + if (z < 0 || z + depth > tex_image->Depth) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)", + dbg_prefix, dbg_prefix); + return false; + } + break; + } + + return true; +} + +void GLAPIENTRY +_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, + GLuint dstName, GLenum dstTarget, GLint dstLevel, + GLint dstX, GLint dstY, GLint dstZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint tmpTexNames[2] = { 0, 0 }; + struct gl_texture_object *srcTexObj, *dstTexObj; + struct gl_texture_image *srcTexImage, *dstTexImage; + GLuint src_bw, src_bh, dst_bw, dst_bh; + int i, srcNewZ, dstNewZ, Bpt; + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, " + "%u, %s, %d, %d, %d, %d, " + "%d, %d, %d)\n", + srcName, _mesa_lookup_enum_by_nr(srcTarget), srcLevel, + srcX, srcY, srcZ, + dstName, _mesa_lookup_enum_by_nr(dstTarget), dstLevel, + dstX, dstY, dstZ, + srcWidth, srcHeight, srcWidth); + + if (!prepare_target(ctx, srcName, &srcTarget, srcLevel, + &srcTexObj, &srcTexImage, &tmpTexNames[0], "src")) + goto cleanup; + + if (!prepare_target(ctx, dstName, &dstTarget, dstLevel, + &dstTexObj, &dstTexImage, &tmpTexNames[1], "dst")) + goto cleanup; + + _mesa_get_format_block_size(srcTexImage->TexFormat, &src_bw, &src_bh); + if ((srcX % src_bw != 0) || (srcY % src_bh != 0) || + (srcWidth % src_bw != 0) || (srcHeight % src_bh != 0)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(unaligned src rectangle)"); + goto cleanup; + } + + _mesa_get_format_block_size(dstTexImage->TexFormat, &dst_bw, &dst_bh); + if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(unaligned dst rectangle)"); + goto cleanup; + } + + /* Very simple sanity check. This is sufficient if one of the textures + * is compressed. */ + Bpt = _mesa_get_format_bytes(srcTexImage->TexFormat); + if (_mesa_get_format_bytes(dstTexImage->TexFormat) != Bpt) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(internalFormat mismatch)"); + goto cleanup; + } + + if (!check_region_bounds(ctx, srcTexImage, srcX, srcY, srcZ, + srcWidth, srcHeight, srcDepth, "src")) + goto cleanup; + + if (!check_region_bounds(ctx, dstTexImage, dstX, dstY, dstZ, + (srcWidth / src_bw) * dst_bw, + (srcHeight / src_bh) * dst_bh, srcDepth, "dst")) + goto cleanup; + + if (_mesa_is_format_compressed(srcTexImage->TexFormat)) { + /* XXX: Technically, we should probaby do some more specific checking + * here. However, this should be sufficient for all compressed + * formats that mesa supports since it is a direct memory copy. + */ + } else if (_mesa_is_format_compressed(dstTexImage->TexFormat)) { + } else if (_mesa_texture_view_compatible_format(ctx, + srcTexImage->InternalFormat, + dstTexImage->InternalFormat)) { + } else { + return; /* Error loged by _mesa_texture_view_compatible_format */ + } + + for (i = 0; i < srcDepth; ++i) { + if (srcTexObj->Target == GL_TEXTURE_CUBE_MAP) { + srcTexImage = srcTexObj->Image[i + srcZ][srcLevel]; + srcNewZ = 0; + } else { + srcNewZ = srcZ + i; + } + + if (dstTexObj->Target == GL_TEXTURE_CUBE_MAP) { + dstTexImage = dstTexObj->Image[i + dstZ][dstLevel]; + dstNewZ = 0; + } else { + dstNewZ = dstZ + i; + } + + ctx->Driver.CopyImageSubData(ctx, srcTexImage, srcX, srcY, srcNewZ, + dstTexImage, dstX, dstY, dstNewZ, + srcWidth, srcHeight); + } + +cleanup: + _mesa_DeleteTextures(2, tmpTexNames); +} diff --git a/mesalib/src/mesa/main/copyimage.h b/mesalib/src/mesa/main/copyimage.h new file mode 100644 index 000000000..40e95b663 --- /dev/null +++ b/mesalib/src/mesa/main/copyimage.h @@ -0,0 +1,49 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2014 Intel Corporation. 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, 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Authors: + * Jason Ekstrand <jason.ekstrand@intel.com> + */ + + +#ifndef COPYIMAGE_H +#define COPYIMAGE_H + +#include "mtypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void GLAPIENTRY +_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, + GLuint destName, GLenum destTarget, GLint destLevel, + GLint destX, GLint destY, GLint destZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + +#ifdef __cplusplus +} +#endif + +#endif /* COPYIMAGE_H */ diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 89765351e..c130b14a5 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -269,6 +269,22 @@ struct dd_function_table { GLsizei width, GLsizei height); /** + * Called by glCopyImageSubData(). + * + * This function should copy one 2-D slice from srcTexImage to + * dstTexImage. If one of the textures is 3-D or is a 1-D or 2-D array + * texture, this function will be called multiple times: once for each + * slice. If one of the textures is a cube map, this function will be + * called once for each face to be copied. + */ + void (*CopyImageSubData)(struct gl_context *ctx, + struct gl_texture_image *src_image, + int src_x, int src_y, int src_z, + struct gl_texture_image *dstTexImage, + int dst_x, int dst_y, int dst_z, + int src_width, int src_height); + + /** * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled. * Note that if the texture is a cube map, the <target> parameter will * indicate which cube face to generate (GL_POSITIVE/NEGATIVE_X/Y/Z). diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c index 0f3bcf0a9..417548a3c 100644 --- a/mesalib/src/mesa/main/enable.c +++ b/mesalib/src/mesa/main/enable.c @@ -313,7 +313,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) } } break; - case GL_CLIP_DISTANCE0: + case GL_CLIP_DISTANCE0: /* aka GL_CLIP_PLANE0 */ case GL_CLIP_DISTANCE1: case GL_CLIP_DISTANCE2: case GL_CLIP_DISTANCE3: @@ -1202,7 +1202,7 @@ _mesa_IsEnabled( GLenum cap ) return ctx->Eval.AutoNormal; case GL_BLEND: return ctx->Color.BlendEnabled & 1; /* return state for buffer[0] */ - case GL_CLIP_DISTANCE0: + case GL_CLIP_DISTANCE0: /* aka GL_CLIP_PLANE0 */ case GL_CLIP_DISTANCE1: case GL_CLIP_DISTANCE2: case GL_CLIP_DISTANCE3: diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index aa0ff50ac..9cde1e020 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -36,7 +36,7 @@ #include "hash.h" #include "mtypes.h" #include "version.h" -#include "hash_table.h" +#include "util/hash_table.h" static mtx_t DynamicIDMutex = _MTX_INITIALIZER_NP; static GLuint NextDynamicID = 1; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 9ac8377a4..d60838a1c 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -95,6 +95,7 @@ static const struct extension extension_table[] = { { "GL_ARB_compressed_texture_pixel_storage", o(dummy_true), GL, 2011 }, { "GL_ARB_compute_shader", o(ARB_compute_shader), GL, 2012 }, { "GL_ARB_copy_buffer", o(dummy_true), GL, 2008 }, + { "GL_ARB_copy_image", o(ARB_copy_image), GL, 2012 }, { "GL_ARB_conservative_depth", o(ARB_conservative_depth), GL, 2011 }, { "GL_ARB_debug_output", o(dummy_true), GL, 2009 }, { "GL_ARB_depth_buffer_float", o(ARB_depth_buffer_float), GL, 2008 }, diff --git a/mesalib/src/mesa/main/format_info.py b/mesalib/src/mesa/main/format_info.py new file mode 100644 index 000000000..448bd0055 --- /dev/null +++ b/mesalib/src/mesa/main/format_info.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python +# +# Copyright 2014 Intel Corporation +# +# 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 VMWARE 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. + +import format_parser as parser +import sys + +def get_gl_base_format(fmat): + if fmat.name == 'MESA_FORMAT_NONE': + return 'GL_NONE' + elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV']: + return 'GL_YCBCR_MESA' + elif fmat.has_channel('r'): + if fmat.has_channel('g'): + if fmat.has_channel('b'): + if fmat.has_channel('a'): + return 'GL_RGBA' + else: + return 'GL_RGB' + else: + return 'GL_RG' + else: + return 'GL_RED' + elif fmat.has_channel('l'): + if fmat.has_channel('a'): + return 'GL_LUMINANCE_ALPHA' + else: + return 'GL_LUMINANCE' + elif fmat.has_channel('a') and fmat.num_channels() == 1: + return 'GL_ALPHA' + elif fmat.has_channel('z'): + if fmat.has_channel('s'): + return 'GL_DEPTH_STENCIL' + else: + return 'GL_DEPTH_COMPONENT' + elif fmat.has_channel('s'): + return 'GL_STENCIL_INDEX' + elif fmat.has_channel('i') and fmat.num_channels() == 1: + return 'GL_INTENSITY' + else: + assert False + +def get_gl_data_type(fmat): + if fmat.is_compressed(): + if 'SIGNED' in fmat.name or 'SNORM' in fmat.name: + return 'GL_SIGNED_NORMALIZED' + else: + return 'GL_UNSIGNED_NORMALIZED' + elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV']: + return 'GL_UNSIGNED_NORMALIZED' + + channel = None + for chan in fmat.channels: + if chan.type == 'x' and len(fmat.channels) > 1: + continue # We can do better + elif chan.name == 's' and fmat.has_channel('z'): + continue # We'll use the type from the depth instead + + channel = chan + break; + + if channel.type == parser.UNSIGNED: + if channel.norm: + return 'GL_UNSIGNED_NORMALIZED' + else: + return 'GL_UNSIGNED_INT' + elif channel.type == parser.SIGNED: + if channel.norm: + return 'GL_SIGNED_NORMALIZED' + else: + return 'GL_INT' + elif channel.type == parser.FLOAT: + return 'GL_FLOAT' + elif channel.type == parser.VOID: + return 'GL_NONE' + else: + assert False + +def get_mesa_layout(fmat): + if fmat.layout == 'array': + return 'MESA_FORMAT_LAYOUT_ARRAY' + elif fmat.layout == 'packed': + return 'MESA_FORMAT_LAYOUT_PACKED' + else: + return 'MESA_FORMAT_LAYOUT_OTHER' + +def get_channel_bits(fmat, chan_name): + if fmat.is_compressed(): + # These values are pretty-much bogus, but OpenGL requires that we + # return an "approximate" number of bits. + if fmat.layout == 's3tc': + return 4 if fmat.has_channel(chan_name) else 0 + elif fmat.layout == 'fxt1': + if chan_name in 'rgb': + return 4 + elif chan_name == 'a': + return 1 if fmat.has_channel('a') else 0 + else: + return 0 + elif fmat.layout == 'rgtc': + return 8 if fmat.has_channel(chan_name) else 0 + elif fmat.layout in ('etc1', 'etc2'): + if fmat.name.endswith('_ALPHA1') and chan_name == 'a': + return 1 + + bits = 11 if fmat.name.endswith('11_EAC') else 8 + return bits if fmat.has_channel(chan_name) else 0 + else: + assert False + else: + # Uncompressed textures + for chan in fmat.channels: + if chan.name == chan_name: + return chan.size + return 0 + +formats = parser.parse(sys.argv[1]) + +print ''' +/* + * Mesa 3-D graphics library + * + * Copyright (c) 2014 Intel Corporation + * + * 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + + /* + * This file is AUTOGENERATED by format_info.py. Do not edit it + * manually or commit it into version control. + */ + +static struct gl_format_info format_info[MESA_FORMAT_COUNT] = +{ +''' + +for fmat in formats: + print ' {' + print ' {0},'.format(fmat.name) + print ' "{0}",'.format(fmat.name) + print ' {0},'.format(get_mesa_layout(fmat)) + print ' {0},'.format(get_gl_base_format(fmat)) + print ' {0},'.format(get_gl_data_type(fmat)) + + bits = [ get_channel_bits(fmat, name) for name in ['r', 'g', 'b', 'a']] + print ' {0},'.format(', '.join(map(str, bits))) + bits = [ get_channel_bits(fmat, name) for name in ['l', 'i', 'z', 's']] + print ' {0},'.format(', '.join(map(str, bits))) + + print ' {0}, {1}, {2},'.format(fmat.block_width, fmat.block_height, + int(fmat.block_size() / 8)) + + print ' {{ {0} }},'.format(', '.join(map(str, fmat.swizzle))) + print ' },' + +print '};' diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c index c97c05297..6cbf8593b 100644 --- a/mesalib/src/mesa/main/format_pack.c +++ b/mesalib/src/mesa/main/format_pack.c @@ -41,6 +41,7 @@ #include "macros.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "util/format_srgb.h" /** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ @@ -58,39 +59,6 @@ typedef void (*pack_float_rgba_row_func)(GLuint n, const GLfloat src[][4], void *dst); - -static inline GLfloat -linear_to_srgb(GLfloat cl) -{ - if (cl < 0.0f) - return 0.0f; - else if (cl < 0.0031308f) - return 12.92f * cl; - else if (cl < 1.0f) - return 1.055f * powf(cl, 0.41666f) - 0.055f; - else - return 1.0f; -} - - -static inline GLubyte -linear_float_to_srgb_ubyte(GLfloat cl) -{ - GLubyte res = FLOAT_TO_UBYTE(linear_to_srgb(cl)); - return res; -} - - -static inline GLubyte -linear_ubyte_to_srgb_ubyte(GLubyte cl) -{ - GLubyte res = FLOAT_TO_UBYTE(linear_to_srgb(cl / 255.0f)); - return res; -} - - - - /* * MESA_FORMAT_A8B8G8R8_UNORM */ @@ -1043,18 +1011,18 @@ static void pack_ubyte_BGR_SRGB8(const GLubyte src[4], void *dst) { GLubyte *d = ((GLubyte *) dst); - d[2] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - d[1] = linear_ubyte_to_srgb_ubyte(src[GCOMP]); - d[0] = linear_ubyte_to_srgb_ubyte(src[BCOMP]); + d[2] = util_format_linear_to_srgb_8unorm(src[RCOMP]); + d[1] = util_format_linear_to_srgb_8unorm(src[GCOMP]); + d[0] = util_format_linear_to_srgb_8unorm(src[BCOMP]); } static void pack_float_BGR_SRGB8(const GLfloat src[4], void *dst) { GLubyte *d = ((GLubyte *) dst); - d[2] = linear_float_to_srgb_ubyte(src[RCOMP]); - d[1] = linear_float_to_srgb_ubyte(src[GCOMP]); - d[0] = linear_float_to_srgb_ubyte(src[BCOMP]); + d[2] = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); + d[1] = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); + d[0] = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); } @@ -1064,9 +1032,9 @@ static void pack_ubyte_A8B8G8R8_SRGB(const GLubyte src[4], void *dst) { GLuint *d = ((GLuint *) dst); - GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]); - GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]); + GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); + GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); + GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); *d = PACK_COLOR_8888(r, g, b, src[ACOMP]); } @@ -1075,9 +1043,9 @@ pack_float_A8B8G8R8_SRGB(const GLfloat src[4], void *dst) { GLuint *d = ((GLuint *) dst); GLubyte r, g, b, a; - r = linear_float_to_srgb_ubyte(src[RCOMP]); - g = linear_float_to_srgb_ubyte(src[GCOMP]); - b = linear_float_to_srgb_ubyte(src[BCOMP]); + r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); + g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); + b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); *d = PACK_COLOR_8888(r, g, b, a); } @@ -1089,9 +1057,9 @@ static void pack_ubyte_B8G8R8A8_SRGB(const GLubyte src[4], void *dst) { GLuint *d = ((GLuint *) dst); - GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]); - GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]); + GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); + GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); + GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); *d = PACK_COLOR_8888(src[ACOMP], r, g, b); } @@ -1100,9 +1068,9 @@ pack_float_B8G8R8A8_SRGB(const GLfloat src[4], void *dst) { GLuint *d = ((GLuint *) dst); GLubyte r, g, b, a; - r = linear_float_to_srgb_ubyte(src[RCOMP]); - g = linear_float_to_srgb_ubyte(src[GCOMP]); - b = linear_float_to_srgb_ubyte(src[BCOMP]); + r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); + g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); + b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); *d = PACK_COLOR_8888(a, r, g, b); } @@ -1114,9 +1082,9 @@ static void pack_ubyte_R8G8B8A8_SRGB(const GLubyte src[4], void *dst) { GLuint *d = ((GLuint *) dst); - GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); - GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]); - GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]); + GLubyte r = util_format_linear_to_srgb_8unorm(src[RCOMP]); + GLubyte g = util_format_linear_to_srgb_8unorm(src[GCOMP]); + GLubyte b = util_format_linear_to_srgb_8unorm(src[BCOMP]); *d = PACK_COLOR_8888(src[ACOMP], b, g, r); } @@ -1125,9 +1093,9 @@ pack_float_R8G8B8A8_SRGB(const GLfloat src[4], void *dst) { GLuint *d = ((GLuint *) dst); GLubyte r, g, b, a; - r = linear_float_to_srgb_ubyte(src[RCOMP]); - g = linear_float_to_srgb_ubyte(src[GCOMP]); - b = linear_float_to_srgb_ubyte(src[BCOMP]); + r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); + g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); + b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); *d = PACK_COLOR_8888(a, b, g, r); } @@ -1139,14 +1107,14 @@ static void pack_ubyte_L_SRGB8(const GLubyte src[4], void *dst) { GLubyte *d = ((GLubyte *) dst); - *d = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + *d = util_format_linear_to_srgb_8unorm(src[RCOMP]); } static void pack_float_L_SRGB8(const GLfloat src[4], void *dst) { GLubyte *d = ((GLubyte *) dst); - GLubyte l = linear_float_to_srgb_ubyte(src[RCOMP]); + GLubyte l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); *d = l; } @@ -1157,7 +1125,7 @@ static void pack_ubyte_L8A8_SRGB(const GLubyte src[4], void *dst) { GLushort *d = ((GLushort *) dst); - GLubyte l = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + GLubyte l = util_format_linear_to_srgb_8unorm(src[RCOMP]); *d = PACK_COLOR_88(src[ACOMP], l); } @@ -1165,7 +1133,7 @@ static void pack_float_L8A8_SRGB(const GLfloat src[4], void *dst) { GLushort *d = ((GLushort *) dst); - GLubyte a, l = linear_float_to_srgb_ubyte(src[RCOMP]); + GLubyte a, l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); CLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); *d = PACK_COLOR_88(a, l); } @@ -1742,9 +1710,9 @@ static void pack_float_R8G8B8X8_SRGB(const GLfloat src[4], void *dst) { GLuint *d = (GLuint *) dst; - GLubyte r = linear_float_to_srgb_ubyte(src[RCOMP]); - GLubyte g = linear_float_to_srgb_ubyte(src[GCOMP]); - GLubyte b = linear_float_to_srgb_ubyte(src[BCOMP]); + GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); + GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); + GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); *d = PACK_COLOR_8888(127, b, g, r); } @@ -1892,9 +1860,9 @@ static void pack_float_B8G8R8X8_SRGB(const GLfloat src[4], void *dst) { GLuint *d = (GLuint *) dst; - GLubyte r = linear_float_to_srgb_ubyte(src[RCOMP]); - GLubyte g = linear_float_to_srgb_ubyte(src[GCOMP]); - GLubyte b = linear_float_to_srgb_ubyte(src[BCOMP]); + GLubyte r = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); + GLubyte g = util_format_linear_float_to_srgb_8unorm(src[GCOMP]); + GLubyte b = util_format_linear_float_to_srgb_8unorm(src[BCOMP]); *d = PACK_COLOR_8888(127, r, g, b); } diff --git a/mesalib/src/mesa/main/format_parser.py b/mesalib/src/mesa/main/format_parser.py new file mode 100644 index 000000000..5e45c74de --- /dev/null +++ b/mesalib/src/mesa/main/format_parser.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python +# +# Copyright 2009 VMware, Inc. +# Copyright 2014 Intel Corporation +# 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 VMWARE 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. + +VOID = 'x' +UNSIGNED = 'u' +SIGNED = 's' +FLOAT = 'f' + +ARRAY = 'array' +PACKED = 'packed' +OTHER = 'other' + +RGB = 'rgb' +SRGB = 'srgb' +YUV = 'yuv' +ZS = 'zs' + +def is_power_of_two(x): + return not bool(x & (x - 1)) + +VERY_LARGE = 99999999999999999999999 + +class Channel: + """Describes a color channel.""" + + def __init__(self, type, norm, size): + self.type = type + self.norm = norm + self.size = size + self.sign = type in (SIGNED, FLOAT) + self.name = None # Set when the channels are added to the format + self.shift = -1 # Set when the channels are added to the format + self.index = -1 # Set when the channels are added to the format + + def __str__(self): + s = str(self.type) + if self.norm: + s += 'n' + s += str(self.size) + return s + + def __eq__(self, other): + return self.type == other.type and self.norm == other.norm and self.size == other.size + + def max(self): + """Returns the maximum representable number.""" + if self.type == FLOAT: + return VERY_LARGE + if self.norm: + return 1 + if self.type == UNSIGNED: + return (1 << self.size) - 1 + if self.type == SIGNED: + return (1 << (self.size - 1)) - 1 + assert False + + def min(self): + """Returns the minimum representable number.""" + if self.type == FLOAT: + return -VERY_LARGE + if self.type == UNSIGNED: + return 0 + if self.norm: + return -1 + if self.type == SIGNED: + return -(1 << (self.size - 1)) + assert False + + def one(self): + """Returns the value that represents 1.0f.""" + if self.type == UNSIGNED: + return (1 << self.size) - 1 + if self.type == SIGNED: + return (1 << (self.size - 1)) - 1 + else: + return 1 + + def is_power_of_two(self): + """Returns true if the size of this channel is a power of two.""" + return is_power_of_two(self.size) + +class Swizzle: + """Describes a swizzle operation. + + A Swizzle is a mapping from one set of channels in one format to the + channels in another. Each channel in the destination format is + associated with one of the following constants: + + * SWIZZLE_X: The first channel in the source format + * SWIZZLE_Y: The second channel in the source format + * SWIZZLE_Z: The third channel in the source format + * SWIZZLE_W: The fourth channel in the source format + * SWIZZLE_ZERO: The numeric constant 0 + * SWIZZLE_ONE: THe numeric constant 1 + * SWIZZLE_NONE: No data available for this channel + + Sometimes a Swizzle is represented by a 4-character string. In this + case, the source channels are represented by the characters "x", "y", + "z", and "w"; the numeric constants are represented as "0" and "1"; and + no mapping is represented by "_". For instance, the map from + luminance-alpha to rgba is given by "xxxy" because each of the three rgb + channels maps to the first luminance-alpha channel and the alpha channel + maps to second luminance-alpha channel. The mapping from bgr to rgba is + given by "zyx1" because the first three colors are reversed and alpha is + always 1. + """ + + __identity_str = 'xyzw01_' + + SWIZZLE_X = 0 + SWIZZLE_Y = 1 + SWIZZLE_Z = 2 + SWIZZLE_W = 3 + SWIZZLE_ZERO = 4 + SWIZZLE_ONE = 5 + SWIZZLE_NONE = 6 + + def __init__(self, swizzle): + """Creates a Swizzle object from a string or array.""" + if isinstance(swizzle, str): + swizzle = [Swizzle.__identity_str.index(c) for c in swizzle] + else: + swizzle = list(swizzle) + for s in swizzle: + assert isinstance(s, int) and 0 <= s and s <= Swizzle.SWIZZLE_NONE + + assert len(swizzle) <= 4 + + self.__list = swizzle + [Swizzle.SWIZZLE_NONE] * (4 - len(swizzle)) + assert len(self.__list) == 4 + + def __iter__(self): + """Returns an iterator that iterates over this Swizzle. + + The values that the iterator produces are described by the SWIZZLE_* + constants. + """ + return self.__list.__iter__() + + def __str__(self): + """Returns a string representation of this Swizzle.""" + return ''.join(Swizzle.__identity_str[i] for i in self.__list) + + def __getitem__(self, idx): + """Returns the SWIZZLE_* constant for the given destination channel. + + Valid values for the destination channel include any of the SWIZZLE_* + constants or any of the following single-character strings: "x", "y", + "z", "w", "r", "g", "b", "a", "z" "s". + """ + + if isinstance(idx, int): + assert idx >= Swizzle.SWIZZLE_X and idx <= Swizzle.SWIZZLE_NONE + if idx <= Swizzle.SWIZZLE_W: + return self.__list.__getitem__(idx) + else: + return idx + elif isinstance(idx, str): + if idx in 'xyzw': + idx = 'xyzw'.find(idx) + elif idx in 'rgba': + idx = 'rgba'.find(idx) + elif idx in 'zs': + idx = 'zs'.find(idx) + else: + assert False + return self.__list.__getitem__(idx) + else: + assert False + + def __mul__(self, other): + """Returns the composition of this Swizzle with another Swizzle. + + The resulting swizzle is such that, for any valid input to + __getitem__, (a * b)[i] = a[b[i]]. + """ + assert isinstance(other, Swizzle) + return Swizzle(self[x] for x in other) + + def inverse(self): + """Returns a pseudo-inverse of this swizzle. + + Since swizzling isn't necisaraly a bijection, a Swizzle can never + be truely inverted. However, the swizzle returned is *almost* the + inverse of this swizzle in the sense that, for each i in range(3), + a[a.inverse()[i]] is either i or SWIZZLE_NONE. If swizzle is just + a permutation with no channels added or removed, then this + function returns the actual inverse. + + This "pseudo-inverse" idea can be demonstrated by mapping from + luminance-alpha to rgba that is given by "xxxy". To get from rgba + to lumanence-alpha, we use Swizzle("xxxy").inverse() or "xw__". + This maps the first component in the lumanence-alpha texture is + the red component of the rgba image and the second to the alpha + component, exactly as you would expect. + """ + rev = [Swizzle.SWIZZLE_NONE] * 4 + for i in xrange(4): + for j in xrange(4): + if self.__list[j] == i and rev[i] == Swizzle.SWIZZLE_NONE: + rev[i] = j + return Swizzle(rev) + + +class Format: + """Describes a pixel format.""" + + def __init__(self, name, layout, block_width, block_height, channels, swizzle, colorspace): + """Constructs a Format from some metadata and a list of channels. + + The channel objects must be unique to this Format and should not be + re-used to construct another Format. This is because certain channel + information such as shift, offset, and the channel name are set when + the Format is created and are calculated based on the entire list of + channels. + + Arguments: + name -- Name of the format such as 'MESA_FORMAT_A8R8G8B8' + layout -- One of 'array', 'packed' 'other', or a compressed layout + block_width -- The block width if the format is compressed, 1 otherwise + block_height -- The block height if the format is compressed, 1 otherwise + channels -- A list of Channel objects + swizzle -- A Swizzle from this format to rgba + colorspace -- one of 'rgb', 'srgb', 'yuv', or 'zs' + """ + self.name = name + self.layout = layout + self.block_width = block_width + self.block_height = block_height + self.channels = channels + assert isinstance(swizzle, Swizzle) + self.swizzle = swizzle + self.name = name + assert colorspace in (RGB, SRGB, YUV, ZS) + self.colorspace = colorspace + + # Name the channels + chan_names = ['']*4 + if self.colorspace in (RGB, SRGB): + for (i, s) in enumerate(swizzle): + if s < 4: + chan_names[s] += 'rgba'[i] + elif colorspace == ZS: + for (i, s) in enumerate(swizzle): + if s < 4: + chan_names[s] += 'zs'[i] + else: + chan_names = ['x', 'y', 'z', 'w'] + + for c, name in zip(self.channels, chan_names): + assert c.name is None + if name == 'rgb': + c.name = 'l' + elif name == 'rgba': + c.name = 'i' + elif name == '': + c.name = 'x' + else: + c.name = name + + # Set indices and offsets + if self.layout == PACKED: + shift = 0 + for channel in self.channels: + assert channel.shift == -1 + channel.shift = shift + shift += channel.size + for idx, channel in enumerate(self.channels): + assert channel.index == -1 + channel.index = idx + else: + pass # Shift means nothing here + + def __str__(self): + return self.name + + def short_name(self): + """Returns a short name for a format. + + The short name should be suitable to be used as suffix in function + names. + """ + + name = self.name + if name.startswith('MESA_FORMAT_'): + name = name[len('MESA_FORMAT_'):] + name = name.lower() + return name + + def block_size(self): + """Returns the block size (in bits) of the format.""" + size = 0 + for channel in self.channels: + size += channel.size + return size + + def num_channels(self): + """Returns the number of channels in the format.""" + nr_channels = 0 + for channel in self.channels: + if channel.size: + nr_channels += 1 + return nr_channels + + def array_element(self): + """Returns a non-void channel if this format is an array, otherwise None. + + If the returned channel is not None, then this format can be + considered to be an array of num_channels() channels identical to the + returned channel. + """ + if self.layout == ARRAY: + return self.channels[0] + elif self.layout == PACKED: + ref_channel = self.channels[0] + if ref_channel.type == VOID: + ref_channel = self.channels[1] + for channel in self.channels: + if channel.size == 0 or channel.type == VOID: + continue + if channel.size != ref_channel.size or channel.size % 8 != 0: + return None + if channel.type != ref_channel.type: + return None + if channel.norm != ref_channel.norm: + return None + return ref_channel + else: + return None + + def is_array(self): + """Returns true if this format can be considered an array format. + + This function will return true if self.layout == 'array'. However, + some formats, such as MESA_FORMAT_A8G8B8R8, can be considered as + array formats even though they are technically packed. + """ + return self.array_element() != None + + def is_compressed(self): + """Returns true if this is a compressed format.""" + return self.block_width != 1 or self.block_height != 1 + + def is_int(self): + """Returns true if this format is an integer format. + + See also: is_norm() + """ + if self.layout not in (ARRAY, PACKED): + return False + for channel in self.channels: + if channel.type not in (VOID, UNSIGNED, SIGNED): + return False + return True + + def is_float(self): + """Returns true if this format is an floating-point format.""" + if self.layout not in (ARRAY, PACKED): + return False + for channel in self.channels: + if channel.type not in (VOID, FLOAT): + return False + return True + + def channel_type(self): + """Returns the type of the channels in this format.""" + _type = VOID + for c in self.channels: + if c.type == VOID: + continue + if _type == VOID: + _type = c.type + assert c.type == _type + return _type + + def channel_size(self): + """Returns the size (in bits) of the channels in this format. + + This function should only be called if all of the channels have the + same size. This is always the case if is_array() returns true. + """ + size = None + for c in self.channels: + if c.type == VOID: + continue + if size is None: + size = c.size + assert c.size == size + return size + + def max_channel_size(self): + """Returns the size of the largest channel.""" + size = 0 + for c in self.channels: + if c.type == VOID: + continue + size = max(size, c.size) + return size + + def is_normalized(self): + """Returns true if this format is normalized. + + While only integer formats can be normalized, not all integer formats + are normalized. Normalized integer formats are those where the + integer value is re-interpreted as a fixed point value in the range + [0, 1]. + """ + norm = None + for c in self.channels: + if c.type == VOID: + continue + if norm is None: + norm = c.norm + assert c.norm == norm + return norm + + def has_channel(self, name): + """Returns true if this format has the given channel.""" + if self.is_compressed(): + # Compressed formats are a bit tricky because the list of channels + # contains a single channel of type void. Since we don't have any + # channel information there, we pull it from the swizzle. + if str(self.swizzle) == 'xxxx': + return name == 'i' + elif str(self.swizzle)[0:3] in ('xxx', 'yyy'): + if name == 'l': + return True + elif name == 'a': + return self.swizzle['a'] <= Swizzle.SWIZZLE_W + else: + return False + elif name in 'rgba': + return self.swizzle[name] <= Swizzle.SWIZZLE_W + else: + return False + else: + for channel in self.channels: + if channel.name == name: + return True + return False + + def get_channel(self, name): + """Returns the channel with the given name if it exists.""" + for channel in self.channels: + if channel.name == name: + return channel + return None + +def _parse_channels(fields, layout, colorspace, swizzle): + channels = [] + for field in fields: + if not field: + continue + + type = field[0] if field[0] else 'x' + + if field[1] == 'n': + norm = True + size = int(field[2:]) + else: + norm = False + size = int(field[1:]) + + channel = Channel(type, norm, size) + channels.append(channel) + + return channels + +def parse(filename): + """Parse a format descrition in CSV format. + + This function parses the given CSV file and returns an iterable of + channels.""" + + with open(filename) as stream: + for line in stream: + try: + comment = line.index('#') + except ValueError: + pass + else: + line = line[:comment] + line = line.strip() + if not line: + continue + + fields = [field.strip() for field in line.split(',')] + + name = fields[0] + layout = fields[1] + block_width = int(fields[2]) + block_height = int(fields[3]) + colorspace = fields[9] + + swizzle = Swizzle(fields[8]) + channels = _parse_channels(fields[4:8], layout, colorspace, swizzle) + + yield Format(name, layout, block_width, block_height, channels, swizzle, colorspace) diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index ad5ea4cd1..b84ed0248 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -28,6 +28,7 @@ #include "macros.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "util/format_srgb.h" /** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ @@ -53,34 +54,6 @@ struct z32f_x24s8 #define EXPAND_6_8(X) ( ((X) << 2) | ((X) >> 4) ) -/** - * Convert an 8-bit sRGB value from non-linear space to a - * linear RGB value in [0, 1]. - * Implemented with a 256-entry lookup table. - */ -GLfloat -_mesa_nonlinear_to_linear(GLubyte cs8) -{ - static GLfloat table[256]; - static GLboolean tableReady = GL_FALSE; - if (!tableReady) { - /* compute lookup table now */ - GLuint i; - for (i = 0; i < 256; i++) { - const GLfloat cs = UBYTE_TO_FLOAT(i); - if (cs <= 0.04045) { - table[i] = cs / 12.92f; - } - else { - table[i] = (GLfloat) pow((cs + 0.055) / 1.055, 2.4); - } - } - tableReady = GL_TRUE; - } - return table[cs8]; -} - - /**********************************************************************/ /* Unpack, returning GLfloat colors */ /**********************************************************************/ @@ -763,9 +736,9 @@ unpack_BGR_SRGB8(const void *src, GLfloat dst[][4], GLuint n) const GLubyte *s = (const GLubyte *) src; GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_nonlinear_to_linear(s[i*3+2]); - dst[i][GCOMP] = _mesa_nonlinear_to_linear(s[i*3+1]); - dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i*3+0]); + dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+2]); + dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+1]); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i*3+0]); dst[i][ACOMP] = 1.0F; } } @@ -776,9 +749,9 @@ unpack_A8B8G8R8_SRGB(const void *src, GLfloat dst[][4], GLuint n) const GLuint *s = ((const GLuint *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 24) ); - dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); + dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 24) ); + dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); /* linear! */ } } @@ -789,9 +762,9 @@ unpack_B8G8R8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) const GLuint *s = ((const GLuint *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff ); + dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); + dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */ } } @@ -802,9 +775,9 @@ unpack_R8G8B8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) const GLuint *s = ((const GLuint *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff ); - dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); + dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); + dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */ } } @@ -817,7 +790,7 @@ unpack_L_SRGB8(const void *src, GLfloat dst[][4], GLuint n) for (i = 0; i < n; i++) { dst[i][RCOMP] = dst[i][GCOMP] = - dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i]); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i]); dst[i][ACOMP] = 1.0F; } } @@ -830,7 +803,7 @@ unpack_L8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) for (i = 0; i < n; i++) { dst[i][RCOMP] = dst[i][GCOMP] = - dst[i][BCOMP] = _mesa_nonlinear_to_linear(s[i] & 0xff); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i] & 0xff); dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] >> 8); /* linear! */ } } @@ -2124,9 +2097,9 @@ unpack_R8G8B8X8_SRGB(const void *src, GLfloat dst[][4], GLuint n) const GLuint *s = ((const GLuint *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff ); - dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); + dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); + dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 24 ); /* linear! */ } } @@ -2319,9 +2292,9 @@ unpack_B8G8R8X8_SRGB(const void *src, GLfloat dst[][4], GLuint n) const GLuint *s = ((const GLuint *) src); GLuint i; for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = _mesa_nonlinear_to_linear( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = _mesa_nonlinear_to_linear( (s[i] ) & 0xff ); + dst[i][RCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 16) & 0xff ); + dst[i][GCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); + dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float( (s[i] ) & 0xff ); dst[i][ACOMP] = 1.0F; } } diff --git a/mesalib/src/mesa/main/format_unpack.h b/mesalib/src/mesa/main/format_unpack.h index 51f97df4d..eba3c6650 100644 --- a/mesalib/src/mesa/main/format_unpack.h +++ b/mesalib/src/mesa/main/format_unpack.h @@ -25,9 +25,6 @@ #ifndef FORMAT_UNPACK_H #define FORMAT_UNPACK_H -extern GLfloat -_mesa_nonlinear_to_linear(GLubyte cs8); - extern void _mesa_unpack_rgba_row(mesa_format format, GLuint n, const void *src, GLfloat dst[][4]); diff --git a/mesalib/src/mesa/main/format_utils.c b/mesalib/src/mesa/main/format_utils.c new file mode 100644 index 000000000..240e3bc0c --- /dev/null +++ b/mesalib/src/mesa/main/format_utils.c @@ -0,0 +1,977 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2014 Intel Corporation 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, 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "format_utils.h" +#include "glformats.h" + +static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 }; +static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 }; +static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 }; + +/** + * Describes a format as an array format, if possible + * + * A helper function for figuring out if a (possibly packed) format is + * actually an array format and, if so, what the array parameters are. + * + * \param[in] format the mesa format + * \param[out] type the GL type of the array (GL_BYTE, etc.) + * \param[out] num_components the number of components in the array + * \param[out] swizzle a swizzle describing how to get from the + * given format to RGBA + * \param[out] normalized for integer formats, this represents whether + * the format is a normalized integer or a + * regular integer + * \return true if this format is an array format, false otherwise + */ +bool +_mesa_format_to_array(mesa_format format, GLenum *type, int *num_components, + uint8_t swizzle[4], bool *normalized) +{ + int i; + GLuint format_components; + uint8_t packed_swizzle[4]; + const uint8_t *endian; + + if (_mesa_is_format_compressed(format)) + return false; + + *normalized = !_mesa_is_format_integer(format); + + _mesa_format_to_type_and_comps(format, type, &format_components); + + switch (_mesa_get_format_layout(format)) { + case MESA_FORMAT_LAYOUT_ARRAY: + *num_components = format_components; + _mesa_get_format_swizzle(format, swizzle); + return true; + case MESA_FORMAT_LAYOUT_PACKED: + switch (*type) { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + if (_mesa_get_format_max_bits(format) != 8) + return false; + *num_components = _mesa_get_format_bytes(format); + switch (*num_components) { + case 1: + endian = map_identity; + break; + case 2: + endian = _mesa_little_endian() ? map_identity : map_1032; + break; + case 4: + endian = _mesa_little_endian() ? map_identity : map_3210; + break; + default: + endian = map_identity; + assert(!"Invalid number of components"); + } + break; + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_HALF_FLOAT: + if (_mesa_get_format_max_bits(format) != 16) + return false; + *num_components = _mesa_get_format_bytes(format) / 2; + switch (*num_components) { + case 1: + endian = map_identity; + break; + case 2: + endian = _mesa_little_endian() ? map_identity : map_1032; + break; + default: + endian = map_identity; + assert(!"Invalid number of components"); + } + break; + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + /* This isn't packed. At least not really. */ + assert(format_components == 1); + if (_mesa_get_format_max_bits(format) != 32) + return false; + *num_components = format_components; + endian = map_identity; + break; + default: + return false; + } + + _mesa_get_format_swizzle(format, packed_swizzle); + + for (i = 0; i < 4; ++i) + swizzle[i] = endian[packed_swizzle[i]]; + + return true; + case MESA_FORMAT_LAYOUT_OTHER: + default: + return false; + } +} + +/* A bunch of format conversion macros and helper functions used below */ + +/* Only guaranteed to work for BITS <= 32 */ +#define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1)) +#define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1)) + +/* Extends an integer of size SRC_BITS to one of size DST_BITS linearly */ +#define EXTEND_NORMALIZED_INT(X, SRC_BITS, DST_BITS) \ + (((X) * (int)(MAX_UINT(DST_BITS) / MAX_UINT(SRC_BITS))) + \ + ((DST_BITS % SRC_BITS) ? ((X) >> (SRC_BITS - DST_BITS % SRC_BITS)) : 0)) + +static inline float +unorm_to_float(unsigned x, unsigned src_bits) +{ + return x * (1.0f / (float)MAX_UINT(src_bits)); +} + +static inline float +snorm_to_float(int x, unsigned src_bits) +{ + if (x == -MAX_INT(src_bits)) + return -1.0f; + else + return x * (1.0f / (float)MAX_INT(src_bits)); +} + +static inline uint16_t +unorm_to_half(unsigned x, unsigned src_bits) +{ + return _mesa_float_to_half(unorm_to_float(x, src_bits)); +} + +static inline uint16_t +snorm_to_half(int x, unsigned src_bits) +{ + return _mesa_float_to_half(snorm_to_float(x, src_bits)); +} + +static inline unsigned +float_to_unorm(float x, unsigned dst_bits) +{ + if (x < 0.0f) + return 0; + else if (x > 1.0f) + return MAX_UINT(dst_bits); + else + return F_TO_I(x * MAX_UINT(dst_bits)); +} + +static inline unsigned +half_to_unorm(uint16_t x, unsigned dst_bits) +{ + return float_to_unorm(_mesa_half_to_float(x), dst_bits); +} + +static inline unsigned +unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits) +{ + if (src_bits < dst_bits) + return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits); + else + return x >> (src_bits - dst_bits); +} + +static inline unsigned +snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits) +{ + if (x < 0) + return 0; + else + return unorm_to_unorm(x, src_bits - 1, dst_bits); +} + +static inline int +float_to_snorm(float x, unsigned dst_bits) +{ + if (x < -1.0f) + return -MAX_INT(dst_bits); + else if (x > 1.0f) + return MAX_INT(dst_bits); + else + return F_TO_I(x * MAX_INT(dst_bits)); +} + +static inline int +half_to_snorm(uint16_t x, unsigned dst_bits) +{ + return float_to_snorm(_mesa_half_to_float(x), dst_bits); +} + +static inline int +unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits) +{ + return unorm_to_unorm(x, src_bits, dst_bits - 1); +} + +static inline int +snorm_to_snorm(int x, unsigned src_bits, unsigned dst_bits) +{ + if (x < -MAX_INT(src_bits)) + return -MAX_INT(dst_bits); + else if (src_bits < dst_bits) + return EXTEND_NORMALIZED_INT(x, src_bits - 1, dst_bits - 1); + else + return x >> (src_bits - dst_bits); +} + +static inline unsigned +float_to_uint(float x) +{ + if (x < 0.0f) + return 0; + else + return x; +} + +static inline unsigned +half_to_uint(uint16_t x) +{ + if (_mesa_half_is_negative(x)) + return 0; + else + return _mesa_float_to_half(x); +} + +/** + * Attempts to perform the given swizzle-and-convert operation with memcpy + * + * This function determines if the given swizzle-and-convert operation can + * be done with a simple memcpy and, if so, does the memcpy. If not, it + * returns false and we fall back to the standard version below. + * + * The arguments are exactly the same as for _mesa_swizzle_and_convert + * + * \return true if it successfully performed the swizzle-and-convert + * operation with memcpy, false otherwise + */ +static bool +swizzle_convert_try_memcpy(void *dst, GLenum dst_type, int num_dst_channels, + const void *src, GLenum src_type, int num_src_channels, + const uint8_t swizzle[4], bool normalized, int count) +{ + int i; + + if (src_type != dst_type) + return false; + if (num_src_channels != num_dst_channels) + return false; + + for (i = 0; i < num_dst_channels; ++i) + if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE) + return false; + + memcpy(dst, src, count * num_src_channels * _mesa_sizeof_type(src_type)); + + return true; +} + +/** + * Represents a single instance of the standard swizzle-and-convert loop + * + * Any swizzle-and-convert operation simply loops through the pixels and + * performs the transformation operation one pixel at a time. This macro + * embodies one instance of the conversion loop. This way we can do all + * control flow outside of the loop and allow the compiler to unroll + * everything inside the loop. + * + * Note: This loop is carefully crafted for performance. Be careful when + * changing it and run some benchmarks to ensure no performance regressions + * if you do. + * + * \param DST_TYPE the C datatype of the destination + * \param DST_CHANS the number of destination channels + * \param SRC_TYPE the C datatype of the source + * \param SRC_CHANS the number of source channels + * \param CONV an expression for converting from the source data, + * storred in the variable "src", to the destination + * format + */ +#define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \ + for (s = 0; s < count; ++s) { \ + for (j = 0; j < SRC_CHANS; ++j) { \ + SRC_TYPE src = typed_src[j]; \ + tmp[j] = CONV; \ + } \ + \ + typed_dst[0] = tmp[swizzle_x]; \ + if (DST_CHANS > 1) { \ + typed_dst[1] = tmp[swizzle_y]; \ + if (DST_CHANS > 2) { \ + typed_dst[2] = tmp[swizzle_z]; \ + if (DST_CHANS > 3) { \ + typed_dst[3] = tmp[swizzle_w]; \ + } \ + } \ + } \ + typed_src += SRC_CHANS; \ + typed_dst += DST_CHANS; \ + } \ + +/** + * Represents a single swizzle-and-convert operation + * + * This macro represents everything done in a single swizzle-and-convert + * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro. + * This macro acts as a wrapper that uses a nested switch to ensure that + * all looping parameters get unrolled. + * + * This macro makes assumptions about variables etc. in the calling + * function. Changes to _mesa_swizzle_and_convert may require changes to + * this macro. + * + * \param DST_TYPE the C datatype of the destination + * \param SRC_TYPE the C datatype of the source + * \param CONV an expression for converting from the source data, + * storred in the variable "src", to the destination + * format + */ +#define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \ + do { \ + const SRC_TYPE *typed_src = void_src; \ + DST_TYPE *typed_dst = void_dst; \ + DST_TYPE tmp[7]; \ + tmp[4] = 0; \ + tmp[5] = one; \ + switch (num_dst_channels) { \ + case 1: \ + switch (num_src_channels) { \ + case 1: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV) \ + break; \ + case 2: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV) \ + break; \ + case 3: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV) \ + break; \ + case 4: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV) \ + break; \ + } \ + break; \ + case 2: \ + switch (num_src_channels) { \ + case 1: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV) \ + break; \ + case 2: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV) \ + break; \ + case 3: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV) \ + break; \ + case 4: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV) \ + break; \ + } \ + break; \ + case 3: \ + switch (num_src_channels) { \ + case 1: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV) \ + break; \ + case 2: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV) \ + break; \ + case 3: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV) \ + break; \ + case 4: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV) \ + break; \ + } \ + break; \ + case 4: \ + switch (num_src_channels) { \ + case 1: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV) \ + break; \ + case 2: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV) \ + break; \ + case 3: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV) \ + break; \ + case 4: \ + SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV) \ + break; \ + } \ + break; \ + } \ + } while (0); + +/** + * Convert between array-based color formats. + * + * Most format conversion operations required by GL can be performed by + * converting one channel at a time, shuffling the channels around, and + * optionally filling missing channels with zeros and ones. This function + * does just that in a general, yet efficient, way. + * + * The swizzle parameter is an array of 4 numbers (see + * _mesa_get_format_swizzle) that describes where each channel in the + * destination should come from in the source. If swizzle[i] < 4 then it + * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is + * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding + * dst[i] will be filled with the appropreate representation of zero or one + * respectively. + * + * Under most circumstances, the source and destination images must be + * different as no care is taken not to clobber one with the other. + * However, if they have the same number of bits per pixel, it is safe to + * do an in-place conversion. + * + * \param[out] dst pointer to where the converted data should + * be stored + * + * \param[in] dst_type the destination GL type of the converted + * data (GL_BYTE, etc.) + * + * \param[in] num_dst_channels the number of channels in the converted + * data + * + * \param[in] src pointer to the source data + * + * \param[in] src_type the GL type of the source data (GL_BYTE, + * etc.) + * + * \param[in] num_src_channels the number of channels in the source data + * (the number of channels total, not just + * the number used) + * + * \param[in] swizzle describes how to get the destination data + * from the source data. + * + * \param[in] normalized for integer types, this indicates whether + * the data should be considered as integers + * or as normalized integers; + * + * \param[in] count the number of pixels to convert + */ +void +_mesa_swizzle_and_convert(void *void_dst, GLenum dst_type, int num_dst_channels, + const void *void_src, GLenum src_type, int num_src_channels, + const uint8_t swizzle[4], bool normalized, int count) +{ + int s, j; + register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w; + + if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels, + void_src, src_type, num_src_channels, + swizzle, normalized, count)) + return; + + swizzle_x = swizzle[0]; + swizzle_y = swizzle[1]; + swizzle_z = swizzle[2]; + swizzle_w = swizzle[3]; + + switch (dst_type) { + case GL_FLOAT: + { + const float one = 1.0f; + switch (src_type) { + case GL_FLOAT: + SWIZZLE_CONVERT(float, float, src) + break; + case GL_HALF_FLOAT: + SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src)) + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(float, uint8_t, unorm_to_float(src, 8)) + } else { + SWIZZLE_CONVERT(float, uint8_t, src) + } + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(float, int8_t, snorm_to_float(src, 8)) + } else { + SWIZZLE_CONVERT(float, int8_t, src) + } + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(float, uint16_t, unorm_to_float(src, 16)) + } else { + SWIZZLE_CONVERT(float, uint16_t, src) + } + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(float, int16_t, snorm_to_float(src, 16)) + } else { + SWIZZLE_CONVERT(float, int16_t, src) + } + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(float, uint32_t, unorm_to_float(src, 32)) + } else { + SWIZZLE_CONVERT(float, uint32_t, src) + } + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(float, int32_t, snorm_to_float(src, 32)) + } else { + SWIZZLE_CONVERT(float, int32_t, src) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_HALF_FLOAT: + { + const uint16_t one = _mesa_float_to_half(1.0f); + switch (src_type) { + case GL_FLOAT: + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src)) + break; + case GL_HALF_FLOAT: + SWIZZLE_CONVERT(uint16_t, uint16_t, src) + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_half(src, 8)) + } else { + SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src)) + } + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_half(src, 8)) + } else { + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src)) + } + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint16_t, unorm_to_half(src, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src)) + } + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_half(src, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src)) + } + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_half(src, 32)) + } else { + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src)) + } + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_half(src, 32)) + } else { + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src)) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_UNSIGNED_BYTE: + { + const uint8_t one = normalized ? UINT8_MAX : 1; + switch (src_type) { + case GL_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, float, float_to_unorm(src, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, float, (src < 0) ? 0 : src) + } + break; + case GL_HALF_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_unorm(src, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_uint(src)) + } + break; + case GL_UNSIGNED_BYTE: + SWIZZLE_CONVERT(uint8_t, uint8_t, src) + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, int8_t, snorm_to_unorm(src, 8, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, int8_t, (src < 0) ? 0 : src) + } + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, uint16_t, unorm_to_unorm(src, 16, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, uint16_t, src) + } + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, int16_t, snorm_to_unorm(src, 16, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, int16_t, (src < 0) ? 0 : src) + } + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, uint32_t, unorm_to_unorm(src, 32, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, uint32_t, src) + } + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, int32_t, snorm_to_unorm(src, 32, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, int32_t, (src < 0) ? 0 : src) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_BYTE: + { + const int8_t one = normalized ? INT8_MAX : 1; + switch (src_type) { + case GL_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, float, float_to_snorm(src, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, float, src) + } + break; + case GL_HALF_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_snorm(src, 8)) + } else { + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_float(src)) + } + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(int8_t, uint8_t, unorm_to_snorm(src, 8, 8)) + } else { + SWIZZLE_CONVERT(int8_t, uint8_t, src) + } + break; + case GL_BYTE: + SWIZZLE_CONVERT(int8_t, int8_t, src) + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(int8_t, uint16_t, unorm_to_snorm(src, 16, 8)) + } else { + SWIZZLE_CONVERT(int8_t, uint16_t, src) + } + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(int8_t, int16_t, snorm_to_snorm(src, 16, 8)) + } else { + SWIZZLE_CONVERT(int8_t, int16_t, src) + } + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(int8_t, uint32_t, unorm_to_snorm(src, 32, 8)) + } else { + SWIZZLE_CONVERT(int8_t, uint32_t, src) + } + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(int8_t, int32_t, snorm_to_snorm(src, 32, 8)) + } else { + SWIZZLE_CONVERT(int8_t, int32_t, src) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_UNSIGNED_SHORT: + { + const uint16_t one = normalized ? UINT16_MAX : 1; + switch (src_type) { + case GL_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, float, float_to_unorm(src, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, float, (src < 0) ? 0 : src) + } + break; + case GL_HALF_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_unorm(src, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_uint(src)) + } + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_unorm(src, 8, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, uint8_t, src) + } + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_unorm(src, 8, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, int8_t, (src < 0) ? 0 : src) + } + break; + case GL_UNSIGNED_SHORT: + SWIZZLE_CONVERT(uint16_t, uint16_t, src) + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_unorm(src, 16, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, int16_t, (src < 0) ? 0 : src) + } + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_unorm(src, 32, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, uint32_t, src) + } + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_unorm(src, 32, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, int32_t, (src < 0) ? 0 : src) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_SHORT: + { + const int16_t one = normalized ? INT16_MAX : 1; + switch (src_type) { + case GL_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, float, float_to_snorm(src, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, float, src) + } + break; + case GL_HALF_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_snorm(src, 16)) + } else { + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_float(src)) + } + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(int16_t, uint8_t, unorm_to_snorm(src, 8, 16)) + } else { + SWIZZLE_CONVERT(int16_t, uint8_t, src) + } + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(int16_t, int8_t, snorm_to_snorm(src, 8, 16)) + } else { + SWIZZLE_CONVERT(int16_t, int8_t, src) + } + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(int16_t, uint16_t, unorm_to_snorm(src, 16, 16)) + } else { + SWIZZLE_CONVERT(int16_t, uint16_t, src) + } + break; + case GL_SHORT: + SWIZZLE_CONVERT(int16_t, int16_t, src) + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(int16_t, uint32_t, unorm_to_snorm(src, 32, 16)) + } else { + SWIZZLE_CONVERT(int16_t, uint32_t, src) + } + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(int16_t, int32_t, snorm_to_snorm(src, 32, 16)) + } else { + SWIZZLE_CONVERT(int16_t, int32_t, src) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_UNSIGNED_INT: + { + const uint32_t one = normalized ? UINT32_MAX : 1; + switch (src_type) { case GL_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, float, float_to_unorm(src, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, float, (src < 0) ? 0 : src) + } + break; + case GL_HALF_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_unorm(src, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_uint(src)) + } + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, uint8_t, unorm_to_unorm(src, 8, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, uint8_t, src) + } + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, int8_t, snorm_to_unorm(src, 8, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, int8_t, (src < 0) ? 0 : src) + } + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, uint16_t, unorm_to_unorm(src, 16, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, uint16_t, src) + } + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, int16_t, snorm_to_unorm(src, 16, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, int16_t, (src < 0) ? 0 : src) + } + break; + case GL_UNSIGNED_INT: + SWIZZLE_CONVERT(uint32_t, uint32_t, src) + break; + case GL_INT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, int32_t, snorm_to_unorm(src, 32, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, int32_t, (src < 0) ? 0 : src) + } + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + case GL_INT: + { + const int32_t one = normalized ? INT32_MAX : 1; + switch (src_type) { + case GL_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, float, float_to_snorm(src, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, float, src) + } + break; + case GL_HALF_FLOAT: + if (normalized) { + SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_snorm(src, 32)) + } else { + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_float(src)) + } + break; + case GL_UNSIGNED_BYTE: + if (normalized) { + SWIZZLE_CONVERT(int32_t, uint8_t, unorm_to_snorm(src, 8, 32)) + } else { + SWIZZLE_CONVERT(int32_t, uint8_t, src) + } + break; + case GL_BYTE: + if (normalized) { + SWIZZLE_CONVERT(int32_t, int8_t, snorm_to_snorm(src, 8, 32)) + } else { + SWIZZLE_CONVERT(int32_t, int8_t, src) + } + break; + case GL_UNSIGNED_SHORT: + if (normalized) { + SWIZZLE_CONVERT(int32_t, uint16_t, unorm_to_snorm(src, 16, 32)) + } else { + SWIZZLE_CONVERT(int32_t, uint16_t, src) + } + break; + case GL_SHORT: + if (normalized) { + SWIZZLE_CONVERT(int32_t, int16_t, snorm_to_snorm(src, 16, 32)) + } else { + SWIZZLE_CONVERT(int32_t, int16_t, src) + } + break; + case GL_UNSIGNED_INT: + if (normalized) { + SWIZZLE_CONVERT(int32_t, uint32_t, unorm_to_snorm(src, 32, 32)) + } else { + SWIZZLE_CONVERT(int32_t, uint32_t, src) + } + break; + case GL_INT: + SWIZZLE_CONVERT(int32_t, int32_t, src) + break; + default: + assert(!"Invalid channel type combination"); + } + } + break; + default: + assert(!"Invalid channel type"); + } +} diff --git a/mesalib/src/mesa/main/format_utils.h b/mesalib/src/mesa/main/format_utils.h new file mode 100644 index 000000000..9f778e377 --- /dev/null +++ b/mesalib/src/mesa/main/format_utils.h @@ -0,0 +1,45 @@ +/** + * \file format_utils.h + * A collection of format conversion utility functions. + */ + +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2014 Intel Corporation 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, 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef FORMAT_UTILS_H +#define FORMAT_UTILS_H + +#include "imports.h" + +bool +_mesa_format_to_array(mesa_format, GLenum *type, int *num_components, + uint8_t swizzle[4], bool *normalized); + +void +_mesa_swizzle_and_convert(void *dst, GLenum dst_type, int num_dst_channels, + const void *src, GLenum src_type, int num_src_channels, + const uint8_t swizzle[4], bool normalized, int count); + +#endif diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index 1f20a9a6a..f03425e41 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -40,6 +40,8 @@ struct gl_format_info /** text name for debugging */ const char *StrName; + enum mesa_format_layout Layout; + /** * Base format is one of GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_ALPHA, * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_YCBCR_MESA, @@ -59,7 +61,6 @@ struct gl_format_info GLubyte AlphaBits; GLubyte LuminanceBits; GLubyte IntensityBits; - GLubyte IndexBits; GLubyte DepthBits; GLubyte StencilBits; @@ -68,1745 +69,11 @@ struct gl_format_info */ GLubyte BlockWidth, BlockHeight; GLubyte BytesPerBlock; -}; - -/** - * Info about each format. - * These must be in the same order as the MESA_FORMAT_* enums so that - * we can do lookups without searching. - */ -static struct gl_format_info format_info[MESA_FORMAT_COUNT] = -{ - /* Packed unorm formats */ - { - MESA_FORMAT_NONE, /* Name */ - "MESA_FORMAT_NONE", /* StrName */ - GL_NONE, /* BaseFormat */ - GL_NONE, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 0, 0, 0 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A8B8G8R8_UNORM, /* Name */ - "MESA_FORMAT_A8B8G8R8_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_X8B8G8R8_UNORM, /* Name */ - "MESA_FORMAT_X8B8G8R8_UNORM",/* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R8G8B8A8_UNORM, /* Name */ - "MESA_FORMAT_R8G8B8A8_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R8G8B8X8_UNORM, /* Name */ - "MESA_FORMAT_R8G8B8X8_UNORM",/* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B8G8R8A8_UNORM, /* Name */ - "MESA_FORMAT_B8G8R8A8_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B8G8R8X8_UNORM, /* Name */ - "MESA_FORMAT_B8G8R8X8_UNORM",/* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A8R8G8B8_UNORM, /* Name */ - "MESA_FORMAT_A8R8G8B8_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_X8R8G8B8_UNORM, /* Name */ - "MESA_FORMAT_X8R8G8B8_UNORM",/* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_L16A16_UNORM, /* Name */ - "MESA_FORMAT_L16A16_UNORM", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ - 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A16L16_UNORM, /* Name */ - "MESA_FORMAT_A16L16_UNORM", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ - 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B5G6R5_UNORM, /* Name */ - "MESA_FORMAT_B5G6R5_UNORM", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R5G6B5_UNORM, /* Name */ - "MESA_FORMAT_R5G6B5_UNORM", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B4G4R4A4_UNORM, /* Name */ - "MESA_FORMAT_B4G4R4A4_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B4G4R4X4_UNORM, - "MESA_FORMAT_B4G4R4X4_UNORM", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_A4R4G4B4_UNORM, /* Name */ - "MESA_FORMAT_A4R4G4B4_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A1B5G5R5_UNORM, /* Name */ - "MESA_FORMAT_A1B5G5R5_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B5G5R5A1_UNORM, /* Name */ - "MESA_FORMAT_B5G5R5A1_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B5G5R5X1_UNORM, - "MESA_FORMAT_B5G5R5X1_UNORM", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 5, 5, 5, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_A1R5G5B5_UNORM, /* Name */ - "MESA_FORMAT_A1R5G5B5_UNORM",/* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_L8A8_UNORM, /* Name */ - "MESA_FORMAT_L8A8_UNORM", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ - 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A8L8_UNORM, /* Name */ - "MESA_FORMAT_A8L8_UNORM", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ - 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R8G8_UNORM, - "MESA_FORMAT_R8G8_UNORM", - GL_RG, - GL_UNSIGNED_NORMALIZED, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_G8R8_UNORM, - "MESA_FORMAT_G8R8_UNORM", - GL_RG, - GL_UNSIGNED_NORMALIZED, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_L4A4_UNORM, /* Name */ - "MESA_FORMAT_L4A4_UNORM", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 4, /* Red/Green/Blue/AlphaBits */ - 4, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_B2G3R3_UNORM, /* Name */ - "MESA_FORMAT_B2G3R3_UNORM", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 3, 3, 2, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R16G16_UNORM, - "MESA_FORMAT_R16G16_UNORM", - GL_RG, - GL_UNSIGNED_NORMALIZED, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_G16R16_UNORM, - "MESA_FORMAT_G16R16_UNORM", - GL_RG, - GL_UNSIGNED_NORMALIZED, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_B10G10R10A2_UNORM, - "MESA_FORMAT_B10G10R10A2_UNORM", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 10, 10, 10, 2, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_B10G10R10X2_UNORM, - "MESA_FORMAT_B10G10R10X2_UNORM", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 10, 10, 10, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R10G10B10A2_UNORM, - "MESA_FORMAT_R10G10B10A2_UNORM", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 10, 10, 10, 2, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_S8_UINT_Z24_UNORM, /* Name */ - "MESA_FORMAT_S8_UINT_Z24_UNORM", /* StrName */ - GL_DEPTH_STENCIL, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_X8_UINT_Z24_UNORM, /* Name */ - "MESA_FORMAT_X8_UINT_Z24_UNORM", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z24_UNORM_S8_UINT, /* Name */ - "MESA_FORMAT_Z24_UNORM_S8_UINT", /* StrName */ - GL_DEPTH_STENCIL, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z24_UNORM_X8_UINT, /* Name */ - "MESA_FORMAT_Z24_UNORM_X8_UINT", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_YCBCR, /* Name */ - "MESA_FORMAT_YCBCR", /* StrName */ - GL_YCBCR_MESA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_YCBCR_REV, /* Name */ - "MESA_FORMAT_YCBCR_REV", /* StrName */ - GL_YCBCR_MESA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - - /* Array unorm formats */ - { - MESA_FORMAT_A_UNORM8, /* Name */ - "MESA_FORMAT_A_UNORM8", /* StrName */ - GL_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A_UNORM16, /* Name */ - "MESA_FORMAT_A_UNORM16", /* StrName */ - GL_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_L_UNORM8, /* Name */ - "MESA_FORMAT_L_UNORM8", /* StrName */ - GL_LUMINANCE, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_L_UNORM16, /* Name */ - "MESA_FORMAT_L_UNORM16", /* StrName */ - GL_LUMINANCE, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_I_UNORM8, /* Name */ - "MESA_FORMAT_I_UNORM8", /* StrName */ - GL_INTENSITY, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 8, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_I_UNORM16, /* Name */ - "MESA_FORMAT_I_UNORM16", /* StrName */ - GL_INTENSITY, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 16, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R_UNORM8, - "MESA_FORMAT_R_UNORM8", - GL_RED, - GL_UNSIGNED_NORMALIZED, - 8, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_R_UNORM16, - "MESA_FORMAT_R_UNORM16", - GL_RED, - GL_UNSIGNED_NORMALIZED, - 16, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_BGR_UNORM8, /* Name */ - "MESA_FORMAT_BGR_UNORM8", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 3 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGB_UNORM8, /* Name */ - "MESA_FORMAT_RGB_UNORM8", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 3 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGBA_UNORM16, - "MESA_FORMAT_RGBA_UNORM16", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBX_UNORM16, - "MESA_FORMAT_RGBX_UNORM16", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_Z_UNORM16, /* Name */ - "MESA_FORMAT_Z_UNORM16", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 16, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z_UNORM32, /* Name */ - "MESA_FORMAT_Z_UNORM32", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_S_UINT8, /* Name */ - "MESA_FORMAT_S_UINT8", /* StrName */ - GL_STENCIL_INDEX, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - - /* Packed signed/normalized formats */ - { - MESA_FORMAT_A8B8G8R8_SNORM, - "MESA_FORMAT_A8B8G8R8_SNORM", - GL_RGBA, - GL_SIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_X8B8G8R8_SNORM, - "MESA_FORMAT_X8B8G8R8_SNORM", - GL_RGB, - GL_SIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 /* 4 bpp, but no alpha */ - }, - { - MESA_FORMAT_R8G8B8A8_SNORM, - "MESA_FORMAT_R8G8B8A8_SNORM", - GL_RGBA, - GL_SIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R8G8B8X8_SNORM, - "MESA_FORMAT_R8G8B8X8_SNORM", - GL_RGB, - GL_SIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R16G16_SNORM, - "MESA_FORMAT_R16G16_SNORM", - GL_RG, - GL_SIGNED_NORMALIZED, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_G16R16_SNORM, - "MESA_FORMAT_G16R16_SNORM", - GL_RG, - GL_SIGNED_NORMALIZED, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R8G8_SNORM, - "MESA_FORMAT_R8G8_SNORM", - GL_RG, - GL_SIGNED_NORMALIZED, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_G8R8_SNORM, - "MESA_FORMAT_G8R8_SNORM", - GL_RG, - GL_SIGNED_NORMALIZED, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_L8A8_SNORM, - "MESA_FORMAT_L8A8_SNORM", - GL_LUMINANCE_ALPHA, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 8, - 8, 0, 0, 0, 0, - 1, 1, 2 - }, - - /* Array signed/normalized formats */ - { - MESA_FORMAT_A_SNORM8, - "MESA_FORMAT_A_SNORM8", - GL_ALPHA, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 8, - 0, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_A_SNORM16, - "MESA_FORMAT_A_SNORM16", - GL_ALPHA, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 16, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_L_SNORM8, - "MESA_FORMAT_L_SNORM8", - GL_LUMINANCE, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 0, - 8, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_L_SNORM16, - "MESA_FORMAT_L_SNORM16", - GL_LUMINANCE, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 0, - 16, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_I_SNORM8, - "MESA_FORMAT_I_SNORM8", - GL_INTENSITY, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 0, - 0, 8, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_I_SNORM16, - "MESA_FORMAT_I_SNORM16", - GL_INTENSITY, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 0, - 0, 16, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_R_SNORM8, /* Name */ - "MESA_FORMAT_R_SNORM8", /* StrName */ - GL_RED, /* BaseFormat */ - GL_SIGNED_NORMALIZED, /* DataType */ - 8, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_R_SNORM16, - "MESA_FORMAT_R_SNORM16", - GL_RED, - GL_SIGNED_NORMALIZED, - 16, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_LA_SNORM16, - "MESA_FORMAT_LA_SNORM16", - GL_LUMINANCE_ALPHA, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 16, - 16, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RGB_SNORM16, - "MESA_FORMAT_RGB_SNORM16", - GL_RGB, - GL_SIGNED_NORMALIZED, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 6 - }, - { - MESA_FORMAT_RGBA_SNORM16, - "MESA_FORMAT_RGBA_SNORM16", - GL_RGBA, - GL_SIGNED_NORMALIZED, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBX_SNORM16, - "MESA_FORMAT_RGBX_SNORM16", - GL_RGB, - GL_SIGNED_NORMALIZED, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - - /* Packed sRGB formats */ - { - MESA_FORMAT_A8B8G8R8_SRGB, - "MESA_FORMAT_A8B8G8R8_SRGB", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_B8G8R8A8_SRGB, - "MESA_FORMAT_B8G8R8A8_SRGB", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_B8G8R8X8_SRGB, - "MESA_FORMAT_B8G8R8X8_SRGB", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R8G8B8A8_SRGB, - "MESA_FORMAT_R8G8B8A8_SRGB", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R8G8B8X8_SRGB, - "MESA_FORMAT_R8G8B8X8_SRGB", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_L8A8_SRGB, - "MESA_FORMAT_L8A8_SRGB", - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_NORMALIZED, - 0, 0, 0, 8, - 8, 0, 0, 0, 0, - 1, 1, 2 - }, - - /* Array sRGB formats */ - { - MESA_FORMAT_L_SRGB8, - "MESA_FORMAT_L_SRGB8", - GL_LUMINANCE, - GL_UNSIGNED_NORMALIZED, - 0, 0, 0, 0, - 8, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_BGR_SRGB8, - "MESA_FORMAT_BGR_SRGB8", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 3 - }, - - /* Packed float formats */ - { - MESA_FORMAT_R9G9B9E5_FLOAT, - "MESA_FORMAT_RGB9_E5", - GL_RGB, - GL_FLOAT, - 9, 9, 9, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R11G11B10_FLOAT, - "MESA_FORMAT_R11G11B10_FLOAT", - GL_RGB, - GL_FLOAT, - 11, 11, 10, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_Z32_FLOAT_S8X24_UINT, /* Name */ - "MESA_FORMAT_Z32_FLOAT_S8X24_UINT", /* StrName */ - GL_DEPTH_STENCIL, /* BaseFormat */ - /* DataType here is used to answer GL_TEXTURE_DEPTH_TYPE queries, and is - * never used for stencil because stencil is always GL_UNSIGNED_INT. - */ - GL_FLOAT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 32, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 8 /* BlockWidth/Height,Bytes */ - }, - - /* Array float formats */ - { - MESA_FORMAT_A_FLOAT16, - "MESA_FORMAT_A_FLOAT16", - GL_ALPHA, - GL_FLOAT, - 0, 0, 0, 16, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_A_FLOAT32, - "MESA_FORMAT_A_FLOAT32", - GL_ALPHA, - GL_FLOAT, - 0, 0, 0, 32, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_L_FLOAT16, - "MESA_FORMAT_L_FLOAT16", - GL_LUMINANCE, - GL_FLOAT, - 0, 0, 0, 0, - 16, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_L_FLOAT32, - "MESA_FORMAT_L_FLOAT32", - GL_LUMINANCE, - GL_FLOAT, - 0, 0, 0, 0, - 32, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_LA_FLOAT16, - "MESA_FORMAT_LA_FLOAT16", - GL_LUMINANCE_ALPHA, - GL_FLOAT, - 0, 0, 0, 16, - 16, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_LA_FLOAT32, - "MESA_FORMAT_LA_FLOAT32", - GL_LUMINANCE_ALPHA, - GL_FLOAT, - 0, 0, 0, 32, - 32, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_I_FLOAT16, - "MESA_FORMAT_I_FLOAT16", - GL_INTENSITY, - GL_FLOAT, - 0, 0, 0, 0, - 0, 16, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_I_FLOAT32, - "MESA_FORMAT_I_FLOAT32", - GL_INTENSITY, - GL_FLOAT, - 0, 0, 0, 0, - 0, 32, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R_FLOAT16, - "MESA_FORMAT_R_FLOAT16", - GL_RED, - GL_FLOAT, - 16, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_R_FLOAT32, - "MESA_FORMAT_R_FLOAT32", - GL_RED, - GL_FLOAT, - 32, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RG_FLOAT16, - "MESA_FORMAT_RG_FLOAT16", - GL_RG, - GL_FLOAT, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RG_FLOAT32, - "MESA_FORMAT_RG_FLOAT32", - GL_RG, - GL_FLOAT, - 32, 32, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGB_FLOAT16, - "MESA_FORMAT_RGB_FLOAT16", - GL_RGB, - GL_FLOAT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 6 - }, - { - MESA_FORMAT_RGB_FLOAT32, - "MESA_FORMAT_RGB_FLOAT32", - GL_RGB, - GL_FLOAT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 12 - }, - { - MESA_FORMAT_RGBA_FLOAT16, - "MESA_FORMAT_RGBA_FLOAT16", - GL_RGBA, - GL_FLOAT, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBA_FLOAT32, - "MESA_FORMAT_RGBA_FLOAT32", - GL_RGBA, - GL_FLOAT, - 32, 32, 32, 32, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - { - MESA_FORMAT_RGBX_FLOAT16, - "MESA_FORMAT_RGBX_FLOAT16", - GL_RGB, - GL_FLOAT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBX_FLOAT32, - "MESA_FORMAT_RGBX_FLOAT32", - GL_RGB, - GL_FLOAT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - { - MESA_FORMAT_Z_FLOAT32, /* Name */ - "MESA_FORMAT_Z_FLOAT32", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_FLOAT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - - /* Packed signed/unsigned non-normalized integer formats */ - { - MESA_FORMAT_B10G10R10A2_UINT, - "MESA_FORMAT_B10G10R10A2_UINT", - GL_RGBA, - GL_UNSIGNED_INT, - 10, 10, 10, 2, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R10G10B10A2_UINT, - "MESA_FORMAT_R10G10B10A2_UINT", - GL_RGBA, - GL_UNSIGNED_INT, - 10, 10, 10, 2, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - - /* Array signed/unsigned non-normalized integer formats */ - { - MESA_FORMAT_A_UINT8, - "MESA_FORMAT_A_UINT8", - GL_ALPHA, - GL_UNSIGNED_INT, - 0, 0, 0, 8, - 0, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_A_UINT16, - "MESA_FORMAT_A_UINT16", - GL_ALPHA, - GL_UNSIGNED_INT, - 0, 0, 0, 16, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_A_UINT32, - "MESA_FORMAT_A_UINT32", - GL_ALPHA, - GL_UNSIGNED_INT, - 0, 0, 0, 32, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_A_SINT8, - "MESA_FORMAT_A_SINT8", - GL_ALPHA, - GL_INT, - 0, 0, 0, 8, - 0, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_A_SINT16, - "MESA_FORMAT_A_SINT16", - GL_ALPHA, - GL_INT, - 0, 0, 0, 16, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_A_SINT32, - "MESA_FORMAT_A_SINT32", - GL_ALPHA, - GL_INT, - 0, 0, 0, 32, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_I_UINT8, - "MESA_FORMAT_I_UINT8", - GL_INTENSITY, - GL_UNSIGNED_INT, - 0, 0, 0, 0, - 0, 8, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_I_UINT16, - "MESA_FORMAT_I_UINT16", - GL_INTENSITY, - GL_UNSIGNED_INT, - 0, 0, 0, 0, - 0, 16, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_I_UINT32, - "MESA_FORMAT_I_UINT32", - GL_INTENSITY, - GL_UNSIGNED_INT, - 0, 0, 0, 0, - 0, 32, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_I_SINT8, - "MESA_FORMAT_I_SINT8", - GL_INTENSITY, - GL_INT, - 0, 0, 0, 0, - 0, 8, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_I_SINT16, - "MESA_FORMAT_I_SINT16", - GL_INTENSITY, - GL_INT, - 0, 0, 0, 0, - 0, 16, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_I_SINT32, - "MESA_FORMAT_I_SINT32", - GL_INTENSITY, - GL_INT, - 0, 0, 0, 0, - 0, 32, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_L_UINT8, - "MESA_FORMAT_L_UINT8", - GL_LUMINANCE, - GL_UNSIGNED_INT, - 0, 0, 0, 0, - 8, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_L_UINT16, - "MESA_FORMAT_L_UINT16", - GL_LUMINANCE, - GL_UNSIGNED_INT, - 0, 0, 0, 0, - 16, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_L_UINT32, - "MESA_FORMAT_L_UINT32", - GL_LUMINANCE, - GL_UNSIGNED_INT, - 0, 0, 0, 0, - 32, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_L_SINT8, - "MESA_FORMAT_L_SINT8", - GL_LUMINANCE, - GL_INT, - 0, 0, 0, 0, - 8, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_L_SINT16, - "MESA_FORMAT_L_SINT16", - GL_LUMINANCE, - GL_INT, - 0, 0, 0, 0, - 16, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_L_SINT32, - "MESA_FORMAT_L_SINT32", - GL_LUMINANCE, - GL_INT, - 0, 0, 0, 0, - 32, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_LA_UINT8, - "MESA_FORMAT_LA_UINT8", - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_INT, - 0, 0, 0, 8, - 8, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_LA_UINT16, - "MESA_FORMAT_LA_UINT16", - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_INT, - 0, 0, 0, 16, - 16, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_LA_UINT32, - "MESA_FORMAT_LA_UINT32", - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_INT, - 0, 0, 0, 32, - 32, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_LA_SINT8, - "MESA_FORMAT_LA_SINT8", - GL_LUMINANCE_ALPHA, - GL_INT, - 0, 0, 0, 8, - 8, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_LA_SINT16, - "MESA_FORMAT_LA_SINT16", - GL_LUMINANCE_ALPHA, - GL_INT, - 0, 0, 0, 16, - 16, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_LA_SINT32, - "MESA_FORMAT_LA_SINT32", - GL_LUMINANCE_ALPHA, - GL_INT, - 0, 0, 0, 32, - 32, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_R_UINT8, - "MESA_FORMAT_R_UINT8", - GL_RED, - GL_UNSIGNED_INT, - 8, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_R_UINT16, - "MESA_FORMAT_R_UINT16", - GL_RED, - GL_UNSIGNED_INT, - 16, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_R_UINT32, - "MESA_FORMAT_R_UINT32", - GL_RED, - GL_UNSIGNED_INT, - 32, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_R_SINT8, - "MESA_FORMAT_R_SINT8", - GL_RED, - GL_INT, - 8, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_R_SINT16, - "MESA_FORMAT_R_SINT16", - GL_RED, - GL_INT, - 16, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_R_SINT32, - "MESA_FORMAT_R_SINT32", - GL_RED, - GL_INT, - 32, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RG_UINT8, - "MESA_FORMAT_RG_UINT8", - GL_RG, - GL_UNSIGNED_INT, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_RG_UINT16, - "MESA_FORMAT_RG_UINT16", - GL_RG, - GL_UNSIGNED_INT, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RG_UINT32, - "MESA_FORMAT_RG_UINT32", - GL_RG, - GL_UNSIGNED_INT, - 32, 32, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RG_SINT8, - "MESA_FORMAT_RG_SINT8", - GL_RG, - GL_INT, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_RG_SINT16, - "MESA_FORMAT_RG_SINT16", - GL_RG, - GL_INT, - 16, 16, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RG_SINT32, - "MESA_FORMAT_RG_SINT32", - GL_RG, - GL_INT, - 32, 32, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGB_UINT8, - "MESA_FORMAT_RGB_UINT8", - GL_RGB, - GL_UNSIGNED_INT, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 3 - }, - { - MESA_FORMAT_RGB_UINT16, - "MESA_FORMAT_RGB_UINT16", - GL_RGB, - GL_UNSIGNED_INT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 6 - }, - { - MESA_FORMAT_RGB_UINT32, - "MESA_FORMAT_RGB_UINT32", - GL_RGB, - GL_UNSIGNED_INT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 12 - }, - { - MESA_FORMAT_RGB_SINT8, - "MESA_FORMAT_RGB_SINT8", - GL_RGB, - GL_INT, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 3 - }, - { - MESA_FORMAT_RGB_SINT16, - "MESA_FORMAT_RGB_SINT16", - GL_RGB, - GL_INT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 6 - }, - { - MESA_FORMAT_RGB_SINT32, - "MESA_FORMAT_RGB_SINT32", - GL_RGB, - GL_INT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 12 - }, - { - MESA_FORMAT_RGBA_UINT8, - "MESA_FORMAT_RGBA_UINT8", - GL_RGBA, - GL_UNSIGNED_INT, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RGBA_UINT16, - "MESA_FORMAT_RGBA_UINT16", - GL_RGBA, - GL_UNSIGNED_INT, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBA_UINT32, - "MESA_FORMAT_RGBA_UINT32", - GL_RGBA, - GL_UNSIGNED_INT, - 32, 32, 32, 32, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - { - MESA_FORMAT_RGBA_SINT8, - "MESA_FORMAT_RGBA_SINT8", - GL_RGBA, - GL_INT, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RGBA_SINT16, - "MESA_FORMAT_RGBA_SINT16", - GL_RGBA, - GL_INT, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBA_SINT32, - "MESA_FORMAT_RGBA_SINT32", - GL_RGBA, - GL_INT, - 32, 32, 32, 32, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - { - MESA_FORMAT_RGBX_UINT8, - "MESA_FORMAT_RGBX_UINT8", - GL_RGB, - GL_UNSIGNED_INT, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RGBX_UINT16, - "MESA_FORMAT_RGBX_UINT16", - GL_RGB, - GL_UNSIGNED_INT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBX_UINT32, - "MESA_FORMAT_RGBX_UINT32", - GL_RGB, - GL_UNSIGNED_INT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - { - MESA_FORMAT_RGBX_SINT8, - "MESA_FORMAT_RGBX_SINT8", - GL_RGB, - GL_INT, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_RGBX_SINT16, - "MESA_FORMAT_RGBX_SINT16", - GL_RGB, - GL_INT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGBX_SINT32, - "MESA_FORMAT_RGBX_SINT32", - GL_RGB, - GL_INT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - - /* DXT compressed formats */ - { - MESA_FORMAT_RGB_DXT1, /* Name */ - "MESA_FORMAT_RGB_DXT1", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_DXT1, - "MESA_FORMAT_RGBA_DXT1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_DXT3, - "MESA_FORMAT_RGBA_DXT3", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_DXT5, - "MESA_FORMAT_RGBA_DXT5", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - - /* DXT sRGB compressed formats */ - { - MESA_FORMAT_SRGB_DXT1, /* Name */ - "MESA_FORMAT_SRGB_DXT1", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_SRGBA_DXT1, - "MESA_FORMAT_SRGBA_DXT1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_SRGBA_DXT3, - "MESA_FORMAT_SRGBA_DXT3", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_SRGBA_DXT5, - "MESA_FORMAT_SRGBA_DXT5", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - - /* FXT1 compressed formats */ - { - MESA_FORMAT_RGB_FXT1, - "MESA_FORMAT_RGB_FXT1", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 0, /* approx Red/Green/BlueBits */ - 0, 0, 0, 0, 0, - 8, 4, 16 /* 16 bytes per 8x4 block */ - }, - { - MESA_FORMAT_RGBA_FXT1, - "MESA_FORMAT_RGBA_FXT1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 1, /* approx Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, - 8, 4, 16 /* 16 bytes per 8x4 block */ - }, - - /* RGTC compressed formats */ - { - MESA_FORMAT_R_RGTC1_UNORM, - "MESA_FORMAT_R_RGTC1_UNORM", - GL_RED, - GL_UNSIGNED_NORMALIZED, - 8, 0, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_R_RGTC1_SNORM, - "MESA_FORMAT_R_RGTC1_SNORM", - GL_RED, - GL_SIGNED_NORMALIZED, - 8, 0, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RG_RGTC2_UNORM, - "MESA_FORMAT_RG_RGTC2_UNORM", - GL_RG, - GL_UNSIGNED_NORMALIZED, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RG_RGTC2_SNORM, - "MESA_FORMAT_RG_RGTC2_SNORM", - GL_RG, - GL_SIGNED_NORMALIZED, - 8, 8, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - - /* LATC1/2 compressed formats */ - { - MESA_FORMAT_L_LATC1_UNORM, - "MESA_FORMAT_L_LATC1_UNORM", - GL_LUMINANCE, - GL_UNSIGNED_NORMALIZED, - 0, 0, 0, 0, - 4, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_L_LATC1_SNORM, - "MESA_FORMAT_L_LATC1_SNORM", - GL_LUMINANCE, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 0, - 4, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_LA_LATC2_UNORM, - "MESA_FORMAT_LA_LATC2_UNORM", - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_NORMALIZED, - 0, 0, 0, 4, - 4, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_LA_LATC2_SNORM, - "MESA_FORMAT_LA_LATC2_SNORM", - GL_LUMINANCE_ALPHA, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 4, - 4, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - - /* ETC1/2 compressed formats */ - { - MESA_FORMAT_ETC1_RGB8, - "MESA_FORMAT_ETC1_RGB8", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_RGB8, - "MESA_FORMAT_ETC2_RGB8", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_SRGB8, - "MESA_FORMAT_ETC2_SRGB8", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_RGBA8_EAC, - "MESA_FORMAT_ETC2_RGBA8_EAC", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC, - "MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_R11_EAC, - "MESA_FORMAT_ETC2_R11_EAC", - GL_RED, - GL_UNSIGNED_NORMALIZED, - 11, 0, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_RG11_EAC, - "MESA_FORMAT_ETC2_RG11_EAC", - GL_RG, - GL_UNSIGNED_NORMALIZED, - 11, 11, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_SIGNED_R11_EAC, - "MESA_FORMAT_ETC2_SIGNED_R11_EAC", - GL_RED, - GL_SIGNED_NORMALIZED, - 11, 0, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_SIGNED_RG11_EAC, - "MESA_FORMAT_ETC2_SIGNED_RG11_EAC", - GL_RG, - GL_SIGNED_NORMALIZED, - 11, 11, 0, 0, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1, - "MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 1, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1, - "MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 1, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, + uint8_t Swizzle[4]; }; - +#include "format_info.c" static const struct gl_format_info * _mesa_get_format_info(mesa_format format) @@ -1881,7 +148,7 @@ _mesa_get_format_bits(mesa_format format, GLenum pname) case GL_TEXTURE_LUMINANCE_SIZE: return info->LuminanceBits; case GL_INDEX_BITS: - return info->IndexBits; + return 0; case GL_DEPTH_BITS: case GL_TEXTURE_DEPTH_SIZE_ARB: case GL_RENDERBUFFER_DEPTH_SIZE_EXT: @@ -1915,6 +182,21 @@ _mesa_get_format_max_bits(mesa_format format) /** + * Return the layout type of the given format. + * The return value will be one of: + * MESA_FORMAT_LAYOUT_ARRAY + * MESA_FORMAT_LAYOUT_PACKED + * MESA_FORMAT_LAYOUT_OTHER + */ +extern enum mesa_format_layout +_mesa_get_format_layout(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + return info->Layout; +} + + +/** * Return the data type (or more specifically, the data representation) * for the given format. * The return value will be one of: @@ -1961,6 +243,33 @@ _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh) } +/** + * Returns the an array of four numbers representing the transformation + * from the RGBA or SZ colorspace to the given format. For array formats, + * the i'th RGBA component is given by: + * + * if (swizzle[i] <= MESA_FORMAT_SWIZZLE_W) + * comp = data[swizzle[i]]; + * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_ZERO) + * comp = 0; + * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_ONE) + * comp = 1; + * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_NONE) + * // data does not contain a channel of this format + * + * For packed formats, the swizzle gives the number of components left of + * the least significant bit. + * + * Compressed formats have no swizzle. + */ +void +_mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle)); +} + + /** Is the given format a compressed format? */ GLboolean _mesa_is_format_compressed(mesa_format format) @@ -2331,7 +640,6 @@ check_format_to_type_and_comps(void) } } - /** * Do sanity checking of the format info table. */ diff --git a/mesalib/src/mesa/main/formats.csv b/mesalib/src/mesa/main/formats.csv new file mode 100644 index 000000000..eade6facd --- /dev/null +++ b/mesalib/src/mesa/main/formats.csv @@ -0,0 +1,282 @@ +########################################################################### +# +# Copyright 2009-2010 VMware, Inc. +# Copyright 2014 Intel Corporation +# 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 THE AUTHORS 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. +# +########################################################################### + +# This CSV file has the input data for gen_format.h and gen_format.c +# +# Each format entry contains: +# - name, per enum mesa_format +# - layout +# - pixel block's width +# - pixel block's height +# - channel encoding (only meaningful for array or packed layout), containing for each +# channel the following information: +# - type, one of +# - 'x': void +# - 'u': unsigned +# - 's': signed +# - 'h': fixed +# - 'f': FLOAT +# - optionally followed by 'n' if it is normalized +# - number of bits +# - channel swizzle +# - color space: rgb, srgb, yub, sz + +# None +# Described as regular uint_8 bytes, i.e. MESA_FORMAT_R8_USCALED +MESA_FORMAT_NONE , other , 1, 1, x8 , , , , 0001, rgb + +# Packed unorm formats +MESA_FORMAT_A8B8G8R8_UNORM , packed, 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb +MESA_FORMAT_X8B8G8R8_UNORM , packed, 1, 1, x8 , un8 , un8 , un8 , wzy1, rgb +MESA_FORMAT_R8G8B8A8_UNORM , packed, 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb +MESA_FORMAT_R8G8B8X8_UNORM , packed, 1, 1, un8 , un8 , un8 , x8 , xyz1, rgb +MESA_FORMAT_B8G8R8A8_UNORM , packed, 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb +MESA_FORMAT_B8G8R8X8_UNORM , packed, 1, 1, un8 , un8 , un8 , x8 , zyx1, rgb +MESA_FORMAT_A8R8G8B8_UNORM , packed, 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb +MESA_FORMAT_X8R8G8B8_UNORM , packed, 1, 1, x8 , un8 , un8 , un8 , yzw1, rgb +MESA_FORMAT_L16A16_UNORM , packed, 1, 1, un16, un16, , , xxxy, rgb +MESA_FORMAT_A16L16_UNORM , packed, 1, 1, un16, un16, , , yyyx, rgb +MESA_FORMAT_B5G6R5_UNORM , packed, 1, 1, un5 , un6 , un5 , , zyx1, rgb +MESA_FORMAT_R5G6B5_UNORM , packed, 1, 1, un5 , un6 , un5 , , xyz1, rgb +MESA_FORMAT_B4G4R4A4_UNORM , packed, 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb +MESA_FORMAT_B4G4R4X4_UNORM , packed, 1, 1, un4 , un4 , un4 , x4 , zyx1, rgb +MESA_FORMAT_A4R4G4B4_UNORM , packed, 1, 1, un4 , un4 , un4 , un4 , yzwx, rgb +MESA_FORMAT_A1B5G5R5_UNORM , packed, 1, 1, un1 , un5 , un5 , un5 , wzyx, rgb +MESA_FORMAT_B5G5R5A1_UNORM , packed, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb +MESA_FORMAT_B5G5R5X1_UNORM , packed, 1, 1, un5 , un5 , un5 , x1 , zyx1, rgb +MESA_FORMAT_A1R5G5B5_UNORM , packed, 1, 1, un1 , un5 , un5 , un5 , yzwx, rgb +MESA_FORMAT_L8A8_UNORM , packed, 1, 1, un8 , un8 , , , xxxy, rgb +MESA_FORMAT_A8L8_UNORM , packed, 1, 1, un8 , un8 , , , yyyx, rgb +MESA_FORMAT_R8G8_UNORM , packed, 1, 1, un8 , un8 , , , xy01, rgb +MESA_FORMAT_G8R8_UNORM , packed, 1, 1, un8 , un8 , , , yx01, rgb +MESA_FORMAT_L4A4_UNORM , packed, 1, 1, un4 , un4 , , , xxxy, rgb + +MESA_FORMAT_B2G3R3_UNORM , packed, 1, 1, un2 , un3 , un3 , , zyx1, rgb +MESA_FORMAT_R16G16_UNORM , packed, 1, 1, un16, un16, , , xy01, rgb +MESA_FORMAT_G16R16_UNORM , packed, 1, 1, un16, un16, , , yx01, rgb +MESA_FORMAT_B10G10R10A2_UNORM , packed, 1, 1, un10, un10, un10, un2 , zyxw, rgb +MESA_FORMAT_B10G10R10X2_UNORM , packed, 1, 1, un10, un10, un10, x2 , zyx1, rgb +MESA_FORMAT_R10G10B10A2_UNORM , packed, 1, 1, un10, un10, un10, un2 , xyzw, rgb + +MESA_FORMAT_S8_UINT_Z24_UNORM , packed, 1, 1, un24, u8 , , , xy__, zs +MESA_FORMAT_X8_UINT_Z24_UNORM , packed, 1, 1, un24, x8 , , , x___, zs +MESA_FORMAT_Z24_UNORM_S8_UINT , packed, 1, 1, u8 , un24, , , yx__, zs +MESA_FORMAT_Z24_UNORM_X8_UINT , packed, 1, 1, x8 , un24, , , y___, zs + +MESA_FORMAT_YCBCR , other , 1, 1, x16 , , , , xyzw, yuv +MESA_FORMAT_YCBCR_REV , other , 1, 1, x16 , , , , xyzw, yuv + +# Array normalized formats +MESA_FORMAT_A_UNORM8 , array , 1, 1, un8 , , , , 000x, rgb +MESA_FORMAT_A_UNORM16 , array , 1, 1, un16, , , , 000x, rgb +MESA_FORMAT_L_UNORM8 , array , 1, 1, un8 , , , , xxx1, rgb +MESA_FORMAT_L_UNORM16 , array , 1, 1, un16, , , , xxx1, rgb +MESA_FORMAT_I_UNORM8 , array , 1, 1, un8 , , , , xxxx, rgb +MESA_FORMAT_I_UNORM16 , array , 1, 1, un16, , , , xxxx, rgb +MESA_FORMAT_R_UNORM8 , array , 1, 1, un8 , , , , x001, rgb +MESA_FORMAT_R_UNORM16 , array , 1, 1, un16, , , , x001, rgb +MESA_FORMAT_BGR_UNORM8 , array , 1, 1, un8 , un8 , un8 , , zyx1, rgb +MESA_FORMAT_RGB_UNORM8 , array , 1, 1, un8 , un8 , un8 , , xyz1, rgb +MESA_FORMAT_RGBA_UNORM16 , array , 1, 1, un16, un16, un16, un16, xyzw, rgb +MESA_FORMAT_RGBX_UNORM16 , array , 1, 1, un16, un16, un16, x16 , xyz1, rgb + +MESA_FORMAT_Z_UNORM16 , array , 1, 1, un16, , , , x___, zs +MESA_FORMAT_Z_UNORM32 , array , 1, 1, un32, , , , x___, zs +MESA_FORMAT_S_UINT8 , array , 1, 1, u8 , , , , _x__, zs + +# Packed signed formats +MESA_FORMAT_A8B8G8R8_SNORM , packed, 1, 1, sn8 , sn8 , sn8 , sn8 , wzyx, rgb +MESA_FORMAT_X8B8G8R8_SNORM , packed, 1, 1, x8 , sn8 , sn8 , sn8 , wzy1, rgb +MESA_FORMAT_R8G8B8A8_SNORM , packed, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb +MESA_FORMAT_R8G8B8X8_SNORM , packed, 1, 1, sn8 , sn8 , sn8 , x8 , xyz1, rgb +MESA_FORMAT_R16G16_SNORM , packed, 1, 1, sn16, sn16, , , xy01, rgb +MESA_FORMAT_G16R16_SNORM , packed, 1, 1, sn16, sn16, , , yx01, rgb +MESA_FORMAT_R8G8_SNORM , packed, 1, 1, sn8 , sn8 , , , xy01, rgb +MESA_FORMAT_G8R8_SNORM , packed, 1, 1, sn8 , sn8 , , , yx01, rgb +MESA_FORMAT_L8A8_SNORM , packed, 1, 1, sn8 , sn8 , , , xxxy, rgb + +# Array signed/normalized formats +MESA_FORMAT_A_SNORM8 , array , 1, 1, sn8 , , , , 000x, rgb +MESA_FORMAT_A_SNORM16 , array , 1, 1, sn16, , , , 000x, rgb +MESA_FORMAT_L_SNORM8 , array , 1, 1, sn8 , , , , xxx1, rgb +MESA_FORMAT_L_SNORM16 , array , 1, 1, sn16, , , , xxx1, rgb +MESA_FORMAT_I_SNORM8 , array , 1, 1, sn8 , , , , xxxx, rgb +MESA_FORMAT_I_SNORM16 , array , 1, 1, sn16, , , , xxxx, rgb +MESA_FORMAT_R_SNORM8 , array , 1, 1, sn8 , , , , x001, rgb +MESA_FORMAT_R_SNORM16 , array , 1, 1, sn16, , , , x001, rgb +MESA_FORMAT_LA_SNORM16 , array , 1, 1, sn16, sn16, , , xxxy, rgb +MESA_FORMAT_RGB_SNORM16 , array , 1, 1, sn16, sn16, sn16, , xyz1, rgb +MESA_FORMAT_RGBA_SNORM16 , array , 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb +MESA_FORMAT_RGBX_SNORM16 , array , 1, 1, sn16, sn16, sn16, x16 , xyz1, rgb + +# Packed sRGB formats +MESA_FORMAT_A8B8G8R8_SRGB , packed, 1, 1, un8 , un8 , un8 , un8 , wzyx, srgb +MESA_FORMAT_B8G8R8A8_SRGB , packed, 1, 1, un8 , un8 , un8 , un8 , zyxw, srgb +MESA_FORMAT_B8G8R8X8_SRGB , packed, 1, 1, un8 , un8 , un8 , x8 , zyx1, srgb +MESA_FORMAT_R8G8B8A8_SRGB , packed, 1, 1, un8 , un8 , un8 , un8 , xyzw, srgb +MESA_FORMAT_R8G8B8X8_SRGB , packed, 1, 1, un8 , un8 , un8 , x8 , xyz1, srgb +MESA_FORMAT_L8A8_SRGB , packed, 1, 1, un8 , un8 , , , xxxy, srgb + +# Array sRGB formats +MESA_FORMAT_L_SRGB8 , array , 1, 1, un8 , , , , xxx1, srgb +MESA_FORMAT_BGR_SRGB8 , array , 1, 1, un8 , un8 , un8 , , zyx1, srgb + +# Packed float formats +MESA_FORMAT_R9G9B9E5_FLOAT , other , 1, 1, f9 , f9 , f9 , x5 , xyz1, rgb +MESA_FORMAT_R11G11B10_FLOAT , packed, 1, 1, f11 , f11 , f10 , , xyz1, rgb +MESA_FORMAT_Z32_FLOAT_S8X24_UINT , packed, 1, 1, u8 , x24 , f32 , , zx__, zs + +# Array float formats +MESA_FORMAT_A_FLOAT16 , array , 1, 1, f16 , , , , 000x, rgb +MESA_FORMAT_A_FLOAT32 , array , 1, 1, f32 , , , , 000x, rgb +MESA_FORMAT_L_FLOAT16 , array , 1, 1, f16 , , , , xxx1, rgb +MESA_FORMAT_L_FLOAT32 , array , 1, 1, f32 , , , , xxx1, rgb +MESA_FORMAT_LA_FLOAT16 , array , 1, 1, f16 , f16 , , , xxxy, rgb +MESA_FORMAT_LA_FLOAT32 , array , 1, 1, f32 , f32 , , , xxxy, rgb +MESA_FORMAT_I_FLOAT16 , array , 1, 1, f16 , , , , xxxx, rgb +MESA_FORMAT_I_FLOAT32 , array , 1, 1, f32 , , , , xxxx, rgb +MESA_FORMAT_R_FLOAT16 , array , 1, 1, f16 , , , , x001, rgb +MESA_FORMAT_R_FLOAT32 , array , 1, 1, f32 , , , , x001, rgb +MESA_FORMAT_RG_FLOAT16 , array , 1, 1, f16 , f16 , , , xy01, rgb +MESA_FORMAT_RG_FLOAT32 , array , 1, 1, f32 , f32 , , , xy01, rgb +MESA_FORMAT_RGB_FLOAT16 , array , 1, 1, f16 , f16 , f16 , , xyz1, rgb +MESA_FORMAT_RGB_FLOAT32 , array , 1, 1, f32 , f32 , f32 , , xyz1, rgb +MESA_FORMAT_RGBA_FLOAT16 , array , 1, 1, f16 , f16 , f16 , f16 , xyzw, rgb +MESA_FORMAT_RGBA_FLOAT32 , array , 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb +MESA_FORMAT_RGBX_FLOAT16 , array , 1, 1, f16 , f16 , f16 , x16 , xyz1, rgb +MESA_FORMAT_RGBX_FLOAT32 , array , 1, 1, f32 , f32 , f32 , x32 , xyz1, rgb +MESA_FORMAT_Z_FLOAT32 , array , 1, 1, f32 , , , , x___, zs + +# Packed signed/unsigned non-normalized integer formats +MESA_FORMAT_B10G10R10A2_UINT , packed, 1, 1, u10 , u10 , u10 , u2 , zyxw, rgb +MESA_FORMAT_R10G10B10A2_UINT , packed, 1, 1, u10 , u10 , u10 , u2 , xyzw, rgb + +# Array signed/unsigned non-normalized integer formats +MESA_FORMAT_A_UINT8 , array , 1, 1, u8 , , , , 000x, rgb +MESA_FORMAT_A_UINT16 , array , 1, 1, u16 , , , , 000x, rgb +MESA_FORMAT_A_UINT32 , array , 1, 1, u32 , , , , 000x, rgb +MESA_FORMAT_A_SINT8 , array , 1, 1, s8 , , , , 000x, rgb +MESA_FORMAT_A_SINT16 , array , 1, 1, s16 , , , , 000x, rgb +MESA_FORMAT_A_SINT32 , array , 1, 1, s32 , , , , 000x, rgb + +MESA_FORMAT_I_UINT8 , array , 1, 1, u8 , , , , xxxx, rgb +MESA_FORMAT_I_UINT16 , array , 1, 1, u16 , , , , xxxx, rgb +MESA_FORMAT_I_UINT32 , array , 1, 1, u32 , , , , xxxx, rgb +MESA_FORMAT_I_SINT8 , array , 1, 1, s8 , , , , xxxx, rgb +MESA_FORMAT_I_SINT16 , array , 1, 1, s16 , , , , xxxx, rgb +MESA_FORMAT_I_SINT32 , array , 1, 1, s32 , , , , xxxx, rgb + +MESA_FORMAT_L_UINT8 , array , 1, 1, u8 , , , , xxx1, rgb +MESA_FORMAT_L_UINT16 , array , 1, 1, u16 , , , , xxx1, rgb +MESA_FORMAT_L_UINT32 , array , 1, 1, u32 , , , , xxx1, rgb +MESA_FORMAT_L_SINT8 , array , 1, 1, s8 , , , , xxx1, rgb +MESA_FORMAT_L_SINT16 , array , 1, 1, s16 , , , , xxx1, rgb +MESA_FORMAT_L_SINT32 , array , 1, 1, s32 , , , , xxx1, rgb + +MESA_FORMAT_LA_UINT8 , array , 1, 1, u8 , u8 , , , xxxy, rgb +MESA_FORMAT_LA_UINT16 , array , 1, 1, u16 , u16 , , , xxxy, rgb +MESA_FORMAT_LA_UINT32 , array , 1, 1, u32 , u32 , , , xxxy, rgb +MESA_FORMAT_LA_SINT8 , array , 1, 1, s8 , s8 , , , xxxy, rgb +MESA_FORMAT_LA_SINT16 , array , 1, 1, s16 , s16 , , , xxxy, rgb +MESA_FORMAT_LA_SINT32 , array , 1, 1, s32 , s32 , , , xxxy, rgb + +MESA_FORMAT_R_UINT8 , array , 1, 1, u8 , , , , x001, rgb +MESA_FORMAT_R_UINT16 , array , 1, 1, u16 , , , , x001, rgb +MESA_FORMAT_R_UINT32 , array , 1, 1, u32 , , , , x001, rgb +MESA_FORMAT_R_SINT8 , array , 1, 1, s8 , , , , x001, rgb +MESA_FORMAT_R_SINT16 , array , 1, 1, s16 , , , , x001, rgb +MESA_FORMAT_R_SINT32 , array , 1, 1, s32 , , , , x001, rgb + +MESA_FORMAT_RG_UINT8 , array , 1, 1, u8 , u8 , , , xy01, rgb +MESA_FORMAT_RG_UINT16 , array , 1, 1, u16 , u16 , , , xy01, rgb +MESA_FORMAT_RG_UINT32 , array , 1, 1, u32 , u32 , , , xy01, rgb +MESA_FORMAT_RG_SINT8 , array , 1, 1, s8 , s8 , , , xy01, rgb +MESA_FORMAT_RG_SINT16 , array , 1, 1, s16 , s16 , , , xy01, rgb +MESA_FORMAT_RG_SINT32 , array , 1, 1, s32 , s32 , , , xy01, rgb + +MESA_FORMAT_RGB_UINT8 , array , 1, 1, u8 , u8 , u8 , , xyz1, rgb +MESA_FORMAT_RGB_UINT16 , array , 1, 1, u16 , u16 , u16 , , xyz1, rgb +MESA_FORMAT_RGB_UINT32 , array , 1, 1, u32 , u32 , u32 , , xyz1, rgb +MESA_FORMAT_RGB_SINT8 , array , 1, 1, s8 , s8 , s8 , , xyz1, rgb +MESA_FORMAT_RGB_SINT16 , array , 1, 1, s16 , s16 , s16 , , xyz1, rgb +MESA_FORMAT_RGB_SINT32 , array , 1, 1, s32 , s32 , s32 , , xyz1, rgb + +MESA_FORMAT_RGBA_UINT8 , array , 1, 1, u8 , u8 , u8 , u8 , xyzw, rgb +MESA_FORMAT_RGBA_UINT16 , array , 1, 1, u16 , u16 , u16 , u16 , xyzw, rgb +MESA_FORMAT_RGBA_UINT32 , array , 1, 1, u32 , u32 , u32 , u32 , xyzw, rgb +MESA_FORMAT_RGBA_SINT8 , array , 1, 1, s8 , s8 , s8 , s8 , xyzw, rgb +MESA_FORMAT_RGBA_SINT16 , array , 1, 1, s16 , s16 , s16 , s16 , xyzw, rgb +MESA_FORMAT_RGBA_SINT32 , array , 1, 1, s32 , s32 , s32 , s32 , xyzw, rgb + +MESA_FORMAT_RGBX_UINT8 , array , 1, 1, u8 , u8 , u8 , x8 , xyz1, rgb +MESA_FORMAT_RGBX_UINT16 , array , 1, 1, u16 , u16 , u16 , x16 , xyz1, rgb +MESA_FORMAT_RGBX_UINT32 , array , 1, 1, u32 , u32 , u32 , x32 , xyz1, rgb +MESA_FORMAT_RGBX_SINT8 , array , 1, 1, s8 , s8 , s8 , x8 , xyz1, rgb +MESA_FORMAT_RGBX_SINT16 , array , 1, 1, s16 , s16 , s16 , x16 , xyz1, rgb +MESA_FORMAT_RGBX_SINT32 , array , 1, 1, s32 , s32 , s32 , x32 , xyz1, rgb + +# DTX compressed formats +MESA_FORMAT_RGB_DXT1 , s3tc , 4, 4, x64 , , , , xyz1, rgb +MESA_FORMAT_RGBA_DXT1 , s3tc , 4, 4, x64 , , , , xyzw, rgb +MESA_FORMAT_RGBA_DXT3 , s3tc , 4, 4, x128, , , , xyzw, rgb +MESA_FORMAT_RGBA_DXT5 , s3tc , 4, 4, x128, , , , xyzw, rgb + +# DTX sRGB compressed formats +MESA_FORMAT_SRGB_DXT1 , s3tc , 4, 4, x64 , , , , xyz1, srgb +MESA_FORMAT_SRGBA_DXT1 , s3tc , 4, 4, x64 , , , , xyzw, srgb +MESA_FORMAT_SRGBA_DXT3 , s3tc , 4, 4, x128, , , , xyzw, srgb +MESA_FORMAT_SRGBA_DXT5 , s3tc , 4, 4, x128, , , , xyzw, srgb + +# FXT1 compressed formats +MESA_FORMAT_RGB_FXT1 , fxt1 , 8, 4, x128, , , , xyz1, rgb +MESA_FORMAT_RGBA_FXT1 , fxt1 , 8, 4, x128, , , , xyzw, rgb + +# RGTC compressed formats +MESA_FORMAT_R_RGTC1_UNORM , rgtc , 4, 4, x64 , , , , x001, rgb +MESA_FORMAT_R_RGTC1_SNORM , rgtc , 4, 4, x64 , , , , x001, rgb +MESA_FORMAT_RG_RGTC2_UNORM , rgtc , 4, 4, x128, , , , xy01, rgb +MESA_FORMAT_RG_RGTC2_SNORM , rgtc , 4, 4, x128, , , , xy01, rgb + +# LATC1/2 compressed formats +MESA_FORMAT_L_LATC1_UNORM , rgtc , 4, 4, x64 , , , , xxx1, rgb +MESA_FORMAT_L_LATC1_SNORM , rgtc , 4, 4, x64 , , , , xxx1, rgb +MESA_FORMAT_LA_LATC2_UNORM , rgtc , 4, 4, x128, , , , xxxy, rgb +MESA_FORMAT_LA_LATC2_SNORM , rgtc , 4, 4, x128, , , , xxxy, rgb + +# ETC1/2 compressed formats +MESA_FORMAT_ETC1_RGB8 , etc1 , 4, 4, x64 , , , , xyz1, rgb +MESA_FORMAT_ETC2_RGB8 , etc2 , 4, 4, x64 , , , , xyz1, rgb +MESA_FORMAT_ETC2_SRGB8 , etc2 , 4, 4, x64 , , , , xyz1, srgb +MESA_FORMAT_ETC2_RGBA8_EAC , etc2 , 4, 4, x128, , , , xyzw, rgb +MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC , etc2 , 4, 4, x128, , , , xyzw, srgb +MESA_FORMAT_ETC2_R11_EAC , etc2 , 4, 4, x64 , , , , x001, rgb +MESA_FORMAT_ETC2_RG11_EAC , etc2 , 4, 4, x128, , , , xy01, rgb +MESA_FORMAT_ETC2_SIGNED_R11_EAC , etc2 , 4, 4, x64 , , , , x001, rgb +MESA_FORMAT_ETC2_SIGNED_RG11_EAC , etc2 , 4, 4, x128, , , , xy01, rgb +MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1 , etc2 , 4, 4, x64 , , , , xyzw, rgb +MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1, etc2 , 4, 4, x64 , , , , xyzw, srgb diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index dc50bc830..457c8abf8 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -35,6 +35,7 @@ #include <GL/gl.h> #include <stdbool.h> +#include <stdint.h> #ifdef __cplusplus @@ -56,6 +57,29 @@ extern "C" { */ #define MAX_PIXEL_BYTES 16 +/** + * Specifies the layout of a pixel format. See the MESA_FORMAT + * documentation below. + */ +enum mesa_format_layout { + MESA_FORMAT_LAYOUT_ARRAY, + MESA_FORMAT_LAYOUT_PACKED, + MESA_FORMAT_LAYOUT_OTHER, +}; + +/** + * An enum representing different possible swizzling values. This is used + * to interpret the output of _mesa_get_format_swizzle + */ +enum { + MESA_FORMAT_SWIZZLE_X = 0, + MESA_FORMAT_SWIZZLE_Y = 1, + MESA_FORMAT_SWIZZLE_Z = 2, + MESA_FORMAT_SWIZZLE_W = 3, + MESA_FORMAT_SWIZZLE_ZERO = 4, + MESA_FORMAT_SWIZZLE_ONE = 5, + MESA_FORMAT_SWIZZLE_NONE = 6, +}; /** * Mesa texture/renderbuffer image formats. @@ -419,6 +443,9 @@ _mesa_get_format_bits(mesa_format format, GLenum pname); extern GLuint _mesa_get_format_max_bits(mesa_format format); +extern enum mesa_format_layout +_mesa_get_format_layout(mesa_format format); + extern GLenum _mesa_get_format_datatype(mesa_format format); @@ -428,6 +455,9 @@ _mesa_get_format_base_format(mesa_format format); extern void _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh); +extern void +_mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]); + extern GLboolean _mesa_is_format_compressed(mesa_format format); diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 35d6172a3..ff858207b 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -84,6 +84,7 @@ descriptor=[ [ "SAMPLES_ARB", "BUFFER_INT(Visual.samples), extra_new_buffers" ], # GL_ARB_sample_shading + [ "SAMPLE_SHADING_ARB", "CONTEXT_BOOL(Multisample.SampleShading), extra_gl40_ARB_sample_shading" ], [ "MIN_SAMPLE_SHADING_VALUE_ARB", "CONTEXT_FLOAT(Multisample.MinSampleShadingValue), extra_gl40_ARB_sample_shading" ], # GL_SGIS_generate_mipmap diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 304d45298..0fb25ba0f 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -353,6 +353,170 @@ _mesa_bytes_per_vertex_attrib(GLint comps, GLenum type) } } +/** + * Test if the given format is unsized. + */ +GLboolean +_mesa_is_enum_format_unsized(GLenum format) +{ + switch (format) { + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + case GL_RGB: + case GL_BGR: + case GL_RG: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_INTENSITY: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + + case GL_SRGB: + case GL_SRGB_ALPHA: + case GL_SLUMINANCE: + case GL_SLUMINANCE_ALPHA: + + case GL_RGBA_SNORM: + case GL_RGB_SNORM: + case GL_RG_SNORM: + case GL_RED_SNORM: + case GL_ALPHA_SNORM: + case GL_INTENSITY_SNORM: + case GL_LUMINANCE_SNORM: + case GL_LUMINANCE_ALPHA_SNORM: + + case GL_RED_INTEGER: + case GL_GREEN_INTEGER: + case GL_BLUE_INTEGER: + case GL_ALPHA_INTEGER: + case GL_RGB_INTEGER: + case GL_RGBA_INTEGER: + case GL_BGR_INTEGER: + case GL_BGRA_INTEGER: + case GL_RG_INTEGER: + case GL_LUMINANCE_INTEGER_EXT: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + case GL_STENCIL_INDEX: + return GL_TRUE; + default: + return GL_FALSE; + } +} + +/** + * Test if the given format is a UNORM (unsigned-normalized) format. + */ +GLboolean +_mesa_is_enum_format_unorm(GLenum format) +{ + switch(format) { + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case 1: + case GL_LUMINANCE: + case GL_SLUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case 2: + case GL_LUMINANCE_ALPHA: + case GL_SLUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_R8: + case GL_R16: + case GL_RG: + case GL_RG8: + case GL_RG16: + case 3: + case GL_RGB: + case GL_BGR: + case GL_SRGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB565: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + case 4: + case GL_ABGR_EXT: + case GL_RGBA: + case GL_BGRA: + case GL_SRGB_ALPHA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_TRUE; + default: + return GL_FALSE; + } +} + +/** + * Test if the given format is a SNORM (signed-normalized) format. + */ +GLboolean +_mesa_is_enum_format_snorm(GLenum format) +{ + switch (format) { + /* signed, normalized texture formats */ + case GL_RED_SNORM: + case GL_R8_SNORM: + case GL_R16_SNORM: + case GL_RG_SNORM: + case GL_RG8_SNORM: + case GL_RG16_SNORM: + case GL_RGB_SNORM: + case GL_RGB8_SNORM: + case GL_RGB16_SNORM: + case GL_RGBA_SNORM: + case GL_RGBA8_SNORM: + case GL_RGBA16_SNORM: + case GL_ALPHA_SNORM: + case GL_ALPHA8_SNORM: + case GL_ALPHA16_SNORM: + case GL_LUMINANCE_SNORM: + case GL_LUMINANCE8_SNORM: + case GL_LUMINANCE16_SNORM: + case GL_LUMINANCE_ALPHA_SNORM: + case GL_LUMINANCE8_ALPHA8_SNORM: + case GL_LUMINANCE16_ALPHA16_SNORM: + case GL_INTENSITY_SNORM: + case GL_INTENSITY8_SNORM: + case GL_INTENSITY16_SNORM: + return GL_TRUE; + default: + return GL_FALSE; + } +} /** * Test if the given format is an integer (non-normalized) format. diff --git a/mesalib/src/mesa/main/glformats.h b/mesalib/src/mesa/main/glformats.h index d64114ec9..7b0321570 100644 --- a/mesalib/src/mesa/main/glformats.h +++ b/mesalib/src/mesa/main/glformats.h @@ -57,6 +57,15 @@ extern GLboolean _mesa_is_type_unsigned(GLenum type); extern GLboolean +_mesa_is_enum_format_unsized(GLenum format); + +extern GLboolean +_mesa_is_enum_format_unorm(GLenum format); + +extern GLboolean +_mesa_is_enum_format_snorm(GLenum format); + +extern GLboolean _mesa_is_enum_format_integer(GLenum format); extern GLboolean diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c index 674c29d65..52095f7d1 100644 --- a/mesalib/src/mesa/main/hash.c +++ b/mesalib/src/mesa/main/hash.c @@ -37,7 +37,7 @@ #include "glheader.h" #include "imports.h" #include "hash.h" -#include "hash_table.h" +#include "util/hash_table.h" /** * Magic GLuint object name that gets stored outside of the struct hash_table. diff --git a/mesalib/src/mesa/main/hash_table.c b/mesalib/src/mesa/main/hash_table.c deleted file mode 100644 index ad8f89852..000000000 --- a/mesalib/src/mesa/main/hash_table.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright © 2009,2012 Intel Corporation - * Copyright © 1988-2004 Keith Packard and Bart Massey. - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Except as contained in this notice, the names of the authors - * or their institutions shall not be used in advertising or - * otherwise to promote the sale, use or other dealings in this - * Software without prior written authorization from the - * authors. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Keith Packard <keithp@keithp.com> - */ - -/** - * Implements an open-addressing, linear-reprobing hash table. - * - * For more information, see: - * - * http://cgit.freedesktop.org/~anholt/hash_table/tree/README - */ - -#include <stdlib.h> -#include <string.h> - -#include "main/hash_table.h" -#include "main/macros.h" -#include "ralloc.h" - -static const uint32_t deleted_key_value; - -/** - * From Knuth -- a good choice for hash/rehash values is p, p-2 where - * p and p-2 are both prime. These tables are sized to have an extra 10% - * free to avoid exponential performance degradation as the hash table fills - */ -static const struct { - uint32_t max_entries, size, rehash; -} hash_sizes[] = { - { 2, 5, 3 }, - { 4, 7, 5 }, - { 8, 13, 11 }, - { 16, 19, 17 }, - { 32, 43, 41 }, - { 64, 73, 71 }, - { 128, 151, 149 }, - { 256, 283, 281 }, - { 512, 571, 569 }, - { 1024, 1153, 1151 }, - { 2048, 2269, 2267 }, - { 4096, 4519, 4517 }, - { 8192, 9013, 9011 }, - { 16384, 18043, 18041 }, - { 32768, 36109, 36107 }, - { 65536, 72091, 72089 }, - { 131072, 144409, 144407 }, - { 262144, 288361, 288359 }, - { 524288, 576883, 576881 }, - { 1048576, 1153459, 1153457 }, - { 2097152, 2307163, 2307161 }, - { 4194304, 4613893, 4613891 }, - { 8388608, 9227641, 9227639 }, - { 16777216, 18455029, 18455027 }, - { 33554432, 36911011, 36911009 }, - { 67108864, 73819861, 73819859 }, - { 134217728, 147639589, 147639587 }, - { 268435456, 295279081, 295279079 }, - { 536870912, 590559793, 590559791 }, - { 1073741824, 1181116273, 1181116271}, - { 2147483648ul, 2362232233ul, 2362232231ul} -}; - -static int -entry_is_free(const struct hash_entry *entry) -{ - return entry->key == NULL; -} - -static int -entry_is_deleted(const struct hash_table *ht, struct hash_entry *entry) -{ - return entry->key == ht->deleted_key; -} - -static int -entry_is_present(const struct hash_table *ht, struct hash_entry *entry) -{ - return entry->key != NULL && entry->key != ht->deleted_key; -} - -struct hash_table * -_mesa_hash_table_create(void *mem_ctx, - bool (*key_equals_function)(const void *a, - const void *b)) -{ - struct hash_table *ht; - - ht = ralloc(mem_ctx, struct hash_table); - if (ht == NULL) - return NULL; - - ht->size_index = 0; - ht->size = hash_sizes[ht->size_index].size; - ht->rehash = hash_sizes[ht->size_index].rehash; - ht->max_entries = hash_sizes[ht->size_index].max_entries; - ht->key_equals_function = key_equals_function; - ht->table = rzalloc_array(ht, struct hash_entry, ht->size); - ht->entries = 0; - ht->deleted_entries = 0; - ht->deleted_key = &deleted_key_value; - - if (ht->table == NULL) { - ralloc_free(ht); - return NULL; - } - - return ht; -} - -/** - * Frees the given hash table. - * - * If delete_function is passed, it gets called on each entry present before - * freeing. - */ -void -_mesa_hash_table_destroy(struct hash_table *ht, - void (*delete_function)(struct hash_entry *entry)) -{ - if (!ht) - return; - - if (delete_function) { - struct hash_entry *entry; - - hash_table_foreach(ht, entry) { - delete_function(entry); - } - } - ralloc_free(ht); -} - -/** Sets the value of the key pointer used for deleted entries in the table. - * - * The assumption is that usually keys are actual pointers, so we use a - * default value of a pointer to an arbitrary piece of storage in the library. - * But in some cases a consumer wants to store some other sort of value in the - * table, like a uint32_t, in which case that pointer may conflict with one of - * their valid keys. This lets that user select a safe value. - * - * This must be called before any keys are actually deleted from the table. - */ -void -_mesa_hash_table_set_deleted_key(struct hash_table *ht, const void *deleted_key) -{ - ht->deleted_key = deleted_key; -} - -/** - * Finds a hash table entry with the given key and hash of that key. - * - * Returns NULL if no entry is found. Note that the data pointer may be - * modified by the user. - */ -struct hash_entry * -_mesa_hash_table_search(struct hash_table *ht, uint32_t hash, - const void *key) -{ - uint32_t start_hash_address = hash % ht->size; - uint32_t hash_address = start_hash_address; - - do { - uint32_t double_hash; - - struct hash_entry *entry = ht->table + hash_address; - - if (entry_is_free(entry)) { - return NULL; - } else if (entry_is_present(ht, entry) && entry->hash == hash) { - if (ht->key_equals_function(key, entry->key)) { - return entry; - } - } - - double_hash = 1 + hash % ht->rehash; - - hash_address = (hash_address + double_hash) % ht->size; - } while (hash_address != start_hash_address); - - return NULL; -} - -static void -_mesa_hash_table_rehash(struct hash_table *ht, int new_size_index) -{ - struct hash_table old_ht; - struct hash_entry *table, *entry; - - if (new_size_index >= ARRAY_SIZE(hash_sizes)) - return; - - table = rzalloc_array(ht, struct hash_entry, - hash_sizes[new_size_index].size); - if (table == NULL) - return; - - old_ht = *ht; - - ht->table = table; - ht->size_index = new_size_index; - ht->size = hash_sizes[ht->size_index].size; - ht->rehash = hash_sizes[ht->size_index].rehash; - ht->max_entries = hash_sizes[ht->size_index].max_entries; - ht->entries = 0; - ht->deleted_entries = 0; - - hash_table_foreach(&old_ht, entry) { - _mesa_hash_table_insert(ht, entry->hash, - entry->key, entry->data); - } - - ralloc_free(old_ht.table); -} - -/** - * Inserts the key with the given hash into the table. - * - * Note that insertion may rearrange the table on a resize or rehash, - * so previously found hash_entries are no longer valid after this function. - */ -struct hash_entry * -_mesa_hash_table_insert(struct hash_table *ht, uint32_t hash, - const void *key, void *data) -{ - uint32_t start_hash_address, hash_address; - - if (ht->entries >= ht->max_entries) { - _mesa_hash_table_rehash(ht, ht->size_index + 1); - } else if (ht->deleted_entries + ht->entries >= ht->max_entries) { - _mesa_hash_table_rehash(ht, ht->size_index); - } - - start_hash_address = hash % ht->size; - hash_address = start_hash_address; - do { - struct hash_entry *entry = ht->table + hash_address; - uint32_t double_hash; - - if (!entry_is_present(ht, entry)) { - if (entry_is_deleted(ht, entry)) - ht->deleted_entries--; - entry->hash = hash; - entry->key = key; - entry->data = data; - ht->entries++; - return entry; - } - - /* Implement replacement when another insert happens - * with a matching key. This is a relatively common - * feature of hash tables, with the alternative - * generally being "insert the new value as well, and - * return it first when the key is searched for". - * - * Note that the hash table doesn't have a delete - * callback. If freeing of old data pointers is - * required to avoid memory leaks, perform a search - * before inserting. - */ - if (entry->hash == hash && - ht->key_equals_function(key, entry->key)) { - entry->key = key; - entry->data = data; - return entry; - } - - - double_hash = 1 + hash % ht->rehash; - - hash_address = (hash_address + double_hash) % ht->size; - } while (hash_address != start_hash_address); - - /* We could hit here if a required resize failed. An unchecked-malloc - * application could ignore this result. - */ - return NULL; -} - -/** - * This function deletes the given hash table entry. - * - * Note that deletion doesn't otherwise modify the table, so an iteration over - * the table deleting entries is safe. - */ -void -_mesa_hash_table_remove(struct hash_table *ht, - struct hash_entry *entry) -{ - if (!entry) - return; - - entry->key = ht->deleted_key; - ht->entries--; - ht->deleted_entries++; -} - -/** - * This function is an iterator over the hash table. - * - * Pass in NULL for the first entry, as in the start of a for loop. Note that - * an iteration over the table is O(table_size) not O(entries). - */ -struct hash_entry * -_mesa_hash_table_next_entry(struct hash_table *ht, - struct hash_entry *entry) -{ - if (entry == NULL) - entry = ht->table; - else - entry = entry + 1; - - for (; entry != ht->table + ht->size; entry++) { - if (entry_is_present(ht, entry)) { - return entry; - } - } - - return NULL; -} - -/** - * Returns a random entry from the hash table. - * - * This may be useful in implementing random replacement (as opposed - * to just removing everything) in caches based on this hash table - * implementation. @predicate may be used to filter entries, or may - * be set to NULL for no filtering. - */ -struct hash_entry * -_mesa_hash_table_random_entry(struct hash_table *ht, - bool (*predicate)(struct hash_entry *entry)) -{ - struct hash_entry *entry; - uint32_t i = rand() % ht->size; - - if (ht->entries == 0) - return NULL; - - for (entry = ht->table + i; entry != ht->table + ht->size; entry++) { - if (entry_is_present(ht, entry) && - (!predicate || predicate(entry))) { - return entry; - } - } - - for (entry = ht->table; entry != ht->table + i; entry++) { - if (entry_is_present(ht, entry) && - (!predicate || predicate(entry))) { - return entry; - } - } - - return NULL; -} - - -/** - * Quick FNV-1 hash implementation based on: - * http://www.isthe.com/chongo/tech/comp/fnv/ - * - * FNV-1 is not be the best hash out there -- Jenkins's lookup3 is supposed to - * be quite good, and it probably beats FNV. But FNV has the advantage that - * it involves almost no code. For an improvement on both, see Paul - * Hsieh's http://www.azillionmonkeys.com/qed/hash.html - */ -uint32_t -_mesa_hash_data(const void *data, size_t size) -{ - uint32_t hash = 2166136261ul; - const uint8_t *bytes = data; - - while (size-- != 0) { - hash ^= *bytes; - hash = hash * 0x01000193; - bytes++; - } - - return hash; -} - -/** FNV-1 string hash implementation */ -uint32_t -_mesa_hash_string(const char *key) -{ - uint32_t hash = 2166136261ul; - - while (*key != 0) { - hash ^= *key; - hash = hash * 0x01000193; - key++; - } - - return hash; -} - -/** - * String compare function for use as the comparison callback in - * _mesa_hash_table_create(). - */ -bool -_mesa_key_string_equal(const void *a, const void *b) -{ - return strcmp(a, b) == 0; -} - -bool -_mesa_key_pointer_equal(const void *a, const void *b) -{ - return a == b; -} diff --git a/mesalib/src/mesa/main/hash_table.h b/mesalib/src/mesa/main/hash_table.h deleted file mode 100644 index f51131aee..000000000 --- a/mesalib/src/mesa/main/hash_table.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright © 2009,2012 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * - */ - -#ifndef _HASH_TABLE_H -#define _HASH_TABLE_H - -#include <inttypes.h> -#include <stdbool.h> - -#include "compiler.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct hash_entry { - uint32_t hash; - const void *key; - void *data; -}; - -struct hash_table { - struct hash_entry *table; - bool (*key_equals_function)(const void *a, const void *b); - const void *deleted_key; - uint32_t size; - uint32_t rehash; - uint32_t max_entries; - uint32_t size_index; - uint32_t entries; - uint32_t deleted_entries; -}; - -struct hash_table * -_mesa_hash_table_create(void *mem_ctx, - bool (*key_equals_function)(const void *a, - const void *b)); -void _mesa_hash_table_destroy(struct hash_table *ht, - void (*delete_function)(struct hash_entry *entry)); -void _mesa_hash_table_set_deleted_key(struct hash_table *ht, - const void *deleted_key); - -struct hash_entry * -_mesa_hash_table_insert(struct hash_table *ht, uint32_t hash, - const void *key, void *data); -struct hash_entry * -_mesa_hash_table_search(struct hash_table *ht, uint32_t hash, - const void *key); -void _mesa_hash_table_remove(struct hash_table *ht, - struct hash_entry *entry); - -struct hash_entry *_mesa_hash_table_next_entry(struct hash_table *ht, - struct hash_entry *entry); -struct hash_entry * -_mesa_hash_table_random_entry(struct hash_table *ht, - bool (*predicate)(struct hash_entry *entry)); - -uint32_t _mesa_hash_data(const void *data, size_t size); -uint32_t _mesa_hash_string(const char *key); -bool _mesa_key_string_equal(const void *a, const void *b); -bool _mesa_key_pointer_equal(const void *a, const void *b); - -static inline uint32_t _mesa_hash_pointer(const void *pointer) -{ - return _mesa_hash_data(&pointer, sizeof(pointer)); -} - -/** - * This foreach function is safe against deletion (which just replaces - * an entry's data with the deleted marker), but not against insertion - * (which may rehash the table, making entry a dangling pointer). - */ -#define hash_table_foreach(ht, entry) \ - for (entry = _mesa_hash_table_next_entry(ht, NULL); \ - entry != NULL; \ - entry = _mesa_hash_table_next_entry(ht, entry)) - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif /* _HASH_TABLE_H */ diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index aee495a4c..000fd5b49 100755 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -163,7 +163,6 @@ INV_SQRTF(float x) ***/ static inline GLfloat LOG2(GLfloat x) { -#ifdef USE_IEEE #if 0 /* This is pretty fast, but not accurate enough (only 2 fractional bits). * Based on code from http://www.stereopsis.com/log2.html @@ -185,13 +184,6 @@ static inline GLfloat LOG2(GLfloat x) num.i += 127 << 23; num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3; return num.f + log_2; -#else - /* - * NOTE: log_base_2(x) = log(x) / log(2) - * NOTE: 1.442695 = 1/log(2). - */ - return (GLfloat) (log(x) * 1.442695F); -#endif } @@ -199,14 +191,7 @@ static inline GLfloat LOG2(GLfloat x) /*** *** IS_INF_OR_NAN: test if float is infinite or NaN ***/ -#ifdef USE_IEEE -static inline int IS_INF_OR_NAN( float x ) -{ - fi_type tmp; - tmp.f = x; - return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31); -} -#elif defined(isfinite) +#if defined(isfinite) #define IS_INF_OR_NAN(x) (!isfinite(x)) #elif defined(finite) #define IS_INF_OR_NAN(x) (!finite(x)) @@ -320,7 +305,7 @@ static inline int IFLOOR(float f) __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st"); __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st"); return (ai - bi) >> 1; -#elif defined(USE_IEEE) +#else int ai, bi; double af, bf; fi_type u; @@ -329,9 +314,6 @@ static inline int IFLOOR(float f) u.f = (float) af; ai = u.i; u.f = (float) bf; bi = u.i; return (ai - bi) >> 1; -#else - int i = IROUND(f); - return (i > f) ? i - 1 : i; #endif } @@ -355,7 +337,7 @@ static inline int ICEIL(float f) __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st"); __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st"); return (ai - bi + 1) >> 1; -#elif defined(USE_IEEE) +#else int ai, bi; double af, bf; fi_type u; @@ -364,9 +346,6 @@ static inline int ICEIL(float f) u.f = (float) af; ai = u.i; u.f = (float) bf; bi = u.i; return (ai - bi + 1) >> 1; -#else - int i = IROUND(f); - return (i < f) ? i + 1 : i; #endif } @@ -551,6 +530,11 @@ _mesa_float_to_half(float f); extern float _mesa_half_to_float(GLhalfARB h); +static inline bool +_mesa_half_is_negative(GLhalfARB h) +{ + return h & 0x8000; +} extern void * _mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size, diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h index 5228c3a8f..0ba658a9a 100644 --- a/mesalib/src/mesa/main/macros.h +++ b/mesalib/src/mesa/main/macros.h @@ -140,7 +140,7 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255] ***/ -#if defined(USE_IEEE) && !defined(DEBUG) +#ifndef DEBUG /* This function/macro is sensitive to precision. Test very carefully * if you change it! */ @@ -818,7 +818,9 @@ DIFFERENT_SIGNS(GLfloat x, GLfloat y) #define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE) /* Compute the size of an array */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif /* Stringify */ #define STRINGIFY(x) #x diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 3f60a5530..e141ac658 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1693,6 +1693,9 @@ struct gl_array_attrib /** One of the DRAW_xxx flags, not consumed by drivers */ gl_draw_method DrawMethod; + + /** Legal array datatypes */ + GLbitfield LegalTypesMask; }; @@ -2048,13 +2051,31 @@ typedef enum */ typedef enum { - SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */ - SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */ - SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */ - SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */ - SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */ - SYSTEM_VALUE_SAMPLE_MASK_IN, /**< Fragment shader only */ - SYSTEM_VALUE_INVOCATION_ID, /**< Geometry shader only */ + /** + * \name Vertex shader system values + */ + /*@{*/ + SYSTEM_VALUE_VERTEX_ID, + SYSTEM_VALUE_INSTANCE_ID, + /*@}*/ + + /** + * \name Geometry shader system values + */ + /*@{*/ + SYSTEM_VALUE_INVOCATION_ID, + /*@}*/ + + /** + * \name Fragment shader system values + */ + /*@{*/ + SYSTEM_VALUE_FRONT_FACE, /**< (not done yet) */ + SYSTEM_VALUE_SAMPLE_ID, + SYSTEM_VALUE_SAMPLE_POS, + SYSTEM_VALUE_SAMPLE_MASK_IN, + /*@}*/ + SYSTEM_VALUE_MAX /**< Number of values */ } gl_system_value; @@ -3531,6 +3552,7 @@ struct gl_extensions GLboolean ARB_color_buffer_float; GLboolean ARB_compute_shader; GLboolean ARB_conservative_depth; + GLboolean ARB_copy_image; GLboolean ARB_depth_buffer_float; GLboolean ARB_depth_clamp; GLboolean ARB_depth_texture; diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c index c26eda4c6..c02910e31 100644 --- a/mesalib/src/mesa/main/performance_monitor.c +++ b/mesalib/src/mesa/main/performance_monitor.c @@ -43,7 +43,7 @@ #include "mtypes.h" #include "performance_monitor.h" #include "bitset.h" -#include "ralloc.h" +#include "util/ralloc.h" void _mesa_init_performance_monitors(struct gl_context *ctx) diff --git a/mesalib/src/mesa/main/pipelineobj.c b/mesalib/src/mesa/main/pipelineobj.c index 90c1d005f..017d4257e 100644 --- a/mesalib/src/mesa/main/pipelineobj.c +++ b/mesalib/src/mesa/main/pipelineobj.c @@ -44,7 +44,7 @@ #include "main/uniforms.h" #include "program/program.h" #include "program/prog_parameter.h" -#include "ralloc.h" +#include "util/ralloc.h" #include <stdbool.h> #include "../glsl/glsl_parser_extras.h" #include "../glsl/ir_uniform.h" diff --git a/mesalib/src/mesa/main/set.c b/mesalib/src/mesa/main/set.c index 989e5dece..52c1dabd8 100644 --- a/mesalib/src/mesa/main/set.c +++ b/mesalib/src/mesa/main/set.c @@ -36,7 +36,7 @@ #include "macros.h" #include "set.h" -#include "ralloc.h" +#include "util/ralloc.h" /* * From Knuth -- a good choice for hash/rehash values is p, p-2 where diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 2bbef35d3..b4a5e7050 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -42,7 +42,6 @@ #include "main/dispatch.h" #include "main/enums.h" #include "main/hash.h" -#include "main/hash_table.h" #include "main/mtypes.h" #include "main/pipelineobj.h" #include "main/shaderapi.h" @@ -52,7 +51,8 @@ #include "program/program.h" #include "program/prog_print.h" #include "program/prog_parameter.h" -#include "ralloc.h" +#include "util/ralloc.h" +#include "util/hash_table.h" #include <stdbool.h> #include "../glsl/glsl_parser_extras.h" #include "../glsl/ir.h" diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index b9feff4a4..693e9a259 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -40,7 +40,7 @@ #include "program/program.h" #include "program/prog_parameter.h" #include "program/hash_table.h" -#include "ralloc.h" +#include "util/ralloc.h" /**********************************************************************/ /*** Shader object functions ***/ diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c index 5ae7014b1..0189dd296 100644 --- a/mesalib/src/mesa/main/shared.c +++ b/mesalib/src/mesa/main/shared.c @@ -30,7 +30,6 @@ #include "imports.h" #include "mtypes.h" #include "hash.h" -#include "hash_table.h" #include "atifragshader.h" #include "bufferobj.h" #include "shared.h" @@ -42,6 +41,7 @@ #include "shaderobj.h" #include "syncobj.h" +#include "util/hash_table.h" /** * Allocate and initialize a shared context state structure. diff --git a/mesalib/src/mesa/main/syncobj.c b/mesalib/src/mesa/main/syncobj.c index 9721b14b4..9a9c572c5 100644 --- a/mesalib/src/mesa/main/syncobj.c +++ b/mesalib/src/mesa/main/syncobj.c @@ -64,7 +64,7 @@ #include "dispatch.h" #include "mtypes.h" #include "set.h" -#include "hash_table.h" +#include "util/hash_table.h" #include "syncobj.h" diff --git a/mesalib/src/mesa/main/texcompress_etc.c b/mesalib/src/mesa/main/texcompress_etc.c index ae973b001..98b4fe201 100644 --- a/mesalib/src/mesa/main/texcompress_etc.c +++ b/mesalib/src/mesa/main/texcompress_etc.c @@ -43,6 +43,7 @@ #include "texstore.h" #include "macros.h" #include "format_unpack.h" +#include "util/format_srgb.h" struct etc2_block { @@ -1307,9 +1308,9 @@ fetch_etc2_srgb8(const GLubyte *map, etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, false /* punchthrough_alpha */); - texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]); - texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]); - texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); texel[ACOMP] = 1.0f; } @@ -1345,9 +1346,9 @@ fetch_etc2_srgb8_alpha8_eac(const GLubyte *map, etc2_rgba8_parse_block(&block, src); etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst); - texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]); - texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]); - texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); } @@ -1473,9 +1474,9 @@ fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map, true /* punchthrough alpha */); etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst, true /* punchthrough alpha */); - texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]); - texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]); - texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]); texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]); } diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c index 894c46de1..5b275efe0 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -44,6 +44,7 @@ #include "texcompress_s3tc.h" #include "texstore.h" #include "format_unpack.h" +#include "util/format_srgb.h" #if defined(_WIN32) || defined(WIN32) @@ -419,9 +420,9 @@ fetch_srgb_dxt1(const GLubyte *map, if (fetch_ext_rgb_dxt1) { GLubyte tex[4]; fetch_ext_rgb_dxt1(rowStride, map, i, j, tex); - texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]); - texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]); - texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]); texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]); } else { @@ -436,9 +437,9 @@ fetch_srgba_dxt1(const GLubyte *map, if (fetch_ext_rgba_dxt1) { GLubyte tex[4]; fetch_ext_rgba_dxt1(rowStride, map, i, j, tex); - texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]); - texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]); - texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]); texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]); } else { @@ -453,9 +454,9 @@ fetch_srgba_dxt3(const GLubyte *map, if (fetch_ext_rgba_dxt3) { GLubyte tex[4]; fetch_ext_rgba_dxt3(rowStride, map, i, j, tex); - texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]); - texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]); - texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]); texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]); } else { @@ -470,9 +471,9 @@ fetch_srgba_dxt5(const GLubyte *map, if (fetch_ext_rgba_dxt5) { GLubyte tex[4]; fetch_ext_rgba_dxt5(rowStride, map, i, j, tex); - texel[RCOMP] = _mesa_nonlinear_to_linear(tex[RCOMP]); - texel[GCOMP] = _mesa_nonlinear_to_linear(tex[GCOMP]); - texel[BCOMP] = _mesa_nonlinear_to_linear(tex[BCOMP]); + texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]); + texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]); + texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]); texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]); } else { diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index fb2dee7d8..bb050b188 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -1770,9 +1770,9 @@ compressedteximage_only_format(const struct gl_context *ctx, GLenum format) * Helper function to determine whether a target and specific compression * format are supported. */ -static GLboolean -target_can_be_compressed(const struct gl_context *ctx, GLenum target, - GLenum intFormat) +GLboolean +_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, + GLenum intFormat) { (void) intFormat; /* not used yet */ @@ -1781,6 +1781,7 @@ target_can_be_compressed(const struct gl_context *ctx, GLenum target, case GL_PROXY_TEXTURE_2D: return GL_TRUE; /* true for any compressed format so far */ case GL_PROXY_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: @@ -2211,7 +2212,7 @@ texture_error_check( struct gl_context *ctx, /* additional checks for compressed textures */ if (_mesa_is_compressed_format(ctx, internalFormat)) { - if (!target_can_be_compressed(ctx, target, internalFormat)) { + if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%dD(target can't be compressed)", dimensions); return GL_TRUE; @@ -2297,9 +2298,16 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, GLenum error = GL_NO_ERROR; char *reason = ""; /* no error */ - if (!target_can_be_compressed(ctx, target, internalFormat)) { + if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) { reason = "target"; - error = GL_INVALID_ENUM; + /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: + * + * "The ETC2/EAC texture compression algorithm supports only + * two-dimensional images. If internalformat is an ETC2/EAC format, + * CompressedTexImage3D will generate an INVALID_OPERATION error if + * target is not TEXTURE_2D_ARRAY." + */ + error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_ENUM : GL_INVALID_OPERATION; goto error; } @@ -2704,6 +2712,17 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, "glCopyTexImage%dD(srgb usage mismatch)", dimensions); return GL_TRUE; } + + /* Page 139, Table 3.15 of OpenGL ES 3.0 spec does not define ReadPixels + * types for SNORM formats. Also, conversion to SNORM formats is not + * allowed by Table 3.2 on Page 110. + */ + if(_mesa_is_enum_format_snorm(internalFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%dD(internalFormat=%s)", dimensions, + _mesa_lookup_enum_by_nr(internalFormat)); + return GL_TRUE; + } } if (!_mesa_source_buffer_exists(ctx, baseFormat)) { @@ -2722,6 +2741,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, if (_mesa_is_color_format(internalFormat)) { bool is_int = _mesa_is_enum_format_integer(internalFormat); bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format); + bool is_unorm = _mesa_is_enum_format_unorm(internalFormat); + bool is_rbunorm = _mesa_is_enum_format_unorm(rb_internal_format); if (is_int || is_rbint) { if (is_int != is_rbint) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -2735,10 +2756,23 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } } + + /* From page 138 of OpenGL ES 3.0 spec: + * "The error INVALID_OPERATION is generated if floating-point RGBA + * data is required; if signed integer RGBA data is required and the + * format of the current color buffer is not signed integer; if + * unsigned integer RGBA data is required and the format of the + * current color buffer is not unsigned integer; or if fixed-point + * RGBA data is required and the format of the current color buffer + * is not fixed-point. + */ + if (_mesa_is_gles(ctx) && is_unorm != is_rbunorm) + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%dD(unorm vs non-unorm)", dimensions); } if (_mesa_is_compressed_format(ctx, internalFormat)) { - if (!target_can_be_compressed(ctx, target, internalFormat)) { + if (!_mesa_target_can_be_compressed(ctx, target, internalFormat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%dD(target)", dimensions); return GL_TRUE; @@ -3608,6 +3642,28 @@ copytexsubimage_by_slice(struct gl_context *ctx, } } +static GLboolean +formats_differ_in_component_sizes (mesa_format f1, + mesa_format f2) +{ + GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS); + GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS); + GLint f1_b_bits = _mesa_get_format_bits(f1, GL_BLUE_BITS); + GLint f1_a_bits = _mesa_get_format_bits(f1, GL_ALPHA_BITS); + + GLint f2_r_bits = _mesa_get_format_bits(f2, GL_RED_BITS); + GLint f2_g_bits = _mesa_get_format_bits(f2, GL_GREEN_BITS); + GLint f2_b_bits = _mesa_get_format_bits(f2, GL_BLUE_BITS); + GLint f2_a_bits = _mesa_get_format_bits(f2, GL_ALPHA_BITS); + + if ((f1_r_bits && f2_r_bits && f1_r_bits != f2_r_bits) + || (f1_g_bits && f2_g_bits && f1_g_bits != f2_g_bits) + || (f1_b_bits && f2_b_bits && f1_b_bits != f2_b_bits) + || (f1_a_bits && f2_a_bits && f1_a_bits != f2_a_bits)) + return GL_TRUE; + + return GL_FALSE; +} /** * Implement the glCopyTexImage1/2D() functions. @@ -3621,6 +3677,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage; const GLuint face = _mesa_tex_target_to_face(target); mesa_format texFormat; + struct gl_renderbuffer *rb; FLUSH_VERTICES(ctx, 0); @@ -3650,6 +3707,40 @@ copyteximage(struct gl_context *ctx, GLuint dims, texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, internalFormat, GL_NONE, GL_NONE); + + rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); + + if (_mesa_is_gles3(ctx)) { + if (_mesa_is_enum_format_unsized(internalFormat)) { + /* Conversion from GL_RGB10_A2 source buffer format is not allowed in + * OpenGL ES 3.0. Khronos bug# 9807. + */ + if (rb->InternalFormat == GL_RGB10_A2) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer and" + " writing to unsized internal format)", dims); + return; + } + } + /* From Page 139 of OpenGL ES 3.0 spec: + * "If internalformat is sized, the internal format of the new texel + * array is internalformat, and this is also the new texel array’s + * effective internal format. If the component sizes of internalformat + * do not exactly match the corresponding component sizes of the source + * buffer’s effective internal format, described below, an + * INVALID_OPERATION error is generated. If internalformat is unsized, + * the internal format of the new texel array is the effective internal + * format of the source buffer, and this is also the new texel array’s + * effective internal format. + */ + else if (formats_differ_in_component_sizes (texFormat, rb->Format)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%uD(componenet size changed in" + " internal format)", dims); + return; + } + } + assert(texFormat != MESA_FORMAT_NONE); if (!ctx->Driver.TestProxyTexImage(ctx, proxy_target(target), diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 42305f44f..52bfa7816 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -123,6 +123,9 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, mesa_format format, GLint width, GLint height, GLint depth, GLint border); +extern GLboolean +_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, + GLenum intFormat); extern GLuint _mesa_tex_target_to_face(GLenum target); diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 86c8f3c92..897d5891a 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -41,6 +41,7 @@ #include "texstorage.h" #include "textureview.h" #include "mtypes.h" +#include "glformats.h" @@ -53,6 +54,13 @@ static GLboolean legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target) { + if (_mesa_is_gles3(ctx) + && target != GL_TEXTURE_2D + && target != GL_TEXTURE_CUBE_MAP + && target != GL_TEXTURE_3D + && target != GL_TEXTURE_2D_ARRAY) + return GL_FALSE; + switch (dims) { case 1: switch (target) { @@ -294,6 +302,23 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, return GL_TRUE; } + /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: + * + * "The ETC2/EAC texture compression algorithm supports only + * two-dimensional images. If internalformat is an ETC2/EAC format, + * CompressedTexImage3D will generate an INVALID_OPERATION error if + * target is not TEXTURE_2D_ARRAY." + * + * This should also be applicable for glTexStorage3D(). + */ + if (_mesa_is_compressed_format(ctx, internalformat) + && !_mesa_target_can_be_compressed(ctx, target, internalformat)) { + _mesa_error(ctx, _mesa_is_desktop_gl(ctx)? + GL_INVALID_ENUM : GL_INVALID_OPERATION, + "glTexStorage3D(internalformat = %s)", + _mesa_lookup_enum_by_nr(internalformat)); + } + /* levels check */ if (levels < 1) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)", diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index aea53f8d1..0e036d9eb 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -55,6 +55,7 @@ #include "bufferobj.h" #include "colormac.h" #include "format_pack.h" +#include "format_utils.h" #include "image.h" #include "macros.h" #include "mipmap.h" @@ -87,35 +88,6 @@ enum { typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); -/** - * Return GL_TRUE if the given image format is one that be converted - * to another format by swizzling. - */ -static GLboolean -can_swizzle(GLenum logicalBaseFormat) -{ - switch (logicalBaseFormat) { - case GL_RGBA: - case GL_RGB: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_BGR: - case GL_BGRA: - case GL_ABGR_EXT: - case GL_RG: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - - enum { IDX_LUMINANCE = 0, IDX_ALPHA, @@ -233,21 +205,44 @@ static int get_map_idx(GLenum value) { switch (value) { - case GL_LUMINANCE: return IDX_LUMINANCE; - case GL_ALPHA: return IDX_ALPHA; - case GL_INTENSITY: return IDX_INTENSITY; - case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA; - case GL_RGB: return IDX_RGB; - case GL_RGBA: return IDX_RGBA; - case GL_RED: return IDX_RED; - case GL_GREEN: return IDX_GREEN; - case GL_BLUE: return IDX_BLUE; - case GL_BGR: return IDX_BGR; - case GL_BGRA: return IDX_BGRA; - case GL_ABGR_EXT: return IDX_ABGR; - case GL_RG: return IDX_RG; + case GL_LUMINANCE: + case GL_LUMINANCE_INTEGER_EXT: + return IDX_LUMINANCE; + case GL_ALPHA: + case GL_ALPHA_INTEGER: + return IDX_ALPHA; + case GL_INTENSITY: + return IDX_INTENSITY; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + return IDX_LUMINANCE_ALPHA; + case GL_RGB: + case GL_RGB_INTEGER: + return IDX_RGB; + case GL_RGBA: + case GL_RGBA_INTEGER: + return IDX_RGBA; + case GL_RED: + case GL_RED_INTEGER: + return IDX_RED; + case GL_GREEN: + return IDX_GREEN; + case GL_BLUE: + return IDX_BLUE; + case GL_BGR: + case GL_BGR_INTEGER: + return IDX_BGR; + case GL_BGRA: + case GL_BGRA_INTEGER: + return IDX_BGRA; + case GL_ABGR_EXT: + return IDX_ABGR; + case GL_RG: + case GL_RG_INTEGER: + return IDX_RG; default: - _mesa_problem(NULL, "Unexpected inFormat"); + _mesa_problem(NULL, "Unexpected inFormat %s", + _mesa_lookup_enum_by_nr(value)); return 0; } } @@ -662,257 +657,9 @@ _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, } -/** - * Copy GLubyte pixels from <src> to <dst> with swizzling. - * \param dst destination pixels - * \param dstComponents number of color components in destination pixels - * \param src source pixels - * \param srcComponents number of color components in source pixels - * \param map the swizzle mapping. map[X] says where to find the X component - * in the source image's pixels. For example, if the source image - * is GL_BGRA and X = red, map[0] yields 2. - * \param count number of pixels to copy/swizzle. - */ -static void -swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, - GLuint srcComponents, const GLubyte *map, GLuint count) -{ -#define SWZ_CPY(dst, src, count, dstComps, srcComps) \ - do { \ - GLuint i; \ - for (i = 0; i < count; i++) { \ - GLuint j; \ - if (srcComps == 4) { \ - COPY_4UBV(tmp, src); \ - } \ - else { \ - for (j = 0; j < srcComps; j++) { \ - tmp[j] = src[j]; \ - } \ - } \ - src += srcComps; \ - for (j = 0; j < dstComps; j++) { \ - dst[j] = tmp[map[j]]; \ - } \ - dst += dstComps; \ - } \ - } while (0) - - GLubyte tmp[6]; - - tmp[ZERO] = 0x0; - tmp[ONE] = 0xff; - - ASSERT(srcComponents <= 4); - ASSERT(dstComponents <= 4); - - switch (dstComponents) { - case 4: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 4, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 4, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 4, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 4, 1); - break; - default: - ; - } - break; - case 3: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 3, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 3, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 3, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 3, 1); - break; - default: - ; - } - break; - case 2: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 2, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 2, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 2, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 2, 1); - break; - default: - ; - } - break; - case 1: - switch (srcComponents) { - case 4: - SWZ_CPY(dst, src, count, 1, 4); - break; - case 3: - SWZ_CPY(dst, src, count, 1, 3); - break; - case 2: - SWZ_CPY(dst, src, count, 1, 2); - break; - case 1: - SWZ_CPY(dst, src, count, 1, 1); - break; - default: - ; - } - break; - default: - ; - } -#undef SWZ_CPY -} - - - static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; - - -/** - * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a - * mapping array depending on endianness. - */ -static const GLubyte * -type_mapping( GLenum srcType ) -{ - switch (srcType) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return map_identity; - case GL_UNSIGNED_INT_8_8_8_8: - return _mesa_little_endian() ? map_3210 : map_identity; - case GL_UNSIGNED_INT_8_8_8_8_REV: - return _mesa_little_endian() ? map_identity : map_3210; - default: - return NULL; - } -} - - -/** - * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a - * mapping array depending on pixelstore byte swapping state. - */ -static const GLubyte * -byteswap_mapping( GLboolean swapBytes, - GLenum srcType ) -{ - if (!swapBytes) - return map_identity; - - switch (srcType) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return map_identity; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - return map_3210; - default: - return NULL; - } -} - - - -/** - * Transfer a GLubyte texture image with component swizzling. - */ -static void -_mesa_swizzle_ubyte_image(struct gl_context *ctx, - GLuint dimensions, - GLenum srcFormat, - GLenum srcType, - - GLenum baseInternalFormat, - - const GLubyte *rgba2dst, - GLuint dstComponents, - - GLint dstRowStride, - GLubyte **dstSlices, - - GLint srcWidth, GLint srcHeight, GLint srcDepth, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking ) -{ - GLint srcComponents = _mesa_components_in_format(srcFormat); - const GLubyte *srctype2ubyte, *swap; - GLubyte map[4], src2base[6], base2rgba[6]; - GLint i; - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, - srcFormat, GL_UNSIGNED_BYTE); - const GLint srcImageStride - = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, - GL_UNSIGNED_BYTE); - const GLubyte *srcImage - = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr, - srcWidth, srcHeight, srcFormat, - GL_UNSIGNED_BYTE, 0, 0, 0); - - (void) ctx; - - /* Translate from src->baseInternal->GL_RGBA->dst. This will - * correctly deal with RGBA->RGB->RGBA conversions where the final - * A value must be 0xff regardless of the incoming alpha values. - */ - compute_component_mapping(srcFormat, baseInternalFormat, src2base); - compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba); - swap = byteswap_mapping(srcPacking->SwapBytes, srcType); - srctype2ubyte = type_mapping(srcType); - - - for (i = 0; i < 4; i++) - map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]]; - -/* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */ - - if (srcComponents == dstComponents && - srcRowStride == dstRowStride && - srcRowStride == srcWidth * srcComponents && - dimensions < 3) { - /* 1 and 2D images only */ - GLubyte *dstImage = dstSlices[0]; - swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, - srcWidth * srcHeight); - } - else { - GLint img, row; - for (img = 0; img < srcDepth; img++) { - const GLubyte *srcRow = srcImage; - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth); - dstRow += dstRowStride; - srcRow += srcRowStride; - } - srcImage += srcImageStride; - } - } -} +static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE }; /** @@ -988,6 +735,10 @@ store_ubyte_texture(TEXSTORE_PARAMS) if (!tempImage) return GL_FALSE; + /* This way we will use the RGB versions of the packing functions and it + * will work for both RGB and sRGB textures*/ + dstFormat = _mesa_get_srgb_format_linear(dstFormat); + src = tempImage; for (img = 0; img < srcDepth; img++) { _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight, @@ -1178,845 +929,13 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS) dst += dstRowStride; src += srcRowStride; } + return GL_TRUE; + } else { + return GL_FALSE; } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -/** - * Store a texture in MESA_FORMAT_A8B8G8R8_UNORM or MESA_FORMAT_R8G8B8A8_UNORM. - */ -static GLboolean -_mesa_texstore_rgba8888(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - - ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_UNORM || - dstFormat == MESA_FORMAT_R8G8B8A8_UNORM || - dstFormat == MESA_FORMAT_X8B8G8R8_UNORM || - dstFormat == MESA_FORMAT_R8G8B8X8_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - if (!ctx->_ImageTransferState && - (srcType == GL_UNSIGNED_BYTE || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if ((littleEndian && (dstFormat == MESA_FORMAT_A8B8G8R8_UNORM || - dstFormat == MESA_FORMAT_X8B8G8R8_UNORM)) || - (!littleEndian && (dstFormat == MESA_FORMAT_R8G8B8A8_UNORM || - dstFormat == MESA_FORMAT_R8G8B8X8_UNORM))) { - dstmap[3] = 0; - dstmap[2] = 1; - dstmap[1] = 2; - dstmap[0] = 3; - } - else { - dstmap[3] = 3; - dstmap[2] = 2; - dstmap[1] = 1; - dstmap[0] = 0; - } - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 4, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_argb8888(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - - ASSERT(dstFormat == MESA_FORMAT_B8G8R8A8_UNORM || - dstFormat == MESA_FORMAT_A8R8G8B8_UNORM || - dstFormat == MESA_FORMAT_B8G8R8X8_UNORM || - dstFormat == MESA_FORMAT_X8R8G8B8_UNORM ); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - (dstFormat == MESA_FORMAT_B8G8R8A8_UNORM || - dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) && - srcFormat == GL_RGB && - (baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB) && - srcType == GL_UNSIGNED_BYTE) { - int img, row, col; - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *d4 = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - d4[col] = PACK_COLOR_8888(0xff, - srcRow[col * 3 + RCOMP], - srcRow[col * 3 + GCOMP], - srcRow[col * 3 + BCOMP]); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_B8G8R8A8_UNORM && - srcFormat == GL_LUMINANCE_ALPHA && - baseInternalFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* special case of storing LA -> ARGB8888 */ - int img, row, col; - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - for (img = 0; img < srcDepth; img++) { - const GLubyte *srcRow = (const GLubyte *) - _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, - srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *d4 = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1]; - d4[col] = PACK_COLOR_8888(a, l, l, l); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - dstFormat == MESA_FORMAT_B8G8R8A8_UNORM && - srcFormat == GL_RGBA && - baseInternalFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* same as above case, but src data has alpha too */ - GLint img, row, col; - /* For some reason, streaming copies to write-combined regions - * are extremely sensitive to the characteristics of how the - * source data is retrieved. By reordering the source reads to - * be in-order, the speed of this operation increases by half. - * Strangely the same isn't required for the RGB path, above. - */ - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *d4 = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP], - srcRow[col * 4 + RCOMP], - srcRow[col * 4 + GCOMP], - srcRow[col * 4 + BCOMP]); - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - (srcType == GL_UNSIGNED_BYTE || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if ((littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) || - (littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM)) { - dstmap[3] = 3; /* alpha */ - dstmap[2] = 0; /* red */ - dstmap[1] = 1; /* green */ - dstmap[0] = 2; /* blue */ - } - else { - assert((littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) || - (littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM)); - dstmap[3] = 2; - dstmap[2] = 1; - dstmap[1] = 0; - dstmap[0] = 3; - } - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 4, - dstRowStride, - dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_rgb888(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_BGR_UNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 3); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* extract RGB from RGBA */ - GLint img, row, col; - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP]; - dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; - dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP]; - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - dstmap[0] = 2; - dstmap[1] = 1; - dstmap[2] = 0; - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 3, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_bgr888(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_RGB_UNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 3); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { - /* extract BGR from RGBA */ - int img, row, col; - for (img = 0; img < srcDepth; img++) { - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, - srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP]; - dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; - dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP]; - } - dstRow += dstRowStride; - srcRow += srcRowStride; - } - } - } - else if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - dstmap[0] = 0; - dstmap[1] = 1; - dstmap[2] = 2; - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 3, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_argb2101010(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UNORM || - dstFormat == MESA_FORMAT_B10G10R10X2_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 - * if the internal format is RGB. */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - if (baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB) { - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b); - src += 4; - } - dstRow += dstRowStride; - } - } else { - ASSERT(0); - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm44(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L4A4_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - { - /* general path */ - const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLubyte *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLubyte *dstUS = (GLubyte *) dstRow; - for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance, src[1] is alpha */ - dstUS[col] = PACK_COLOR_44( src[1], - src[0] ); - src += 2; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm88(TEXSTORE_PARAMS) -{ - const GLboolean littleEndian = _mesa_little_endian(); - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L8A8_UNORM || - dstFormat == MESA_FORMAT_A8L8_UNORM || - dstFormat == MESA_FORMAT_R8G8_UNORM || - dstFormat == MESA_FORMAT_G8R8_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - littleEndian && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if (dstFormat == MESA_FORMAT_L8A8_UNORM || dstFormat == MESA_FORMAT_A8L8_UNORM) { - if ((littleEndian && dstFormat == MESA_FORMAT_L8A8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_A8L8_UNORM)) { - dstmap[0] = 0; - dstmap[1] = 3; - } - else { - dstmap[0] = 3; - dstmap[1] = 0; - } - } - else { - if ((littleEndian && dstFormat == MESA_FORMAT_R8G8_UNORM) || - (!littleEndian && dstFormat == MESA_FORMAT_G8R8_UNORM)) { - dstmap[0] = 0; - dstmap[1] = 1; - } - else { - dstmap[0] = 1; - dstmap[1] = 0; - } - } - dstmap[2] = ZERO; /* ? */ - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 2, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - /* general path */ - const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLubyte *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - if (dstFormat == MESA_FORMAT_L8A8_UNORM || - dstFormat == MESA_FORMAT_R8G8_UNORM) { - for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance (or R), src[1] is alpha (or G) */ - dstUS[col] = PACK_COLOR_88( src[1], - src[0] ); - src += 2; - } - } - else { - for (col = 0; col < srcWidth; col++) { - /* src[0] is luminance (or R), src[1] is alpha (or G) */ - dstUS[col] = PACK_COLOR_88_REV( src[1], - src[0] ); - src += 2; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats. - */ -static GLboolean -_mesa_texstore_unorm1616(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L16A16_UNORM || - dstFormat == MESA_FORMAT_A16L16_UNORM || - dstFormat == MESA_FORMAT_R16G16_UNORM || - dstFormat == MESA_FORMAT_G16R16_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - if (dstFormat == MESA_FORMAT_L16A16_UNORM || - dstFormat == MESA_FORMAT_R16G16_UNORM) { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_USHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[1]); - dstUI[col] = PACK_COLOR_1616(a, l); - src += 2; - } - } - else { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_USHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[1]); - dstUI[col] = PACK_COLOR_1616_REV(a, l); - src += 2; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* Texstore for R16, A16, L16, I16. */ -static GLboolean -_mesa_texstore_unorm16(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R_UNORM16 || - dstFormat == MESA_FORMAT_A_UNORM16 || - dstFormat == MESA_FORMAT_L_UNORM16 || - dstFormat == MESA_FORMAT_I_UNORM16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r; - - UNCLAMPED_FLOAT_TO_USHORT(r, src[0]); - dstUS[col] = r; - src += 1; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_rgba_16(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_RGBA_UNORM16 || - dstFormat == MESA_FORMAT_RGBX_UNORM16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 8); - - { - /* general path */ - /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 - * if the internal format is RGB. */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - - if (!tempImage) - return GL_FALSE; - - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstUS = (GLushort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r, g, b, a; - - UNCLAMPED_FLOAT_TO_USHORT(r, src[0]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[1]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[2]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[3]); - dstUS[col*4+0] = r; - dstUS[col*4+1] = g; - dstUS[col*4+2] = b; - dstUS[col*4+3] = a; - src += 4; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_RGB_SNORM16 || - dstFormat == MESA_FORMAT_RGBA_SNORM16 || - dstFormat == MESA_FORMAT_RGBX_SNORM16); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2; - GLint img, row, col; - - if (!tempImage) - return GL_FALSE; - - /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2, - * 3 or 4 components/pixel here. - */ - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLshort *dstRowS = (GLshort *) dstRow; - if (dstFormat == MESA_FORMAT_RGBA_SNORM16) { - for (col = 0; col < srcWidth; col++) { - GLuint c; - for (c = 0; c < comps; c++) { - GLshort p; - UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]); - dstRowS[col * comps + c] = p; - } - } - dstRow += dstRowStride; - src += 4 * srcWidth; - } - else if (dstFormat == MESA_FORMAT_RGBX_SNORM16) { - for (col = 0; col < srcWidth; col++) { - GLuint c; - - for (c = 0; c < 3; c++) { - GLshort p; - UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]); - dstRowS[col * comps + c] = p; - } - dstRowS[col * comps + 3] = 32767; - } - dstRow += dstRowStride; - src += 3 * srcWidth; - } - else { - for (col = 0; col < srcWidth; col++) { - GLuint c; - for (c = 0; c < comps; c++) { - GLshort p; - UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]); - dstRowS[col * comps + c] = p; - } - } - dstRow += dstRowStride; - src += 3 * srcWidth; - } - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. - */ -static GLboolean -_mesa_texstore_unorm8(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A_UNORM8 || - dstFormat == MESA_FORMAT_L_UNORM8 || - dstFormat == MESA_FORMAT_I_UNORM8 || - dstFormat == MESA_FORMAT_R_UNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { - GLubyte dstmap[4]; - - /* dstmap - how to swizzle from RGBA to dst format: - */ - if (dstFormat == MESA_FORMAT_A_UNORM8) { - dstmap[0] = 3; - } - else { - dstmap[0] = 0; - } - dstmap[1] = ZERO; /* ? */ - dstmap[2] = ZERO; /* ? */ - dstmap[3] = ONE; /* ? */ - - _mesa_swizzle_ubyte_image(ctx, dims, - srcFormat, - srcType, - baseInternalFormat, - dstmap, 1, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcAddr, - srcPacking); - } - else { - /* general path */ - const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - const GLubyte *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col] = src[col]; - } - dstRow += dstRowStride; - src += srcWidth; - } - } - free((void *) tempImage); - } - return GL_TRUE; } - /** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ @@ -2063,330 +982,6 @@ _mesa_texstore_ycbcr(TEXSTORE_PARAMS) /** - * Store a texture in a signed normalized 8-bit format. - */ -static GLboolean -_mesa_texstore_snorm8(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A_SNORM8 || - dstFormat == MESA_FORMAT_L_SNORM8 || - dstFormat == MESA_FORMAT_I_SNORM8 || - dstFormat == MESA_FORMAT_R_SNORM8); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - for (col = 0; col < srcWidth; col++) { - dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]); - } - dstRow += dstRowStride; - src += srcWidth; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** - * Store a texture in a signed normalized two-channel 16-bit format. - */ -static GLboolean -_mesa_texstore_snorm88(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_L8A8_SNORM || - dstFormat == MESA_FORMAT_G8R8_SNORM || - dstFormat == MESA_FORMAT_R8G8_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dst = (GLushort *) dstRow; - - if (dstFormat == MESA_FORMAT_L8A8_SNORM || - dstFormat == MESA_FORMAT_R8G8_SNORM) { - for (col = 0; col < srcWidth; col++) { - GLubyte l = FLOAT_TO_BYTE_TEX(src[0]); - GLubyte a = FLOAT_TO_BYTE_TEX(src[1]); - - dst[col] = PACK_COLOR_88_REV(l, a); - src += 2; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLubyte l = FLOAT_TO_BYTE_TEX(src[0]); - GLubyte a = FLOAT_TO_BYTE_TEX(src[1]); - - dst[col] = PACK_COLOR_88(l, a); - src += 2; - } - } - - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/* Texstore for signed R16, A16, L16, I16. */ -static GLboolean -_mesa_texstore_snorm16(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R_SNORM16 || - dstFormat == MESA_FORMAT_A_SNORM16 || - dstFormat == MESA_FORMAT_L_SNORM16 || - dstFormat == MESA_FORMAT_I_SNORM16); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLshort *dstUS = (GLshort *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort r; - - UNCLAMPED_FLOAT_TO_SHORT(r, src[0]); - dstUS[col] = r; - src += 1; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/** - * Do texstore for 2-channel, 16-bit/channel, signed normalized formats. - */ -static GLboolean -_mesa_texstore_snorm1616(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_LA_SNORM16 || - dstFormat == MESA_FORMAT_G16R16_SNORM || - dstFormat == MESA_FORMAT_R16G16_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dst = (GLuint *) dstRow; - - if (dstFormat == MESA_FORMAT_LA_SNORM16 || - dstFormat == MESA_FORMAT_R16G16_SNORM) { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); - dst[col] = PACK_COLOR_1616_REV(l, a); - src += 2; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort l, a; - - UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); - UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); - dst[col] = PACK_COLOR_1616_REV(l, a); - src += 2; - } - } - - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -/** - * Store a texture in MESA_FORMAT_X8B8G8R8_SNORM or - * MESA_FORMAT_R8G8B8X8_SNORM. - */ -static GLboolean -_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_X8B8G8R8_SNORM || - dstFormat == MESA_FORMAT_R8G8B8X8_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLbyte *dst = dstRow; - if (dstFormat == MESA_FORMAT_X8B8G8R8_SNORM) { - for (col = 0; col < srcWidth; col++) { - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[0] = 127; - srcRow += 3; - dst += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[3] = 127; - srcRow += 3; - dst += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - - -/** - * Store a texture in MESA_FORMAT_A8B8G8R8_SNORM or - * MESA_FORMAT_R8G8B8A8_SNORM - */ -static GLboolean -_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SNORM || - dstFormat == MESA_FORMAT_R8G8B8A8_SNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLbyte *dstRow = (GLbyte *) dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLbyte *dst = dstRow; - if (dstFormat == MESA_FORMAT_A8B8G8R8_SNORM) { - for (col = 0; col < srcWidth; col++) { - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]); - srcRow += 4; - dst += 4; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); - dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); - dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); - dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]); - srcRow += 4; - dst += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -/** * Store a combined depth/stencil texture image. */ static GLboolean @@ -2599,742 +1194,6 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) } -/** - * Store an image in any of the formats: - * _mesa_texformat_rgba_float32 - * _mesa_texformat_rgb_float32 - * _mesa_texformat_alpha_float32 - * _mesa_texformat_luminance_float32 - * _mesa_texformat_luminance_alpha_float32 - * _mesa_texformat_intensity_float32 - */ -static GLboolean -_mesa_texstore_rgba_float32(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in _mesa_make_temp_float_image */ - if (dstFormat == MESA_FORMAT_RGBX_FLOAT32) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 || - dstFormat == MESA_FORMAT_RGB_FLOAT32 || - dstFormat == MESA_FORMAT_A_FLOAT32 || - dstFormat == MESA_FORMAT_L_FLOAT32 || - dstFormat == MESA_FORMAT_LA_FLOAT32 || - dstFormat == MESA_FORMAT_I_FLOAT32 || - dstFormat == MESA_FORMAT_R_FLOAT32 || - dstFormat == MESA_FORMAT_RG_FLOAT32 || - dstFormat == MESA_FORMAT_RGBX_FLOAT32); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_RG); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat)); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint bytesPerRow; - GLint img, row; - if (!tempImage) - return GL_FALSE; - bytesPerRow = srcWidth * components * sizeof(GLfloat); - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - memcpy(dstRow, srcRow, bytesPerRow); - dstRow += dstRowStride; - srcRow += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - - -/** - * As above, but store 16-bit floats. - */ -static GLboolean -_mesa_texstore_rgba_float16(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in _mesa_make_temp_float_image */ - if (dstFormat == MESA_FORMAT_RGBX_FLOAT16) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 || - dstFormat == MESA_FORMAT_RGB_FLOAT16 || - dstFormat == MESA_FORMAT_A_FLOAT16 || - dstFormat == MESA_FORMAT_L_FLOAT16 || - dstFormat == MESA_FORMAT_LA_FLOAT16 || - dstFormat == MESA_FORMAT_I_FLOAT16 || - dstFormat == MESA_FORMAT_R_FLOAT16 || - dstFormat == MESA_FORMAT_RG_FLOAT16 || - dstFormat == MESA_FORMAT_RGBX_FLOAT16); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_RG); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB)); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLhalfARB *dstTexel = (GLhalfARB *) dstRow; - GLint i; - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = _mesa_float_to_half(src[i]); - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, signed int8 */ -static GLboolean -_mesa_texstore_rgba_int8(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_SINT8) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_SINT8 || - dstFormat == MESA_FORMAT_RG_SINT8 || - dstFormat == MESA_FORMAT_RGB_SINT8 || - dstFormat == MESA_FORMAT_RGBA_SINT8 || - dstFormat == MESA_FORMAT_A_SINT8 || - dstFormat == MESA_FORMAT_I_SINT8 || - dstFormat == MESA_FORMAT_L_SINT8 || - dstFormat == MESA_FORMAT_LA_SINT8 || - dstFormat == MESA_FORMAT_RGBX_SINT8); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte)); - - { - /* general path */ - const GLuint *tempImage = make_temp_uint_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, - srcPacking); - const GLuint *src = tempImage; - GLint img, row; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLbyte *dstTexel = (GLbyte *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, signed int16 */ -static GLboolean -_mesa_texstore_rgba_int16(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_SINT16) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_SINT16 || - dstFormat == MESA_FORMAT_RG_SINT16 || - dstFormat == MESA_FORMAT_RGB_SINT16 || - dstFormat == MESA_FORMAT_RGBA_SINT16 || - dstFormat == MESA_FORMAT_A_SINT16 || - dstFormat == MESA_FORMAT_L_SINT16 || - dstFormat == MESA_FORMAT_I_SINT16 || - dstFormat == MESA_FORMAT_LA_SINT16 || - dstFormat == MESA_FORMAT_RGBX_SINT16); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort)); - - { - /* general path */ - const GLuint *tempImage = make_temp_uint_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, - srcPacking); - const GLuint *src = tempImage; - GLint img, row; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLshort *dstTexel = (GLshort *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, signed int32 */ -static GLboolean -_mesa_texstore_rgba_int32(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_SINT32) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_SINT32 || - dstFormat == MESA_FORMAT_RG_SINT32 || - dstFormat == MESA_FORMAT_RGB_SINT32 || - dstFormat == MESA_FORMAT_RGBA_SINT32 || - dstFormat == MESA_FORMAT_A_SINT32 || - dstFormat == MESA_FORMAT_I_SINT32 || - dstFormat == MESA_FORMAT_L_SINT32 || - dstFormat == MESA_FORMAT_LA_SINT32 || - dstFormat == MESA_FORMAT_RGBX_SINT32); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint)); - - { - /* general path */ - const GLuint *tempImage = make_temp_uint_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, - srcPacking); - const GLuint *src = tempImage; - GLint img, row; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLint *dstTexel = (GLint *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLint) src[i]; - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, unsigned int8 */ -static GLboolean -_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_UINT8) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_UINT8 || - dstFormat == MESA_FORMAT_RG_UINT8 || - dstFormat == MESA_FORMAT_RGB_UINT8 || - dstFormat == MESA_FORMAT_RGBA_UINT8 || - dstFormat == MESA_FORMAT_A_UINT8 || - dstFormat == MESA_FORMAT_I_UINT8 || - dstFormat == MESA_FORMAT_L_UINT8 || - dstFormat == MESA_FORMAT_LA_UINT8 || - dstFormat == MESA_FORMAT_RGBX_UINT8); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte)); - - { - /* general path */ - const GLuint *tempImage = - make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - const GLuint *src = tempImage; - GLint img, row; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLubyte *dstTexel = (GLubyte *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLubyte) MIN2(src[i], 0xff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, unsigned int16 */ -static GLboolean -_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_UINT16) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_UINT16 || - dstFormat == MESA_FORMAT_RG_UINT16 || - dstFormat == MESA_FORMAT_RGB_UINT16 || - dstFormat == MESA_FORMAT_RGBA_UINT16 || - dstFormat == MESA_FORMAT_A_UINT16 || - dstFormat == MESA_FORMAT_I_UINT16 || - dstFormat == MESA_FORMAT_L_UINT16 || - dstFormat == MESA_FORMAT_LA_UINT16 || - dstFormat == MESA_FORMAT_RGBX_UINT16); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort)); - - { - /* general path */ - const GLuint *tempImage = - make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - const GLuint *src = tempImage; - GLint img, row; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLushort *dstTexel = (GLushort *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLushort) MIN2(src[i], 0xffff); - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -/* non-normalized, unsigned int32 */ -static GLboolean -_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) -{ - GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - GLint components = _mesa_components_in_format(baseFormat); - - /* this forces alpha to 1 in make_temp_uint_image */ - if (dstFormat == MESA_FORMAT_RGBX_UINT32) { - baseFormat = GL_RGBA; - components = 4; - } - - ASSERT(dstFormat == MESA_FORMAT_R_UINT32 || - dstFormat == MESA_FORMAT_RG_UINT32 || - dstFormat == MESA_FORMAT_RGB_UINT32 || - dstFormat == MESA_FORMAT_RGBA_UINT32 || - dstFormat == MESA_FORMAT_A_UINT32 || - dstFormat == MESA_FORMAT_I_UINT32 || - dstFormat == MESA_FORMAT_L_UINT32 || - dstFormat == MESA_FORMAT_LA_UINT32 || - dstFormat == MESA_FORMAT_RGBX_UINT32); - ASSERT(baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB || - baseInternalFormat == GL_RG || - baseInternalFormat == GL_RED || - baseInternalFormat == GL_ALPHA || - baseInternalFormat == GL_LUMINANCE || - baseInternalFormat == GL_LUMINANCE_ALPHA || - baseInternalFormat == GL_INTENSITY); - ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint)); - - { - /* general path */ - const GLuint *tempImage = - make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - const GLuint *src = tempImage; - GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); - GLint img, row; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstTexel = (GLuint *) dstRow; - GLint i; - if (is_unsigned) { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = src[i]; - } - } else { - for (i = 0; i < srcWidth * components; i++) { - dstTexel[i] = MAX2((GLint) src[i], 0); - } - } - dstRow += dstRowStride; - src += srcWidth * components; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean -_mesa_texstore_srgb8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_BGR_SRGB8); - - /* reuse normal rgb texstore code */ - newDstFormat = MESA_FORMAT_BGR_UNORM8; - - k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_srgba8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SRGB || - dstFormat == MESA_FORMAT_R8G8B8X8_SRGB || - dstFormat == MESA_FORMAT_R8G8B8A8_SRGB); - - newDstFormat = _mesa_get_srgb_format_linear(dstFormat); - - k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_sargb8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - assert(dstFormat == MESA_FORMAT_B8G8R8A8_SRGB || - dstFormat == MESA_FORMAT_B8G8R8X8_SRGB); - - newDstFormat = _mesa_get_srgb_format_linear(dstFormat); - - k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_sl8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_L_SRGB8); - - newDstFormat = MESA_FORMAT_L_UNORM8; - - /* _mesa_textore_a8 handles luminance8 too */ - k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - - -static GLboolean -_mesa_texstore_sla8(TEXSTORE_PARAMS) -{ - mesa_format newDstFormat; - GLboolean k; - - ASSERT(dstFormat == MESA_FORMAT_L8A8_SRGB); - - /* reuse normal luminance/alpha texstore code */ - newDstFormat = MESA_FORMAT_L8A8_UNORM; - - k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat, - newDstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, - srcAddr, srcPacking); - return k; -} - -static GLboolean -_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R9G9B9E5_FLOAT); - ASSERT(baseInternalFormat == GL_RGB); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint*)dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]); - } - dstRow += dstRowStride; - srcRow += srcWidth * 3; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R11G11B10_FLOAT); - ASSERT(baseInternalFormat == GL_RGB); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *srcRow = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint*)dstRow; - for (col = 0; col < srcWidth; col++) { - dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]); - } - dstRow += dstRowStride; - srcRow += srcWidth * 3; - } - } - - free((void *) tempImage); - } - return GL_TRUE; -} - - static GLboolean _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) { @@ -3496,118 +1355,16 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) return GL_TRUE; } -static GLboolean -_mesa_texstore_abgr2101010(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* general path */ - const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); - const GLfloat *src = tempImage; - GLint img, row, col; - if (!tempImage) - return GL_FALSE; - for (img = 0; img < srcDepth; img++) { - GLubyte *dstRow = dstSlices[img]; - - for (row = 0; row < srcHeight; row++) { - GLuint *dstUI = (GLuint *) dstRow; - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r); - src += 4; - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} static GLboolean -_mesa_texstore_null(TEXSTORE_PARAMS) -{ - (void) ctx; (void) dims; - (void) baseInternalFormat; - (void) dstFormat; - (void) dstRowStride; (void) dstSlices, - (void) srcWidth; (void) srcHeight; (void) srcDepth; - (void) srcFormat; (void) srcType; - (void) srcAddr; - (void) srcPacking; - - /* should never happen */ - _mesa_problem(NULL, "_mesa_texstore_null() is called"); - return GL_FALSE; -} - - -/** - * Return the StoreTexImageFunc pointer to store an image in the given format. - */ -static StoreTexImageFunc -_mesa_get_texstore_func(mesa_format format) +texstore_depth_stencil(TEXSTORE_PARAMS) { static StoreTexImageFunc table[MESA_FORMAT_COUNT]; static GLboolean initialized = GL_FALSE; if (!initialized) { - table[MESA_FORMAT_NONE] = _mesa_texstore_null; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_R8G8B8A8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_B8G8R8A8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_A8R8G8B8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_X8B8G8R8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_R8G8B8X8_UNORM] = _mesa_texstore_rgba8888; - table[MESA_FORMAT_B8G8R8X8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_X8R8G8B8_UNORM] = _mesa_texstore_argb8888; - table[MESA_FORMAT_BGR_UNORM8] = _mesa_texstore_rgb888; - table[MESA_FORMAT_RGB_UNORM8] = _mesa_texstore_bgr888; - table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565; - table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565; - table[MESA_FORMAT_B4G4R4A4_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A4R4G4B4_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A1B5G5R5_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_B5G5R5A1_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A1R5G5B5_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_L4A4_UNORM] = _mesa_texstore_unorm44; - table[MESA_FORMAT_L8A8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_A8L8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_L16A16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_A16L16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_B2G3R3_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_A_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_A_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_L_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_L_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_I_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_I_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; - table[MESA_FORMAT_R_UNORM8] = _mesa_texstore_unorm8; - table[MESA_FORMAT_R8G8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_G8R8_UNORM] = _mesa_texstore_unorm88; - table[MESA_FORMAT_R_UNORM16] = _mesa_texstore_unorm16; - table[MESA_FORMAT_R16G16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_G16R16_UNORM] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_B10G10R10A2_UNORM] = _mesa_texstore_argb2101010; + memset(table, 0, sizeof table); + table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8; table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24; table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16; @@ -3615,11 +1372,28 @@ _mesa_get_texstore_func(mesa_format format) table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8; table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32; table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8; - table[MESA_FORMAT_BGR_SRGB8] = _mesa_texstore_srgb8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_B8G8R8A8_SRGB] = _mesa_texstore_sargb8; - table[MESA_FORMAT_L_SRGB8] = _mesa_texstore_sl8; - table[MESA_FORMAT_L8A8_SRGB] = _mesa_texstore_sla8; + table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32; + table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; + + initialized = GL_TRUE; + } + + ASSERT(table[dstFormat]); + return table[dstFormat](ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); +} + +static GLboolean +texstore_compressed(TEXSTORE_PARAMS) +{ + static StoreTexImageFunc table[MESA_FORMAT_COUNT]; + static GLboolean initialized = GL_FALSE; + + if (!initialized) { + memset(table, 0, sizeof table); + table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1; table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1; table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3; @@ -3630,32 +1404,6 @@ _mesa_get_texstore_func(mesa_format format) table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1; table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3; table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5; - table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_A_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_A_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_L_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_L_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_LA_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_LA_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_I_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_I_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_R_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_R8G8_SNORM] = _mesa_texstore_snorm88; - table[MESA_FORMAT_X8B8G8R8_SNORM] = _mesa_texstore_signed_rgbx8888; - table[MESA_FORMAT_A8B8G8R8_SNORM] = _mesa_texstore_signed_rgba8888; - table[MESA_FORMAT_R8G8B8A8_SNORM] = _mesa_texstore_signed_rgba8888; - table[MESA_FORMAT_R_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_R16G16_SNORM] = _mesa_texstore_snorm1616; - table[MESA_FORMAT_RGB_SNORM16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBA_SNORM16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBA_UNORM16] = _mesa_texstore_rgba_16; table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1; table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1; table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2; @@ -3677,107 +1425,327 @@ _mesa_get_texstore_func(mesa_format format) _mesa_texstore_etc2_rgb8_punchthrough_alpha1; table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = _mesa_texstore_etc2_srgb8_punchthrough_alpha1; - table[MESA_FORMAT_A_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_L_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_L8A8_SNORM] = _mesa_texstore_snorm88; - table[MESA_FORMAT_I_SNORM8] = _mesa_texstore_snorm8; - table[MESA_FORMAT_A_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_L_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_LA_SNORM16] = _mesa_texstore_snorm1616; - table[MESA_FORMAT_I_SNORM16] = _mesa_texstore_snorm16; - table[MESA_FORMAT_R9G9B9E5_FLOAT] = _mesa_texstore_rgb9_e5; - table[MESA_FORMAT_R11G11B10_FLOAT] = _mesa_texstore_r11_g11_b10f; - table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32; - table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; - table[MESA_FORMAT_A_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_A_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_A_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_A_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_A_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_A_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_I_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_I_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_I_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_I_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_I_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_I_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_L_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_L_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_L_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_L_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_L_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_L_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_LA_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_LA_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_LA_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_LA_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_LA_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_LA_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RG_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RGB_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_RGBA_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_R_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RG_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGB_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGBA_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_R_SINT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RG_SINT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RGB_SINT32] = _mesa_texstore_rgba_int32; - table[MESA_FORMAT_RGBA_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32; + initialized = GL_TRUE; + } + + ASSERT(table[dstFormat]); + return table[dstFormat](ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); +} + +static void +invert_swizzle(uint8_t dst[4], const uint8_t src[4]) +{ + int i, j; + + dst[0] = MESA_FORMAT_SWIZZLE_NONE; + dst[1] = MESA_FORMAT_SWIZZLE_NONE; + dst[2] = MESA_FORMAT_SWIZZLE_NONE; + dst[3] = MESA_FORMAT_SWIZZLE_NONE; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE) + dst[i] = j; +} + +/** Store a texture by per-channel conversions and swizzling. + * + * This function attempts to perform a texstore operation by doing simple + * per-channel conversions and swizzling. This covers a huge chunk of the + * texture storage operations that anyone cares about. If this function is + * incapable of performing the operation, it bails and returns GL_FALSE. + */ +static GLboolean +texstore_swizzle(TEXSTORE_PARAMS) +{ + const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, + srcFormat, srcType); + const GLint srcImageStride = _mesa_image_image_stride(srcPacking, + srcWidth, srcHeight, srcFormat, srcType); + const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims, + srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); + const int src_components = _mesa_components_in_format(srcFormat); + + GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4]; + const GLubyte *swap; + GLenum dst_type; + int dst_components; + bool is_array, normalized, need_swap; + GLint i, img, row; + const GLubyte *src_row; + GLubyte *dst_row; + + is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components, + rgba2dst, &normalized); + + if (!is_array) + return GL_FALSE; + + switch (srcType) { + case GL_FLOAT: + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_INT: + /* If wa have to swap bytes in a multi-byte datatype, that means + * we're not doing an array conversion anymore */ + if (srcPacking->SwapBytes) + return GL_FALSE; + need_swap = false; + break; + case GL_UNSIGNED_INT_8_8_8_8: + need_swap = srcPacking->SwapBytes; + if (_mesa_little_endian()) + need_swap = !need_swap; + srcType = GL_UNSIGNED_BYTE; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + need_swap = srcPacking->SwapBytes; + if (!_mesa_little_endian()) + need_swap = !need_swap; + srcType = GL_UNSIGNED_BYTE; + break; + default: + return GL_FALSE; + } + swap = need_swap ? map_3210 : map_identity; + + compute_component_mapping(srcFormat, baseInternalFormat, base2src); + compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); + invert_swizzle(dst2rgba, rgba2dst); + + for (i = 0; i < 4; i++) { + if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE) + swizzle[i] = MESA_FORMAT_SWIZZLE_NONE; + else + swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]]; + } + + /* Is it normalized? */ + normalized |= !_mesa_is_enum_format_integer(srcFormat); + + for (img = 0; img < srcDepth; img++) { + if (dstRowStride == srcWidth * dst_components && + srcRowStride == srcWidth * src_components) { + _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components, + srcImage, srcType, src_components, + swizzle, normalized, srcWidth * srcHeight); + } else { + src_row = srcImage; + dst_row = dstSlices[img]; + for (row = 0; row < srcHeight; row++) { + _mesa_swizzle_and_convert(dst_row, dst_type, dst_components, + src_row, srcType, src_components, + swizzle, normalized, srcWidth); + dst_row += dstRowStride; + src_row += srcRowStride; + } + } + srcImage += srcImageStride; + } + + return GL_TRUE; +} + + +/** Stores a texture by converting float and then to the texture format + * + * This function performs a texstore operation by converting to float, + * applying pixel transfer ops, and then converting to the texture's + * internal format using pixel store functions. This function will work + * for any rgb or srgb textore format. + */ +static GLboolean +texstore_via_float(TEXSTORE_PARAMS) +{ + GLuint i, img, row; + const GLint src_stride = + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + float *tmp_row; + bool need_convert; + uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6]; + + tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row)); + if (!tmp_row) + return GL_FALSE; + + /* The GL spec (4.0, compatibility profile) only specifies srgb + * conversion as something that is done in the sampler during the + * filtering process before the colors are handed to the shader. + * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec) + * does not list RGB <-> sRGB conversions anywhere. Therefore, we just + * treat sRGB formats the same as RGB formats for the purposes of + * texture upload and transfer ops. + */ + dstFormat = _mesa_get_srgb_format_linear(dstFormat); + + need_convert = false; + if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) { + compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba); + compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); + for (i = 0; i < 4; ++i) { + map[i] = base2rgba[rgba2base[i]]; + if (map[i] != i) + need_convert = true; + } + } + + for (img = 0; img < srcDepth; img++) { + dst_row = dstSlices[img]; + src_row = _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + for (row = 0; row < srcHeight; row++) { + _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, tmp_row, + srcFormat, srcType, src_row, + srcPacking, ctx->_ImageTransferState); + if (need_convert) + _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4, + tmp_row, GL_FLOAT, 4, + map, false, srcWidth); + _mesa_pack_float_rgba_row(dstFormat, srcWidth, + (const GLfloat (*)[4])tmp_row, + dst_row); + dst_row += dstRowStride; + src_row += src_stride; + } + } + + return GL_TRUE; +} + +/** Stores an integer rgba texture + * + * This function performs an integer texture storage operation by unpacking + * the texture to 32-bit integers, and repacking it into the internal + * format of the texture. This will work for any integer rgb texture + * storage operation. + */ +static GLboolean +texstore_rgba_integer(TEXSTORE_PARAMS) +{ + GLuint i, img, row, *tmp_row; + GLenum dst_type, tmp_type; + const GLint src_stride = + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); + int num_dst_components; + bool is_array, normalized; + uint8_t *src_row, *dst_row; + uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4]; + + tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row)); + if (!tmp_row) + return GL_FALSE; + + is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components, + rgba2dst, &normalized); + + assert(is_array && !normalized); + + if (!is_array) + return GL_FALSE; + + invert_swizzle(dst2rgba, rgba2dst); + compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba); + compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base); + + for (i = 0; i < 4; ++i) { + if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE) + swizzle[i] = MESA_FORMAT_SWIZZLE_NONE; + else + swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]]; + } + + if (_mesa_is_type_unsigned(srcType)) { + tmp_type = GL_UNSIGNED_INT; + } else { + tmp_type = GL_INT; + } + + for (img = 0; img < srcDepth; img++) { + dst_row = dstSlices[img]; + src_row = _mesa_image_address(dims, srcPacking, srcAddr, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + for (row = 0; row < srcHeight; row++) { + _mesa_unpack_color_span_uint(ctx, srcWidth, GL_RGBA, tmp_row, + srcFormat, srcType, src_row, srcPacking); + _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components, + tmp_row, tmp_type, 4, + swizzle, false, srcWidth); + dst_row += dstRowStride; + src_row += src_stride; + } + } + + return GL_TRUE; +} + +static GLboolean +texstore_rgba(TEXSTORE_PARAMS) +{ + static StoreTexImageFunc table[MESA_FORMAT_COUNT]; + static GLboolean initialized = GL_FALSE; + + if (!initialized) { + memset(table, 0, sizeof table); + + table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565; + table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565; + table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; + table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint; table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint; - table[MESA_FORMAT_B4G4R4X4_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_B5G5R5X1_UNORM] = store_ubyte_texture; - table[MESA_FORMAT_R8G8B8X8_SNORM] = _mesa_texstore_signed_rgbx8888; - table[MESA_FORMAT_R8G8B8X8_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_R8G8B8A8_SRGB] = _mesa_texstore_srgba8; - table[MESA_FORMAT_RGBX_UINT8] = _mesa_texstore_rgba_uint8; - table[MESA_FORMAT_RGBX_SINT8] = _mesa_texstore_rgba_int8; - table[MESA_FORMAT_B10G10R10X2_UNORM] = _mesa_texstore_argb2101010; - table[MESA_FORMAT_RGBX_UNORM16] = _mesa_texstore_rgba_16; - table[MESA_FORMAT_RGBX_SNORM16] = _mesa_texstore_signed_rgba_16; - table[MESA_FORMAT_RGBX_FLOAT16] = _mesa_texstore_rgba_float16; - table[MESA_FORMAT_RGBX_UINT16] = _mesa_texstore_rgba_uint16; - table[MESA_FORMAT_RGBX_SINT16] = _mesa_texstore_rgba_int16; - table[MESA_FORMAT_RGBX_FLOAT32] = _mesa_texstore_rgba_float32; - table[MESA_FORMAT_RGBX_UINT32] = _mesa_texstore_rgba_uint32; - table[MESA_FORMAT_RGBX_SINT32] = _mesa_texstore_rgba_int32; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = _mesa_texstore_abgr2101010; - - table[MESA_FORMAT_G8R8_SNORM] = _mesa_texstore_snorm88; - table[MESA_FORMAT_G16R16_SNORM] = _mesa_texstore_snorm1616; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = _mesa_texstore_sargb8; - initialized = GL_TRUE; } - ASSERT(table[format]); - return table[format]; -} + if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking)) { + return GL_TRUE; + } + + if (texstore_swizzle(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking)) { + return GL_TRUE; + } + if (_mesa_is_format_integer(dstFormat)) { + return texstore_rgba_integer(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + } else if (_mesa_get_format_max_bits(dstFormat) <= 8 && + !_mesa_is_format_signed(dstFormat)) { + return store_ubyte_texture(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } else { + return texstore_via_float(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); + } +} GLboolean _mesa_texstore_needs_transfer_ops(struct gl_context *ctx, @@ -3863,8 +1831,6 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS) srcAddr, srcPacking); return GL_TRUE; } - - /** * Store user data into texture memory. * Called via glTex[Sub]Image1/2/3D() @@ -3873,9 +1839,6 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS) GLboolean _mesa_texstore(TEXSTORE_PARAMS) { - StoreTexImageFunc storeImage; - GLboolean success; - if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat, dstFormat, dstRowStride, dstSlices, @@ -3884,14 +1847,22 @@ _mesa_texstore(TEXSTORE_PARAMS) return GL_TRUE; } - storeImage = _mesa_get_texstore_func(dstFormat); - - success = storeImage(ctx, dims, baseInternalFormat, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - return success; + if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) { + return texstore_depth_stencil(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } else if (_mesa_is_format_compressed(dstFormat)) { + return texstore_compressed(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } else { + return texstore_rgba(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking); + } } diff --git a/mesalib/src/mesa/main/textureview.c b/mesalib/src/mesa/main/textureview.c index 77a3b782b..b3521e219 100644 --- a/mesalib/src/mesa/main/textureview.c +++ b/mesalib/src/mesa/main/textureview.c @@ -320,15 +320,11 @@ target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget) * If an error is found, record it with _mesa_error() * \return false if any error, true otherwise. */ -static bool -compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTexObj, - GLenum internalformat) +GLboolean +_mesa_texture_view_compatible_format(struct gl_context *ctx, + GLenum origInternalFormat, + GLenum newInternalFormat) { - /* Level 0 of a texture created by glTextureStorage or glTextureView - * is always defined. - */ - struct gl_texture_image *texImage = origTexObj->Image[0][0]; - GLint origInternalFormat = texImage->InternalFormat; unsigned int origViewClass, newViewClass; /* The two textures' internal formats must be compatible according to @@ -337,19 +333,15 @@ compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTe * The internal formats must be identical if not in that table, * or an INVALID_OPERATION error is generated. */ - if (origInternalFormat == internalformat) - return true; + if (origInternalFormat == newInternalFormat) + return GL_TRUE; origViewClass = lookup_view_class(ctx, origInternalFormat); - newViewClass = lookup_view_class(ctx, internalformat); + newViewClass = lookup_view_class(ctx, newInternalFormat); if ((origViewClass == newViewClass) && origViewClass != false) - return true; + return GL_TRUE; - _mesa_error(ctx, GL_INVALID_OPERATION, - "glTextureView(internalformat %s not compatible with origtexture %s)", - _mesa_lookup_enum_by_nr(internalformat), - _mesa_lookup_enum_by_nr(origInternalFormat)); - return false; + return GL_FALSE; } /** * Helper function for TexStorage and teximagemultisample to set immutable @@ -512,8 +504,14 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, return; } - if (!compatible_format(ctx, origTexObj, internalformat)) { - return; /* Error logged */ + if (!_mesa_texture_view_compatible_format(ctx, + origTexObj->Image[0][0]->InternalFormat, + internalformat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureView(internalformat %s not compatible with origtexture %s)", + _mesa_lookup_enum_by_nr(internalformat), + _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat)); + return; } texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, diff --git a/mesalib/src/mesa/main/textureview.h b/mesalib/src/mesa/main/textureview.h index 3088ac193..549a13cd8 100644 --- a/mesalib/src/mesa/main/textureview.h +++ b/mesalib/src/mesa/main/textureview.h @@ -29,6 +29,10 @@ #ifndef TEXTUREVIEW_H #define TEXTUREVIEW_H +GLboolean +_mesa_texture_view_compatible_format(struct gl_context *ctx, + GLenum origInternalFormat, + GLenum newInternalFormat); extern void GLAPIENTRY _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 609d94bd7..7e630e65b 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -171,18 +171,17 @@ _mesa_GetActiveUniformsiv(GLuint program, _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)"); } -static bool +static struct gl_uniform_storage * validate_uniform_parameters(struct gl_context *ctx, struct gl_shader_program *shProg, GLint location, GLsizei count, - unsigned *loc, unsigned *array_index, const char *caller, bool negative_one_is_not_valid) { if (!shProg || !shProg->LinkStatus) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller); - return false; + return NULL; } if (location == -1) { @@ -214,7 +213,7 @@ validate_uniform_parameters(struct gl_context *ctx, caller, location); } - return false; + return NULL; } /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec: @@ -224,7 +223,7 @@ validate_uniform_parameters(struct gl_context *ctx, */ if (count < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller); - return false; + return NULL; } /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: @@ -243,14 +242,14 @@ validate_uniform_parameters(struct gl_context *ctx, if (location < -1) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", caller, location); - return false; + return NULL; } /* Check that the given location is in bounds of uniform remap table. */ if (location >= (GLint) shProg->NumUniformRemapTable) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", caller, location); - return false; + return NULL; } /* If the driver storage pointer in remap table is -1, we ignore silently. @@ -266,30 +265,33 @@ validate_uniform_parameters(struct gl_context *ctx, */ if (shProg->UniformRemapTable[location] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) - return false; + return NULL; - _mesa_uniform_split_location_offset(shProg, location, loc, array_index); + struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location]; - if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) { + if (uni->array_elements == 0 && count > 1) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(count > 1 for non-array, location=%d)", caller, location); - return false; + return NULL; } + /* The array index specified by the uniform location is just the uniform + * location minus the base location of of the uniform. + */ + *array_index = location - uni->remap_location; + /* If the uniform is an array, check that array_index is in bounds. * If not an array, check that array_index is zero. * array_index is unsigned so no need to check for less than zero. */ - unsigned limit = shProg->UniformStorage[*loc].array_elements; - if (limit == 0) - limit = 1; + const unsigned limit = MAX2(uni->array_elements, 1); if (*array_index >= limit) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", caller, location); - return false; + return NULL; } - return true; + return uni; } /** @@ -302,15 +304,14 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, { struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); - struct gl_uniform_storage *uni; - unsigned loc, offset; + unsigned offset; - if (!validate_uniform_parameters(ctx, shProg, location, 1, - &loc, &offset, "glGetUniform", true)) + struct gl_uniform_storage *const uni = + validate_uniform_parameters(ctx, shProg, location, 1, + &offset, "glGetUniform", true); + if (uni == NULL) return; - uni = &shProg->UniformStorage[loc]; - { unsigned elements = (uni->type->is_sampler()) ? 1 : uni->type->components(); @@ -607,18 +608,17 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, GLint location, GLsizei count, const GLvoid *values, GLenum type) { - unsigned loc, offset; + unsigned offset; unsigned components; unsigned src_components; enum glsl_base_type basicType; - struct gl_uniform_storage *uni; - if (!validate_uniform_parameters(ctx, shProg, location, count, - &loc, &offset, "glUniform", false)) + struct gl_uniform_storage *const uni = + validate_uniform_parameters(ctx, shProg, location, count, + &offset, "glUniform", false); + if (uni == NULL) return; - uni = &shProg->UniformStorage[loc]; - /* Verify that the types are compatible. */ switch (type) { @@ -894,17 +894,17 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, GLint location, GLsizei count, GLboolean transpose, const GLfloat *values) { - unsigned loc, offset; + unsigned offset; unsigned vectors; unsigned components; unsigned elements; - struct gl_uniform_storage *uni; - if (!validate_uniform_parameters(ctx, shProg, location, count, - &loc, &offset, "glUniformMatrix", false)) + struct gl_uniform_storage *const uni = + validate_uniform_parameters(ctx, shProg, location, count, + &offset, "glUniformMatrix", false); + if (uni == NULL) return; - uni = &shProg->UniformStorage[loc]; if (!uni->type->is_matrix()) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(non-matrix uniform)"); @@ -993,9 +993,7 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, * * Returns the uniform index into UniformStorage (also the * glGetActiveUniformsiv uniform index), and stores the referenced - * array offset in *offset, or GL_INVALID_INDEX (-1). Those two - * return values can be encoded into a uniform location for - * glUniform* using _mesa_uniform_merge_location_offset(index, offset). + * array offset in *offset, or GL_INVALID_INDEX (-1). */ extern "C" unsigned _mesa_get_uniform_location(struct gl_context *ctx, diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index f450173af..0d0cbf57e 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -932,7 +932,8 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) shProg->UniformStorage[index].atomic_buffer_index != -1) return -1; - return _mesa_uniform_merge_location_offset(shProg, index, offset); + /* location in remap table + array element offset */ + return shProg->UniformStorage[index].remap_location + offset; } GLuint GLAPIENTRY @@ -1089,18 +1090,38 @@ _mesa_GetActiveUniformBlockiv(GLuint program, params[0] = strlen(block->Name) + 1; return; - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: - params[0] = block->NumUniforms; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: { + unsigned count = 0; + + for (i = 0; i < block->NumUniforms; i++) { + unsigned offset; + const int idx = + _mesa_get_uniform_location(ctx, shProg, + block->Uniforms[i].IndexName, + &offset); + if (idx != -1) + count++; + } + + params[0] = count; return; + } + + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: { + unsigned count = 0; - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: for (i = 0; i < block->NumUniforms; i++) { unsigned offset; - params[i] = _mesa_get_uniform_location(ctx, shProg, - block->Uniforms[i].IndexName, - &offset); + const int idx = + _mesa_get_uniform_location(ctx, shProg, + block->Uniforms[i].IndexName, + &offset); + + if (idx != -1) + params[count++] = idx; } return; + } case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1; diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h index 10518dcbb..e7a370e84 100644 --- a/mesalib/src/mesa/main/uniforms.h +++ b/mesalib/src/mesa/main/uniforms.h @@ -323,69 +323,6 @@ struct gl_builtin_uniform_desc { unsigned int num_elements; }; -/** - * \name GLSL uniform arrays and structs require special handling. - * - * The GL_ARB_shader_objects spec says that if you use - * glGetUniformLocation to get the location of an array, you CANNOT - * access other elements of the array by adding an offset to the - * returned location. For example, you must call - * glGetUniformLocation("foo[16]") if you want to set the 16th element - * of the array with glUniform(). - * - * HOWEVER, some other OpenGL drivers allow accessing array elements - * by adding an offset to the returned array location. And some apps - * seem to depend on that behaviour. - * - * Mesa's gl_uniform_list doesn't directly support this since each - * entry in the list describes one uniform variable, not one uniform - * element. We could insert dummy entries in the list for each array - * element after [0] but that causes complications elsewhere. - * - * We solve this problem by creating multiple entries for uniform arrays - * in the UniformRemapTable so that their elements get sequential locations. - * - * Utility functions below offer functionality to split UniformRemapTable - * location in to location of the uniform in UniformStorage + offset to the - * array element (0 if not an array) and also merge it back again as the - * UniformRemapTable location. - * - */ -/*@{*/ -/** - * Combine the uniform's storage index and the array index - */ -static inline GLint -_mesa_uniform_merge_location_offset(const struct gl_shader_program *prog, - unsigned storage_index, - unsigned uniform_array_index) -{ - /* location in remap table + array element offset */ - return prog->UniformStorage[storage_index].remap_location + - uniform_array_index; -} - -/** - * Separate the uniform storage index and array index - */ -static inline void -_mesa_uniform_split_location_offset(const struct gl_shader_program *prog, - GLint location, unsigned *storage_index, - unsigned *uniform_array_index) -{ - *storage_index = prog->UniformRemapTable[location] - prog->UniformStorage; - *uniform_array_index = location - - prog->UniformRemapTable[location]->remap_location; - - /*gl_uniform_storage in UniformStorage with the calculated base_location - * must match with the entry in remap table - */ - assert(&prog->UniformStorage[*storage_index] == - prog->UniformRemapTable[location]); -} -/*@}*/ - - #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 46956efb5..230fb30cb 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -24,6 +24,8 @@ */ +#include <inttypes.h> /* for PRId64 macro */ + #include "glheader.h" #include "imports.h" #include "bufferobj.h" @@ -46,21 +48,22 @@ /** Used to indicate which GL datatypes are accepted by each of the * glVertex/Color/Attrib/EtcPointer() functions. */ -#define BOOL_BIT 0x1 -#define BYTE_BIT 0x2 -#define UNSIGNED_BYTE_BIT 0x4 -#define SHORT_BIT 0x8 -#define UNSIGNED_SHORT_BIT 0x10 -#define INT_BIT 0x20 -#define UNSIGNED_INT_BIT 0x40 -#define HALF_BIT 0x80 -#define FLOAT_BIT 0x100 -#define DOUBLE_BIT 0x200 -#define FIXED_ES_BIT 0x400 -#define FIXED_GL_BIT 0x800 -#define UNSIGNED_INT_2_10_10_10_REV_BIT 0x1000 -#define INT_2_10_10_10_REV_BIT 0x2000 -#define UNSIGNED_INT_10F_11F_11F_REV_BIT 0x4000 +#define BOOL_BIT (1 << 0) +#define BYTE_BIT (1 << 1) +#define UNSIGNED_BYTE_BIT (1 << 2) +#define SHORT_BIT (1 << 3) +#define UNSIGNED_SHORT_BIT (1 << 4) +#define INT_BIT (1 << 5) +#define UNSIGNED_INT_BIT (1 << 6) +#define HALF_BIT (1 << 7) +#define FLOAT_BIT (1 << 8) +#define DOUBLE_BIT (1 << 9) +#define FIXED_ES_BIT (1 << 10) +#define FIXED_GL_BIT (1 << 11) +#define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12) +#define INT_2_10_10_10_REV_BIT (1 << 13) +#define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14) +#define ALL_TYPE_BITS ((1 << 15) - 1) /** Convert GL datatype enum into a <type>_BIT value seen above */ @@ -179,6 +182,53 @@ vertex_binding_divisor(struct gl_context *ctx, GLuint bindingIndex, /** + * Examine the API profile and extensions to determine which types are legal + * for vertex arrays. This is called once from update_array_format(). + */ +static GLbitfield +get_legal_types_mask(const struct gl_context *ctx) +{ + GLbitfield legalTypesMask = ALL_TYPE_BITS; + + if (_mesa_is_gles(ctx)) { + legalTypesMask &= ~(FIXED_GL_BIT | + DOUBLE_BIT | + UNSIGNED_INT_10F_11F_11F_REV_BIT); + + /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until + * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or + * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed + * until 3.0 or with the GL_OES_vertex_half float extension, which isn't + * quite as trivial as we'd like because it uses a different enum value + * for GL_HALF_FLOAT_OES. + */ + if (ctx->Version < 30) { + legalTypesMask &= ~(UNSIGNED_INT_BIT | + INT_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT | + HALF_BIT); + } + } + else { + legalTypesMask &= ~FIXED_ES_BIT; + + if (!ctx->Extensions.ARB_ES2_compatibility) + legalTypesMask &= ~FIXED_GL_BIT; + + if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) + legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); + + if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev) + legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT; + } + + return legalTypesMask; +} + + +/** * Does error checking and updates the format in an attrib array. * * Called by update_array() and VertexAttrib*Format(). @@ -208,40 +258,19 @@ update_array_format(struct gl_context *ctx, GLuint elementSize; GLenum format = GL_RGBA; - if (_mesa_is_gles(ctx)) { - legalTypesMask &= ~(FIXED_GL_BIT | DOUBLE_BIT | UNSIGNED_INT_10F_11F_11F_REV_BIT); - - /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until - * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or - * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed - * until 3.0 or with the GL_OES_vertex_half float extension, which isn't - * quite as trivial as we'd like because it uses a different enum value - * for GL_HALF_FLOAT_OES. + if (ctx->Array.LegalTypesMask == 0) { + /* One-time initialization. We can't do this in _mesa_init_varrays() + * below because extensions are not yet enabled at that point. */ - if (ctx->Version < 30) { - legalTypesMask &= ~(UNSIGNED_INT_BIT - | INT_BIT - | UNSIGNED_INT_2_10_10_10_REV_BIT - | INT_2_10_10_10_REV_BIT - | HALF_BIT); - } + ctx->Array.LegalTypesMask = get_legal_types_mask(ctx); + } + + legalTypesMask &= ctx->Array.LegalTypesMask; + if (_mesa_is_gles(ctx) && sizeMax == BGRA_OR_4) { /* BGRA ordering is not supported in ES contexts. */ - if (sizeMax == BGRA_OR_4) - sizeMax = 4; - } else { - legalTypesMask &= ~FIXED_ES_BIT; - - if (!ctx->Extensions.ARB_ES2_compatibility) - legalTypesMask &= ~FIXED_GL_BIT; - - if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) - legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT | - INT_2_10_10_10_REV_BIT); - - if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev) - legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT; + sizeMax = 4; } typeBit = type_to_bit(ctx, type); @@ -1397,7 +1426,8 @@ _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, */ if (offset < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindVertexBuffer(offset=%lld < 0)", (long long)offset); + "glBindVertexBuffer(offset=%" PRId64 " < 0)", + (int64_t) offset); return; } @@ -1523,15 +1553,15 @@ _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, */ if (offsets[i] < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindVertexBuffer(offsets[%u]=%lldd < 0)", - i, (long long int) offsets[i]); + "glBindVertexBuffer(offsets[%u]=%" PRId64 " < 0)", + i, (int64_t) offsets[i]); continue; } if (strides[i] < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glBindVertexBuffer(strides[%u]=%lld < 0)", - i, (long long int) strides[i]); + "glBindVertexBuffer(strides[%u]=%d < 0)", + i, strides[i]); continue; } diff --git a/mesalib/src/mesa/main/vdpau.c b/mesalib/src/mesa/main/vdpau.c index 975b812cd..e1c3e00ba 100644 --- a/mesalib/src/mesa/main/vdpau.c +++ b/mesalib/src/mesa/main/vdpau.c @@ -32,9 +32,9 @@ */ #include <stdbool.h> +#include "util/hash_table.h" #include "context.h" #include "glformats.h" -#include "hash_table.h" #include "set.h" #include "texobj.h" #include "teximage.h" |