diff options
Diffstat (limited to 'mesalib/src/mesa/main')
100 files changed, 9256 insertions, 16178 deletions
diff --git a/mesalib/src/mesa/main/.gitignore b/mesalib/src/mesa/main/.gitignore index fec06291a..e65472d63 100644 --- a/mesalib/src/mesa/main/.gitignore +++ b/mesalib/src/mesa/main/.gitignore @@ -9,3 +9,5 @@ remap_helper.h get_hash.h get_hash.h.tmp format_info.c +format_pack.c +format_unpack.c diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c index 7d9893385..9c2e29e64 100644 --- a/mesalib/src/mesa/main/api_validate.c +++ b/mesalib/src/mesa/main/api_validate.c @@ -36,25 +36,6 @@ /** - * \return number of bytes in array [count] of type. - */ -static GLsizei -index_bytes(GLenum type, GLsizei count) -{ - if (type == GL_UNSIGNED_INT) { - return count * sizeof(GLuint); - } - else if (type == GL_UNSIGNED_BYTE) { - return count * sizeof(GLubyte); - } - else { - ASSERT(type == GL_UNSIGNED_SHORT); - return count * sizeof(GLushort); - } -} - - -/** * Check if OK to draw arrays/elements. */ static bool @@ -67,9 +48,7 @@ check_valid_to_render(struct gl_context *ctx, const char *function) switch (ctx->API) { case API_OPENGLES2: /* For ES2, we can draw if we have a vertex program/shader). */ - if (!ctx->VertexProgram._Current) - return false; - break; + return ctx->VertexProgram._Current != NULL; case API_OPENGLES: /* For OpenGL ES, only draw if we have vertex positions @@ -89,14 +68,21 @@ check_valid_to_render(struct gl_context *ctx, const char *function) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function); return false; } - /* fallthrough */ - case API_OPENGL_COMPAT: { - const struct gl_shader_program *const vsProg = - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; - const bool haveVertexShader = (vsProg && vsProg->LinkStatus); - const bool haveVertexProgram = ctx->VertexProgram._Enabled; - - if (haveVertexShader || haveVertexProgram) { + + /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec + * says: + * + * "If there is no active program for the vertex or fragment shader + * stages, the results of vertex and/or fragment processing will be + * undefined. However, this is not an error." + * + * The fragment shader is not tested here because other state (e.g., + * GL_RASTERIZER_DISCARD) affects whether or not we actually care. + */ + return ctx->VertexProgram._Current != NULL; + + case API_OPENGL_COMPAT: + if (ctx->VertexProgram._Current != NULL) { /* Draw regardless of whether or not we have any vertex arrays. * (Ex: could draw a point using a constant vertex pos) */ @@ -109,7 +95,6 @@ check_valid_to_render(struct gl_context *ctx, const char *function) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); } break; - } default: unreachable("Invalid API value in check_valid_to_render()"); @@ -128,27 +113,21 @@ check_valid_to_render(struct gl_context *ctx, const char *function) bool _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode) { - switch (mode) { - case GL_POINTS: - case GL_LINES: - case GL_LINE_LOOP: - case GL_LINE_STRIP: - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: + /* The overwhelmingly common case is (mode <= GL_TRIANGLE_FAN). Test that + * first and exit. You would think that a switch-statement would be the + * right approach, but at least GCC 4.7.2 generates some pretty dire code + * for the common case. + */ + if (likely(mode <= GL_TRIANGLE_FAN)) return true; - case GL_QUADS: - case GL_QUAD_STRIP: - case GL_POLYGON: + + if (mode <= GL_POLYGON) return (ctx->API == API_OPENGL_COMPAT); - case GL_LINES_ADJACENCY: - case GL_LINE_STRIP_ADJACENCY: - case GL_TRIANGLES_ADJACENCY: - case GL_TRIANGLE_STRIP_ADJACENCY: + + if (mode <= GL_TRIANGLE_STRIP_ADJACENCY) return _mesa_has_geometry_shaders(ctx); - default: - return false; - } + + return false; } @@ -351,20 +330,10 @@ validate_DrawElements_common(struct gl_context *ctx, if (!check_valid_to_render(ctx, caller)) return false; - /* Vertex buffer object tests */ - if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, "%s index out of buffer bounds", caller); - return false; - } - } - else { - /* not using a VBO */ - if (!indices) - return false; - } + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) + return false; if (count == 0) return false; @@ -422,21 +391,9 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx, if (!check_valid_to_render(ctx, "glMultiDrawElements")) return GL_FALSE; - /* Vertex buffer object tests */ - if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - for (i = 0; i < primcount; i++) { - if (index_bytes(type, count[i]) > - ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, - "glMultiDrawElements index out of buffer bounds"); - return GL_FALSE; - } - } - } - else { - /* not using a VBO */ + /* Not using a VBO for indices, so avoid NULL pointer derefs later. + */ + if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { for (i = 0; i < primcount; i++) { if (!indices[i]) return GL_FALSE; diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 4684615a8..07934b9bc 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -1248,8 +1248,10 @@ _mesa_PopAttrib(void) _mesa_FrontFace(polygon->FrontFace); _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); _mesa_PolygonMode(GL_BACK, polygon->BackMode); - _mesa_PolygonOffset(polygon->OffsetFactor, - polygon->OffsetUnits); + _mesa_polygon_offset_clamp(ctx, + polygon->OffsetFactor, + polygon->OffsetUnits, + polygon->OffsetClamp); _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); diff --git a/mesalib/src/mesa/main/bitset.h b/mesalib/src/mesa/main/bitset.h deleted file mode 100644 index 601fd0ebf..000000000 --- a/mesalib/src/mesa/main/bitset.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2006 Brian Paul 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. - */ - -/** - * \file bitset.h - * \brief Bitset of arbitrary size definitions. - * \author Michal Krol - */ - -#ifndef BITSET_H -#define BITSET_H - -#include "imports.h" - -/**************************************************************************** - * generic bitset implementation - */ - -#define BITSET_WORD GLuint -#define BITSET_WORDBITS (sizeof (BITSET_WORD) * 8) - -/* bitset declarations - */ -#define BITSET_WORDS(bits) (ALIGN(bits, BITSET_WORDBITS) / BITSET_WORDBITS) -#define BITSET_DECLARE(name, bits) BITSET_WORD name[BITSET_WORDS(bits)] - -/* bitset operations - */ -#define BITSET_COPY(x, y) memcpy( (x), (y), sizeof (x) ) -#define BITSET_EQUAL(x, y) (memcmp( (x), (y), sizeof (x) ) == 0) -#define BITSET_ZERO(x) memset( (x), 0, sizeof (x) ) -#define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) ) - -#define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS) -#define BITSET_BIT(b) (1 << ((b) % BITSET_WORDBITS)) - -/* single bit operations - */ -#define BITSET_TEST(x, b) ((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) -#define BITSET_SET(x, b) ((x)[BITSET_BITWORD(b)] |= BITSET_BIT(b)) -#define BITSET_CLEAR(x, b) ((x)[BITSET_BITWORD(b)] &= ~BITSET_BIT(b)) - -#define BITSET_MASK(b) ((b) == BITSET_WORDBITS ? ~0 : BITSET_BIT(b) - 1) -#define BITSET_RANGE(b, e) (BITSET_MASK((e) + 1) & ~BITSET_MASK(b)) - -/* bit range operations - */ -#define BITSET_TEST_RANGE(x, b, e) \ - (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) : \ - (assert (!"BITSET_TEST_RANGE: bit range crosses word boundary"), 0)) -#define BITSET_SET_RANGE(x, b, e) \ - (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] |= BITSET_RANGE(b, e)) : \ - (assert (!"BITSET_SET_RANGE: bit range crosses word boundary"), 0)) -#define BITSET_CLEAR_RANGE(x, b, e) \ - (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \ - (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0)) - -/* Get first bit set in a bitset. - */ -static inline int -__bitset_ffs(const BITSET_WORD *x, int n) -{ - int i; - - for (i = 0; i < n; i++) { - if (x[i]) - return ffs(x[i]) + BITSET_WORDBITS * i; - } - - return 0; -} - -#define BITSET_FFS(x) __bitset_ffs(x, Elements(x)) - -#endif diff --git a/mesalib/src/mesa/main/blit.c b/mesalib/src/mesa/main/blit.c index 0b70a3da4..b97b56479 100644 --- a/mesalib/src/mesa/main/blit.c +++ b/mesalib/src/mesa/main/blit.c @@ -506,7 +506,7 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, } ASSERT(ctx->Driver.BlitFramebuffer); - ctx->Driver.BlitFramebuffer(ctx, + ctx->Driver.BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 2bae1bc72..b372c68f2 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -117,6 +117,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target) return &ctx->AtomicBuffer; } break; + case GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD: + if (ctx->Extensions.AMD_pinned_memory) { + return &ctx->ExternalVirtualMemoryBuffer; + } + break; default: return NULL; } @@ -1226,7 +1231,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) } } - if (ctx->UniformBuffer == bufObj) { + if (ctx->AtomicBuffer == bufObj) { _mesa_BindBuffer( GL_ATOMIC_COUNTER_BUFFER, 0 ); } @@ -1242,6 +1247,10 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) _mesa_BindBuffer( GL_TEXTURE_BUFFER, 0 ); } + if (ctx->ExternalVirtualMemoryBuffer == bufObj) { + _mesa_BindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0); + } + /* The ID is immediately freed for re-use */ _mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]); /* Make sure we do not run into the classic ABA problem on bind. @@ -1381,7 +1390,16 @@ _mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, ASSERT(ctx->Driver.BufferData); if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW, flags, bufObj)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()"); + if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + /* Even though the interaction between AMD_pinned_memory and + * glBufferStorage is not described in the spec, Graham Sellers + * said that it should behave the same as glBufferData. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferStorage()"); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()"); + } } } @@ -1465,7 +1483,18 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size, GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT, bufObj)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB()"); + if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + /* From GL_AMD_pinned_memory: + * + * INVALID_OPERATION is generated by BufferData if <target> is + * EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, and the store cannot be + * mapped to the GPU address space. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferData()"); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferData()"); + } } } @@ -2887,7 +2916,7 @@ static void unbind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count) { struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj; - GLuint i; + GLint i; for (i = 0; i < count; i++) set_ubo_binding(ctx, &ctx->UniformBufferBindings[first + i], @@ -2898,7 +2927,7 @@ static void bind_uniform_buffers_base(struct gl_context *ctx, GLuint first, GLsizei count, const GLuint *buffers) { - GLuint i; + GLint i; if (!error_check_bind_uniform_buffers(ctx, first, count, "glBindBuffersBase")) return; @@ -2965,7 +2994,7 @@ bind_uniform_buffers_range(struct gl_context *ctx, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes) { - GLuint i; + GLint i; if (!error_check_bind_uniform_buffers(ctx, first, count, "glBindBuffersRange")) @@ -3122,7 +3151,7 @@ unbind_xfb_buffers(struct gl_context *ctx, GLuint first, GLsizei count) { struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj; - GLuint i; + GLint i; for (i = 0; i < count; i++) _mesa_set_transform_feedback_binding(ctx, tfObj, first + i, @@ -3136,7 +3165,7 @@ bind_xfb_buffers_base(struct gl_context *ctx, { struct gl_transform_feedback_object *tfObj = ctx->TransformFeedback.CurrentObject; - GLuint i; + GLint i; if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, "glBindBuffersBase")) @@ -3204,7 +3233,7 @@ bind_xfb_buffers_range(struct gl_context *ctx, { struct gl_transform_feedback_object *tfObj = ctx->TransformFeedback.CurrentObject; - GLuint i; + GLint i; if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, "glBindBuffersRange")) @@ -3342,7 +3371,7 @@ static void unbind_atomic_buffers(struct gl_context *ctx, GLuint first, GLsizei count) { struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj; - GLuint i; + GLint i; for (i = 0; i < count; i++) set_atomic_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i], @@ -3355,7 +3384,7 @@ bind_atomic_buffers_base(struct gl_context *ctx, GLsizei count, const GLuint *buffers) { - GLuint i; + GLint i; if (!error_check_bind_atomic_buffers(ctx, first, count, "glBindBuffersBase")) @@ -3422,7 +3451,7 @@ bind_atomic_buffers_range(struct gl_context *ctx, const GLintptr *offsets, const GLsizeiptr *sizes) { - GLuint i; + GLint i; if (!error_check_bind_atomic_buffers(ctx, first, count, "glBindBuffersRange")) diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c index 1ee20098d..e5076e9bb 100644 --- a/mesalib/src/mesa/main/buffers.c +++ b/mesalib/src/mesa/main/buffers.c @@ -301,7 +301,7 @@ _mesa_DrawBuffer(GLenum buffer) void GLAPIENTRY _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) { - GLint output; + GLuint output; GLbitfield usedBufferMask, supportedMask; GLbitfield destMask[MAX_DRAW_BUFFERS]; GET_CURRENT_CONTEXT(ctx); @@ -326,8 +326,9 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) /* From the ES 3.0 specification, page 180: * "If the GL is bound to the default framebuffer, then n must be 1 * and the constant must be BACK or NONE." + * (same restriction applies with GL_EXT_draw_buffers specification) */ - if (_mesa_is_gles3(ctx) && _mesa_is_winsys_fbo(ctx->DrawBuffer) && + if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(ctx->DrawBuffer) && (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); return; @@ -335,6 +336,20 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) /* complicated error checking... */ for (output = 0; output < n; output++) { + /* Section 4.2 (Whole Framebuffer Operations) of the OpenGL 3.0 + * specification says: + * + * "Each buffer listed in bufs must be BACK, NONE, or one of the values + * from table 4.3 (NONE, COLOR_ATTACHMENTi)" + */ + if (_mesa_is_gles3(ctx) && buffers[output] != GL_NONE && + buffers[output] != GL_BACK && + (buffers[output] < GL_COLOR_ATTACHMENT0 || + buffers[output] >= GL_COLOR_ATTACHMENT0 + ctx->Const.MaxColorAttachments)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffers(buffer)"); + return; + } + if (buffers[output] == GL_NONE) { destMask[output] = 0x0; } @@ -399,8 +414,9 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers) /* ES 3.0 is even more restrictive. From the ES 3.0 spec, page 180: * "If the GL is bound to a framebuffer object, the ith buffer listed * in bufs must be COLOR_ATTACHMENTi or NONE. [...] INVALID_OPERATION." + * (same restriction applies with GL_EXT_draw_buffers specification) */ - if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(ctx->DrawBuffer) && + if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(ctx->DrawBuffer) && buffers[output] != GL_NONE && buffers[output] != GL_COLOR_ATTACHMENT0 + output) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index 4671ee245..3c4ced8ed 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -225,7 +225,7 @@ _mesa_Clear( GLbitfield mask ) /** Returned by make_color_buffer_mask() for errors */ -#define INVALID_MASK ~0x0 +#define INVALID_MASK ~0x0U /** diff --git a/mesalib/src/mesa/main/colormac.h b/mesalib/src/mesa/main/colormac.h index c8adca6b6..bc69f4673 100644 --- a/mesalib/src/mesa/main/colormac.h +++ b/mesalib/src/mesa/main/colormac.h @@ -69,9 +69,6 @@ _mesa_unclamped_float_rgba_to_ubyte(GLubyte dst[4], const GLfloat src[4]) #define PACK_COLOR_565( X, Y, Z ) \ ((((X) & 0xf8) << 8) | (((Y) & 0xfc) << 3) | (((Z) & 0xf8) >> 3)) -#define PACK_COLOR_565_REV( X, Y, Z ) \ - (((X) & 0xf8) | ((Y) & 0xe0) >> 5 | (((Y) & 0x1c) << 11) | (((Z) & 0xf8) << 5)) - #define PACK_COLOR_5551( R, G, B, A ) \ ((((R) & 0xf8) << 8) | (((G) & 0xf8) << 3) | (((B) & 0xf8) >> 2) | \ ((A) >> 7)) diff --git a/mesalib/src/mesa/main/config.h b/mesalib/src/mesa/main/config.h index 4ec4b7502..5a66a4eec 100644 --- a/mesalib/src/mesa/main/config.h +++ b/mesalib/src/mesa/main/config.h @@ -178,7 +178,7 @@ #define MAX_COMBINED_ATOMIC_BUFFERS (MAX_UNIFORM_BUFFERS * 6) /* Size of an atomic counter in bytes according to ARB_shader_atomic_counters */ #define ATOMIC_COUNTER_SIZE 4 -#define MAX_IMAGE_UNIFORMS 16 +#define MAX_IMAGE_UNIFORMS 32 /* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */ #define MAX_IMAGE_UNITS (MAX_IMAGE_UNIFORMS * 6) /*@}*/ @@ -300,6 +300,9 @@ #define MAX_COMPUTE_IMAGE_UNIFORMS 8 /*@}*/ +/** For GL_ARB_pipeline_statistics_query */ +#define MAX_PIPELINE_STATISTICS 11 + /* * Color channel component order * diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 400c158a7..b186a1fad 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -118,7 +118,7 @@ #include "scissor.h" #include "shared.h" #include "shaderobj.h" -#include "simple_list.h" +#include "util/simple_list.h" #include "state.h" #include "stencil.h" #include "texcompress_s3tc.h" @@ -908,6 +908,9 @@ nop_glFlush(void) #endif +extern void (*__glapi_noop_table[])(void); + + /** * Allocate and initialize a new dispatch table. All the dispatch * function pointers will point at the _mesa_generic_nop() function @@ -929,7 +932,13 @@ _mesa_alloc_dispatch_table(void) _glapi_proc *entry = (_glapi_proc *) table; GLint i; for (i = 0; i < numEntries; i++) { +#if defined(_WIN32) + /* FIXME: This will not generate an error, but at least it won't + * corrupt the stack like _mesa_generic_nop does. */ + entry[i] = __glapi_noop_table[i]; +#else entry[i] = (_glapi_proc) _mesa_generic_nop; +#endif } #if defined(_WIN32) @@ -1271,7 +1280,6 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_free_attrib_data(ctx); _mesa_free_buffer_objects(ctx); - _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); _mesa_free_matrix_data( ctx ); @@ -1903,49 +1911,69 @@ shader_linked_or_absent(struct gl_context *ctx, GLboolean _mesa_valid_to_render(struct gl_context *ctx, const char *where) { - bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false }; unsigned i; /* This depends on having up to date derived state (shaders) */ if (ctx->NewState) _mesa_update_state(ctx); - for (i = 0; i < MESA_SHADER_COMPUTE; i++) { - if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i], - &from_glsl_shader[i], where)) - return GL_FALSE; - } + if (ctx->API == API_OPENGL_CORE || ctx->API == API_OPENGLES2) { + bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false }; - /* Any shader stages that are not supplied by the GLSL shader and have - * assembly shaders enabled must now be validated. - */ - if (!from_glsl_shader[MESA_SHADER_VERTEX] - && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(vertex program not valid)", where); - return GL_FALSE; - } + for (i = 0; i < MESA_SHADER_COMPUTE; i++) { + if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i], + &from_glsl_shader[i], where)) + return GL_FALSE; + } - /* FINISHME: If GL_NV_geometry_program4 is ever supported, the current - * FINISHME: geometry program should validated here. - */ - (void) from_glsl_shader[MESA_SHADER_GEOMETRY]; + /* In OpenGL Core Profile and OpenGL ES 2.0 / 3.0, there are no assembly + * shaders. Don't check state related to those. + */ + } else { + bool has_vertex_shader = false; + bool has_fragment_shader = false; + + /* In OpenGL Compatibility Profile, there is only vertex shader and + * fragment shader. We take this path also for API_OPENGLES because + * optimizing that path would make the other (more common) paths + * slightly slower. + */ + if (!shader_linked_or_absent(ctx, + ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX], + &has_vertex_shader, where)) + return GL_FALSE; - if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) { - if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(fragment program not valid)", where); - return GL_FALSE; - } + if (!shader_linked_or_absent(ctx, + ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT], + &has_fragment_shader, where)) + return GL_FALSE; - /* If drawing to integer-valued color buffers, there must be an - * active fragment shader (GL_EXT_texture_integer). + /* Any shader stages that are not supplied by the GLSL shader and have + * assembly shaders enabled must now be validated. */ - if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { + if (!has_vertex_shader + && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(integer format but no fragment shader)", where); + "%s(vertex program not valid)", where); return GL_FALSE; } + + if (!has_fragment_shader) { + if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(fragment program not valid)", where); + return GL_FALSE; + } + + /* If drawing to integer-valued color buffers, there must be an + * active fragment shader (GL_EXT_texture_integer). + */ + if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(integer format but no fragment shader)", where); + return GL_FALSE; + } + } } /* A pipeline object is bound */ diff --git a/mesalib/src/mesa/main/context.h b/mesalib/src/mesa/main/context.h index d902ea76e..d5650877e 100644 --- a/mesalib/src/mesa/main/context.h +++ b/mesalib/src/mesa/main/context.h @@ -326,6 +326,17 @@ _mesa_has_geometry_shaders(const struct gl_context *ctx) } +/** + * Checks if the context supports compute shaders. + */ +static inline bool +_mesa_has_compute_shaders(const struct gl_context *ctx) +{ + return (ctx->API == API_OPENGL_CORE && ctx->Extensions.ARB_compute_shader) || + (ctx->API == API_OPENGLES2 && ctx->Version >= 31); +} + + #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/copyimage.c b/mesalib/src/mesa/main/copyimage.c index df7d7c272..455929dc2 100644 --- a/mesalib/src/mesa/main/copyimage.c +++ b/mesalib/src/mesa/main/copyimage.c @@ -152,7 +152,7 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level, return false; } - *tex_image = _mesa_select_tex_image(ctx, *tex_obj, *target, level); + *tex_image = _mesa_select_tex_image(*tex_obj, *target, level); if (!*tex_image) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level); diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 2f40915d9..ec8662b30 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -415,6 +415,22 @@ struct dd_function_table { struct gl_texture_object *texObj, struct gl_texture_object *origTexObj); + /** Sets the given buffer object as the texture's storage. The given + * texture must have target GL_TEXTURE_1D, GL_TEXTURE_2D, + * GL_TEXTURE_RECTANGLE, and GL_TEXTURE_2D_ARRAY; have only a single + * mipmap level; be immutable; and must not have any assigned storage. + * The format and dimensions of the gl_texture_object will already be + * initialized. + * + * This function is used by the meta PBO texture upload path. + */ + bool (*SetTextureStorageForBufferObject)(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_buffer_object *bufferObj, + uint32_t buffer_offset, + uint32_t row_stride, + bool read_only); + /** * Map a renderbuffer into user space. * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT and @@ -563,7 +579,7 @@ struct dd_function_table { /** Select a polygon rasterization mode */ void (*PolygonMode)(struct gl_context *ctx, GLenum face, GLenum mode); /** Set the scale and units used to calculate depth values */ - void (*PolygonOffset)(struct gl_context *ctx, GLfloat factor, GLfloat units); + void (*PolygonOffset)(struct gl_context *ctx, GLfloat factor, GLfloat units, GLfloat clamp); /** Set the polygon stippling pattern */ void (*PolygonStipple)(struct gl_context *ctx, const GLubyte *mask ); /* Specifies the current buffer for reading */ @@ -697,6 +713,8 @@ struct dd_function_table { struct gl_framebuffer *fb); /*@}*/ void (*BlitFramebuffer)(struct gl_context *ctx, + struct gl_framebuffer *readFb, + struct gl_framebuffer *drawFb, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index d297f5120..025f6abd2 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -484,9 +484,13 @@ typedef enum /* ARB_uniform_buffer_object */ OPCODE_UNIFORM_BLOCK_BINDING, + /* EXT_polygon_offset_clamp */ + OPCODE_POLYGON_OFFSET_CLAMP, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, + OPCODE_NOP, /* No-op (used for 8-byte alignment */ OPCODE_END_OF_LIST, OPCODE_EXT_0 } OpCode; @@ -545,13 +549,13 @@ union pointer * Save a 4 or 8-byte pointer at dest (and dest+1). */ static inline void -save_pointer(union gl_dlist_node *dest, void *src) +save_pointer(Node *dest, void *src) { union pointer p; unsigned i; STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2); - STATIC_ASSERT(sizeof(union gl_dlist_node) == 4); + STATIC_ASSERT(sizeof(Node) == 4); p.ptr = src; @@ -564,7 +568,7 @@ save_pointer(union gl_dlist_node *dest, void *src) * Retrieve a 4 or 8-byte pointer from node (node+1). */ static inline void * -get_pointer(const union gl_dlist_node *node) +get_pointer(const Node *node) { union pointer p; unsigned i; @@ -578,7 +582,7 @@ get_pointer(const union gl_dlist_node *node) /** * Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit - * environment. In 64-bit env, sizeof(Node)==8 anyway. + * environment. */ union uint64_pair { @@ -957,11 +961,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, /* no PBO */ GLvoid *image; - if (type == GL_BITMAP) - image = _mesa_unpack_bitmap(width, height, pixels, unpack); - else - image = _mesa_unpack_image(dimensions, width, height, depth, - format, type, pixels, unpack); + image = _mesa_unpack_image(dimensions, width, height, depth, + format, type, pixels, unpack); if (pixels && !image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction"); } @@ -983,11 +984,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, } src = ADD_POINTERS(map, pixels); - if (type == GL_BITMAP) - image = _mesa_unpack_bitmap(width, height, src, unpack); - else - image = _mesa_unpack_image(dimensions, width, height, depth, - format, type, src, unpack); + image = _mesa_unpack_image(dimensions, width, height, depth, + format, type, src, unpack); ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); @@ -1018,16 +1016,19 @@ memdup(const void *src, GLsizei bytes) * Allocate space for a display list instruction (opcode + payload space). * \param opcode the instruction opcode (OPCODE_* value) * \param bytes instruction payload size (not counting opcode) - * \return pointer to allocated memory (the opcode space) + * \param align8 does the payload need to be 8-byte aligned? + * This is only relevant in 64-bit environments. + * \return pointer to allocated memory (the payload will be at pointer+1) */ static Node * -dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) +dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8) { const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */ + GLuint nopNode; Node *n; - if (opcode < (GLuint) OPCODE_EXT_0) { + if (opcode < OPCODE_EXT_0) { if (InstSize[opcode] == 0) { /* save instruction size now */ InstSize[opcode] = numNodes; @@ -1038,7 +1039,20 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) } } - if (ctx->ListState.CurrentPos + numNodes + contNodes > BLOCK_SIZE) { + if (sizeof(void *) > sizeof(Node) && align8 + && ctx->ListState.CurrentPos % 2 == 0) { + /* The opcode would get placed at node[0] and the payload would start + * at node[1]. But the payload needs to be at an even offset (8-byte + * multiple). + */ + nopNode = 1; + } + else { + nopNode = 0; + } + + if (ctx->ListState.CurrentPos + nopNode + numNodes + contNodes + > BLOCK_SIZE) { /* This block is full. Allocate a new block and chain to it */ Node *newblock; n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; @@ -1048,13 +1062,34 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); return NULL; } + + /* a fresh block should be 8-byte aligned on 64-bit systems */ + assert(((GLintptr) newblock) % sizeof(void *) == 0); + save_pointer(&n[1], newblock); ctx->ListState.CurrentBlock = newblock; ctx->ListState.CurrentPos = 0; + + /* Display list nodes are always 4 bytes. If we need 8-byte alignment + * we have to insert a NOP so that the payload of the real opcode lands + * on an even location: + * node[0] = OPCODE_NOP + * node[1] = OPCODE_x; + * node[2] = start of payload + */ + nopNode = sizeof(void *) > sizeof(Node) && align8; } n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; - ctx->ListState.CurrentPos += numNodes; + if (nopNode) { + assert(ctx->ListState.CurrentPos % 2 == 0); /* even value */ + n[0].opcode = OPCODE_NOP; + n++; + /* The "real" opcode will now be at an odd location and the payload + * will be at an even location. + */ + } + ctx->ListState.CurrentPos += nopNode + numNodes; n[0].opcode = opcode; @@ -1075,7 +1110,22 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes) void * _mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes) { - Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes); + Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, false); + if (n) + return n + 1; /* return pointer to payload area, after opcode */ + else + return NULL; +} + + +/** + * Same as _mesa_dlist_alloc(), but return a pointer which is 8-byte + * aligned in 64-bit environments, 4-byte aligned otherwise. + */ +void * +_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes) +{ + Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, true); if (n) return n + 1; /* return pointer to payload area, after opcode */ else @@ -1125,7 +1175,7 @@ _mesa_dlist_alloc_opcode(struct gl_context *ctx, static inline Node * alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) { - return dlist_alloc(ctx, opcode, nparams * sizeof(Node)); + return dlist_alloc(ctx, opcode, nparams * sizeof(Node), false); } @@ -3144,6 +3194,22 @@ save_PolygonOffsetEXT(GLfloat factor, GLfloat bias) save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias); } +static void GLAPIENTRY +save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_POLYGON_OFFSET_CLAMP, 3); + if (n) { + n[1].f = factor; + n[2].f = units; + n[3].f = clamp; + } + if (ctx->ExecuteFlag) { + CALL_PolygonOffsetClampEXT(ctx->Exec, (factor, units, clamp)); + } +} static void GLAPIENTRY save_PopAttrib(void) @@ -7985,17 +8051,8 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_LoadIdentity(ctx->Exec, ()); break; case OPCODE_LOAD_MATRIX: - if (sizeof(Node) == sizeof(GLfloat)) { - CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); - } - else { - GLfloat m[16]; - GLuint i; - for (i = 0; i < 16; i++) { - m[i] = n[1 + i].f; - } - CALL_LoadMatrixf(ctx->Exec, (m)); - } + STATIC_ASSERT(sizeof(Node) == sizeof(GLfloat)); + CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); break; case OPCODE_LOAD_NAME: CALL_LoadName(ctx->Exec, (n[1].ui)); @@ -8041,17 +8098,7 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_MatrixMode(ctx->Exec, (n[1].e)); break; case OPCODE_MULT_MATRIX: - if (sizeof(Node) == sizeof(GLfloat)) { - CALL_MultMatrixf(ctx->Exec, (&n[1].f)); - } - else { - GLfloat m[16]; - GLuint i; - for (i = 0; i < 16; i++) { - m[i] = n[1 + i].f; - } - CALL_MultMatrixf(ctx->Exec, (m)); - } + CALL_MultMatrixf(ctx->Exec, (&n[1].f)); break; case OPCODE_ORTHO: CALL_Ortho(ctx->Exec, @@ -8096,6 +8143,9 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_POLYGON_OFFSET: CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f)); break; + case OPCODE_POLYGON_OFFSET_CLAMP: + CALL_PolygonOffsetClampEXT(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + break; case OPCODE_POP_ATTRIB: CALL_PopAttrib(ctx->Exec, ()); break; @@ -8648,84 +8698,34 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); break; case OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI: - { - GLfloat values[4]; - GLuint i, dst = n[1].ui; - - for (i = 0; i < 4; i++) - values[i] = n[1 + i].f; - CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, values)); - } + CALL_SetFragmentShaderConstantATI(ctx->Exec, (n[1].ui, &n[2].f)); break; case OPCODE_ATTR_1F_NV: CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_NV: - /* Really shouldn't have to do this - the Node structure - * is convenient, but it would be better to store the data - * packed appropriately so that it can be sent directly - * on. With x86_64 becoming common, this will start to - * matter more. - */ - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib2fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f)); + CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_NV: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib3fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f)); + CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_NV: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib4fNV(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f, n[5].f)); + CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_1F_ARB: CALL_VertexAttrib1fARB(ctx->Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_ARB: - /* Really shouldn't have to do this - the Node structure - * is convenient, but it would be better to store the data - * packed appropriately so that it can be sent directly - * on. With x86_64 becoming common, this will start to - * matter more. - */ - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib2fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f)); + CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_ARB: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib3fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f)); + CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_ARB: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); - else - CALL_VertexAttrib4fARB(ctx->Exec, (n[1].e, n[2].f, n[3].f, - n[4].f, n[5].f)); + CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); break; case OPCODE_MATERIAL: - if (sizeof(Node) == sizeof(GLfloat)) - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); - else { - GLfloat f[4]; - f[0] = n[3].f; - f[1] = n[4].f; - f[2] = n[5].f; - f[3] = n[6].f; - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, f)); - } + CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); break; case OPCODE_BEGIN: CALL_Begin(ctx->Exec, (n[1].e)); @@ -8903,6 +8903,9 @@ execute_list(struct gl_context *ctx, GLuint list) case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); break; + case OPCODE_NOP: + /* no-op */ + break; case OPCODE_END_OF_LIST: done = GL_TRUE; break; @@ -9702,6 +9705,9 @@ _mesa_initialize_save_table(const struct gl_context *ctx) SET_ProgramUniformMatrix4x2fv(table, save_ProgramUniformMatrix4x2fv); SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv); SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv); + + /* GL_EXT_polygon_offset_clamp */ + SET_PolygonOffsetClampEXT(table, save_PolygonOffsetClampEXT); } @@ -9953,6 +9959,9 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) fprintf(f, "DISPLAY-LIST-CONTINUE\n"); n = (Node *) get_pointer(&n[1]); break; + case OPCODE_NOP: + fprintf(f, "NOP\n"); + break; case OPCODE_END_OF_LIST: fprintf(f, "END-LIST %u\n", list); done = GL_TRUE; @@ -10103,6 +10112,8 @@ _mesa_init_display_list(struct gl_context *ctx) ctx->List.ListBase = 0; save_vtxfmt_init(&ctx->ListState.ListVtxfmt); + + InstSize[OPCODE_NOP] = 1; } diff --git a/mesalib/src/mesa/main/dlist.h b/mesalib/src/mesa/main/dlist.h index c57eb74da..6189632d4 100644 --- a/mesalib/src/mesa/main/dlist.h +++ b/mesalib/src/mesa/main/dlist.h @@ -60,6 +60,9 @@ extern void _mesa_compile_error( struct gl_context *ctx, GLenum error, const cha extern void *_mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint sz); +extern void * +_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes); + extern GLint _mesa_dlist_alloc_opcode( struct gl_context *ctx, GLuint sz, void (*execute)( struct gl_context *, void * ), void (*destroy)( struct gl_context *, void * ), diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c index 417548a3c..11365ecc4 100644 --- a/mesalib/src/mesa/main/enable.c +++ b/mesalib/src/mesa/main/enable.c @@ -34,7 +34,7 @@ #include "enable.h" #include "errors.h" #include "light.h" -#include "simple_list.h" +#include "util/simple_list.h" #include "mtypes.h" #include "enums.h" #include "api_arrayelt.h" diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 4e7853b90..478e4ed33 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -134,7 +134,7 @@ static const GLenum debug_severity_enums[] = { static enum mesa_debug_source gl_enum_to_debug_source(GLenum e) { - int i; + unsigned i; for (i = 0; i < Elements(debug_source_enums); i++) { if (debug_source_enums[i] == e) @@ -146,7 +146,7 @@ gl_enum_to_debug_source(GLenum e) static enum mesa_debug_type gl_enum_to_debug_type(GLenum e) { - int i; + unsigned i; for (i = 0; i < Elements(debug_type_enums); i++) { if (debug_type_enums[i] == e) @@ -158,7 +158,7 @@ gl_enum_to_debug_type(GLenum e) static enum mesa_debug_severity gl_enum_to_debug_severity(GLenum e) { - int i; + unsigned i; for (i = 0; i < Elements(debug_severity_enums); i++) { if (debug_severity_enums[i] == e) @@ -633,7 +633,7 @@ debug_fetch_message(const struct gl_debug_state *debug) * Delete the oldest debug messages out of the log. */ static void -debug_delete_messages(struct gl_debug_state *debug, unsigned count) +debug_delete_messages(struct gl_debug_state *debug, int count) { struct gl_debug_log *log = &debug->Log; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 0df04c2e6..f21201538 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -104,6 +104,7 @@ static const struct extension extension_table[] = { { "GL_ARB_depth_clamp", o(ARB_depth_clamp), GL, 2003 }, { "GL_ARB_depth_texture", o(ARB_depth_texture), GLL, 2001 }, { "GL_ARB_derivative_control", o(ARB_derivative_control), GL, 2014 }, + { "GL_ARB_direct_state_access", o(dummy_false), GL, 2014 }, { "GL_ARB_draw_buffers", o(dummy_true), GL, 2002 }, { "GL_ARB_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 }, { "GL_ARB_draw_elements_base_vertex", o(ARB_draw_elements_base_vertex), GL, 2009 }, @@ -120,6 +121,7 @@ static const struct extension extension_table[] = { { "GL_ARB_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL, 1998 }, { "GL_ARB_get_program_binary", o(dummy_true), GL, 2010 }, { "GL_ARB_gpu_shader5", o(ARB_gpu_shader5), GLC, 2010 }, + { "GL_ARB_gpu_shader_fp64", o(ARB_gpu_shader_fp64), GLC, 2010 }, { "GL_ARB_half_float_pixel", o(dummy_true), GL, 2003 }, { "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL, 2008 }, { "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL, 2008 }, @@ -133,6 +135,7 @@ static const struct extension extension_table[] = { { "GL_ARB_multitexture", o(dummy_true), GLL, 1998 }, { "GL_ARB_occlusion_query2", o(ARB_occlusion_query2), GL, 2003 }, { "GL_ARB_occlusion_query", o(ARB_occlusion_query), GLL, 2001 }, + { "GL_ARB_pipeline_statistics_query", o(ARB_pipeline_statistics_query), GL, 2014 }, { "GL_ARB_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 }, { "GL_ARB_point_parameters", o(EXT_point_parameters), GLL, 1997 }, { "GL_ARB_point_sprite", o(ARB_point_sprite), GL, 2003 }, @@ -147,6 +150,7 @@ static const struct extension extension_table[] = { { "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 }, { "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 }, { "GL_ARB_shader_objects", o(dummy_true), GL, 2002 }, + { "GL_ARB_shader_precision", o(ARB_shader_precision), GL, 2010 }, { "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, { "GL_ARB_shader_texture_lod", o(ARB_shader_texture_lod), GL, 2009 }, { "GL_ARB_shading_language_100", o(dummy_true), GLL, 2003 }, @@ -156,6 +160,7 @@ static const struct extension extension_table[] = { { "GL_ARB_stencil_texturing", o(ARB_stencil_texturing), GL, 2012 }, { "GL_ARB_sync", o(ARB_sync), GL, 2003 }, { "GL_ARB_texture_barrier", o(NV_texture_barrier), GL, 2014 }, + { "GL_ARB_tessellation_shader", o(ARB_tessellation_shader), GLC, 2009 }, { "GL_ARB_texture_border_clamp", o(ARB_texture_border_clamp), GLL, 2000 }, { "GL_ARB_texture_buffer_object", o(ARB_texture_buffer_object), GLC, 2008 }, { "GL_ARB_texture_buffer_object_rgb32", o(ARB_texture_buffer_object_rgb32), GLC, 2009 }, @@ -212,6 +217,7 @@ static const struct extension extension_table[] = { { "GL_EXT_compiled_vertex_array", o(dummy_true), GLL, 1996 }, { "GL_EXT_copy_texture", o(dummy_true), GLL, 1995 }, { "GL_EXT_depth_bounds_test", o(EXT_depth_bounds_test), GL, 2002 }, + { "GL_EXT_draw_buffers", o(dummy_true), ES2, 2012 }, { "GL_EXT_draw_buffers2", o(EXT_draw_buffers2), GL, 2006 }, { "GL_EXT_draw_instanced", o(ARB_draw_instanced), GL, 2006 }, { "GL_EXT_draw_range_elements", o(dummy_true), GLL, 1997 }, @@ -231,6 +237,7 @@ static const struct extension extension_table[] = { { "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 }, { "GL_EXT_point_parameters", o(EXT_point_parameters), GLL, 1997 }, { "GL_EXT_polygon_offset", o(dummy_true), GLL, 1995 }, + { "GL_EXT_polygon_offset_clamp", o(EXT_polygon_offset_clamp), GL, 2014 }, { "GL_EXT_provoking_vertex", o(EXT_provoking_vertex), GL, 2009 }, { "GL_EXT_rescale_normal", o(dummy_true), GLL, 1997 }, { "GL_EXT_secondary_color", o(dummy_true), GLL, 1999 }, @@ -314,6 +321,10 @@ static const struct extension extension_table[] = { { "GL_OES_texture_3D", o(EXT_texture3D), ES2, 2005 }, { "GL_OES_texture_cube_map", o(ARB_texture_cube_map), ES1, 2007 }, { "GL_OES_texture_env_crossbar", o(ARB_texture_env_crossbar), ES1, 2005 }, + { "GL_OES_texture_float", o(OES_texture_float), ES2, 2005 }, + { "GL_OES_texture_float_linear", o(OES_texture_float_linear), ES2, 2005 }, + { "GL_OES_texture_half_float", o(OES_texture_half_float), ES2, 2005 }, + { "GL_OES_texture_half_float_linear", o(OES_texture_half_float_linear), ES2, 2005 }, { "GL_OES_texture_mirrored_repeat", o(dummy_true), ES1, 2005 }, { "GL_OES_texture_npot", o(ARB_texture_non_power_of_two), ES1 | ES2, 2005 }, { "GL_OES_vertex_array_object", o(dummy_true), ES1 | ES2, 2010 }, @@ -327,6 +338,7 @@ static const struct extension extension_table[] = { { "GL_AMD_conservative_depth", o(ARB_conservative_depth), GL, 2009 }, { "GL_AMD_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 }, { "GL_AMD_performance_monitor", o(AMD_performance_monitor), GL, 2007 }, + { "GL_AMD_pinned_memory", o(AMD_pinned_memory), GL, 2013 }, { "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 }, { "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, { "GL_AMD_shader_trinary_minmax", o(dummy_true), GL, 2012 }, @@ -503,7 +515,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) ctx->Extensions.NV_point_sprite = GL_TRUE; ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; ctx->Extensions.NV_texture_rectangle = GL_TRUE; - ctx->Extensions.NV_fragment_program_option = GL_TRUE; ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; ctx->Extensions.OES_standard_derivatives = GL_TRUE; ctx->Extensions.TDFX_texture_compression_FXT1 = GL_TRUE; diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 4c3c157a4..305362297 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -468,6 +468,7 @@ set_renderbuffer_attachment(struct gl_context *ctx, remove_attachment(ctx, att); att->Type = GL_RENDERBUFFER_EXT; att->Texture = NULL; /* just to be safe */ + att->Layered = GL_FALSE; att->Complete = GL_FALSE; _mesa_reference_renderbuffer(&att->Renderbuffer, rb); } @@ -780,6 +781,18 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, att->Complete = GL_FALSE; return; } + + /* OES_texture_float allows creation and use of floating point + * textures with GL_FLOAT, GL_HALF_FLOAT but it does not allow + * these textures to be used as a render target, this is done via + * GL_EXT_color_buffer(_half)_float with set of new sized types. + */ + if (_mesa_is_gles(ctx) && (texImage->TexObject->_IsFloat || + texImage->TexObject->_IsHalfFloat)) { + att_incomplete("bad internal format"); + att->Complete = GL_FALSE; + return; + } } else if (format == GL_DEPTH) { if (baseFormat == GL_DEPTH_COMPONENT) { @@ -886,6 +899,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, GLuint max_layer_count = 0, att_layer_count; bool is_layered = false; GLenum layer_tex_target = 0; + bool has_depth_attachment = false; + bool has_stencil_attachment = false; assert(_mesa_is_user_fbo(fb)); @@ -923,6 +938,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; fbo_incomplete(ctx, "depth attachment incomplete", -1); return; + } else if (att->Type != GL_NONE) { + has_depth_attachment = true; } } else if (i == -1) { @@ -932,6 +949,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; fbo_incomplete(ctx, "stencil attachment incomplete", -1); return; + } else if (att->Type != GL_NONE) { + has_stencil_attachment = true; } } else { @@ -960,7 +979,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, if (!is_format_color_renderable(ctx, attFormat, texImg->InternalFormat) && !is_legal_depth_format(ctx, f)) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; fbo_incomplete(ctx, "texture attachment incomplete", -1); return; } @@ -1128,6 +1147,20 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, } } + /* The OpenGL ES3 spec, in chapter 9.4. FRAMEBUFFER COMPLETENESS, says: + * + * "Depth and stencil attachments, if present, are the same image." + * + * This restriction is not present in the OpenGL ES2 spec. + */ + if (_mesa_is_gles3(ctx) && + has_stencil_attachment && has_depth_attachment && + !_mesa_has_depthstencil_combined(fb)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; + fbo_incomplete(ctx, "Depth and stencil attachments must be the same image", -1); + return; + } + /* Provisionally set status = COMPLETE ... */ fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; @@ -1291,6 +1324,11 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) GLint i; GET_CURRENT_CONTEXT(ctx); + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteRenderbuffers(n < 0)"); + return; + } + FLUSH_VERTICES(ctx, _NEW_BUFFERS); for (i = 0; i < n; i++) { @@ -1430,9 +1468,6 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RGB8: return GL_RGB; case GL_RGB: - if (_mesa_is_gles3(ctx)) - return GL_RGB; - /* fallthrough */ case GL_R3_G3_B2: case GL_RGB4: case GL_RGB5: @@ -1447,9 +1482,6 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RGBA8: return GL_RGBA; case GL_RGBA: - if (_mesa_is_gles3(ctx)) - return GL_RGBA; - /* fallthrough */ case GL_RGBA2: case GL_RGBA12: case GL_RGBA16: @@ -2183,6 +2215,11 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) GLint i; GET_CURRENT_CONTEXT(ctx); + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteFramebuffers(n < 0)"); + return; + } + FLUSH_VERTICES(ctx, _NEW_BUFFERS); for (i = 0; i < n; i++) { @@ -2323,7 +2360,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb, static void framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, - GLint level, GLint zoffset, GLboolean layered) + GLint level, GLuint zoffset, GLboolean layered) { struct gl_renderbuffer_attachment *att; struct gl_texture_object *texObj = NULL; @@ -2417,8 +2454,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, } if (texObj->Target == GL_TEXTURE_3D) { - const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); - if (zoffset < 0 || zoffset >= maxSize) { + const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); + if (zoffset >= maxSize) { _mesa_error(ctx, GL_INVALID_VALUE, "glFramebufferTexture%s(zoffset)", caller); return; @@ -2428,8 +2465,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) || (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) || (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) { - if (zoffset < 0 || - zoffset >= (GLint) ctx->Const.MaxArrayTextureLayers) { + if (zoffset >= ctx->Const.MaxArrayTextureLayers) { _mesa_error(ctx, GL_INVALID_VALUE, "glFramebufferTexture%s(layer)", caller); return; @@ -2766,7 +2802,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, if (_mesa_is_gles3(ctx) && attachment != GL_BACK && attachment != GL_DEPTH && attachment != GL_STENCIL) { - _mesa_error(ctx, GL_INVALID_OPERATION, + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferAttachmentParameteriv(attachment)"); return; } @@ -2869,7 +2905,8 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, _mesa_error(ctx, err, "glGetFramebufferAttachmentParameteriv(pname)"); } else if (att->Type == GL_TEXTURE) { - if (att->Texture && att->Texture->Target == GL_TEXTURE_3D) { + if (att->Texture && (att->Texture->Target == GL_TEXTURE_3D || + att->Texture->Target == GL_TEXTURE_2D_ARRAY)) { *params = att->Zoffset; } else { @@ -2967,7 +3004,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, } else if (att->Texture) { const struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, att->Texture, att->Texture->Target, + _mesa_select_tex_image(att->Texture, att->Texture->Target, att->TextureLevel); if (texImage) { *params = get_component_bits(pname, texImage->_BaseFormat, diff --git a/mesalib/src/mesa/main/feedback.c b/mesalib/src/mesa/main/feedback.c index 9ea0b92f3..6bc4294f9 100644 --- a/mesalib/src/mesa/main/feedback.c +++ b/mesalib/src/mesa/main/feedback.c @@ -89,7 +89,7 @@ _mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) ctx->Feedback.Type = type; ctx->Feedback.BufferSize = size; ctx->Feedback.Buffer = buffer; - ctx->Feedback.Count = 0; /* Becaues of this. */ + ctx->Feedback.Count = 0; /* Because of this. */ } diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index bc6fdbdd8..c6828925f 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -418,7 +418,7 @@ static GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) continue; samp = _mesa_get_samplerobj(ctx, i); - format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; + format = _mesa_texture_base_format(texObj); key->unit[i].enabled = 1; key->enabled_units |= (1<<i); diff --git a/mesalib/src/mesa/main/ffvertex_prog.c b/mesalib/src/mesa/main/ffvertex_prog.c index d5afc3d81..c51c20ddf 100644 --- a/mesalib/src/mesa/main/ffvertex_prog.c +++ b/mesalib/src/mesa/main/ffvertex_prog.c @@ -302,7 +302,7 @@ struct ureg { struct tnl_program { const struct state_key *state; struct gl_vertex_program *program; - GLint max_inst; /** number of instructions allocated for program */ + GLuint max_inst; /** number of instructions allocated for program */ GLboolean mvp_with_dp4; GLuint temp_in_use; @@ -578,7 +578,7 @@ static void emit_op3fn(struct tnl_program *p, GLuint nr; struct prog_instruction *inst; - assert((GLint) p->program->Base.NumInstructions <= p->max_inst); + assert(p->program->Base.NumInstructions <= p->max_inst); if (p->program->Base.NumInstructions == p->max_inst) { /* need to extend the program's instruction array */ diff --git a/mesalib/src/mesa/main/format_info.py b/mesalib/src/mesa/main/format_info.py index 7424fe0cd..3bae57e54 100644 --- a/mesalib/src/mesa/main/format_info.py +++ b/mesalib/src/mesa/main/format_info.py @@ -58,7 +58,7 @@ def get_gl_base_format(fmat): elif fmat.has_channel('i') and fmat.num_channels() == 1: return 'GL_INTENSITY' else: - assert False + sys.exit("error, could not determine base format for {0}, check swizzle".format(fmat.name)); def get_gl_data_type(fmat): if fmat.is_compressed(): @@ -192,6 +192,22 @@ for fmat in formats: int(fmat.block_size() / 8)) print ' {{ {0} }},'.format(', '.join(map(str, fmat.swizzle))) + if fmat.is_array(): + chan = fmat.array_element() + norm = chan.norm or chan.type == parser.FLOAT + print ' MESA_ARRAY_FORMAT({0}),'.format(', '.join([ + str(chan.size / 8), + str(int(chan.sign)), + str(int(chan.type == parser.FLOAT)), + str(int(norm)), + str(len(fmat.channels)), + str(fmat.swizzle[0]), + str(fmat.swizzle[1]), + str(fmat.swizzle[2]), + str(fmat.swizzle[3]), + ])) + else: + print ' 0,' print ' },' print '};' diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c deleted file mode 100644 index 31c9f7767..000000000 --- a/mesalib/src/mesa/main/format_pack.c +++ /dev/null @@ -1,2994 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (c) 2011 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * 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. - */ - - -/** - * Color, depth, stencil packing functions. - * Used to pack basic color, depth and stencil formats to specific - * hardware formats. - * - * There are both per-pixel and per-row packing functions: - * - The former will be used by swrast to write values to the color, depth, - * stencil buffers when drawing points, lines and masked spans. - * - The later will be used for image-oriented functions like glDrawPixels, - * glAccum, and glTexImage. - */ - - -#include "colormac.h" -#include "format_pack.h" -#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 */ -struct z32f_x24s8 -{ - float z; - uint32_t x24s8; -}; - - -typedef void (*pack_ubyte_rgba_row_func)(GLuint n, - const GLubyte src[][4], void *dst); - -typedef void (*pack_float_rgba_row_func)(GLuint n, - const GLfloat src[][4], void *dst); - - -/* - * MESA_FORMAT_A8B8G8R8_UNORM - */ - -static void -pack_ubyte_A8B8G8R8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[RCOMP], src[GCOMP], src[BCOMP], src[ACOMP]); -} - -static void -pack_float_A8B8G8R8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A8B8G8R8_UNORM(v, dst); -} - -static void -pack_row_ubyte_A8B8G8R8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][RCOMP], src[i][GCOMP], - src[i][BCOMP], src[i][ACOMP]); - } -} - -static void -pack_row_float_A8B8G8R8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_A8B8G8R8_UNORM(v, d + i); - } -} - - - -/* - * MESA_FORMAT_R8G8B8A8_UNORM - */ - -static void -pack_ubyte_R8G8B8A8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[ACOMP], src[BCOMP], src[GCOMP], src[RCOMP]); -} - -static void -pack_float_R8G8B8A8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_R8G8B8A8_UNORM(v, dst); -} - -static void -pack_row_ubyte_R8G8B8A8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][ACOMP], src[i][BCOMP], - src[i][GCOMP], src[i][RCOMP]); - } -} - -static void -pack_row_float_R8G8B8A8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_R8G8B8A8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_B8G8R8A8_UNORM - */ - -static void -pack_ubyte_B8G8R8A8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B8G8R8A8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B8G8R8A8_UNORM(v, dst); -} - -static void -pack_row_ubyte_B8G8R8A8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][ACOMP], src[i][RCOMP], - src[i][GCOMP], src[i][BCOMP]); - } -} - -static void -pack_row_float_B8G8R8A8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_B8G8R8A8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_A8R8G8B8_UNORM - */ - -static void -pack_ubyte_A8R8G8B8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[BCOMP], src[GCOMP], src[RCOMP], src[ACOMP]); -} - -static void -pack_float_A8R8G8B8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A8R8G8B8_UNORM(v, dst); -} - -static void -pack_row_ubyte_A8R8G8B8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][BCOMP], src[i][GCOMP], - src[i][RCOMP], src[i][ACOMP]); - } -} - -static void -pack_row_float_A8R8G8B8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_A8R8G8B8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_B8G8R8X8_UNORM - */ - -static void -pack_ubyte_B8G8R8X8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(0x0, src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B8G8R8X8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B8G8R8X8_UNORM(v, dst); -} - -static void -pack_row_ubyte_B8G8R8X8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(0, src[i][RCOMP], src[i][GCOMP], src[i][BCOMP]); - } -} - -static void -pack_row_float_B8G8R8X8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_B8G8R8X8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_X8R8G8B8_UNORM - */ - -static void -pack_ubyte_X8R8G8B8_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = PACK_COLOR_8888(src[BCOMP], src[GCOMP], src[RCOMP], 0); -} - -static void -pack_float_X8R8G8B8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_X8R8G8B8_UNORM(v, dst); -} - -static void -pack_row_ubyte_X8R8G8B8_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = PACK_COLOR_8888(src[i][BCOMP], src[i][GCOMP], src[i][RCOMP], 0); - } -} - -static void -pack_row_float_X8R8G8B8_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_X8R8G8B8_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_BGR_UNORM8 - */ - -static void -pack_ubyte_BGR_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - d[2] = src[RCOMP]; - d[1] = src[GCOMP]; - d[0] = src[BCOMP]; -} - -static void -pack_float_BGR_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[2], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[BCOMP]); -} - -static void -pack_row_ubyte_BGR_UNORM8(GLuint n, const GLubyte src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i*3+2] = src[i][RCOMP]; - d[i*3+1] = src[i][GCOMP]; - d[i*3+0] = src[i][BCOMP]; - } -} - -static void -pack_row_float_BGR_UNORM8(GLuint n, const GLfloat src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - d[i*3+2] = v[RCOMP]; - d[i*3+1] = v[GCOMP]; - d[i*3+0] = v[BCOMP]; - } -} - - -/* - * MESA_FORMAT_RGB_UNORM8 - */ - -static void -pack_ubyte_RGB_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - d[2] = src[BCOMP]; - d[1] = src[GCOMP]; - d[0] = src[RCOMP]; -} - -static void -pack_float_RGB_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[2], src[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[RCOMP]); -} - -static void -pack_row_ubyte_RGB_UNORM8(GLuint n, const GLubyte src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i*3+2] = src[i][BCOMP]; - d[i*3+1] = src[i][GCOMP]; - d[i*3+0] = src[i][RCOMP]; - } -} - -static void -pack_row_float_RGB_UNORM8(GLuint n, const GLfloat src[][4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - d[i*3+2] = v[BCOMP]; - d[i*3+1] = v[GCOMP]; - d[i*3+0] = v[RCOMP]; - } -} - - -/* - * MESA_FORMAT_B5G6R5_UNORM - */ - -static void -pack_ubyte_B5G6R5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_565(src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B5G6R5_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[3]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], src[BCOMP]); - pack_ubyte_B5G6R5_UNORM(v, dst); -} - -static void -pack_row_ubyte_B5G6R5_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - pack_ubyte_B5G6R5_UNORM(src[i], d + i); - } -} - -static void -pack_row_float_B5G6R5_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_B5G6R5_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_R5G6B5_UNORM - * Warning: these functions do not match the current Mesa definition - * of MESA_FORMAT_R5G6B5_UNORM. - */ - -static void -pack_ubyte_R5G6B5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_565_REV(src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_R5G6B5_UNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte r, g, b; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, src[BCOMP]); - *d = PACK_COLOR_565_REV(r, g, b); -} - -static void -pack_row_ubyte_R5G6B5_UNORM(GLuint n, const GLubyte src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - pack_ubyte_R5G6B5_UNORM(src[i], d + i); - } -} - -static void -pack_row_float_R5G6B5_UNORM(GLuint n, const GLfloat src[][4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src[i]); - pack_ubyte_R5G6B5_UNORM(v, d + i); - } -} - - -/* - * MESA_FORMAT_B4G4R4A4_UNORM - */ - -static void -pack_ubyte_B4G4R4A4_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B4G4R4A4_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B4G4R4A4_UNORM(v, dst); -} - -/* use fallback row packing functions */ - - -/* - * MESA_FORMAT_A4R4G4B4_UNORM - */ - -static void -pack_ubyte_A4R4G4B4_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(src[BCOMP], src[GCOMP], src[RCOMP], src[ACOMP]); -} - -static void -pack_float_A4R4G4B4_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A4R4G4B4_UNORM(v, dst); -} - -/* use fallback row packing functions */ - - -/* - * MESA_FORMAT_A1B5G5R5_UNORM - */ - -static void -pack_ubyte_A1B5G5R5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_5551(src[RCOMP], src[GCOMP], src[BCOMP], src[ACOMP]); -} - -static void -pack_float_A1B5G5R5_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A1B5G5R5_UNORM(v, dst); -} - -/* use fallback row packing functions */ - - -/* - * MESA_FORMAT_B5G5R5A1_UNORM - */ - -static void -pack_ubyte_B5G5R5A1_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_1555(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B5G5R5A1_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_B5G5R5A1_UNORM(v, dst); -} - - -/* MESA_FORMAT_A1R5G5B5_UNORM - * Warning: these functions do not match the current Mesa definition - * of MESA_FORMAT_A1R5G5B5_UNORM. - */ - -static void -pack_ubyte_A1R5G5B5_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst), tmp; - tmp = PACK_COLOR_1555(src[ACOMP], src[RCOMP], src[GCOMP], src[BCOMP]); - *d = (tmp >> 8) | (tmp << 8); -} - -static void -pack_float_A1R5G5B5_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_A1R5G5B5_UNORM(v, dst); -} - - -/* MESA_FORMAT_L4A4_UNORM */ - -static void -pack_ubyte_L4A4_UNORM(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = PACK_COLOR_44(src[ACOMP], src[RCOMP]); -} - -static void -pack_float_L4A4_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], src[ACOMP]); - pack_ubyte_L4A4_UNORM(v, dst); -} - - -/* MESA_FORMAT_L8A8_UNORM */ - -static void -pack_ubyte_L8A8_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_88(src[ACOMP], src[RCOMP]); -} - -static void -pack_float_L8A8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], src[ACOMP]); - pack_ubyte_L8A8_UNORM(v, dst); -} - - -/* MESA_FORMAT_A8L8_UNORM */ - -static void -pack_ubyte_A8L8_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_88(src[RCOMP], src[ACOMP]); -} - -static void -pack_float_A8L8_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], src[ACOMP]); - pack_ubyte_A8L8_UNORM(v, dst); -} - - -/* MESA_FORMAT_L16A16_UNORM */ - -static void -pack_ubyte_L16A16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l = UBYTE_TO_USHORT(src[RCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_1616(a, l); -} - -static void -pack_float_L16A16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l, a; - UNCLAMPED_FLOAT_TO_USHORT(l, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_1616(a, l); -} - - -/* MESA_FORMAT_A16L16_UNORM */ - -static void -pack_ubyte_A16L16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l = UBYTE_TO_USHORT(src[RCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_1616(l, a); -} - -static void -pack_float_A16L16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort l, a; - UNCLAMPED_FLOAT_TO_USHORT(l, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_1616(l, a); -} - - -/* MESA_FORMAT_B2G3R3_UNORM */ - -static void -pack_ubyte_B2G3R3_UNORM(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = PACK_COLOR_332(src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_B2G3R3_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], src[BCOMP]); - pack_ubyte_B2G3R3_UNORM(v, dst); -} - - -/* MESA_FORMAT_A_UNORM8 */ - -static void -pack_ubyte_A_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = src[ACOMP]; -} - -static void -pack_float_A_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[ACOMP]); -} - - -/* MESA_FORMAT_A_UNORM16 */ - -static void -pack_ubyte_A_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = UBYTE_TO_USHORT(src[ACOMP]); -} - -static void -pack_float_A_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[ACOMP]); -} - - -/* MESA_FORMAT_L_UNORM8 */ - -static void -pack_ubyte_L_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = src[RCOMP]; -} - -static void -pack_float_L_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[RCOMP]); -} - - -/* MESA_FORMAT_L_UNORM16 */ - -static void -pack_ubyte_L_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = UBYTE_TO_USHORT(src[RCOMP]); -} - -static void -pack_float_L_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); -} - - -/* MESA_FORMAT_YCBCR */ - -static void -pack_ubyte_YCBCR(const GLubyte src[4], void *dst) -{ - /* todo */ -} - -static void -pack_float_YCBCR(const GLfloat src[4], void *dst) -{ - /* todo */ -} - - -/* MESA_FORMAT_YCBCR_REV */ - -static void -pack_ubyte_YCBCR_REV(const GLubyte src[4], void *dst) -{ - /* todo */ -} - -static void -pack_float_YCBCR_REV(const GLfloat src[4], void *dst) -{ - /* todo */ -} - - -/* MESA_FORMAT_R_UNORM8 */ - -static void -pack_ubyte_R_UNORM8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = src[RCOMP]; -} - -static void -pack_float_R_UNORM8(const GLfloat src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - GLubyte r; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - d[0] = r; -} - - -/* MESA_FORMAT_R8G8_UNORM */ - -static void -pack_ubyte_R8G8_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_88(src[GCOMP], src[RCOMP]); -} - -static void -pack_float_R8G8_UNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte r, g; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, src[GCOMP]); - *d = PACK_COLOR_88(g, r); -} - - -/* MESA_FORMAT_G8R8_UNORM */ - -static void -pack_ubyte_G8R8_UNORM(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *d = PACK_COLOR_88(src[RCOMP], src[GCOMP]); -} - -static void -pack_float_G8R8_UNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte r, g; - UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, src[GCOMP]); - *d = PACK_COLOR_88(r, g); -} - - -/* MESA_FORMAT_R_UNORM16 */ - -static void -pack_ubyte_R_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = UBYTE_TO_USHORT(src[RCOMP]); -} - -static void -pack_float_R_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); -} - - -/* MESA_FORMAT_R16G16_UNORM */ - -static void -pack_ubyte_R16G16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - *d = PACK_COLOR_1616(g, r); -} - -static void -pack_float_R16G16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - *d = PACK_COLOR_1616(g, r); -} - - -/* MESA_FORMAT_G16R16_UNORM */ - -static void -pack_ubyte_G16R16_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - *d = PACK_COLOR_1616(r, g); -} - - -static void -pack_float_G16R16_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - *d = PACK_COLOR_1616(r, g); -} - - -/* MESA_FORMAT_B10G10R10A2_UNORM */ - -static void -pack_ubyte_B10G10R10A2_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, r, g, b); -} - -static void -pack_float_B10G10R10A2_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b, a; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, r, g, b); -} - - -/* MESA_FORMAT_R10G10B10A2_UINT */ - -static void -pack_ubyte_R10G10B10A2_UINT(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - -static void -pack_float_R10G10B10A2_UINT(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b, a; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - - -/* MESA_FORMAT_BGR_SRGB8 */ - -static void -pack_ubyte_BGR_SRGB8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - 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] = 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]); -} - - -/* MESA_FORMAT_A8B8G8R8_SRGB */ - -static void -pack_ubyte_A8B8G8R8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - 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]); -} - -static void -pack_float_A8B8G8R8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - 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); -} - - -/* MESA_FORMAT_B8G8R8A8_SRGB */ - -static void -pack_ubyte_B8G8R8A8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - 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); -} - -static void -pack_float_B8G8R8A8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - 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); -} - - -/* MESA_FORMAT_A8R8G8B8_SRGB */ - -static void -pack_ubyte_A8R8G8B8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - 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(b, g, r, src[ACOMP]); -} - -static void -pack_float_A8R8G8B8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - 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(b, g, r, a); -} - - -/* MESA_FORMAT_R8G8B8A8_SRGB */ - -static void -pack_ubyte_R8G8B8A8_SRGB(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - 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); -} - -static void -pack_float_R8G8B8A8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLubyte r, g, b, a; - 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); -} - - -/* MESA_FORMAT_L_SRGB8 */ - -static void -pack_ubyte_L_SRGB8(const GLubyte src[4], void *dst) -{ - GLubyte *d = ((GLubyte *) dst); - *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 = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - *d = l; -} - - -/* MESA_FORMAT_L8A8_SRGB */ - -static void -pack_ubyte_L8A8_SRGB(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte l = util_format_linear_to_srgb_8unorm(src[RCOMP]); - *d = PACK_COLOR_88(src[ACOMP], l); -} - -/* MESA_FORMAT_A8L8_SRGB */ - -static void -pack_ubyte_A8L8_SRGB(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte l = util_format_linear_to_srgb_8unorm(src[RCOMP]); - *d = PACK_COLOR_88(l, src[ACOMP]); -} - -static void -pack_float_L8A8_SRGB(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - 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); -} - -static void -pack_float_A8L8_SRGB(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - GLubyte a, l = util_format_linear_float_to_srgb_8unorm(src[RCOMP]); - CLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); - *d = PACK_COLOR_88(l, a); -} - - -/* MESA_FORMAT_RGBA_FLOAT32 */ - -static void -pack_ubyte_RGBA_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[0]); - d[1] = UBYTE_TO_FLOAT(src[1]); - d[2] = UBYTE_TO_FLOAT(src[2]); - d[3] = UBYTE_TO_FLOAT(src[3]); -} - -static void -pack_float_RGBA_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; - d[3] = src[3]; -} - - -/* MESA_FORMAT_RGBA_FLOAT16 */ - -static void -pack_ubyte_RGBA_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[0])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[1])); - d[2] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[2])); - d[3] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[3])); -} - -static void -pack_float_RGBA_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[0]); - d[1] = _mesa_float_to_half(src[1]); - d[2] = _mesa_float_to_half(src[2]); - d[3] = _mesa_float_to_half(src[3]); -} - - -/* MESA_FORMAT_RGB_FLOAT32 */ - -static void -pack_ubyte_RGB_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[0]); - d[1] = UBYTE_TO_FLOAT(src[1]); - d[2] = UBYTE_TO_FLOAT(src[2]); -} - -static void -pack_float_RGB_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[0]; - d[1] = src[1]; - d[2] = src[2]; -} - - -/* MESA_FORMAT_RGB_FLOAT16 */ - -static void -pack_ubyte_RGB_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[0])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[1])); - d[2] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[2])); -} - -static void -pack_float_RGB_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[0]); - d[1] = _mesa_float_to_half(src[1]); - d[2] = _mesa_float_to_half(src[2]); -} - - -/* MESA_FORMAT_A_FLOAT32 */ - -static void -pack_ubyte_A_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[ACOMP]); -} - -static void -pack_float_A_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[ACOMP]; -} - - -/* MESA_FORMAT_A_FLOAT16 */ - -static void -pack_ubyte_A_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[ACOMP])); -} - -static void -pack_float_A_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[ACOMP]); -} - - -/* MESA_FORMAT_L_FLOAT32 (and I_FLOAT32, R_FLOAT32) */ - -static void -pack_ubyte_L_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[RCOMP]); -} - -static void -pack_float_L_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; -} - - -/* MESA_FORMAT_L_FLOAT16 (and I_FLOAT16, R_FLOAT32) */ - -static void -pack_ubyte_L_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[RCOMP])); -} - -static void -pack_float_L_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); -} - - -/* MESA_FORMAT_LA_FLOAT32 */ - -static void -pack_ubyte_LA_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[RCOMP]); - d[1] = UBYTE_TO_FLOAT(src[ACOMP]); -} - -static void -pack_float_LA_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; - d[1] = src[ACOMP]; -} - - -/* MESA_FORMAT_LA_FLOAT16 */ - -static void -pack_ubyte_LA_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[RCOMP])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[ACOMP])); -} - -static void -pack_float_LA_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); - d[1] = _mesa_float_to_half(src[ACOMP]); -} - - -/* MESA_FORMAT_RG_FLOAT32 */ - -static void -pack_ubyte_RG_FLOAT32(const GLubyte src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = UBYTE_TO_FLOAT(src[RCOMP]); - d[1] = UBYTE_TO_FLOAT(src[GCOMP]); -} - -static void -pack_float_RG_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; - d[1] = src[GCOMP]; -} - - -/* MESA_FORMAT_RG_FLOAT16 */ - -static void -pack_ubyte_RG_FLOAT16(const GLubyte src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[RCOMP])); - d[1] = _mesa_float_to_half(UBYTE_TO_FLOAT(src[GCOMP])); -} - -static void -pack_float_RG_FLOAT16(const GLfloat src[4], void *dst) -{ - GLhalfARB *d = ((GLhalfARB *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); - d[1] = _mesa_float_to_half(src[GCOMP]); -} - - -/* MESA_FORMAT_RGBA_UNORM16 */ - -static void -pack_ubyte_RGBA_16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - d[0] = UBYTE_TO_USHORT(src[RCOMP]); - d[1] = UBYTE_TO_USHORT(src[GCOMP]); - d[2] = UBYTE_TO_USHORT(src[BCOMP]); - d[3] = UBYTE_TO_USHORT(src[ACOMP]); -} - -static void -pack_float_RGBA_16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[2], src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[3], src[ACOMP]); -} - - - -/* - * MESA_FORMAT_R_SNORM8 - */ - -static void -pack_float_R_SNORM8(const GLfloat src[4], void *dst) -{ - GLbyte *d = (GLbyte *) dst; - *d = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_R8G8_SNORM - */ - -static void -pack_float_R8G8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (g << 8) | r; -} - - -/* - * MESA_FORMAT_X8B8G8R8_SNORM - */ - -static void -pack_float_X8B8G8R8_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - GLbyte a = 127; - *d = PACK_COLOR_8888(r, g, b, a); -} - - -/* - * MESA_FORMAT_A8B8G8R8_SNORM - */ - -static void -pack_float_A8B8G8R8_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_8888(r, g, b, a); -} - - -/* - * MESA_FORMAT_R8G8B8A8_SNORM - */ - -static void -pack_float_R8G8B8A8_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_8888(a, b, g, r); -} - - -/* - * MESA_FORMAT_R_SNORM16 - */ - -static void -pack_float_R_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - *d = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_R16G16_SNORM - */ - -static void -pack_float_R16G16_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLshort r = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLshort g = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (g << 16) | (r & 0xffff); -} - - -/* - * MESA_FORMAT_RGB_SNORM16 - */ - -static void -pack_float_RGB_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - d[0] = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - d[1] = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - d[2] = FLOAT_TO_SHORT(CLAMP(src[BCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_RGBA_SNORM16 - */ - -static void -pack_float_RGBA_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - d[0] = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - d[1] = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - d[2] = FLOAT_TO_SHORT(CLAMP(src[BCOMP], -1.0f, 1.0f)); - d[3] = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_A_SNORM8 - */ - -static void -pack_float_A_SNORM8(const GLfloat src[4], void *dst) -{ - GLbyte *d = (GLbyte *) dst; - *d = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_L_SNORM8 - */ - -static void -pack_float_L_SNORM8(const GLfloat src[4], void *dst) -{ - GLbyte *d = (GLbyte *) dst; - *d = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_L8A8_SNORM - */ - -static void -pack_float_L8A8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte l = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = (a << 8) | l; -} - - -/* - * MESA_FORMAT_A8L8_SNORM - */ - -static void -pack_float_A8L8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte l = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte a = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = (l << 8) | a; -} - - -/* - * MESA_FORMAT_A_SNORM16 - */ - -static void -pack_float_A_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - *d = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_L_SNORM16 - */ - -static void -pack_float_L_SNORM16(const GLfloat src[4], void *dst) -{ - GLshort *d = (GLshort *) dst; - *d = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); -} - - -/* - * MESA_FORMAT_LA_SNORM16 - */ - -static void -pack_float_LA_SNORM16(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLshort l = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLshort a = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_1616(a, l); -} - - -/* - * MESA_FORMAT_R9G9B9E5_FLOAT; - */ - -static void -pack_float_R9G9B9E5_FLOAT(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - *d = float3_to_rgb9e5(src); -} - -static void -pack_ubyte_R9G9B9E5_FLOAT(const GLubyte src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLfloat rgb[3]; - rgb[0] = UBYTE_TO_FLOAT(src[RCOMP]); - rgb[1] = UBYTE_TO_FLOAT(src[GCOMP]); - rgb[2] = UBYTE_TO_FLOAT(src[BCOMP]); - *d = float3_to_rgb9e5(rgb); -} - - - -/* - * MESA_FORMAT_R11G11B10_FLOAT; - */ - -static void -pack_ubyte_R11G11B10_FLOAT(const GLubyte src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLfloat rgb[3]; - rgb[0] = UBYTE_TO_FLOAT(src[RCOMP]); - rgb[1] = UBYTE_TO_FLOAT(src[GCOMP]); - rgb[2] = UBYTE_TO_FLOAT(src[BCOMP]); - *d = float3_to_r11g11b10f(rgb); -} - -static void -pack_float_R11G11B10_FLOAT(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - *d = float3_to_r11g11b10f(src); -} - - -/* - * MESA_FORMAT_B4G4R4X4_UNORM - */ - -static void -pack_ubyte_XRGB4444_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_4444(255, src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_XRGB4444_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_XRGB4444_UNORM(v, dst); -} - - -/* - * MESA_FORMAT_B5G5R5X1_UNORM - */ - -static void -pack_ubyte_XRGB1555_UNORM(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = PACK_COLOR_1555(255, src[RCOMP], src[GCOMP], src[BCOMP]); -} - -static void -pack_float_XRGB1555_UNORM(const GLfloat src[4], void *dst) -{ - GLubyte v[4]; - _mesa_unclamped_float_rgba_to_ubyte(v, src); - pack_ubyte_XRGB1555_UNORM(v, dst); -} - - -/* - * MESA_FORMAT_R8G8B8X8_SNORM - */ - -static void -pack_float_XBGR8888_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - GLbyte b = FLOAT_TO_BYTE(CLAMP(src[BCOMP], -1.0f, 1.0f)); - *d = PACK_COLOR_8888(127, b, g, r); -} - - -/* - * MESA_FORMAT_R8G8B8X8_SRGB - */ - -static void -pack_float_R8G8B8X8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - 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(255, b, g, r); -} - - -/* - * MESA_FORMAT_X8B8G8R8_SRGB - */ - -static void -pack_float_X8B8G8R8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - 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(r, g, b, 255); -} - - -/* MESA_FORMAT_B10G10R10X2_UNORM */ - -static void -pack_ubyte_B10G10R10X2_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - *d = PACK_COLOR_2101010_US(3, r, g, b); -} - -static void -pack_float_B10G10R10X2_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - *d = PACK_COLOR_2101010_US(3, r, g, b); -} - - -/* MESA_FORMAT_RGBX_UNORM16 */ - -static void -pack_ubyte_RGBX_UNORM16(const GLubyte src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - d[0] = UBYTE_TO_USHORT(src[RCOMP]); - d[1] = UBYTE_TO_USHORT(src[GCOMP]); - d[2] = UBYTE_TO_USHORT(src[BCOMP]); - d[3] = 65535; -} - -static void -pack_float_RGBX_UNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(d[2], src[BCOMP]); - d[3] = 65535; -} - - -/* MESA_FORMAT_RGBX_SNORM16 */ - -static void -pack_float_RGBX_SNORM16(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - UNCLAMPED_FLOAT_TO_SHORT(d[0], src[RCOMP]); - UNCLAMPED_FLOAT_TO_SHORT(d[1], src[GCOMP]); - UNCLAMPED_FLOAT_TO_SHORT(d[2], src[BCOMP]); - d[3] = 32767; -} - - -/* MESA_FORMAT_RGBX_FLOAT16 */ - -static void -pack_float_XBGR16161616_FLOAT(const GLfloat src[4], void *dst) -{ - GLushort *d = ((GLushort *) dst); - d[0] = _mesa_float_to_half(src[RCOMP]); - d[1] = _mesa_float_to_half(src[GCOMP]); - d[2] = _mesa_float_to_half(src[BCOMP]); - d[3] = _mesa_float_to_half(1.0); -} - -/* MESA_FORMAT_RGBX_FLOAT32 */ - -static void -pack_float_RGBX_FLOAT32(const GLfloat src[4], void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[0] = src[RCOMP]; - d[1] = src[GCOMP]; - d[2] = src[BCOMP]; - d[3] = 1.0; -} - -/* MESA_FORMAT_R10G10B10A2_UNORM */ - -static void -pack_ubyte_R10G10B10A2_UNORM(const GLubyte src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r = UBYTE_TO_USHORT(src[RCOMP]); - GLushort g = UBYTE_TO_USHORT(src[GCOMP]); - GLushort b = UBYTE_TO_USHORT(src[BCOMP]); - GLushort a = UBYTE_TO_USHORT(src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - -static void -pack_float_R10G10B10A2_UNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = ((GLuint *) dst); - GLushort r, g, b, a; - UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); - *d = PACK_COLOR_2101010_US(a, b, g, r); -} - -/* - * MESA_FORMAT_G8R8_SNORM - */ - -static void -pack_float_G8R8_SNORM(const GLfloat src[4], void *dst) -{ - GLushort *d = (GLushort *) dst; - GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (r << 8) | (g & 0xff); -} - -/* - * MESA_FORMAT_G16R16_SNORM - */ - -static void -pack_float_G16R16_SNORM(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - GLshort r = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); - GLshort g = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f)); - *d = (r << 16) | (g & 0xffff); -} - -/* - * MESA_FORMAT_B8G8R8X8_SRGB - */ - -static void -pack_float_B8G8R8X8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - 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); -} - -/* - * MESA_FORMAT_X8R8G8B8_SRGB - */ - -static void -pack_float_X8R8G8B8_SRGB(const GLfloat src[4], void *dst) -{ - GLuint *d = (GLuint *) dst; - 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(b, g, r, 255); -} - -/** - * Return a function that can pack a GLubyte rgba[4] color. - */ -gl_pack_ubyte_rgba_func -_mesa_get_pack_ubyte_rgba_function(mesa_format format) -{ - static gl_pack_ubyte_rgba_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_NONE] = NULL; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_ubyte_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_ubyte_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_ubyte_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_ubyte_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_ubyte_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_ubyte_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_ubyte_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_ubyte_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_ubyte_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_ubyte_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_ubyte_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_ubyte_R5G6B5_UNORM; - table[MESA_FORMAT_B4G4R4A4_UNORM] = pack_ubyte_B4G4R4A4_UNORM; - table[MESA_FORMAT_A4R4G4B4_UNORM] = pack_ubyte_A4R4G4B4_UNORM; - table[MESA_FORMAT_A1B5G5R5_UNORM] = pack_ubyte_A1B5G5R5_UNORM; - table[MESA_FORMAT_B5G5R5A1_UNORM] = pack_ubyte_B5G5R5A1_UNORM; - table[MESA_FORMAT_A1R5G5B5_UNORM] = pack_ubyte_A1R5G5B5_UNORM; - table[MESA_FORMAT_L4A4_UNORM] = pack_ubyte_L4A4_UNORM; - table[MESA_FORMAT_L8A8_UNORM] = pack_ubyte_L8A8_UNORM; - table[MESA_FORMAT_A8L8_UNORM] = pack_ubyte_A8L8_UNORM; - table[MESA_FORMAT_L16A16_UNORM] = pack_ubyte_L16A16_UNORM; - table[MESA_FORMAT_A16L16_UNORM] = pack_ubyte_A16L16_UNORM; - table[MESA_FORMAT_B2G3R3_UNORM] = pack_ubyte_B2G3R3_UNORM; - table[MESA_FORMAT_A_UNORM8] = pack_ubyte_A_UNORM8; - table[MESA_FORMAT_A_UNORM16] = pack_ubyte_A_UNORM16; - table[MESA_FORMAT_L_UNORM8] = pack_ubyte_L_UNORM8; - table[MESA_FORMAT_L_UNORM16] = pack_ubyte_L_UNORM16; - table[MESA_FORMAT_I_UNORM8] = pack_ubyte_L_UNORM8; /* reuse pack_ubyte_L_UNORM8 */ - table[MESA_FORMAT_I_UNORM16] = pack_ubyte_L_UNORM16; /* reuse pack_ubyte_L_UNORM16 */ - table[MESA_FORMAT_YCBCR] = pack_ubyte_YCBCR; - table[MESA_FORMAT_YCBCR_REV] = pack_ubyte_YCBCR_REV; - table[MESA_FORMAT_R_UNORM8] = pack_ubyte_R_UNORM8; - table[MESA_FORMAT_R8G8_UNORM] = pack_ubyte_R8G8_UNORM; - table[MESA_FORMAT_G8R8_UNORM] = pack_ubyte_G8R8_UNORM; - table[MESA_FORMAT_R_UNORM16] = pack_ubyte_R_UNORM16; - table[MESA_FORMAT_R16G16_UNORM] = pack_ubyte_R16G16_UNORM; - table[MESA_FORMAT_G16R16_UNORM] = pack_ubyte_G16R16_UNORM; - table[MESA_FORMAT_B10G10R10A2_UNORM] = pack_ubyte_B10G10R10A2_UNORM; - table[MESA_FORMAT_R10G10B10A2_UINT] = pack_ubyte_R10G10B10A2_UINT; - - /* should never convert RGBA to these formats */ - table[MESA_FORMAT_S8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z24_UNORM_S8_UINT] = NULL; - table[MESA_FORMAT_Z_UNORM16] = NULL; - table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL; - table[MESA_FORMAT_X8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z_UNORM32] = NULL; - table[MESA_FORMAT_S_UINT8] = NULL; - - /* sRGB */ - table[MESA_FORMAT_BGR_SRGB8] = pack_ubyte_BGR_SRGB8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = pack_ubyte_A8B8G8R8_SRGB; - table[MESA_FORMAT_B8G8R8A8_SRGB] = pack_ubyte_B8G8R8A8_SRGB; - table[MESA_FORMAT_A8R8G8B8_SRGB] = pack_ubyte_A8R8G8B8_SRGB; - table[MESA_FORMAT_R8G8B8A8_SRGB] = pack_ubyte_R8G8B8A8_SRGB; - table[MESA_FORMAT_L_SRGB8] = pack_ubyte_L_SRGB8; - table[MESA_FORMAT_L8A8_SRGB] = pack_ubyte_L8A8_SRGB; - table[MESA_FORMAT_A8L8_SRGB] = pack_ubyte_A8L8_SRGB; - /* n/a */ - table[MESA_FORMAT_SRGB_DXT1] = NULL; /* pack_ubyte_SRGB_DXT1; */ - table[MESA_FORMAT_SRGBA_DXT1] = NULL; /* pack_ubyte_SRGBA_DXT1; */ - table[MESA_FORMAT_SRGBA_DXT3] = NULL; /* pack_ubyte_SRGBA_DXT3; */ - table[MESA_FORMAT_SRGBA_DXT5] = NULL; /* pack_ubyte_SRGBA_DXT5; */ - - table[MESA_FORMAT_RGB_FXT1] = NULL; /* pack_ubyte_RGB_FXT1; */ - table[MESA_FORMAT_RGBA_FXT1] = NULL; /* pack_ubyte_RGBA_FXT1; */ - table[MESA_FORMAT_RGB_DXT1] = NULL; /* pack_ubyte_RGB_DXT1; */ - table[MESA_FORMAT_RGBA_DXT1] = NULL; /* pack_ubyte_RGBA_DXT1; */ - table[MESA_FORMAT_RGBA_DXT3] = NULL; /* pack_ubyte_RGBA_DXT3; */ - table[MESA_FORMAT_RGBA_DXT5] = NULL; /* pack_ubyte_RGBA_DXT5; */ - - table[MESA_FORMAT_RGBA_FLOAT32] = pack_ubyte_RGBA_FLOAT32; - table[MESA_FORMAT_RGBA_FLOAT16] = pack_ubyte_RGBA_FLOAT16; - table[MESA_FORMAT_RGB_FLOAT32] = pack_ubyte_RGB_FLOAT32; - table[MESA_FORMAT_RGB_FLOAT16] = pack_ubyte_RGB_FLOAT16; - table[MESA_FORMAT_A_FLOAT32] = pack_ubyte_A_FLOAT32; - table[MESA_FORMAT_A_FLOAT16] = pack_ubyte_A_FLOAT16; - table[MESA_FORMAT_L_FLOAT32] = pack_ubyte_L_FLOAT32; - table[MESA_FORMAT_L_FLOAT16] = pack_ubyte_L_FLOAT16; - table[MESA_FORMAT_LA_FLOAT32] = pack_ubyte_LA_FLOAT32; - table[MESA_FORMAT_LA_FLOAT16] = pack_ubyte_LA_FLOAT16; - table[MESA_FORMAT_I_FLOAT32] = pack_ubyte_L_FLOAT32; - table[MESA_FORMAT_I_FLOAT16] = pack_ubyte_L_FLOAT16; - table[MESA_FORMAT_R_FLOAT32] = pack_ubyte_L_FLOAT32; - table[MESA_FORMAT_R_FLOAT16] = pack_ubyte_L_FLOAT16; - table[MESA_FORMAT_RG_FLOAT32] = pack_ubyte_RG_FLOAT32; - table[MESA_FORMAT_RG_FLOAT16] = pack_ubyte_RG_FLOAT16; - - /* n/a */ - table[MESA_FORMAT_RGBA_SINT8] = NULL; /* pack_ubyte_RGBA_INT8 */ - table[MESA_FORMAT_RGBA_SINT16] = NULL; /* pack_ubyte_RGBA_INT16 */ - table[MESA_FORMAT_RGBA_SINT32] = NULL; /* pack_ubyte_RGBA_INT32 */ - table[MESA_FORMAT_RGBA_UINT8] = NULL; /* pack_ubyte_RGBA_UINT8 */ - table[MESA_FORMAT_RGBA_UINT16] = NULL; /* pack_ubyte_RGBA_UINT16 */ - table[MESA_FORMAT_RGBA_UINT32] = NULL; /* pack_ubyte_RGBA_UINT32 */ - - table[MESA_FORMAT_RGBA_UNORM16] = pack_ubyte_RGBA_16; - - /* n/a */ - table[MESA_FORMAT_R_SNORM8] = NULL; - table[MESA_FORMAT_R8G8_SNORM] = NULL; - table[MESA_FORMAT_X8B8G8R8_SNORM] = NULL; - table[MESA_FORMAT_A8B8G8R8_SNORM] = NULL; - table[MESA_FORMAT_R8G8B8A8_SNORM] = NULL; - table[MESA_FORMAT_R_SNORM16] = NULL; - table[MESA_FORMAT_R16G16_SNORM] = NULL; - table[MESA_FORMAT_RGB_SNORM16] = NULL; - table[MESA_FORMAT_RGBA_SNORM16] = NULL; - table[MESA_FORMAT_A_SNORM8] = NULL; - table[MESA_FORMAT_L_SNORM8] = NULL; - table[MESA_FORMAT_L8A8_SNORM] = NULL; - table[MESA_FORMAT_A8L8_SNORM] = NULL; - table[MESA_FORMAT_I_SNORM8] = NULL; - table[MESA_FORMAT_A_SNORM16] = NULL; - table[MESA_FORMAT_L_SNORM16] = NULL; - table[MESA_FORMAT_LA_SNORM16] = NULL; - table[MESA_FORMAT_I_SNORM16] = NULL; - - - table[MESA_FORMAT_RGBA_UNORM16] = pack_ubyte_RGBA_16; - - table[MESA_FORMAT_R9G9B9E5_FLOAT] = pack_ubyte_R9G9B9E5_FLOAT; - table[MESA_FORMAT_R11G11B10_FLOAT] = pack_ubyte_R11G11B10_FLOAT; - - table[MESA_FORMAT_B4G4R4X4_UNORM] = pack_ubyte_XRGB4444_UNORM; - table[MESA_FORMAT_B5G5R5X1_UNORM] = pack_ubyte_XRGB1555_UNORM; - table[MESA_FORMAT_R8G8B8X8_SNORM] = NULL; - table[MESA_FORMAT_R8G8B8X8_SRGB] = NULL; - table[MESA_FORMAT_X8B8G8R8_SRGB] = NULL; - table[MESA_FORMAT_RGBX_UINT8] = NULL; - table[MESA_FORMAT_RGBX_SINT8] = NULL; - table[MESA_FORMAT_B10G10R10X2_UNORM] = pack_ubyte_B10G10R10X2_UNORM; - table[MESA_FORMAT_RGBX_UNORM16] = pack_ubyte_RGBX_UNORM16; - table[MESA_FORMAT_RGBX_SNORM16] = NULL; - table[MESA_FORMAT_RGBX_FLOAT16] = NULL; - table[MESA_FORMAT_RGBX_UINT16] = NULL; - table[MESA_FORMAT_RGBX_SINT16] = NULL; - table[MESA_FORMAT_RGBX_FLOAT32] = NULL; - table[MESA_FORMAT_RGBX_UINT32] = NULL; - table[MESA_FORMAT_RGBX_SINT32] = NULL; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = pack_ubyte_R10G10B10A2_UNORM; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = NULL; - table[MESA_FORMAT_X8R8G8B8_SRGB] = NULL; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -/** - * Return a function that can pack a GLfloat rgba[4] color. - */ -gl_pack_float_rgba_func -_mesa_get_pack_float_rgba_function(mesa_format format) -{ - static gl_pack_float_rgba_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_NONE] = NULL; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_float_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_float_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_float_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_float_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_float_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_float_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_float_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_float_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_float_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_float_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_float_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_float_R5G6B5_UNORM; - table[MESA_FORMAT_B4G4R4A4_UNORM] = pack_float_B4G4R4A4_UNORM; - table[MESA_FORMAT_A4R4G4B4_UNORM] = pack_float_A4R4G4B4_UNORM; - table[MESA_FORMAT_A1B5G5R5_UNORM] = pack_float_A1B5G5R5_UNORM; - table[MESA_FORMAT_B5G5R5A1_UNORM] = pack_float_B5G5R5A1_UNORM; - table[MESA_FORMAT_A1R5G5B5_UNORM] = pack_float_A1R5G5B5_UNORM; - - table[MESA_FORMAT_L4A4_UNORM] = pack_float_L4A4_UNORM; - table[MESA_FORMAT_L8A8_UNORM] = pack_float_L8A8_UNORM; - table[MESA_FORMAT_A8L8_UNORM] = pack_float_A8L8_UNORM; - table[MESA_FORMAT_L16A16_UNORM] = pack_float_L16A16_UNORM; - table[MESA_FORMAT_A16L16_UNORM] = pack_float_A16L16_UNORM; - table[MESA_FORMAT_B2G3R3_UNORM] = pack_float_B2G3R3_UNORM; - table[MESA_FORMAT_A_UNORM8] = pack_float_A_UNORM8; - table[MESA_FORMAT_A_UNORM16] = pack_float_A_UNORM16; - table[MESA_FORMAT_L_UNORM8] = pack_float_L_UNORM8; - table[MESA_FORMAT_L_UNORM16] = pack_float_L_UNORM16; - table[MESA_FORMAT_I_UNORM8] = pack_float_L_UNORM8; /* reuse pack_float_L_UNORM8 */ - table[MESA_FORMAT_I_UNORM16] = pack_float_L_UNORM16; /* reuse pack_float_L_UNORM16 */ - table[MESA_FORMAT_YCBCR] = pack_float_YCBCR; - table[MESA_FORMAT_YCBCR_REV] = pack_float_YCBCR_REV; - table[MESA_FORMAT_R_UNORM8] = pack_float_R_UNORM8; - table[MESA_FORMAT_R8G8_UNORM] = pack_float_R8G8_UNORM; - table[MESA_FORMAT_G8R8_UNORM] = pack_float_G8R8_UNORM; - table[MESA_FORMAT_R_UNORM16] = pack_float_R_UNORM16; - table[MESA_FORMAT_R16G16_UNORM] = pack_float_R16G16_UNORM; - table[MESA_FORMAT_G16R16_UNORM] = pack_float_G16R16_UNORM; - table[MESA_FORMAT_B10G10R10A2_UNORM] = pack_float_B10G10R10A2_UNORM; - table[MESA_FORMAT_R10G10B10A2_UINT] = pack_float_R10G10B10A2_UINT; - - /* should never convert RGBA to these formats */ - table[MESA_FORMAT_S8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z24_UNORM_S8_UINT] = NULL; - table[MESA_FORMAT_Z_UNORM16] = NULL; - table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL; - table[MESA_FORMAT_X8_UINT_Z24_UNORM] = NULL; - table[MESA_FORMAT_Z_UNORM32] = NULL; - table[MESA_FORMAT_S_UINT8] = NULL; - - table[MESA_FORMAT_BGR_SRGB8] = pack_float_BGR_SRGB8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = pack_float_A8B8G8R8_SRGB; - table[MESA_FORMAT_B8G8R8A8_SRGB] = pack_float_B8G8R8A8_SRGB; - table[MESA_FORMAT_A8R8G8B8_SRGB] = pack_float_A8R8G8B8_SRGB; - table[MESA_FORMAT_R8G8B8A8_SRGB] = pack_float_R8G8B8A8_SRGB; - table[MESA_FORMAT_L_SRGB8] = pack_float_L_SRGB8; - table[MESA_FORMAT_L8A8_SRGB] = pack_float_L8A8_SRGB; - table[MESA_FORMAT_A8L8_SRGB] = pack_float_A8L8_SRGB; - - /* n/a */ - table[MESA_FORMAT_SRGB_DXT1] = NULL; - table[MESA_FORMAT_SRGBA_DXT1] = NULL; - table[MESA_FORMAT_SRGBA_DXT3] = NULL; - table[MESA_FORMAT_SRGBA_DXT5] = NULL; - - table[MESA_FORMAT_RGB_FXT1] = NULL; - table[MESA_FORMAT_RGBA_FXT1] = NULL; - table[MESA_FORMAT_RGB_DXT1] = NULL; - table[MESA_FORMAT_RGBA_DXT1] = NULL; - table[MESA_FORMAT_RGBA_DXT3] = NULL; - table[MESA_FORMAT_RGBA_DXT5] = NULL; - - table[MESA_FORMAT_RGBA_FLOAT32] = pack_float_RGBA_FLOAT32; - table[MESA_FORMAT_RGBA_FLOAT16] = pack_float_RGBA_FLOAT16; - table[MESA_FORMAT_RGB_FLOAT32] = pack_float_RGB_FLOAT32; - table[MESA_FORMAT_RGB_FLOAT16] = pack_float_RGB_FLOAT16; - table[MESA_FORMAT_A_FLOAT32] = pack_float_A_FLOAT32; - table[MESA_FORMAT_A_FLOAT16] = pack_float_A_FLOAT16; - table[MESA_FORMAT_L_FLOAT32] = pack_float_L_FLOAT32; - table[MESA_FORMAT_L_FLOAT16] = pack_float_L_FLOAT16; - table[MESA_FORMAT_LA_FLOAT32] = pack_float_LA_FLOAT32; - table[MESA_FORMAT_LA_FLOAT16] = pack_float_LA_FLOAT16; - - table[MESA_FORMAT_I_FLOAT32] = pack_float_L_FLOAT32; - table[MESA_FORMAT_I_FLOAT16] = pack_float_L_FLOAT16; - table[MESA_FORMAT_R_FLOAT32] = pack_float_L_FLOAT32; - table[MESA_FORMAT_R_FLOAT16] = pack_float_L_FLOAT16; - table[MESA_FORMAT_RG_FLOAT32] = pack_float_RG_FLOAT32; - table[MESA_FORMAT_RG_FLOAT16] = pack_float_RG_FLOAT16; - - /* n/a */ - table[MESA_FORMAT_RGBA_SINT8] = NULL; - table[MESA_FORMAT_RGBA_SINT16] = NULL; - table[MESA_FORMAT_RGBA_SINT32] = NULL; - table[MESA_FORMAT_RGBA_UINT8] = NULL; - table[MESA_FORMAT_RGBA_UINT16] = NULL; - table[MESA_FORMAT_RGBA_UINT32] = NULL; - - table[MESA_FORMAT_RGBA_UNORM16] = pack_float_RGBA_16; - - table[MESA_FORMAT_R_SNORM8] = pack_float_R_SNORM8; - table[MESA_FORMAT_R8G8_SNORM] = pack_float_R8G8_SNORM; - table[MESA_FORMAT_X8B8G8R8_SNORM] = pack_float_X8B8G8R8_SNORM; - table[MESA_FORMAT_A8B8G8R8_SNORM] = pack_float_A8B8G8R8_SNORM; - table[MESA_FORMAT_R8G8B8A8_SNORM] = pack_float_R8G8B8A8_SNORM; - table[MESA_FORMAT_R_SNORM16] = pack_float_R_SNORM16; - table[MESA_FORMAT_R16G16_SNORM] = pack_float_R16G16_SNORM; - table[MESA_FORMAT_RGB_SNORM16] = pack_float_RGB_SNORM16; - table[MESA_FORMAT_RGBA_SNORM16] = pack_float_RGBA_SNORM16; - table[MESA_FORMAT_A_SNORM8] = pack_float_A_SNORM8; - table[MESA_FORMAT_L_SNORM8] = pack_float_L_SNORM8; - table[MESA_FORMAT_L8A8_SNORM] = pack_float_L8A8_SNORM; - table[MESA_FORMAT_A8L8_SNORM] = pack_float_A8L8_SNORM; - table[MESA_FORMAT_I_SNORM8] = pack_float_L_SNORM8; /* reused */ - table[MESA_FORMAT_A_SNORM16] = pack_float_A_SNORM16; - table[MESA_FORMAT_L_SNORM16] = pack_float_L_SNORM16; - table[MESA_FORMAT_LA_SNORM16] = pack_float_LA_SNORM16; - table[MESA_FORMAT_I_SNORM16] = pack_float_L_SNORM16; /* reused */ - - table[MESA_FORMAT_R9G9B9E5_FLOAT] = pack_float_R9G9B9E5_FLOAT; - table[MESA_FORMAT_R11G11B10_FLOAT] = pack_float_R11G11B10_FLOAT; - - table[MESA_FORMAT_B4G4R4X4_UNORM] = pack_float_XRGB4444_UNORM; - table[MESA_FORMAT_B5G5R5X1_UNORM] = pack_float_XRGB1555_UNORM; - table[MESA_FORMAT_R8G8B8X8_SNORM] = pack_float_XBGR8888_SNORM; - table[MESA_FORMAT_R8G8B8X8_SRGB] = pack_float_R8G8B8X8_SRGB; - table[MESA_FORMAT_X8B8G8R8_SRGB] = pack_float_X8B8G8R8_SRGB; - table[MESA_FORMAT_RGBX_UINT8] = NULL; - table[MESA_FORMAT_RGBX_SINT8] = NULL; - table[MESA_FORMAT_B10G10R10X2_UNORM] = pack_float_B10G10R10X2_UNORM; - table[MESA_FORMAT_RGBX_UNORM16] = pack_float_RGBX_UNORM16; - table[MESA_FORMAT_RGBX_SNORM16] = pack_float_RGBX_SNORM16; - table[MESA_FORMAT_RGBX_FLOAT16] = pack_float_XBGR16161616_FLOAT; - table[MESA_FORMAT_RGBX_UINT16] = NULL; - table[MESA_FORMAT_RGBX_SINT16] = NULL; - table[MESA_FORMAT_RGBX_FLOAT32] = pack_float_RGBX_FLOAT32; - table[MESA_FORMAT_RGBX_UINT32] = NULL; - table[MESA_FORMAT_RGBX_SINT32] = NULL; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = pack_float_R10G10B10A2_UNORM; - - table[MESA_FORMAT_G8R8_SNORM] = pack_float_G8R8_SNORM; - table[MESA_FORMAT_G16R16_SNORM] = pack_float_G16R16_SNORM; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = pack_float_B8G8R8X8_SRGB; - table[MESA_FORMAT_X8R8G8B8_SRGB] = pack_float_X8R8G8B8_SRGB; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -static pack_float_rgba_row_func -get_pack_float_rgba_row_function(mesa_format format) -{ - static pack_float_rgba_row_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - /* We don't need a special row packing function for each format. - * There's a generic fallback which uses a per-pixel packing function. - */ - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_row_float_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_row_float_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_row_float_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_row_float_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_row_float_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_row_float_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_row_float_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_row_float_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_row_float_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_row_float_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_row_float_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_row_float_R5G6B5_UNORM; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -static pack_ubyte_rgba_row_func -get_pack_ubyte_rgba_row_function(mesa_format format) -{ - static pack_ubyte_rgba_row_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - /* We don't need a special row packing function for each format. - * There's a generic fallback which uses a per-pixel packing function. - */ - memset(table, 0, sizeof(table)); - - table[MESA_FORMAT_A8B8G8R8_UNORM] = pack_row_ubyte_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = pack_row_ubyte_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = pack_row_ubyte_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = pack_row_ubyte_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = pack_row_ubyte_A8B8G8R8_UNORM; /* reused */ - table[MESA_FORMAT_R8G8B8X8_UNORM] = pack_row_ubyte_R8G8B8A8_UNORM; /* reused */ - table[MESA_FORMAT_B8G8R8X8_UNORM] = pack_row_ubyte_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = pack_row_ubyte_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = pack_row_ubyte_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = pack_row_ubyte_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = pack_row_ubyte_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = pack_row_ubyte_R5G6B5_UNORM; - - initialized = GL_TRUE; - } - - return table[format]; -} - - - -/** - * Pack a row of GLfloat rgba[4] values to the destination. - */ -void -_mesa_pack_float_rgba_row(mesa_format format, GLuint n, - const GLfloat src[][4], void *dst) -{ - pack_float_rgba_row_func packrow = get_pack_float_rgba_row_function(format); - if (packrow) { - /* use "fast" function */ - packrow(n, src, dst); - } - else { - /* slower fallback */ - gl_pack_float_rgba_func pack = _mesa_get_pack_float_rgba_function(format); - GLuint dstStride = _mesa_get_format_bytes(format); - GLubyte *dstPtr = (GLubyte *) dst; - GLuint i; - - assert(pack); - if (!pack) - return; - - for (i = 0; i < n; i++) { - pack(src[i], dstPtr); - dstPtr += dstStride; - } - } -} - - -/** - * Pack a row of GLubyte rgba[4] values to the destination. - */ -void -_mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, - const GLubyte src[][4], void *dst) -{ - pack_ubyte_rgba_row_func packrow = get_pack_ubyte_rgba_row_function(format); - if (packrow) { - /* use "fast" function */ - packrow(n, src, dst); - } - else { - /* slower fallback */ - gl_pack_ubyte_rgba_func pack = _mesa_get_pack_ubyte_rgba_function(format); - const GLuint stride = _mesa_get_format_bytes(format); - GLubyte *d = ((GLubyte *) dst); - GLuint i; - - assert(pack); - if (!pack) - return; - - for (i = 0; i < n; i++) { - pack(src[i], d); - d += stride; - } - } -} - - -/** - * Pack a 2D image of ubyte RGBA pixels in the given format. - * \param srcRowStride source image row stride in bytes - * \param dstRowStride destination image row stride in bytes - */ -void -_mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, - const GLubyte *src, GLint srcRowStride, - void *dst, GLint dstRowStride) -{ - pack_ubyte_rgba_row_func packrow = get_pack_ubyte_rgba_row_function(format); - GLubyte *dstUB = (GLubyte *) dst; - GLuint i; - - if (packrow) { - if (srcRowStride == width * 4 * sizeof(GLubyte) && - dstRowStride == _mesa_format_row_stride(format, width)) { - /* do whole image at once */ - packrow(width * height, (const GLubyte (*)[4]) src, dst); - } - else { - /* row by row */ - for (i = 0; i < height; i++) { - packrow(width, (const GLubyte (*)[4]) src, dstUB); - src += srcRowStride; - dstUB += dstRowStride; - } - } - } - else { - /* slower fallback */ - for (i = 0; i < height; i++) { - _mesa_pack_ubyte_rgba_row(format, width, - (const GLubyte (*)[4]) src, dstUB); - src += srcRowStride; - dstUB += dstRowStride; - } - } -} - - - -/** - ** Pack float Z pixels - **/ - -static void -pack_float_S8_UINT_Z24_UNORM(const GLfloat *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint s = *d & 0xff; - GLuint z = (GLuint) (*src * scale); - assert(z <= 0xffffff); - *d = (z << 8) | s; -} - -static void -pack_float_Z24_UNORM_S8_UINT(const GLfloat *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint s = *d & 0xff000000; - GLuint z = (GLuint) (*src * scale); - assert(z <= 0xffffff); - *d = s | z; -} - -static void -pack_float_Z_UNORM16(const GLfloat *src, void *dst) -{ - GLushort *d = ((GLushort *) dst); - const GLfloat scale = (GLfloat) 0xffff; - *d = (GLushort) (*src * scale); -} - -static void -pack_float_Z_UNORM32(const GLfloat *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffffff; - *d = (GLuint) (*src * scale); -} - -static void -pack_float_Z_FLOAT32(const GLfloat *src, void *dst) -{ - GLfloat *d = (GLfloat *) dst; - *d = *src; -} - -gl_pack_float_z_func -_mesa_get_pack_float_z_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - return pack_float_S8_UINT_Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - return pack_float_Z24_UNORM_S8_UINT; - case MESA_FORMAT_Z_UNORM16: - return pack_float_Z_UNORM16; - case MESA_FORMAT_Z_UNORM32: - return pack_float_Z_UNORM32; - case MESA_FORMAT_Z_FLOAT32: - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_float_Z_FLOAT32; - default: - _mesa_problem(NULL, - "unexpected format in _mesa_get_pack_float_z_func()"); - return NULL; - } -} - - - -/** - ** Pack uint Z pixels. The incoming src value is always in - ** the range [0, 2^32-1]. - **/ - -static void -pack_uint_S8_UINT_Z24_UNORM(const GLuint *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *d & 0xff; - GLuint z = *src & 0xffffff00; - *d = z | s; -} - -static void -pack_uint_Z24_UNORM_S8_UINT(const GLuint *src, void *dst) -{ - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *d & 0xff000000; - GLuint z = *src >> 8; - *d = s | z; -} - -static void -pack_uint_Z_UNORM16(const GLuint *src, void *dst) -{ - GLushort *d = ((GLushort *) dst); - *d = *src >> 16; -} - -static void -pack_uint_Z_UNORM32(const GLuint *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - *d = *src; -} - -static void -pack_uint_Z_FLOAT32(const GLuint *src, void *dst) -{ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - *d = (GLuint) (*src * scale); - assert(*d >= 0.0f); - assert(*d <= 1.0f); -} - -static void -pack_uint_Z_FLOAT32_X24S8(const GLuint *src, void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - *d = (GLfloat) (*src * scale); - assert(*d >= 0.0f); - assert(*d <= 1.0f); -} - -gl_pack_uint_z_func -_mesa_get_pack_uint_z_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - return pack_uint_S8_UINT_Z24_UNORM; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - return pack_uint_Z24_UNORM_S8_UINT; - case MESA_FORMAT_Z_UNORM16: - return pack_uint_Z_UNORM16; - case MESA_FORMAT_Z_UNORM32: - return pack_uint_Z_UNORM32; - case MESA_FORMAT_Z_FLOAT32: - return pack_uint_Z_FLOAT32; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_uint_Z_FLOAT32_X24S8; - default: - _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()"); - return NULL; - } -} - - -/** - ** Pack ubyte stencil pixels - **/ - -static void -pack_ubyte_stencil_Z24_S8(const GLubyte *src, void *dst) -{ - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *src; - GLuint z = *d & 0xffffff00; - *d = z | s; -} - -static void -pack_ubyte_stencil_S8_Z24(const GLubyte *src, void *dst) -{ - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint s = *src << 24; - GLuint z = *d & 0xffffff; - *d = s | z; -} - -static void -pack_ubyte_stencil_S8(const GLubyte *src, void *dst) -{ - GLubyte *d = (GLubyte *) dst; - *d = *src; -} - -static void -pack_ubyte_stencil_Z32_FLOAT_X24S8(const GLubyte *src, void *dst) -{ - GLfloat *d = ((GLfloat *) dst); - d[1] = *src; -} - - -gl_pack_ubyte_stencil_func -_mesa_get_pack_ubyte_stencil_func(mesa_format format) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - return pack_ubyte_stencil_Z24_S8; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - return pack_ubyte_stencil_S8_Z24; - case MESA_FORMAT_S_UINT8: - return pack_ubyte_stencil_S8; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - return pack_ubyte_stencil_Z32_FLOAT_X24S8; - default: - _mesa_problem(NULL, - "unexpected format in _mesa_pack_ubyte_stencil_func()"); - return NULL; - } -} - - - -void -_mesa_pack_float_z_row(mesa_format format, GLuint n, - const GLfloat *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff; - GLuint z = (GLuint) (src[i] * scale); - assert(z <= 0xffffff); - d[i] = (z << 8) | s; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff000000; - GLuint z = (GLuint) (src[i] * scale); - assert(z <= 0xffffff); - d[i] = s | z; - } - } - break; - case MESA_FORMAT_Z_UNORM16: - { - GLushort *d = ((GLushort *) dst); - const GLfloat scale = (GLfloat) 0xffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i] = (GLushort) (src[i] * scale); - } - } - break; - case MESA_FORMAT_Z_UNORM32: - { - GLuint *d = ((GLuint *) dst); - const GLdouble scale = (GLdouble) 0xffffffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i] = (GLuint) (src[i] * scale); - } - } - break; - case MESA_FORMAT_Z_FLOAT32: - memcpy(dst, src, n * sizeof(GLfloat)); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - GLuint i; - for (i = 0; i < n; i++) { - d[i].z = src[i]; - } - } - break; - default: - _mesa_problem(NULL, "unexpected format in _mesa_pack_float_z_row()"); - } -} - - -/** - * The incoming Z values are always in the range [0, 0xffffffff]. - */ -void -_mesa_pack_uint_z_row(mesa_format format, GLuint n, - const GLuint *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff; - GLuint z = src[i] & 0xffffff00; - d[i] = z | s; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - { - /* don't disturb the stencil values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = d[i] & 0xff000000; - GLuint z = src[i] >> 8; - d[i] = s | z; - } - } - break; - case MESA_FORMAT_Z_UNORM16: - { - GLushort *d = ((GLushort *) dst); - GLuint i; - for (i = 0; i < n; i++) { - d[i] = src[i] >> 16; - } - } - break; - case MESA_FORMAT_Z_UNORM32: - memcpy(dst, src, n * sizeof(GLfloat)); - break; - case MESA_FORMAT_Z_FLOAT32: - { - GLuint *d = ((GLuint *) dst); - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i] = (GLuint) (src[i] * scale); - assert(d[i] >= 0.0f); - assert(d[i] <= 1.0f); - } - } - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; - GLuint i; - for (i = 0; i < n; i++) { - d[i].z = (GLfloat) (src[i] * scale); - assert(d[i].z >= 0.0f); - assert(d[i].z <= 1.0f); - } - } - break; - default: - _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()"); - } -} - - -void -_mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n, - const GLubyte *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - { - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = src[i]; - GLuint z = d[i] & 0xffffff00; - d[i] = z | s; - } - } - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - { - /* don't disturb the Z values */ - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = src[i] << 24; - GLuint z = d[i] & 0xffffff; - d[i] = s | z; - } - } - break; - case MESA_FORMAT_S_UINT8: - memcpy(dst, src, n * sizeof(GLubyte)); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - GLuint i; - for (i = 0; i < n; i++) { - d[i].x24s8 = src[i]; - } - } - break; - default: - _mesa_problem(NULL, "unexpected format in _mesa_pack_ubyte_stencil_row()"); - } -} - - -/** - * Incoming Z/stencil values are always in uint_24_8 format. - */ -void -_mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, - const GLuint *src, void *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - memcpy(dst, src, n * sizeof(GLuint)); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - { - GLuint *d = ((GLuint *) dst); - GLuint i; - for (i = 0; i < n; i++) { - GLuint s = src[i] << 24; - GLuint z = src[i] >> 8; - d[i] = s | z; - } - } - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - { - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - GLuint i; - for (i = 0; i < n; i++) { - GLfloat z = (GLfloat) ((src[i] >> 8) * scale); - d[i].z = z; - d[i].x24s8 = src[i]; - } - } - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row", - _mesa_get_format_name(format)); - return; - } -} - - - -/** - * Convert a boolean color mask to a packed color where each channel of - * the packed value at dst will be 0 or ~0 depending on the colorMask. - */ -void -_mesa_pack_colormask(mesa_format format, const GLubyte colorMask[4], void *dst) -{ - GLfloat maskColor[4]; - - switch (_mesa_get_format_datatype(format)) { - case GL_UNSIGNED_NORMALIZED: - /* simple: 1.0 will convert to ~0 in the right bit positions */ - maskColor[0] = colorMask[0] ? 1.0f : 0.0f; - maskColor[1] = colorMask[1] ? 1.0f : 0.0f; - maskColor[2] = colorMask[2] ? 1.0f : 0.0f; - maskColor[3] = colorMask[3] ? 1.0f : 0.0f; - _mesa_pack_float_rgba_row(format, 1, - (const GLfloat (*)[4]) maskColor, dst); - break; - case GL_SIGNED_NORMALIZED: - case GL_FLOAT: - /* These formats are harder because it's hard to know the floating - * point values that will convert to ~0 for each color channel's bits. - * This solution just generates a non-zero value for each color channel - * then fixes up the non-zero values to be ~0. - * Note: we'll need to add special case code if we ever have to deal - * with formats with unequal color channel sizes, like R11_G11_B10. - * We issue a warning below for channel sizes other than 8,16,32. - */ - { - GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */ - GLuint bytes = _mesa_get_format_bytes(format); - GLuint i; - - /* this should put non-zero values into the channels of dst */ - maskColor[0] = colorMask[0] ? -1.0f : 0.0f; - maskColor[1] = colorMask[1] ? -1.0f : 0.0f; - maskColor[2] = colorMask[2] ? -1.0f : 0.0f; - maskColor[3] = colorMask[3] ? -1.0f : 0.0f; - _mesa_pack_float_rgba_row(format, 1, - (const GLfloat (*)[4]) maskColor, dst); - - /* fix-up the dst channels by converting non-zero values to ~0 */ - if (bits == 8) { - GLubyte *d = (GLubyte *) dst; - for (i = 0; i < bytes; i++) { - d[i] = d[i] ? 0xff : 0x0; - } - } - else if (bits == 16) { - GLushort *d = (GLushort *) dst; - for (i = 0; i < bytes / 2; i++) { - d[i] = d[i] ? 0xffff : 0x0; - } - } - else if (bits == 32) { - GLuint *d = (GLuint *) dst; - for (i = 0; i < bytes / 4; i++) { - d[i] = d[i] ? 0xffffffffU : 0x0; - } - } - else { - _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()"); - return; - } - } - break; - default: - _mesa_problem(NULL, "unexpected format data type in gen_color_mask()"); - return; - } -} diff --git a/mesalib/src/mesa/main/format_pack.h b/mesalib/src/mesa/main/format_pack.h index 2577def41..aa7113e9b 100644 --- a/mesalib/src/mesa/main/format_pack.h +++ b/mesalib/src/mesa/main/format_pack.h @@ -68,7 +68,6 @@ extern gl_pack_ubyte_stencil_func _mesa_get_pack_ubyte_stencil_func(mesa_format format); - extern void _mesa_pack_float_rgba_row(mesa_format format, GLuint n, const GLfloat src[][4], void *dst); @@ -77,6 +76,9 @@ extern void _mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, const GLubyte src[][4], void *dst); +extern void +_mesa_pack_uint_rgba_row(mesa_format format, GLuint n, + const GLuint src[][4], void *dst); extern void _mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, diff --git a/mesalib/src/mesa/main/format_pack.py b/mesalib/src/mesa/main/format_pack.py new file mode 100644 index 000000000..f141da83c --- /dev/null +++ b/mesalib/src/mesa/main/format_pack.py @@ -0,0 +1,1004 @@ +#!/usr/bin/env python + +from mako.template import Template +from sys import argv + +string = """/* + * Mesa 3-D graphics library + * + * Copyright (c) 2011 VMware, Inc. + * 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. + */ + + +/** + * Color, depth, stencil packing functions. + * Used to pack basic color, depth and stencil formats to specific + * hardware formats. + * + * There are both per-pixel and per-row packing functions: + * - The former will be used by swrast to write values to the color, depth, + * stencil buffers when drawing points, lines and masked spans. + * - The later will be used for image-oriented functions like glDrawPixels, + * glAccum, and glTexImage. + */ + +#include <stdint.h> + +#include "colormac.h" +#include "format_pack.h" +#include "format_utils.h" +#include "macros.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "util/format_srgb.h" + +#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS)) +#define PACK(SRC, OFFSET, BITS) (((SRC) & MAX_UINT(BITS)) << (OFFSET)) + +<% +import format_parser as parser + +formats = parser.parse(argv[1]) + +rgb_formats = [] +for f in formats: + if f.name == 'MESA_FORMAT_NONE': + continue + if f.colorspace not in ('rgb', 'srgb'): + continue + + rgb_formats.append(f) +%> + +/* ubyte packing functions */ + +%for f in rgb_formats: + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +pack_ubyte_${f.short_name()}(const GLubyte src[4], void *dst) +{ + %for (i, c) in enumerate(f.channels): + <% i = f.swizzle.inverse()[i] %> + %if c.type == 'x': + <% continue %> + %endif + + ${c.datatype()} ${c.name} = + %if not f.is_normalized() and f.is_int(): + %if c.type == parser.SIGNED: + _mesa_unsigned_to_signed(src[${i}], ${c.size}); + %else: + _mesa_unsigned_to_unsigned(src[${i}], ${c.size}); + %endif + %elif c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + util_format_linear_to_srgb_8unorm(src[${i}]); + %else: + _mesa_unorm_to_unorm(src[${i}], 8, ${c.size}); + %endif + %elif c.type == parser.SIGNED: + _mesa_unorm_to_snorm(src[${i}], 8, ${c.size}); + %elif c.type == parser.FLOAT: + %if c.size == 32: + _mesa_unorm_to_float(src[${i}], 8); + %elif c.size == 16: + _mesa_unorm_to_half(src[${i}], 8); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %endfor + + %if f.layout == parser.ARRAY: + ${f.datatype()} *d = (${f.datatype()} *)dst; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d[${i}] = ${c.name}; + %endfor + %elif f.layout == parser.PACKED: + ${f.datatype()} d = 0; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d |= PACK(${c.name}, ${c.shift}, ${c.size}); + %endfor + (*(${f.datatype()} *)dst) = d; + %else: + <% assert False %> + %endif +} +%endfor + +static inline void +pack_ubyte_r9g9b9e5_float(const GLubyte src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + GLfloat rgb[3]; + rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8); + rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8); + rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8); + *d = float3_to_rgb9e5(rgb); +} + +static inline void +pack_ubyte_r11g11b10_float(const GLubyte src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + GLfloat rgb[3]; + rgb[0] = _mesa_unorm_to_float(src[RCOMP], 8); + rgb[1] = _mesa_unorm_to_float(src[GCOMP], 8); + rgb[2] = _mesa_unorm_to_float(src[BCOMP], 8); + *d = float3_to_r11g11b10f(rgb); +} + +/* uint packing functions */ + +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +pack_uint_${f.short_name()}(const GLuint src[4], void *dst) +{ + %for (i, c) in enumerate(f.channels): + <% i = f.swizzle.inverse()[i] %> + %if c.type == 'x': + <% continue %> + %endif + + ${c.datatype()} ${c.name} = + %if c.type == parser.SIGNED: + _mesa_signed_to_signed(src[${i}], ${c.size}); + %elif c.type == parser.UNSIGNED: + _mesa_unsigned_to_unsigned(src[${i}], ${c.size}); + %else: + assert(!"Invalid type: only integer types are allowed"); + %endif + %endfor + + %if f.layout == parser.ARRAY: + ${f.datatype()} *d = (${f.datatype()} *)dst; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d[${i}] = ${c.name}; + %endfor + %elif f.layout == parser.PACKED: + ${f.datatype()} d = 0; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d |= PACK(${c.name}, ${c.shift}, ${c.size}); + %endfor + (*(${f.datatype()} *)dst) = d; + %else: + <% assert False %> + %endif +} +%endfor + +/* float packing functions */ + +%for f in rgb_formats: + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +pack_float_${f.short_name()}(const GLfloat src[4], void *dst) +{ + %for (i, c) in enumerate(f.channels): + <% i = f.swizzle.inverse()[i] %> + %if c.type == 'x': + <% continue %> + %endif + + ${c.datatype()} ${c.name} = + %if c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + util_format_linear_float_to_srgb_8unorm(src[${i}]); + %else: + _mesa_float_to_unorm(src[${i}], ${c.size}); + %endif + %elif c.type == parser.SIGNED: + _mesa_float_to_snorm(src[${i}], ${c.size}); + %elif c.type == parser.FLOAT: + %if c.size == 32: + src[${i}]; + %elif c.size == 16: + _mesa_float_to_half(src[${i}]); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %endfor + + %if f.layout == parser.ARRAY: + ${f.datatype()} *d = (${f.datatype()} *)dst; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d[${i}] = ${c.name}; + %endfor + %elif f.layout == parser.PACKED: + ${f.datatype()} d = 0; + %for (i, c) in enumerate(f.channels): + %if c.type == 'x': + <% continue %> + %endif + d |= PACK(${c.name}, ${c.shift}, ${c.size}); + %endfor + (*(${f.datatype()} *)dst) = d; + %else: + <% assert False %> + %endif +} +%endfor + +static inline void +pack_float_r9g9b9e5_float(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + *d = float3_to_rgb9e5(src); +} + +static inline void +pack_float_r11g11b10_float(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + *d = float3_to_r11g11b10f(src); +} + +/** + * Return a function that can pack a GLubyte rgba[4] color. + */ +gl_pack_ubyte_rgba_func +_mesa_get_pack_ubyte_rgba_function(mesa_format format) +{ + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %endif + + case ${f.name}: + return pack_ubyte_${f.short_name()}; +%endfor + default: + return NULL; + } +} + +/** + * Return a function that can pack a GLfloat rgba[4] color. + */ +gl_pack_float_rgba_func +_mesa_get_pack_float_rgba_function(mesa_format format) +{ + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + return pack_float_${f.short_name()}; +%endfor + default: + return NULL; + } +} + +/** + * Pack a row of GLubyte rgba[4] values to the destination. + */ +void +_mesa_pack_ubyte_rgba_row(mesa_format format, GLuint n, + const GLubyte src[][4], void *dst) +{ + GLuint i; + GLubyte *d = dst; + + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + pack_ubyte_${f.short_name()}(src[i], d); + d += ${f.block_size() / 8}; + } + break; +%endfor + default: + assert(!"Invalid format"); + } +} + +/** + * Pack a row of GLuint rgba[4] values to the destination. + */ +void +_mesa_pack_uint_rgba_row(mesa_format format, GLuint n, + const GLuint src[][4], void *dst) +{ + GLuint i; + GLubyte *d = dst; + + switch (format) { +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + pack_uint_${f.short_name()}(src[i], d); + d += ${f.block_size() / 8}; + } + break; +%endfor + default: + assert(!"Invalid format"); + } +} + +/** + * Pack a row of GLfloat rgba[4] values to the destination. + */ +void +_mesa_pack_float_rgba_row(mesa_format format, GLuint n, + const GLfloat src[][4], void *dst) +{ + GLuint i; + GLubyte *d = dst; + + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + pack_float_${f.short_name()}(src[i], d); + d += ${f.block_size() / 8}; + } + break; +%endfor + default: + assert(!"Invalid format"); + } +} + +/** + * Pack a 2D image of ubyte RGBA pixels in the given format. + * \param srcRowStride source image row stride in bytes + * \param dstRowStride destination image row stride in bytes + */ +void +_mesa_pack_ubyte_rgba_rect(mesa_format format, GLuint width, GLuint height, + const GLubyte *src, GLint srcRowStride, + void *dst, GLint dstRowStride) +{ + GLubyte *dstUB = dst; + GLuint i; + + if (srcRowStride == width * 4 * sizeof(GLubyte) && + dstRowStride == _mesa_format_row_stride(format, width)) { + /* do whole image at once */ + _mesa_pack_ubyte_rgba_row(format, width * height, + (const GLubyte (*)[4]) src, dst); + } + else { + /* row by row */ + for (i = 0; i < height; i++) { + _mesa_pack_ubyte_rgba_row(format, width, + (const GLubyte (*)[4]) src, dstUB); + src += srcRowStride; + dstUB += dstRowStride; + } + } +} + + +/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ +struct z32f_x24s8 +{ + float z; + uint32_t x24s8; +}; + + +/** + ** Pack float Z pixels + **/ + +static void +pack_float_S8_UINT_Z24_UNORM(const GLfloat *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint s = *d & 0xff; + GLuint z = (GLuint) (*src * scale); + assert(z <= 0xffffff); + *d = (z << 8) | s; +} + +static void +pack_float_Z24_UNORM_S8_UINT(const GLfloat *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint s = *d & 0xff000000; + GLuint z = (GLuint) (*src * scale); + assert(z <= 0xffffff); + *d = s | z; +} + +static void +pack_float_Z_UNORM16(const GLfloat *src, void *dst) +{ + GLushort *d = ((GLushort *) dst); + const GLfloat scale = (GLfloat) 0xffff; + *d = (GLushort) (*src * scale); +} + +static void +pack_float_Z_UNORM32(const GLfloat *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffffff; + *d = (GLuint) (*src * scale); +} + +static void +pack_float_Z_FLOAT32(const GLfloat *src, void *dst) +{ + GLfloat *d = (GLfloat *) dst; + *d = *src; +} + +gl_pack_float_z_func +_mesa_get_pack_float_z_func(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + return pack_float_S8_UINT_Z24_UNORM; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + return pack_float_Z24_UNORM_S8_UINT; + case MESA_FORMAT_Z_UNORM16: + return pack_float_Z_UNORM16; + case MESA_FORMAT_Z_UNORM32: + return pack_float_Z_UNORM32; + case MESA_FORMAT_Z_FLOAT32: + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return pack_float_Z_FLOAT32; + default: + _mesa_problem(NULL, + "unexpected format in _mesa_get_pack_float_z_func()"); + return NULL; + } +} + + + +/** + ** Pack uint Z pixels. The incoming src value is always in + ** the range [0, 2^32-1]. + **/ + +static void +pack_uint_S8_UINT_Z24_UNORM(const GLuint *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *d & 0xff; + GLuint z = *src & 0xffffff00; + *d = z | s; +} + +static void +pack_uint_Z24_UNORM_S8_UINT(const GLuint *src, void *dst) +{ + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *d & 0xff000000; + GLuint z = *src >> 8; + *d = s | z; +} + +static void +pack_uint_Z_UNORM16(const GLuint *src, void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = *src >> 16; +} + +static void +pack_uint_Z_UNORM32(const GLuint *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + *d = *src; +} + +static void +pack_uint_Z_FLOAT32(const GLuint *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + *d = (GLuint) (*src * scale); + assert(*d >= 0.0f); + assert(*d <= 1.0f); +} + +static void +pack_uint_Z_FLOAT32_X24S8(const GLuint *src, void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + *d = (GLfloat) (*src * scale); + assert(*d >= 0.0f); + assert(*d <= 1.0f); +} + +gl_pack_uint_z_func +_mesa_get_pack_uint_z_func(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + return pack_uint_S8_UINT_Z24_UNORM; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + return pack_uint_Z24_UNORM_S8_UINT; + case MESA_FORMAT_Z_UNORM16: + return pack_uint_Z_UNORM16; + case MESA_FORMAT_Z_UNORM32: + return pack_uint_Z_UNORM32; + case MESA_FORMAT_Z_FLOAT32: + return pack_uint_Z_FLOAT32; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return pack_uint_Z_FLOAT32_X24S8; + default: + _mesa_problem(NULL, "unexpected format in _mesa_get_pack_uint_z_func()"); + return NULL; + } +} + + +/** + ** Pack ubyte stencil pixels + **/ + +static void +pack_ubyte_stencil_Z24_S8(const GLubyte *src, void *dst) +{ + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *src; + GLuint z = *d & 0xffffff00; + *d = z | s; +} + +static void +pack_ubyte_stencil_S8_Z24(const GLubyte *src, void *dst) +{ + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint s = *src << 24; + GLuint z = *d & 0xffffff; + *d = s | z; +} + +static void +pack_ubyte_stencil_S8(const GLubyte *src, void *dst) +{ + GLubyte *d = (GLubyte *) dst; + *d = *src; +} + +static void +pack_ubyte_stencil_Z32_FLOAT_X24S8(const GLubyte *src, void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[1] = *src; +} + + +gl_pack_ubyte_stencil_func +_mesa_get_pack_ubyte_stencil_func(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + return pack_ubyte_stencil_Z24_S8; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + return pack_ubyte_stencil_S8_Z24; + case MESA_FORMAT_S_UINT8: + return pack_ubyte_stencil_S8; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return pack_ubyte_stencil_Z32_FLOAT_X24S8; + default: + _mesa_problem(NULL, + "unexpected format in _mesa_pack_ubyte_stencil_func()"); + return NULL; + } +} + + + +void +_mesa_pack_float_z_row(mesa_format format, GLuint n, + const GLfloat *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff; + GLuint z = (GLuint) (src[i] * scale); + assert(z <= 0xffffff); + d[i] = (z << 8) | s; + } + } + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff000000; + GLuint z = (GLuint) (src[i] * scale); + assert(z <= 0xffffff); + d[i] = s | z; + } + } + break; + case MESA_FORMAT_Z_UNORM16: + { + GLushort *d = ((GLushort *) dst); + const GLfloat scale = (GLfloat) 0xffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = (GLushort) (src[i] * scale); + } + } + break; + case MESA_FORMAT_Z_UNORM32: + { + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = (GLuint) (src[i] * scale); + } + } + break; + case MESA_FORMAT_Z_FLOAT32: + memcpy(dst, src, n * sizeof(GLfloat)); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + GLuint i; + for (i = 0; i < n; i++) { + d[i].z = src[i]; + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_float_z_row()"); + } +} + + +/** + * The incoming Z values are always in the range [0, 0xffffffff]. + */ +void +_mesa_pack_uint_z_row(mesa_format format, GLuint n, + const GLuint *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff; + GLuint z = src[i] & 0xffffff00; + d[i] = z | s; + } + } + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + { + /* don't disturb the stencil values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = d[i] & 0xff000000; + GLuint z = src[i] >> 8; + d[i] = s | z; + } + } + break; + case MESA_FORMAT_Z_UNORM16: + { + GLushort *d = ((GLushort *) dst); + GLuint i; + for (i = 0; i < n; i++) { + d[i] = src[i] >> 16; + } + } + break; + case MESA_FORMAT_Z_UNORM32: + memcpy(dst, src, n * sizeof(GLfloat)); + break; + case MESA_FORMAT_Z_FLOAT32: + { + GLuint *d = ((GLuint *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = (GLuint) (src[i] * scale); + assert(d[i] >= 0.0f); + assert(d[i] <= 1.0f); + } + } + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i].z = (GLfloat) (src[i] * scale); + assert(d[i].z >= 0.0f); + assert(d[i].z <= 1.0f); + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()"); + } +} + + +void +_mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n, + const GLubyte *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + { + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = src[i]; + GLuint z = d[i] & 0xffffff00; + d[i] = z | s; + } + } + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + { + /* don't disturb the Z values */ + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = src[i] << 24; + GLuint z = d[i] & 0xffffff; + d[i] = s | z; + } + } + break; + case MESA_FORMAT_S_UINT8: + memcpy(dst, src, n * sizeof(GLubyte)); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + GLuint i; + for (i = 0; i < n; i++) { + d[i].x24s8 = src[i]; + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_ubyte_stencil_row()"); + } +} + + +/** + * Incoming Z/stencil values are always in uint_24_8 format. + */ +void +_mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, + const GLuint *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + memcpy(dst, src, n * sizeof(GLuint)); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + { + GLuint *d = ((GLuint *) dst); + GLuint i; + for (i = 0; i < n; i++) { + GLuint s = src[i] << 24; + GLuint z = src[i] >> 8; + d[i] = s | z; + } + } + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + { + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + GLuint i; + for (i = 0; i < n; i++) { + GLfloat z = (GLfloat) ((src[i] >> 8) * scale); + d[i].z = z; + d[i].x24s8 = src[i]; + } + } + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row", + _mesa_get_format_name(format)); + return; + } +} + + + +/** + * Convert a boolean color mask to a packed color where each channel of + * the packed value at dst will be 0 or ~0 depending on the colorMask. + */ +void +_mesa_pack_colormask(mesa_format format, const GLubyte colorMask[4], void *dst) +{ + GLfloat maskColor[4]; + + switch (_mesa_get_format_datatype(format)) { + case GL_UNSIGNED_NORMALIZED: + /* simple: 1.0 will convert to ~0 in the right bit positions */ + maskColor[0] = colorMask[0] ? 1.0f : 0.0f; + maskColor[1] = colorMask[1] ? 1.0f : 0.0f; + maskColor[2] = colorMask[2] ? 1.0f : 0.0f; + maskColor[3] = colorMask[3] ? 1.0f : 0.0f; + _mesa_pack_float_rgba_row(format, 1, + (const GLfloat (*)[4]) maskColor, dst); + break; + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + /* These formats are harder because it's hard to know the floating + * point values that will convert to ~0 for each color channel's bits. + * This solution just generates a non-zero value for each color channel + * then fixes up the non-zero values to be ~0. + * Note: we'll need to add special case code if we ever have to deal + * with formats with unequal color channel sizes, like R11_G11_B10. + * We issue a warning below for channel sizes other than 8,16,32. + */ + { + GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */ + GLuint bytes = _mesa_get_format_bytes(format); + GLuint i; + + /* this should put non-zero values into the channels of dst */ + maskColor[0] = colorMask[0] ? -1.0f : 0.0f; + maskColor[1] = colorMask[1] ? -1.0f : 0.0f; + maskColor[2] = colorMask[2] ? -1.0f : 0.0f; + maskColor[3] = colorMask[3] ? -1.0f : 0.0f; + _mesa_pack_float_rgba_row(format, 1, + (const GLfloat (*)[4]) maskColor, dst); + + /* fix-up the dst channels by converting non-zero values to ~0 */ + if (bits == 8) { + GLubyte *d = (GLubyte *) dst; + for (i = 0; i < bytes; i++) { + d[i] = d[i] ? 0xff : 0x0; + } + } + else if (bits == 16) { + GLushort *d = (GLushort *) dst; + for (i = 0; i < bytes / 2; i++) { + d[i] = d[i] ? 0xffff : 0x0; + } + } + else if (bits == 32) { + GLuint *d = (GLuint *) dst; + for (i = 0; i < bytes / 4; i++) { + d[i] = d[i] ? 0xffffffffU : 0x0; + } + } + else { + _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()"); + return; + } + } + break; + default: + _mesa_problem(NULL, "unexpected format data type in gen_color_mask()"); + return; + } +} +""" + +template = Template(string); + +print template.render(argv = argv[0:]) diff --git a/mesalib/src/mesa/main/format_parser.py b/mesalib/src/mesa/main/format_parser.py index 5e45c74de..11184f78e 100644 --- a/mesalib/src/mesa/main/format_parser.py +++ b/mesalib/src/mesa/main/format_parser.py @@ -24,6 +24,8 @@ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +import sys + VOID = 'x' UNSIGNED = 'u' SIGNED = 's' @@ -102,6 +104,10 @@ class Channel: """Returns true if the size of this channel is a power of two.""" return is_power_of_two(self.size) + def datatype(self): + """Returns the datatype corresponding to a channel type and size""" + return _get_datatype(self.type, self.size) + class Swizzle: """Describes a swizzle operation. @@ -469,6 +475,49 @@ class Format: return channel return None + def datatype(self): + """Returns the datatype corresponding to a format's channel type and size""" + if self.layout == PACKED: + if self.block_size() == 8: + return 'uint8_t' + if self.block_size() == 16: + return 'uint16_t' + if self.block_size() == 32: + return 'uint32_t' + else: + assert False + else: + return _get_datatype(self.channel_type(), self.channel_size()) + +def _get_datatype(type, size): + if type == FLOAT: + if size == 32: + return 'float' + elif size == 16: + return 'uint16_t' + else: + assert False + elif type == UNSIGNED: + if size <= 8: + return 'uint8_t' + elif size <= 16: + return 'uint16_t' + elif size <= 32: + return 'uint32_t' + else: + assert False + elif type == SIGNED: + if size <= 8: + return 'int8_t' + elif size <= 16: + return 'int16_t' + elif size <= 32: + return 'int32_t' + else: + assert False + else: + assert False + def _parse_channels(fields, layout, colorspace, swizzle): channels = [] for field in fields: @@ -515,7 +564,10 @@ def parse(filename): block_height = int(fields[3]) colorspace = fields[9] - swizzle = Swizzle(fields[8]) + try: + swizzle = Swizzle(fields[8]) + except: + sys.exit("error parsing swizzle for format " + name) 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 deleted file mode 100644 index d5628a9e7..000000000 --- a/mesalib/src/mesa/main/format_unpack.c +++ /dev/null @@ -1,4400 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (c) 2011 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * 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 "colormac.h" -#include "format_unpack.h" -#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 */ -struct z32f_x24s8 -{ - float z; - uint32_t x24s8; -}; - - -/* Expand 1, 2, 3, 4, 5, 6-bit values to fill 8 bits */ - -#define EXPAND_1_8(X) ( (X) ? 0xff : 0x0 ) - -#define EXPAND_2_8(X) ( ((X) << 6) | ((X) << 4) | ((X) << 2) | (X) ) - -#define EXPAND_3_8(X) ( ((X) << 5) | ((X) << 2) | ((X) >> 1) ) - -#define EXPAND_4_8(X) ( ((X) << 4) | (X) ) - -#define EXPAND_5_8(X) ( ((X) << 3) | ((X) >> 2) ) - -#define EXPAND_6_8(X) ( ((X) << 2) | ((X) >> 4) ) - - -/**********************************************************************/ -/* Unpack, returning GLfloat colors */ -/**********************************************************************/ - -typedef void (*unpack_rgba_func)(const void *src, GLfloat dst[][4], GLuint n); - - -static void -unpack_A8B8G8R8_UNORM(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] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - } -} - -static void -unpack_R8G8B8A8_UNORM(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] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - } -} - -static void -unpack_B8G8R8A8_UNORM(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] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - } -} - -static void -unpack_A8R8G8B8_UNORM(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] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - } -} - -static void -unpack_RGBX8888(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] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_RGBX8888_REV(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] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_B8G8R8X8_UNORM(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] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] ) & 0xff ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_X8R8G8B8_UNORM(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] = UBYTE_TO_FLOAT( (s[i] >> 8) & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( (s[i] >> 16) & 0xff ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( (s[i] >> 24) ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_BGR_UNORM8(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] = UBYTE_TO_FLOAT( s[i*3+2] ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i*3+1] ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i*3+0] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGB_UNORM8(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] = UBYTE_TO_FLOAT( s[i*3+0] ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i*3+1] ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i*3+2] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_B5G6R5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 11) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 5 ) & 0x3f) * (1.0F / 63.0F); - dst[i][BCOMP] = ((s[i] ) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R5G6B5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_R5G6B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLuint t = (s[i] >> 8) | (s[i] << 8); /* byte swap */ - dst[i][RCOMP] = UBYTE_TO_FLOAT( ((t >> 8) & 0xf8) | ((t >> 13) & 0x7) ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( ((t >> 3) & 0xfc) | ((t >> 9) & 0x3) ); - dst[i][BCOMP] = UBYTE_TO_FLOAT( ((t << 3) & 0xf8) | ((t >> 2) & 0x7) ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_B4G4R4A4_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] >> 12) & 0xf) * (1.0F / 15.0F); - } -} - -static void -unpack_A4R4G4B4_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] >> 12) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - } -} - -static void -unpack_A1B5G5R5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 11) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 6) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((s[i] >> 1) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = ((s[i] ) & 0x01) * 1.0F; - } -} - -static void -unpack_B5G5R5A1_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 10) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 5) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = ((s[i] >> 15) & 0x01) * 1.0F; - } -} - -static void -unpack_A1R5G5B5_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_A1R5G5B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLushort tmp = (s[i] << 8) | (s[i] >> 8); /* byteswap */ - dst[i][RCOMP] = ((tmp >> 10) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((tmp >> 5) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((tmp >> 0) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = ((tmp >> 15) & 0x01) * 1.0F; - } -} - -static void -unpack_L4A4_UNORM(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = (s[i] & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - } -} - -static void -unpack_L8A8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - } -} - -static void -unpack_A8L8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - } -} - -static void -unpack_L16A16_UNORM(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - dst[i][ACOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - } -} - -static void -unpack_A16L16_UNORM(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - dst[i][ACOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - } -} - -static void -unpack_B2G3R3_UNORM(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] = ((s[i] >> 5) & 0x7) * (1.0F / 7.0F); - dst[i][GCOMP] = ((s[i] >> 2) & 0x7) * (1.0F / 7.0F); - dst[i][BCOMP] = ((s[i] ) & 0x3) * (1.0F / 3.0F); - dst[i][ACOMP] = 1.0F; - } -} - - -static void -unpack_A_UNORM8(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i]); - } -} - -static void -unpack_A_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = USHORT_TO_FLOAT(s[i]); - } -} - -static void -unpack_L_UNORM8(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = UBYTE_TO_FLOAT(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = USHORT_TO_FLOAT(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_I_UNORM8(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i]); - } -} - -static void -unpack_I_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = USHORT_TO_FLOAT(s[i]); - } -} - -static void -unpack_YCBCR(const void *src, GLfloat dst[][4], GLuint n) -{ - GLuint i; - for (i = 0; i < n; i++) { - const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ - const GLushort *src1 = src0 + 1; /* odd */ - const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ - const GLubyte cb = *src0 & 0xff; /* chroma U */ - const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */ - const GLubyte cr = *src1 & 0xff; /* chroma V */ - const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ - GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); - GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); - GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); - r *= (1.0F / 255.0F); - g *= (1.0F / 255.0F); - b *= (1.0F / 255.0F); - dst[i][RCOMP] = CLAMP(r, 0.0F, 1.0F); - dst[i][GCOMP] = CLAMP(g, 0.0F, 1.0F); - dst[i][BCOMP] = CLAMP(b, 0.0F, 1.0F); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_YCBCR_REV(const void *src, GLfloat dst[][4], GLuint n) -{ - GLuint i; - for (i = 0; i < n; i++) { - const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ - const GLushort *src1 = src0 + 1; /* odd */ - const GLubyte y0 = *src0 & 0xff; /* luminance */ - const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ - const GLubyte y1 = *src1 & 0xff; /* luminance */ - const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */ - const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ - GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); - GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); - GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); - r *= (1.0F / 255.0F); - g *= (1.0F / 255.0F); - b *= (1.0F / 255.0F); - dst[i][RCOMP] = CLAMP(r, 0.0F, 1.0F); - dst[i][GCOMP] = CLAMP(g, 0.0F, 1.0F); - dst[i][BCOMP] = CLAMP(b, 0.0F, 1.0F); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R_UNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = UBYTE_TO_FLOAT(s[i]); - dst[i][1] = - dst[i][2] = 0.0F; - dst[i][3] = 1.0F; - } -} - -static void -unpack_R8G8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_G8R8_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = UBYTE_TO_FLOAT( s[i] >> 8 ); - dst[i][GCOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT(s[i]); - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R16G16_UNORM(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] = USHORT_TO_FLOAT( s[i] & 0xffff ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i] >> 16 ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_G16R16_UNORM(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] = USHORT_TO_FLOAT( s[i] >> 16 ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i] & 0xffff ); - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_B10G10R10A2_UNORM(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] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); - dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); - dst[i][ACOMP] = ((s[i] >> 30) & 0x03) * (1.0F / 3.0F); - } -} - - -static void -unpack_B10G10R10A2_UINT(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] = (GLfloat)((s[i] >> 20) & 0x3ff); - dst[i][GCOMP] = (GLfloat)((s[i] >> 10) & 0x3ff); - dst[i][BCOMP] = (GLfloat)((s[i] >> 0) & 0x3ff); - dst[i][ACOMP] = (GLfloat)((s[i] >> 30) & 0x03); - } -} - - -static void -unpack_R10G10B10A2_UINT(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] = (GLfloat)((s[i] >> 0) & 0x3ff); - dst[i][GCOMP] = (GLfloat)((s[i] >> 10) & 0x3ff); - dst[i][BCOMP] = (GLfloat)((s[i] >> 20) & 0x3ff); - dst[i][ACOMP] = (GLfloat)((s[i] >> 30) & 0x03); - } -} - - -static void -unpack_S8_UINT_Z24_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = (GLfloat) ((s[i] >> 8) * scale); - dst[i][3] = 1.0F; - ASSERT(dst[i][0] >= 0.0F); - ASSERT(dst[i][0] <= 1.0F); - } -} - -static void -unpack_Z24_UNORM_S8_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = (float) ((s[i] & 0x00ffffff) * scale); - dst[i][3] = 1.0F; - ASSERT(dst[i][0] >= 0.0F); - ASSERT(dst[i][0] <= 1.0F); - } -} - -static void -unpack_Z_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i] * (1.0F / 65535.0F); - dst[i][3] = 1.0F; - } -} - -static void -unpack_Z24_UNORM_X8_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - unpack_Z24_UNORM_S8_UINT(src, dst, n); -} - -static void -unpack_X8_UINT_Z24_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - unpack_S8_UINT_Z24_UNORM(src, dst, n); -} - -static void -unpack_Z_UNORM32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i] * (1.0F / 0xffffffff); - dst[i][3] = 1.0F; - } -} - -static void -unpack_Z32_FLOAT_S8X24_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i].z; - dst[i][3] = 1.0F; - } -} - -static void -unpack_Z_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = ((const GLfloat *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = s[i]; - dst[i][3] = 1.0F; - } -} - - -static void -unpack_S8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* should never be used */ - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = - dst[i][1] = - dst[i][2] = 0.0F; - dst[i][3] = 1.0F; - } -} - - -static void -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] = 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; - } -} - -static void -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] = 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! */ - } -} - -static void -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] = 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! */ - } -} - -static void -unpack_A8R8G8B8_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] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - 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] >> 24) ); - dst[i][ACOMP] = UBYTE_TO_FLOAT( s[i] & 0xff ); /* linear! */ - } -} - -static void -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] = 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! */ - } -} - -static void -unpack_L_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] = - dst[i][GCOMP] = - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L8A8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i] & 0xff); - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] >> 8); /* linear! */ - } -} - -static void -unpack_A8L8_SRGB(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = util_format_srgb_8unorm_to_linear_float(s[i] >> 8); - dst[i][ACOMP] = UBYTE_TO_FLOAT(s[i] & 0xff); /* linear! */ - } -} - -static void -unpack_SRGB_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_SRGBA_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_SRGBA_DXT3(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_SRGBA_DXT5(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGB_FXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_FXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGB_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_DXT1(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_DXT3(const void *src, GLfloat dst[][4], GLuint n) -{ -} - -static void -unpack_RGBA_DXT5(const void *src, GLfloat dst[][4], GLuint n) -{ -} - - -static void -unpack_RGBA_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = s[i*4+3]; - } -} - -static void -unpack_RGBA_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*4+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*4+1]); - dst[i][BCOMP] = _mesa_half_to_float(s[i*4+2]); - dst[i][ACOMP] = _mesa_half_to_float(s[i*4+3]); - } -} - -static void -unpack_RGB_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*3+0]; - dst[i][GCOMP] = s[i*3+1]; - dst[i][BCOMP] = s[i*3+2]; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGB_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*3+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*3+1]); - dst[i][BCOMP] = _mesa_half_to_float(s[i*3+2]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_A_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_A_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = _mesa_half_to_float(s[i]); - } -} - -static void -unpack_L_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = s[i]; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = _mesa_half_to_float(s[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_LA_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = s[i*2+0]; - dst[i][ACOMP] = s[i*2+1]; - } -} - -static void -unpack_LA_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = _mesa_half_to_float(s[i*2+0]); - dst[i][ACOMP] = _mesa_half_to_float(s[i*2+1]); - } -} - -static void -unpack_I_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_I_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = _mesa_half_to_float(s[i]); - } -} - -static void -unpack_R_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i]; - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i]); - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RG_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*2+0]; - dst[i][GCOMP] = s[i*2+1]; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RG_FLOAT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLhalfARB *s = (const GLhalfARB *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*2+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*2+1]); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_ALPHA_UINT8(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_UINT32(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_ALPHA_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_UINT8(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_UINT32(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_INTENSITY_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = (GLfloat) s[i]; - } -} - -static void -unpack_LUMINANCE_UINT8(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] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_UINT32(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] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = dst[i][GCOMP] = dst[i][BCOMP] = (GLfloat) s[i]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_LUMINANCE_ALPHA_UINT8(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_UINT32(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] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_LUMINANCE_ALPHA_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = (GLfloat) s[2*i+0]; - dst[i][ACOMP] = (GLfloat) s[2*i+1]; - } -} - -static void -unpack_R_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_INT8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_INT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - - -static void -unpack_RGBA_INT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_UINT8(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] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_UINT8(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] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_UINT8(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] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_UINT8(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] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_UINT16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_UINT32(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] = (GLfloat) s[i]; - dst[i][GCOMP] = 0.0; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RG_UINT32(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] = (GLfloat) s[i*2+0]; - dst[i][GCOMP] = (GLfloat) s[i*2+1]; - dst[i][BCOMP] = 0.0; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGB_UINT32(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] = (GLfloat) s[i*3+0]; - dst[i][GCOMP] = (GLfloat) s[i*3+1]; - dst[i][BCOMP] = (GLfloat) s[i*3+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBA_UINT32(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] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = (GLfloat) s[i*4+3]; - } -} - -static void -unpack_R_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R8G8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_X8B8G8R8_SNORM(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] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 24) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][ACOMP] = 1.0f; - } -} - -static void -unpack_A8B8G8R8_SNORM(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] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 24) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] ) ); - } -} - -static void -unpack_R8G8B8A8_SNORM(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] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] ) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 24) ); - } -} - -static void -unpack_R_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R16G16_SNORM(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] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] & 0xffff) ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] >> 16) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGB_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i*3+0] ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( s[i*3+1] ); - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*3+2] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_RGBA_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+0] ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+1] ); - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+2] ); - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i*4+3] ); - } -} - -static void -unpack_RGBA_16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT( s[i*4+0] ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i*4+1] ); - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i*4+2] ); - dst[i][ACOMP] = USHORT_TO_FLOAT( s[i*4+3] ); - } -} - -static void -unpack_RED_RGTC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_RED_RGTC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_RG_RGTC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_RG_RGTC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_L_LATC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_L_LATC1(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_LA_LATC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_SIGNED_LA_LATC2(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC1_RGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SRGB8(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RGBA8_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SRGB8_ALPHA8_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_R11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RG11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SIGNED_R11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SIGNED_RG11_EAC(const void *src, GLfloat dst[][4], GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_RGB8_PUNCHTHROUGH_ALPHA1(const void *src, GLfloat dst[][4], - GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1(const void *src, GLfloat dst[][4], - GLuint n) -{ - /* XXX to do */ -} - -static void -unpack_A_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = 0.0F; - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_L_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_L8A8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - } -} - - -static void -unpack_A8L8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - } -} - -static void -unpack_I_SNORM8(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = ((const GLbyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = BYTE_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_A_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = 0.0F; - dst[i][GCOMP] = 0.0F; - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_L_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_LA_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*2+0] ); - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i*2+1] ); - } -} - -static void -unpack_I_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = ((const GLshort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = SHORT_TO_FLOAT_TEX( s[i] ); - } -} - -static void -unpack_R9G9B9E5_FLOAT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - rgb9e5_to_float3(s[i], dst[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_R11G11B10_FLOAT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLuint *s = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i++) { - r11g11b10f_to_float3(s[i], dst[i]); - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_XRGB4444_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 8) & 0xf) * (1.0F / 15.0F); - dst[i][GCOMP] = ((s[i] >> 4) & 0xf) * (1.0F / 15.0F); - dst[i][BCOMP] = ((s[i] ) & 0xf) * (1.0F / 15.0F); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XRGB1555_UNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = ((s[i] >> 10) & 0x1f) * (1.0F / 31.0F); - dst[i][GCOMP] = ((s[i] >> 5) & 0x1f) * (1.0F / 31.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x1f) * (1.0F / 31.0F); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R8G8B8X8_SNORM(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] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] ) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][BCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 16) ); - dst[i][ACOMP] = 1.0; - } -} - -static void -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] = 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] = 1.0f; - } -} - -static void -unpack_X8B8G8R8_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] = 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] = 1.0f; - } -} - -static void -unpack_XBGR8888_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR8888_SINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLbyte *s = (const GLbyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_B10G10R10X2_UNORM(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] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); - dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); - dst[i][BCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBX_UNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = USHORT_TO_FLOAT( s[i*4+0] ); - dst[i][GCOMP] = USHORT_TO_FLOAT( s[i*4+1] ); - dst[i][BCOMP] = USHORT_TO_FLOAT( s[i*4+2] ); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBX_SNORM16(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+0] ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+1] ); - dst[i][BCOMP] = SHORT_TO_FLOAT_TEX( s[i*4+2] ); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR16161616_FLOAT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = _mesa_half_to_float(s[i*4+0]); - dst[i][GCOMP] = _mesa_half_to_float(s[i*4+1]); - dst[i][BCOMP] = _mesa_half_to_float(s[i*4+2]); - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR16161616_UINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR16161616_SINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLshort *s = (const GLshort *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_RGBX_FLOAT32(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLfloat *s = (const GLfloat *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*4+0]; - dst[i][GCOMP] = s[i*4+1]; - dst[i][BCOMP] = s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR32323232_UINT(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] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_XBGR32323232_SINT(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLint *s = (const GLint *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLfloat) s[i*4+0]; - dst[i][GCOMP] = (GLfloat) s[i*4+1]; - dst[i][BCOMP] = (GLfloat) s[i*4+2]; - dst[i][ACOMP] = 1.0; - } -} - -static void -unpack_R10G10B10A2_UNORM(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] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F); - dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F); - dst[i][BCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F); - dst[i][ACOMP] = ((s[i] >> 30) & 0x03) * (1.0F / 3.0F); - } -} - -static void -unpack_G8R8_SNORM(const void *src, GLfloat dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) ); - dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -unpack_G16R16_SNORM(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] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] >> 16) ); - dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] & 0xffff) ); - dst[i][BCOMP] = 0.0F; - dst[i][ACOMP] = 1.0F; - } -} - -static void -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] = 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; - } -} - -static void -unpack_X8R8G8B8_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] = util_format_srgb_8unorm_to_linear_float( (s[i] >> 8) & 0xff ); - 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] >> 24) ); - dst[i][ACOMP] = 1.0F; - } -} - -/** - * Return the unpacker function for the given format. - */ -static unpack_rgba_func -get_unpack_rgba_function(mesa_format format) -{ - static unpack_rgba_func table[MESA_FORMAT_COUNT]; - static GLboolean initialized = GL_FALSE; - - if (!initialized) { - table[MESA_FORMAT_NONE] = NULL; - - table[MESA_FORMAT_A8B8G8R8_UNORM] = unpack_A8B8G8R8_UNORM; - table[MESA_FORMAT_R8G8B8A8_UNORM] = unpack_R8G8B8A8_UNORM; - table[MESA_FORMAT_B8G8R8A8_UNORM] = unpack_B8G8R8A8_UNORM; - table[MESA_FORMAT_A8R8G8B8_UNORM] = unpack_A8R8G8B8_UNORM; - table[MESA_FORMAT_X8B8G8R8_UNORM] = unpack_RGBX8888; - table[MESA_FORMAT_R8G8B8X8_UNORM] = unpack_RGBX8888_REV; - table[MESA_FORMAT_B8G8R8X8_UNORM] = unpack_B8G8R8X8_UNORM; - table[MESA_FORMAT_X8R8G8B8_UNORM] = unpack_X8R8G8B8_UNORM; - table[MESA_FORMAT_BGR_UNORM8] = unpack_BGR_UNORM8; - table[MESA_FORMAT_RGB_UNORM8] = unpack_RGB_UNORM8; - table[MESA_FORMAT_B5G6R5_UNORM] = unpack_B5G6R5_UNORM; - table[MESA_FORMAT_R5G6B5_UNORM] = unpack_R5G6B5_UNORM; - table[MESA_FORMAT_B4G4R4A4_UNORM] = unpack_B4G4R4A4_UNORM; - table[MESA_FORMAT_A4R4G4B4_UNORM] = unpack_A4R4G4B4_UNORM; - table[MESA_FORMAT_A1B5G5R5_UNORM] = unpack_A1B5G5R5_UNORM; - table[MESA_FORMAT_B5G5R5A1_UNORM] = unpack_B5G5R5A1_UNORM; - table[MESA_FORMAT_A1R5G5B5_UNORM] = unpack_A1R5G5B5_UNORM; - table[MESA_FORMAT_L4A4_UNORM] = unpack_L4A4_UNORM; - table[MESA_FORMAT_L8A8_UNORM] = unpack_L8A8_UNORM; - table[MESA_FORMAT_A8L8_UNORM] = unpack_A8L8_UNORM; - table[MESA_FORMAT_L16A16_UNORM] = unpack_L16A16_UNORM; - table[MESA_FORMAT_A16L16_UNORM] = unpack_A16L16_UNORM; - table[MESA_FORMAT_B2G3R3_UNORM] = unpack_B2G3R3_UNORM; - table[MESA_FORMAT_A_UNORM8] = unpack_A_UNORM8; - table[MESA_FORMAT_A_UNORM16] = unpack_A_UNORM16; - table[MESA_FORMAT_L_UNORM8] = unpack_L_UNORM8; - table[MESA_FORMAT_L_UNORM16] = unpack_L_UNORM16; - table[MESA_FORMAT_I_UNORM8] = unpack_I_UNORM8; - table[MESA_FORMAT_I_UNORM16] = unpack_I_UNORM16; - table[MESA_FORMAT_YCBCR] = unpack_YCBCR; - table[MESA_FORMAT_YCBCR_REV] = unpack_YCBCR_REV; - table[MESA_FORMAT_R_UNORM8] = unpack_R_UNORM8; - table[MESA_FORMAT_R8G8_UNORM] = unpack_R8G8_UNORM; - table[MESA_FORMAT_G8R8_UNORM] = unpack_G8R8_UNORM; - table[MESA_FORMAT_R_UNORM16] = unpack_R_UNORM16; - table[MESA_FORMAT_R16G16_UNORM] = unpack_R16G16_UNORM; - table[MESA_FORMAT_G16R16_UNORM] = unpack_G16R16_UNORM; - table[MESA_FORMAT_B10G10R10A2_UNORM] = unpack_B10G10R10A2_UNORM; - table[MESA_FORMAT_B10G10R10A2_UINT] = unpack_B10G10R10A2_UINT; - table[MESA_FORMAT_R10G10B10A2_UINT] = unpack_R10G10B10A2_UINT; - table[MESA_FORMAT_S8_UINT_Z24_UNORM] = unpack_S8_UINT_Z24_UNORM; - table[MESA_FORMAT_Z24_UNORM_S8_UINT] = unpack_Z24_UNORM_S8_UINT; - table[MESA_FORMAT_Z_UNORM16] = unpack_Z_UNORM16; - table[MESA_FORMAT_Z24_UNORM_X8_UINT] = unpack_Z24_UNORM_X8_UINT; - table[MESA_FORMAT_X8_UINT_Z24_UNORM] = unpack_X8_UINT_Z24_UNORM; - table[MESA_FORMAT_Z_UNORM32] = unpack_Z_UNORM32; - table[MESA_FORMAT_S_UINT8] = unpack_S8; - table[MESA_FORMAT_BGR_SRGB8] = unpack_BGR_SRGB8; - table[MESA_FORMAT_A8B8G8R8_SRGB] = unpack_A8B8G8R8_SRGB; - table[MESA_FORMAT_B8G8R8A8_SRGB] = unpack_B8G8R8A8_SRGB; - table[MESA_FORMAT_A8R8G8B8_SRGB] = unpack_A8R8G8B8_SRGB; - table[MESA_FORMAT_R8G8B8A8_SRGB] = unpack_R8G8B8A8_SRGB; - table[MESA_FORMAT_L_SRGB8] = unpack_L_SRGB8; - table[MESA_FORMAT_L8A8_SRGB] = unpack_L8A8_SRGB; - table[MESA_FORMAT_A8L8_SRGB] = unpack_A8L8_SRGB; - table[MESA_FORMAT_SRGB_DXT1] = unpack_SRGB_DXT1; - table[MESA_FORMAT_SRGBA_DXT1] = unpack_SRGBA_DXT1; - table[MESA_FORMAT_SRGBA_DXT3] = unpack_SRGBA_DXT3; - table[MESA_FORMAT_SRGBA_DXT5] = unpack_SRGBA_DXT5; - - table[MESA_FORMAT_RGB_FXT1] = unpack_RGB_FXT1; - table[MESA_FORMAT_RGBA_FXT1] = unpack_RGBA_FXT1; - table[MESA_FORMAT_RGB_DXT1] = unpack_RGB_DXT1; - table[MESA_FORMAT_RGBA_DXT1] = unpack_RGBA_DXT1; - table[MESA_FORMAT_RGBA_DXT3] = unpack_RGBA_DXT3; - table[MESA_FORMAT_RGBA_DXT5] = unpack_RGBA_DXT5; - - table[MESA_FORMAT_RGBA_FLOAT32] = unpack_RGBA_FLOAT32; - table[MESA_FORMAT_RGBA_FLOAT16] = unpack_RGBA_FLOAT16; - table[MESA_FORMAT_RGB_FLOAT32] = unpack_RGB_FLOAT32; - table[MESA_FORMAT_RGB_FLOAT16] = unpack_RGB_FLOAT16; - table[MESA_FORMAT_A_FLOAT32] = unpack_A_FLOAT32; - table[MESA_FORMAT_A_FLOAT16] = unpack_A_FLOAT16; - table[MESA_FORMAT_L_FLOAT32] = unpack_L_FLOAT32; - table[MESA_FORMAT_L_FLOAT16] = unpack_L_FLOAT16; - table[MESA_FORMAT_LA_FLOAT32] = unpack_LA_FLOAT32; - table[MESA_FORMAT_LA_FLOAT16] = unpack_LA_FLOAT16; - table[MESA_FORMAT_I_FLOAT32] = unpack_I_FLOAT32; - table[MESA_FORMAT_I_FLOAT16] = unpack_I_FLOAT16; - table[MESA_FORMAT_R_FLOAT32] = unpack_R_FLOAT32; - table[MESA_FORMAT_R_FLOAT16] = unpack_R_FLOAT16; - table[MESA_FORMAT_RG_FLOAT32] = unpack_RG_FLOAT32; - table[MESA_FORMAT_RG_FLOAT16] = unpack_RG_FLOAT16; - - table[MESA_FORMAT_A_UINT8] = unpack_ALPHA_UINT8; - table[MESA_FORMAT_A_UINT16] = unpack_ALPHA_UINT16; - table[MESA_FORMAT_A_UINT32] = unpack_ALPHA_UINT32; - table[MESA_FORMAT_A_SINT8] = unpack_ALPHA_INT8; - table[MESA_FORMAT_A_SINT16] = unpack_ALPHA_INT16; - table[MESA_FORMAT_A_SINT32] = unpack_ALPHA_INT32; - - table[MESA_FORMAT_I_UINT8] = unpack_INTENSITY_UINT8; - table[MESA_FORMAT_I_UINT16] = unpack_INTENSITY_UINT16; - table[MESA_FORMAT_I_UINT32] = unpack_INTENSITY_UINT32; - table[MESA_FORMAT_I_SINT8] = unpack_INTENSITY_INT8; - table[MESA_FORMAT_I_SINT16] = unpack_INTENSITY_INT16; - table[MESA_FORMAT_I_SINT32] = unpack_INTENSITY_INT32; - - table[MESA_FORMAT_L_UINT8] = unpack_LUMINANCE_UINT8; - table[MESA_FORMAT_L_UINT16] = unpack_LUMINANCE_UINT16; - table[MESA_FORMAT_L_UINT32] = unpack_LUMINANCE_UINT32; - table[MESA_FORMAT_L_SINT8] = unpack_LUMINANCE_INT8; - table[MESA_FORMAT_L_SINT16] = unpack_LUMINANCE_INT16; - table[MESA_FORMAT_L_SINT32] = unpack_LUMINANCE_INT32; - - table[MESA_FORMAT_LA_UINT8] = unpack_LUMINANCE_ALPHA_UINT8; - table[MESA_FORMAT_LA_UINT16] = unpack_LUMINANCE_ALPHA_UINT16; - table[MESA_FORMAT_LA_UINT32] = unpack_LUMINANCE_ALPHA_UINT32; - table[MESA_FORMAT_LA_SINT8] = unpack_LUMINANCE_ALPHA_INT8; - table[MESA_FORMAT_LA_SINT16] = unpack_LUMINANCE_ALPHA_INT16; - table[MESA_FORMAT_LA_SINT32] = unpack_LUMINANCE_ALPHA_INT32; - - table[MESA_FORMAT_R_SINT8] = unpack_R_INT8; - table[MESA_FORMAT_RG_SINT8] = unpack_RG_INT8; - table[MESA_FORMAT_RGB_SINT8] = unpack_RGB_INT8; - table[MESA_FORMAT_RGBA_SINT8] = unpack_RGBA_INT8; - table[MESA_FORMAT_R_SINT16] = unpack_R_INT16; - table[MESA_FORMAT_RG_SINT16] = unpack_RG_INT16; - table[MESA_FORMAT_RGB_SINT16] = unpack_RGB_INT16; - table[MESA_FORMAT_RGBA_SINT16] = unpack_RGBA_INT16; - table[MESA_FORMAT_R_SINT32] = unpack_R_INT32; - table[MESA_FORMAT_RG_SINT32] = unpack_RG_INT32; - table[MESA_FORMAT_RGB_SINT32] = unpack_RGB_INT32; - table[MESA_FORMAT_RGBA_SINT32] = unpack_RGBA_INT32; - table[MESA_FORMAT_R_UINT8] = unpack_R_UINT8; - table[MESA_FORMAT_RG_UINT8] = unpack_RG_UINT8; - table[MESA_FORMAT_RGB_UINT8] = unpack_RGB_UINT8; - table[MESA_FORMAT_RGBA_UINT8] = unpack_RGBA_UINT8; - table[MESA_FORMAT_R_UINT16] = unpack_R_UINT16; - table[MESA_FORMAT_RG_UINT16] = unpack_RG_UINT16; - table[MESA_FORMAT_RGB_UINT16] = unpack_RGB_UINT16; - table[MESA_FORMAT_RGBA_UINT16] = unpack_RGBA_UINT16; - table[MESA_FORMAT_R_UINT32] = unpack_R_UINT32; - table[MESA_FORMAT_RG_UINT32] = unpack_RG_UINT32; - table[MESA_FORMAT_RGB_UINT32] = unpack_RGB_UINT32; - table[MESA_FORMAT_RGBA_UINT32] = unpack_RGBA_UINT32; - - table[MESA_FORMAT_R_SNORM8] = unpack_R_SNORM8; - table[MESA_FORMAT_R8G8_SNORM] = unpack_R8G8_SNORM; - table[MESA_FORMAT_X8B8G8R8_SNORM] = unpack_X8B8G8R8_SNORM; - table[MESA_FORMAT_A8B8G8R8_SNORM] = unpack_A8B8G8R8_SNORM; - table[MESA_FORMAT_R8G8B8A8_SNORM] = unpack_R8G8B8A8_SNORM; - table[MESA_FORMAT_R_SNORM16] = unpack_R_SNORM16; - table[MESA_FORMAT_R16G16_SNORM] = unpack_R16G16_SNORM; - table[MESA_FORMAT_RGB_SNORM16] = unpack_RGB_SNORM16; - table[MESA_FORMAT_RGBA_SNORM16] = unpack_RGBA_SNORM16; - table[MESA_FORMAT_RGBA_UNORM16] = unpack_RGBA_16; - - table[MESA_FORMAT_R_RGTC1_UNORM] = unpack_RED_RGTC1; - table[MESA_FORMAT_R_RGTC1_SNORM] = unpack_SIGNED_RED_RGTC1; - table[MESA_FORMAT_RG_RGTC2_UNORM] = unpack_RG_RGTC2; - table[MESA_FORMAT_RG_RGTC2_SNORM] = unpack_SIGNED_RG_RGTC2; - - table[MESA_FORMAT_L_LATC1_UNORM] = unpack_L_LATC1; - table[MESA_FORMAT_L_LATC1_SNORM] = unpack_SIGNED_L_LATC1; - table[MESA_FORMAT_LA_LATC2_UNORM] = unpack_LA_LATC2; - table[MESA_FORMAT_LA_LATC2_SNORM] = unpack_SIGNED_LA_LATC2; - - table[MESA_FORMAT_ETC1_RGB8] = unpack_ETC1_RGB8; - table[MESA_FORMAT_ETC2_RGB8] = unpack_ETC2_RGB8; - table[MESA_FORMAT_ETC2_SRGB8] = unpack_ETC2_SRGB8; - table[MESA_FORMAT_ETC2_RGBA8_EAC] = unpack_ETC2_RGBA8_EAC; - table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = unpack_ETC2_SRGB8_ALPHA8_EAC; - table[MESA_FORMAT_ETC2_R11_EAC] = unpack_ETC2_R11_EAC; - table[MESA_FORMAT_ETC2_RG11_EAC] = unpack_ETC2_RG11_EAC; - table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = unpack_ETC2_SIGNED_R11_EAC; - table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = unpack_ETC2_SIGNED_RG11_EAC; - table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] = - unpack_ETC2_RGB8_PUNCHTHROUGH_ALPHA1; - table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = - unpack_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1; - table[MESA_FORMAT_A_SNORM8] = unpack_A_SNORM8; - table[MESA_FORMAT_L_SNORM8] = unpack_L_SNORM8; - table[MESA_FORMAT_L8A8_SNORM] = unpack_L8A8_SNORM; - table[MESA_FORMAT_A8L8_SNORM] = unpack_A8L8_SNORM; - table[MESA_FORMAT_I_SNORM8] = unpack_I_SNORM8; - table[MESA_FORMAT_A_SNORM16] = unpack_A_SNORM16; - table[MESA_FORMAT_L_SNORM16] = unpack_L_SNORM16; - table[MESA_FORMAT_LA_SNORM16] = unpack_LA_SNORM16; - table[MESA_FORMAT_I_SNORM16] = unpack_I_SNORM16; - - table[MESA_FORMAT_R9G9B9E5_FLOAT] = unpack_R9G9B9E5_FLOAT; - table[MESA_FORMAT_R11G11B10_FLOAT] = unpack_R11G11B10_FLOAT; - - table[MESA_FORMAT_Z_FLOAT32] = unpack_Z_FLOAT32; - table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = unpack_Z32_FLOAT_S8X24_UINT; - - table[MESA_FORMAT_B4G4R4X4_UNORM] = unpack_XRGB4444_UNORM; - table[MESA_FORMAT_B5G5R5X1_UNORM] = unpack_XRGB1555_UNORM; - table[MESA_FORMAT_R8G8B8X8_SNORM] = unpack_R8G8B8X8_SNORM; - table[MESA_FORMAT_R8G8B8X8_SRGB] = unpack_R8G8B8X8_SRGB; - table[MESA_FORMAT_X8B8G8R8_SRGB] = unpack_X8B8G8R8_SRGB; - table[MESA_FORMAT_RGBX_UINT8] = unpack_XBGR8888_UINT; - table[MESA_FORMAT_RGBX_SINT8] = unpack_XBGR8888_SINT; - table[MESA_FORMAT_B10G10R10X2_UNORM] = unpack_B10G10R10X2_UNORM; - table[MESA_FORMAT_RGBX_UNORM16] = unpack_RGBX_UNORM16; - table[MESA_FORMAT_RGBX_SNORM16] = unpack_RGBX_SNORM16; - table[MESA_FORMAT_RGBX_FLOAT16] = unpack_XBGR16161616_FLOAT; - table[MESA_FORMAT_RGBX_UINT16] = unpack_XBGR16161616_UINT; - table[MESA_FORMAT_RGBX_SINT16] = unpack_XBGR16161616_SINT; - table[MESA_FORMAT_RGBX_FLOAT32] = unpack_RGBX_FLOAT32; - table[MESA_FORMAT_RGBX_UINT32] = unpack_XBGR32323232_UINT; - table[MESA_FORMAT_RGBX_SINT32] = unpack_XBGR32323232_SINT; - - table[MESA_FORMAT_R10G10B10A2_UNORM] = unpack_R10G10B10A2_UNORM; - - table[MESA_FORMAT_G8R8_SNORM] = unpack_G8R8_SNORM; - table[MESA_FORMAT_G16R16_SNORM] = unpack_G16R16_SNORM; - - table[MESA_FORMAT_B8G8R8X8_SRGB] = unpack_B8G8R8X8_SRGB; - table[MESA_FORMAT_X8R8G8B8_SRGB] = unpack_X8R8G8B8_SRGB; - - initialized = GL_TRUE; - } - - if (table[format] == NULL) { - _mesa_problem(NULL, "unsupported unpack for format %s", - _mesa_get_format_name(format)); - } - - return table[format]; -} - - -/** - * Unpack rgba colors, returning as GLfloat values. - */ -void -_mesa_unpack_rgba_row(mesa_format format, GLuint n, - const void *src, GLfloat dst[][4]) -{ - unpack_rgba_func unpack = get_unpack_rgba_function(format); - unpack(src, dst, n); -} - - -/**********************************************************************/ -/* Unpack, returning GLubyte colors */ -/**********************************************************************/ - - -static void -unpack_ubyte_A8B8G8R8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 24); - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 8) & 0xff; - dst[i][ACOMP] = (s[i] ) & 0xff; - } -} - -static void -unpack_ubyte_R8G8B8A8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] ) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] >> 16) & 0xff; - dst[i][ACOMP] = (s[i] >> 24); - } -} - -static void -unpack_ubyte_B8G8R8A8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 16) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] ) & 0xff; - dst[i][ACOMP] = (s[i] >> 24); - } -} - -static void -unpack_ubyte_A8R8G8B8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 8) & 0xff; - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 24); - dst[i][ACOMP] = (s[i] ) & 0xff; - } -} - -static void -unpack_ubyte_RGBX8888(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 24); - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 8) & 0xff; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_RGBX8888_REV(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] ) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] >> 16) & 0xff; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_B8G8R8X8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 16) & 0xff; - dst[i][GCOMP] = (s[i] >> 8) & 0xff; - dst[i][BCOMP] = (s[i] ) & 0xff; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_X8R8G8B8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (s[i] >> 8) & 0xff; - dst[i][GCOMP] = (s[i] >> 16) & 0xff; - dst[i][BCOMP] = (s[i] >> 24); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_BGR_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*3+2]; - dst[i][GCOMP] = s[i*3+1]; - dst[i][BCOMP] = s[i*3+0]; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_RGB_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i*3+0]; - dst[i][GCOMP] = s[i*3+1]; - dst[i][BCOMP] = s[i*3+2]; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_B5G6R5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f); - dst[i][GCOMP] = EXPAND_6_8((s[i] >> 5 ) & 0x3f); - dst[i][BCOMP] = EXPAND_5_8( s[i] & 0x1f); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_R5G6B5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_R5G6B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLuint t = (s[i] >> 8) | (s[i] << 8); /* byte swap */ - dst[i][RCOMP] = EXPAND_5_8((t >> 11) & 0x1f); - dst[i][GCOMP] = EXPAND_6_8((t >> 5 ) & 0x3f); - dst[i][BCOMP] = EXPAND_5_8( t & 0x1f); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_B4G4R4A4_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); - dst[i][GCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); - dst[i][BCOMP] = EXPAND_4_8((s[i] ) & 0xf); - dst[i][ACOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); - } -} - -static void -unpack_ubyte_A4R4G4B4_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_4_8((s[i] >> 4) & 0xf); - dst[i][GCOMP] = EXPAND_4_8((s[i] >> 8) & 0xf); - dst[i][BCOMP] = EXPAND_4_8((s[i] >> 12) & 0xf); - dst[i][ACOMP] = EXPAND_4_8((s[i] ) & 0xf); - } -} - -static void -unpack_ubyte_A1B5G5R5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_5_8((s[i] >> 11) & 0x1f); - dst[i][GCOMP] = EXPAND_5_8((s[i] >> 6) & 0x1f); - dst[i][BCOMP] = EXPAND_5_8((s[i] >> 1) & 0x1f); - dst[i][ACOMP] = EXPAND_1_8((s[i] ) & 0x01); - } -} - -static void -unpack_ubyte_B5G5R5A1_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_5_8((s[i] >> 10) & 0x1f); - dst[i][GCOMP] = EXPAND_5_8((s[i] >> 5) & 0x1f); - dst[i][BCOMP] = EXPAND_5_8((s[i] >> 0) & 0x1f); - dst[i][ACOMP] = EXPAND_1_8((s[i] >> 15) & 0x01); - } -} - -static void -unpack_ubyte_A1R5G5B5_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - /* Warning: this function does not match the current Mesa definition - * of MESA_FORMAT_A1R5G5B5_UNORM. - */ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - GLushort tmp = (s[i] << 8) | (s[i] >> 8); /* byteswap */ - dst[i][RCOMP] = EXPAND_5_8((tmp >> 10) & 0x1f); - dst[i][GCOMP] = EXPAND_5_8((tmp >> 5) & 0x1f); - dst[i][BCOMP] = EXPAND_5_8((tmp >> 0) & 0x1f); - dst[i][ACOMP] = EXPAND_1_8((tmp >> 15) & 0x01); - } -} - -static void -unpack_ubyte_L4A4_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xf); - dst[i][ACOMP] = EXPAND_4_8(s[i] >> 4); - } -} - -static void -unpack_ubyte_L8A8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = EXPAND_4_8(s[i] & 0xff); - dst[i][ACOMP] = EXPAND_4_8(s[i] >> 8); - } -} - -static void -unpack_ubyte_A8L8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = EXPAND_4_8(s[i] >> 8); - dst[i][ACOMP] = EXPAND_4_8(s[i] & 0xff); - } -} - -static void -unpack_ubyte_B2G3R3_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = EXPAND_3_8((s[i] >> 5) & 0x7); - dst[i][GCOMP] = EXPAND_3_8((s[i] >> 2) & 0x7); - dst[i][BCOMP] = EXPAND_2_8((s[i] ) & 0x3); - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_A_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = 0; - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_ubyte_L_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = s[i]; - dst[i][ACOMP] = 0xff; - } -} - - -static void -unpack_ubyte_I_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = - dst[i][GCOMP] = - dst[i][BCOMP] = - dst[i][ACOMP] = s[i]; - } -} - -static void -unpack_ubyte_R_UNORM8(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLubyte *s = ((const GLubyte *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][0] = s[i]; - dst[i][1] = - dst[i][2] = 0; - dst[i][3] = 0xff; - } -} - -static void -unpack_ubyte_R8G8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i] & 0xff; - dst[i][GCOMP] = s[i] >> 8; - dst[i][BCOMP] = 0; - dst[i][ACOMP] = 0xff; - } -} - -static void -unpack_ubyte_G8R8_UNORM(const void *src, GLubyte dst[][4], GLuint n) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i][RCOMP] = s[i] >> 8; - dst[i][GCOMP] = s[i] & 0xff; - dst[i][BCOMP] = 0; - dst[i][ACOMP] = 0xff; - } -} - - -/** - * Unpack rgba colors, returning as GLubyte values. This should usually - * only be used for unpacking formats that use 8 bits or less per channel. - */ -void -_mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n, - const void *src, GLubyte dst[][4]) -{ - switch (format) { - case MESA_FORMAT_A8B8G8R8_UNORM: - unpack_ubyte_A8B8G8R8_UNORM(src, dst, n); - break; - case MESA_FORMAT_R8G8B8A8_UNORM: - unpack_ubyte_R8G8B8A8_UNORM(src, dst, n); - break; - case MESA_FORMAT_B8G8R8A8_UNORM: - unpack_ubyte_B8G8R8A8_UNORM(src, dst, n); - break; - case MESA_FORMAT_A8R8G8B8_UNORM: - unpack_ubyte_A8R8G8B8_UNORM(src, dst, n); - break; - case MESA_FORMAT_X8B8G8R8_UNORM: - unpack_ubyte_RGBX8888(src, dst, n); - break; - case MESA_FORMAT_R8G8B8X8_UNORM: - unpack_ubyte_RGBX8888_REV(src, dst, n); - break; - case MESA_FORMAT_B8G8R8X8_UNORM: - unpack_ubyte_B8G8R8X8_UNORM(src, dst, n); - break; - case MESA_FORMAT_X8R8G8B8_UNORM: - unpack_ubyte_X8R8G8B8_UNORM(src, dst, n); - break; - case MESA_FORMAT_BGR_UNORM8: - unpack_ubyte_BGR_UNORM8(src, dst, n); - break; - case MESA_FORMAT_RGB_UNORM8: - unpack_ubyte_RGB_UNORM8(src, dst, n); - break; - case MESA_FORMAT_B5G6R5_UNORM: - unpack_ubyte_B5G6R5_UNORM(src, dst, n); - break; - case MESA_FORMAT_R5G6B5_UNORM: - unpack_ubyte_R5G6B5_UNORM(src, dst, n); - break; - case MESA_FORMAT_B4G4R4A4_UNORM: - unpack_ubyte_B4G4R4A4_UNORM(src, dst, n); - break; - case MESA_FORMAT_A4R4G4B4_UNORM: - unpack_ubyte_A4R4G4B4_UNORM(src, dst, n); - break; - case MESA_FORMAT_A1B5G5R5_UNORM: - unpack_ubyte_A1B5G5R5_UNORM(src, dst, n); - break; - case MESA_FORMAT_B5G5R5A1_UNORM: - unpack_ubyte_B5G5R5A1_UNORM(src, dst, n); - break; - case MESA_FORMAT_A1R5G5B5_UNORM: - unpack_ubyte_A1R5G5B5_UNORM(src, dst, n); - break; - case MESA_FORMAT_L4A4_UNORM: - unpack_ubyte_L4A4_UNORM(src, dst, n); - break; - case MESA_FORMAT_L8A8_UNORM: - unpack_ubyte_L8A8_UNORM(src, dst, n); - break; - case MESA_FORMAT_A8L8_UNORM: - unpack_ubyte_A8L8_UNORM(src, dst, n); - break; - case MESA_FORMAT_B2G3R3_UNORM: - unpack_ubyte_B2G3R3_UNORM(src, dst, n); - break; - case MESA_FORMAT_A_UNORM8: - unpack_ubyte_A_UNORM8(src, dst, n); - break; - case MESA_FORMAT_L_UNORM8: - unpack_ubyte_L_UNORM8(src, dst, n); - break; - case MESA_FORMAT_I_UNORM8: - unpack_ubyte_I_UNORM8(src, dst, n); - break; - case MESA_FORMAT_R_UNORM8: - unpack_ubyte_R_UNORM8(src, dst, n); - break; - case MESA_FORMAT_R8G8_UNORM: - unpack_ubyte_R8G8_UNORM(src, dst, n); - break; - case MESA_FORMAT_G8R8_UNORM: - unpack_ubyte_G8R8_UNORM(src, dst, n); - break; - default: - /* get float values, convert to ubyte */ - { - GLfloat *tmp = malloc(n * 4 * sizeof(GLfloat)); - if (tmp) { - GLuint i; - _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp); - for (i = 0; i < n; i++) { - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][0], tmp[i*4+0]); - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][1], tmp[i*4+1]); - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][2], tmp[i*4+2]); - UNCLAMPED_FLOAT_TO_UBYTE(dst[i][3], tmp[i*4+3]); - } - free(tmp); - } - } - break; - } -} - - -/**********************************************************************/ -/* Unpack, returning GLuint colors */ -/**********************************************************************/ - -static void -unpack_int_rgba_RGBA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - memcpy(dst, src, n * 4 * sizeof(GLuint)); -} - -static void -unpack_int_rgba_RGBA_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_RGBA_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_RGBA_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_RGBA_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_B8G8R8A8_UNORM(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLubyte) src[i * 4 + 2]; - dst[i][GCOMP] = (GLubyte) src[i * 4 + 1]; - dst[i][BCOMP] = (GLubyte) src[i * 4 + 0]; - dst[i][ACOMP] = (GLubyte) src[i * 4 + 3]; - } -} - -static void -unpack_int_rgba_B8G8R8X8_UNORM(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][RCOMP] = (GLubyte) src[i * 4 + 2]; - dst[i][GCOMP] = (GLubyte) src[i * 4 + 1]; - dst[i][BCOMP] = (GLubyte) src[i * 4 + 0]; - dst[i][ACOMP] = (GLubyte) 0xff; - } -} - -static void -unpack_int_rgba_RGB_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RGB_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 3 + 0]; - dst[i][1] = src[i * 3 + 1]; - dst[i][2] = src[i * 3 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_RG_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 2 + 0]; - dst[i][1] = src[i * 2 + 1]; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i]; - dst[i][1] = 0; - dst[i][2] = 0; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_ALPHA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_ALPHA_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = 0; - dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_LUMINANCE_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_LUMINANCE_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i]; - dst[i][3] = 1; - } -} - - -static void -unpack_int_rgba_LUMINANCE_ALPHA_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_LUMINANCE_ALPHA_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = src[i * 2 + 0]; - dst[i][3] = src[i * 2 + 1]; - } -} - -static void -unpack_int_rgba_INTENSITY_UINT32(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_UINT16(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_INT16(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_UINT8(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_INTENSITY_INT8(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = dst[i][1] = dst[i][2] = dst[i][3] = src[i]; - } -} - -static void -unpack_int_rgba_B10G10R10A2_UINT(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 20) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 0) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -static void -unpack_int_rgba_R10G10B10A2_UINT(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 0) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 20) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -static void -unpack_int_rgba_B10G10R10A2_UNORM(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 20) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 0) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -static void -unpack_int_rgba_XBGR8888_UINT(const GLubyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR8888_SINT(const GLbyte *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR16161616_UINT(const GLushort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR16161616_SINT(const GLshort *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_XBGR32323232_UINT(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - dst[i][0] = src[i * 4 + 0]; - dst[i][1] = src[i * 4 + 1]; - dst[i][2] = src[i * 4 + 2]; - dst[i][3] = 1; - } -} - -static void -unpack_int_rgba_R10G10B10A2_UNORM(const GLuint *src, GLuint dst[][4], GLuint n) -{ - unsigned int i; - - for (i = 0; i < n; i++) { - GLuint tmp = src[i]; - dst[i][0] = (tmp >> 0) & 0x3ff; - dst[i][1] = (tmp >> 10) & 0x3ff; - dst[i][2] = (tmp >> 20) & 0x3ff; - dst[i][3] = (tmp >> 30) & 0x3; - } -} - -void -_mesa_unpack_uint_rgba_row(mesa_format format, GLuint n, - const void *src, GLuint dst[][4]) -{ - switch (format) { - /* Since there won't be any sign extension happening, there's no need to - * make separate paths for 32-bit-to-32-bit integer unpack. - */ - case MESA_FORMAT_RGBA_UINT32: - case MESA_FORMAT_RGBA_SINT32: - unpack_int_rgba_RGBA_UINT32(src, dst, n); - break; - - case MESA_FORMAT_RGBA_UINT16: - unpack_int_rgba_RGBA_UINT16(src, dst, n); - break; - case MESA_FORMAT_RGBA_SINT16: - unpack_int_rgba_RGBA_INT16(src, dst, n); - break; - - case MESA_FORMAT_RGBA_UINT8: - unpack_int_rgba_RGBA_UINT8(src, dst, n); - break; - case MESA_FORMAT_RGBA_SINT8: - unpack_int_rgba_RGBA_INT8(src, dst, n); - break; - - case MESA_FORMAT_B8G8R8A8_UNORM: - unpack_int_rgba_B8G8R8A8_UNORM(src, dst, n); - break; - - case MESA_FORMAT_B8G8R8X8_UNORM: - unpack_int_rgba_B8G8R8X8_UNORM(src, dst, n); - break; - - case MESA_FORMAT_RGB_UINT32: - case MESA_FORMAT_RGB_SINT32: - unpack_int_rgba_RGB_UINT32(src, dst, n); - break; - - case MESA_FORMAT_RGB_UINT16: - unpack_int_rgba_RGB_UINT16(src, dst, n); - break; - case MESA_FORMAT_RGB_SINT16: - unpack_int_rgba_RGB_INT16(src, dst, n); - break; - - case MESA_FORMAT_RGB_UINT8: - unpack_int_rgba_RGB_UINT8(src, dst, n); - break; - case MESA_FORMAT_RGB_SINT8: - unpack_int_rgba_RGB_INT8(src, dst, n); - break; - - case MESA_FORMAT_RG_UINT32: - case MESA_FORMAT_RG_SINT32: - unpack_int_rgba_RG_UINT32(src, dst, n); - break; - - case MESA_FORMAT_RG_UINT16: - unpack_int_rgba_RG_UINT16(src, dst, n); - break; - case MESA_FORMAT_RG_SINT16: - unpack_int_rgba_RG_INT16(src, dst, n); - break; - - case MESA_FORMAT_RG_UINT8: - unpack_int_rgba_RG_UINT8(src, dst, n); - break; - case MESA_FORMAT_RG_SINT8: - unpack_int_rgba_RG_INT8(src, dst, n); - break; - - case MESA_FORMAT_R_UINT32: - case MESA_FORMAT_R_SINT32: - unpack_int_rgba_R_UINT32(src, dst, n); - break; - - case MESA_FORMAT_R_UINT16: - unpack_int_rgba_R_UINT16(src, dst, n); - break; - case MESA_FORMAT_R_SINT16: - unpack_int_rgba_R_INT16(src, dst, n); - break; - - case MESA_FORMAT_R_UINT8: - unpack_int_rgba_R_UINT8(src, dst, n); - break; - case MESA_FORMAT_R_SINT8: - unpack_int_rgba_R_INT8(src, dst, n); - break; - - case MESA_FORMAT_A_UINT32: - case MESA_FORMAT_A_SINT32: - unpack_int_rgba_ALPHA_UINT32(src, dst, n); - break; - - case MESA_FORMAT_A_UINT16: - unpack_int_rgba_ALPHA_UINT16(src, dst, n); - break; - case MESA_FORMAT_A_SINT16: - unpack_int_rgba_ALPHA_INT16(src, dst, n); - break; - - case MESA_FORMAT_A_UINT8: - unpack_int_rgba_ALPHA_UINT8(src, dst, n); - break; - case MESA_FORMAT_A_SINT8: - unpack_int_rgba_ALPHA_INT8(src, dst, n); - break; - - case MESA_FORMAT_L_UINT32: - case MESA_FORMAT_L_SINT32: - unpack_int_rgba_LUMINANCE_UINT32(src, dst, n); - break; - case MESA_FORMAT_L_UINT16: - unpack_int_rgba_LUMINANCE_UINT16(src, dst, n); - break; - case MESA_FORMAT_L_SINT16: - unpack_int_rgba_LUMINANCE_INT16(src, dst, n); - break; - - case MESA_FORMAT_L_UINT8: - unpack_int_rgba_LUMINANCE_UINT8(src, dst, n); - break; - case MESA_FORMAT_L_SINT8: - unpack_int_rgba_LUMINANCE_INT8(src, dst, n); - break; - - case MESA_FORMAT_LA_UINT32: - case MESA_FORMAT_LA_SINT32: - unpack_int_rgba_LUMINANCE_ALPHA_UINT32(src, dst, n); - break; - - case MESA_FORMAT_LA_UINT16: - unpack_int_rgba_LUMINANCE_ALPHA_UINT16(src, dst, n); - break; - case MESA_FORMAT_LA_SINT16: - unpack_int_rgba_LUMINANCE_ALPHA_INT16(src, dst, n); - break; - - case MESA_FORMAT_LA_UINT8: - unpack_int_rgba_LUMINANCE_ALPHA_UINT8(src, dst, n); - break; - case MESA_FORMAT_LA_SINT8: - unpack_int_rgba_LUMINANCE_ALPHA_INT8(src, dst, n); - break; - - case MESA_FORMAT_I_UINT32: - case MESA_FORMAT_I_SINT32: - unpack_int_rgba_INTENSITY_UINT32(src, dst, n); - break; - - case MESA_FORMAT_I_UINT16: - unpack_int_rgba_INTENSITY_UINT16(src, dst, n); - break; - case MESA_FORMAT_I_SINT16: - unpack_int_rgba_INTENSITY_INT16(src, dst, n); - break; - - case MESA_FORMAT_I_UINT8: - unpack_int_rgba_INTENSITY_UINT8(src, dst, n); - break; - case MESA_FORMAT_I_SINT8: - unpack_int_rgba_INTENSITY_INT8(src, dst, n); - break; - - case MESA_FORMAT_B10G10R10A2_UINT: - unpack_int_rgba_B10G10R10A2_UINT(src, dst, n); - break; - - case MESA_FORMAT_R10G10B10A2_UINT: - unpack_int_rgba_R10G10B10A2_UINT(src, dst, n); - break; - - case MESA_FORMAT_B10G10R10A2_UNORM: - unpack_int_rgba_B10G10R10A2_UNORM(src, dst, n); - break; - - case MESA_FORMAT_RGBX_UINT8: - unpack_int_rgba_XBGR8888_UINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_SINT8: - unpack_int_rgba_XBGR8888_SINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_UINT16: - unpack_int_rgba_XBGR16161616_UINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_SINT16: - unpack_int_rgba_XBGR16161616_SINT(src, dst, n); - break; - - case MESA_FORMAT_RGBX_UINT32: - case MESA_FORMAT_RGBX_SINT32: - unpack_int_rgba_XBGR32323232_UINT(src, dst, n); - break; - - case MESA_FORMAT_R10G10B10A2_UNORM: - unpack_int_rgba_R10G10B10A2_UNORM(src, dst, n); - break; - - default: - _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, - _mesa_get_format_name(format)); - return; - } -} - -/** - * Unpack a 2D rect of pixels returning float RGBA colors. - * \param format the source image format - * \param src start address of the source image - * \param srcRowStride source image row stride in bytes - * \param dst start address of the dest image - * \param dstRowStride dest image row stride in bytes - * \param x source image start X pos - * \param y source image start Y pos - * \param width width of rect region to convert - * \param height height of rect region to convert - */ -void -_mesa_unpack_rgba_block(mesa_format format, - const void *src, GLint srcRowStride, - GLfloat dst[][4], GLint dstRowStride, - GLuint x, GLuint y, GLuint width, GLuint height) -{ - unpack_rgba_func unpack = get_unpack_rgba_function(format); - const GLuint srcPixStride = _mesa_get_format_bytes(format); - const GLuint dstPixStride = 4 * sizeof(GLfloat); - const GLubyte *srcRow; - GLubyte *dstRow; - GLuint i; - - /* XXX needs to be fixed for compressed formats */ - - srcRow = ((const GLubyte *) src) + srcRowStride * y + srcPixStride * x; - dstRow = ((GLubyte *) dst) + dstRowStride * y + dstPixStride * x; - - for (i = 0; i < height; i++) { - unpack(srcRow, (GLfloat (*)[4]) dstRow, width); - - dstRow += dstRowStride; - srcRow += srcRowStride; - } -} - - - - -typedef void (*unpack_float_z_func)(GLuint n, const void *src, GLfloat *dst); - -static void -unpack_float_z_X8_UINT_Z24_UNORM(GLuint n, const void *src, GLfloat *dst) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLfloat) ((s[i] >> 8) * scale); - ASSERT(dst[i] >= 0.0F); - ASSERT(dst[i] <= 1.0F); - } -} - -static void -unpack_float_z_Z24_UNORM_X8_UINT(GLuint n, const void *src, GLfloat *dst) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLfloat) ((s[i] & 0x00ffffff) * scale); - ASSERT(dst[i] >= 0.0F); - ASSERT(dst[i] <= 1.0F); - } -} - -static void -unpack_float_Z_UNORM16(GLuint n, const void *src, GLfloat *dst) -{ - const GLushort *s = ((const GLushort *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = s[i] * (1.0F / 65535.0F); - } -} - -static void -unpack_float_Z_UNORM32(GLuint n, const void *src, GLfloat *dst) -{ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = s[i] * (1.0F / 0xffffffff); - } -} - -static void -unpack_float_Z_FLOAT32(GLuint n, const void *src, GLfloat *dst) -{ - memcpy(dst, src, n * sizeof(float)); -} - -static void -unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) -{ - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = s[i].z; - } -} - - - -/** - * Unpack Z values. - * The returned values will always be in the range [0.0, 1.0]. - */ -void -_mesa_unpack_float_z_row(mesa_format format, GLuint n, - const void *src, GLfloat *dst) -{ - unpack_float_z_func unpack; - - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - unpack = unpack_float_z_X8_UINT_Z24_UNORM; - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - unpack = unpack_float_z_Z24_UNORM_X8_UINT; - break; - case MESA_FORMAT_Z_UNORM16: - unpack = unpack_float_Z_UNORM16; - break; - case MESA_FORMAT_Z_UNORM32: - unpack = unpack_float_Z_UNORM32; - break; - case MESA_FORMAT_Z_FLOAT32: - unpack = unpack_float_Z_FLOAT32; - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack = unpack_float_z_Z32X24S8; - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_float_z_row", - _mesa_get_format_name(format)); - return; - } - - unpack(n, src, dst); -} - - - -typedef void (*unpack_uint_z_func)(const void *src, GLuint *dst, GLuint n); - -static void -unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, GLuint *dst, GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24); - } -} - -static void -unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, GLuint *dst, GLuint n) -{ - /* only return Z, not stencil data */ - const GLuint *s = ((const GLuint *) src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff); - } -} - -static void -unpack_uint_Z_UNORM16(const void *src, GLuint *dst, GLuint n) -{ - const GLushort *s = ((const GLushort *)src); - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (s[i] << 16) | s[i]; - } -} - -static void -unpack_uint_Z_UNORM32(const void *src, GLuint *dst, GLuint n) -{ - memcpy(dst, src, n * sizeof(GLuint)); -} - -static void -unpack_uint_Z_FLOAT32(const void *src, GLuint *dst, GLuint n) -{ - const float *s = (const float *)src; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F)); - } -} - -static void -unpack_uint_Z_FLOAT32_X24S8(const void *src, GLuint *dst, GLuint n) -{ - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - GLuint i; - - for (i = 0; i < n; i++) { - dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F)); - } -} - - -/** - * Unpack Z values. - * The returned values will always be in the range [0, 0xffffffff]. - */ -void -_mesa_unpack_uint_z_row(mesa_format format, GLuint n, - const void *src, GLuint *dst) -{ - unpack_uint_z_func unpack; - const GLubyte *srcPtr = (GLubyte *) src; - - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - case MESA_FORMAT_X8_UINT_Z24_UNORM: - unpack = unpack_uint_z_X8_UINT_Z24_UNORM; - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - case MESA_FORMAT_Z24_UNORM_X8_UINT: - unpack = unpack_uint_z_Z24_UNORM_X8_UINT; - break; - case MESA_FORMAT_Z_UNORM16: - unpack = unpack_uint_Z_UNORM16; - break; - case MESA_FORMAT_Z_UNORM32: - unpack = unpack_uint_Z_UNORM32; - break; - case MESA_FORMAT_Z_FLOAT32: - unpack = unpack_uint_Z_FLOAT32; - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack = unpack_uint_Z_FLOAT32_X24S8; - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row", - _mesa_get_format_name(format)); - return; - } - - unpack(srcPtr, dst, n); -} - - -static void -unpack_ubyte_s_S_UINT8(const void *src, GLubyte *dst, GLuint n) -{ - memcpy(dst, src, n); -} - -static void -unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, GLubyte *dst, GLuint n) -{ - GLuint i; - const GLuint *src32 = src; - - for (i = 0; i < n; i++) - dst[i] = src32[i] & 0xff; -} - -static void -unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, GLubyte *dst, GLuint n) -{ - GLuint i; - const GLuint *src32 = src; - - for (i = 0; i < n; i++) - dst[i] = src32[i] >> 24; -} - -static void -unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, GLubyte *dst, GLuint n) -{ - GLuint i; - const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; - - for (i = 0; i < n; i++) - dst[i] = s[i].x24s8 & 0xff; -} - -void -_mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n, - const void *src, GLubyte *dst) -{ - switch (format) { - case MESA_FORMAT_S_UINT8: - unpack_ubyte_s_S_UINT8(src, dst, n); - break; - case MESA_FORMAT_S8_UINT_Z24_UNORM: - unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n); - break; - default: - _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row", - _mesa_get_format_name(format)); - return; - } -} - -static void -unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const GLuint *src, GLuint *dst, GLuint n) -{ - GLuint i; - - for (i = 0; i < n; i++) { - GLuint val = src[i]; - dst[i] = val >> 24 | val << 8; - } -} - -static void -unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src, - GLuint *dst, GLuint n) -{ - GLuint i; - - for (i = 0; i < n; i++) { - /* 8 bytes per pixel (float + uint32) */ - GLfloat zf = ((GLfloat *) src)[i * 2 + 0]; - GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff); - GLuint s = src[i * 2 + 1] & 0xff; - dst[i] = (z24 << 8) | s; - } -} - -static void -unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const GLuint *src, GLuint *dst, GLuint n) -{ - memcpy(dst, src, n * 4); -} - -/** - * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8. - * \param format the source data format - */ -void -_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, - const void *src, GLuint *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n); - break; - default: - _mesa_problem(NULL, - "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", - _mesa_get_format_name(format)); - return; - } -} - -static void -unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const GLuint *src, - GLuint *dst, GLuint n) -{ - GLuint i; - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - - for (i = 0; i < n; i++) { - const GLuint z24 = src[i] & 0xffffff; - d[i].z = z24 * scale; - d[i].x24s8 = src[i] >> 24; - assert(d[i].z >= 0.0f); - assert(d[i].z <= 1.0f); - } -} - -static void -unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const GLuint *src, - GLuint *dst, GLuint n) -{ - memcpy(dst, src, n * sizeof(struct z32f_x24s8)); -} - -static void -unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const GLuint *src, - GLuint *dst, GLuint n) -{ - GLuint i; - struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; - const GLdouble scale = 1.0 / (GLdouble) 0xffffff; - - for (i = 0; i < n; i++) { - const GLuint z24 = src[i] >> 8; - d[i].z = z24 * scale; - d[i].x24s8 = src[i] & 0xff; - assert(d[i].z >= 0.0f); - assert(d[i].z <= 1.0f); - } -} - -/** - * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV. - * \param format the source data format - * - * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float - * component and higher 4 bytes contain packed 24-bit and 8-bit - * components. - * - * 31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0 - * +-------------------------+ +--------------------------------+ - * | Float Component | | Unused | 8 bit stencil | - * +-------------------------+ +--------------------------------+ - * lower 4 bytes higher 4 bytes - */ -void -_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, - const void *src, GLuint *dst) -{ - switch (format) { - case MESA_FORMAT_S8_UINT_Z24_UNORM: - unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n); - break; - case MESA_FORMAT_Z24_UNORM_S8_UINT: - unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n); - break; - case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: - unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n); - break; - default: - _mesa_problem(NULL, - "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", - _mesa_get_format_name(format)); - return; - } -} - -/** - * Unpack depth/stencil - * \param format the source data format - * \param type the destination data type - */ -void -_mesa_unpack_depth_stencil_row(mesa_format format, GLuint n, - const void *src, GLenum type, - GLuint *dst) -{ - assert(type == GL_UNSIGNED_INT_24_8 || - type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - - switch (type) { - case GL_UNSIGNED_INT_24_8: - _mesa_unpack_uint_24_8_depth_stencil_row(format, n, src, dst); - break; - case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: - _mesa_unpack_float_32_uint_24_8_depth_stencil_row(format, n, src, dst); - break; - default: - _mesa_problem(NULL, - "bad type 0x%x in _mesa_unpack_depth_stencil_row", - type); - return; - } -} diff --git a/mesalib/src/mesa/main/format_unpack.py b/mesalib/src/mesa/main/format_unpack.py new file mode 100644 index 000000000..2276a1063 --- /dev/null +++ b/mesalib/src/mesa/main/format_unpack.py @@ -0,0 +1,895 @@ +#!/usr/bin/env python + +from mako.template import Template +from sys import argv + +string = """/* + * Mesa 3-D graphics library + * + * Copyright (c) 2011 VMware, Inc. + * 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. + */ + + +/** + * Color, depth, stencil packing functions. + * Used to pack basic color, depth and stencil formats to specific + * hardware formats. + * + * There are both per-pixel and per-row packing functions: + * - The former will be used by swrast to write values to the color, depth, + * stencil buffers when drawing points, lines and masked spans. + * - The later will be used for image-oriented functions like glDrawPixels, + * glAccum, and glTexImage. + */ + +#include <stdint.h> + +#include "colormac.h" +#include "format_unpack.h" +#include "format_utils.h" +#include "macros.h" +#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" +#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "util/format_srgb.h" + +#define UNPACK(SRC, OFFSET, BITS) (((SRC) >> (OFFSET)) & MAX_UINT(BITS)) + +<% +import format_parser as parser + +formats = parser.parse(argv[1]) + +rgb_formats = [] +for f in formats: + if f.name == 'MESA_FORMAT_NONE': + continue + if f.colorspace not in ('rgb', 'srgb'): + continue + + rgb_formats.append(f) +%> + +/* float unpacking functions */ + +%for f in rgb_formats: + %if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %elif f.is_compressed(): + <% continue %> + %endif + +static inline void +unpack_float_${f.short_name()}(const void *void_src, GLfloat dst[4]) +{ + ${f.datatype()} *src = (${f.datatype()} *)void_src; + %if f.layout == parser.PACKED: + %for c in f.channels: + %if c.type != 'x': + ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); + %endif + %endfor + %elif f.layout == parser.ARRAY: + %for (i, c) in enumerate(f.channels): + %if c.type != 'x': + ${c.datatype()} ${c.name} = src[${i}]; + %endif + %endfor + %else: + <% assert False %> + %endif + + %for i in range(4): + <% s = f.swizzle[i] %> + %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: + <% c = f.channels[s] %> + %if c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + dst[${i}] = util_format_srgb_8unorm_to_linear_float(${c.name}); + %else: + dst[${i}] = _mesa_unorm_to_float(${c.name}, ${c.size}); + %endif + %elif c.type == parser.SIGNED: + dst[${i}] = _mesa_snorm_to_float(${c.name}, ${c.size}); + %elif c.type == parser.FLOAT: + %if c.size == 32: + dst[${i}] = ${c.name}; + %elif c.size == 16: + dst[${i}] = _mesa_half_to_float(${c.name}); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %elif s == parser.Swizzle.SWIZZLE_ZERO: + dst[${i}] = 0.0f; + %elif s == parser.Swizzle.SWIZZLE_ONE: + dst[${i}] = 1.0f; + %else: + <% assert False %> + %endif + %endfor +} +%endfor + +static void +unpack_float_r9g9b9e5_float(const void *src, GLfloat dst[4]) +{ + rgb9e5_to_float3(*(const GLuint *)src, dst); + dst[3] = 1.0f; +} + +static void +unpack_float_r11g11b10_float(const void *src, GLfloat dst[4]) +{ + r11g11b10f_to_float3(*(const GLuint *)src, dst); + dst[3] = 1.0f; +} + +static void +unpack_float_ycbcr(const void *src, GLfloat dst[][4], GLuint n) +{ + GLuint i; + for (i = 0; i < n; i++) { + const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ + const GLushort *src1 = src0 + 1; /* odd */ + const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ + const GLubyte cb = *src0 & 0xff; /* chroma U */ + const GLubyte y1 = (*src1 >> 8) & 0xff; /* luminance */ + const GLubyte cr = *src1 & 0xff; /* chroma V */ + const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ + GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); + GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); + GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); + r *= (1.0F / 255.0F); + g *= (1.0F / 255.0F); + b *= (1.0F / 255.0F); + dst[i][0] = CLAMP(r, 0.0F, 1.0F); + dst[i][1] = CLAMP(g, 0.0F, 1.0F); + dst[i][2] = CLAMP(b, 0.0F, 1.0F); + dst[i][3] = 1.0F; + } +} + +static void +unpack_float_ycbcr_rev(const void *src, GLfloat dst[][4], GLuint n) +{ + GLuint i; + for (i = 0; i < n; i++) { + const GLushort *src0 = ((const GLushort *) src) + i * 2; /* even */ + const GLushort *src1 = src0 + 1; /* odd */ + const GLubyte y0 = *src0 & 0xff; /* luminance */ + const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ + const GLubyte y1 = *src1 & 0xff; /* luminance */ + const GLubyte cb = (*src1 >> 8) & 0xff; /* chroma U */ + const GLubyte y = (i & 1) ? y1 : y0; /* choose even/odd luminance */ + GLfloat r = 1.164F * (y - 16) + 1.596F * (cr - 128); + GLfloat g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128); + GLfloat b = 1.164F * (y - 16) + 2.018F * (cb - 128); + r *= (1.0F / 255.0F); + g *= (1.0F / 255.0F); + b *= (1.0F / 255.0F); + dst[i][0] = CLAMP(r, 0.0F, 1.0F); + dst[i][1] = CLAMP(g, 0.0F, 1.0F); + dst[i][2] = CLAMP(b, 0.0F, 1.0F); + dst[i][3] = 1.0F; + } +} + +/* ubyte packing functions */ + +%for f in rgb_formats: + %if not f.is_normalized(): + <% continue %> + %endif + +static inline void +unpack_ubyte_${f.short_name()}(const void *void_src, GLubyte dst[4]) +{ + ${f.datatype()} *src = (${f.datatype()} *)void_src; + %if f.layout == parser.PACKED: + %for c in f.channels: + %if c.type != 'x': + ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); + %endif + %endfor + %elif f.layout == parser.ARRAY: + %for (i, c) in enumerate(f.channels): + %if c.type != 'x': + ${c.datatype()} ${c.name} = src[${i}]; + %endif + %endfor + %else: + <% assert False %> + %endif + + %for i in range(4): + <% s = f.swizzle[i] %> + %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: + <% c = f.channels[s] %> + %if c.type == parser.UNSIGNED: + %if f.colorspace == 'srgb' and c.name in 'rgb': + <% assert c.size == 8 %> + dst[${i}] = util_format_srgb_to_linear_8unorm(${c.name}); + %else: + dst[${i}] = _mesa_unorm_to_unorm(${c.name}, ${c.size}, 8); + %endif + %elif c.type == parser.SIGNED: + dst[${i}] = _mesa_snorm_to_unorm(${c.name}, ${c.size}, 8); + %elif c.type == parser.FLOAT: + %if c.size == 32: + dst[${i}] = _mesa_float_to_unorm(${c.name}, 8); + %elif c.size == 16: + dst[${i}] = _mesa_half_to_unorm(${c.name}, 8); + %else: + <% assert False %> + %endif + %else: + <% assert False %> + %endif + %elif s == parser.Swizzle.SWIZZLE_ZERO: + dst[${i}] = 0; + %elif s == parser.Swizzle.SWIZZLE_ONE: + dst[${i}] = 255; + %else: + <% assert False %> + %endif + %endfor +} +%endfor + +/* integer packing functions */ + +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %endif + +static inline void +unpack_int_${f.short_name()}(const void *void_src, GLuint dst[4]) +{ + ${f.datatype()} *src = (${f.datatype()} *)void_src; + %if f.layout == parser.PACKED: + %for c in f.channels: + %if c.type != 'x': + ${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size}); + %endif + %endfor + %elif f.layout == parser.ARRAY: + %for (i, c) in enumerate(f.channels): + %if c.type != 'x': + ${c.datatype()} ${c.name} = src[${i}]; + %endif + %endfor + %else: + <% assert False %> + %endif + + %for i in range(4): + <% s = f.swizzle[i] %> + %if 0 <= s and s <= parser.Swizzle.SWIZZLE_W: + dst[${i}] = ${f.channels[s].name}; + %elif s == parser.Swizzle.SWIZZLE_ZERO: + dst[${i}] = 0; + %elif s == parser.Swizzle.SWIZZLE_ONE: + dst[${i}] = 1; + %else: + <% assert False %> + %endif + %endfor +} +%endfor + + +void +_mesa_unpack_rgba_row(mesa_format format, GLuint n, + const void *src, GLfloat dst[][4]) +{ + GLubyte *s = (GLubyte *)src; + GLuint i; + + switch (format) { +%for f in rgb_formats: + %if f.is_compressed(): + <% continue %> + %elif f.is_int() and not f.is_normalized(): + <% continue %> + %endif + case ${f.name}: + for (i = 0; i < n; ++i) { + unpack_float_${f.short_name()}(s, dst[i]); + s += ${f.block_size() / 8}; + } + break; +%endfor + case MESA_FORMAT_YCBCR: + unpack_float_ycbcr(src, dst, n); + break; + case MESA_FORMAT_YCBCR_REV: + unpack_float_ycbcr_rev(src, dst, n); + break; + default: + _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, + _mesa_get_format_name(format)); + return; + } +} + +void +_mesa_unpack_ubyte_rgba_row(mesa_format format, GLuint n, + const void *src, GLubyte dst[][4]) +{ + GLubyte *s = (GLubyte *)src; + GLuint i; + + switch (format) { +%for f in rgb_formats: + %if not f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + unpack_ubyte_${f.short_name()}(s, dst[i]); + s += ${f.block_size() / 8}; + } + break; +%endfor + default: + /* get float values, convert to ubyte */ + { + GLfloat *tmp = malloc(n * 4 * sizeof(GLfloat)); + if (tmp) { + GLuint i; + _mesa_unpack_rgba_row(format, n, src, (GLfloat (*)[4]) tmp); + for (i = 0; i < n; i++) { + dst[i][0] = _mesa_float_to_unorm(tmp[i*4+0], 8); + dst[i][1] = _mesa_float_to_unorm(tmp[i*4+1], 8); + dst[i][2] = _mesa_float_to_unorm(tmp[i*4+2], 8); + dst[i][3] = _mesa_float_to_unorm(tmp[i*4+3], 8); + } + free(tmp); + } + } + break; + } +} + +void +_mesa_unpack_uint_rgba_row(mesa_format format, GLuint n, + const void *src, GLuint dst[][4]) +{ + GLubyte *s = (GLubyte *)src; + GLuint i; + + switch (format) { +%for f in rgb_formats: + %if not f.is_int(): + <% continue %> + %elif f.is_normalized(): + <% continue %> + %endif + + case ${f.name}: + for (i = 0; i < n; ++i) { + unpack_int_${f.short_name()}(s, dst[i]); + s += ${f.block_size() / 8}; + } + break; +%endfor + default: + _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, + _mesa_get_format_name(format)); + return; + } +} + +/** + * Unpack a 2D rect of pixels returning float RGBA colors. + * \param format the source image format + * \param src start address of the source image + * \param srcRowStride source image row stride in bytes + * \param dst start address of the dest image + * \param dstRowStride dest image row stride in bytes + * \param x source image start X pos + * \param y source image start Y pos + * \param width width of rect region to convert + * \param height height of rect region to convert + */ +void +_mesa_unpack_rgba_block(mesa_format format, + const void *src, GLint srcRowStride, + GLfloat dst[][4], GLint dstRowStride, + GLuint x, GLuint y, GLuint width, GLuint height) +{ + const GLuint srcPixStride = _mesa_get_format_bytes(format); + const GLuint dstPixStride = 4 * sizeof(GLfloat); + const GLubyte *srcRow; + GLubyte *dstRow; + GLuint i; + + /* XXX needs to be fixed for compressed formats */ + + srcRow = ((const GLubyte *) src) + srcRowStride * y + srcPixStride * x; + dstRow = ((GLubyte *) dst) + dstRowStride * y + dstPixStride * x; + + for (i = 0; i < height; i++) { + _mesa_unpack_rgba_row(format, width, srcRow, (GLfloat (*)[4]) dstRow); + + dstRow += dstRowStride; + srcRow += srcRowStride; + } +} + +/** Helper struct for MESA_FORMAT_Z32_FLOAT_S8X24_UINT */ +struct z32f_x24s8 +{ + float z; + uint32_t x24s8; +}; + +typedef void (*unpack_float_z_func)(GLuint n, const void *src, GLfloat *dst); + +static void +unpack_float_z_X8_UINT_Z24_UNORM(GLuint n, const void *src, GLfloat *dst) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLfloat) ((s[i] >> 8) * scale); + ASSERT(dst[i] >= 0.0F); + ASSERT(dst[i] <= 1.0F); + } +} + +static void +unpack_float_z_Z24_UNORM_X8_UINT(GLuint n, const void *src, GLfloat *dst) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLfloat) ((s[i] & 0x00ffffff) * scale); + ASSERT(dst[i] >= 0.0F); + ASSERT(dst[i] <= 1.0F); + } +} + +static void +unpack_float_Z_UNORM16(GLuint n, const void *src, GLfloat *dst) +{ + const GLushort *s = ((const GLushort *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = s[i] * (1.0F / 65535.0F); + } +} + +static void +unpack_float_Z_UNORM32(GLuint n, const void *src, GLfloat *dst) +{ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = s[i] * (1.0F / 0xffffffff); + } +} + +static void +unpack_float_Z_FLOAT32(GLuint n, const void *src, GLfloat *dst) +{ + memcpy(dst, src, n * sizeof(float)); +} + +static void +unpack_float_z_Z32X24S8(GLuint n, const void *src, GLfloat *dst) +{ + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = s[i].z; + } +} + + + +/** + * Unpack Z values. + * The returned values will always be in the range [0.0, 1.0]. + */ +void +_mesa_unpack_float_z_row(mesa_format format, GLuint n, + const void *src, GLfloat *dst) +{ + unpack_float_z_func unpack; + + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + unpack = unpack_float_z_X8_UINT_Z24_UNORM; + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + unpack = unpack_float_z_Z24_UNORM_X8_UINT; + break; + case MESA_FORMAT_Z_UNORM16: + unpack = unpack_float_Z_UNORM16; + break; + case MESA_FORMAT_Z_UNORM32: + unpack = unpack_float_Z_UNORM32; + break; + case MESA_FORMAT_Z_FLOAT32: + unpack = unpack_float_Z_FLOAT32; + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack = unpack_float_z_Z32X24S8; + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_unpack_float_z_row", + _mesa_get_format_name(format)); + return; + } + + unpack(n, src, dst); +} + + + +typedef void (*unpack_uint_z_func)(const void *src, GLuint *dst, GLuint n); + +static void +unpack_uint_z_X8_UINT_Z24_UNORM(const void *src, GLuint *dst, GLuint n) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (s[i] & 0xffffff00) | (s[i] >> 24); + } +} + +static void +unpack_uint_z_Z24_UNORM_X8_UINT(const void *src, GLuint *dst, GLuint n) +{ + /* only return Z, not stencil data */ + const GLuint *s = ((const GLuint *) src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (s[i] << 8) | ((s[i] >> 16) & 0xff); + } +} + +static void +unpack_uint_Z_UNORM16(const void *src, GLuint *dst, GLuint n) +{ + const GLushort *s = ((const GLushort *)src); + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (s[i] << 16) | s[i]; + } +} + +static void +unpack_uint_Z_UNORM32(const void *src, GLuint *dst, GLuint n) +{ + memcpy(dst, src, n * sizeof(GLuint)); +} + +static void +unpack_uint_Z_FLOAT32(const void *src, GLuint *dst, GLuint n) +{ + const float *s = (const float *)src; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F)); + } +} + +static void +unpack_uint_Z_FLOAT32_X24S8(const void *src, GLuint *dst, GLuint n) +{ + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + GLuint i; + + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F)); + } +} + + +/** + * Unpack Z values. + * The returned values will always be in the range [0, 0xffffffff]. + */ +void +_mesa_unpack_uint_z_row(mesa_format format, GLuint n, + const void *src, GLuint *dst) +{ + unpack_uint_z_func unpack; + const GLubyte *srcPtr = (GLubyte *) src; + + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + case MESA_FORMAT_X8_UINT_Z24_UNORM: + unpack = unpack_uint_z_X8_UINT_Z24_UNORM; + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + case MESA_FORMAT_Z24_UNORM_X8_UINT: + unpack = unpack_uint_z_Z24_UNORM_X8_UINT; + break; + case MESA_FORMAT_Z_UNORM16: + unpack = unpack_uint_Z_UNORM16; + break; + case MESA_FORMAT_Z_UNORM32: + unpack = unpack_uint_Z_UNORM32; + break; + case MESA_FORMAT_Z_FLOAT32: + unpack = unpack_uint_Z_FLOAT32; + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack = unpack_uint_Z_FLOAT32_X24S8; + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_unpack_uint_z_row", + _mesa_get_format_name(format)); + return; + } + + unpack(srcPtr, dst, n); +} + + +static void +unpack_ubyte_s_S_UINT8(const void *src, GLubyte *dst, GLuint n) +{ + memcpy(dst, src, n); +} + +static void +unpack_ubyte_s_S8_UINT_Z24_UNORM(const void *src, GLubyte *dst, GLuint n) +{ + GLuint i; + const GLuint *src32 = src; + + for (i = 0; i < n; i++) + dst[i] = src32[i] & 0xff; +} + +static void +unpack_ubyte_s_Z24_UNORM_S8_UINT(const void *src, GLubyte *dst, GLuint n) +{ + GLuint i; + const GLuint *src32 = src; + + for (i = 0; i < n; i++) + dst[i] = src32[i] >> 24; +} + +static void +unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(const void *src, GLubyte *dst, GLuint n) +{ + GLuint i; + const struct z32f_x24s8 *s = (const struct z32f_x24s8 *) src; + + for (i = 0; i < n; i++) + dst[i] = s[i].x24s8 & 0xff; +} + +void +_mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n, + const void *src, GLubyte *dst) +{ + switch (format) { + case MESA_FORMAT_S_UINT8: + unpack_ubyte_s_S_UINT8(src, dst, n); + break; + case MESA_FORMAT_S8_UINT_Z24_UNORM: + unpack_ubyte_s_S8_UINT_Z24_UNORM(src, dst, n); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + unpack_ubyte_s_Z24_UNORM_S8_UINT(src, dst, n); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack_ubyte_s_Z32_FLOAT_S8X24_UINT(src, dst, n); + break; + default: + _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row", + _mesa_get_format_name(format)); + return; + } +} + +static void +unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(const GLuint *src, GLuint *dst, GLuint n) +{ + GLuint i; + + for (i = 0; i < n; i++) { + GLuint val = src[i]; + dst[i] = val >> 24 | val << 8; + } +} + +static void +unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src, + GLuint *dst, GLuint n) +{ + GLuint i; + + for (i = 0; i < n; i++) { + /* 8 bytes per pixel (float + uint32) */ + GLfloat zf = ((GLfloat *) src)[i * 2 + 0]; + GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff); + GLuint s = src[i * 2 + 1] & 0xff; + dst[i] = (z24 << 8) | s; + } +} + +static void +unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(const GLuint *src, GLuint *dst, GLuint n) +{ + memcpy(dst, src, n * 4); +} + +/** + * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8. + * \param format the source data format + */ +void +_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, + const void *src, GLuint *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + unpack_uint_24_8_depth_stencil_S8_UINT_Z24_UNORM(src, dst, n); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + unpack_uint_24_8_depth_stencil_Z24_UNORM_S8_UINT(src, dst, n); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n); + break; + default: + _mesa_problem(NULL, + "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", + _mesa_get_format_name(format)); + return; + } +} + +static void +unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(const GLuint *src, + GLuint *dst, GLuint n) +{ + GLuint i; + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + + for (i = 0; i < n; i++) { + const GLuint z24 = src[i] & 0xffffff; + d[i].z = z24 * scale; + d[i].x24s8 = src[i] >> 24; + assert(d[i].z >= 0.0f); + assert(d[i].z <= 1.0f); + } +} + +static void +unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(const GLuint *src, + GLuint *dst, GLuint n) +{ + memcpy(dst, src, n * sizeof(struct z32f_x24s8)); +} + +static void +unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(const GLuint *src, + GLuint *dst, GLuint n) +{ + GLuint i; + struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; + + for (i = 0; i < n; i++) { + const GLuint z24 = src[i] >> 8; + d[i].z = z24 * scale; + d[i].x24s8 = src[i] & 0xff; + assert(d[i].z >= 0.0f); + assert(d[i].z <= 1.0f); + } +} + +/** + * Unpack depth/stencil returning as GL_FLOAT_32_UNSIGNED_INT_24_8_REV. + * \param format the source data format + * + * In GL_FLOAT_32_UNSIGNED_INT_24_8_REV lower 4 bytes contain float + * component and higher 4 bytes contain packed 24-bit and 8-bit + * components. + * + * 31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0 + * +-------------------------+ +--------------------------------+ + * | Float Component | | Unused | 8 bit stencil | + * +-------------------------+ +--------------------------------+ + * lower 4 bytes higher 4 bytes + */ +void +_mesa_unpack_float_32_uint_24_8_depth_stencil_row(mesa_format format, GLuint n, + const void *src, GLuint *dst) +{ + switch (format) { + case MESA_FORMAT_S8_UINT_Z24_UNORM: + unpack_float_32_uint_24_8_S8_UINT_Z24_UNORM(src, dst, n); + break; + case MESA_FORMAT_Z24_UNORM_S8_UINT: + unpack_float_32_uint_24_8_Z24_UNORM_S8_UINT(src, dst, n); + break; + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + unpack_float_32_uint_24_8_Z32_FLOAT_S8X24_UINT(src, dst, n); + break; + default: + _mesa_problem(NULL, + "bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row", + _mesa_get_format_name(format)); + return; + } +} + +/** + * Unpack depth/stencil + * \param format the source data format + * \param type the destination data type + */ +void +_mesa_unpack_depth_stencil_row(mesa_format format, GLuint n, + const void *src, GLenum type, + GLuint *dst) +{ + assert(type == GL_UNSIGNED_INT_24_8 || + type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); + + switch (type) { + case GL_UNSIGNED_INT_24_8: + _mesa_unpack_uint_24_8_depth_stencil_row(format, n, src, dst); + break; + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + _mesa_unpack_float_32_uint_24_8_depth_stencil_row(format, n, src, dst); + break; + default: + _mesa_problem(NULL, + "bad type 0x%x in _mesa_unpack_depth_stencil_row", + type); + return; + } +} +""" + +template = Template(string); + +print template.render(argv = argv[0:]) diff --git a/mesalib/src/mesa/main/format_utils.c b/mesalib/src/mesa/main/format_utils.c index 93a0ceac0..810bb1634 100644 --- a/mesalib/src/mesa/main/format_utils.c +++ b/mesalib/src/mesa/main/format_utils.c @@ -24,6 +24,549 @@ #include "format_utils.h" #include "glformats.h" +#include "format_pack.h" +#include "format_unpack.h" + +const mesa_array_format RGBA32_FLOAT = + MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3); + +const mesa_array_format RGBA8_UBYTE = + MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3); + +const mesa_array_format RGBA32_UINT = + MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3); + +const mesa_array_format RGBA32_INT = + MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3); + +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; +} + +/* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This + * is used when we need to rebase a format to match a different + * base internal format. + * + * The rebase swizzle can be NULL, which means that no rebase is necessary, + * in which case the src to RGBA swizzle is copied to the output without + * changes. + * + * The resulting rebased swizzle and well as the input swizzles are + * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase + * is necessary. + */ +static void +compute_rebased_rgba_component_mapping(uint8_t *src2rgba, + uint8_t *rebase_swizzle, + uint8_t *rebased_src2rgba) +{ + int i; + + if (rebase_swizzle) { + for (i = 0; i < 4; i++) { + if (rebase_swizzle[i] > MESA_FORMAT_SWIZZLE_W) + rebased_src2rgba[i] = rebase_swizzle[i]; + else + rebased_src2rgba[i] = src2rgba[rebase_swizzle[i]]; + } + } else { + /* No rebase needed, so src2rgba is all that we need */ + memcpy(rebased_src2rgba, src2rgba, 4 * sizeof(uint8_t)); + } +} + +/* Computes the final swizzle transform to apply from src to dst in a + * conversion that might involve a rebase swizzle. + * + * This is used to compute the swizzle transform to apply in conversions + * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle + * and possibly, a rebase swizzle. + * + * The final swizzle transform to apply (src2dst) when a rebase swizzle is + * involved is: src -> rgba -> base -> rgba -> dst + */ +static void +compute_src2dst_component_mapping(uint8_t *src2rgba, uint8_t *rgba2dst, + uint8_t *rebase_swizzle, uint8_t *src2dst) +{ + int i; + + if (!rebase_swizzle) { + for (i = 0; i < 4; i++) { + if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) { + src2dst[i] = rgba2dst[i]; + } else { + src2dst[i] = src2rgba[rgba2dst[i]]; + } + } + } else { + for (i = 0; i < 4; i++) { + if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) { + src2dst[i] = rgba2dst[i]; + } else if (rebase_swizzle[rgba2dst[i]] > MESA_FORMAT_SWIZZLE_W) { + src2dst[i] = rebase_swizzle[rgba2dst[i]]; + } else { + src2dst[i] = src2rgba[rebase_swizzle[rgba2dst[i]]]; + } + } + } +} + +/** + * This function is used by clients of _mesa_format_convert to obtain + * the rebase swizzle to use in a format conversion based on the base + * format involved. + * + * \param baseFormat the base internal format involved in the conversion. + * \param map the rebase swizzle to consider + * + * This function computes 'map' as rgba -> baseformat -> rgba and returns true + * if the resulting swizzle transform is not the identity transform (thus, a + * rebase is needed). If the function returns false then a rebase swizzle + * is not necessary and the value of 'map' is undefined. In this situation + * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle' + * parameter. + */ +bool +_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map) +{ + uint8_t rgba2base[6], base2rgba[6]; + int i; + + switch (baseFormat) { + case GL_ALPHA: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_RG: + case GL_RGB: + case GL_BGR: + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + { + bool needRebase = false; + _mesa_compute_component_mapping(GL_RGBA, baseFormat, rgba2base); + _mesa_compute_component_mapping(baseFormat, GL_RGBA, base2rgba); + for (i = 0; i < 4; i++) { + if (base2rgba[i] > MESA_FORMAT_SWIZZLE_W) { + map[i] = base2rgba[i]; + } else { + map[i] = rgba2base[base2rgba[i]]; + } + if (map[i] != i) + needRebase = true; + } + return needRebase; + } + default: + unreachable("Unexpected base format"); + } +} + +/** + * This can be used to convert between most color formats. + * + * Limitations: + * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats. + * - This function doesn't handle byte-swapping or transferOps, these should + * be handled by the caller. + * + * \param void_dst The address where converted color data will be stored. + * The caller must ensure that the buffer is large enough + * to hold the converted pixel data. + * \param dst_format The destination color format. It can be a mesa_format + * or a mesa_array_format represented as an uint32_t. + * \param dst_stride The stride of the destination format in bytes. + * \param void_src The address of the source color data to convert. + * \param src_format The source color format. It can be a mesa_format + * or a mesa_array_format represented as an uint32_t. + * \param src_stride The stride of the source format in bytes. + * \param width The width, in pixels, of the source image to convert. + * \param height The height, in pixels, of the source image to convert. + * \param rebase_swizzle A swizzle transform to apply during the conversion, + * typically used to match a different internal base + * format involved. NULL if no rebase transform is needed + * (i.e. the internal base format and the base format of + * the dst or the src -depending on whether we are doing + * an upload or a download respectively- are the same). + */ +void +_mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, + void *void_src, uint32_t src_format, size_t src_stride, + size_t width, size_t height, uint8_t *rebase_swizzle) +{ + uint8_t *dst = (uint8_t *)void_dst; + uint8_t *src = (uint8_t *)void_src; + mesa_array_format src_array_format, dst_array_format; + bool src_format_is_mesa_array_format, dst_format_is_mesa_array_format; + uint8_t src2dst[4], src2rgba[4], rgba2dst[4], dst2rgba[4]; + uint8_t rebased_src2rgba[4]; + enum mesa_array_format_datatype src_type = 0, dst_type = 0, common_type; + bool normalized, dst_integer, src_integer, is_signed; + int src_num_channels = 0, dst_num_channels = 0; + uint8_t (*tmp_ubyte)[4]; + float (*tmp_float)[4]; + uint32_t (*tmp_uint)[4]; + int bits; + size_t row; + + if (_mesa_format_is_mesa_array_format(src_format)) { + src_format_is_mesa_array_format = true; + src_array_format = src_format; + } else { + assert(_mesa_is_format_color_format(src_format)); + src_format_is_mesa_array_format = false; + src_array_format = _mesa_format_to_array_format(src_format); + } + + if (_mesa_format_is_mesa_array_format(dst_format)) { + dst_format_is_mesa_array_format = true; + dst_array_format = dst_format; + } else { + assert(_mesa_is_format_color_format(dst_format)); + dst_format_is_mesa_array_format = false; + dst_array_format = _mesa_format_to_array_format(dst_format); + } + + /* First we see if we can implement the conversion with a direct pack + * or unpack. + * + * In this case we want to be careful when we need to apply a swizzle to + * match an internal base format, since in these cases a simple pack/unpack + * to the dst format from the src format may not match the requirements + * of the internal base format. For now we decide to be safe and + * avoid this path in these scenarios but in the future we may want to + * enable it for specific combinations that are known to work. + */ + if (!rebase_swizzle) { + /* Handle the cases where we can directly unpack */ + if (!src_format_is_mesa_array_format) { + if (dst_array_format == RGBA32_FLOAT) { + for (row = 0; row < height; ++row) { + _mesa_unpack_rgba_row(src_format, width, + src, (float (*)[4])dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (dst_array_format == RGBA8_UBYTE) { + assert(!_mesa_is_format_integer_color(src_format)); + for (row = 0; row < height; ++row) { + _mesa_unpack_ubyte_rgba_row(src_format, width, + src, (uint8_t (*)[4])dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (dst_array_format == RGBA32_UINT && + _mesa_is_format_unsigned(src_format)) { + assert(_mesa_is_format_integer_color(src_format)); + for (row = 0; row < height; ++row) { + _mesa_unpack_uint_rgba_row(src_format, width, + src, (uint32_t (*)[4])dst); + src += src_stride; + dst += dst_stride; + } + return; + } + } + + /* Handle the cases where we can directly pack */ + if (!dst_format_is_mesa_array_format) { + if (src_array_format == RGBA32_FLOAT) { + for (row = 0; row < height; ++row) { + _mesa_pack_float_rgba_row(dst_format, width, + (const float (*)[4])src, dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (src_array_format == RGBA8_UBYTE) { + assert(!_mesa_is_format_integer_color(dst_format)); + for (row = 0; row < height; ++row) { + _mesa_pack_ubyte_rgba_row(dst_format, width, + (const uint8_t (*)[4])src, dst); + src += src_stride; + dst += dst_stride; + } + return; + } else if (src_array_format == RGBA32_UINT && + _mesa_is_format_unsigned(dst_format)) { + assert(_mesa_is_format_integer_color(dst_format)); + for (row = 0; row < height; ++row) { + _mesa_pack_uint_rgba_row(dst_format, width, + (const uint32_t (*)[4])src, dst); + src += src_stride; + dst += dst_stride; + } + return; + } + } + } + + /* Handle conversions between array formats */ + normalized = false; + if (src_array_format) { + src_type = _mesa_array_format_get_datatype(src_array_format); + + src_num_channels = _mesa_array_format_get_num_channels(src_array_format); + + _mesa_array_format_get_swizzle(src_array_format, src2rgba); + + normalized = _mesa_array_format_is_normalized(src_array_format); + } + + if (dst_array_format) { + dst_type = _mesa_array_format_get_datatype(dst_array_format); + + dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format); + + _mesa_array_format_get_swizzle(dst_array_format, dst2rgba); + invert_swizzle(rgba2dst, dst2rgba); + + normalized |= _mesa_array_format_is_normalized(dst_array_format); + } + + if (src_array_format && dst_array_format) { + assert(_mesa_array_format_is_normalized(src_array_format) == + _mesa_array_format_is_normalized(dst_array_format)); + + compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle, + src2dst); + + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + src, src_type, src_num_channels, + src2dst, normalized, width); + src += src_stride; + dst += dst_stride; + } + return; + } + + /* At this point, we're fresh out of fast-paths and we need to convert + * to float, uint32, or, if we're lucky, uint8. + */ + dst_integer = false; + src_integer = false; + + if (src_array_format) { + if (!_mesa_array_format_is_float(src_array_format) && + !_mesa_array_format_is_normalized(src_array_format)) + src_integer = true; + } else { + switch (_mesa_get_format_datatype(src_format)) { + case GL_UNSIGNED_INT: + case GL_INT: + src_integer = true; + break; + } + } + + /* If the destination format is signed but the source is unsigned, then we + * don't loose any data by converting to a signed intermediate format above + * and beyond the precision that we loose in the conversion itself. If the + * destination is unsigned then, by using an unsigned intermediate format, + * we make the conversion function that converts from the source to the + * intermediate format take care of truncating at zero. The exception here + * is if the intermediate format is float, in which case the first + * conversion will leave it signed and the second conversion will truncate + * at zero. + */ + is_signed = false; + if (dst_array_format) { + if (!_mesa_array_format_is_float(dst_array_format) && + !_mesa_array_format_is_normalized(dst_array_format)) + dst_integer = true; + is_signed = _mesa_array_format_is_signed(dst_array_format); + bits = 8 * _mesa_array_format_get_type_size(dst_array_format); + } else { + switch (_mesa_get_format_datatype(dst_format)) { + case GL_UNSIGNED_NORMALIZED: + is_signed = false; + break; + case GL_SIGNED_NORMALIZED: + is_signed = true; + break; + case GL_FLOAT: + is_signed = true; + break; + case GL_UNSIGNED_INT: + is_signed = false; + dst_integer = true; + break; + case GL_INT: + is_signed = true; + dst_integer = true; + break; + } + bits = _mesa_get_format_max_bits(dst_format); + } + + assert(src_integer == dst_integer); + + if (src_integer && dst_integer) { + tmp_uint = malloc(width * height * sizeof(*tmp_uint)); + + /* The [un]packing functions for unsigned datatypes treat the 32-bit + * integer array as signed for signed formats and as unsigned for + * unsigned formats. This is a bit of a problem if we ever convert from + * a signed to an unsigned format because the unsigned packing function + * doesn't know that the input is signed and will treat it as unsigned + * and not do the trunctation. The thing that saves us here is that all + * of the packed formats are unsigned, so we can just always use + * _mesa_swizzle_and_convert for signed formats, which is aware of the + * truncation problem. + */ + common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT : + MESA_ARRAY_FORMAT_TYPE_UINT; + if (src_array_format) { + compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, + rebased_src2rgba); + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, + src, src_type, src_num_channels, + rebased_src2rgba, normalized, width); + src += src_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_unpack_uint_rgba_row(src_format, width, + src, tmp_uint + row * width); + if (rebase_swizzle) + _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4, + tmp_uint + row * width, common_type, 4, + rebase_swizzle, false, width); + src += src_stride; + } + } + + /* At this point, we have already done the truncation if the source is + * signed but the destination is unsigned, so no need to force the + * _mesa_swizzle_and_convert path. + */ + if (dst_format_is_mesa_array_format) { + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + tmp_uint + row * width, common_type, 4, + rgba2dst, normalized, width); + dst += dst_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_pack_uint_rgba_row(dst_format, width, + (const uint32_t (*)[4])tmp_uint + row * width, dst); + dst += dst_stride; + } + } + + free(tmp_uint); + } else if (is_signed || bits > 8) { + tmp_float = malloc(width * height * sizeof(*tmp_float)); + + if (src_format_is_mesa_array_format) { + compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, + rebased_src2rgba); + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + src, src_type, src_num_channels, + rebased_src2rgba, normalized, width); + src += src_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_unpack_rgba_row(src_format, width, + src, tmp_float + row * width); + if (rebase_swizzle) + _mesa_swizzle_and_convert(tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + rebase_swizzle, normalized, width); + src += src_stride; + } + } + + if (dst_format_is_mesa_array_format) { + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + tmp_float + row * width, + MESA_ARRAY_FORMAT_TYPE_FLOAT, 4, + rgba2dst, normalized, width); + dst += dst_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_pack_float_rgba_row(dst_format, width, + (const float (*)[4])tmp_float + row * width, dst); + dst += dst_stride; + } + } + + free(tmp_float); + } else { + tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte)); + + if (src_format_is_mesa_array_format) { + compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle, + rebased_src2rgba); + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + src, src_type, src_num_channels, + rebased_src2rgba, normalized, width); + src += src_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_unpack_ubyte_rgba_row(src_format, width, + src, tmp_ubyte + row * width); + if (rebase_swizzle) + _mesa_swizzle_and_convert(tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + rebase_swizzle, normalized, width); + src += src_stride; + } + } + + if (dst_format_is_mesa_array_format) { + for (row = 0; row < height; ++row) { + _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels, + tmp_ubyte + row * width, + MESA_ARRAY_FORMAT_TYPE_UBYTE, 4, + rgba2dst, normalized, width); + dst += dst_stride; + } + } else { + for (row = 0; row < height; ++row) { + _mesa_pack_ubyte_rgba_row(dst_format, width, + (const uint8_t (*)[4])tmp_ubyte + row * width, dst); + dst += dst_stride; + } + } + + free(tmp_ubyte); + } +} 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 }; @@ -132,131 +675,6 @@ _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components, } } -/* 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 * @@ -270,8 +688,12 @@ half_to_uint(uint16_t x) * 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, +swizzle_convert_try_memcpy(void *dst, + enum mesa_array_format_datatype dst_type, + int num_dst_channels, + const void *src, + enum mesa_array_format_datatype src_type, + int num_src_channels, const uint8_t swizzle[4], bool normalized, int count) { int i; @@ -285,7 +707,8 @@ swizzle_convert_try_memcpy(void *dst, GLenum dst_type, int num_dst_channels, if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE) return false; - memcpy(dst, src, count * num_src_channels * _mesa_sizeof_type(src_type)); + memcpy(dst, src, count * num_src_channels * + _mesa_array_format_datatype_get_size(src_type)); return true; } @@ -441,50 +864,50 @@ convert_float(void *void_dst, int num_dst_channels, const float one = 1.0f; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: SWIZZLE_CONVERT(float, float, src); break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src)); break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(float, uint8_t, unorm_to_float(src, 8)); + SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8)); } else { SWIZZLE_CONVERT(float, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(float, int8_t, snorm_to_float(src, 8)); + SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8)); } else { SWIZZLE_CONVERT(float, int8_t, src); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(float, uint16_t, unorm_to_float(src, 16)); + SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16)); } else { SWIZZLE_CONVERT(float, uint16_t, src); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(float, int16_t, snorm_to_float(src, 16)); + SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16)); } else { SWIZZLE_CONVERT(float, int16_t, src); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(float, uint32_t, unorm_to_float(src, 32)); + SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32)); } else { SWIZZLE_CONVERT(float, uint32_t, src); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(float, int32_t, snorm_to_float(src, 32)); + SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32)); } else { SWIZZLE_CONVERT(float, int32_t, src); } @@ -503,50 +926,50 @@ convert_half_float(void *void_dst, int num_dst_channels, const uint16_t one = _mesa_float_to_half(1.0f); switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src)); break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: SWIZZLE_CONVERT(uint16_t, uint16_t, src); break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_half(src, 8)); + SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8)); } else { SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src)); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_half(src, 8)); + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8)); } else { SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint16_t, unorm_to_half(src, 16)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16)); } else { SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_half(src, 16)); + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16)); } else { SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_half(src, 32)); + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32)); } else { SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_half(src, 32)); + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32)); } else { SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src)); } @@ -556,7 +979,6 @@ convert_half_float(void *void_dst, int num_dst_channels, } } - static void convert_ubyte(void *void_dst, int num_dst_channels, const void *void_src, GLenum src_type, int num_src_channels, @@ -565,56 +987,56 @@ convert_ubyte(void *void_dst, int num_dst_channels, const uint8_t one = normalized ? UINT8_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, float, float_to_unorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, float, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_unorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_uint(src)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: SWIZZLE_CONVERT(uint8_t, uint8_t, src); break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint8_t, int8_t, snorm_to_unorm(src, 8, 8)); + SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8)); } else { - SWIZZLE_CONVERT(uint8_t, int8_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint16_t, unorm_to_unorm(src, 16, 8)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint16_t, src); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, int16_t, snorm_to_unorm(src, 16, 8)); + SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(uint8_t, int16_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint32_t, unorm_to_unorm(src, 32, 8)); + SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint32_t, src); + SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, int32_t, snorm_to_unorm(src, 32, 8)); + SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(uint8_t, int32_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8)); } break; default: @@ -631,56 +1053,56 @@ convert_byte(void *void_dst, int num_dst_channels, const int8_t one = normalized ? INT8_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint8_t, float, float_to_snorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, float, src); + SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_snorm(src, 8)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8)); } else { - SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_float(src)); + SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(int8_t, uint8_t, unorm_to_snorm(src, 8, 8)); + SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8)); } else { - SWIZZLE_CONVERT(int8_t, uint8_t, src); + SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8)); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: SWIZZLE_CONVERT(int8_t, int8_t, src); break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(int8_t, uint16_t, unorm_to_snorm(src, 16, 8)); + SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(int8_t, uint16_t, src); + SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(int8_t, int16_t, snorm_to_snorm(src, 16, 8)); + SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8)); } else { - SWIZZLE_CONVERT(int8_t, int16_t, src); + SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(int8_t, uint32_t, unorm_to_snorm(src, 32, 8)); + SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(int8_t, uint32_t, src); + SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(int8_t, int32_t, snorm_to_snorm(src, 32, 8)); + SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8)); } else { - SWIZZLE_CONVERT(int8_t, int32_t, src); + SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8)); } break; default: @@ -697,56 +1119,56 @@ convert_ushort(void *void_dst, int num_dst_channels, const uint16_t one = normalized ? UINT16_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, float, float_to_unorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, float, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_unorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_uint(src)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_unorm(src, 8, 16)); + SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16)); } else { SWIZZLE_CONVERT(uint16_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_unorm(src, 8, 16)); + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16)); } else { - SWIZZLE_CONVERT(uint16_t, int8_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: SWIZZLE_CONVERT(uint16_t, uint16_t, src); break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_unorm(src, 16, 16)); + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16)); } else { - SWIZZLE_CONVERT(uint16_t, int16_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_unorm(src, 32, 16)); + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(uint16_t, uint32_t, src); + SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_unorm(src, 32, 16)); + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(uint16_t, int32_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16)); } break; default: @@ -763,56 +1185,56 @@ convert_short(void *void_dst, int num_dst_channels, const int16_t one = normalized ? INT16_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint16_t, float, float_to_snorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, float, src); + SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_snorm(src, 16)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16)); } else { - SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_float(src)); + SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(int16_t, uint8_t, unorm_to_snorm(src, 8, 16)); + SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16)); } else { SWIZZLE_CONVERT(int16_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(int16_t, int8_t, snorm_to_snorm(src, 8, 16)); + SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16)); } else { SWIZZLE_CONVERT(int16_t, int8_t, src); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(int16_t, uint16_t, unorm_to_snorm(src, 16, 16)); + SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16)); } else { - SWIZZLE_CONVERT(int16_t, uint16_t, src); + SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16)); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: SWIZZLE_CONVERT(int16_t, int16_t, src); break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(int16_t, uint32_t, unorm_to_snorm(src, 32, 16)); + SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(int16_t, uint32_t, src); + SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(int16_t, int32_t, snorm_to_snorm(src, 32, 16)); + SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16)); } else { - SWIZZLE_CONVERT(int16_t, int32_t, src); + SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16)); } break; default: @@ -828,56 +1250,56 @@ convert_uint(void *void_dst, int num_dst_channels, const uint32_t one = normalized ? UINT32_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, float, float_to_unorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, float, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_unorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_uint(src)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint8_t, unorm_to_unorm(src, 8, 32)); + SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32)); } else { SWIZZLE_CONVERT(uint32_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(uint32_t, int8_t, snorm_to_unorm(src, 8, 32)); + SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32)); } else { - SWIZZLE_CONVERT(uint32_t, int8_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32)); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint16_t, unorm_to_unorm(src, 16, 32)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32)); } else { SWIZZLE_CONVERT(uint32_t, uint16_t, src); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, int16_t, snorm_to_unorm(src, 16, 32)); + SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32)); } else { - SWIZZLE_CONVERT(uint32_t, int16_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32)); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: SWIZZLE_CONVERT(uint32_t, uint32_t, src); break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, int32_t, snorm_to_unorm(src, 32, 32)); + SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32)); } else { - SWIZZLE_CONVERT(uint32_t, int32_t, (src < 0) ? 0 : src); + SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32)); } break; default: @@ -891,59 +1313,59 @@ convert_int(void *void_dst, int num_dst_channels, const void *void_src, GLenum src_type, int num_src_channels, const uint8_t swizzle[4], bool normalized, int count) { - const int32_t one = normalized ? INT32_MAX : 12; + const int32_t one = normalized ? INT32_MAX : 1; switch (src_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: if (normalized) { - SWIZZLE_CONVERT(uint32_t, float, float_to_snorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, float, src); + SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32)); } break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: if (normalized) { - SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_snorm(src, 32)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32)); } else { - SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_float(src)); + SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32)); } break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: if (normalized) { - SWIZZLE_CONVERT(int32_t, uint8_t, unorm_to_snorm(src, 8, 32)); + SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32)); } else { SWIZZLE_CONVERT(int32_t, uint8_t, src); } break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: if (normalized) { - SWIZZLE_CONVERT(int32_t, int8_t, snorm_to_snorm(src, 8, 32)); + SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32)); } else { SWIZZLE_CONVERT(int32_t, int8_t, src); } break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: if (normalized) { - SWIZZLE_CONVERT(int32_t, uint16_t, unorm_to_snorm(src, 16, 32)); + SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32)); } else { SWIZZLE_CONVERT(int32_t, uint16_t, src); } break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: if (normalized) { - SWIZZLE_CONVERT(int32_t, int16_t, snorm_to_snorm(src, 16, 32)); + SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32)); } else { SWIZZLE_CONVERT(int32_t, int16_t, src); } break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: if (normalized) { - SWIZZLE_CONVERT(int32_t, uint32_t, unorm_to_snorm(src, 32, 32)); + SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32)); } else { - SWIZZLE_CONVERT(int32_t, uint32_t, src); + SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32)); } break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: SWIZZLE_CONVERT(int32_t, int32_t, src); break; default: @@ -1001,8 +1423,8 @@ convert_int(void *void_dst, int num_dst_channels, * \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, +_mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels, + const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels, const uint8_t swizzle[4], bool normalized, int count) { if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels, @@ -1011,35 +1433,35 @@ _mesa_swizzle_and_convert(void *void_dst, GLenum dst_type, int num_dst_channels, return; switch (dst_type) { - case GL_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_FLOAT: convert_float(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_HALF_FLOAT: + case MESA_ARRAY_FORMAT_TYPE_HALF: convert_half_float(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_UNSIGNED_BYTE: + case MESA_ARRAY_FORMAT_TYPE_UBYTE: convert_ubyte(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_BYTE: + case MESA_ARRAY_FORMAT_TYPE_BYTE: convert_byte(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_UNSIGNED_SHORT: + case MESA_ARRAY_FORMAT_TYPE_USHORT: convert_ushort(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_SHORT: + case MESA_ARRAY_FORMAT_TYPE_SHORT: convert_short(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_UNSIGNED_INT: + case MESA_ARRAY_FORMAT_TYPE_UINT: convert_uint(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; - case GL_INT: + case MESA_ARRAY_FORMAT_TYPE_INT: convert_int(void_dst, num_dst_channels, void_src, src_type, num_src_channels, swizzle, normalized, count); break; diff --git a/mesalib/src/mesa/main/format_utils.h b/mesalib/src/mesa/main/format_utils.h index 9f778e377..7f500ec78 100644 --- a/mesalib/src/mesa/main/format_utils.h +++ b/mesalib/src/mesa/main/format_utils.h @@ -32,14 +32,205 @@ #define FORMAT_UTILS_H #include "imports.h" +#include "macros.h" + +extern const mesa_array_format RGBA32_FLOAT; +extern const mesa_array_format RGBA8_UBYTE; +extern const mesa_array_format RGBA32_UINT; +extern const mesa_array_format RGBA32_INT; + +/* 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)) +#define MIN_INT(BITS) ((BITS) == 32 ? INT32_MIN : (-(1 << (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 +_mesa_unorm_to_float(unsigned x, unsigned src_bits) +{ + return x * (1.0f / (float)MAX_UINT(src_bits)); +} + +static inline float +_mesa_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 +_mesa_unorm_to_half(unsigned x, unsigned src_bits) +{ + return _mesa_float_to_half(_mesa_unorm_to_float(x, src_bits)); +} + +static inline uint16_t +_mesa_snorm_to_half(int x, unsigned src_bits) +{ + return _mesa_float_to_half(_mesa_snorm_to_float(x, src_bits)); +} + +static inline unsigned +_mesa_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 +_mesa_half_to_unorm(uint16_t x, unsigned dst_bits) +{ + return _mesa_float_to_unorm(_mesa_half_to_float(x), dst_bits); +} + +static inline unsigned +_mesa_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 { + unsigned src_half = (1 << (src_bits - 1)) - 1; + + if (src_bits + dst_bits > sizeof(x) * 8) { + assert(src_bits + dst_bits <= sizeof(uint64_t) * 8); + return (((uint64_t) x * MAX_UINT(dst_bits) + src_half) / + MAX_UINT(src_bits)); + } else { + return (x * MAX_UINT(dst_bits) + src_half) / MAX_UINT(src_bits); + } + } +} + +static inline unsigned +_mesa_snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits) +{ + if (x < 0) + return 0; + else + return _mesa_unorm_to_unorm(x, src_bits - 1, dst_bits); +} + +static inline int +_mesa_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 +_mesa_half_to_snorm(uint16_t x, unsigned dst_bits) +{ + return _mesa_float_to_snorm(_mesa_half_to_float(x), dst_bits); +} + +static inline int +_mesa_unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits) +{ + return _mesa_unorm_to_unorm(x, src_bits, dst_bits - 1); +} + +static inline int +_mesa_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 +_mesa_unsigned_to_unsigned(unsigned src, unsigned dst_size) +{ + return MIN2(src, MAX_UINT(dst_size)); +} + +static inline int +_mesa_unsigned_to_signed(unsigned src, unsigned dst_size) +{ + return MIN2(src, (unsigned)MAX_INT(dst_size)); +} + +static inline int +_mesa_signed_to_signed(int src, unsigned dst_size) +{ + return CLAMP(src, MIN_INT(dst_size), MAX_INT(dst_size)); +} + +static inline unsigned +_mesa_signed_to_unsigned(int src, unsigned dst_size) +{ + return CLAMP(src, 0, MAX_UINT(dst_size)); +} + +static inline unsigned +_mesa_float_to_unsigned(float src, unsigned dst_bits) +{ + if (src < 0.0f) + return 0; + if (src > (float)MAX_UINT(dst_bits)) + return MAX_UINT(dst_bits); + return _mesa_signed_to_unsigned(src, dst_bits); +} + +static inline unsigned +_mesa_float_to_signed(float src, unsigned dst_bits) +{ + if (src < (float)(-MAX_INT(dst_bits))) + return -MAX_INT(dst_bits); + if (src > (float)MAX_INT(dst_bits)) + return MAX_INT(dst_bits); + return _mesa_signed_to_signed(src, dst_bits); +} + +static inline unsigned +_mesa_half_to_unsigned(uint16_t src, unsigned dst_bits) +{ + if (_mesa_half_is_negative(src)) + return 0; + return _mesa_unsigned_to_unsigned(_mesa_float_to_half(src), dst_bits); +} + +static inline unsigned +_mesa_half_to_signed(uint16_t src, unsigned dst_bits) +{ + return _mesa_float_to_signed(_mesa_half_to_float(src), dst_bits); +} 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, +_mesa_swizzle_and_convert(void *dst, + enum mesa_array_format_datatype dst_type, + int num_dst_channels, + const void *src, + enum mesa_array_format_datatype src_type, + int num_src_channels, const uint8_t swizzle[4], bool normalized, int count); +bool +_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map); + +void +_mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, + void *void_src, uint32_t src_format, size_t src_stride, + size_t width, size_t height, uint8_t *rebase_swizzle); + #endif diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c index f6274fe30..7741cabad 100644 --- a/mesalib/src/mesa/main/formatquery.c +++ b/mesalib/src/mesa/main/formatquery.c @@ -89,8 +89,22 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * "If the <internalformat> parameter to GetInternalformativ is not * color-, depth- or stencil-renderable, then an INVALID_ENUM error is * generated." + * + * Page 243 of the GLES 3.0.4 spec says this for GetInternalformativ: + * + * "internalformat must be color-renderable, depth-renderable or + * stencilrenderable (as defined in section 4.4.4)." + * + * Section 4.4.4 on page 212 of the same spec says: + * + * "An internal format is color-renderable if it is one of the + * formats from table 3.13 noted as color-renderable or if it + * is unsized format RGBA or RGB." + * + * Therefore, we must accept GL_RGB and GL_RGBA here. */ - if (_mesa_base_fbo_format(ctx, internalformat) == 0) { + if (internalformat != GL_RGB && internalformat != GL_RGBA && + _mesa_base_fbo_format(ctx, internalformat) == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(internalformat=%s)", _mesa_lookup_enum_by_nr(internalformat)); diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index 58c32e23b..958d6f245 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -28,7 +28,8 @@ #include "formats.h" #include "macros.h" #include "glformats.h" - +#include "c11/threads.h" +#include "util/hash_table.h" /** * Information about texture formats. @@ -71,6 +72,7 @@ struct gl_format_info GLubyte BytesPerBlock; uint8_t Swizzle[4]; + mesa_array_format ArrayFormat; }; #include "format_info.c" @@ -213,17 +215,87 @@ _mesa_get_format_datatype(mesa_format format) return info->DataType; } +static GLenum +get_base_format_for_array_format(mesa_array_format format) +{ + uint8_t swizzle[4]; + int num_channels; + + _mesa_array_format_get_swizzle(format, swizzle); + num_channels = _mesa_array_format_get_num_channels(format); + + switch (num_channels) { + case 4: + /* FIXME: RGBX formats have 4 channels, but their base format is GL_RGB. + * This is not really a problem for now because we only create array + * formats from GL format/type combinations, and these cannot specify + * RGBX formats. + */ + return GL_RGBA; + case 3: + return GL_RGB; + case 2: + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 1) + return GL_LUMINANCE_ALPHA; + if (swizzle[0] == 1 && + swizzle[1] == 1 && + swizzle[2] == 1 && + swizzle[3] == 0) + return GL_LUMINANCE_ALPHA; + if (swizzle[0] == 0 && + swizzle[1] == 1 && + swizzle[2] == 4 && + swizzle[3] == 5) + return GL_RG; + if (swizzle[0] == 1 && + swizzle[1] == 0 && + swizzle[2] == 4 && + swizzle[3] == 5) + return GL_RG; + break; + case 1: + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 5) + return GL_LUMINANCE; + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 0) + return GL_INTENSITY; + if (swizzle[0] <= MESA_FORMAT_SWIZZLE_W) + return GL_RED; + if (swizzle[1] <= MESA_FORMAT_SWIZZLE_W) + return GL_GREEN; + if (swizzle[2] <= MESA_FORMAT_SWIZZLE_W) + return GL_BLUE; + if (swizzle[3] <= MESA_FORMAT_SWIZZLE_W) + return GL_ALPHA; + break; + } + + unreachable("Unsupported format"); +} /** * Return the basic format for the given type. The result will be one of * GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, * GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. + * This functions accepts a mesa_format or a mesa_array_format. */ GLenum -_mesa_get_format_base_format(mesa_format format) +_mesa_get_format_base_format(uint32_t format) { - const struct gl_format_info *info = _mesa_get_format_info(format); - return info->BaseFormat; + if (!_mesa_format_is_mesa_array_format(format)) { + const struct gl_format_info *info = _mesa_get_format_info(format); + return info->BaseFormat; + } else { + return get_base_format_for_array_format(format); + } } @@ -269,6 +341,105 @@ _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]) memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle)); } +mesa_array_format +_mesa_array_format_flip_channels(mesa_array_format format) +{ + int num_channels; + uint8_t swizzle[4]; + + num_channels = _mesa_array_format_get_num_channels(format); + _mesa_array_format_get_swizzle(format, swizzle); + + if (num_channels == 1) + return format; + + if (num_channels == 2) { + _mesa_array_format_set_swizzle(&format, swizzle[1], swizzle[0], + swizzle[2], swizzle[3]); + return format; + } + + if (num_channels == 4) { + _mesa_array_format_set_swizzle(&format, swizzle[3], swizzle[2], + swizzle[1], swizzle[0]); + return format; + } + + unreachable("Invalid array format"); +} + +uint32_t +_mesa_format_to_array_format(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + if (_mesa_little_endian()) + return info->ArrayFormat; + else + return _mesa_array_format_flip_channels(info->ArrayFormat); +} + +static struct hash_table *format_array_format_table; +static once_flag format_array_format_table_exists = ONCE_FLAG_INIT; + +static bool +array_formats_equal(const void *a, const void *b) +{ + return (intptr_t)a == (intptr_t)b; +} + +static void +format_array_format_table_init() +{ + const struct gl_format_info *info; + mesa_array_format array_format; + unsigned f; + + format_array_format_table = _mesa_hash_table_create(NULL, NULL, + array_formats_equal); + + for (f = 1; f < MESA_FORMAT_COUNT; ++f) { + info = _mesa_get_format_info(f); + if (!info->ArrayFormat) + continue; + + if (_mesa_little_endian()) { + array_format = info->ArrayFormat; + } else { + array_format = _mesa_array_format_flip_channels(info->ArrayFormat); + } + + /* This can happen and does for some of the BGR formats. Let's take + * the first one in the list. + */ + if (_mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format)) + continue; + + _mesa_hash_table_insert_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format, + (void *)(intptr_t)f); + } +} + +mesa_format +_mesa_format_from_array_format(uint32_t array_format) +{ + struct hash_entry *entry; + + assert(_mesa_format_is_mesa_array_format(array_format)); + + call_once(&format_array_format_table_exists, format_array_format_table_init); + + entry = _mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format); + if (entry) + return (intptr_t)entry->data; + else + return MESA_FORMAT_NONE; +} /** Is the given format a compressed format? */ GLboolean @@ -345,6 +516,25 @@ _mesa_is_format_integer(mesa_format format) return (info->DataType == GL_INT || info->DataType == GL_UNSIGNED_INT); } + +/** + * Return true if the given format is a color format. + */ +GLenum +_mesa_is_format_color_format(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + switch (info->BaseFormat) { + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX: + case GL_DEPTH_STENCIL: + return false; + default: + return true; + } +} + + /** * Return color encoding for given format. * \return GL_LINEAR or GL_SRGB @@ -864,6 +1054,34 @@ _mesa_format_to_type_and_comps(mesa_format format, *comps = 1; return; + case MESA_FORMAT_R3G3B2_UNORM: + *datatype = GL_UNSIGNED_BYTE_2_3_3_REV; + *comps = 3; + return; + case MESA_FORMAT_A4B4G4R4_UNORM: + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; + return; + + case MESA_FORMAT_R4G4B4A4_UNORM: + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; + return; + case MESA_FORMAT_R5G5B5A1_UNORM: + *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *comps = 4; + return; + case MESA_FORMAT_A2B10G10R10_UNORM: + case MESA_FORMAT_A2B10G10R10_UINT: + *datatype = GL_UNSIGNED_INT_10_10_10_2; + *comps = 4; + return; + case MESA_FORMAT_A2R10G10B10_UNORM: + case MESA_FORMAT_A2R10G10B10_UINT: + *datatype = GL_UNSIGNED_INT_10_10_10_2; + *comps = 4; + return; + case MESA_FORMAT_B2G3R3_UNORM: *datatype = GL_UNSIGNED_BYTE_3_3_2; *comps = 3; @@ -1265,6 +1483,7 @@ _mesa_format_to_type_and_comps(mesa_format format, return; case MESA_FORMAT_B10G10R10X2_UNORM: + case MESA_FORMAT_R10G10B10X2_UNORM: *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; *comps = 4; return; @@ -1462,14 +1681,14 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, return format == GL_RGB && type == GL_UNSIGNED_BYTE && littleEndian; case MESA_FORMAT_B5G6R5_UNORM: - return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && !swapBytes; + return ((format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) || + (format == GL_BGR && type == GL_UNSIGNED_SHORT_5_6_5_REV)) && + !swapBytes; case MESA_FORMAT_R5G6B5_UNORM: - /* Some of the 16-bit MESA_FORMATs that would seem to correspond to - * GL_UNSIGNED_SHORT_* are byte-swapped instead of channel-reversed, - * according to formats.h, so they can't be matched. - */ - return GL_FALSE; + return ((format == GL_BGR && type == GL_UNSIGNED_SHORT_5_6_5) || + (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5_REV)) && + !swapBytes; case MESA_FORMAT_B4G4R4A4_UNORM: return format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && @@ -1487,7 +1706,8 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, !swapBytes; case MESA_FORMAT_A1R5G5B5_UNORM: - return GL_FALSE; + return format == GL_BGRA && type == GL_UNSIGNED_SHORT_5_5_5_1 && + !swapBytes; case MESA_FORMAT_L4A4_UNORM: return GL_FALSE; @@ -1506,6 +1726,54 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, case MESA_FORMAT_B2G3R3_UNORM: return format == GL_RGB && type == GL_UNSIGNED_BYTE_3_3_2; + case MESA_FORMAT_R3G3B2_UNORM: + return format == GL_RGB && type == GL_UNSIGNED_BYTE_2_3_3_REV; + + case MESA_FORMAT_A4B4G4R4_UNORM: + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R4G4B4A4_UNORM: + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R5G5B5A1_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV; + + case MESA_FORMAT_A2B10G10R10_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2B10G10R10_UINT: + return format == GL_RGBA_INTEGER_EXT && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2R10G10B10_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2R10G10B10_UINT: + return format == GL_BGRA_INTEGER_EXT && type == GL_UNSIGNED_INT_10_10_10_2; + case MESA_FORMAT_A_UNORM8: return format == GL_ALPHA && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_A_UNORM16: @@ -1867,6 +2135,7 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, case MESA_FORMAT_RGBX_UINT8: case MESA_FORMAT_RGBX_SINT8: case MESA_FORMAT_B10G10R10X2_UNORM: + case MESA_FORMAT_R10G10B10X2_UNORM: case MESA_FORMAT_RGBX_UNORM16: case MESA_FORMAT_RGBX_SNORM16: case MESA_FORMAT_RGBX_FLOAT16: diff --git a/mesalib/src/mesa/main/formats.csv b/mesalib/src/mesa/main/formats.csv index 39bcdbdd2..e159e7dd6 100644 --- a/mesalib/src/mesa/main/formats.csv +++ b/mesalib/src/mesa/main/formats.csv @@ -82,12 +82,20 @@ MESA_FORMAT_G16R16_UNORM , packed, 1, 1, un16, un16, , 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_R10G10B10X2_UNORM , packed, 1, 1, un10, un10, un10, x2 , xyz1, 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_R3G3B2_UNORM , packed, 1, 1, un3 , un3 , un2 , , xyz1, rgb +MESA_FORMAT_A4B4G4R4_UNORM , packed, 1, 1, un4 , un4 , un4 , un4 , wzyx, rgb +MESA_FORMAT_R4G4B4A4_UNORM , packed, 1, 1, un4 , un4 , un4 , un4 , xyzw, rgb +MESA_FORMAT_R5G5B5A1_UNORM , packed, 1, 1, un5 , un5 , un5 , un1 , xyzw, rgb +MESA_FORMAT_A2B10G10R10_UNORM , packed, 1, 1, un2 , un10, un10, un10, wzyx, rgb +MESA_FORMAT_A2R10G10B10_UNORM , packed, 1, 1, un2 , un10, un10, un10, yzwx, rgb + MESA_FORMAT_YCBCR , other , 1, 1, x16 , , , , xyzw, yuv MESA_FORMAT_YCBCR_REV , other , 1, 1, x16 , , , , xyzw, yuv @@ -180,6 +188,8 @@ MESA_FORMAT_Z_FLOAT32 , array , 1, 1, f32 , , , # 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 +MESA_FORMAT_A2B10G10R10_UINT , packed, 1, 1, u2 , u10 , u10 , u10 , wzyx, rgb +MESA_FORMAT_A2R10G10B10_UINT , packed, 1, 1, u2 , u10 , u10 , u10 , yzwx, rgb # Array signed/unsigned non-normalized integer formats MESA_FORMAT_A_UINT8 , array , 1, 1, u8 , , , , 000x, rgb diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index 213ab563d..7e451caf0 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -36,7 +36,7 @@ #include <GL/gl.h> #include <stdbool.h> #include <stdint.h> - +#include "compiler.h" #ifdef __cplusplus extern "C" { @@ -82,6 +82,132 @@ enum { }; /** + * An uint32_t that encodes the information necessary to represent an + * array format + */ +typedef uint32_t mesa_array_format; + +/** + * Encoding for valid array format data types + */ +enum mesa_array_format_datatype { + MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0, + MESA_ARRAY_FORMAT_TYPE_USHORT = 0x1, + MESA_ARRAY_FORMAT_TYPE_UINT = 0x2, + MESA_ARRAY_FORMAT_TYPE_BYTE = 0x4, + MESA_ARRAY_FORMAT_TYPE_SHORT = 0x5, + MESA_ARRAY_FORMAT_TYPE_INT = 0x6, + MESA_ARRAY_FORMAT_TYPE_HALF = 0xd, + MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe, +}; + +/** + * An enum useful to encode/decode information stored in a mesa_array_format + */ +enum { + MESA_ARRAY_FORMAT_TYPE_IS_SIGNED = 0x4, + MESA_ARRAY_FORMAT_TYPE_IS_FLOAT = 0x8, + MESA_ARRAY_FORMAT_TYPE_NORMALIZED = 0x10, + MESA_ARRAY_FORMAT_DATATYPE_MASK = 0xf, + MESA_ARRAY_FORMAT_TYPE_MASK = 0x1f, + MESA_ARRAY_FORMAT_TYPE_SIZE_MASK = 0x3, + MESA_ARRAY_FORMAT_NUM_CHANS_MASK = 0xe0, + MESA_ARRAY_FORMAT_SWIZZLE_X_MASK = 0x00700, + MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK = 0x03800, + MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK = 0x1c000, + MESA_ARRAY_FORMAT_SWIZZLE_W_MASK = 0xe0000, + MESA_ARRAY_FORMAT_BIT = 0x80000000 +}; + +#define MESA_ARRAY_FORMAT(SIZE, SIGNED, IS_FLOAT, NORM, NUM_CHANS, \ + SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) ( \ + (((SIZE >> 1) ) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) | \ + (((SIGNED) << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) | \ + (((IS_FLOAT) << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) | \ + (((NORM) << 4 ) & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) | \ + (((NUM_CHANS) << 5 ) & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) | \ + (((SWIZZLE_X) << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) | \ + (((SWIZZLE_Y) << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) | \ + (((SWIZZLE_Z) << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) | \ + (((SWIZZLE_W) << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) | \ + MESA_ARRAY_FORMAT_BIT) + +/** + * Various helpers to access the data encoded in a mesa_array_format + */ +static inline bool +_mesa_array_format_is_signed(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) != 0; +} + +static inline bool +_mesa_array_format_is_float(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT) != 0; +} + +static inline bool +_mesa_array_format_is_normalized(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_TYPE_NORMALIZED) !=0; +} + +static inline enum mesa_array_format_datatype +_mesa_array_format_get_datatype(mesa_array_format f) +{ + return (enum mesa_array_format_datatype) + (f & MESA_ARRAY_FORMAT_DATATYPE_MASK); +} + +static inline int +_mesa_array_format_datatype_get_size(enum mesa_array_format_datatype type) +{ + return 1 << (type & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK); +} + +static inline int +_mesa_array_format_get_type_size(mesa_array_format f) +{ + return 1 << (f & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK); +} + +static inline int +_mesa_array_format_get_num_channels(mesa_array_format f) +{ + return (f & MESA_ARRAY_FORMAT_NUM_CHANS_MASK) >> 5; +} + +static inline void +_mesa_array_format_get_swizzle(mesa_array_format f, uint8_t *swizzle) +{ + swizzle[0] = (f & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) >> 8; + swizzle[1] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) >> 11; + swizzle[2] = (f & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) >> 14; + swizzle[3] = (f & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK) >> 17; +} + +static inline void +_mesa_array_format_set_swizzle(mesa_array_format *f, + int32_t x, int32_t y, int32_t z, int32_t w) +{ + *f |= ((x << 8 ) & MESA_ARRAY_FORMAT_SWIZZLE_X_MASK) | + ((y << 11) & MESA_ARRAY_FORMAT_SWIZZLE_Y_MASK) | + ((z << 14) & MESA_ARRAY_FORMAT_SWIZZLE_Z_MASK) | + ((w << 17) & MESA_ARRAY_FORMAT_SWIZZLE_W_MASK); +} + +/** + * A helper to know if the format stored in a uint32_t is a mesa_format + * or a mesa_array_format + */ +static inline bool +_mesa_format_is_mesa_array_format(uint32_t f) +{ + return (f & MESA_ARRAY_FORMAT_BIT) != 0; +} + +/** * Mesa texture/renderbuffer image formats. */ typedef enum @@ -139,9 +265,9 @@ typedef enum * ** when type applies to all components * * examples: msb <------ TEXEL BITS -----------> lsb - * MESA_FORMAT_A8B8G8R8_UNORM, AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR - * MESA_FORMAT_R5G6B5_UNORM RRRR RGGG GGGB BBBB - * MESA_FORMAT_B4G4R4X4_UNORM BBBB GGGG RRRR XXXX + * MESA_FORMAT_A8B8G8R8_UNORM, RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA + * MESA_FORMAT_R5G6B5_UNORM BBBB BGGG GGGR RRRR + * MESA_FORMAT_B4G4R4X4_UNORM XXXX RRRR GGGG BBBB * MESA_FORMAT_Z32_FLOAT_S8X24_UINT * MESA_FORMAT_R10G10B10A2_UINT * MESA_FORMAT_R9G9B9E5_FLOAT @@ -226,12 +352,21 @@ typedef enum MESA_FORMAT_B10G10R10A2_UNORM,/* AARR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */ MESA_FORMAT_B10G10R10X2_UNORM,/* xxRR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */ MESA_FORMAT_R10G10B10A2_UNORM,/* AABB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */ + MESA_FORMAT_R10G10B10X2_UNORM,/* xxBB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */ MESA_FORMAT_S8_UINT_Z24_UNORM,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */ MESA_FORMAT_X8_UINT_Z24_UNORM,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ xxxx xxxx */ MESA_FORMAT_Z24_UNORM_S8_UINT,/* SSSS SSSS ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */ MESA_FORMAT_Z24_UNORM_X8_UINT,/* xxxx xxxx ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */ + /* Other formats */ + MESA_FORMAT_R3G3B2_UNORM, /* BBGG GRRR */ + MESA_FORMAT_A4B4G4R4_UNORM, /* RRRR GGGG BBBB AAAA */ + MESA_FORMAT_R4G4B4A4_UNORM, /* AAAA BBBB GGGG RRRR */ + MESA_FORMAT_R5G5B5A1_UNORM, /* ABBB BBGG GGGR RRRR */ + MESA_FORMAT_A2B10G10R10_UNORM,/* RRRR RRRR RRGG GGGG GGGG BBBB BBBB BBAA */ + MESA_FORMAT_A2R10G10B10_UNORM,/* BBBB BBBB BBGG GGGG GGGG RRRR RRRR RRAA */ + MESA_FORMAT_YCBCR, /* YYYY YYYY UorV UorV */ MESA_FORMAT_YCBCR_REV, /* UorV UorV YYYY YYYY */ @@ -326,6 +461,8 @@ typedef enum /* Packed signed/unsigned non-normalized integer formats */ MESA_FORMAT_B10G10R10A2_UINT, /* AARR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */ MESA_FORMAT_R10G10B10A2_UINT, /* AABB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */ + MESA_FORMAT_A2B10G10R10_UINT, /* RRRR RRRR RRGG GGGG GGGG BBBB BBBB BBAA */ + MESA_FORMAT_A2R10G10B10_UINT, /* BBBB BBBB BBGG GGGG GGGG RRRR RRRR RRAA */ /* Array signed/unsigned non-normalized integer formats */ MESA_FORMAT_A_UINT8, @@ -461,14 +598,23 @@ extern GLenum _mesa_get_format_datatype(mesa_format format); extern GLenum -_mesa_get_format_base_format(mesa_format format); +_mesa_get_format_base_format(uint32_t format); extern void _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh); +extern mesa_array_format +_mesa_array_format_flip_channels(mesa_array_format format); + extern void _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]); +extern uint32_t +_mesa_format_to_array_format(mesa_format format); + +extern mesa_format +_mesa_format_from_array_format(uint32_t array_format); + extern GLboolean _mesa_is_format_compressed(mesa_format format); @@ -490,6 +636,9 @@ _mesa_is_format_integer(mesa_format format); extern bool _mesa_is_format_etc2(mesa_format format); +GLenum +_mesa_is_format_color_format(mesa_format format); + extern GLenum _mesa_get_format_color_encoding(mesa_format format); diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index 7416bb118..dc0386d23 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -345,7 +345,7 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) } } - if (minWidth != ~0) { + if (minWidth != ~0U) { fb->Width = minWidth; fb->Height = minHeight; } diff --git a/mesalib/src/mesa/main/genmipmap.c b/mesalib/src/mesa/main/genmipmap.c index 9d111cab2..9aef09019 100644 --- a/mesalib/src/mesa/main/genmipmap.c +++ b/mesalib/src/mesa/main/genmipmap.c @@ -36,21 +36,20 @@ #include "mtypes.h" #include "teximage.h" #include "texobj.h" - +#include "hash.h" /** - * Generate all the mipmap levels below the base level. - * Note: this GL function would be more useful if one could specify a - * cube face, a set of array slices, etc. + * Implements glGenerateMipmap and glGenerateTextureMipmap. + * Generates all the mipmap levels below the base level. */ -void GLAPIENTRY -_mesa_GenerateMipmap(GLenum target) +void +_mesa_generate_texture_mipmap(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + bool dsa) { struct gl_texture_image *srcImage; - struct gl_texture_object *texObj; GLboolean error; - - GET_CURRENT_CONTEXT(ctx); + const char *suffix = dsa ? "Texture" : ""; FLUSH_VERTICES(ctx, 0); @@ -83,13 +82,11 @@ _mesa_GenerateMipmap(GLenum target) } if (error) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target=%s)", - _mesa_lookup_enum_by_nr(target)); + _mesa_error(ctx, GL_INVALID_ENUM, "glGenerate%sMipmap(target=%s)", + suffix, _mesa_lookup_enum_by_nr(target)); return; } - texObj = _mesa_get_current_tex_object(ctx, target); - if (texObj->BaseLevel >= texObj->MaxLevel) { /* nothing to do */ return; @@ -98,17 +95,17 @@ _mesa_GenerateMipmap(GLenum target) if (texObj->Target == GL_TEXTURE_CUBE_MAP && !_mesa_cube_complete(texObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGenerateMipmap(incomplete cube map)"); + "glGenerate%sMipmap(incomplete cube map)", suffix); return; } _mesa_lock_texture(ctx, texObj); - srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); + srcImage = _mesa_select_tex_image(texObj, target, texObj->BaseLevel); if (!srcImage) { _mesa_unlock_texture(ctx, texObj); _mesa_error(ctx, GL_INVALID_OPERATION, - "glGenerateMipmap(zero size base image)"); + "glGenerate%sMipmap(zero size base image)", suffix); return; } @@ -117,19 +114,53 @@ _mesa_GenerateMipmap(GLenum target) _mesa_is_stencil_format(srcImage->InternalFormat)) { _mesa_unlock_texture(ctx, texObj); _mesa_error(ctx, GL_INVALID_OPERATION, - "glGenerateMipmap(invalid internal format)"); + "glGenerate%sMipmap(invalid internal format)", suffix); return; } if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; - for (face = 0; face < 6; face++) - ctx->Driver.GenerateMipmap(ctx, - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, - texObj); + for (face = 0; face < 6; face++) { + ctx->Driver.GenerateMipmap(ctx, + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face, texObj); + } } else { ctx->Driver.GenerateMipmap(ctx, target, texObj); } _mesa_unlock_texture(ctx, texObj); } + +/** + * Generate all the mipmap levels below the base level. + * Note: this GL function would be more useful if one could specify a + * cube face, a set of array slices, etc. + */ +void GLAPIENTRY +_mesa_GenerateMipmap(GLenum target) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_generate_texture_mipmap(ctx, texObj, target, false); +} + +/** + * Generate all the mipmap levels below the base level. + */ +void GLAPIENTRY +_mesa_GenerateTextureMipmap(GLuint texture) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glGenerateTextureMipmap"); + if (!texObj) + return; + + _mesa_generate_texture_mipmap(ctx, texObj, texObj->Target, true); +} diff --git a/mesalib/src/mesa/main/genmipmap.h b/mesalib/src/mesa/main/genmipmap.h index d546a8d7b..f4ef85951 100644 --- a/mesalib/src/mesa/main/genmipmap.h +++ b/mesalib/src/mesa/main/genmipmap.h @@ -28,9 +28,15 @@ #include "glheader.h" +extern void +_mesa_generate_texture_mipmap(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + bool dsa); extern void GLAPIENTRY _mesa_GenerateMipmap(GLenum target); +extern void GLAPIENTRY +_mesa_GenerateTextureMipmap(GLuint texture); #endif /* GENMIPMAP_H */ diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 6091efc7f..3f9d74516 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -392,6 +392,7 @@ EXTRA_EXT2(ARB_transform_feedback3, ARB_gpu_shader5); EXTRA_EXT(INTEL_performance_query); EXTRA_EXT(ARB_explicit_uniform_location); EXTRA_EXT(ARB_clip_control); +EXTRA_EXT(EXT_polygon_offset_clamp); static const int extra_ARB_color_buffer_float_or_glcore[] = { diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index 09a61acc1..41cb2c17b 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -343,6 +343,7 @@ descriptor=[ # GL_ARB_ES3_compatibility [ "MAX_ELEMENT_INDEX", "CONTEXT_INT64(Const.MaxElementIndex), extra_ARB_ES3_compatibility_api_es3"], + [ "PRIMITIVE_RESTART_FIXED_INDEX", "CONTEXT_BOOL(Array.PrimitiveRestartFixedIndex), extra_ARB_ES3_compatibility_api_es3" ], # GL_ARB_fragment_shader [ "MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents), extra_ARB_fragment_shader" ], @@ -403,6 +404,11 @@ descriptor=[ [ "TEXTURE_EXTERNAL_OES", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_OES_EGL_image_external" ], ]}, +{ "apis": ["GL", "GL_CORE", "GLES3"], "params": [ +# GL_ARB_sampler_objects / GL 3.3 / GLES 3.0 + [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ], +]}, + # Remaining enums are only in OpenGL { "apis": ["GL", "GL_CORE"], "params": [ [ "ACCUM_RED_BITS", "BUFFER_INT(Visual.accumRedBits), NO_EXTRA" ], @@ -695,10 +701,6 @@ descriptor=[ [ "SAMPLE_MASK", "CONTEXT_BOOL(Multisample.SampleMask), extra_ARB_texture_multisample" ], [ "MAX_SAMPLE_MASK_WORDS", "CONST(1), extra_ARB_texture_multisample" ], - -# GL_ARB_sampler_objects / GL 3.3 - [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ], - # GL 3.0 [ "CONTEXT_FLAGS", "CONTEXT_INT(Const.ContextFlags), extra_version_30" ], @@ -811,6 +813,9 @@ descriptor=[ [ "VIEWPORT_BOUNDS_RANGE", "CONTEXT_FLOAT2(Const.ViewportBounds), extra_ARB_viewport_array" ], [ "LAYER_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ], [ "VIEWPORT_INDEX_PROVOKING_VERTEX", "CONTEXT_ENUM(Light.ProvokingVertex), extra_ARB_viewport_array" ], + +# GL_EXT_polygon_offset_clamp + [ "POLYGON_OFFSET_CLAMP_EXT", "CONTEXT_FLOAT(Polygon.OffsetClamp), extra_EXT_polygon_offset_clamp" ], ]} ] diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 00478f989..4e05229cf 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -27,7 +27,205 @@ #include "context.h" #include "glformats.h" +#include "formats.h" +#include "enums.h" + +enum { + ZERO = 4, + ONE = 5 +}; + +enum { + IDX_LUMINANCE = 0, + IDX_ALPHA, + IDX_INTENSITY, + IDX_LUMINANCE_ALPHA, + IDX_RGB, + IDX_RGBA, + IDX_RED, + IDX_GREEN, + IDX_BLUE, + IDX_BGR, + IDX_BGRA, + IDX_ABGR, + IDX_RG, + MAX_IDX +}; + +#define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) +#define MAP2(x,y) MAP4(x, y, ZERO, ZERO) +#define MAP3(x,y,z) MAP4(x, y, z, ZERO) +#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } + +static const struct { + GLubyte format_idx; + GLubyte to_rgba[6]; + GLubyte from_rgba[6]; +} mappings[MAX_IDX] = +{ + { + IDX_LUMINANCE, + MAP4(0,0,0,ONE), + MAP1(0) + }, + + { + IDX_ALPHA, + MAP4(ZERO, ZERO, ZERO, 0), + MAP1(3) + }, + + { + IDX_INTENSITY, + MAP4(0, 0, 0, 0), + MAP1(0), + }, + + { + IDX_LUMINANCE_ALPHA, + MAP4(0,0,0,1), + MAP2(0,3) + }, + + { + IDX_RGB, + MAP4(0,1,2,ONE), + MAP3(0,1,2) + }, + + { + IDX_RGBA, + MAP4(0,1,2,3), + MAP4(0,1,2,3), + }, + + { + IDX_RED, + MAP4(0, ZERO, ZERO, ONE), + MAP1(0), + }, + + { + IDX_GREEN, + MAP4(ZERO, 0, ZERO, ONE), + MAP1(1), + }, + + { + IDX_BLUE, + MAP4(ZERO, ZERO, 0, ONE), + MAP1(2), + }, + + { + IDX_BGR, + MAP4(2,1,0,ONE), + MAP3(2,1,0) + }, + + { + IDX_BGRA, + MAP4(2,1,0,3), + MAP4(2,1,0,3) + }, + + { + IDX_ABGR, + MAP4(3,2,1,0), + MAP4(3,2,1,0) + }, + + { + IDX_RG, + MAP4(0, 1, ZERO, ONE), + MAP2(0, 1) + }, +}; + +/** + * Convert a GL image format enum to an IDX_* value (see above). + */ +static int +get_map_idx(GLenum value) +{ + switch (value) { + 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 %s", + _mesa_lookup_enum_by_nr(value)); + return 0; + } +} +/** + * When promoting texture formats (see below) we need to compute the + * mapping of dest components back to source components. + * This function does that. + * \param inFormat the incoming format of the texture + * \param outFormat the final texture format + * \return map[6] a full 6-component map + */ +void +_mesa_compute_component_mapping(GLenum inFormat, GLenum outFormat, GLubyte *map) +{ + const int inFmt = get_map_idx(inFormat); + const int outFmt = get_map_idx(outFormat); + const GLubyte *in2rgba = mappings[inFmt].to_rgba; + const GLubyte *rgba2out = mappings[outFmt].from_rgba; + int i; + + for (i = 0; i < 4; i++) + map[i] = in2rgba[rgba2out[i]]; + + map[ZERO] = ZERO; + map[ONE] = ONE; + +#if 0 + printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", + inFormat, _mesa_lookup_enum_by_nr(inFormat), + outFormat, _mesa_lookup_enum_by_nr(outFormat), + map[0], + map[1], + map[2], + map[3], + map[4], + map[5]); +#endif +} /** * \return GL_TRUE if type is packed pixel type, GL_FALSE otherwise. @@ -93,6 +291,7 @@ _mesa_sizeof_type(GLenum type) case GL_DOUBLE: return sizeof(GLdouble); case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: return sizeof(GLhalfARB); case GL_FIXED: return sizeof(GLfixed); @@ -125,6 +324,7 @@ _mesa_sizeof_packed_type(GLenum type) case GL_INT: return sizeof(GLint); case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: return sizeof(GLhalfARB); case GL_FLOAT: return sizeof(GLfloat); @@ -241,6 +441,7 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) case GL_FLOAT: return comps * sizeof(GLfloat); case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: return comps * sizeof(GLhalfARB); case GL_UNSIGNED_BYTE_3_3_2: case GL_UNSIGNED_BYTE_2_3_3_REV: @@ -258,18 +459,29 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) return -1; /* error */ case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) + return sizeof(GLushort); + else + return -1; case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + if (format == GL_RGBA || format == GL_BGRA || format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) return sizeof(GLushort); else return -1; case GL_UNSIGNED_INT_8_8_8_8: case GL_UNSIGNED_INT_8_8_8_8_REV: + if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT || + format == GL_RGB) + return sizeof(GLuint); + else + return -1; case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: - if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT || + if (format == GL_RGBA || format == GL_BGRA || format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT || format == GL_RGB) return sizeof(GLuint); @@ -1403,12 +1615,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: case GL_UNSIGNED_INT_8_8_8_8: case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT) { @@ -1418,6 +1626,20 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, ctx->Extensions.ARB_texture_rgb10_a2ui) { break; /* OK */ } + return GL_INVALID_OPERATION; + + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_RGBA || + format == GL_BGRA) { + break; /* OK */ + } + if ((format == GL_RGBA_INTEGER_EXT || format == GL_BGRA_INTEGER_EXT) && + ctx->Extensions.ARB_texture_rgb10_a2ui) { + break; /* OK */ + } if (type == GL_UNSIGNED_INT_2_10_10_10_REV && format == GL_RGB && ctx->API == API_OPENGLES2) { break; /* OK by GL_EXT_texture_type_2_10_10_10_REV */ @@ -1448,6 +1670,18 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, } return GL_NO_ERROR; + case GL_HALF_FLOAT_OES: + switch (format) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE: + case GL_ALPHA: + return GL_NO_ERROR; + default: + return GL_INVALID_OPERATION; + } + default: ; /* fall-through */ } @@ -1561,7 +1795,6 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_RGBA: case GL_BGRA: - case GL_ABGR_EXT: switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: @@ -1584,6 +1817,25 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, return GL_INVALID_ENUM; } + case GL_ABGR_EXT: + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_HALF_FLOAT: + return GL_NO_ERROR; + default: + return GL_INVALID_ENUM; + } + case GL_YCBCR_MESA: if (!ctx->Extensions.MESA_ycbcr_texture) return GL_INVALID_ENUM; @@ -1782,7 +2034,8 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type, * \return error code, or GL_NO_ERROR. */ GLenum -_mesa_es3_error_check_format_and_type(GLenum format, GLenum type, +_mesa_es3_error_check_format_and_type(const struct gl_context *ctx, + GLenum format, GLenum type, GLenum internalFormat) { switch (format) { @@ -1847,11 +2100,17 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, case GL_RGBA16F: case GL_RGBA32F: break; + case GL_RGBA: + if (ctx->Extensions.OES_texture_float && internalFormat == format) + break; default: return GL_INVALID_OPERATION; } break; + case GL_HALF_FLOAT_OES: + if (ctx->Extensions.OES_texture_half_float && internalFormat == format) + break; default: return GL_INVALID_OPERATION; } @@ -1956,11 +2215,19 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, case GL_R11F_G11F_B10F: case GL_RGB9_E5: break; + case GL_RGB: + if (ctx->Extensions.OES_texture_float && internalFormat == format) + break; default: return GL_INVALID_OPERATION; } break; + case GL_HALF_FLOAT_OES: + if (!ctx->Extensions.OES_texture_half_float || internalFormat != format) + return GL_INVALID_OPERATION; + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: switch (internalFormat) { case GL_RGB: /* GL_EXT_texture_type_2_10_10_10_REV */ @@ -2200,10 +2467,289 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type, case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: - if (type != GL_UNSIGNED_BYTE || format != internalFormat) - return GL_INVALID_OPERATION; - break; + switch (type) { + case GL_FLOAT: + if (ctx->Extensions.OES_texture_float && internalFormat == format) + break; + case GL_HALF_FLOAT_OES: + if (ctx->Extensions.OES_texture_half_float && internalFormat == format) + break; + default: + if (type != GL_UNSIGNED_BYTE || format != internalFormat) + return GL_INVALID_OPERATION; + } } return GL_NO_ERROR; } + +static void +set_swizzle(uint8_t *swizzle, int x, int y, int z, int w) +{ + swizzle[MESA_FORMAT_SWIZZLE_X] = x; + swizzle[MESA_FORMAT_SWIZZLE_Y] = y; + swizzle[MESA_FORMAT_SWIZZLE_Z] = z; + swizzle[MESA_FORMAT_SWIZZLE_W] = w; +} + +static bool +get_swizzle_from_gl_format(GLenum format, uint8_t *swizzle) +{ + switch (format) { + case GL_RGBA: + case GL_RGBA_INTEGER_EXT: + set_swizzle(swizzle, 0, 1, 2, 3); + return true; + case GL_BGRA: + case GL_BGRA_INTEGER_EXT: + set_swizzle(swizzle, 2, 1, 0, 3); + return true; + case GL_ABGR_EXT: + set_swizzle(swizzle, 3, 2, 1, 0); + return true; + case GL_RGB: + case GL_RGB_INTEGER_EXT: + set_swizzle(swizzle, 0, 1, 2, 5); + return true; + case GL_BGR: + case GL_BGR_INTEGER_EXT: + set_swizzle(swizzle, 2, 1, 0, 5); + return true; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + set_swizzle(swizzle, 0, 0, 0, 1); + return true; + case GL_RG: + case GL_RG_INTEGER: + set_swizzle(swizzle, 0, 1, 4, 5); + return true; + case GL_RED: + case GL_RED_INTEGER_EXT: + set_swizzle(swizzle, 0, 4, 4, 5); + return true; + case GL_GREEN: + case GL_GREEN_INTEGER_EXT: + set_swizzle(swizzle, 4, 0, 4, 5); + return true; + case GL_BLUE: + case GL_BLUE_INTEGER_EXT: + set_swizzle(swizzle, 4, 4, 0, 5); + return true; + case GL_ALPHA: + case GL_ALPHA_INTEGER_EXT: + set_swizzle(swizzle, 4, 4, 4, 0); + return true; + case GL_LUMINANCE: + case GL_LUMINANCE_INTEGER_EXT: + set_swizzle(swizzle, 0, 0, 0, 5); + return true; + case GL_INTENSITY: + set_swizzle(swizzle, 0, 0, 0, 0); + return true; + default: + return false; + } +} + +/** +* Take an OpenGL format (GL_RGB, GL_RGBA, etc), OpenGL data type (GL_INT, +* GL_FOAT, etc) and return a matching mesa_array_format or a mesa_format +* otherwise (for non-array formats). +* +* This function will typically be used to compute a mesa format from a GL type +* so we can then call _mesa_format_convert. This function does +* not consider byte swapping, so it returns types assuming that no byte +* swapping is involved. If byte swapping is involved then clients are supposed +* to handle that on their side before calling _mesa_format_convert. +* +* This function returns an uint32_t that can pack a mesa_format or a +* mesa_array_format. Clients must check the mesa array format bit +* (MESA_ARRAY_FORMAT_BIT) on the return value to know if the returned +* format is a mesa_array_format or a mesa_format. +*/ +uint32_t +_mesa_format_from_format_and_type(GLenum format, GLenum type) +{ + mesa_array_format array_format; + + bool is_array_format = true; + uint8_t swizzle[4]; + bool normalized = false, is_float = false, is_signed = false; + int num_channels = 0, type_size = 0; + + /* Extract array format type information from the OpenGL data type */ + switch (type) { + case GL_UNSIGNED_BYTE: + type_size = 1; + break; + case GL_BYTE: + type_size = 1; + is_signed = true; + break; + case GL_UNSIGNED_SHORT: + type_size = 2; + break; + case GL_SHORT: + type_size = 2; + is_signed = true; + break; + case GL_UNSIGNED_INT: + type_size = 4; + break; + case GL_INT: + type_size = 4; + is_signed = true; + break; + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + type_size = 2; + is_signed = true; + is_float = true; + break; + case GL_FLOAT: + type_size = 4; + is_signed = true; + is_float = true; + break; + default: + is_array_format = false; + break; + } + + /* Extract array format swizzle information from the OpenGL format */ + if (is_array_format) + is_array_format = get_swizzle_from_gl_format(format, swizzle); + + /* If this is an array format type after checking data type and format, + * create the array format + */ + if (is_array_format) { + normalized = !_mesa_is_enum_format_integer(format); + num_channels = _mesa_components_in_format(format); + + array_format = + MESA_ARRAY_FORMAT(type_size, is_signed, is_float, + normalized, num_channels, + swizzle[0], swizzle[1], swizzle[2], swizzle[3]); + + if (!_mesa_little_endian()) + array_format = _mesa_array_format_flip_channels(array_format); + + return array_format; + } + + /* Otherwise this is not an array format, so return the mesa_format + * matching the OpenGL format and data type + */ + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + if (format == GL_RGB) + return MESA_FORMAT_B5G6R5_UNORM; + else if (format == GL_BGR) + return MESA_FORMAT_R5G6B5_UNORM; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + if (format == GL_RGB) + return MESA_FORMAT_R5G6B5_UNORM; + else if (format == GL_BGR) + return MESA_FORMAT_B5G6R5_UNORM; + break; + case GL_UNSIGNED_SHORT_4_4_4_4: + if (format == GL_RGBA) + return MESA_FORMAT_A4B4G4R4_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_A4R4G4B4_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_R4G4B4A4_UNORM; + break; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if (format == GL_RGBA) + return MESA_FORMAT_R4G4B4A4_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_B4G4R4A4_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_A4B4G4R4_UNORM; + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + if (format == GL_RGBA) + return MESA_FORMAT_A1B5G5R5_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_A1R5G5B5_UNORM; + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + if (format == GL_RGBA) + return MESA_FORMAT_R5G5B5A1_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_B5G5R5A1_UNORM; + break; + case GL_UNSIGNED_BYTE_3_3_2: + if (format == GL_RGB) + return MESA_FORMAT_B2G3R3_UNORM; + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + if (format == GL_RGB) + return MESA_FORMAT_R3G3B2_UNORM; + break; + case GL_UNSIGNED_INT_5_9_9_9_REV: + if (format == GL_RGB) + return MESA_FORMAT_R9G9B9E5_FLOAT; + break; + case GL_UNSIGNED_INT_10_10_10_2: + if (format == GL_RGBA) + return MESA_FORMAT_A2B10G10R10_UNORM; + else if (format == GL_RGBA_INTEGER) + return MESA_FORMAT_A2B10G10R10_UINT; + else if (format == GL_BGRA) + return MESA_FORMAT_A2R10G10B10_UNORM; + else if (format == GL_BGRA_INTEGER) + return MESA_FORMAT_A2R10G10B10_UINT; + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_RGB) + return MESA_FORMAT_R10G10B10X2_UNORM; + if (format == GL_RGBA) + return MESA_FORMAT_R10G10B10A2_UNORM; + else if (format == GL_RGBA_INTEGER) + return MESA_FORMAT_R10G10B10A2_UINT; + else if (format == GL_BGRA) + return MESA_FORMAT_B10G10R10A2_UNORM; + else if (format == GL_BGRA_INTEGER) + return MESA_FORMAT_B10G10R10A2_UINT; + break; + case GL_UNSIGNED_INT_8_8_8_8: + if (format == GL_RGBA) + return MESA_FORMAT_A8B8G8R8_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_A8R8G8B8_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_R8G8B8A8_UNORM; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + if (format == GL_RGBA) + return MESA_FORMAT_R8G8B8A8_UNORM; + else if (format == GL_BGRA) + return MESA_FORMAT_B8G8R8A8_UNORM; + else if (format == GL_ABGR_EXT) + return MESA_FORMAT_A8B8G8R8_UNORM; + break; + case GL_UNSIGNED_SHORT_8_8_MESA: + if (format == GL_YCBCR_MESA) + return MESA_FORMAT_YCBCR; + break; + case GL_UNSIGNED_SHORT_8_8_REV_MESA: + if (format == GL_YCBCR_MESA) + return MESA_FORMAT_YCBCR_REV; + break; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + if (format == GL_RGB) + return MESA_FORMAT_R11G11B10_FLOAT; + default: + break; + } + + /* If we got here it means that we could not find a Mesa format that + * matches the GL format/type provided. We may need to add a new Mesa + * format in that case. + */ + unreachable("Unsupported format"); +} diff --git a/mesalib/src/mesa/main/glformats.h b/mesalib/src/mesa/main/glformats.h index 7b0321570..e1ecd64d5 100644 --- a/mesalib/src/mesa/main/glformats.h +++ b/mesalib/src/mesa/main/glformats.h @@ -35,6 +35,9 @@ extern "C" { #endif +extern void +_mesa_compute_component_mapping(GLenum inFormat, GLenum outFormat, GLubyte *map); + extern GLboolean _mesa_type_is_packed(GLenum type); @@ -122,9 +125,12 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type, unsigned dimensions); extern GLenum -_mesa_es3_error_check_format_and_type(GLenum format, GLenum type, +_mesa_es3_error_check_format_and_type(const struct gl_context *ctx, + GLenum format, GLenum type, GLenum internalFormat); +extern uint32_t +_mesa_format_from_format_and_type(GLenum format, GLenum type); #ifdef __cplusplus } diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c index a8c796b9a..1a152ec34 100644 --- a/mesalib/src/mesa/main/hash.c +++ b/mesalib/src/mesa/main/hash.c @@ -277,7 +277,7 @@ _mesa_HashInsert_unlocked(struct _mesa_HashTable *table, GLuint key, void *data) if (entry) { entry->data = data; } else { - _mesa_hash_table_insert_with_hash(table->ht, hash, uint_key(key), data); + _mesa_hash_table_insert_pre_hashed(table->ht, hash, uint_key(key), data); } } } diff --git a/mesalib/src/mesa/main/image.c b/mesalib/src/mesa/main/image.c index 4ea5f04c9..e97b006e0 100644 --- a/mesalib/src/mesa/main/image.c +++ b/mesalib/src/mesa/main/image.c @@ -41,36 +41,45 @@ /** - * Flip the order of the 2 bytes in each word in the given array. + * Flip the order of the 2 bytes in each word in the given array (src) and + * store the result in another array (dst). For in-place byte-swapping this + * function can be called with the same array for src and dst. * - * \param p array. + * \param dst the array where byte-swapped data will be stored. + * \param src the array with the source data we want to byte-swap. * \param n number of words. */ void -_mesa_swap2( GLushort *p, GLuint n ) +_mesa_swap2_copy( GLushort *dst, GLushort *src, GLuint n ) { GLuint i; for (i = 0; i < n; i++) { - p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00); + dst[i] = (src[i] >> 8) | ((src[i] << 8) & 0xff00); } } /* - * Flip the order of the 4 bytes in each word in the given array. + * Flip the order of the 4 bytes in each word in the given array (src) and + * store the result in another array (dst). For in-place byte-swapping this + * function can be called with the same array for src and dst. + * + * \param dst the array where byte-swapped data will be stored. + * \param src the array with the source data we want to byte-swap. + * \param n number of words. */ void -_mesa_swap4( GLuint *p, GLuint n ) +_mesa_swap4_copy( GLuint *dst, GLuint *src, GLuint n ) { GLuint i, a, b; for (i = 0; i < n; i++) { - b = p[i]; + b = src[i]; a = (b >> 24) | ((b >> 8) & 0xff00) | ((b << 8) & 0xff0000) | ((b << 24) & 0xff000000); - p[i] = a; + dst[i] = a; } } @@ -142,7 +151,7 @@ _mesa_image_offset( GLuint dimensions, assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX); bytes_per_row = alignment - * CEILING( comp_per_pixel*pixels_per_row, 8*alignment ); + * DIV_ROUND_UP( comp_per_pixel*pixels_per_row, 8*alignment ); bytes_per_image = bytes_per_row * rows_per_image; @@ -852,19 +861,21 @@ clip_left_or_bottom(GLint *srcX0, GLint *srcX1, */ GLboolean _mesa_clip_blit(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1) { const GLint srcXmin = 0; - const GLint srcXmax = ctx->ReadBuffer->Width; + const GLint srcXmax = readFb->Width; const GLint srcYmin = 0; - const GLint srcYmax = ctx->ReadBuffer->Height; + const GLint srcYmax = readFb->Height; /* these include scissor bounds */ - const GLint dstXmin = ctx->DrawBuffer->_Xmin; - const GLint dstXmax = ctx->DrawBuffer->_Xmax; - const GLint dstYmin = ctx->DrawBuffer->_Ymin; - const GLint dstYmax = ctx->DrawBuffer->_Ymax; + const GLint dstXmin = drawFb->_Xmin; + const GLint dstXmax = drawFb->_Xmax; + const GLint dstYmin = drawFb->_Ymin; + const GLint dstYmax = drawFb->_Ymax; /* printf("PreClipX: src: %d .. %d dst: %d .. %d\n", diff --git a/mesalib/src/mesa/main/image.h b/mesalib/src/mesa/main/image.h index abd84bf2f..501586bfb 100644 --- a/mesalib/src/mesa/main/image.h +++ b/mesalib/src/mesa/main/image.h @@ -28,15 +28,29 @@ #include "glheader.h" +#include "compiler.h" struct gl_context; struct gl_pixelstore_attrib; +struct gl_framebuffer; extern void -_mesa_swap2( GLushort *p, GLuint n ); +_mesa_swap2_copy(GLushort *dst, GLushort *src, GLuint n); extern void -_mesa_swap4( GLuint *p, GLuint n ); +_mesa_swap4_copy(GLuint *dst, GLuint *src, GLuint n); + +static inline void +_mesa_swap2(GLushort *p, GLuint n) +{ + _mesa_swap2_copy(p, p, n); +} + +static inline void +_mesa_swap4(GLuint *p, GLuint n) +{ + _mesa_swap4_copy(p, p, n); +} extern GLintptr _mesa_image_offset( GLuint dimensions, @@ -127,6 +141,8 @@ _mesa_clip_to_region(GLint xmin, GLint ymin, extern GLboolean _mesa_clip_blit(struct gl_context *ctx, + const struct gl_framebuffer *readFb, + const struct gl_framebuffer *drawFb, GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1); diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c index 6945c2f62..4f5a2d11f 100644 --- a/mesalib/src/mesa/main/imports.c +++ b/mesalib/src/mesa/main/imports.c @@ -94,7 +94,7 @@ _mesa_align_malloc(size_t bytes, unsigned long alignment) ASSERT( alignment > 0 ); - ptr = malloc(bytes + alignment + sizeof(void *)); + ptr = (uintptr_t)malloc(bytes + alignment + sizeof(void *)); if (!ptr) return NULL; @@ -143,7 +143,7 @@ _mesa_align_calloc(size_t bytes, unsigned long alignment) ASSERT( alignment > 0 ); - ptr = calloc(1, bytes + alignment + sizeof(void *)); + ptr = (uintptr_t)calloc(1, bytes + alignment + sizeof(void *)); if (!ptr) return NULL; diff --git a/mesalib/src/mesa/main/light.c b/mesalib/src/mesa/main/light.c index d8ef8f258..e483b826e 100644 --- a/mesalib/src/mesa/main/light.c +++ b/mesalib/src/mesa/main/light.c @@ -30,7 +30,7 @@ #include "enums.h" #include "light.h" #include "macros.h" -#include "simple_list.h" +#include "util/simple_list.h" #include "mtypes.h" #include "math/m_matrix.h" @@ -1207,12 +1207,3 @@ _mesa_init_lighting( struct gl_context *ctx ) ctx->_ForceEyeCoords = GL_FALSE; ctx->_ModelViewInvScale = 1.0; } - - -/** - * Deallocate malloc'd lighting state attached to given context. - */ -void -_mesa_free_lighting_data( struct gl_context *ctx ) -{ -} diff --git a/mesalib/src/mesa/main/light.h b/mesalib/src/mesa/main/light.h index c6fba2ea3..d009aa175 100644 --- a/mesalib/src/mesa/main/light.h +++ b/mesalib/src/mesa/main/light.h @@ -102,8 +102,6 @@ extern void _mesa_update_color_material( struct gl_context *ctx, extern void _mesa_init_lighting( struct gl_context *ctx ); -extern void _mesa_free_lighting_data( struct gl_context *ctx ); - extern void _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ); #endif diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h index cd5f2d6f2..cf1f0e9c9 100644 --- a/mesalib/src/mesa/main/macros.h +++ b/mesalib/src/mesa/main/macros.h @@ -31,6 +31,7 @@ #ifndef MACROS_H #define MACROS_H +#include "util/u_math.h" #include "imports.h" @@ -274,14 +275,6 @@ COPY_4UBV(GLubyte dst[4], const GLubyte src[4]) #endif } -/** Copy a 4-element float vector */ -static inline void -COPY_4FV(GLfloat dst[4], const GLfloat src[4]) -{ - /* memcpy seems to be most efficient */ - memcpy(dst, src, sizeof(GLfloat) * 4); -} - /** Copy \p SZ elements into a 4-element vector */ #define COPY_SZ_4V(DST, SZ, SRC) \ do { \ @@ -373,15 +366,6 @@ do { \ (DST)[3] *= S; \ } while (0) -/** Assignment */ -#define ASSIGN_4V( V, V0, V1, V2, V3 ) \ -do { \ - V[0] = V0; \ - V[1] = V1; \ - V[2] = V2; \ - V[3] = V3; \ -} while(0) - /*@}*/ @@ -808,7 +792,7 @@ DIFFERENT_SIGNS(GLfloat x, GLfloat y) /** Compute ceiling of integer quotient of A divided by B. */ -#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) +#define DIV_ROUND_UP( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) /** casts to silence warnings with some compilers */ diff --git a/mesalib/src/mesa/main/matrix.c b/mesalib/src/mesa/main/matrix.c index 99a501321..0539caa47 100644 --- a/mesalib/src/mesa/main/matrix.c +++ b/mesalib/src/mesa/main/matrix.c @@ -690,7 +690,7 @@ free_matrix_stack( struct gl_matrix_stack *stack ) */ void _mesa_init_matrix( struct gl_context * ctx ) { - GLint i; + GLuint i; /* Initialize matrix stacks */ init_matrix_stack(&ctx->ModelviewMatrixStack, MAX_MODELVIEW_STACK_DEPTH, @@ -701,7 +701,7 @@ void _mesa_init_matrix( struct gl_context * ctx ) init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH, _NEW_TEXTURE_MATRIX); for (i = 0; i < Elements(ctx->ProgramMatrixStack); i++) - init_matrix_stack(&ctx->ProgramMatrixStack[i], + init_matrix_stack(&ctx->ProgramMatrixStack[i], MAX_PROGRAM_MATRIX_STACK_DEPTH, _NEW_TRACK_MATRIX); ctx->CurrentStack = &ctx->ModelviewMatrixStack; @@ -720,7 +720,7 @@ void _mesa_init_matrix( struct gl_context * ctx ) */ void _mesa_free_matrix_data( struct gl_context *ctx ) { - GLint i; + GLuint i; free_matrix_stack(&ctx->ModelviewMatrixStack); free_matrix_stack(&ctx->ProjectionMatrixStack); diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index fdaa68282..75a12cd16 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1901,7 +1901,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, GLboolean success = GL_TRUE; /* get src image parameters */ - srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + srcImage = _mesa_select_tex_image(texObj, target, level); ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; @@ -2093,10 +2093,10 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target, GLint border; GLboolean nextLevel; GLuint temp_dst_row_stride, temp_dst_img_stride; /* in bytes */ - GLuint i; + GLint i; /* get src image parameters */ - srcImage = _mesa_select_tex_image(ctx, texObj, target, level); + srcImage = _mesa_select_tex_image(texObj, target, level); ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; @@ -2193,7 +2193,7 @@ _mesa_generate_mipmap(struct gl_context *ctx, GLenum target, GLint maxLevel; ASSERT(texObj); - srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); + srcImage = _mesa_select_tex_image(texObj, target, texObj->BaseLevel); ASSERT(srcImage); maxLevel = _mesa_max_texture_levels(ctx, texObj->Target) - 1; diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index b95dfb9f7..6e9977309 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -41,7 +41,7 @@ #include "main/config.h" #include "glapi/glapi.h" #include "math/m_matrix.h" /* GLmatrix */ -#include "main/simple_list.h" /* struct simple_node */ +#include "util/simple_list.h" /* struct simple_node */ #include "main/formats.h" /* MESA_FORMAT_COUNT */ @@ -1004,6 +1004,7 @@ struct gl_polygon_attrib GLenum CullFaceMode; /**< Culling mode GL_FRONT or GL_BACK */ GLfloat OffsetFactor; /**< Polygon offset factor, from user */ GLfloat OffsetUnits; /**< Polygon offset units, from user */ + GLfloat OffsetClamp; /**< Polygon offset clamp, from user */ GLboolean OffsetPoint; /**< Offset in GL_POINT mode */ GLboolean OffsetLine; /**< Offset in GL_LINE mode */ GLboolean OffsetFill; /**< Offset in GL_FILL mode */ @@ -1220,6 +1221,8 @@ struct gl_texture_object GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ GLboolean Immutable; /**< GL_ARB_texture_storage */ + GLboolean _IsFloat; /**< GL_OES_float_texture */ + GLboolean _IsHalfFloat; /**< GL_OES_half_float_texture */ GLuint MinLevel; /**< GL_ARB_texture_view */ GLuint MinLayer; /**< GL_ARB_texture_view */ @@ -3031,6 +3034,8 @@ struct gl_shader_compiler_options GLboolean OptimizeForAOS; struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */ + + struct nir_shader_compiler_options *NirOptions; }; @@ -3069,6 +3074,9 @@ struct gl_query_state /** GL_ARB_timer_query */ struct gl_query_object *TimeElapsed; + /** GL_ARB_pipeline_statistics_query */ + struct gl_query_object *pipeline_stats[MAX_PIPELINE_STATISTICS]; + GLenum CondRenderMode; }; @@ -3455,6 +3463,17 @@ struct gl_constants GLuint Timestamp; GLuint PrimitivesGenerated; GLuint PrimitivesWritten; + GLuint VerticesSubmitted; + GLuint PrimitivesSubmitted; + GLuint VsInvocations; + GLuint TessPatches; + GLuint TessInvocations; + GLuint GsInvocations; + GLuint GsPrimitives; + GLuint FsInvocations; + GLuint ComputeInvocations; + GLuint ClInPrimitives; + GLuint ClOutPrimitives; } QueryCounterBits; GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ @@ -3745,18 +3764,21 @@ struct gl_extensions GLboolean ARB_explicit_uniform_location; GLboolean ARB_geometry_shader4; GLboolean ARB_gpu_shader5; + GLboolean ARB_gpu_shader_fp64; GLboolean ARB_half_float_vertex; GLboolean ARB_instanced_arrays; GLboolean ARB_internalformat_query; GLboolean ARB_map_buffer_range; GLboolean ARB_occlusion_query; GLboolean ARB_occlusion_query2; + GLboolean ARB_pipeline_statistics_query; GLboolean ARB_point_sprite; GLboolean ARB_sample_shading; GLboolean ARB_seamless_cube_map; GLboolean ARB_shader_atomic_counters; GLboolean ARB_shader_bit_encoding; GLboolean ARB_shader_image_load_store; + GLboolean ARB_shader_precision; GLboolean ARB_shader_stencil_export; GLboolean ARB_shader_texture_lod; GLboolean ARB_shading_language_packing; @@ -3764,6 +3786,7 @@ struct gl_extensions GLboolean ARB_shadow; GLboolean ARB_stencil_texturing; GLboolean ARB_sync; + GLboolean ARB_tessellation_shader; GLboolean ARB_texture_border_clamp; GLboolean ARB_texture_buffer_object; GLboolean ARB_texture_buffer_object_rgb32; @@ -3810,6 +3833,7 @@ struct gl_extensions GLboolean EXT_packed_float; GLboolean EXT_pixel_buffer_object; GLboolean EXT_point_parameters; + GLboolean EXT_polygon_offset_clamp; GLboolean EXT_provoking_vertex; GLboolean EXT_shader_integer_mix; GLboolean EXT_stencil_two_side; @@ -3832,6 +3856,7 @@ struct gl_extensions GLboolean OES_standard_derivatives; /* vendor extensions */ GLboolean AMD_performance_monitor; + GLboolean AMD_pinned_memory; GLboolean AMD_seamless_cubemap_per_texture; GLboolean AMD_vertex_shader_layer; GLboolean AMD_vertex_shader_viewport_index; @@ -3858,6 +3883,10 @@ struct gl_extensions GLboolean OES_draw_texture; GLboolean OES_depth_texture_cube_map; GLboolean OES_EGL_image_external; + GLboolean OES_texture_float; + GLboolean OES_texture_float_linear; + GLboolean OES_texture_half_float; + GLboolean OES_texture_half_float_linear; GLboolean OES_compressed_ETC1_RGB8_texture; GLboolean extension_sentinel; /** The extension string */ @@ -4369,6 +4398,12 @@ struct gl_context struct gl_buffer_object *AtomicBuffer; /** + * Object currently associated w/ the GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD + * target. + */ + struct gl_buffer_object *ExternalVirtualMemoryBuffer; + + /** * Array of atomic counter buffer binding points. */ struct gl_atomic_buffer_binding @@ -4477,9 +4512,6 @@ extern int MESA_DEBUG_FLAGS; # define MESA_VERBOSE 0 # define MESA_DEBUG_FLAGS 0 # define MESA_FUNCTION "a function" -# ifndef NDEBUG -# define NDEBUG -# endif #endif diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c index 1f3fa0c15..b696de9f2 100644 --- a/mesalib/src/mesa/main/multisample.c +++ b/mesalib/src/mesa/main/multisample.c @@ -150,6 +150,16 @@ GLenum _mesa_check_sample_count(struct gl_context *ctx, GLenum target, GLenum internalFormat, GLsizei samples) { + /* Section 4.4 (Framebuffer objects) of the OpenGL 3.0 specification says: + * + * "If internalformat is a signed or unsigned integer format and samples + * is greater than zero, then the error INVALID_OPERATION is generated." + */ + if (_mesa_is_gles3(ctx) && _mesa_is_enum_format_integer(internalFormat)) { + return GL_INVALID_OPERATION; + } + + /* If ARB_internalformat_query is supported, then treat its highest * returned sample count as the absolute maximum for this format; it is * allowed to exceed MAX_SAMPLES. diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index 649a74cce..2111a7604 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -53,8 +53,8 @@ #include "pixeltransfer.h" #include "imports.h" #include "glformats.h" -#include "../../gallium/auxiliary/util/u_format_rgb9e5.h" -#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" +#include "format_utils.h" +#include "format_pack.h" /** @@ -98,7 +98,8 @@ void _mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32], const struct gl_pixelstore_attrib *unpacking ) { - GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap(32, 32, pattern, unpacking); + GLubyte *ptrn = (GLubyte *) _mesa_unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, + GL_BITMAP, pattern, unpacking); if (ptrn) { /* Convert pattern from GLubytes to GLuints and handle big/little * endian differences @@ -142,108 +143,6 @@ _mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest, /* - * Unpack bitmap data. Resulting data will be in most-significant-bit-first - * order with row alignment = 1 byte. - */ -GLvoid * -_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels, - const struct gl_pixelstore_attrib *packing ) -{ - GLint bytes, row, width_in_bytes; - GLubyte *buffer, *dst; - - if (!pixels) - return NULL; - - /* Alloc dest storage */ - bytes = ((width + 7) / 8 * height); - buffer = malloc( bytes ); - if (!buffer) - return NULL; - - width_in_bytes = CEILING( width, 8 ); - dst = buffer; - for (row = 0; row < height; row++) { - const GLubyte *src = (const GLubyte *) - _mesa_image_address2d(packing, pixels, width, height, - GL_COLOR_INDEX, GL_BITMAP, row, 0); - if (!src) { - free(buffer); - return NULL; - } - - if ((packing->SkipPixels & 7) == 0) { - memcpy( dst, src, width_in_bytes ); - if (packing->LsbFirst) { - flip_bytes( dst, width_in_bytes ); - } - } - else { - /* handling SkipPixels is a bit tricky (no pun intended!) */ - GLint i; - if (packing->LsbFirst) { - GLubyte srcMask = 1 << (packing->SkipPixels & 0x7); - GLubyte dstMask = 128; - const GLubyte *s = src; - GLubyte *d = dst; - *d = 0; - for (i = 0; i < width; i++) { - if (*s & srcMask) { - *d |= dstMask; - } - if (srcMask == 128) { - srcMask = 1; - s++; - } - else { - srcMask = srcMask << 1; - } - if (dstMask == 1) { - dstMask = 128; - d++; - *d = 0; - } - else { - dstMask = dstMask >> 1; - } - } - } - else { - GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7); - GLubyte dstMask = 128; - const GLubyte *s = src; - GLubyte *d = dst; - *d = 0; - for (i = 0; i < width; i++) { - if (*s & srcMask) { - *d |= dstMask; - } - if (srcMask == 1) { - srcMask = 128; - s++; - } - else { - srcMask = srcMask >> 1; - } - if (dstMask == 1) { - dstMask = 128; - d++; - *d = 0; - } - else { - dstMask = dstMask >> 1; - } - } - } - } - dst += width_in_bytes; - } - - return buffer; -} - - -/* * Pack bitmap data. */ void @@ -256,7 +155,7 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, if (!source) return; - width_in_bytes = CEILING( width, 8 ); + width_in_bytes = DIV_ROUND_UP( width, 8 ); src = source; for (row = 0; row < height; row++) { GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest, @@ -333,2361 +232,6 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, } -/** - * Get indexes of color components for a basic color format, such as - * GL_RGBA, GL_RED, GL_LUMINANCE_ALPHA, etc. Return -1 for indexes - * that do not apply. - */ -static void -get_component_indexes(GLenum format, - GLint *redIndex, - GLint *greenIndex, - GLint *blueIndex, - GLint *alphaIndex, - GLint *luminanceIndex, - GLint *intensityIndex) -{ - *redIndex = -1; - *greenIndex = -1; - *blueIndex = -1; - *alphaIndex = -1; - *luminanceIndex = -1; - *intensityIndex = -1; - - switch (format) { - case GL_LUMINANCE: - case GL_LUMINANCE_INTEGER_EXT: - *luminanceIndex = 0; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - *luminanceIndex = 0; - *alphaIndex = 1; - break; - case GL_INTENSITY: - *intensityIndex = 0; - break; - case GL_RED: - case GL_RED_INTEGER_EXT: - *redIndex = 0; - break; - case GL_GREEN: - case GL_GREEN_INTEGER_EXT: - *greenIndex = 0; - break; - case GL_BLUE: - case GL_BLUE_INTEGER_EXT: - *blueIndex = 0; - break; - case GL_ALPHA: - case GL_ALPHA_INTEGER_EXT: - *alphaIndex = 0; - break; - case GL_RG: - case GL_RG_INTEGER: - *redIndex = 0; - *greenIndex = 1; - break; - case GL_RGB: - case GL_RGB_INTEGER_EXT: - *redIndex = 0; - *greenIndex = 1; - *blueIndex = 2; - break; - case GL_BGR: - case GL_BGR_INTEGER_EXT: - *blueIndex = 0; - *greenIndex = 1; - *redIndex = 2; - break; - case GL_RGBA: - case GL_RGBA_INTEGER_EXT: - *redIndex = 0; - *greenIndex = 1; - *blueIndex = 2; - *alphaIndex = 3; - break; - case GL_BGRA: - case GL_BGRA_INTEGER: - *redIndex = 2; - *greenIndex = 1; - *blueIndex = 0; - *alphaIndex = 3; - break; - case GL_ABGR_EXT: - *redIndex = 3; - *greenIndex = 2; - *blueIndex = 1; - *alphaIndex = 0; - break; - default: - assert(0 && "bad format in get_component_indexes()"); - } -} - - - -/** - * For small integer types, return the min and max possible values. - * Used for clamping floats to unscaled integer types. - * \return GL_TRUE if type is handled, GL_FALSE otherwise. - */ -static GLboolean -get_type_min_max(GLenum type, GLfloat *min, GLfloat *max) -{ - switch (type) { - case GL_BYTE: - *min = -128.0; - *max = 127.0; - return GL_TRUE; - case GL_UNSIGNED_BYTE: - *min = 0.0; - *max = 255.0; - return GL_TRUE; - case GL_SHORT: - *min = -32768.0; - *max = 32767.0; - return GL_TRUE; - case GL_UNSIGNED_SHORT: - *min = 0.0; - *max = 65535.0; - return GL_TRUE; - default: - return GL_FALSE; - } -} - -/* Customization of unsigned integer packing. - */ -#define SRC_TYPE GLuint - -#define DST_TYPE GLuint -#define SRC_CONVERT(x) (x) -#define FN_NAME pack_uint_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLint -#define SRC_CONVERT(x) MIN2(x, 0x7fffffff) -#define FN_NAME pack_int_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLushort -#define SRC_CONVERT(x) MIN2(x, 0xffff) -#define FN_NAME pack_ushort_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLshort -#define SRC_CONVERT(x) CLAMP((int)x, -32768, 32767) -#define FN_NAME pack_short_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLubyte -#define SRC_CONVERT(x) MIN2(x, 0xff) -#define FN_NAME pack_ubyte_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLbyte -#define SRC_CONVERT(x) CLAMP((int)x, -128, 127) -#define FN_NAME pack_byte_from_uint_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#undef SRC_TYPE - -static void -_pack_rgba_span_from_uints_problem(struct gl_context *ctx, - GLenum dstFormat, GLenum dstType) -{ - _mesa_problem(ctx, - "Unsupported type (%s) / format (%s) " - "in _mesa_pack_rgba_span_from_uints", - _mesa_lookup_enum_by_nr(dstType), - _mesa_lookup_enum_by_nr(dstFormat)); -} - -void -_mesa_pack_rgba_span_from_uints(struct gl_context *ctx, GLuint n, GLuint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr) -{ - GLuint i; - - switch(dstType) { - case GL_UNSIGNED_INT: - pack_uint_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_INT: - pack_int_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_SHORT: - pack_ushort_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_SHORT: - pack_short_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_BYTE: - pack_ubyte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_BYTE: - pack_byte_from_uint_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_BYTE_3_3_2: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 7) << 5) - | (MIN2(rgba[i][GCOMP], 7) << 2) - | (MIN2(rgba[i][BCOMP], 3) ); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 7) ) - | (MIN2(rgba[i][GCOMP], 7) << 3) - | (MIN2(rgba[i][BCOMP], 3) << 6); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 31) << 11) - | (MIN2(rgba[i][GCOMP], 63) << 5) - | (MIN2(rgba[i][BCOMP], 31) ); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 31) ) - | (MIN2(rgba[i][GCOMP], 63) << 5) - | (MIN2(rgba[i][BCOMP], 31) << 11); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 15) << 12) - | (MIN2(rgba[i][GCOMP], 15) << 8) - | (MIN2(rgba[i][BCOMP], 15) << 4) - | (MIN2(rgba[i][ACOMP], 15) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 15) << 12) - | (MIN2(rgba[i][GCOMP], 15) << 8) - | (MIN2(rgba[i][RCOMP], 15) << 4) - | (MIN2(rgba[i][ACOMP], 15) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 15) << 12) - | (MIN2(rgba[i][BCOMP], 15) << 8) - | (MIN2(rgba[i][GCOMP], 15) << 4) - | (MIN2(rgba[i][RCOMP], 15) ); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 15) ) - | (MIN2(rgba[i][GCOMP], 15) << 4) - | (MIN2(rgba[i][BCOMP], 15) << 8) - | (MIN2(rgba[i][ACOMP], 15) << 12); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 15) ) - | (MIN2(rgba[i][GCOMP], 15) << 4) - | (MIN2(rgba[i][RCOMP], 15) << 8) - | (MIN2(rgba[i][ACOMP], 15) << 12); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 15) ) - | (MIN2(rgba[i][BCOMP], 15) << 4) - | (MIN2(rgba[i][GCOMP], 15) << 8) - | (MIN2(rgba[i][RCOMP], 15) << 12); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 31) << 11) - | (MIN2(rgba[i][GCOMP], 31) << 6) - | (MIN2(rgba[i][BCOMP], 31) << 1) - | (MIN2(rgba[i][ACOMP], 1) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 31) << 11) - | (MIN2(rgba[i][GCOMP], 31) << 6) - | (MIN2(rgba[i][RCOMP], 31) << 1) - | (MIN2(rgba[i][ACOMP], 1) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 31) << 11) - | (MIN2(rgba[i][BCOMP], 31) << 6) - | (MIN2(rgba[i][GCOMP], 31) << 1) - | (MIN2(rgba[i][RCOMP], 1) ); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 31) ) - | (MIN2(rgba[i][GCOMP], 31) << 5) - | (MIN2(rgba[i][BCOMP], 31) << 10) - | (MIN2(rgba[i][ACOMP], 1) << 15); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 31) ) - | (MIN2(rgba[i][GCOMP], 31) << 5) - | (MIN2(rgba[i][RCOMP], 31) << 10) - | (MIN2(rgba[i][ACOMP], 1) << 15); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 31) ) - | (MIN2(rgba[i][BCOMP], 31) << 5) - | (MIN2(rgba[i][GCOMP], 31) << 10) - | (MIN2(rgba[i][RCOMP], 1) << 15); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 255) << 24) - | (MIN2(rgba[i][GCOMP], 255) << 16) - | (MIN2(rgba[i][BCOMP], 255) << 8) - | (MIN2(rgba[i][ACOMP], 255) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 255) << 24) - | (MIN2(rgba[i][GCOMP], 255) << 16) - | (MIN2(rgba[i][RCOMP], 255) << 8) - | (MIN2(rgba[i][ACOMP], 255) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 255) << 24) - | (MIN2(rgba[i][BCOMP], 255) << 16) - | (MIN2(rgba[i][GCOMP], 255) << 8) - | (MIN2(rgba[i][RCOMP], 255) ); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 255) ) - | (MIN2(rgba[i][GCOMP], 255) << 8) - | (MIN2(rgba[i][BCOMP], 255) << 16) - | (MIN2(rgba[i][ACOMP], 255) << 24); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 255) ) - | (MIN2(rgba[i][GCOMP], 255) << 8) - | (MIN2(rgba[i][RCOMP], 255) << 16) - | (MIN2(rgba[i][ACOMP], 255) << 24); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 255) ) - | (MIN2(rgba[i][BCOMP], 255) << 8) - | (MIN2(rgba[i][GCOMP], 255) << 16) - | (MIN2(rgba[i][RCOMP], 255) << 24); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 1023) << 22) - | (MIN2(rgba[i][GCOMP], 1023) << 12) - | (MIN2(rgba[i][BCOMP], 1023) << 2) - | (MIN2(rgba[i][ACOMP], 3) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 1023) << 22) - | (MIN2(rgba[i][GCOMP], 1023) << 12) - | (MIN2(rgba[i][RCOMP], 1023) << 2) - | (MIN2(rgba[i][ACOMP], 3) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 1023) << 22) - | (MIN2(rgba[i][BCOMP], 1023) << 12) - | (MIN2(rgba[i][GCOMP], 1023) << 2) - | (MIN2(rgba[i][RCOMP], 3) ); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][RCOMP], 1023) ) - | (MIN2(rgba[i][GCOMP], 1023) << 10) - | (MIN2(rgba[i][BCOMP], 1023) << 20) - | (MIN2(rgba[i][ACOMP], 3) << 30); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][BCOMP], 1023) ) - | (MIN2(rgba[i][GCOMP], 1023) << 10) - | (MIN2(rgba[i][RCOMP], 1023) << 20) - | (MIN2(rgba[i][ACOMP], 3) << 30); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (MIN2(rgba[i][ACOMP], 1023) ) - | (MIN2(rgba[i][BCOMP], 1023) << 10) - | (MIN2(rgba[i][GCOMP], 1023) << 20) - | (MIN2(rgba[i][RCOMP], 3) << 30); - } - } else { - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - } - break; - default: - _pack_rgba_span_from_uints_problem(ctx, dstFormat, dstType); - return; - } -} - - -/* Customization of signed integer packing. - */ -#define SRC_TYPE GLint - -#define DST_TYPE GLuint -#define SRC_CONVERT(x) MAX2(x, 0) -#define FN_NAME pack_uint_from_int_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLushort -#define SRC_CONVERT(x) MAX2(x, 0) -#define FN_NAME pack_ushort_from_int_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLshort -#define SRC_CONVERT(x) CLAMP(x, -0x8000, 0x7fff) -#define FN_NAME pack_short_from_int_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLubyte -#define SRC_CONVERT(x) MAX2(x, 0) -#define FN_NAME pack_ubyte_from_int_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#define DST_TYPE GLbyte -#define SRC_CONVERT(x) CLAMP(x, -0x80, 0x7f) -#define FN_NAME pack_byte_from_int_rgba -#include "pack_tmp.h" -#undef DST_TYPE -#undef SRC_CONVERT -#undef FN_NAME - -#undef SRC_TYPE - -static void -_pack_rgba_span_from_ints_problem(struct gl_context *ctx, - GLenum dstFormat, GLenum dstType) -{ - _mesa_problem(ctx, - "Unsupported type (%s) / format (%s) " - "in _mesa_pack_rgba_span_from_ints", - _mesa_lookup_enum_by_nr(dstType), - _mesa_lookup_enum_by_nr(dstFormat)); -} - -void -_mesa_pack_rgba_span_from_ints(struct gl_context *ctx, GLuint n, GLint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr) -{ - GLuint i; - - switch(dstType) { - case GL_UNSIGNED_INT: - pack_uint_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_INT: - /* No conversion necessary. */ - pack_uint_from_uint_rgba(ctx, dstAddr, dstFormat, (GLuint (*)[4]) rgba, n); - break; - case GL_UNSIGNED_SHORT: - pack_ushort_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_SHORT: - pack_short_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_BYTE: - pack_ubyte_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_BYTE: - pack_byte_from_int_rgba(ctx, dstAddr, dstFormat, rgba, n); - break; - case GL_UNSIGNED_BYTE_3_3_2: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 7) << 5) - | (CLAMP(rgba[i][GCOMP], 0, 7) << 2) - | (CLAMP(rgba[i][BCOMP], 0, 3) ); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 7) ) - | (CLAMP(rgba[i][GCOMP], 0, 7) << 3) - | (CLAMP(rgba[i][BCOMP], 0, 3) << 6); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31) << 11) - | (CLAMP(rgba[i][GCOMP], 0, 63) << 5) - | (CLAMP(rgba[i][BCOMP], 0, 31) ); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if ((dstFormat == GL_RGB) || (dstFormat == GL_RGB_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31) ) - | (CLAMP(rgba[i][GCOMP], 0, 63) << 5) - | (CLAMP(rgba[i][BCOMP], 0, 31) << 11); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 15) << 12) - | (CLAMP(rgba[i][GCOMP], 0, 15) << 8) - | (CLAMP(rgba[i][BCOMP], 0, 15) << 4) - | (CLAMP(rgba[i][ACOMP], 0, 15) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 15) << 12) - | (CLAMP(rgba[i][GCOMP], 0, 15) << 8) - | (CLAMP(rgba[i][RCOMP], 0, 15) << 4) - | (CLAMP(rgba[i][ACOMP], 0, 15) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 15) << 12) - | (CLAMP(rgba[i][BCOMP], 0, 15) << 8) - | (CLAMP(rgba[i][GCOMP], 0, 15) << 4) - | (CLAMP(rgba[i][RCOMP], 0, 15) ); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 15) ) - | (CLAMP(rgba[i][GCOMP], 0, 15) << 4) - | (CLAMP(rgba[i][BCOMP], 0, 15) << 8) - | (CLAMP(rgba[i][ACOMP], 0, 15) << 12); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 15) ) - | (CLAMP(rgba[i][GCOMP], 0, 15) << 4) - | (CLAMP(rgba[i][RCOMP], 0, 15) << 8) - | (CLAMP(rgba[i][ACOMP], 0, 15) << 12); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 15) ) - | (CLAMP(rgba[i][BCOMP], 0, 15) << 4) - | (CLAMP(rgba[i][GCOMP], 0, 15) << 8) - | (CLAMP(rgba[i][RCOMP], 0, 15) << 12); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31) << 11) - | (CLAMP(rgba[i][GCOMP], 0, 31) << 6) - | (CLAMP(rgba[i][BCOMP], 0, 31) << 1) - | (CLAMP(rgba[i][ACOMP], 0, 1) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 31) << 11) - | (CLAMP(rgba[i][GCOMP], 0, 31) << 6) - | (CLAMP(rgba[i][RCOMP], 0, 31) << 1) - | (CLAMP(rgba[i][ACOMP], 0, 1) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 31) << 11) - | (CLAMP(rgba[i][BCOMP], 0, 31) << 6) - | (CLAMP(rgba[i][GCOMP], 0, 31) << 1) - | (CLAMP(rgba[i][RCOMP], 0, 1) ); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 31) ) - | (CLAMP(rgba[i][GCOMP], 0, 31) << 5) - | (CLAMP(rgba[i][BCOMP], 0, 31) << 10) - | (CLAMP(rgba[i][ACOMP], 0, 1) << 15); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 31) ) - | (CLAMP(rgba[i][GCOMP], 0, 31) << 5) - | (CLAMP(rgba[i][RCOMP], 0, 31) << 10) - | (CLAMP(rgba[i][ACOMP], 0, 1) << 15); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 31) ) - | (CLAMP(rgba[i][BCOMP], 0, 31) << 5) - | (CLAMP(rgba[i][GCOMP], 0, 31) << 10) - | (CLAMP(rgba[i][RCOMP], 0, 1) << 15); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 255) << 24) - | (CLAMP(rgba[i][GCOMP], 0, 255) << 16) - | (CLAMP(rgba[i][BCOMP], 0, 255) << 8) - | (CLAMP(rgba[i][ACOMP], 0, 255) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 255) << 24) - | (CLAMP(rgba[i][GCOMP], 0, 255) << 16) - | (CLAMP(rgba[i][RCOMP], 0, 255) << 8) - | (CLAMP(rgba[i][ACOMP], 0, 255) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 255) << 24) - | (CLAMP(rgba[i][BCOMP], 0, 255) << 16) - | (CLAMP(rgba[i][GCOMP], 0, 255) << 8) - | (CLAMP(rgba[i][RCOMP], 0, 255) ); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 255) ) - | (CLAMP(rgba[i][GCOMP], 0, 255) << 8) - | (CLAMP(rgba[i][BCOMP], 0, 255) << 16) - | (CLAMP(rgba[i][ACOMP], 0, 255) << 24); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 255) ) - | (CLAMP(rgba[i][GCOMP], 0, 255) << 8) - | (CLAMP(rgba[i][RCOMP], 0, 255) << 16) - | (CLAMP(rgba[i][ACOMP], 0, 255) << 24); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 255) ) - | (CLAMP(rgba[i][BCOMP], 0, 255) << 8) - | (CLAMP(rgba[i][GCOMP], 0, 255) << 16) - | (CLAMP(rgba[i][RCOMP], 0, 255) << 24); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 1023) << 22) - | (CLAMP(rgba[i][GCOMP], 0, 1023) << 12) - | (CLAMP(rgba[i][BCOMP], 0, 1023) << 2) - | (CLAMP(rgba[i][ACOMP], 0, 3) ); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 1023) << 22) - | (CLAMP(rgba[i][GCOMP], 0, 1023) << 12) - | (CLAMP(rgba[i][RCOMP], 0, 1023) << 2) - | (CLAMP(rgba[i][ACOMP], 0, 3) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 1023) << 22) - | (CLAMP(rgba[i][BCOMP], 0, 1023) << 12) - | (CLAMP(rgba[i][GCOMP], 0, 1023) << 2) - | (CLAMP(rgba[i][RCOMP], 0, 3) ); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if ((dstFormat == GL_RGBA) || (dstFormat == GL_RGBA_INTEGER_EXT)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][RCOMP], 0, 1023) ) - | (CLAMP(rgba[i][GCOMP], 0, 1023) << 10) - | (CLAMP(rgba[i][BCOMP], 0, 1023) << 20) - | (CLAMP(rgba[i][ACOMP], 0, 3) << 30); - } - } - else if ((dstFormat == GL_BGRA) || (dstFormat == GL_BGRA_INTEGER)) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][BCOMP], 0, 1023) ) - | (CLAMP(rgba[i][GCOMP], 0, 1023) << 10) - | (CLAMP(rgba[i][RCOMP], 0, 1023) << 20) - | (CLAMP(rgba[i][ACOMP], 0, 3) << 30); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (CLAMP(rgba[i][ACOMP], 0, 1023) ) - | (CLAMP(rgba[i][BCOMP], 0, 1023) << 10) - | (CLAMP(rgba[i][GCOMP], 0, 1023) << 20) - | (CLAMP(rgba[i][RCOMP], 0, 3) << 30); - } - } else { - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - } - break; - default: - _pack_rgba_span_from_ints_problem(ctx, dstFormat, dstType); - return; - } -} - - -/** - * Used to pack an array [][4] of RGBA float colors as specified - * by the dstFormat, dstType and dstPacking. Used by glReadPixels. - * Historically, the RGBA values were in [0,1] and rescaled to fit - * into GLubytes, etc. But with new integer formats, the RGBA values - * may have any value and we don't always rescale when converting to - * integers. - * - * Note: the rgba values will be modified by this function when any pixel - * transfer ops are enabled. - */ -void -_mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps) -{ - GLfloat *luminance; - const GLint comps = _mesa_components_in_format(dstFormat); - const GLboolean intDstFormat = _mesa_is_enum_format_integer(dstFormat); - GLuint i; - - if (dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_LUMINANCE_INTEGER_EXT || - dstFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT) { - luminance = malloc(n * sizeof(GLfloat)); - if (!luminance) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); - return; - } - } - else { - luminance = NULL; - } - - /* EXT_texture_integer specifies no transfer ops on integer - * types in the resolved issues section. Just set them to 0 - * for integer surfaces. - */ - if (intDstFormat) - transferOps = 0; - - if (transferOps) { - _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); - } - - /* - * Component clamping (besides clamping to [0,1] in - * _mesa_apply_rgba_transfer_ops()). - */ - if (intDstFormat) { - /* clamping to dest type's min/max values */ - GLfloat min, max; - if (get_type_min_max(dstType, &min, &max)) { - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], min, max); - rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], min, max); - rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], min, max); - rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], min, max); - } - } - } - else if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) { - /* compute luminance values */ - if (transferOps & IMAGE_CLAMP_BIT) { - for (i = 0; i < n; i++) { - GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; - luminance[i] = CLAMP(sum, 0.0F, 1.0F); - } - } - else { - for (i = 0; i < n; i++) { - luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; - } - } - } - - /* - * Pack/store the pixels. Ugh! Lots of cases!!! - */ - switch (dstType) { - case GL_UNSIGNED_BYTE: - { - GLubyte *dst = (GLubyte *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UBYTE(rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UBYTE(rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UBYTE(luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_UBYTE(luminance[i]); - dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]); - dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]); - dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]); - dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][ACOMP]); - dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][BCOMP]); - dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][GCOMP]); - dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][RCOMP]); - } - break; - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLubyte) rgba[i][RCOMP]; - } - break; - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLubyte) rgba[i][GCOMP]; - } - break; - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLubyte) rgba[i][BCOMP]; - } - break; - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLubyte) rgba[i][ACOMP]; - } - break; - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLubyte) rgba[i][RCOMP]; - dst[i*2+1] = (GLubyte) rgba[i][GCOMP]; - } - break; - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLubyte) rgba[i][RCOMP]; - dst[i*3+1] = (GLubyte) rgba[i][GCOMP]; - dst[i*3+2] = (GLubyte) rgba[i][BCOMP]; - } - break; - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLubyte) rgba[i][RCOMP]; - dst[i*4+1] = (GLubyte) rgba[i][GCOMP]; - dst[i*4+2] = (GLubyte) rgba[i][BCOMP]; - dst[i*4+3] = (GLubyte) rgba[i][ACOMP]; - } - break; - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLubyte) rgba[i][BCOMP]; - dst[i*3+1] = (GLubyte) rgba[i][GCOMP]; - dst[i*3+2] = (GLubyte) rgba[i][RCOMP]; - } - break; - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLubyte) rgba[i][BCOMP]; - dst[i*4+1] = (GLubyte) rgba[i][GCOMP]; - dst[i*4+2] = (GLubyte) rgba[i][RCOMP]; - dst[i*4+3] = (GLubyte) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLubyte) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = (GLubyte) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLubyte) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_BYTE: - { - GLbyte *dst = (GLbyte *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_BYTE_TEX(rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_BYTE_TEX(rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_BYTE_TEX(luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_BYTE_TEX(luminance[i]); - dst[i*2+1] = FLOAT_TO_BYTE_TEX(rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - dst[i*2+1] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - dst[i*3+1] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_BYTE_TEX(rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - dst[i*4+1] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_BYTE_TEX(rgba[i][BCOMP]); - dst[i*4+3] = FLOAT_TO_BYTE_TEX(rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_BYTE_TEX(rgba[i][BCOMP]); - dst[i*3+1] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_BYTE_TEX(rgba[i][BCOMP]); - dst[i*4+1] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - dst[i*4+3] = FLOAT_TO_BYTE_TEX(rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_BYTE_TEX(rgba[i][ACOMP]); - dst[i*4+1] = FLOAT_TO_BYTE_TEX(rgba[i][BCOMP]); - dst[i*4+2] = FLOAT_TO_BYTE_TEX(rgba[i][GCOMP]); - dst[i*4+3] = FLOAT_TO_BYTE_TEX(rgba[i][RCOMP]); - } - break; - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLbyte) rgba[i][RCOMP]; - } - break; - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLbyte) rgba[i][GCOMP]; - } - break; - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLbyte) rgba[i][BCOMP]; - } - break; - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLbyte) rgba[i][ACOMP]; - } - break; - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLbyte) rgba[i][RCOMP]; - dst[i*2+1] = (GLbyte) rgba[i][GCOMP]; - } - break; - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLbyte) rgba[i][RCOMP]; - dst[i*3+1] = (GLbyte) rgba[i][GCOMP]; - dst[i*3+2] = (GLbyte) rgba[i][BCOMP]; - } - break; - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLbyte) rgba[i][RCOMP]; - dst[i*4+1] = (GLbyte) rgba[i][GCOMP]; - dst[i*4+2] = (GLbyte) rgba[i][BCOMP]; - dst[i*4+3] = (GLbyte) rgba[i][ACOMP]; - } - break; - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLbyte) rgba[i][BCOMP]; - dst[i*3+1] = (GLbyte) rgba[i][GCOMP]; - dst[i*3+2] = (GLbyte) rgba[i][RCOMP]; - } - break; - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLbyte) rgba[i][BCOMP]; - dst[i*4+1] = (GLbyte) rgba[i][GCOMP]; - dst[i*4+2] = (GLbyte) rgba[i][RCOMP]; - dst[i*4+3] = (GLbyte) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLbyte) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = (GLbyte) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLbyte) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_UNSIGNED_SHORT: - { - GLushort *dst = (GLushort *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - CLAMPED_FLOAT_TO_USHORT(dst[i], rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - UNCLAMPED_FLOAT_TO_USHORT(dst[i], luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - UNCLAMPED_FLOAT_TO_USHORT(dst[i*2+0], luminance[i]); - CLAMPED_FLOAT_TO_USHORT(dst[i*2+1], rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - CLAMPED_FLOAT_TO_USHORT(dst[i*2+0], rgba[i][RCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*2+1], rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][RCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][RCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][BCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - CLAMPED_FLOAT_TO_USHORT(dst[i*3+0], rgba[i][BCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*3+1], rgba[i][GCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*3+2], rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][BCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][GCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][RCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - CLAMPED_FLOAT_TO_USHORT(dst[i*4+0], rgba[i][ACOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+1], rgba[i][BCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+2], rgba[i][GCOMP]); - CLAMPED_FLOAT_TO_USHORT(dst[i*4+3], rgba[i][RCOMP]); - } - break; - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLushort) rgba[i][RCOMP]; - } - break; - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLushort) rgba[i][GCOMP]; - } - break; - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLushort) rgba[i][BCOMP]; - } - break; - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLushort) rgba[i][ACOMP]; - } - break; - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLushort) rgba[i][RCOMP]; - dst[i*2+1] = (GLushort) rgba[i][GCOMP]; - } - break; - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLushort) rgba[i][RCOMP]; - dst[i*3+1] = (GLushort) rgba[i][GCOMP]; - dst[i*3+2] = (GLushort) rgba[i][BCOMP]; - } - break; - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLushort) rgba[i][RCOMP]; - dst[i*4+1] = (GLushort) rgba[i][GCOMP]; - dst[i*4+2] = (GLushort) rgba[i][BCOMP]; - dst[i*4+3] = (GLushort) rgba[i][ACOMP]; - } - break; - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLushort) rgba[i][BCOMP]; - dst[i*3+1] = (GLushort) rgba[i][GCOMP]; - dst[i*3+2] = (GLushort) rgba[i][RCOMP]; - } - break; - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLushort) rgba[i][BCOMP]; - dst[i*4+1] = (GLushort) rgba[i][GCOMP]; - dst[i*4+2] = (GLushort) rgba[i][RCOMP]; - dst[i*4+3] = (GLushort) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLushort) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = (GLushort) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLushort) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_SHORT: - { - GLshort *dst = (GLshort *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_SHORT_TEX(rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_SHORT_TEX(rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_SHORT_TEX(luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_SHORT_TEX(luminance[i]); - dst[i*2+1] = FLOAT_TO_SHORT_TEX(rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - dst[i*2+1] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - dst[i*3+1] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_SHORT_TEX(rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - dst[i*4+1] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_SHORT_TEX(rgba[i][BCOMP]); - dst[i*4+3] = FLOAT_TO_SHORT_TEX(rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_SHORT_TEX(rgba[i][BCOMP]); - dst[i*3+1] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_SHORT_TEX(rgba[i][BCOMP]); - dst[i*4+1] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - dst[i*4+3] = FLOAT_TO_SHORT_TEX(rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_SHORT_TEX(rgba[i][ACOMP]); - dst[i*4+1] = FLOAT_TO_SHORT_TEX(rgba[i][BCOMP]); - dst[i*4+2] = FLOAT_TO_SHORT_TEX(rgba[i][GCOMP]); - dst[i*4+3] = FLOAT_TO_SHORT_TEX(rgba[i][RCOMP]); - } - break; - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLshort) rgba[i][RCOMP]; - } - break; - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLshort) rgba[i][GCOMP]; - } - break; - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLshort) rgba[i][BCOMP]; - } - break; - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLshort) rgba[i][ACOMP]; - } - break; - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLshort) rgba[i][RCOMP]; - dst[i*2+1] = (GLshort) rgba[i][GCOMP]; - } - break; - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLshort) rgba[i][RCOMP]; - dst[i*3+1] = (GLshort) rgba[i][GCOMP]; - dst[i*3+2] = (GLshort) rgba[i][BCOMP]; - } - break; - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLshort) rgba[i][RCOMP]; - dst[i*4+1] = (GLshort) rgba[i][GCOMP]; - dst[i*4+2] = (GLshort) rgba[i][BCOMP]; - dst[i*4+3] = (GLshort) rgba[i][ACOMP]; - } - break; - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLshort) rgba[i][BCOMP]; - dst[i*3+1] = (GLshort) rgba[i][GCOMP]; - dst[i*3+2] = (GLshort) rgba[i][RCOMP]; - } - break; - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLshort) rgba[i][BCOMP]; - dst[i*4+1] = (GLshort) rgba[i][GCOMP]; - dst[i*4+2] = (GLshort) rgba[i][RCOMP]; - dst[i*4+3] = (GLshort) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLshort) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = (GLshort) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLshort) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_UNSIGNED_INT: - { - GLuint *dst = (GLuint *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UINT(rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UINT(rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UINT(rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UINT(rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_UINT(luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_UINT(luminance[i]); - dst[i*2+1] = FLOAT_TO_UINT(rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_UINT(rgba[i][RCOMP]); - dst[i*2+1] = FLOAT_TO_UINT(rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_UINT(rgba[i][RCOMP]); - dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_UINT(rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_UINT(rgba[i][RCOMP]); - dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_UINT(rgba[i][BCOMP]); - dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_UINT(rgba[i][BCOMP]); - dst[i*3+1] = FLOAT_TO_UINT(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_UINT(rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_UINT(rgba[i][BCOMP]); - dst[i*4+1] = FLOAT_TO_UINT(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_UINT(rgba[i][RCOMP]); - dst[i*4+3] = FLOAT_TO_UINT(rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_UINT(rgba[i][ACOMP]); - dst[i*4+1] = FLOAT_TO_UINT(rgba[i][BCOMP]); - dst[i*4+2] = FLOAT_TO_UINT(rgba[i][GCOMP]); - dst[i*4+3] = FLOAT_TO_UINT(rgba[i][RCOMP]); - } - break; - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLuint) rgba[i][RCOMP]; - } - break; - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLuint) rgba[i][GCOMP]; - } - break; - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLuint) rgba[i][BCOMP]; - } - break; - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLuint) rgba[i][ACOMP]; - } - break; - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLuint) rgba[i][RCOMP]; - dst[i*2+1] = (GLuint) rgba[i][GCOMP]; - } - break; - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLuint) rgba[i][RCOMP]; - dst[i*3+1] = (GLuint) rgba[i][GCOMP]; - dst[i*3+2] = (GLuint) rgba[i][BCOMP]; - } - break; - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLuint) rgba[i][RCOMP]; - dst[i*4+1] = (GLuint) rgba[i][GCOMP]; - dst[i*4+2] = (GLuint) rgba[i][BCOMP]; - dst[i*4+3] = (GLuint) rgba[i][ACOMP]; - } - break; - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLuint) rgba[i][BCOMP]; - dst[i*3+1] = (GLuint) rgba[i][GCOMP]; - dst[i*3+2] = (GLuint) rgba[i][RCOMP]; - } - break; - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLuint) rgba[i][BCOMP]; - dst[i*4+1] = (GLuint) rgba[i][GCOMP]; - dst[i*4+2] = (GLuint) rgba[i][RCOMP]; - dst[i*4+3] = (GLuint) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLuint) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = (GLuint) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLuint) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_INT: - { - GLint *dst = (GLint *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_INT(rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_INT(rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_INT(rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_INT(rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = FLOAT_TO_INT(luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_INT(luminance[i]); - dst[i*2+1] = FLOAT_TO_INT(rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = FLOAT_TO_INT(rgba[i][RCOMP]); - dst[i*2+1] = FLOAT_TO_INT(rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_INT(rgba[i][RCOMP]); - dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_INT(rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_INT(rgba[i][RCOMP]); - dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_INT(rgba[i][BCOMP]); - dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = FLOAT_TO_INT(rgba[i][BCOMP]); - dst[i*3+1] = FLOAT_TO_INT(rgba[i][GCOMP]); - dst[i*3+2] = FLOAT_TO_INT(rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_INT(rgba[i][BCOMP]); - dst[i*4+1] = FLOAT_TO_INT(rgba[i][GCOMP]); - dst[i*4+2] = FLOAT_TO_INT(rgba[i][RCOMP]); - dst[i*4+3] = FLOAT_TO_INT(rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = FLOAT_TO_INT(rgba[i][ACOMP]); - dst[i*4+1] = FLOAT_TO_INT(rgba[i][BCOMP]); - dst[i*4+2] = FLOAT_TO_INT(rgba[i][GCOMP]); - dst[i*4+3] = FLOAT_TO_INT(rgba[i][RCOMP]); - } - break; - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLint) rgba[i][RCOMP]; - } - break; - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLint) rgba[i][GCOMP]; - } - break; - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLint) rgba[i][BCOMP]; - } - break; - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLint) rgba[i][ACOMP]; - } - break; - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLint) rgba[i][RCOMP]; - dst[i*2+1] = (GLint) rgba[i][GCOMP]; - } - break; - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLint) rgba[i][RCOMP]; - dst[i*3+1] = (GLint) rgba[i][GCOMP]; - dst[i*3+2] = (GLint) rgba[i][BCOMP]; - } - break; - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLint) rgba[i][RCOMP]; - dst[i*4+1] = (GLint) rgba[i][GCOMP]; - dst[i*4+2] = (GLint) rgba[i][BCOMP]; - dst[i*4+3] = (GLint) rgba[i][ACOMP]; - } - break; - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = (GLint) rgba[i][BCOMP]; - dst[i*3+1] = (GLint) rgba[i][GCOMP]; - dst[i*3+2] = (GLint) rgba[i][RCOMP]; - } - break; - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = (GLint) rgba[i][BCOMP]; - dst[i*4+1] = (GLint) rgba[i][GCOMP]; - dst[i*4+2] = (GLint) rgba[i][RCOMP]; - dst[i*4+3] = (GLint) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = (GLint) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = (GLint) rgba[i][ACOMP]; - } - break; - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = (GLint) (rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_FLOAT: - { - GLfloat *dst = (GLfloat *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = rgba[i][RCOMP]; - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = rgba[i][GCOMP]; - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = rgba[i][BCOMP]; - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = rgba[i][ACOMP]; - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = luminance[i]; - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = luminance[i]; - dst[i*2+1] = rgba[i][ACOMP]; - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = rgba[i][RCOMP]; - dst[i*2+1] = rgba[i][GCOMP]; - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = rgba[i][RCOMP]; - dst[i*3+1] = rgba[i][GCOMP]; - dst[i*3+2] = rgba[i][BCOMP]; - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = rgba[i][RCOMP]; - dst[i*4+1] = rgba[i][GCOMP]; - dst[i*4+2] = rgba[i][BCOMP]; - dst[i*4+3] = rgba[i][ACOMP]; - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = rgba[i][BCOMP]; - dst[i*3+1] = rgba[i][GCOMP]; - dst[i*3+2] = rgba[i][RCOMP]; - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = rgba[i][BCOMP]; - dst[i*4+1] = rgba[i][GCOMP]; - dst[i*4+2] = rgba[i][RCOMP]; - dst[i*4+3] = rgba[i][ACOMP]; - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = rgba[i][ACOMP]; - dst[i*4+1] = rgba[i][BCOMP]; - dst[i*4+2] = rgba[i][GCOMP]; - dst[i*4+3] = rgba[i][RCOMP]; - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_HALF_FLOAT_ARB: - { - GLhalfARB *dst = (GLhalfARB *) dstAddr; - switch (dstFormat) { - case GL_RED: - for (i=0;i<n;i++) - dst[i] = _mesa_float_to_half(rgba[i][RCOMP]); - break; - case GL_GREEN: - for (i=0;i<n;i++) - dst[i] = _mesa_float_to_half(rgba[i][GCOMP]); - break; - case GL_BLUE: - for (i=0;i<n;i++) - dst[i] = _mesa_float_to_half(rgba[i][BCOMP]); - break; - case GL_ALPHA: - for (i=0;i<n;i++) - dst[i] = _mesa_float_to_half(rgba[i][ACOMP]); - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) - dst[i] = _mesa_float_to_half(luminance[i]); - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - dst[i*2+0] = _mesa_float_to_half(luminance[i]); - dst[i*2+1] = _mesa_float_to_half(rgba[i][ACOMP]); - } - break; - case GL_RG: - for (i=0;i<n;i++) { - dst[i*2+0] = _mesa_float_to_half(rgba[i][RCOMP]); - dst[i*2+1] = _mesa_float_to_half(rgba[i][GCOMP]); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - dst[i*3+0] = _mesa_float_to_half(rgba[i][RCOMP]); - dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]); - dst[i*3+2] = _mesa_float_to_half(rgba[i][BCOMP]); - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - dst[i*4+0] = _mesa_float_to_half(rgba[i][RCOMP]); - dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]); - dst[i*4+2] = _mesa_float_to_half(rgba[i][BCOMP]); - dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]); - } - break; - case GL_BGR: - for (i=0;i<n;i++) { - dst[i*3+0] = _mesa_float_to_half(rgba[i][BCOMP]); - dst[i*3+1] = _mesa_float_to_half(rgba[i][GCOMP]); - dst[i*3+2] = _mesa_float_to_half(rgba[i][RCOMP]); - } - break; - case GL_BGRA: - for (i=0;i<n;i++) { - dst[i*4+0] = _mesa_float_to_half(rgba[i][BCOMP]); - dst[i*4+1] = _mesa_float_to_half(rgba[i][GCOMP]); - dst[i*4+2] = _mesa_float_to_half(rgba[i][RCOMP]); - dst[i*4+3] = _mesa_float_to_half(rgba[i][ACOMP]); - } - break; - case GL_ABGR_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = _mesa_float_to_half(rgba[i][ACOMP]); - dst[i*4+1] = _mesa_float_to_half(rgba[i][BCOMP]); - dst[i*4+2] = _mesa_float_to_half(rgba[i][GCOMP]); - dst[i*4+3] = _mesa_float_to_half(rgba[i][RCOMP]); - } - break; - default: - _mesa_problem(ctx, "bad format in _mesa_pack_rgba_span\n"); - } - } - break; - case GL_UNSIGNED_BYTE_3_3_2: - if (dstFormat == GL_RGB) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 7.0F) << 5) - | (F_TO_I(rgba[i][GCOMP] * 7.0F) << 2) - | (F_TO_I(rgba[i][BCOMP] * 3.0F) ); - } - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - if (dstFormat == GL_RGB) { - GLubyte *dst = (GLubyte *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 7.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 7.0F) << 3) - | (F_TO_I(rgba[i][BCOMP] * 3.0F) << 6); - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (dstFormat == GL_RGB) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) << 11) - | (F_TO_I(rgba[i][GCOMP] * 63.0F) << 5) - | (F_TO_I(rgba[i][BCOMP] * 31.0F) ); - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if (dstFormat == GL_RGB) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 63.0F) << 5) - | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 11); - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if (dstFormat == GL_RGBA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 15.0F) << 12) - | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 8) - | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 4) - | (F_TO_I(rgba[i][ACOMP] * 15.0F) ); - } - } - else if (dstFormat == GL_BGRA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 15.0F) << 12) - | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 8) - | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 4) - | (F_TO_I(rgba[i][ACOMP] * 15.0F) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12) - | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 8) - | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 4) - | (F_TO_I(rgba[i][RCOMP] * 15.0F) ); - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if (dstFormat == GL_RGBA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 15.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 4) - | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 8) - | (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12); - } - } - else if (dstFormat == GL_BGRA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 15.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 4) - | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 8) - | (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 15.0F) ) - | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 4) - | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 8) - | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 12); - } - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if (dstFormat == GL_RGBA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) << 11) - | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 6) - | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 1) - | (F_TO_I(rgba[i][ACOMP] * 1.0F) ); - } - } - else if (dstFormat == GL_BGRA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 31.0F) << 11) - | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 6) - | (F_TO_I(rgba[i][RCOMP] * 31.0F) << 1) - | (F_TO_I(rgba[i][ACOMP] * 1.0F) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 31.0F) << 11) - | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 6) - | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 1) - | (F_TO_I(rgba[i][RCOMP] * 1.0F) ); - } - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (dstFormat == GL_RGBA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 5) - | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 10) - | (F_TO_I(rgba[i][ACOMP] * 1.0F) << 15); - } - } - else if (dstFormat == GL_BGRA) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 31.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 5) - | (F_TO_I(rgba[i][RCOMP] * 31.0F) << 10) - | (F_TO_I(rgba[i][ACOMP] * 1.0F) << 15); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLushort *dst = (GLushort *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 31.0F) ) - | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 5) - | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 10) - | (F_TO_I(rgba[i][RCOMP] * 1.0F) << 15); - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if (dstFormat == GL_RGBA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 255.F) << 24) - | (F_TO_I(rgba[i][GCOMP] * 255.F) << 16) - | (F_TO_I(rgba[i][BCOMP] * 255.F) << 8) - | (F_TO_I(rgba[i][ACOMP] * 255.F) ); - } - } - else if (dstFormat == GL_BGRA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 255.F) << 24) - | (F_TO_I(rgba[i][GCOMP] * 255.F) << 16) - | (F_TO_I(rgba[i][RCOMP] * 255.F) << 8) - | (F_TO_I(rgba[i][ACOMP] * 255.F) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 255.F) << 24) - | (F_TO_I(rgba[i][BCOMP] * 255.F) << 16) - | (F_TO_I(rgba[i][GCOMP] * 255.F) << 8) - | (F_TO_I(rgba[i][RCOMP] * 255.F) ); - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (dstFormat == GL_RGBA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 255.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 8) - | (F_TO_I(rgba[i][BCOMP] * 255.0F) << 16) - | (F_TO_I(rgba[i][ACOMP] * 255.0F) << 24); - } - } - else if (dstFormat == GL_BGRA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 255.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 8) - | (F_TO_I(rgba[i][RCOMP] * 255.0F) << 16) - | (F_TO_I(rgba[i][ACOMP] * 255.0F) << 24); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 255.0F) ) - | (F_TO_I(rgba[i][BCOMP] * 255.0F) << 8) - | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 16) - | (F_TO_I(rgba[i][RCOMP] * 255.0F) << 24); - } - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if (dstFormat == GL_RGBA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 22) - | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 12) - | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 2) - | (F_TO_I(rgba[i][ACOMP] * 3.0F) ); - } - } - else if (dstFormat == GL_BGRA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 22) - | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 12) - | (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 2) - | (F_TO_I(rgba[i][ACOMP] * 3.0F) ); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 1023.0F) << 22) - | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 12) - | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 2) - | (F_TO_I(rgba[i][RCOMP] * 3.0F) ); - } - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (dstFormat == GL_RGBA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][RCOMP] * 1023.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 10) - | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 20) - | (F_TO_I(rgba[i][ACOMP] * 3.0F) << 30); - } - } - else if (dstFormat == GL_BGRA) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][BCOMP] * 1023.0F) ) - | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 10) - | (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 20) - | (F_TO_I(rgba[i][ACOMP] * 3.0F) << 30); - } - } - else if (dstFormat == GL_ABGR_EXT) { - GLuint *dst = (GLuint *) dstAddr; - for (i=0;i<n;i++) { - dst[i] = (F_TO_I(rgba[i][ACOMP] * 1023.0F) ) - | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 10) - | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 20) - | (F_TO_I(rgba[i][RCOMP] * 3.0F) << 30); - } - } - break; - case GL_UNSIGNED_INT_5_9_9_9_REV: - { - GLuint *dst = (GLuint *) dstAddr; - for (i = 0; i < n; i++) { - dst[i] = float3_to_rgb9e5(rgba[i]); - } - } - break; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - { - GLuint *dst = (GLuint *) dstAddr; - for (i = 0; i < n; i++) { - dst[i] = float3_to_r11g11b10f(rgba[i]); - } - } - break; - default: - _mesa_problem(ctx, "bad type in _mesa_pack_rgba_span_float"); - free(luminance); - return; - } - - if (dstPacking->SwapBytes) { - GLint swapSize = _mesa_sizeof_packed_type(dstType); - if (swapSize == 2) { - _mesa_swap2((GLushort *) dstAddr, n * comps); - } - else if (swapSize == 4) { - _mesa_swap4((GLuint *) dstAddr, n * comps); - } - } - - free(luminance); -} - - - #define SWAP2BYTE(VALUE) \ { \ GLubyte *bytes = (GLubyte *) &(VALUE); \ @@ -2724,6 +268,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[], srcType == GL_INT || srcType == GL_UNSIGNED_INT_24_8_EXT || srcType == GL_HALF_FLOAT_ARB || + srcType == GL_HALF_FLOAT_OES || srcType == GL_FLOAT || srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); @@ -2863,6 +408,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[], } break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLuint i; const GLhalfARB *s = (const GLhalfARB *) src; @@ -2921,743 +467,6 @@ extract_uint_indexes(GLuint n, GLuint indexes[], } -/** - * Return source/dest RGBA indexes for unpacking pixels. - */ -static void -get_component_mapping(GLenum format, - GLint *rSrc, - GLint *gSrc, - GLint *bSrc, - GLint *aSrc, - GLint *rDst, - GLint *gDst, - GLint *bDst, - GLint *aDst) -{ - switch (format) { - case GL_RED: - case GL_RED_INTEGER_EXT: - *rSrc = 0; - *gSrc = *bSrc = *aSrc = -1; - break; - case GL_GREEN: - case GL_GREEN_INTEGER_EXT: - *gSrc = 0; - *rSrc = *bSrc = *aSrc = -1; - break; - case GL_BLUE: - case GL_BLUE_INTEGER_EXT: - *bSrc = 0; - *rSrc = *gSrc = *aSrc = -1; - break; - case GL_ALPHA: - case GL_ALPHA_INTEGER_EXT: - *rSrc = *gSrc = *bSrc = -1; - *aSrc = 0; - break; - case GL_LUMINANCE: - case GL_LUMINANCE_INTEGER_EXT: - *rSrc = *gSrc = *bSrc = 0; - *aSrc = -1; - break; - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - *rSrc = *gSrc = *bSrc = 0; - *aSrc = 1; - break; - case GL_INTENSITY: - *rSrc = *gSrc = *bSrc = *aSrc = 0; - break; - case GL_RG: - case GL_RG_INTEGER: - *rSrc = 0; - *gSrc = 1; - *bSrc = -1; - *aSrc = -1; - *rDst = 0; - *gDst = 1; - *bDst = 2; - *aDst = 3; - break; - case GL_RGB: - case GL_RGB_INTEGER: - *rSrc = 0; - *gSrc = 1; - *bSrc = 2; - *aSrc = -1; - *rDst = 0; - *gDst = 1; - *bDst = 2; - *aDst = 3; - break; - case GL_BGR: - case GL_BGR_INTEGER: - *rSrc = 2; - *gSrc = 1; - *bSrc = 0; - *aSrc = -1; - *rDst = 2; - *gDst = 1; - *bDst = 0; - *aDst = 3; - break; - case GL_RGBA: - case GL_RGBA_INTEGER: - *rSrc = 0; - *gSrc = 1; - *bSrc = 2; - *aSrc = 3; - *rDst = 0; - *gDst = 1; - *bDst = 2; - *aDst = 3; - break; - case GL_BGRA: - case GL_BGRA_INTEGER: - *rSrc = 2; - *gSrc = 1; - *bSrc = 0; - *aSrc = 3; - *rDst = 2; - *gDst = 1; - *bDst = 0; - *aDst = 3; - break; - case GL_ABGR_EXT: - *rSrc = 3; - *gSrc = 2; - *bSrc = 1; - *aSrc = 0; - *rDst = 3; - *gDst = 2; - *bDst = 1; - *aDst = 0; - break; - default: - _mesa_problem(NULL, "bad srcFormat %s in get_component_mapping", - _mesa_lookup_enum_by_nr(format)); - return; - } -} - - - -/* - * This function extracts floating point RGBA values from arbitrary - * image data. srcFormat and srcType are the format and type parameters - * passed to glDrawPixels, glTexImage[123]D, glTexSubImage[123]D, etc. - * - * Refering to section 3.6.4 of the OpenGL 1.2 spec, this function - * implements the "Conversion to floating point", "Conversion to RGB", - * and "Final Expansion to RGBA" operations. - * - * Args: n - number of pixels - * rgba - output colors - * srcFormat - format of incoming data - * srcType - data type of incoming data - * src - source data pointer - * swapBytes - perform byteswapping of incoming data? - */ -static void -extract_float_rgba(GLuint n, GLfloat rgba[][4], - GLenum srcFormat, GLenum srcType, const GLvoid *src, - GLboolean swapBytes) -{ - GLint rSrc, gSrc, bSrc, aSrc; - GLint stride; - GLint rDst, bDst, gDst, aDst; - GLboolean intFormat; - GLfloat rs = 1.0f, gs = 1.0f, bs = 1.0f, as = 1.0f; /* scale factors */ - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT); - - ASSERT(srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - get_component_mapping(srcFormat, - &rSrc, &gSrc, &bSrc, &aSrc, - &rDst, &gDst, &bDst, &aDst); - - stride = _mesa_components_in_format(srcFormat); - - intFormat = _mesa_is_enum_format_integer(srcFormat); - -#define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT_FLT, DEFAULT_INT, TYPE, CONVERSION) \ - if ((SRC_INDEX) < 0) { \ - GLuint i; \ - if (intFormat) { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = DEFAULT_INT; \ - } \ - } \ - else { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = DEFAULT_FLT; \ - } \ - } \ - } \ - else if (swapBytes) { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - TYPE value = s[SRC_INDEX]; \ - if (sizeof(TYPE) == 2) { \ - SWAP2BYTE(value); \ - } \ - else if (sizeof(TYPE) == 4) { \ - SWAP4BYTE(value); \ - } \ - if (intFormat) \ - rgba[i][DST_INDEX] = (GLfloat) value; \ - else \ - rgba[i][DST_INDEX] = (GLfloat) CONVERSION(value); \ - s += stride; \ - } \ - } \ - else { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - if (intFormat) { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = (GLfloat) s[SRC_INDEX]; \ - s += stride; \ - } \ - } \ - else { \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = (GLfloat) CONVERSION(s[SRC_INDEX]); \ - s += stride; \ - } \ - } \ - } - - switch (srcType) { - case GL_UNSIGNED_BYTE: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLubyte, UBYTE_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLubyte, UBYTE_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLubyte, UBYTE_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 255, GLubyte, UBYTE_TO_FLOAT); - break; - case GL_BYTE: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLbyte, BYTE_TO_FLOAT_TEX); - PROCESS(aSrc, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOAT_TEX); - break; - case GL_UNSIGNED_SHORT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLushort, USHORT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 0xffff, GLushort, USHORT_TO_FLOAT); - break; - case GL_SHORT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLshort, SHORT_TO_FLOAT_TEX); - PROCESS(aSrc, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOAT_TEX); - break; - case GL_UNSIGNED_INT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLuint, UINT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 0xffffffff, GLuint, UINT_TO_FLOAT); - break; - case GL_INT: - PROCESS(rSrc, RCOMP, 0.0F, 0, GLint, INT_TO_FLOAT); - PROCESS(gSrc, GCOMP, 0.0F, 0, GLint, INT_TO_FLOAT); - PROCESS(bSrc, BCOMP, 0.0F, 0, GLint, INT_TO_FLOAT); - PROCESS(aSrc, ACOMP, 1.0F, 2147483647, GLint, INT_TO_FLOAT); - break; - case GL_FLOAT: - PROCESS(rSrc, RCOMP, 0.0F, 0.0F, GLfloat, (GLfloat)); - PROCESS(gSrc, GCOMP, 0.0F, 0.0F, GLfloat, (GLfloat)); - PROCESS(bSrc, BCOMP, 0.0F, 0.0F, GLfloat, (GLfloat)); - PROCESS(aSrc, ACOMP, 1.0F, 1.0F, GLfloat, (GLfloat)); - break; - case GL_HALF_FLOAT_ARB: - PROCESS(rSrc, RCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float); - PROCESS(gSrc, GCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float); - PROCESS(bSrc, BCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float); - PROCESS(aSrc, ACOMP, 1.0F, 1.0F, GLhalfARB, _mesa_half_to_float); - break; - case GL_UNSIGNED_BYTE_3_3_2: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - if (!intFormat) { - rs = 1.0F / 7.0F; - gs = 1.0F / 7.0F; - bs = 1.0F / 3.0F; - } - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p >> 5) ) * rs; - rgba[i][gDst] = ((p >> 2) & 0x7) * gs; - rgba[i][bDst] = ((p ) & 0x3) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - if (!intFormat) { - rs = 1.0F / 7.0F; - gs = 1.0F / 7.0F; - bs = 1.0F / 3.0F; - } - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p ) & 0x7) * rs; - rgba[i][gDst] = ((p >> 3) & 0x7) * gs; - rgba[i][bDst] = ((p >> 6) ) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (!intFormat) { - rs = 1.0F / 31.0F; - gs = 1.0F / 63.0F; - bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p ) & 0x1f) * bs; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p ) & 0x1f) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if (!intFormat) { - rs = 1.0F / 31.0F; - gs = 1.0F / 63.0F; - bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p >> 11) ) * bs; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x3f) * gs; - rgba[i][bDst] = ((p >> 11) ) * bs; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if (!intFormat) { - rs = gs = bs = as = 1.0F / 15.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 12) ) * rs; - rgba[i][gDst] = ((p >> 8) & 0xf) * gs; - rgba[i][bDst] = ((p >> 4) & 0xf) * bs; - rgba[i][aDst] = ((p ) & 0xf) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 12) ) * rs; - rgba[i][gDst] = ((p >> 8) & 0xf) * gs; - rgba[i][bDst] = ((p >> 4) & 0xf) * bs; - rgba[i][aDst] = ((p ) & 0xf) * as; - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if (!intFormat) { - rs = gs = bs = as = 1.0F / 15.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0xf) * rs; - rgba[i][gDst] = ((p >> 4) & 0xf) * gs; - rgba[i][bDst] = ((p >> 8) & 0xf) * bs; - rgba[i][aDst] = ((p >> 12) ) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0xf) * rs; - rgba[i][gDst] = ((p >> 4) & 0xf) * gs; - rgba[i][bDst] = ((p >> 8) & 0xf) * bs; - rgba[i][aDst] = ((p >> 12) ) * as; - } - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if (!intFormat) { - rs = gs = bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 6) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 1) & 0x1f) * bs; - rgba[i][aDst] = ((p ) & 0x1) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ) * rs; - rgba[i][gDst] = ((p >> 6) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 1) & 0x1f) * bs; - rgba[i][aDst] = ((p ) & 0x1) * as; - } - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (!intFormat) { - rs = gs = bs = 1.0F / 31.0F; - } - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 10) & 0x1f) * bs; - rgba[i][aDst] = ((p >> 15) ) * as; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f) * rs; - rgba[i][gDst] = ((p >> 5) & 0x1f) * gs; - rgba[i][bDst] = ((p >> 10) & 0x1f) * bs; - rgba[i][aDst] = ((p >> 15) ) * as; - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p ) & 0xff); - rgba[i][gDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][aDst] = (GLfloat) ((p >> 24) ); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p ) & 0xff); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p >> 24) ); - } - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p >> 24) ); - rgba[i][gDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][aDst] = (GLfloat) ((p ) & 0xff); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p >> 24) ); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p ) & 0xff); - } - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p >> 24) ); - rgba[i][gDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][aDst] = (GLfloat) ((p ) & 0xff); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p >> 24) ); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p ) & 0xff); - } - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - if (intFormat) { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = (GLfloat) ((p ) & 0xff); - rgba[i][gDst] = (GLfloat) ((p >> 8) & 0xff); - rgba[i][bDst] = (GLfloat) ((p >> 16) & 0xff); - rgba[i][aDst] = (GLfloat) ((p >> 24) ); - } - } - else { - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = UBYTE_TO_FLOAT((p ) & 0xff); - rgba[i][gDst] = UBYTE_TO_FLOAT((p >> 8) & 0xff); - rgba[i][bDst] = UBYTE_TO_FLOAT((p >> 16) & 0xff); - rgba[i][aDst] = UBYTE_TO_FLOAT((p >> 24) ); - } - } - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if (!intFormat) { - rs = 1.0F / 1023.0F; - gs = 1.0F / 1023.0F; - bs = 1.0F / 1023.0F; - as = 1.0F / 3.0F; - } - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p >> 22) ) * rs; - rgba[i][gDst] = ((p >> 12) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 2) & 0x3ff) * bs; - rgba[i][aDst] = ((p ) & 0x3 ) * as; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 22) ) * rs; - rgba[i][gDst] = ((p >> 12) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 2) & 0x3ff) * bs; - rgba[i][aDst] = ((p ) & 0x3 ) * as; - } - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (!intFormat) { - rs = 1.0F / 1023.0F; - gs = 1.0F / 1023.0F; - bs = 1.0F / 1023.0F; - as = 1.0F / 3.0F; - } - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p ) & 0x3ff) * rs; - rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs; - if (aSrc < 0) { - rgba[i][aDst] = 1.0F; - } else { - rgba[i][aDst] = (p >> 30) * as; - } - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0x3ff) * rs; - rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs; - rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs; - if (aSrc < 0) { - rgba[i][aDst] = 1.0F; - } else { - rgba[i][aDst] = (p >> 30) * as; - } - } - } - break; - case GL_UNSIGNED_INT_5_9_9_9_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgb9e5_to_float3(p, f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - rgb9e5_to_float3(uisrc[i], f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - break; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - r11g11b10f_to_float3(p, f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - GLfloat f[3]; - for (i = 0; i < n; i ++) { - r11g11b10f_to_float3(uisrc[i], f); - rgba[i][rDst] = f[0]; - rgba[i][gDst] = f[1]; - rgba[i][bDst] = f[2]; - rgba[i][aDst] = 1.0F; - } - } - break; - default: - _mesa_problem(NULL, "bad srcType in extract float data"); - break; - } -#undef PROCESS -} - - static inline GLuint clamp_float_to_uint(GLfloat f) { @@ -3673,1326 +482,6 @@ clamp_half_to_uint(GLhalfARB h) } -/** - * \sa extract_float_rgba() - */ -static void -extract_uint_rgba(GLuint n, GLuint rgba[][4], - GLenum srcFormat, GLenum srcType, const GLvoid *src, - GLboolean swapBytes) -{ - GLint rSrc, gSrc, bSrc, aSrc; - GLint stride; - GLint rDst, bDst, gDst, aDst; - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT); - - ASSERT(srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - get_component_mapping(srcFormat, - &rSrc, &gSrc, &bSrc, &aSrc, - &rDst, &gDst, &bDst, &aDst); - - stride = _mesa_components_in_format(srcFormat); - -#define PROCESS(SRC_INDEX, DST_INDEX, DEFAULT, TYPE, CONVERSION) \ - if ((SRC_INDEX) < 0) { \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = DEFAULT; \ - } \ - } \ - else if (swapBytes) { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - TYPE value = s[SRC_INDEX]; \ - if (sizeof(TYPE) == 2) { \ - SWAP2BYTE(value); \ - } \ - else if (sizeof(TYPE) == 4) { \ - SWAP4BYTE(value); \ - } \ - rgba[i][DST_INDEX] = CONVERSION(value); \ - s += stride; \ - } \ - } \ - else { \ - const TYPE *s = (const TYPE *) src; \ - GLuint i; \ - for (i = 0; i < n; i++) { \ - rgba[i][DST_INDEX] = CONVERSION(s[SRC_INDEX]); \ - s += stride; \ - } \ - } - - switch (srcType) { - case GL_UNSIGNED_BYTE: - PROCESS(rSrc, RCOMP, 0, GLubyte, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLubyte, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLubyte, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLubyte, (GLuint)); - break; - case GL_BYTE: - PROCESS(rSrc, RCOMP, 0, GLbyte, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLbyte, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLbyte, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLbyte, (GLuint)); - break; - case GL_UNSIGNED_SHORT: - PROCESS(rSrc, RCOMP, 0, GLushort, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLushort, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLushort, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLushort, (GLuint)); - break; - case GL_SHORT: - PROCESS(rSrc, RCOMP, 0, GLshort, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLshort, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLshort, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLshort, (GLuint)); - break; - case GL_UNSIGNED_INT: - PROCESS(rSrc, RCOMP, 0, GLuint, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLuint, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLuint, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLuint, (GLuint)); - break; - case GL_INT: - PROCESS(rSrc, RCOMP, 0, GLint, (GLuint)); - PROCESS(gSrc, GCOMP, 0, GLint, (GLuint)); - PROCESS(bSrc, BCOMP, 0, GLint, (GLuint)); - PROCESS(aSrc, ACOMP, 1, GLint, (GLuint)); - break; - case GL_FLOAT: - PROCESS(rSrc, RCOMP, 0, GLfloat, clamp_float_to_uint); - PROCESS(gSrc, GCOMP, 0, GLfloat, clamp_float_to_uint); - PROCESS(bSrc, BCOMP, 0, GLfloat, clamp_float_to_uint); - PROCESS(aSrc, ACOMP, 1, GLfloat, clamp_float_to_uint); - break; - case GL_HALF_FLOAT_ARB: - PROCESS(rSrc, RCOMP, 0, GLhalfARB, clamp_half_to_uint); - PROCESS(gSrc, GCOMP, 0, GLhalfARB, clamp_half_to_uint); - PROCESS(bSrc, BCOMP, 0, GLhalfARB, clamp_half_to_uint); - PROCESS(aSrc, ACOMP, 1, GLhalfARB, clamp_half_to_uint); - break; - case GL_UNSIGNED_BYTE_3_3_2: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p >> 5) ); - rgba[i][gDst] = ((p >> 2) & 0x7); - rgba[i][bDst] = ((p ) & 0x3); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_BYTE_2_3_3_REV: - { - const GLubyte *ubsrc = (const GLubyte *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLubyte p = ubsrc[i]; - rgba[i][rDst] = ((p ) & 0x7); - rgba[i][gDst] = ((p >> 3) & 0x7); - rgba[i][bDst] = ((p >> 6) ); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p ) & 0x1f); - rgba[i][aDst] = 1; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p ) & 0x1f); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_SHORT_5_6_5_REV: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p >> 11) ); - rgba[i][aDst] = 1; - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x3f); - rgba[i][bDst] = ((p >> 11) ); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 12) ); - rgba[i][gDst] = ((p >> 8) & 0xf); - rgba[i][bDst] = ((p >> 4) & 0xf); - rgba[i][aDst] = ((p ) & 0xf); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 12) ); - rgba[i][gDst] = ((p >> 8) & 0xf); - rgba[i][bDst] = ((p >> 4) & 0xf); - rgba[i][aDst] = ((p ) & 0xf); - } - } - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0xf); - rgba[i][gDst] = ((p >> 4) & 0xf); - rgba[i][bDst] = ((p >> 8) & 0xf); - rgba[i][aDst] = ((p >> 12) ); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0xf); - rgba[i][gDst] = ((p >> 4) & 0xf); - rgba[i][bDst] = ((p >> 8) & 0xf); - rgba[i][aDst] = ((p >> 12) ); - } - } - break; - case GL_UNSIGNED_SHORT_5_5_5_1: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 6) & 0x1f); - rgba[i][bDst] = ((p >> 1) & 0x1f); - rgba[i][aDst] = ((p ) & 0x1 ); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p >> 11) ); - rgba[i][gDst] = ((p >> 6) & 0x1f); - rgba[i][bDst] = ((p >> 1) & 0x1f); - rgba[i][aDst] = ((p ) & 0x1 ); - } - } - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (swapBytes) { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - SWAP2BYTE(p); - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x1f); - rgba[i][bDst] = ((p >> 10) & 0x1f); - rgba[i][aDst] = ((p >> 15) ); - } - } - else { - const GLushort *ussrc = (const GLushort *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLushort p = ussrc[i]; - rgba[i][rDst] = ((p ) & 0x1f); - rgba[i][gDst] = ((p >> 5) & 0x1f); - rgba[i][bDst] = ((p >> 10) & 0x1f); - rgba[i][aDst] = ((p >> 15) ); - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0xff); - rgba[i][gDst] = ((p >> 8) & 0xff); - rgba[i][bDst] = ((p >> 16) & 0xff); - rgba[i][aDst] = ((p >> 24) ); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 24) ); - rgba[i][gDst] = ((p >> 16) & 0xff); - rgba[i][bDst] = ((p >> 8) & 0xff); - rgba[i][aDst] = ((p ) & 0xff); - } - } - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 24) ); - rgba[i][gDst] = ((p >> 16) & 0xff); - rgba[i][bDst] = ((p >> 8) & 0xff); - rgba[i][aDst] = ((p ) & 0xff); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0xff); - rgba[i][gDst] = ((p >> 8) & 0xff); - rgba[i][bDst] = ((p >> 16) & 0xff); - rgba[i][aDst] = ((p >> 24) ); - } - } - break; - case GL_UNSIGNED_INT_10_10_10_2: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p >> 22) ); - rgba[i][gDst] = ((p >> 12) & 0x3ff); - rgba[i][bDst] = ((p >> 2) & 0x3ff); - rgba[i][aDst] = ((p ) & 0x3 ); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p >> 22) ); - rgba[i][gDst] = ((p >> 12) & 0x3ff); - rgba[i][bDst] = ((p >> 2) & 0x3ff); - rgba[i][aDst] = ((p ) & 0x3 ); - } - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgba[i][rDst] = ((p ) & 0x3ff); - rgba[i][gDst] = ((p >> 10) & 0x3ff); - rgba[i][bDst] = ((p >> 20) & 0x3ff); - rgba[i][aDst] = ((p >> 30) ); - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgba[i][rDst] = ((p ) & 0x3ff); - rgba[i][gDst] = ((p >> 10) & 0x3ff); - rgba[i][bDst] = ((p >> 20) & 0x3ff); - rgba[i][aDst] = ((p >> 30) ); - } - } - break; - case GL_UNSIGNED_INT_5_9_9_9_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - rgb9e5_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - rgb9e5_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - break; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - if (swapBytes) { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - SWAP4BYTE(p); - r11g11b10f_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - else { - const GLuint *uisrc = (const GLuint *) src; - GLuint i; - float f[3]; - for (i = 0; i < n; i ++) { - GLuint p = uisrc[i]; - r11g11b10f_to_float3(p, f); - rgba[i][rDst] = clamp_float_to_uint(f[0]); - rgba[i][gDst] = clamp_float_to_uint(f[1]); - rgba[i][bDst] = clamp_float_to_uint(f[2]); - rgba[i][aDst] = 1; - } - } - break; - default: - _mesa_problem(NULL, "bad srcType in extract uint data"); - break; - } -#undef PROCESS -} - - - -/* - * Unpack a row of color image data from a client buffer according to - * the pixel unpacking parameters. - * Return GLubyte values in the specified dest image format. - * This is used by glDrawPixels and glTexImage?D(). - * \param ctx - the context - * n - number of pixels in the span - * dstFormat - format of destination color array - * dest - the destination color array - * srcFormat - source image format - * srcType - source image data type - * source - source image pointer - * srcPacking - pixel unpacking parameters - * transferOps - bitmask of IMAGE_*_BIT values of operations to apply - * - * XXX perhaps expand this to process whole images someday. - */ -void -_mesa_unpack_color_span_ubyte(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLubyte dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps ) -{ - GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat); - ASSERT(dstFormat == GL_ALPHA || - dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_INTENSITY || - dstFormat == GL_RED || - dstFormat == GL_RG || - dstFormat == GL_RGB || - dstFormat == GL_RGBA); - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_COLOR_INDEX); - - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - /* EXT_texture_integer specifies no transfer ops on integer - * types in the resolved issues section. Just set them to 0 - * for integer surfaces. - */ - if (intFormat) - transferOps = 0; - - /* Try simple cases first */ - if (transferOps == 0) { - if (srcType == GL_UNSIGNED_BYTE) { - if (dstFormat == GL_RGBA) { - if (srcFormat == GL_RGBA) { - memcpy( dest, source, n * 4 * sizeof(GLubyte) ); - return; - } - else if (srcFormat == GL_RGB) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLubyte *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = 255; - src += 3; - dst += 4; - } - return; - } - } - else if (dstFormat == GL_RGB) { - if (srcFormat == GL_RGB) { - memcpy( dest, source, n * 3 * sizeof(GLubyte) ); - return; - } - else if (srcFormat == GL_RGBA) { - GLuint i; - const GLubyte *src = (const GLubyte *) source; - GLubyte *dst = dest; - for (i = 0; i < n; i++) { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - src += 4; - dst += 3; - } - return; - } - } - else if (dstFormat == srcFormat) { - GLint comps = _mesa_components_in_format(srcFormat); - assert(comps > 0); - memcpy( dest, source, n * comps * sizeof(GLubyte) ); - return; - } - } - } - - - /* general solution begins here */ - { - GLint dstComponents; - GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); - - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - dstComponents = _mesa_components_in_format( dstFormat ); - /* source & dest image formats should have been error checked by now */ - assert(dstComponents > 0); - - /* - * Extract image data and convert to RGBA floats - */ - if (srcFormat == GL_COLOR_INDEX) { - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - free(rgba); - return; - } - - extract_uint_indexes(n, indexes, srcFormat, srcType, source, - srcPacking); - - /* Convert indexes to RGBA */ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); - - /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting - * with color indexes. - */ - transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); - - free(indexes); - } - else { - /* non-color index data */ - extract_float_rgba(n, rgba, srcFormat, srcType, source, - srcPacking->SwapBytes); - } - - /* Need to clamp if returning GLubytes */ - transferOps |= IMAGE_CLAMP_BIT; - - if (transferOps) { - _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); - } - - get_component_indexes(dstFormat, - &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - - /* Now return the GLubyte data in the requested dstFormat */ - if (rDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[rDst], rgba[i][RCOMP]); - dst += dstComponents; - } - } - - if (gDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[gDst], rgba[i][GCOMP]); - dst += dstComponents; - } - } - - if (bDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[bDst], rgba[i][BCOMP]); - dst += dstComponents; - } - } - - if (aDst >= 0) { - GLubyte *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - CLAMPED_FLOAT_TO_UBYTE(dst[aDst], rgba[i][ACOMP]); - dst += dstComponents; - } - } - - if (iDst >= 0) { - GLubyte *dst = dest; - GLuint i; - assert(iDst == 0); - assert(dstComponents == 1); - for (i = 0; i < n; i++) { - /* Intensity comes from red channel */ - CLAMPED_FLOAT_TO_UBYTE(dst[i], rgba[i][RCOMP]); - } - } - - if (lDst >= 0) { - GLubyte *dst = dest; - GLuint i; - assert(lDst == 0); - for (i = 0; i < n; i++) { - /* Luminance comes from red channel */ - CLAMPED_FLOAT_TO_UBYTE(dst[0], rgba[i][RCOMP]); - dst += dstComponents; - } - } - - free(rgba); - } -} - - -/** - * Same as _mesa_unpack_color_span_ubyte(), but return GLfloat data - * instead of GLubyte. - */ -void -_mesa_unpack_color_span_float( struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLfloat dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps ) -{ - ASSERT(dstFormat == GL_ALPHA || - dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_INTENSITY || - dstFormat == GL_RED || - dstFormat == GL_RG || - dstFormat == GL_RGB || - dstFormat == GL_RGBA); - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT || - srcFormat == GL_COLOR_INDEX); - - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - /* general solution, no special cases, yet */ - { - GLint dstComponents; - GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat)); - GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat); - - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - dstComponents = _mesa_components_in_format( dstFormat ); - /* source & dest image formats should have been error checked by now */ - assert(dstComponents > 0); - - /* EXT_texture_integer specifies no transfer ops on integer - * types in the resolved issues section. Just set them to 0 - * for integer surfaces. - */ - if (intFormat) - transferOps = 0; - - /* - * Extract image data and convert to RGBA floats - */ - if (srcFormat == GL_COLOR_INDEX) { - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - free(rgba); - return; - } - - extract_uint_indexes(n, indexes, srcFormat, srcType, source, - srcPacking); - - /* Convert indexes to RGBA */ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); - - /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting - * with color indexes. - */ - transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); - - free(indexes); - } - else { - /* non-color index data */ - extract_float_rgba(n, rgba, srcFormat, srcType, source, - srcPacking->SwapBytes); - } - - if (transferOps) { - _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba); - } - - get_component_indexes(dstFormat, - &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - - /* Now pack results in the requested dstFormat */ - if (rDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[rDst] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - - if (gDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[gDst] = rgba[i][GCOMP]; - dst += dstComponents; - } - } - - if (bDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[bDst] = rgba[i][BCOMP]; - dst += dstComponents; - } - } - - if (aDst >= 0) { - GLfloat *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[aDst] = rgba[i][ACOMP]; - dst += dstComponents; - } - } - - if (iDst >= 0) { - GLfloat *dst = dest; - GLuint i; - assert(iDst == 0); - assert(dstComponents == 1); - for (i = 0; i < n; i++) { - /* Intensity comes from red channel */ - dst[i] = rgba[i][RCOMP]; - } - } - - if (lDst >= 0) { - GLfloat *dst = dest; - GLuint i; - assert(lDst == 0); - for (i = 0; i < n; i++) { - /* Luminance comes from red channel */ - dst[0] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - - free(rgba); - } -} - - -/** - * Same as _mesa_unpack_color_span_ubyte(), but return GLuint data - * instead of GLubyte. - * No pixel transfer ops are applied. - */ -void -_mesa_unpack_color_span_uint(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLuint *dest, - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint (*rgba)[4] = malloc(n * 4 * sizeof(GLfloat)); - - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - ASSERT(dstFormat == GL_ALPHA || - dstFormat == GL_LUMINANCE || - dstFormat == GL_LUMINANCE_ALPHA || - dstFormat == GL_INTENSITY || - dstFormat == GL_RED || - dstFormat == GL_RG || - dstFormat == GL_RGB || - dstFormat == GL_RGBA); - - ASSERT(srcFormat == GL_RED || - srcFormat == GL_GREEN || - srcFormat == GL_BLUE || - srcFormat == GL_ALPHA || - srcFormat == GL_LUMINANCE || - srcFormat == GL_LUMINANCE_ALPHA || - srcFormat == GL_INTENSITY || - srcFormat == GL_RG || - srcFormat == GL_RGB || - srcFormat == GL_BGR || - srcFormat == GL_RGBA || - srcFormat == GL_BGRA || - srcFormat == GL_ABGR_EXT || - srcFormat == GL_RED_INTEGER_EXT || - srcFormat == GL_GREEN_INTEGER_EXT || - srcFormat == GL_BLUE_INTEGER_EXT || - srcFormat == GL_ALPHA_INTEGER_EXT || - srcFormat == GL_RG_INTEGER || - srcFormat == GL_RGB_INTEGER_EXT || - srcFormat == GL_RGBA_INTEGER_EXT || - srcFormat == GL_BGR_INTEGER_EXT || - srcFormat == GL_BGRA_INTEGER_EXT || - srcFormat == GL_LUMINANCE_INTEGER_EXT || - srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT); - - ASSERT(srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT || - srcType == GL_UNSIGNED_BYTE_3_3_2 || - srcType == GL_UNSIGNED_BYTE_2_3_3_REV || - srcType == GL_UNSIGNED_SHORT_5_6_5 || - srcType == GL_UNSIGNED_SHORT_5_6_5_REV || - srcType == GL_UNSIGNED_SHORT_4_4_4_4 || - srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || - srcType == GL_UNSIGNED_SHORT_5_5_5_1 || - srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV || - srcType == GL_UNSIGNED_INT_10_10_10_2 || - srcType == GL_UNSIGNED_INT_2_10_10_10_REV || - srcType == GL_UNSIGNED_INT_5_9_9_9_REV || - srcType == GL_UNSIGNED_INT_10F_11F_11F_REV); - - - /* Extract image data as uint[4] pixels */ - extract_uint_rgba(n, rgba, srcFormat, srcType, source, - srcPacking->SwapBytes); - - if (dstFormat == GL_RGBA) { - /* simple case */ - memcpy(dest, rgba, 4 * sizeof(GLuint) * n); - } - else { - /* general case */ - GLint rDst, gDst, bDst, aDst, lDst, iDst; - GLint dstComponents = _mesa_components_in_format( dstFormat ); - - assert(dstComponents > 0); - - get_component_indexes(dstFormat, - &rDst, &gDst, &bDst, &aDst, &lDst, &iDst); - - /* Now pack values in the requested dest format */ - if (rDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[rDst] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - - if (gDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[gDst] = rgba[i][GCOMP]; - dst += dstComponents; - } - } - - if (bDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[bDst] = rgba[i][BCOMP]; - dst += dstComponents; - } - } - - if (aDst >= 0) { - GLuint *dst = dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[aDst] = rgba[i][ACOMP]; - dst += dstComponents; - } - } - - if (iDst >= 0) { - GLuint *dst = dest; - GLuint i; - assert(iDst == 0); - assert(dstComponents == 1); - for (i = 0; i < n; i++) { - /* Intensity comes from red channel */ - dst[i] = rgba[i][RCOMP]; - } - } - - if (lDst >= 0) { - GLuint *dst = dest; - GLuint i; - assert(lDst == 0); - for (i = 0; i < n; i++) { - /* Luminance comes from red channel */ - dst[0] = rgba[i][RCOMP]; - dst += dstComponents; - } - } - } - - free(rgba); -} - - -/* - * Unpack a row of color index data from a client buffer according to - * the pixel unpacking parameters. - * This is (or will be) used by glDrawPixels, glTexImage[123]D, etc. - * - * Args: ctx - the context - * n - number of pixels - * dstType - destination data type - * dest - destination array - * srcType - source pixel type - * source - source data pointer - * srcPacking - pixel unpacking parameters - * transferOps - the pixel transfer operations to apply - */ -void -_mesa_unpack_index_span( struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, - GLenum srcType, const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps ) -{ - ASSERT(srcType == GL_BITMAP || - srcType == GL_UNSIGNED_BYTE || - srcType == GL_BYTE || - srcType == GL_UNSIGNED_SHORT || - srcType == GL_SHORT || - srcType == GL_UNSIGNED_INT || - srcType == GL_INT || - srcType == GL_HALF_FLOAT_ARB || - srcType == GL_FLOAT); - - ASSERT(dstType == GL_UNSIGNED_BYTE || - dstType == GL_UNSIGNED_SHORT || - dstType == GL_UNSIGNED_INT); - - - transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); - - /* - * Try simple cases first - */ - if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE - && dstType == GL_UNSIGNED_BYTE) { - memcpy(dest, source, n * sizeof(GLubyte)); - } - else if (transferOps == 0 && srcType == GL_UNSIGNED_INT - && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) { - memcpy(dest, source, n * sizeof(GLuint)); - } - else { - /* - * general solution - */ - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); - return; - } - - extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source, - srcPacking); - - if (transferOps) - _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); - - /* convert to dest type */ - switch (dstType) { - case GL_UNSIGNED_BYTE: - { - GLubyte *dst = (GLubyte *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLubyte) (indexes[i] & 0xff); - } - } - break; - case GL_UNSIGNED_SHORT: - { - GLuint *dst = (GLuint *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLushort) (indexes[i] & 0xffff); - } - } - break; - case GL_UNSIGNED_INT: - memcpy(dest, indexes, n * sizeof(GLuint)); - break; - default: - _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span"); - } - - free(indexes); - } -} - - -void -_mesa_pack_index_span( struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, const GLuint *source, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps ) -{ - GLuint *indexes = malloc(n * sizeof(GLuint)); - - if (!indexes) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel packing"); - return; - } - - transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); - - if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) { - /* make a copy of input */ - memcpy(indexes, source, n * sizeof(GLuint)); - _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes); - source = indexes; - } - - switch (dstType) { - case GL_UNSIGNED_BYTE: - { - GLubyte *dst = (GLubyte *) dest; - GLuint i; - for (i = 0; i < n; i++) { - *dst++ = (GLubyte) source[i]; - } - } - break; - case GL_BYTE: - { - GLbyte *dst = (GLbyte *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLbyte) source[i]; - } - } - break; - case GL_UNSIGNED_SHORT: - { - GLushort *dst = (GLushort *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLushort) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap2( (GLushort *) dst, n ); - } - } - break; - case GL_SHORT: - { - GLshort *dst = (GLshort *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLshort) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap2( (GLushort *) dst, n ); - } - } - break; - case GL_UNSIGNED_INT: - { - GLuint *dst = (GLuint *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLuint) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap4( (GLuint *) dst, n ); - } - } - break; - case GL_INT: - { - GLint *dst = (GLint *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLint) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap4( (GLuint *) dst, n ); - } - } - break; - case GL_FLOAT: - { - GLfloat *dst = (GLfloat *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = (GLfloat) source[i]; - } - if (dstPacking->SwapBytes) { - _mesa_swap4( (GLuint *) dst, n ); - } - } - break; - case GL_HALF_FLOAT_ARB: - { - GLhalfARB *dst = (GLhalfARB *) dest; - GLuint i; - for (i = 0; i < n; i++) { - dst[i] = _mesa_float_to_half((GLfloat) source[i]); - } - if (dstPacking->SwapBytes) { - _mesa_swap2( (GLushort *) dst, n ); - } - } - break; - default: - _mesa_problem(ctx, "bad type in _mesa_pack_index_span"); - } - - free(indexes); -} - - /* * Unpack a row of stencil data from a client buffer according to * the pixel unpacking parameters. @@ -5023,6 +512,7 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n, srcType == GL_INT || srcType == GL_UNSIGNED_INT_24_8_EXT || srcType == GL_HALF_FLOAT_ARB || + srcType == GL_HALF_FLOAT_OES || srcType == GL_FLOAT || srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); @@ -5213,6 +703,7 @@ _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n, } break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLhalfARB *dst = (GLhalfARB *) dest; GLuint i; @@ -5430,6 +921,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n, needClamp = GL_TRUE; break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLuint i; const GLhalfARB *src = (const GLhalfARB *) source; @@ -5619,6 +1111,7 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest, } break; case GL_HALF_FLOAT_ARB: + case GL_HALF_FLOAT_OES: { GLhalfARB *dst = (GLhalfARB *) dest; GLuint i; @@ -5699,7 +1192,6 @@ _mesa_pack_depth_stencil_span(struct gl_context *ctx,GLuint n, - /** * Unpack image data. Apply byte swapping, byte flipping (bitmap). * Return all image data in a contiguous block. This is used when we @@ -5839,130 +1331,303 @@ _mesa_unpack_image( GLuint dimensions, } } - - -/** - * If we unpack colors from a luminance surface, we'll get pixel colors - * such as (l, l, l, a). - * When we call _mesa_pack_rgba_span_float(format=GL_LUMINANCE), that - * function will compute L=R+G+B before packing. The net effect is we'll - * accidentally store luminance values = 3*l. - * This function compensates for that by converting (aka rebasing) (l,l,l,a) - * to be (l,0,0,a). - * It's a similar story for other formats such as LUMINANCE_ALPHA, ALPHA - * and INTENSITY. - * - * Finally, we also need to do this when the actual surface format does - * not match the logical surface format. For example, suppose the user - * requests a GL_LUMINANCE texture but the driver stores it as RGBA. - * Again, we'll get pixel values like (l,l,l,a). - */ void -_mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat) +_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], + GLvoid *dstAddr, GLenum dst_format, + GLbitfield transferOps) { - GLuint i; + int i; + GLfloat *dst = (GLfloat *) dstAddr; - switch (baseFormat) { - case GL_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = 0.0F; - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - } - break; - case GL_INTENSITY: - /* fall-through */ + switch (dst_format) { case GL_LUMINANCE: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - rgba[i][ACOMP] = 1.0F; + if (transferOps & IMAGE_CLAMP_BIT) { + for (i = 0; i < n; i++) { + GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + dst[i] = CLAMP(sum, 0.0F, 1.0F); + } + } else { + for (i = 0; i < n; i++) { + dst[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + } } - break; + return; case GL_LUMINANCE_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - } - break; - case GL_RGB: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = 1.0F; - } - break; - case GL_RG: - for (i = 0; i < n; i++) { - rgba[i][BCOMP] = 0.0F; - rgba[i][ACOMP] = 1.0F; - } - break; - case GL_RED: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0.0F; - rgba[i][BCOMP] = 0.0F; - rgba[i][ACOMP] = 1.0F; + if (transferOps & IMAGE_CLAMP_BIT) { + for (i = 0; i < n; i++) { + GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + dst[2*i] = CLAMP(sum, 0.0F, 1.0F); + dst[2*i+1] = rgba[i][ACOMP]; + } + } else { + for (i = 0; i < n; i++) { + dst[2*i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + dst[2*i+1] = rgba[i][ACOMP]; + } } - break; - + return; default: - /* no-op */ - ; + assert(!"Unsupported format"); } } +static int32_t +clamp_sint64_to_sint32(int64_t src) +{ + return CLAMP(src, INT32_MIN, INT32_MAX); +} + +static int32_t +clamp_sint64_to_uint32(int64_t src) +{ + return CLAMP(src, 0, UINT32_MAX); +} + +static int32_t +clamp_uint64_to_uint32(uint64_t src) +{ + return MIN2(src, UINT32_MAX); +} + +static int32_t +clamp_uint64_to_sint32(uint64_t src) +{ + return MIN2(src, INT32_MAX); +} + +static int32_t +convert_integer_luminance64(int64_t src64, int bits, + bool dst_is_signed, bool src_is_signed) +{ + int32_t src32; + + /* Clamp Luminance value from 64-bit to 32-bit. Consider if we need + * any signed<->unsigned conversion too. + */ + if (src_is_signed && dst_is_signed) + src32 = clamp_sint64_to_sint32(src64); + else if (src_is_signed && !dst_is_signed) + src32 = clamp_sint64_to_uint32(src64); + else if (!src_is_signed && dst_is_signed) + src32 = clamp_uint64_to_sint32(src64); + else + src32 = clamp_uint64_to_uint32(src64); + + /* If the dst type is < 32-bit, we need an extra clamp */ + if (bits == 32) { + return src32; + } else { + if (dst_is_signed) + return _mesa_signed_to_signed(src32, bits); + else + return _mesa_unsigned_to_unsigned(src32, bits); + } +} + +static int32_t +convert_integer(int32_t src, int bits, bool dst_is_signed, bool src_is_signed) +{ + if (src_is_signed && dst_is_signed) + return _mesa_signed_to_signed(src, bits); + else if (src_is_signed && !dst_is_signed) + return _mesa_signed_to_unsigned(src, bits); + else if (!src_is_signed && dst_is_signed) + return _mesa_unsigned_to_signed(src, bits); + else + return _mesa_unsigned_to_unsigned(src, bits); +} -/** - * As above, but GLuint components. - */ void -_mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat) +_mesa_pack_luminance_from_rgba_integer(GLuint n, + GLuint rgba[][4], bool rgba_is_signed, + GLvoid *dstAddr, + GLenum dst_format, + GLenum dst_type) { - GLuint i; + int i; + int64_t lum64; + int32_t lum32, alpha; + bool dst_is_signed; + int dst_bits; + + assert(dst_format == GL_LUMINANCE_INTEGER_EXT || + dst_format == GL_LUMINANCE_ALPHA_INTEGER_EXT); + + /* We first compute luminance values as a 64-bit addition of the + * 32-bit R,G,B components, then we clamp the result to the dst type size. + * + * Notice that this operation involves casting the 32-bit R,G,B components + * to 64-bit before the addition. Since rgba is defined as a GLuint array + * we need to be careful when rgba packs signed data and make sure + * that we cast to a 32-bit signed integer values before casting them to + * 64-bit signed integers. + */ + dst_is_signed = (dst_type == GL_BYTE || dst_type == GL_SHORT || + dst_type == GL_INT); - switch (baseFormat) { - case GL_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = 0; - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - } - break; - case GL_INTENSITY: - /* fall-through */ - case GL_LUMINANCE: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1; - } - break; - case GL_LUMINANCE_ALPHA: - for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - } - break; - case GL_RGB: - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = 1; - } - break; - case GL_RG: + dst_bits = _mesa_sizeof_type(dst_type) * 8; + assert(dst_bits > 0); + + switch (dst_format) { + case GL_LUMINANCE_INTEGER_EXT: for (i = 0; i < n; i++) { - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1; + if (!rgba_is_signed) { + lum64 = (uint64_t) rgba[i][RCOMP] + + (uint64_t) rgba[i][GCOMP] + + (uint64_t) rgba[i][BCOMP]; + } else { + lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + + (int64_t) ((int32_t) rgba[i][GCOMP]) + + (int64_t) ((int32_t) rgba[i][BCOMP]); + } + lum32 = convert_integer_luminance64(lum64, dst_bits, + dst_is_signed, rgba_is_signed); + switch (dst_type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: { + GLbyte *dst = (GLbyte *) dstAddr; + dst[i] = lum32; + } + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: { + GLshort *dst = (GLshort *) dstAddr; + dst[i] = lum32; + } + break; + case GL_INT: + case GL_UNSIGNED_INT: { + GLint *dst = (GLint *) dstAddr; + dst[i] = lum32; + } + break; + } } - break; - case GL_RED: + return; + case GL_LUMINANCE_ALPHA_INTEGER_EXT: for (i = 0; i < n; i++) { - rgba[i][GCOMP] = 0; - rgba[i][BCOMP] = 0; - rgba[i][ACOMP] = 1; + if (!rgba_is_signed) { + lum64 = (uint64_t) rgba[i][RCOMP] + + (uint64_t) rgba[i][GCOMP] + + (uint64_t) rgba[i][BCOMP]; + } else { + lum64 = (int64_t) ((int32_t) rgba[i][RCOMP]) + + (int64_t) ((int32_t) rgba[i][GCOMP]) + + (int64_t) ((int32_t) rgba[i][BCOMP]); + } + lum32 = convert_integer_luminance64(lum64, dst_bits, + dst_is_signed, rgba_is_signed); + alpha = convert_integer(rgba[i][ACOMP], dst_bits, + dst_is_signed, rgba_is_signed); + switch (dst_type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: { + GLbyte *dst = (GLbyte *) dstAddr; + dst[2*i] = lum32; + dst[2*i+1] = alpha; + } + case GL_SHORT: + case GL_UNSIGNED_SHORT: { + GLshort *dst = (GLshort *) dstAddr; + dst[i] = lum32; + dst[2*i+1] = alpha; + } + break; + case GL_INT: + case GL_UNSIGNED_INT: { + GLint *dst = (GLint *) dstAddr; + dst[i] = lum32; + dst[2*i+1] = alpha; + } + break; + } } - default: - /* no-op */ - ; + return; + } +} + +GLfloat * +_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps) +{ + int count, img; + GLuint *indexes; + GLfloat *rgba, *dstPtr; + + count = srcWidth * srcHeight; + indexes = malloc(count * sizeof(GLuint)); + if (!indexes) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return NULL; + } + + rgba = malloc(4 * count * srcDepth * sizeof(GLfloat)); + if (!rgba) { + free(indexes); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking"); + return NULL; } + + /* Convert indexes to RGBA float */ + dstPtr = rgba; + for (img = 0; img < srcDepth; img++) { + const GLubyte *srcPtr = + (const GLubyte *) _mesa_image_address(dims, srcPacking, src, + srcWidth, srcHeight, + srcFormat, srcType, + img, 0, 0); + + extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking); + + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) + _mesa_shift_and_offset_ci(ctx, count, indexes); + + _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr); + + /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting + * with color indexes. + */ + transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT); + _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr); + + dstPtr += srcHeight * srcWidth * 4; + } + + free(indexes); + + return rgba; } +GLubyte * +_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps) +{ + GLfloat *rgba; + GLubyte *dst; + int count, i; + + transferOps |= IMAGE_CLAMP_BIT; + rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims, + src, srcFormat, srcType, + srcWidth, srcHeight, srcDepth, + srcPacking, transferOps); + + count = srcWidth * srcHeight * srcDepth; + dst = malloc(count * 4 * sizeof(GLubyte)); + for (i = 0; i < count; i++) { + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]); + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]); + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]); + CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]); + } + + free(rgba); + return dst; +} diff --git a/mesalib/src/mesa/main/pack.h b/mesalib/src/mesa/main/pack.h index 2173b652e..ac0a099e3 100644 --- a/mesalib/src/mesa/main/pack.h +++ b/mesalib/src/mesa/main/pack.h @@ -41,63 +41,12 @@ _mesa_pack_polygon_stipple(const GLuint pattern[32], GLubyte *dest, const struct gl_pixelstore_attrib *packing); -extern GLvoid * -_mesa_unpack_bitmap(GLint width, GLint height, const GLubyte *pixels, - const struct gl_pixelstore_attrib *packing); - extern void _mesa_pack_bitmap(GLint width, GLint height, const GLubyte *source, GLubyte *dest, const struct gl_pixelstore_attrib *packing); extern void -_mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, - GLfloat rgba[][4], - GLenum dstFormat, GLenum dstType, GLvoid *dstAddr, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps); - - -extern void -_mesa_unpack_color_span_ubyte(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLubyte dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - - -extern void -_mesa_unpack_color_span_float(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLfloat dest[], - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - -extern void -_mesa_unpack_color_span_uint(struct gl_context *ctx, - GLuint n, GLenum dstFormat, GLuint *dest, - GLenum srcFormat, GLenum srcType, - const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking); - -extern void -_mesa_unpack_index_span(struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, - GLenum srcType, const GLvoid *source, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - - -extern void -_mesa_pack_index_span(struct gl_context *ctx, GLuint n, - GLenum dstType, GLvoid *dest, const GLuint *source, - const struct gl_pixelstore_attrib *dstPacking, - GLbitfield transferOps); - - -extern void _mesa_unpack_stencil_span(struct gl_context *ctx, GLuint n, GLenum dstType, GLvoid *dest, GLenum srcType, const GLvoid *source, @@ -136,23 +85,28 @@ _mesa_unpack_image(GLuint dimensions, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *unpack); - -void -_mesa_pack_rgba_span_from_uints(struct gl_context *ctx, GLuint n, GLuint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr); - - -void -_mesa_pack_rgba_span_from_ints(struct gl_context *ctx, GLuint n, GLint rgba[][4], - GLenum dstFormat, GLenum dstType, - GLvoid *dstAddr); - - extern void -_mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat); +_mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], + GLvoid *dstAddr, GLenum dst_format, + GLbitfield transferOps); extern void -_mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat); +_mesa_pack_luminance_from_rgba_integer(GLuint n, GLuint rgba[][4], bool rgba_is_signed, + GLvoid *dstAddr, GLenum dst_format, + GLenum dst_type); + +extern GLfloat * +_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps); + +extern GLubyte * +_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims, + const void *src, GLenum srcFormat, GLenum srcType, + int srcWidth, int srcHeight, int srcDepth, + const struct gl_pixelstore_attrib *srcPacking, + GLbitfield transferOps); #endif diff --git a/mesalib/src/mesa/main/pack_tmp.h b/mesalib/src/mesa/main/pack_tmp.h deleted file mode 100644 index 0d4eb387d..000000000 --- a/mesalib/src/mesa/main/pack_tmp.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright © 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. - */ - -static void -FN_NAME(struct gl_context *ctx, - DST_TYPE *dst, - GLenum dstFormat, - SRC_TYPE rgba[][4], - int n) -{ - int i; - - switch (dstFormat) { - case GL_RED_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = SRC_CONVERT(rgba[i][RCOMP]); - } - break; - - case GL_GREEN_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = SRC_CONVERT(rgba[i][GCOMP]); - } - break; - - case GL_BLUE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = SRC_CONVERT(rgba[i][BCOMP]); - }; - break; - - case GL_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = SRC_CONVERT(rgba[i][ACOMP]); - } - break; - - case GL_RG_INTEGER: - for (i=0;i<n;i++) { - dst[i*2+0] = SRC_CONVERT(rgba[i][RCOMP]); - dst[i*2+1] = SRC_CONVERT(rgba[i][GCOMP]); - } - break; - - case GL_RGB_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = SRC_CONVERT(rgba[i][RCOMP]); - dst[i*3+1] = SRC_CONVERT(rgba[i][GCOMP]); - dst[i*3+2] = SRC_CONVERT(rgba[i][BCOMP]); - } - break; - - case GL_RGBA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = SRC_CONVERT(rgba[i][RCOMP]); - dst[i*4+1] = SRC_CONVERT(rgba[i][GCOMP]); - dst[i*4+2] = SRC_CONVERT(rgba[i][BCOMP]); - dst[i*4+3] = SRC_CONVERT(rgba[i][ACOMP]); - } - break; - - case GL_BGR_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*3+0] = SRC_CONVERT(rgba[i][BCOMP]); - dst[i*3+1] = SRC_CONVERT(rgba[i][GCOMP]); - dst[i*3+2] = SRC_CONVERT(rgba[i][RCOMP]); - } - break; - - case GL_BGRA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*4+0] = SRC_CONVERT(rgba[i][BCOMP]); - dst[i*4+1] = SRC_CONVERT(rgba[i][GCOMP]); - dst[i*4+2] = SRC_CONVERT(rgba[i][RCOMP]); - dst[i*4+3] = SRC_CONVERT(rgba[i][ACOMP]); - } - break; - - case GL_LUMINANCE_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i] = SRC_CONVERT(rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - } - break; - - case GL_LUMINANCE_ALPHA_INTEGER_EXT: - for (i=0;i<n;i++) { - dst[i*2+0] = SRC_CONVERT(rgba[i][RCOMP] + - rgba[i][GCOMP] + - rgba[i][BCOMP]); - dst[i*2+1] = SRC_CONVERT(rgba[i][ACOMP]); - } - break; - - default: - _mesa_problem(ctx, - "Unsupported format (%s)", - _mesa_lookup_enum_by_nr(dstFormat)); - break; - } -} diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c index c02910e31..2d740daf0 100644 --- a/mesalib/src/mesa/main/performance_monitor.c +++ b/mesalib/src/mesa/main/performance_monitor.c @@ -42,7 +42,7 @@ #include "macros.h" #include "mtypes.h" #include "performance_monitor.h" -#include "bitset.h" +#include "util/bitset.h" #include "util/ralloc.h" void diff --git a/mesalib/src/mesa/main/polygon.c b/mesalib/src/mesa/main/polygon.c index cdaa24483..a1f0aa02d 100644 --- a/mesalib/src/mesa/main/polygon.c +++ b/mesalib/src/mesa/main/polygon.c @@ -235,25 +235,33 @@ _mesa_GetPolygonStipple( GLubyte *dest ) _mesa_GetnPolygonStippleARB(INT_MAX, dest); } - -void GLAPIENTRY -_mesa_PolygonOffset( GLfloat factor, GLfloat units ) +void +_mesa_polygon_offset_clamp(struct gl_context *ctx, + GLfloat factor, GLfloat units, GLfloat clamp) { - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units); - if (ctx->Polygon.OffsetFactor == factor && - ctx->Polygon.OffsetUnits == units) + ctx->Polygon.OffsetUnits == units && + ctx->Polygon.OffsetClamp == clamp) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.OffsetFactor = factor; ctx->Polygon.OffsetUnits = units; + ctx->Polygon.OffsetClamp = clamp; if (ctx->Driver.PolygonOffset) - ctx->Driver.PolygonOffset( ctx, factor, units ); + ctx->Driver.PolygonOffset( ctx, factor, units, clamp ); +} + +void GLAPIENTRY +_mesa_PolygonOffset( GLfloat factor, GLfloat units ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units); + + _mesa_polygon_offset_clamp(ctx, factor, units, 0.0); } @@ -265,6 +273,23 @@ _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF ); } +void GLAPIENTRY +_mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->Extensions.EXT_polygon_offset_clamp) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "unsupported function (glPolygonOffsetClampEXT) called"); + return; + } + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPolygonOffsetClampEXT %f %f %f\n", factor, units, clamp); + + _mesa_polygon_offset_clamp(ctx, factor, units, clamp); +} + /**********************************************************************/ @@ -292,6 +317,7 @@ void _mesa_init_polygon( struct gl_context * ctx ) ctx->Polygon.StippleFlag = GL_FALSE; ctx->Polygon.OffsetFactor = 0.0F; ctx->Polygon.OffsetUnits = 0.0F; + ctx->Polygon.OffsetClamp = 0.0F; ctx->Polygon.OffsetPoint = GL_FALSE; ctx->Polygon.OffsetLine = GL_FALSE; ctx->Polygon.OffsetFill = GL_FALSE; diff --git a/mesalib/src/mesa/main/polygon.h b/mesalib/src/mesa/main/polygon.h index 530adba4c..41344a2ef 100644 --- a/mesalib/src/mesa/main/polygon.h +++ b/mesalib/src/mesa/main/polygon.h @@ -55,12 +55,18 @@ extern void GLAPIENTRY _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ); extern void GLAPIENTRY +_mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp ); + +extern void GLAPIENTRY _mesa_PolygonStipple( const GLubyte *mask ); extern void GLAPIENTRY _mesa_GetPolygonStipple( GLubyte *mask ); -extern void +extern void +_mesa_polygon_offset_clamp(struct gl_context *ctx, + GLfloat factor, GLfloat units, GLfloat clamp); +extern void _mesa_init_polygon( struct gl_context * ctx ); #endif diff --git a/mesalib/src/mesa/main/querymatrix.c b/mesalib/src/mesa/main/querymatrix.c index eb36c7604..ef8517571 100644 --- a/mesalib/src/mesa/main/querymatrix.c +++ b/mesalib/src/mesa/main/querymatrix.c @@ -37,8 +37,12 @@ #define INT_TO_FIXED(x) ((GLfixed) ((x) << 16)) #define FLOAT_TO_FIXED(x) ((GLfixed) ((x) * 65536.0)) -#if defined(_MSC_VER) -#if _MSC_VER < 1800 /* Not required on VS2013 and above. */ +#if defined(fpclassify) +/* ISO C99 says that fpclassify is a macro. Assume that any implementation + * of fpclassify, whether it's in a C99 compiler or not, will be a macro. + */ +#elif defined(_MSC_VER) +/* Not required on VS2013 and above. */ /* Oddly, the fpclassify() function doesn't exist in such a form * on MSVC. This is an implementation using slightly different * lower-level Windows functions. @@ -71,16 +75,8 @@ fpclassify(double x) return FP_NAN; } } -#endif /* _MSC_VER < 1800 */ - -#elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ - defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - (defined(__sun) && defined(__C99FEATURES__)) || defined(__MINGW32__) || \ - (defined(__sun) && defined(__GNUC__)) || defined(ANDROID) || defined(__HAIKU__) - -/* fpclassify is available. */ -#elif !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600 +#else enum {FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL} fpclassify(double x) diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c index 932359c4e..1b19afe4b 100644 --- a/mesalib/src/mesa/main/queryobj.c +++ b/mesalib/src/mesa/main/queryobj.c @@ -142,6 +142,18 @@ _mesa_init_query_object_functions(struct dd_function_table *driver) driver->CheckQuery = _mesa_check_query; } +static struct gl_query_object ** +get_pipe_stats_binding_point(struct gl_context *ctx, + GLenum target) +{ + if (!_mesa_is_desktop_gl(ctx) || + !ctx->Extensions.ARB_pipeline_statistics_query) + return NULL; + + const int which = target - GL_VERTICES_SUBMITTED_ARB; + assert(which < MAX_PIPELINE_STATISTICS); + return &ctx->Query.pipeline_stats[which]; +} /** * Return pointer to the query object binding point for the given target and @@ -183,6 +195,38 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index) return &ctx->Query.PrimitivesWritten[index]; else return NULL; + + case GL_VERTICES_SUBMITTED_ARB: + case GL_PRIMITIVES_SUBMITTED_ARB: + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + return get_pipe_stats_binding_point(ctx, target); + + case GL_GEOMETRY_SHADER_INVOCATIONS: + /* GL_GEOMETRY_SHADER_INVOCATIONS is defined in a non-sequential order */ + target = GL_VERTICES_SUBMITTED_ARB + MAX_PIPELINE_STATISTICS - 1; + /* fallthrough */ + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + if (_mesa_has_geometry_shaders(ctx)) + return get_pipe_stats_binding_point(ctx, target); + else + return NULL; + + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + if (ctx->Extensions.ARB_tessellation_shader) + return get_pipe_stats_binding_point(ctx, target); + else + return NULL; + + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + if (_mesa_has_compute_shaders(ctx)) + return get_pipe_stats_binding_point(ctx, target); + else + return NULL; + default: return NULL; } @@ -553,6 +597,39 @@ _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: *params = ctx->Const.QueryCounterBits.PrimitivesWritten; break; + case GL_VERTICES_SUBMITTED_ARB: + *params = ctx->Const.QueryCounterBits.VerticesSubmitted; + break; + case GL_PRIMITIVES_SUBMITTED_ARB: + *params = ctx->Const.QueryCounterBits.PrimitivesSubmitted; + break; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.VsInvocations; + break; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + *params = ctx->Const.QueryCounterBits.TessPatches; + break; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.TessInvocations; + break; + case GL_GEOMETRY_SHADER_INVOCATIONS: + *params = ctx->Const.QueryCounterBits.GsInvocations; + break; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + *params = ctx->Const.QueryCounterBits.GsPrimitives; + break; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.FsInvocations; + break; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + *params = ctx->Const.QueryCounterBits.ComputeInvocations; + break; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + *params = ctx->Const.QueryCounterBits.ClInPrimitives; + break; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + *params = ctx->Const.QueryCounterBits.ClOutPrimitives; + break; default: _mesa_problem(ctx, "Unknown target in glGetQueryIndexediv(target = %s)", @@ -771,6 +848,18 @@ _mesa_init_queryobj(struct gl_context *ctx) ctx->Const.QueryCounterBits.Timestamp = 64; ctx->Const.QueryCounterBits.PrimitivesGenerated = 64; ctx->Const.QueryCounterBits.PrimitivesWritten = 64; + + ctx->Const.QueryCounterBits.VerticesSubmitted = 64; + ctx->Const.QueryCounterBits.PrimitivesSubmitted = 64; + ctx->Const.QueryCounterBits.VsInvocations = 64; + ctx->Const.QueryCounterBits.TessPatches = 64; + ctx->Const.QueryCounterBits.TessInvocations = 64; + ctx->Const.QueryCounterBits.GsInvocations = 64; + ctx->Const.QueryCounterBits.GsPrimitives = 64; + ctx->Const.QueryCounterBits.FsInvocations = 64; + ctx->Const.QueryCounterBits.ComputeInvocations = 64; + ctx->Const.QueryCounterBits.ClInPrimitives = 64; + ctx->Const.QueryCounterBits.ClOutPrimitives = 64; } diff --git a/mesalib/src/mesa/main/rastpos.c b/mesalib/src/mesa/main/rastpos.c index a9a6ceec0..2027a9bd0 100644 --- a/mesalib/src/mesa/main/rastpos.c +++ b/mesalib/src/mesa/main/rastpos.c @@ -490,7 +490,7 @@ void glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) */ void _mesa_init_rastpos( struct gl_context * ctx ) { - int i; + unsigned i; ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 ); ctx->Current.RasterDistance = 0.0; diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index b09cf5499..ca4b9431b 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -39,6 +39,8 @@ #include "state.h" #include "glformats.h" #include "fbobject.h" +#include "format_utils.h" +#include "pixeltransfer.h" /** @@ -405,174 +407,217 @@ read_stencil_pixels( struct gl_context *ctx, ctx->Driver.UnmapRenderbuffer(ctx, rb); } - -/** - * Try to do glReadPixels of RGBA data using swizzle. - * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path) +/* + * Read R, G, B, A, RGB, L, or LA pixels. */ -static GLboolean -read_rgba_pixels_swizzle(struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels, - const struct gl_pixelstore_attrib *packing) +static void +read_rgba_pixels( struct gl_context *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) { - struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; + GLbitfield transferOps; + bool dst_is_integer, dst_is_luminance, needs_rebase; + int dst_stride, src_stride, rb_stride; + uint32_t dst_format, src_format; GLubyte *dst, *map; - int dstStride, stride, j; - GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE; - - /* XXX we could check for other swizzle/special cases here as needed */ - if (rb->Format == MESA_FORMAT_R8G8B8A8_UNORM && - format == GL_BGRA && - type == GL_UNSIGNED_INT_8_8_8_8_REV && - !ctx->Pack.SwapBytes) { - swizzle_rb = GL_TRUE; - } - else if (rb->Format == MESA_FORMAT_B8G8R8X8_UNORM && - format == GL_BGRA && - type == GL_UNSIGNED_INT_8_8_8_8_REV && - !ctx->Pack.SwapBytes) { - copy_xrgb = GL_TRUE; - } - else { - return GL_FALSE; - } + mesa_format rb_format; + bool needs_rgba; + void *rgba, *src; + bool src_is_uint = false; + uint8_t rebase_swizzle[4]; + struct gl_framebuffer *fb = ctx->ReadBuffer; + struct gl_renderbuffer *rb = fb->_ColorReadBuffer; - dstStride = _mesa_image_row_stride(packing, width, format, type); + if (!rb) + return; + + transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, + GL_FALSE); + /* Describe the dst format */ + dst_is_integer = _mesa_is_enum_format_integer(format); + dst_stride = _mesa_image_row_stride(packing, width, format, type); + dst_format = _mesa_format_from_format_and_type(format, type); + dst_is_luminance = format == GL_LUMINANCE || + format == GL_LUMINANCE_ALPHA || + format == GL_LUMINANCE_INTEGER_EXT || + format == GL_LUMINANCE_ALPHA_INTEGER_EXT; dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); + format, type, 0, 0); + /* Map the source render buffer */ ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride); + &map, &rb_stride); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); - return GL_TRUE; /* don't bother trying the slow path */ + return; } + rb_format = _mesa_get_srgb_format_linear(rb->Format); - if (swizzle_rb) { - /* swap R/B */ - for (j = 0; j < height; j++) { - int i; - for (i = 0; i < width; i++) { - GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; - GLuint pixel = map4[i]; - dst4[i] = (pixel & 0xff00ff00) - | ((pixel & 0x00ff0000) >> 16) - | ((pixel & 0x000000ff) << 16); - } - dst += dstStride; - map += stride; - } - } else if (copy_xrgb) { - /* convert xrgb -> argb */ - for (j = 0; j < height; j++) { - GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; - int i; - for (i = 0; i < width; i++) { - dst4[i] = map4[i] | 0xff000000; /* set A=0xff */ - } - dst += dstStride; - map += stride; - } + /* + * Depending on the base formats involved in the conversion we might need to + * rebase some values, so for these formats we compute a rebase swizzle. + */ + if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) { + needs_rebase = true; + rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE; + } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) { + needs_rebase = true; + rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W; + } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) { + needs_rebase = + _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat, + rebase_swizzle); + } else { + needs_rebase = false; } - ctx->Driver.UnmapRenderbuffer(ctx, rb); - - return GL_TRUE; -} - -static void -slow_read_rgba_pixels( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - GLbitfield transferOps ) -{ - struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; - const mesa_format rbFormat = _mesa_get_srgb_format_linear(rb->Format); - void *rgba; - GLubyte *dst, *map; - int dstStride, stride, j; - GLboolean dst_is_integer = _mesa_is_enum_format_integer(format); - GLboolean dst_is_uint = _mesa_is_format_unsigned(rbFormat); - - dstStride = _mesa_image_row_stride(packing, width, format, type); - dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, - format, type, 0, 0); - - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride); - if (!map) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); - return; - } + /* Since _mesa_format_convert does not handle transferOps we need to handle + * them before we call the function. This requires to convert to RGBA float + * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is + * integer transferOps do not apply. + * + * Converting to luminance also requires converting to RGBA first, so we can + * then compute luminance values as L=R+G+B. Notice that this is different + * from GetTexImage, where we compute L=R. + */ + assert(!transferOps || (transferOps && !dst_is_integer)); - rgba = malloc(width * MAX_PIXEL_BYTES); - if (!rgba) - goto done; + needs_rgba = transferOps || dst_is_luminance; + rgba = NULL; + if (needs_rgba) { + uint32_t rgba_format; + int rgba_stride; + bool need_convert; - for (j = 0; j < height; j++) { + /* Convert to RGBA float or int/uint depending on the type of the src */ if (dst_is_integer) { - _mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba); - _mesa_rebase_rgba_uint(width, (GLuint (*)[4]) rgba, - rb->_BaseFormat); - if (dst_is_uint) { - _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format, - type, dst); + src_is_uint = _mesa_is_format_unsigned(rb_format); + if (src_is_uint) { + rgba_format = RGBA32_UINT; + rgba_stride = width * 4 * sizeof(GLuint); } else { - _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format, - type, dst); + rgba_format = RGBA32_INT; + rgba_stride = width * 4 * sizeof(GLint); } } else { - _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba); - _mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba, - rb->_BaseFormat); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, - type, dst, packing, transferOps); + rgba_format = RGBA32_FLOAT; + rgba_stride = width * 4 * sizeof(GLfloat); } - dst += dstStride; - map += stride; - } - - free(rgba); - -done: - ctx->Driver.UnmapRenderbuffer(ctx, rb); -} -/* - * Read R, G, B, A, RGB, L, or LA pixels. - */ -static void -read_rgba_pixels( struct gl_context *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid *pixels, - const struct gl_pixelstore_attrib *packing ) -{ - GLbitfield transferOps; - struct gl_framebuffer *fb = ctx->ReadBuffer; - struct gl_renderbuffer *rb = fb->_ColorReadBuffer; + /* If we are lucky and the dst format matches the RGBA format we need to + * convert to, then we can convert directly into the dst buffer and avoid + * the final conversion/copy from the rgba buffer to the dst buffer. + */ + if (dst_format == rgba_format) { + need_convert = false; + rgba = dst; + } else { + need_convert = true; + rgba = malloc(height * rgba_stride); + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + goto done_unmap; + } + } - if (!rb) - return; + /* Convert to RGBA now */ + _mesa_format_convert(rgba, rgba_format, rgba_stride, + map, rb_format, rb_stride, + width, height, + needs_rebase ? rebase_swizzle : NULL); + + /* Handle transfer ops if necessary */ + if (transferOps) + _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba); + + /* If we had to rebase, we have already taken care of that */ + needs_rebase = false; + + /* If we were lucky and our RGBA conversion matches the dst format, then + * we are done. + */ + if (!need_convert) + goto done_swap; + + /* Otherwise, we need to convert from RGBA to dst next */ + src = rgba; + src_format = rgba_format; + src_stride = rgba_stride; + } else { + /* No RGBA conversion needed, convert directly to dst */ + src = map; + src_format = rb_format; + src_stride = rb_stride; + } - transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type, - GL_FALSE); + /* Do the conversion. + * + * If the dst format is Luminance, we need to do the conversion by computing + * L=R+G+B values. + */ + if (!dst_is_luminance) { + _mesa_format_convert(dst, dst_format, dst_stride, + src, src_format, src_stride, + width, height, + needs_rebase ? rebase_swizzle : NULL); + } else if (!dst_is_integer) { + /* Compute float Luminance values from RGBA float */ + int luminance_stride, luminance_bytes; + void *luminance; + uint32_t luminance_format; + + luminance_stride = width * sizeof(GL_FLOAT); + if (format == GL_LUMINANCE_ALPHA) + luminance_stride *= 2; + luminance_bytes = height * luminance_stride; + luminance = malloc(luminance_bytes); + if (!luminance) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + free(rgba); + goto done_unmap; + } + _mesa_pack_luminance_from_rgba_float(width * height, src, + luminance, format, transferOps); + + /* Convert from Luminance float to dst (this will hadle type conversion + * from float to the type of dst if necessary) + */ + luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT); + _mesa_format_convert(dst, dst_format, dst_stride, + luminance, luminance_format, luminance_stride, + width, height, NULL); + } else { + _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint, + dst, format, type); + } - /* Try the optimized paths first. */ - if (!transferOps && - read_rgba_pixels_swizzle(ctx, x, y, width, height, - format, type, pixels, packing)) { - return; + if (rgba) + free(rgba); + +done_swap: + /* Handle byte swapping if required */ + if (packing->SwapBytes) { + GLint swapSize = _mesa_sizeof_packed_type(type); + if (swapSize == 2 || swapSize == 4) { + int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; + assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); + if (swapSize == 2) + _mesa_swap2((GLushort *) dst, width * height * swapsPerPixel); + else if (swapSize == 4) + _mesa_swap4((GLuint *) dst, width * height * swapsPerPixel); + } } - slow_read_rgba_pixels(ctx, x, y, width, height, - format, type, pixels, packing, transferOps); +done_unmap: + ctx->Driver.UnmapRenderbuffer(ctx, rb); } /** diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c index 0bc7f2b96..98f3c13b5 100644 --- a/mesalib/src/mesa/main/renderbuffer.c +++ b/mesalib/src/mesa/main/renderbuffer.c @@ -38,6 +38,8 @@ void _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) { + GET_CURRENT_CONTEXT(ctx); + mtx_init(&rb->Mutex, mtx_plain); rb->ClassID = 0; @@ -53,7 +55,23 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) rb->Width = 0; rb->Height = 0; rb->Depth = 0; - rb->InternalFormat = GL_RGBA; + + /* In GL 3, the initial format is GL_RGBA according to Table 6.26 + * on page 302 of the GL 3.3 spec. + * + * In GLES 3, the initial format is GL_RGBA4 according to Table 6.15 + * on page 258 of the GLES 3.0.4 spec. + * + * If the context is current, set the initial format based on the + * specs. If the context is not current, we cannot determine the + * API, so default to GL_RGBA. + */ + if (ctx && _mesa_is_gles3(ctx)) { + rb->InternalFormat = GL_RGBA4; + } else { + rb->InternalFormat = GL_RGBA; + } + rb->Format = MESA_FORMAT_NONE; } diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c index 18a14d89a..d62a06bf1 100644 --- a/mesalib/src/mesa/main/samplerobj.c +++ b/mesalib/src/mesa/main/samplerobj.c @@ -732,8 +732,16 @@ _mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameteri(sampler %u)", sampler); return; } @@ -817,8 +825,16 @@ _mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameterf(sampler %u)", sampler); return; } @@ -901,8 +917,16 @@ _mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameteriv(sampler %u)", sampler); return; } @@ -993,8 +1017,16 @@ _mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glSamplerParameterfv(sampler %u)", sampler); return; } @@ -1249,8 +1281,16 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameteriv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glGetSamplerParameteriv(sampler %u)", sampler); return; } @@ -1271,13 +1311,22 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) *params = sampObj->MagFilter; break; case GL_TEXTURE_MIN_LOD: - *params = (GLint) sampObj->MinLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->MinLod); break; case GL_TEXTURE_MAX_LOD: - *params = (GLint) sampObj->MaxLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->MaxLod); break; case GL_TEXTURE_LOD_BIAS: - *params = (GLint) sampObj->LodBias; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->LodBias); break; case GL_TEXTURE_COMPARE_MODE: if (!ctx->Extensions.ARB_shadow) @@ -1290,7 +1339,10 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) *params = sampObj->CompareFunc; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: - *params = (GLint) sampObj->MaxAnisotropy; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(sampObj->MaxAnisotropy); break; case GL_TEXTURE_BORDER_COLOR: params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); @@ -1327,8 +1379,16 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) sampObj = _mesa_lookup_samplerobj(ctx, sampler); if (!sampObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameterfv(sampler %u)", - sampler); + /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states: + * + * "An INVALID_OPERATION error is generated if sampler is not the name + * of a sampler object previously returned from a call to GenSamplers." + * + * In desktop GL, an GL_INVALID_VALUE is returned instead. + */ + _mesa_error(ctx, (_mesa_is_gles(ctx) ? + GL_INVALID_OPERATION : GL_INVALID_VALUE), + "glGetSamplerParameterfv(sampler %u)", sampler); return; } diff --git a/mesalib/src/mesa/main/set.c b/mesalib/src/mesa/main/set.c deleted file mode 100644 index 52c1dabd8..000000000 --- a/mesalib/src/mesa/main/set.c +++ /dev/null @@ -1,346 +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> - */ - -#include <stdlib.h> - -#include "macros.h" -#include "set.h" -#include "util/ralloc.h" - -/* - * 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 - */ - -uint32_t deleted_key_value; -const void *deleted_key = &deleted_key_value; - -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(struct set_entry *entry) -{ - return entry->key == NULL; -} - -static int -entry_is_deleted(struct set_entry *entry) -{ - return entry->key == deleted_key; -} - -static int -entry_is_present(struct set_entry *entry) -{ - return entry->key != NULL && entry->key != deleted_key; -} - -struct set * -_mesa_set_create(void *mem_ctx, - bool (*key_equals_function)(const void *a, - const void *b)) -{ - struct set *ht; - - ht = ralloc(mem_ctx, struct set); - 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 set_entry, ht->size); - ht->entries = 0; - ht->deleted_entries = 0; - - if (ht->table == NULL) { - ralloc_free(ht); - return NULL; - } - - return ht; -} - -/** - * Frees the given set. - * - * If delete_function is passed, it gets called on each entry present before - * freeing. - */ -void -_mesa_set_destroy(struct set *ht, void (*delete_function)(struct set_entry *entry)) -{ - if (!ht) - return; - - if (delete_function) { - struct set_entry *entry; - - set_foreach (ht, entry) { - delete_function(entry); - } - } - ralloc_free(ht->table); - ralloc_free(ht); -} - -/** - * Finds a set entry with the given key and hash of that key. - * - * Returns NULL if no entry is found. - */ -struct set_entry * -_mesa_set_search(const struct set *ht, uint32_t hash, const void *key) -{ - uint32_t hash_address; - - hash_address = hash % ht->size; - do { - uint32_t double_hash; - - struct set_entry *entry = ht->table + hash_address; - - if (entry_is_free(entry)) { - return NULL; - } else if (entry_is_present(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 != hash % ht->size); - - return NULL; -} - -static void -set_rehash(struct set *ht, int new_size_index) -{ - struct set old_ht; - struct set_entry *table, *entry; - - if (new_size_index >= ARRAY_SIZE(hash_sizes)) - return; - - table = rzalloc_array(ht, struct set_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; - - for (entry = old_ht.table; - entry != old_ht.table + old_ht.size; - entry++) { - if (entry_is_present(entry)) { - _mesa_set_add(ht, entry->hash, entry->key); - } - } - - 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 set_entry * -_mesa_set_add(struct set *ht, uint32_t hash, const void *key) -{ - uint32_t hash_address; - - if (ht->entries >= ht->max_entries) { - set_rehash(ht, ht->size_index + 1); - } else if (ht->deleted_entries + ht->entries >= ht->max_entries) { - set_rehash(ht, ht->size_index); - } - - hash_address = hash % ht->size; - do { - struct set_entry *entry = ht->table + hash_address; - uint32_t double_hash; - - if (!entry_is_present(entry)) { - if (entry_is_deleted(entry)) - ht->deleted_entries--; - entry->hash = hash; - entry->key = key; - 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 keys 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; - return entry; - } - - double_hash = 1 + hash % ht->rehash; - - hash_address = (hash_address + double_hash) % ht->size; - } while (hash_address != hash % ht->size); - - /* 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_set_remove(struct set *ht, struct set_entry *entry) -{ - if (!entry) - return; - - entry->key = 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 set_entry * -_mesa_set_next_entry(const struct set *ht, struct set_entry *entry) -{ - if (entry == NULL) - entry = ht->table; - else - entry = entry + 1; - - for (; entry != ht->table + ht->size; entry++) { - if (entry_is_present(entry)) { - return entry; - } - } - - return NULL; -} - -struct set_entry * -_mesa_set_random_entry(struct set *ht, - int (*predicate)(struct set_entry *entry)) -{ - struct set_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(entry) && - (!predicate || predicate(entry))) { - return entry; - } - } - - for (entry = ht->table; entry != ht->table + i; entry++) { - if (entry_is_present(entry) && - (!predicate || predicate(entry))) { - return entry; - } - } - - return NULL; -} - diff --git a/mesalib/src/mesa/main/set.h b/mesalib/src/mesa/main/set.h deleted file mode 100644 index 206d0c4d2..000000000 --- a/mesalib/src/mesa/main/set.h +++ /dev/null @@ -1,94 +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 _SET_H -#define _SET_H - -#include <inttypes.h> -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct set_entry { - uint32_t hash; - const void *key; -}; - -struct set { - void *mem_ctx; - struct set_entry *table; - bool (*key_equals_function)(const void *a, const void *b); - uint32_t size; - uint32_t rehash; - uint32_t max_entries; - uint32_t size_index; - uint32_t entries; - uint32_t deleted_entries; -}; - -struct set * -_mesa_set_create(void *mem_ctx, - bool (*key_equals_function)(const void *a, - const void *b)); -void -_mesa_set_destroy(struct set *set, - void (*delete_function)(struct set_entry *entry)); - -struct set_entry * -_mesa_set_add(struct set *set, uint32_t hash, const void *key); - -struct set_entry * -_mesa_set_search(const struct set *set, uint32_t hash, - const void *key); - -void -_mesa_set_remove(struct set *set, struct set_entry *entry); - -struct set_entry * -_mesa_set_next_entry(const struct set *set, struct set_entry *entry); - -struct set_entry * -_mesa_set_random_entry(struct set *set, - int (*predicate)(struct set_entry *entry)); - -/** - * This foreach function is safe against deletion, but not against - * insertion (which may rehash the set, making entry a dangling - * pointer). - */ -#define set_foreach(set, entry) \ - for (entry = _mesa_set_next_entry(set, NULL); \ - entry != NULL; \ - entry = _mesa_set_next_entry(set, entry)) - -#ifdef __cplusplus -} /* extern C */ -#endif - -#endif /* _SET_H */ diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index 766ad2965..df9081b73 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -109,6 +109,11 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; + if (maxLength < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)"); + return; + } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 6d831f762..52eab4655 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -307,7 +307,7 @@ create_shader(struct gl_context *ctx, GLenum type) } -static GLuint +static GLuint create_shader_program(struct gl_context *ctx) { GLuint name; @@ -326,8 +326,9 @@ create_shader_program(struct gl_context *ctx) /** - * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's - * DeleteProgramARB. + * Delete a shader program. Actually, just decrement the program's + * reference count and mark it as DeletePending. + * Used to implement glDeleteProgram() and glDeleteObjectARB(). */ static void delete_shader_program(struct gl_context *ctx, GLuint name) @@ -430,9 +431,7 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) /* not found */ { GLenum err; - if (is_shader(ctx, shader)) - err = GL_INVALID_OPERATION; - else if (is_program(ctx, shader)) + if (is_shader(ctx, shader) || is_program(ctx, shader)) err = GL_INVALID_OPERATION; else err = GL_INVALID_VALUE; @@ -449,8 +448,16 @@ static void get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj) { - struct gl_shader_program *shProg = + struct gl_shader_program *shProg; + + if (maxCount < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders(maxCount < 0)"); + return; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); + if (shProg) { GLuint i; for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { @@ -512,7 +519,8 @@ check_gs_query(struct gl_context *ctx, const struct gl_shader_program *shProg) * programs (see glGetProgramivARB). */ static void -get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) +get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, + GLint *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); @@ -532,7 +540,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param /* Are uniform buffer objects available in this context? */ const bool has_ubo = - (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_uniform_buffer_object) + (ctx->API == API_OPENGL_COMPAT && + ctx->Extensions.ARB_uniform_buffer_object) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); @@ -600,7 +609,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { /* Add one for the terminating NUL character. */ - const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; + const GLint len = + strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; if (len > max_len) max_len = len; @@ -754,8 +764,7 @@ static void get_program_info_log(struct gl_context *ctx, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { - struct gl_shader_program *shProg - = _mesa_lookup_shader_program(ctx, program); + struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); return; @@ -785,6 +794,12 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *sourceOut) { struct gl_shader *sh; + + if (maxLength < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(bufSize < 0)"); + return; + } + sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); if (!sh) { return; @@ -870,7 +885,6 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) } fflush(stderr); } - } if (!sh->CompileStatus) { @@ -917,7 +931,7 @@ link_program(struct gl_context *ctx, GLuint program) _mesa_glsl_link_shader(ctx, shProg); - if (shProg->LinkStatus == GL_FALSE && + if (shProg->LinkStatus == GL_FALSE && (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) { _mesa_debug(ctx, "Error linking program %u:\n%s\n", shProg->Name, shProg->InfoLog); @@ -985,8 +999,7 @@ _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, } } -/** - */ + static void use_shader_program(struct gl_context *ctx, GLenum type, struct gl_shader_program *shProg, @@ -1033,6 +1046,7 @@ use_shader_program(struct gl_context *ctx, GLenum type, } } + /** * Use the named shader program for subsequent rendering. */ @@ -1070,7 +1084,7 @@ validate_shader_program(const struct gl_shader_program *shProg, any active sampler in the current program object refers to a texture image unit where fixed-function fragment processing accesses a - texture target that does not match the sampler type, or + texture target that does not match the sampler type, or the sum of the number of active samplers in the program and the number of texture image units enabled for fixed-function fragment @@ -1078,7 +1092,6 @@ validate_shader_program(const struct gl_shader_program *shProg, image units allowed. */ - /* * Check: any two active samplers in the current program object are of * different types, but refer to the same texture image unit, @@ -1672,7 +1685,7 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, (void) binaryformat; (void) binary; (void) length; - _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); + _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderBinary"); } @@ -1681,30 +1694,46 @@ _mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) { struct gl_shader_program *shProg; + GLsizei length_dummy; GET_CURRENT_CONTEXT(ctx); - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary"); - if (!shProg) - return; - - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramBinary(program %u not linked)", - shProg->Name); - return; - } - if (bufSize < 0){ _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramBinary(bufSize < 0)"); return; } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramBinary"); + if (!shProg) + return; + /* The ARB_get_program_binary spec says: * * "If <length> is NULL, then no length is returned." + * + * Ensure that length always points to valid storage to avoid multiple NULL + * pointer checks below. */ if (length != NULL) + length = &length_dummy; + + + /* The ARB_get_program_binary spec says: + * + * "When a program object's LINK_STATUS is FALSE, its program binary + * length is zero, and a call to GetProgramBinary will generate an + * INVALID_OPERATION error. + */ + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramBinary(program %u not linked)", + shProg->Name); *length = 0; + return; + } + + *length = 0; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramBinary(driver supports zero binary formats)"); (void) binaryFormat; (void) binary; @@ -1723,8 +1752,31 @@ _mesa_ProgramBinary(GLuint program, GLenum binaryFormat, (void) binaryFormat; (void) binary; - (void) length; - _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__); + + /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says: + * + * "If a negative number is provided where an argument of type sizei or + * sizeiptr is specified, an INVALID_VALUE error is generated." + */ + if (length < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glProgramBinary(length < 0)"); + return; + } + + /* The ARB_get_program_binary spec says: + * + * "<binaryFormat> and <binary> must be those returned by a previous + * call to GetProgramBinary, and <length> must be the length of the + * program binary as returned by GetProgramBinary or GetProgramiv with + * <pname> PROGRAM_BINARY_LENGTH. Loading the program binary will fail, + * setting the LINK_STATUS of <program> to FALSE, if these conditions + * are not met." + * + * Since any value of binaryFormat passed "is not one of those specified as + * allowable for [this] command, an INVALID_ENUM error is generated." + */ + shProg->LinkStatus = GL_FALSE; + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary"); } @@ -1755,12 +1807,7 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) * ProgramParameteri is not TRUE or FALSE." */ if (value != GL_TRUE && value != GL_FALSE) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(pname=%s, value=%d): " - "value must be 0 or 1.", - _mesa_lookup_enum_by_nr(pname), - value); - return; + goto invalid_value; } /* No need to notify the driver. Any changes will actually take effect @@ -1791,24 +1838,26 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value) * Chapter 7.3 Program Objects */ if (value != GL_TRUE && value != GL_FALSE) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glProgramParameteri(pname=%s, value=%d): " - "value must be 0 or 1.", - _mesa_lookup_enum_by_nr(pname), - value); - return; + goto invalid_value; } shProg->SeparateShader = value; return; default: - break; + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); + return; } - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteri(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); +invalid_value: + _mesa_error(ctx, GL_INVALID_VALUE, + "glProgramParameteri(pname=%s, value=%d): " + "value must be 0 or 1.", + _mesa_lookup_enum_by_nr(pname), + value); } + void _mesa_use_shader_program(struct gl_context *ctx, GLenum type, struct gl_shader_program *shProg, diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 81bd7829d..02ccf450b 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -193,9 +193,9 @@ _mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) * Then set ptr to point to shProg, incrementing its refcount. */ void -_mesa_reference_shader_program(struct gl_context *ctx, - struct gl_shader_program **ptr, - struct gl_shader_program *shProg) +_mesa_reference_shader_program_(struct gl_context *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg) { assert(ptr); if (*ptr == shProg) { diff --git a/mesalib/src/mesa/main/shaderobj.h b/mesalib/src/mesa/main/shaderobj.h index 05ddfeb50..92f7a33ee 100644 --- a/mesalib/src/mesa/main/shaderobj.h +++ b/mesalib/src/mesa/main/shaderobj.h @@ -62,9 +62,20 @@ _mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) extern void -_mesa_reference_shader_program(struct gl_context *ctx, +_mesa_reference_shader_program_(struct gl_context *ctx, struct gl_shader_program **ptr, struct gl_shader_program *shProg); + +static inline void +_mesa_reference_shader_program(struct gl_context *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg) +{ + if (*ptr != shProg) + _mesa_reference_shader_program_(ctx, ptr, shProg); +} + + extern void _mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader); diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c index f74a8232f..ccf5355f3 100644 --- a/mesalib/src/mesa/main/shared.c +++ b/mesalib/src/mesa/main/shared.c @@ -36,12 +36,12 @@ #include "program/program.h" #include "dlist.h" #include "samplerobj.h" -#include "set.h" #include "shaderapi.h" #include "shaderobj.h" #include "syncobj.h" #include "util/hash_table.h" +#include "util/set.h" /** * Allocate and initialize a shared context state structure. @@ -119,7 +119,8 @@ _mesa_alloc_shared_state(struct gl_context *ctx) shared->FrameBuffers = _mesa_NewHashTable(); shared->RenderBuffers = _mesa_NewHashTable(); - shared->SyncObjects = _mesa_set_create(NULL, _mesa_key_pointer_equal); + shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); return shared; } diff --git a/mesalib/src/mesa/main/simple_list.h b/mesalib/src/mesa/main/simple_list.h deleted file mode 100644 index 903432dce..000000000 --- a/mesalib/src/mesa/main/simple_list.h +++ /dev/null @@ -1,210 +0,0 @@ -/** - * \file simple_list.h - * Simple macros for type-safe, intrusive lists. - * - * Intended to work with a list sentinal which is created as an empty - * list. Insert & delete are O(1). - * - * \author - * (C) 1997, Keith Whitwell - */ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul 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 _SIMPLE_LIST_H -#define _SIMPLE_LIST_H - -#ifdef __cplusplus -extern "C" { -#endif - -struct simple_node { - struct simple_node *next; - struct simple_node *prev; -}; - -/** - * Remove an element from list. - * - * \param elem element to remove. - */ -#define remove_from_list(elem) \ -do { \ - (elem)->next->prev = (elem)->prev; \ - (elem)->prev->next = (elem)->next; \ -} while (0) - -/** - * Insert an element to the list head. - * - * \param list list. - * \param elem element to insert. - */ -#define insert_at_head(list, elem) \ -do { \ - (elem)->prev = list; \ - (elem)->next = (list)->next; \ - (list)->next->prev = elem; \ - (list)->next = elem; \ -} while(0) - -/** - * Insert an element to the list tail. - * - * \param list list. - * \param elem element to insert. - */ -#define insert_at_tail(list, elem) \ -do { \ - (elem)->next = list; \ - (elem)->prev = (list)->prev; \ - (list)->prev->next = elem; \ - (list)->prev = elem; \ -} while(0) - -/** - * Move an element to the list head. - * - * \param list list. - * \param elem element to move. - */ -#define move_to_head(list, elem) \ -do { \ - remove_from_list(elem); \ - insert_at_head(list, elem); \ -} while (0) - -/** - * Move an element to the list tail. - * - * \param list list. - * \param elem element to move. - */ -#define move_to_tail(list, elem) \ -do { \ - remove_from_list(elem); \ - insert_at_tail(list, elem); \ -} while (0) - -/** - * Make a empty list empty. - * - * \param sentinal list (sentinal element). - */ -#define make_empty_list(sentinal) \ -do { \ - (sentinal)->next = sentinal; \ - (sentinal)->prev = sentinal; \ -} while (0) - -/** - * Get list first element. - * - * \param list list. - * - * \return pointer to first element. - */ -#define first_elem(list) ((list)->next) - -/** - * Get list last element. - * - * \param list list. - * - * \return pointer to last element. - */ -#define last_elem(list) ((list)->prev) - -/** - * Get next element. - * - * \param elem element. - * - * \return pointer to next element. - */ -#define next_elem(elem) ((elem)->next) - -/** - * Get previous element. - * - * \param elem element. - * - * \return pointer to previous element. - */ -#define prev_elem(elem) ((elem)->prev) - -/** - * Test whether element is at end of the list. - * - * \param list list. - * \param elem element. - * - * \return non-zero if element is at end of list, or zero otherwise. - */ -#define at_end(list, elem) ((elem) == (list)) - -/** - * Test if a list is empty. - * - * \param list list. - * - * \return non-zero if list empty, or zero otherwise. - */ -#define is_empty_list(list) ((list)->next == (list)) - -/** - * Walk through the elements of a list. - * - * \param ptr pointer to the current element. - * \param list list. - * - * \note It should be followed by a { } block or a single statement, as in a \c - * for loop. - */ -#define foreach(ptr, list) \ - for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) - -/** - * Walk through the elements of a list. - * - * Same as #foreach but lets you unlink the current value during a list - * traversal. Useful for freeing a list, element by element. - * - * \param ptr pointer to the current element. - * \param t temporary pointer. - * \param list list. - * - * \note It should be followed by a { } block or a single statement, as in a \c - * for loop. - */ -#define foreach_s(ptr, t, list) \ - for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/mesalib/src/mesa/main/stencil.c b/mesalib/src/mesa/main/stencil.c index f65116abe..2a19a17b8 100644 --- a/mesalib/src/mesa/main/stencil.c +++ b/mesalib/src/mesa/main/stencil.c @@ -573,12 +573,24 @@ _mesa_init_stencil(struct gl_context *ctx) ctx->Stencil.Ref[0] = 0; ctx->Stencil.Ref[1] = 0; ctx->Stencil.Ref[2] = 0; - ctx->Stencil.ValueMask[0] = ~0U; - ctx->Stencil.ValueMask[1] = ~0U; - ctx->Stencil.ValueMask[2] = ~0U; - ctx->Stencil.WriteMask[0] = ~0U; - ctx->Stencil.WriteMask[1] = ~0U; - ctx->Stencil.WriteMask[2] = ~0U; + + /* 4.1.4 Stencil Test section of the GL-ES 3.0 specification says: + * + * "In the initial state, [...] the front and back stencil mask are both + * set to the value 2^s − 1, where s is greater than or equal to the + * number of bits in the deepest stencil buffer* supported by the GL + * implementation." + * + * Since the maximum supported precision for stencil buffers is 8 bits, + * mask values should be initialized to 2^8 - 1 = 0xFF. + */ + ctx->Stencil.ValueMask[0] = 0xFF; + ctx->Stencil.ValueMask[1] = 0xFF; + ctx->Stencil.ValueMask[2] = 0xFF; + ctx->Stencil.WriteMask[0] = 0xFF; + ctx->Stencil.WriteMask[1] = 0xFF; + ctx->Stencil.WriteMask[2] = 0xFF; + ctx->Stencil.Clear = 0; ctx->Stencil._BackFace = 1; } diff --git a/mesalib/src/mesa/main/syncobj.c b/mesalib/src/mesa/main/syncobj.c index 225399eda..c1b2d3bed 100644 --- a/mesalib/src/mesa/main/syncobj.c +++ b/mesalib/src/mesa/main/syncobj.c @@ -63,8 +63,8 @@ #include "get.h" #include "dispatch.h" #include "mtypes.h" -#include "set.h" #include "util/hash_table.h" +#include "util/set.h" #include "syncobj.h" @@ -173,9 +173,7 @@ _mesa_validate_sync(struct gl_context *ctx, const struct gl_sync_object *syncObj) { return (syncObj != NULL) - && _mesa_set_search(ctx->Shared->SyncObjects, - _mesa_hash_pointer(syncObj), - syncObj) != NULL + && _mesa_set_search(ctx->Shared->SyncObjects, syncObj) != NULL && (syncObj->Type == GL_SYNC_FENCE) && !syncObj->DeletePending; } @@ -198,9 +196,7 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj) mtx_lock(&ctx->Shared->Mutex); syncObj->RefCount--; if (syncObj->RefCount == 0) { - entry = _mesa_set_search(ctx->Shared->SyncObjects, - _mesa_hash_pointer(syncObj), - syncObj); + entry = _mesa_set_search(ctx->Shared->SyncObjects, syncObj); assert (entry != NULL); _mesa_set_remove(ctx->Shared->SyncObjects, entry); mtx_unlock(&ctx->Shared->Mutex); @@ -289,9 +285,7 @@ _mesa_FenceSync(GLenum condition, GLbitfield flags) ctx->Driver.FenceSync(ctx, syncObj, condition, flags); mtx_lock(&ctx->Shared->Mutex); - _mesa_set_add(ctx->Shared->SyncObjects, - _mesa_hash_pointer(syncObj), - syncObj); + _mesa_set_add(ctx->Shared->SyncObjects, syncObj); mtx_unlock(&ctx->Shared->Mutex); return (GLsync) syncObj; diff --git a/mesalib/src/mesa/main/texcompress_bptc.c b/mesalib/src/mesa/main/texcompress_bptc.c index 9204f123e..c944ac26f 100644 --- a/mesalib/src/mesa/main/texcompress_bptc.c +++ b/mesalib/src/mesa/main/texcompress_bptc.c @@ -1276,7 +1276,6 @@ _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) { const GLubyte *pixels; const GLubyte *tempImage = NULL; - GLenum baseFormat; int rowstride; if (srcFormat != GL_RGBA || @@ -1284,15 +1283,19 @@ _mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) ctx->_ImageTransferState || srcPacking->SwapBytes) { /* convert image to RGBA/ubyte */ - baseFormat = _mesa_get_format_base_format(dstFormat); - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; rowstride = srcWidth * 4; @@ -1584,7 +1587,6 @@ texstore_bptc_rgb_float(TEXSTORE_PARAMS, { const float *pixels; const float *tempImage = NULL; - GLenum baseFormat; int rowstride; if (srcFormat != GL_RGB || @@ -1592,16 +1594,19 @@ texstore_bptc_rgb_float(TEXSTORE_PARAMS, ctx->_ImageTransferState || srcPacking->SwapBytes) { /* convert image to RGB/float */ - baseFormat = _mesa_get_format_base_format(dstFormat); - tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - baseFormat, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, - ctx->_ImageTransferState); + GLfloat *tempImageSlices[1]; + int rgbRowStride = 3 * srcWidth * sizeof(GLfloat); + tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLfloat)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLfloat *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_RGB_FLOAT32, + rgbRowStride, (GLubyte **)tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; rowstride = srcWidth * sizeof(float) * 3; diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c index 61b01c6b4..7b25e1039 100644 --- a/mesalib/src/mesa/main/texcompress_fxt1.c +++ b/mesalib/src/mesa/main/texcompress_fxt1.c @@ -69,14 +69,19 @@ _mesa_texstore_rgb_fxt1(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGB/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbRowStride = 3 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_RGB_UNORM8, + rgbRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcRowStride = 3 * srcWidth; srcFormat = GL_RGB; @@ -118,14 +123,19 @@ _mesa_texstore_rgba_fxt1(TEXSTORE_PARAMS) ctx->_ImageTransferState || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcRowStride = 4 * srcWidth; srcFormat = GL_RGBA; diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c index f7ee24d47..e3042011a 100644 --- a/mesalib/src/mesa/main/texcompress_rgtc.c +++ b/mesalib/src/mesa/main/texcompress_rgtc.c @@ -83,18 +83,24 @@ _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS) const GLubyte *srcaddr; GLubyte srcpixels[4][4]; GLubyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, redRowStride; + GLubyte *tempImageSlices[1]; + ASSERT(dstFormat == MESA_FORMAT_R_RGTC1_UNORM || dstFormat == MESA_FORMAT_L_LATC1_UNORM); - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + redRowStride = 1 * srcWidth * sizeof(GLubyte); + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R_UNORM8, + redRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = dstSlices[0]; @@ -130,18 +136,24 @@ _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS) const GLfloat *srcaddr; GLbyte srcpixels[4][4]; GLbyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, redRowStride; + GLfloat *tempImageSlices[1]; + ASSERT(dstFormat == MESA_FORMAT_R_RGTC1_SNORM || dstFormat == MESA_FORMAT_L_LATC1_SNORM); - tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); + redRowStride = 1 * srcWidth * sizeof(GLfloat); + tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLfloat *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R_FLOAT32, + redRowStride, (GLubyte **)tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = (GLbyte *) dstSlices[0]; @@ -177,19 +189,30 @@ _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS) const GLubyte *srcaddr; GLubyte srcpixels[4][4]; GLubyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, rgRowStride; + mesa_format tempFormat; + GLubyte *tempImageSlices[1]; ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM || dstFormat == MESA_FORMAT_LA_LATC2_UNORM); - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + if (baseInternalFormat == GL_RG) + tempFormat = MESA_FORMAT_R8G8_UNORM; + else + tempFormat = MESA_FORMAT_L8A8_UNORM; + + rgRowStride = 2 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + tempFormat, + rgRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = dstSlices[0]; @@ -231,19 +254,30 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS) const GLfloat *srcaddr; GLbyte srcpixels[4][4]; GLbyte *blkaddr; - GLint dstRowDiff; + GLint dstRowDiff, rgRowStride; + mesa_format tempFormat; + GLfloat *tempImageSlices[1]; ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM || dstFormat == MESA_FORMAT_LA_LATC2_SNORM); - tempImage = _mesa_make_temp_float_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking, 0x0); + if (baseInternalFormat == GL_RG) + tempFormat = MESA_FORMAT_RG_FLOAT32; + else + tempFormat = MESA_FORMAT_LA_FLOAT32; + + rgRowStride = 2 * srcWidth * sizeof(GLfloat); + tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLfloat *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + tempFormat, + rgRowStride, (GLubyte **)tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); dst = (GLbyte *) dstSlices[0]; diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c index 254f84ef7..bfb53dce4 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -142,14 +142,19 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGB/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbRowStride = 3 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_RGB_UNORM8, + rgbRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcFormat = GL_RGB; } @@ -194,14 +199,19 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; srcFormat = GL_RGBA; } @@ -246,14 +256,19 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; } else { @@ -297,14 +312,19 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS) srcPacking->RowLength != srcWidth || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - _mesa_get_format_base_format(dstFormat), - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); + GLubyte *tempImageSlices[1]; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); + tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ + tempImageSlices[0] = (GLubyte *) tempImage; + _mesa_texstore(ctx, dims, + baseInternalFormat, + MESA_FORMAT_R8G8B8A8_UNORM, + rgbaRowStride, tempImageSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); pixels = tempImage; } else { diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index cb5f7936c..24df5b6f8 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -44,9 +44,10 @@ #include "texcompress.h" #include "texgetimage.h" #include "teximage.h" +#include "texobj.h" #include "texstore.h" - - +#include "format_utils.h" +#include "pixeltransfer.h" /** * Can the given type represent negative values? @@ -241,13 +242,15 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, const mesa_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat); const GLenum baseFormat = _mesa_get_format_base_format(texFormat); - const GLenum destBaseFormat = _mesa_base_tex_format(ctx, format); - GLenum rebaseFormat = GL_NONE; const GLuint width = texImage->Width; const GLuint height = texImage->Height; const GLuint depth = texImage->Depth; - GLfloat *tempImage, *tempSlice, *srcRow; - GLuint row, slice; + GLfloat *tempImage, *tempSlice; + GLuint slice; + int srcStride, dstStride; + uint32_t dstFormat; + bool needsRebase; + uint8_t rebaseSwizzle[4]; /* Decompress into temp float buffer, then pack into user buffer */ tempImage = malloc(width * height * depth @@ -281,46 +284,39 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, } } + /* Depending on the base format involved we may need to apply a rebase + * tranaform (for example: if we download to a Luminance format we want + * G=0 and B=0). + */ if (baseFormat == GL_LUMINANCE || - baseFormat == GL_INTENSITY || - baseFormat == GL_LUMINANCE_ALPHA) { - /* If a luminance (or intensity) texture is read back as RGB(A), the - * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat - * here to get G=B=0. - */ - rebaseFormat = texImage->_BaseFormat; - } - else if ((baseFormat == GL_RGBA || - baseFormat == GL_RGB || - baseFormat == GL_RG) && - (destBaseFormat == GL_LUMINANCE || - destBaseFormat == GL_LUMINANCE_ALPHA || - destBaseFormat == GL_LUMINANCE_INTEGER_EXT || - destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) { - /* If we're reading back an RGB(A) texture as luminance then we need - * to return L=tex(R). Note, that's different from glReadPixels which - * returns L=R+G+B. - */ - rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ - } - - if (rebaseFormat) { - _mesa_rebase_rgba_float(width * height, (GLfloat (*)[4]) tempImage, - rebaseFormat); + baseFormat == GL_INTENSITY) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE; + } else if (baseFormat == GL_LUMINANCE_ALPHA) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W; + } else { + needsRebase = false; } + srcStride = 4 * width * sizeof(GLfloat); + dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type); + dstFormat = _mesa_format_from_format_and_type(format, type); tempSlice = tempImage; for (slice = 0; slice < depth; slice++) { - srcRow = tempSlice; - for (row = 0; row < height; row++) { - void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, - width, height, format, type, - slice, row, 0); - - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow, - format, type, dest, &ctx->Pack, transferOps); - srcRow += 4 * width; - } + void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + slice, 0, 0); + _mesa_format_convert(dest, dstFormat, dstStride, + tempSlice, RGBA32_FLOAT, srcStride, + width, height, + needsRebase ? rebaseSwizzle : NULL); tempSlice += 4 * width * height; } @@ -376,145 +372,162 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, const mesa_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat); const GLuint width = texImage->Width; - GLenum destBaseFormat = _mesa_base_pack_format(format); - GLenum rebaseFormat = GL_NONE; GLuint height = texImage->Height; GLuint depth = texImage->Depth; - GLuint img, row; - GLfloat (*rgba)[4]; - GLuint (*rgba_uint)[4]; - GLboolean tex_is_integer = _mesa_is_format_integer_color(texImage->TexFormat); - GLboolean tex_is_uint = _mesa_is_format_unsigned(texImage->TexFormat); - GLenum texBaseFormat = _mesa_get_format_base_format(texImage->TexFormat); - - /* Allocate buffer for one row of texels */ - rgba = malloc(4 * width * sizeof(GLfloat)); - rgba_uint = (GLuint (*)[4]) rgba; - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); - return; - } + GLuint img; + GLboolean dst_is_integer = _mesa_is_enum_format_integer(format); + uint32_t dst_format; + int dst_stride; + uint8_t rebaseSwizzle[4]; + bool needsRebase; + void *rgba = NULL; if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { depth = height; height = 1; } + /* Depending on the base format involved we may need to apply a rebase + * tranaform (for example: if we download to a Luminance format we want + * G=0 and B=0). + */ if (texImage->_BaseFormat == GL_LUMINANCE || - texImage->_BaseFormat == GL_INTENSITY || - texImage->_BaseFormat == GL_LUMINANCE_ALPHA) { - /* If a luminance (or intensity) texture is read back as RGB(A), the - * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat - * here to get G=B=0. - */ - rebaseFormat = texImage->_BaseFormat; - } - else if ((texImage->_BaseFormat == GL_RGBA || - texImage->_BaseFormat == GL_RGB || - texImage->_BaseFormat == GL_RG) && - (destBaseFormat == GL_LUMINANCE || - destBaseFormat == GL_LUMINANCE_ALPHA || - destBaseFormat == GL_LUMINANCE_INTEGER_EXT || - destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) { - /* If we're reading back an RGB(A) texture as luminance then we need - * to return L=tex(R). Note, that's different from glReadPixels which - * returns L=R+G+B. - */ - rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ - } - else if (texImage->_BaseFormat != texBaseFormat) { - /* The internal format and the real format differ, so we can't rely - * on the unpack functions setting the correct constant values. - * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1) - */ - switch (texImage->_BaseFormat) { - case GL_RED: - if ((texBaseFormat == GL_RGBA || - texBaseFormat == GL_RGB || - texBaseFormat == GL_RG) && - (destBaseFormat == GL_RGBA || - destBaseFormat == GL_RGB || - destBaseFormat == GL_RG || - destBaseFormat == GL_GREEN)) { - rebaseFormat = texImage->_BaseFormat; - break; - } - /* fall through */ - case GL_RG: - if ((texBaseFormat == GL_RGBA || - texBaseFormat == GL_RGB) && - (destBaseFormat == GL_RGBA || - destBaseFormat == GL_RGB || - destBaseFormat == GL_BLUE)) { - rebaseFormat = texImage->_BaseFormat; - break; - } - /* fall through */ - case GL_RGB: - if (texBaseFormat == GL_RGBA && - (destBaseFormat == GL_RGBA || - destBaseFormat == GL_ALPHA || - destBaseFormat == GL_LUMINANCE_ALPHA)) { - rebaseFormat = texImage->_BaseFormat; - } - break; - - case GL_ALPHA: - if (destBaseFormat != GL_ALPHA) { - rebaseFormat = texImage->_BaseFormat; - } - break; - } - } + texImage->_BaseFormat == GL_INTENSITY) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_ONE; + } else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) { + needsRebase = true; + rebaseSwizzle[0] = MESA_FORMAT_SWIZZLE_X; + rebaseSwizzle[1] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[2] = MESA_FORMAT_SWIZZLE_ZERO; + rebaseSwizzle[3] = MESA_FORMAT_SWIZZLE_W; + } else if (texImage->_BaseFormat != _mesa_get_format_base_format(texFormat)) { + needsRebase = + _mesa_compute_rgba2base2rgba_component_mapping(texImage->_BaseFormat, + rebaseSwizzle); + } else { + needsRebase = false; + } + + /* Describe the dst format */ + dst_is_integer = _mesa_is_enum_format_integer(format); + dst_format = _mesa_format_from_format_and_type(format, type); + dst_stride = _mesa_image_row_stride(&ctx->Pack, width, format, type); + + /* Since _mesa_format_convert does not handle transferOps we need to handle + * them before we call the function. This requires to convert to RGBA float + * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is + * integer then transferOps do not apply. + */ + assert(!transferOps || (transferOps && !dst_is_integer)); for (img = 0; img < depth; img++) { GLubyte *srcMap; GLint rowstride; + GLubyte *img_src; + void *dest; + void *src; + int src_stride; + uint32_t src_format; /* map src texture buffer */ ctx->Driver.MapTextureImage(ctx, texImage, img, 0, 0, width, height, GL_MAP_READ_BIT, &srcMap, &rowstride); - if (srcMap) { - for (row = 0; row < height; row++) { - const GLubyte *src = srcMap + row * rowstride; - void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, - width, height, format, type, - img, row, 0); + if (!srcMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); + goto done; + } - if (tex_is_integer) { - _mesa_unpack_uint_rgba_row(texFormat, width, src, rgba_uint); - if (rebaseFormat) - _mesa_rebase_rgba_uint(width, rgba_uint, rebaseFormat); - if (tex_is_uint) { - _mesa_pack_rgba_span_from_uints(ctx, width, - (GLuint (*)[4]) rgba_uint, - format, type, dest); - } else { - _mesa_pack_rgba_span_from_ints(ctx, width, - (GLint (*)[4]) rgba_uint, - format, type, dest); - } - } else { - _mesa_unpack_rgba_row(texFormat, width, src, rgba); - if (rebaseFormat) - _mesa_rebase_rgba_float(width, rgba, rebaseFormat); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, - format, type, dest, - &ctx->Pack, transferOps); - } - } - - /* Unmap the src texture buffer */ - ctx->Driver.UnmapTextureImage(ctx, texImage, img); + img_src = srcMap; + dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, 0, 0); + + if (transferOps) { + uint32_t rgba_format; + int rgba_stride; + bool need_convert = false; + + /* We will convert to RGBA float */ + rgba_format = RGBA32_FLOAT; + rgba_stride = width * 4 * sizeof(GLfloat); + + /* If we are lucky and the dst format matches the RGBA format we need + * to convert to, then we can convert directly into the dst buffer + * and avoid the final conversion/copy from the rgba buffer to the dst + * buffer. + */ + if (format == rgba_format) { + rgba = dest; + } else if (rgba == NULL) { /* Allocate the RGBA buffer only once */ + need_convert = true; + rgba = malloc(height * rgba_stride); + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); + ctx->Driver.UnmapTextureImage(ctx, texImage, img); + return; + } + } + + _mesa_format_convert(rgba, rgba_format, rgba_stride, + img_src, texFormat, rowstride, + width, height, + needsRebase ? rebaseSwizzle : NULL); + + /* Handle transfer ops now */ + _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba); + + /* If we had to rebase, we have already handled that */ + needsRebase = false; + + /* If we were lucky and our RGBA conversion matches the dst format, then + * we are done. + */ + if (!need_convert) + goto do_swap; + + /* Otherwise, we need to convert from RGBA to dst next */ + src = rgba; + src_format = rgba_format; + src_stride = rgba_stride; + } else { + /* No RGBA conversion needed, convert directly to dst */ + src = img_src; + src_format = texFormat; + src_stride = rowstride; } - else { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); - break; + + /* Do the conversion to destination format */ + _mesa_format_convert(dest, dst_format, dst_stride, + src, src_format, src_stride, + width, height, + needsRebase ? rebaseSwizzle : NULL); + + do_swap: + /* Handle byte swapping if required */ + if (ctx->Pack.SwapBytes) { + GLint swapSize = _mesa_sizeof_packed_type(type); + if (swapSize == 2 || swapSize == 4) { + int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize; + assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0); + if (swapSize == 2) + _mesa_swap2((GLushort *) dest, width * height * swapsPerPixel); + else if (swapSize == 4) + _mesa_swap4((GLuint *) dest, width * height * swapsPerPixel); + } } + + /* Unmap the src texture buffer */ + ctx->Driver.UnmapTextureImage(ctx, texImage, img); } - free(rgba); +done: + if (rgba) + free(rgba); } @@ -585,7 +598,7 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, if (memCopy) { const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat); - const GLuint bytesPerRow = texImage->Width * bpp; + const GLint bytesPerRow = texImage->Width * bpp; GLubyte *dst = _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width, texImage->Height, format, type, 0, 0); @@ -631,9 +644,9 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, * unmap with ctx->Driver.UnmapTextureImage(). */ void -_mesa_get_teximage(struct gl_context *ctx, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage) +_mesa_GetTexImage_sw(struct gl_context *ctx, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_image *texImage) { const GLuint dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); @@ -689,14 +702,14 @@ _mesa_get_teximage(struct gl_context *ctx, * All error checking will have been done before this routine is called. */ void -_mesa_get_compressed_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLvoid *img) +_mesa_GetCompressedTexImage_sw(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLvoid *img) { const GLuint dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); struct compressed_pixelstore store; - GLuint i, slice; + GLint slice; GLubyte *dest; _mesa_compute_compressed_pixelstore(dimensions, texImage->TexFormat, @@ -729,19 +742,19 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, GLubyte *src; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, 0, + ctx->Driver.MapTextureImage(ctx, texImage, slice, 0, 0, texImage->Width, texImage->Height, GL_MAP_READ_BIT, &src, &srcRowStride); if (src) { - + GLint i; for (i = 0; i < store.CopyRowsPerSlice; i++) { memcpy(dest, src, store.CopyBytesPerRow); dest += store.TotalBytesPerRow; src += srcRowStride; } - ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + ctx->Driver.UnmapTextureImage(ctx, texImage, slice); /* Advance to next slice */ dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice); @@ -758,24 +771,17 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, /** - * Validate the texture target enum supplied to glTexImage or - * glCompressedTexImage. + * Validate the texture target enum supplied to glGetTex(ture)Image or + * glGetCompressedTex(ture)Image. */ static GLboolean -legal_getteximage_target(struct gl_context *ctx, GLenum target) +legal_getteximage_target(struct gl_context *ctx, GLenum target, bool dsa) { switch (target) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: return GL_TRUE; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - return ctx->Extensions.ARB_texture_cube_map; case GL_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY_EXT: @@ -783,6 +789,24 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target) return ctx->Extensions.EXT_texture_array; case GL_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; + + /* Section 8.11 (Texture Queries) of the OpenGL 4.5 core profile spec + * (30.10.2014) says: + * "An INVALID_ENUM error is generated if the effective target is not + * one of TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY, + * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, TEXTURE_RECTANGLE, one of + * the targets from table 8.19 (for GetTexImage and GetnTexImage *only*), + * or TEXTURE_CUBE_MAP (for GetTextureImage *only*)." (Emphasis added.) + */ + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return dsa ? GL_FALSE : ctx->Extensions.ARB_texture_cube_map; + case GL_TEXTURE_CUBE_MAP: + return dsa ? GL_TRUE : GL_FALSE; default: return GL_FALSE; } @@ -790,84 +814,74 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target) /** - * Do error checking for a glGetTexImage() call. + * Do error checking for a glGetTex(ture)Image() call. * \return GL_TRUE if any error, GL_FALSE if no errors. */ static GLboolean -getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, +getteximage_error_check(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLenum target, GLint level, GLenum format, GLenum type, GLsizei clientMemSize, - GLvoid *pixels ) + GLvoid *pixels, bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, target); const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; - GLenum baseFormat, err; - - if (!legal_getteximage_target(ctx, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target); - return GL_TRUE; - } + GLenum baseFormat; + const char *suffix = dsa ? "ture" : ""; + assert(texImage); assert(maxLevels != 0); if (level < 0 || level >= maxLevels) { - _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); - return GL_TRUE; - } - - err = _mesa_error_check_format_and_type(ctx, format, type); - if (err != GL_NO_ERROR) { - _mesa_error(ctx, err, "glGetTexImage(format/type)"); - return GL_TRUE; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - - if (!texObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetTex%sImage(level out of range)", suffix); return GL_TRUE; } - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (!texImage) { - /* non-existant texture image */ - return GL_TRUE; - } + /* + * Format and type checking has been moved up to GetnTexImage and + * GetTextureImage so that it happens before getting the texImage object. + */ baseFormat = _mesa_get_format_base_format(texImage->TexFormat); - + /* Make sure the requested image format is compatible with the * texture's format. */ if (_mesa_is_color_format(format) && !_mesa_is_color_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_depth_format(format) && !_mesa_is_depth_format(baseFormat) && !_mesa_is_depthstencil_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_stencil_format(format) && !ctx->Extensions.ARB_texture_stencil8) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format=GL_STENCIL_INDEX)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTex%sImage(format=GL_STENCIL_INDEX)", suffix); return GL_TRUE; } else if (_mesa_is_ycbcr_format(format) && !_mesa_is_ycbcr_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_depthstencil_format(format) && !_mesa_is_depthstencil_format(baseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } else if (_mesa_is_enum_format_integer(format) != _mesa_is_format_integer(texImage->TexFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sImage(format mismatch)", suffix); return GL_TRUE; } @@ -876,11 +890,13 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, format, type, clientMemSize, pixels)) { if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(out of bounds PBO access)"); + "glGetTex%sImage(out of bounds PBO access)", suffix); } else { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetnTexImageARB(out of bounds access:" - " bufSize (%d) is too small)", clientMemSize); + "%s(out of bounds access:" + " bufSize (%d) is too small)", + dsa ? "glGetTextureImage" : "glGetnTexImageARB", + clientMemSize); } return GL_TRUE; } @@ -889,7 +905,7 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, /* PBO should not be mapped */ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(PBO is mapped)"); + "glGetTex%sImage(PBO is mapped)", suffix); return GL_TRUE; } } @@ -898,9 +914,12 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, } - /** - * Get texture image. Called by glGetTexImage. + * This is the implementation for glGetnTexImageARB, glGetTextureImage, + * and glGetTexImage. + * + * Requires caller to pass in texImage object because _mesa_GetTextureImage + * must handle the GL_TEXTURE_CUBE_MAP target. * * \param target texture target. * \param level image level. @@ -908,19 +927,29 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level, * \param type pixel data type for returned image. * \param bufSize size of the pixels data buffer. * \param pixels returned pixel data. + * \param dsa True when the caller is an ARB_direct_state_access function, + * false otherwise */ -void GLAPIENTRY -_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *pixels ) +void +_mesa_get_texture_image(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, GLenum target, + GLint level, GLenum format, GLenum type, + GLsizei bufSize, GLvoid *pixels, bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); + assert(texObj); + assert(texImage); FLUSH_VERTICES(ctx, 0); - if (getteximage_error_check(ctx, target, level, format, type, - bufSize, pixels)) { + /* + * Legal target checking has been moved up to GetnTexImage and + * GetTextureImage so that it can be caught before receiving a NULL + * texImage object and exiting. + */ + + if (getteximage_error_check(ctx, texImage, target, level, format, + type, bufSize, pixels, dsa)) { return; } @@ -929,15 +958,13 @@ _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, return; } - texObj = _mesa_get_current_tex_object(ctx, target); - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { - _mesa_debug(ctx, "glGetTexImage(tex %u) format = %s, w=%d, h=%d," + _mesa_debug(ctx, "glGetTex%sImage(tex %u) format = %s, w=%d, h=%d," " dstFmt=0x%x, dstType=0x%x\n", + dsa ? "ture": "", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height, @@ -951,6 +978,58 @@ _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, _mesa_unlock_texture(ctx, texObj); } +/** + * Get texture image. Called by glGetTexImage. + * + * \param target texture target. + * \param level image level. + * \param format pixel data format for returned image. + * \param type pixel data type for returned image. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetnTexImageARB(GLenum target, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLenum err; + GET_CURRENT_CONTEXT(ctx); + + /* + * This has been moved here because a format/type mismatch can cause a NULL + * texImage object, which in turn causes the mismatch error to be + * ignored. + */ + err = _mesa_error_check_format_and_type(ctx, format, type); + if (err != GL_NO_ERROR) { + _mesa_error(ctx, err, "glGetnTexImage(format/type)"); + return; + } + + /* + * Legal target checking has been moved here to prevent exiting with a NULL + * texImage object. + */ + if (!legal_getteximage_target(ctx, target, false)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetnTexImage(target=0x%x)", + target); + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + texImage = _mesa_select_tex_image(texObj, target, level); + if (!texImage) + return; + + _mesa_get_texture_image(ctx, texObj, texImage, target, level, format, type, + bufSize, pixels, false); +} + void GLAPIENTRY _mesa_GetTexImage( GLenum target, GLint level, GLenum format, @@ -959,51 +1038,162 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, _mesa_GetnTexImageARB(target, level, format, type, INT_MAX, pixels); } +/** + * Get texture image. + * + * \param texture texture name. + * \param level image level. + * \param format pixel data format for returned image. + * \param type pixel data type for returned image. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int i; + GLint image_stride; + GLenum err; + GET_CURRENT_CONTEXT(ctx); + + /* + * This has been moved here because a format/type mismatch can cause a NULL + * texImage object, which in turn causes the mismatch error to be + * ignored. + */ + err = _mesa_error_check_format_and_type(ctx, format, type); + if (err != GL_NO_ERROR) { + _mesa_error(ctx, err, "glGetTextureImage(format/type)"); + return; + } + + texObj = _mesa_lookup_texture_err(ctx, texture, "glGetTextureImage"); + if (!texObj) + return; + + /* + * Legal target checking has been moved here to prevent exiting with a NULL + * texImage object. + */ + if (!legal_getteximage_target(ctx, texObj->Target, true)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTextureImage(target=%s)", + _mesa_lookup_enum_by_nr(texObj->Target)); + return; + } + + /* Must handle special case GL_TEXTURE_CUBE_MAP. */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + + /* Error checking */ + if (texObj->NumLayers < 6) { + /* Not enough image planes for a cube map. The spec does not say + * what should happen in this case because the user has always + * specified each cube face separately (using + * GL_TEXTURE_CUBE_MAP_POSITIVE_X+i) in previous GL versions. + * This is addressed in Khronos Bug 13223. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureImage(insufficient cube map storage)"); + return; + } + + /* + * What do we do if the user created a texture with the following code + * and then called this function with its handle? + * + * GLuint tex; + * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); + * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); + * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the + * // wrong format, or given the wrong size, etc. + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); + * + * A bug has been filed against the spec for this case. In the + * meantime, we will check for cube completeness. + * + * According to Section 8.17 Texture Completeness in the OpenGL 4.5 + * Core Profile spec (30.10.2014): + * "[A] cube map texture is cube complete if the + * following conditions all hold true: The [base level] texture + * images of each of the six cube map faces have identical, positive, + * and square dimensions. The [base level] images were each specified + * with the same internal format." + * + * It seems reasonable to check for cube completeness of an arbitrary + * level here so that the returned data has a consistent format and size + * and therefore fits in the user's buffer. + */ + if (!_mesa_cube_level_complete(texObj, level)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureImage(cube map incomplete)"); + return; + } + + /* Copy each face. */ + for (i = 0; i < 6; ++i) { + texImage = texObj->Image[i][level]; + _mesa_get_texture_image(ctx, texObj, texImage, texObj->Target, level, + format, type, bufSize, pixels, true); + + image_stride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, + texImage->Height, format, + type); + pixels = (GLubyte *) pixels + image_stride; + bufSize -= image_stride; + } + } + else { + texImage = _mesa_select_tex_image(texObj, texObj->Target, level); + if (!texImage) + return; + + _mesa_get_texture_image(ctx, texObj, texImage, texObj->Target, level, + format, type, bufSize, pixels, true); + } +} /** * Do error checking for a glGetCompressedTexImage() call. * \return GL_TRUE if any error, GL_FALSE if no errors. */ static GLboolean -getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, - GLint level, GLsizei clientMemSize, GLvoid *img) +getcompressedteximage_error_check(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLenum target, + GLint level, GLsizei clientMemSize, + GLvoid *img, bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, target); GLuint compressedSize, dimensions; + const char *suffix = dsa ? "ture" : ""; - if (!legal_getteximage_target(ctx, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)", - target); + assert(texImage); + + if (!legal_getteximage_target(ctx, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetCompressedTex%sImage(target=%s)", suffix, + _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } assert(maxLevels != 0); if (level < 0 || level >= maxLevels) { _mesa_error(ctx, GL_INVALID_VALUE, - "glGetCompressedTexImageARB(bad level = %d)", level); - return GL_TRUE; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); - return GL_TRUE; - } - - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - - if (!texImage) { - /* probably invalid mipmap level */ - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetCompressedTexImageARB(level)"); + "glGetCompressedTex%sImage(bad level = %d)", suffix, level); return GL_TRUE; } if (!_mesa_is_format_compressed(texImage->TexFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImageARB(texture is not compressed)"); + "glGetCompressedTex%sImage(texture is not compressed)", + suffix); return GL_TRUE; } @@ -1015,8 +1205,9 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, /* Check for invalid pixel storage modes */ dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions, - &ctx->Pack, - "glGetCompressedTexImageARB")) { + &ctx->Pack, dsa ? + "glGetCompressedTextureImage": + "glGetCompressedTexImage")) { return GL_TRUE; } @@ -1024,8 +1215,9 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, /* do bounds checking on writing to client memory */ if (clientMemSize < (GLsizei) compressedSize) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetnCompressedTexImageARB(out of bounds access:" - " bufSize (%d) is too small)", clientMemSize); + "%s(out of bounds access: bufSize (%d) is too small)", + dsa ? "glGetCompressedTextureImage" : + "glGetnCompressedTexImageARB", clientMemSize); return GL_TRUE; } } else { @@ -1033,14 +1225,15 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, if ((const GLubyte *) img + compressedSize > (const GLubyte *) ctx->Pack.BufferObj->Size) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImage(out of bounds PBO access)"); + "glGetCompressedTex%sImage(out of bounds PBO access)", + suffix); return GL_TRUE; } /* make sure PBO is not mapped */ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImage(PBO is mapped)"); + "glGetCompressedTex%sImage(PBO is mapped)", suffix); return GL_TRUE; } } @@ -1048,49 +1241,132 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, return GL_FALSE; } - -void GLAPIENTRY -_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, - GLvoid *img) +/** Implements glGetnCompressedTexImageARB, glGetCompressedTexImage, and + * glGetCompressedTextureImage. + * + * texImage must be passed in because glGetCompressedTexImage must handle the + * target GL_TEXTURE_CUBE_MAP. + */ +void +_mesa_get_compressed_texture_image(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLsizei bufSize, GLvoid *pixels, + bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); + assert(texObj); + assert(texImage); FLUSH_VERTICES(ctx, 0); - if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) { + if (getcompressedteximage_error_check(ctx, texImage, target, level, + bufSize, pixels, dsa)) { return; } - if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) { + if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !pixels) { /* not an error, do nothing */ return; } - texObj = _mesa_get_current_tex_object(ctx, target); - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (_mesa_is_zero_size_texture(texImage)) return; if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) { _mesa_debug(ctx, - "glGetCompressedTexImage(tex %u) format = %s, w=%d, h=%d\n", - texObj->Name, + "glGetCompressedTex%sImage(tex %u) format = %s, w=%d, h=%d\n", + dsa ? "ture" : "", texObj->Name, _mesa_get_format_name(texImage->TexFormat), texImage->Width, texImage->Height); } _mesa_lock_texture(ctx, texObj); { - ctx->Driver.GetCompressedTexImage(ctx, texImage, img); + ctx->Driver.GetCompressedTexImage(ctx, texImage, pixels); } _mesa_unlock_texture(ctx, texObj); } void GLAPIENTRY +_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, + GLvoid *img) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + texImage = _mesa_select_tex_image(texObj, target, level); + if (!texImage) + return; + + _mesa_get_compressed_texture_image(ctx, texObj, texImage, target, level, + bufSize, img, false); +} + +void GLAPIENTRY _mesa_GetCompressedTexImage(GLenum target, GLint level, GLvoid *img) { _mesa_GetnCompressedTexImageARB(target, level, INT_MAX, img); } + +/** + * Get compressed texture image. + * + * \param texture texture name. + * \param level image level. + * \param bufSize size of the pixels data buffer. + * \param pixels returned pixel data. + */ +void GLAPIENTRY +_mesa_GetCompressedTextureImage(GLuint texture, GLint level, + GLsizei bufSize, GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int i; + GLint image_stride; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glGetCompressedTextureImage"); + if (!texObj) + return; + + /* Must handle special case GL_TEXTURE_CUBE_MAP. */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + assert(texObj->NumLayers >= 6); + + /* Copy each face. */ + for (i = 0; i < 6; ++i) { + texImage = texObj->Image[i][level]; + if (!texImage) + return; + + _mesa_get_compressed_texture_image(ctx, texObj, texImage, + texObj->Target, level, + bufSize, pixels, true); + + /* Compressed images don't have a client format */ + image_stride = _mesa_format_image_size(texImage->TexFormat, + texImage->Width, + texImage->Height, 1); + + pixels = (GLubyte *) pixels + image_stride; + bufSize -= image_stride; + } + } + else { + texImage = _mesa_select_tex_image(texObj, texObj->Target, level); + if (!texImage) + return; + + _mesa_get_compressed_texture_image(ctx, texObj, texImage, + texObj->Target, level, bufSize, + pixels, true); + } +} diff --git a/mesalib/src/mesa/main/texgetimage.h b/mesalib/src/mesa/main/texgetimage.h index a292fabc0..1fa2f59dc 100644 --- a/mesalib/src/mesa/main/texgetimage.h +++ b/mesalib/src/mesa/main/texgetimage.h @@ -37,16 +37,30 @@ extern GLenum _mesa_base_pack_format(GLenum format); extern void -_mesa_get_teximage(struct gl_context *ctx, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage); +_mesa_GetTexImage_sw(struct gl_context *ctx, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_image *texImage); extern void -_mesa_get_compressed_teximage(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLvoid *data); +_mesa_GetCompressedTexImage_sw(struct gl_context *ctx, + struct gl_texture_image *texImage, + GLvoid *data); +extern void +_mesa_get_texture_image(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, GLenum target, + GLint level, GLenum format, GLenum type, + GLsizei bufSize, GLvoid *pixels, bool dsa); + +extern void +_mesa_get_compressed_texture_image( struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLsizei bufSize, GLvoid *pixels, + bool dsa ); extern void GLAPIENTRY @@ -55,6 +69,9 @@ _mesa_GetTexImage( GLenum target, GLint level, extern void GLAPIENTRY _mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *pixels ); +extern void GLAPIENTRY +_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *pixels); extern void GLAPIENTRY _mesa_GetCompressedTexImage(GLenum target, GLint lod, GLvoid *img); @@ -63,4 +80,8 @@ extern void GLAPIENTRY _mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, GLvoid *img); +extern void GLAPIENTRY +_mesa_GetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, + GLvoid *pixels); + #endif /* TEXGETIMAGE_H */ diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 7766904c9..29c325bf2 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -62,7 +62,58 @@ */ #define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) +/** + * Returns a corresponding internal floating point format for a given base + * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal + * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it + * needs to be a 16 bit component. + * + * For example, given base format GL_RGBA, type GL_Float return GL_RGBA32F_ARB. + */ +static GLenum +adjust_for_oes_float_texture(GLenum format, GLenum type) +{ + switch (type) { + case GL_FLOAT: + switch (format) { + case GL_RGBA: + return GL_RGBA32F; + case GL_RGB: + return GL_RGB32F; + case GL_ALPHA: + return GL_ALPHA32F_ARB; + case GL_LUMINANCE: + return GL_LUMINANCE32F_ARB; + case GL_LUMINANCE_ALPHA: + return GL_LUMINANCE_ALPHA32F_ARB; + default: + break; + } + break; + case GL_HALF_FLOAT_OES: + switch (format) { + case GL_RGBA: + return GL_RGBA16F; + case GL_RGB: + return GL_RGB16F; + case GL_ALPHA: + return GL_ALPHA16F_ARB; + case GL_LUMINANCE: + return GL_LUMINANCE16F_ARB; + case GL_LUMINANCE_ALPHA: + return GL_LUMINANCE_ALPHA16F_ARB; + default: + break; + } + break; + + default: + break; + } + + return format; +} /** * Return the simple base format for a given internal texture format. @@ -81,92 +132,102 @@ GLint _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) { switch (internalFormat) { - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; - case 2: - case GL_LUMINANCE_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: - return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; - case 3: - return (ctx->API != API_OPENGL_CORE) ? GL_RGB : -1; - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return GL_RGB; - case 4: - return (ctx->API != API_OPENGL_CORE) ? GL_RGBA : -1; - case GL_RGBA: - 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_RGBA; - default: - ; /* fallthrough */ + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; + case 2: + case GL_LUMINANCE_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: + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; + case 3: + return (ctx->API != API_OPENGL_CORE) ? GL_RGB : -1; + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return GL_RGB; + case 4: + return (ctx->API != API_OPENGL_CORE) ? GL_RGBA : -1; + case GL_RGBA: + 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_RGBA; + default: + ; /* fallthrough */ } /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0). */ if (_mesa_is_gles(ctx)) { switch (internalFormat) { - case GL_BGRA: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_BGRA: + return GL_RGBA; + default: + ; /* fallthrough */ } } if (ctx->Extensions.ARB_ES2_compatibility) { switch (internalFormat) { - case GL_RGB565: - return GL_RGB; - default: - ; /* fallthrough */ + case GL_RGB565: + return GL_RGB; + default: + ; /* fallthrough */ } } if (ctx->Extensions.ARB_depth_texture) { switch (internalFormat) { - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - return GL_DEPTH_COMPONENT; - case GL_DEPTH_STENCIL: - case GL_DEPTH24_STENCIL8: - return GL_DEPTH_STENCIL; - default: - ; /* fallthrough */ + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + return GL_DEPTH_COMPONENT; + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return GL_DEPTH_STENCIL; + default: + ; /* fallthrough */ + } + } + + if (ctx->Extensions.ARB_stencil_texturing) { + switch (internalFormat) { + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX8: + return GL_STENCIL_INDEX; + default: + ; /* fallthrough */ } } @@ -189,12 +250,12 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) if (ctx->Extensions.TDFX_texture_compression_FXT1) { switch (internalFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - return GL_RGB; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_COMPRESSED_RGB_FXT1_3DFX: + return GL_RGB; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return GL_RGBA; + default: + ; /* fallthrough */ } } @@ -202,28 +263,28 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) */ if (ctx->Extensions.ANGLE_texture_compression_dxt) { switch (internalFormat) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return GL_RGB; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return GL_RGB; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return GL_RGBA; + default: + ; /* fallthrough */ } } if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ANGLE_texture_compression_dxt) { switch (internalFormat) { - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - return GL_RGB; - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - return GL_RGBA; - default: - ; /* fallthrough */ + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + return GL_RGB; + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + return GL_RGBA; + default: + ; /* fallthrough */ } } @@ -234,65 +295,65 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) if (ctx->Extensions.ARB_texture_float) { switch (internalFormat) { - case GL_ALPHA16F_ARB: - case GL_ALPHA32F_ARB: - return GL_ALPHA; - case GL_RGBA16F_ARB: - case GL_RGBA32F_ARB: - return GL_RGBA; - case GL_RGB16F_ARB: - case GL_RGB32F_ARB: - return GL_RGB; - case GL_INTENSITY16F_ARB: - case GL_INTENSITY32F_ARB: - return GL_INTENSITY; - case GL_LUMINANCE16F_ARB: - case GL_LUMINANCE32F_ARB: - return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA16F_ARB: - case GL_LUMINANCE_ALPHA32F_ARB: - return GL_LUMINANCE_ALPHA; - default: - ; /* fallthrough */ + case GL_ALPHA16F_ARB: + case GL_ALPHA32F_ARB: + return GL_ALPHA; + case GL_RGBA16F_ARB: + case GL_RGBA32F_ARB: + return GL_RGBA; + case GL_RGB16F_ARB: + case GL_RGB32F_ARB: + return GL_RGB; + case GL_INTENSITY16F_ARB: + case GL_INTENSITY32F_ARB: + return GL_INTENSITY; + case GL_LUMINANCE16F_ARB: + case GL_LUMINANCE32F_ARB: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA16F_ARB: + case GL_LUMINANCE_ALPHA32F_ARB: + return GL_LUMINANCE_ALPHA; + default: + ; /* fallthrough */ } } if (ctx->Extensions.EXT_texture_snorm) { switch (internalFormat) { - case GL_RED_SNORM: - case GL_R8_SNORM: - case GL_R16_SNORM: - return GL_RED; - case GL_RG_SNORM: - case GL_RG8_SNORM: - case GL_RG16_SNORM: - return GL_RG; - case GL_RGB_SNORM: - case GL_RGB8_SNORM: - case GL_RGB16_SNORM: - return GL_RGB; - case GL_RGBA_SNORM: - case GL_RGBA8_SNORM: - case GL_RGBA16_SNORM: - return GL_RGBA; - case GL_ALPHA_SNORM: - case GL_ALPHA8_SNORM: - case GL_ALPHA16_SNORM: - return GL_ALPHA; - case GL_LUMINANCE_SNORM: - case GL_LUMINANCE8_SNORM: - case GL_LUMINANCE16_SNORM: - return GL_LUMINANCE; - case GL_LUMINANCE_ALPHA_SNORM: - case GL_LUMINANCE8_ALPHA8_SNORM: - case GL_LUMINANCE16_ALPHA16_SNORM: - return GL_LUMINANCE_ALPHA; - case GL_INTENSITY_SNORM: - case GL_INTENSITY8_SNORM: - case GL_INTENSITY16_SNORM: - return GL_INTENSITY; - default: - ; /* fallthrough */ + case GL_RED_SNORM: + case GL_R8_SNORM: + case GL_R16_SNORM: + return GL_RED; + case GL_RG_SNORM: + case GL_RG8_SNORM: + case GL_RG16_SNORM: + return GL_RG; + case GL_RGB_SNORM: + case GL_RGB8_SNORM: + case GL_RGB16_SNORM: + return GL_RGB; + case GL_RGBA_SNORM: + case GL_RGBA8_SNORM: + case GL_RGBA16_SNORM: + return GL_RGBA; + case GL_ALPHA_SNORM: + case GL_ALPHA8_SNORM: + case GL_ALPHA16_SNORM: + return GL_ALPHA; + case GL_LUMINANCE_SNORM: + case GL_LUMINANCE8_SNORM: + case GL_LUMINANCE16_SNORM: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA_SNORM: + case GL_LUMINANCE8_ALPHA8_SNORM: + case GL_LUMINANCE16_ALPHA16_SNORM: + return GL_LUMINANCE_ALPHA; + case GL_INTENSITY_SNORM: + case GL_INTENSITY8_SNORM: + case GL_INTENSITY16_SNORM: + return GL_INTENSITY; + default: + ; /* fallthrough */ } } @@ -727,87 +788,6 @@ proxy_target(GLenum target) } -/** - * Return a pointer to the current texture object for the given target - * on the current texture unit. - * Note: all <target> error checking should have been done by this point. - */ -struct gl_texture_object * -_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) -{ - struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); - const GLboolean arrayTex = ctx->Extensions.EXT_texture_array; - - switch (target) { - case GL_TEXTURE_1D: - return texUnit->CurrentTex[TEXTURE_1D_INDEX]; - case GL_PROXY_TEXTURE_1D: - return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; - case GL_TEXTURE_2D: - return texUnit->CurrentTex[TEXTURE_2D_INDEX]; - case GL_PROXY_TEXTURE_2D: - return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; - case GL_TEXTURE_3D: - return texUnit->CurrentTex[TEXTURE_3D_INDEX]; - case GL_PROXY_TEXTURE_3D: - return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_ARB: - return ctx->Extensions.ARB_texture_cube_map - ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - return ctx->Extensions.ARB_texture_cube_map - ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; - case GL_TEXTURE_CUBE_MAP_ARRAY: - return ctx->Extensions.ARB_texture_cube_map_array - ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: - return ctx->Extensions.ARB_texture_cube_map_array - ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; - case GL_TEXTURE_RECTANGLE_NV: - return ctx->Extensions.NV_texture_rectangle - ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; - case GL_PROXY_TEXTURE_RECTANGLE_NV: - return ctx->Extensions.NV_texture_rectangle - ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; - case GL_TEXTURE_1D_ARRAY_EXT: - return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_1D_ARRAY_EXT: - return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; - case GL_TEXTURE_2D_ARRAY_EXT: - return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_2D_ARRAY_EXT: - return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; - case GL_TEXTURE_BUFFER: - return ctx->API == API_OPENGL_CORE && - ctx->Extensions.ARB_texture_buffer_object ? - texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; - case GL_TEXTURE_EXTERNAL_OES: - return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external - ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; - case GL_TEXTURE_2D_MULTISAMPLE: - return ctx->Extensions.ARB_texture_multisample - ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; - case GL_PROXY_TEXTURE_2D_MULTISAMPLE: - return ctx->Extensions.ARB_texture_multisample - ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; - case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - return ctx->Extensions.ARB_texture_multisample - ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; - case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: - return ctx->Extensions.ARB_texture_multisample - ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; - default: - _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()"); - return NULL; - } -} - /** @@ -815,7 +795,6 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) * target and mipmap level. The target and level parameters should * have already been error-checked. * - * \param ctx GL context. * \param texObj texture unit. * \param target texture target. * \param level image level. @@ -823,9 +802,8 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) * \return pointer to the texture image structure, or NULL on failure. */ struct gl_texture_image * -_mesa_select_tex_image(struct gl_context *ctx, - const struct gl_texture_object *texObj, - GLenum target, GLint level) +_mesa_select_tex_image(const struct gl_texture_object *texObj, + GLenum target, GLint level) { const GLuint face = _mesa_tex_target_to_face(target); @@ -851,7 +829,7 @@ _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, if (!texObj) return NULL; - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { @@ -1313,7 +1291,7 @@ init_teximage_fields_ms(struct gl_context *ctx, target = img->TexObject->Target; img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); - ASSERT(img->_BaseFormat > 0); + ASSERT(img->_BaseFormat != -1); img->InternalFormat = internalFormat; img->Border = border; img->Width = width; @@ -1604,12 +1582,11 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, * \return GL_TRUE if error found, GL_FALSE otherwise. */ static GLboolean -error_check_subtexture_dimensions(struct gl_context *ctx, - const char *function, GLuint dims, +error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims, const struct gl_texture_image *destImage, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei subWidth, GLsizei subHeight, - GLsizei subDepth) + GLsizei subDepth, const char *func) { const GLenum target = destImage->TexObject->Target; GLuint bw, bh; @@ -1617,32 +1594,32 @@ error_check_subtexture_dimensions(struct gl_context *ctx, /* Check size */ if (subWidth < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s%dD(width=%d)", function, dims, subWidth); + "%s%dD(width=%d)", func, dims, subWidth); return GL_TRUE; } if (dims > 1 && subHeight < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s%dD(height=%d)", function, dims, subHeight); + "%s%dD(height=%d)", func, dims, subHeight); return GL_TRUE; } if (dims > 2 && subDepth < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s%dD(depth=%d)", function, dims, subDepth); + "%s%dD(depth=%d)", func, dims, subDepth); return GL_TRUE; } /* check xoffset and width */ if (xoffset < - (GLint) destImage->Border) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset)", - function, dims); + func, dims); return GL_TRUE; } if (xoffset + subWidth > (GLint) destImage->Width) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(xoffset+width)", - function, dims); + func, dims); return GL_TRUE; } @@ -1651,28 +1628,33 @@ error_check_subtexture_dimensions(struct gl_context *ctx, GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border; if (yoffset < -yBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset)", - function, dims); + func, dims); return GL_TRUE; } if (yoffset + subHeight > (GLint) destImage->Height) { _mesa_error(ctx, GL_INVALID_VALUE, "%s%dD(yoffset+height)", - function, dims); + func, dims); return GL_TRUE; } } /* check zoffset and depth */ if (dims > 2) { + GLint depth; GLint zBorder = (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 0 : destImage->Border; if (zoffset < -zBorder) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", function); + _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset)", func); return GL_TRUE; } - if (zoffset + subDepth > (GLint) destImage->Depth) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset+depth)", function); + + depth = (GLint) destImage->Depth; + if (target == GL_TEXTURE_CUBE_MAP) + depth = 6; + if (zoffset + subDepth > depth) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s3D(zoffset+depth)", func); return GL_TRUE; } } @@ -1691,7 +1673,7 @@ error_check_subtexture_dimensions(struct gl_context *ctx, if ((xoffset % bw != 0) || (yoffset % bh != 0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s%dD(xoffset = %d, yoffset = %d)", - function, dims, xoffset, yoffset); + func, dims, xoffset, yoffset); return GL_TRUE; } @@ -1703,14 +1685,14 @@ error_check_subtexture_dimensions(struct gl_context *ctx, if ((subWidth % bw != 0) && (xoffset + subWidth != (GLint) destImage->Width)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "%s%dD(width = %d)", function, dims, subWidth); + "%s%dD(width = %d)", func, dims, subWidth); return GL_TRUE; } if ((subHeight % bh != 0) && (yoffset + subHeight != (GLint) destImage->Height)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "%s%dD(height = %d)", function, dims, subHeight); + "%s%dD(height = %d)", func, dims, subHeight); return GL_TRUE; } } @@ -1889,7 +1871,8 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) * proxy targets are not supported. */ static GLboolean -legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) +legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, + bool dsa) { switch (dims) { case 1: @@ -1923,6 +1906,13 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; + + /* Table 8.15 of the OpenGL 4.5 core profile spec + * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D + * and CopyTextureSubImage3D. + */ + case GL_TEXTURE_CUBE_MAP: + return dsa; default: return GL_FALSE; } @@ -1942,6 +1932,9 @@ static GLboolean mutable_tex_object(struct gl_context *ctx, GLenum target) { struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return GL_FALSE; + return !texObj->Immutable; } @@ -2137,7 +2130,7 @@ texture_error_check( struct gl_context *ctx, if (_mesa_is_gles(ctx)) { if (_mesa_is_gles3(ctx)) { - err = _mesa_es3_error_check_format_and_type(format, type, + err = _mesa_es3_error_check_format_and_type(ctx, format, type, internalFormat); } else { if (format != internalFormat) { @@ -2317,14 +2310,14 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, case GL_PALETTE8_RGB5_A1_OES: /* check level (note that level should be zero or less!) */ if (level > 0 || level < -maxLevels) { - reason = "level"; - error = GL_INVALID_VALUE; + reason = "level"; + error = GL_INVALID_VALUE; goto error; } if (dimensions != 2) { - reason = "compressed paletted textures must be 2D"; - error = GL_INVALID_OPERATION; + reason = "compressed paletted textures must be 2D"; + error = GL_INVALID_OPERATION; goto error; } @@ -2332,7 +2325,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, * checked against the actual size later. */ expectedSize = _mesa_cpal_compressed_size(level, internalFormat, - width, height); + width, height); /* This is for the benefit of the TestProxyTexImage below. It expects * level to be non-negative. OES_compressed_paletted_texture uses a @@ -2347,8 +2340,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, default: /* check level */ if (level < 0 || level >= maxLevels) { - reason = "level"; - error = GL_INVALID_VALUE; + reason = "level"; + error = GL_INVALID_VALUE; goto error; } @@ -2401,7 +2394,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, error: /* Note: not all error paths exit through here. */ - _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason); + _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", + dimensions, reason); return GL_TRUE; } @@ -2431,26 +2425,34 @@ error: */ static GLboolean texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, + struct gl_texture_object *texObj, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint width, GLint height, GLint depth, - GLenum format, GLenum type) + GLenum format, GLenum type, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLenum err; + const char* suffix = dsa ? "ture" : ""; + + if (!texObj) { + /* must be out of memory */ + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sSubImage%dD()", + suffix, dimensions); + return GL_TRUE; + } /* check target (proxies not allowed) */ - if (!legal_texsubimage_target(ctx, dimensions, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", - dimensions, _mesa_lookup_enum_by_nr(target)); + if (!legal_texsubimage_target(ctx, dimensions, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sSubImage%uD(target=%s)", + suffix, dimensions, _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } /* level check */ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%uD(level=%d)", - dimensions, level); + _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sSubImage%uD(level=%d)", + suffix, dimensions, level); return GL_TRUE; } @@ -2463,9 +2465,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, err = _mesa_es_error_check_format_and_type(format, type, dimensions); if (err != GL_NO_ERROR) { _mesa_error(ctx, err, - "glTexSubImage%dD(format = %s, type = %s)", - dimensions, - _mesa_lookup_enum_by_nr(format), + "glTex%sSubImage%dD(format = %s, type = %s)", + suffix, dimensions, _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); return GL_TRUE; } @@ -2474,38 +2475,34 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, err = _mesa_error_check_format_and_type(ctx, format, type); if (err != GL_NO_ERROR) { _mesa_error(ctx, err, - "glTexSubImage%dD(incompatible format = %s, type = %s)", - dimensions, _mesa_lookup_enum_by_nr(format), + "glTex%sSubImage%dD(incompatible format = %s, type = %s)", + suffix, dimensions, _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); return GL_TRUE; } - /* Get dest texture object / image pointers */ - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - /* must be out of memory */ - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage%dD()", dimensions); - return GL_TRUE; - } - - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { /* non-existant texture level */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage%dD(invalid texture image)", dimensions); + "glTex%sSubImage%dD(invalid texture image)", suffix, + dimensions); return GL_TRUE; } - if (error_check_subtexture_dimensions(ctx, "glTexSubImage", dimensions, + if (error_check_subtexture_dimensions(ctx, dimensions, texImage, xoffset, yoffset, 0, - width, height, 1)) { + width, height, 1, + dsa ? "glTextureSubImage" : + "glTexSubImage")) { return GL_TRUE; } if (_mesa_is_format_compressed(texImage->TexFormat)) { if (compressedteximage_only_format(ctx, texImage->InternalFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage%dD(no compression for format)", dimensions); + "glTex%sSubImage%dD(no compression for format)", + suffix, dimensions); return GL_TRUE; } } @@ -2515,8 +2512,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, if (_mesa_is_format_integer_color(texImage->TexFormat) != _mesa_is_enum_format_integer(format)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexSubImage%dD(integer/non-integer format mismatch)", - dimensions); + "glTex%sSubImage%dD(integer/non-integer format mismatch)", + suffix, dimensions); return GL_TRUE; } } @@ -2554,7 +2551,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, GLenum rb_internal_format; /* check target */ - if (!legal_texsubimage_target(ctx, dimensions, target)) { + if (!legal_texsubimage_target(ctx, dimensions, target, false)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", dimensions, _mesa_lookup_enum_by_nr(target)); return GL_TRUE; @@ -2579,10 +2576,9 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } if (ctx->ReadBuffer->Visual.samples > 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexImage%dD(multisample FBO)", - dimensions); - return GL_TRUE; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexImage%dD(multisample FBO)", dimensions); + return GL_TRUE; } } @@ -2791,12 +2787,13 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, */ static GLboolean copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, + const struct gl_texture_object *texObj, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLint width, GLint height) + GLint width, GLint height, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; + const char *suffix = dsa ? "ture" : ""; /* Check that the source buffer is complete */ if (_mesa_is_user_fbo(ctx->ReadBuffer)) { @@ -2805,89 +2802,97 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, } if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glCopyTexImage%dD(invalid readbuffer)", dimensions); + "glCopyTex%sSubImage%dD(invalid readbuffer)", + suffix, dimensions); return GL_TRUE; } if (ctx->ReadBuffer->Visual.samples > 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(multisample FBO)", - dimensions); - return GL_TRUE; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTex%sSubImage%dD(multisample FBO)", suffix, + dimensions); + return GL_TRUE; } } /* check target (proxies not allowed) */ - if (!legal_texsubimage_target(ctx, dimensions, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)", - dimensions, _mesa_lookup_enum_by_nr(target)); + if (!legal_texsubimage_target(ctx, dimensions, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTex%sSubImage%uD(target=%s)", + suffix, dimensions, + _mesa_lookup_enum_by_nr(target)); return GL_TRUE; } /* Check level */ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexSubImage%dD(level=%d)", dimensions, level); + "glCopyTex%sSubImage%dD(level=%d)", suffix, + dimensions, level); return GL_TRUE; } - /* Get dest texture object / image pointers */ - texObj = _mesa_get_current_tex_object(ctx, target); + /* Get dest image pointers */ if (!texObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%dD()", dimensions); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTex%sSubImage%dD()", + suffix, dimensions); return GL_TRUE; } - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { /* destination image does not exist */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(invalid texture image)", dimensions); + "glCopyTex%sSubImage%dD(invalid texture image)", + suffix, dimensions); return GL_TRUE; } - if (error_check_subtexture_dimensions(ctx, "glCopyTexSubImage", - dimensions, texImage, + if (error_check_subtexture_dimensions(ctx, dimensions, texImage, xoffset, yoffset, zoffset, - width, height, 1)) { + width, height, 1, dsa ? + "glCompressedTextureSubImage" : + "glCompressedTexSubImage")) { return GL_TRUE; } if (_mesa_is_format_compressed(texImage->TexFormat)) { if (compressedteximage_only_format(ctx, texImage->InternalFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(no compression for format)", dimensions); + "glCopyTex%sSubImage%dD(no compression for format)", + suffix, dimensions); return GL_TRUE; } } if (texImage->InternalFormat == GL_YCBCR_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTex%sSubImage2D", suffix); return GL_TRUE; } if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", - dimensions, texImage->_BaseFormat); + "glCopyTex%sSubImage%dD(missing readbuffer, format=0x%x)", + suffix, dimensions, texImage->_BaseFormat); return GL_TRUE; } /* From the EXT_texture_integer spec: * - * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* - * if the texture internalformat is an integer format and the read color - * buffer is not an integer format, or if the internalformat is not an - * integer format and the read color buffer is an integer format." + * "INVALID_OPERATION is generated by CopyTexImage* and + * CopyTexSubImage* if the texture internalformat is an integer format + * and the read color buffer is not an integer format, or if the + * internalformat is not an integer format and the read color buffer + * is an integer format." */ if (_mesa_is_color_format(texImage->InternalFormat)) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; if (_mesa_is_format_integer_color(rb->Format) != - _mesa_is_format_integer_color(texImage->TexFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCopyTexImage%dD(integer vs non-integer)", dimensions); - return GL_TRUE; + _mesa_is_format_integer_color(texImage->TexFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTex%sSubImage%dD(integer vs non-integer)", + suffix, dimensions); + return GL_TRUE; } } @@ -2969,7 +2974,6 @@ static inline void check_gen_mipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj, GLint level) { - ASSERT(target != GL_TEXTURE_CUBE_MAP); if (texObj->GenerateMipmap && level == texObj->BaseLevel && level < texObj->MaxLevel) { @@ -3042,7 +3046,7 @@ _mesa_choose_texture_format(struct gl_context *ctx, /* see if we've already chosen a format for the previous level */ if (level > 0) { struct gl_texture_image *prevImage = - _mesa_select_tex_image(ctx, texObj, target, level - 1); + _mesa_select_tex_image(texObj, target, level - 1); /* See if the prev level is defined and has an internal format which * matches the new internal format. */ @@ -3239,6 +3243,19 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, texFormat = _mesa_glenum_to_compressed_format(internalFormat); } else { + /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized + * internal floating point format for the given base format. + */ + if (_mesa_is_gles(ctx) && format == internalFormat) { + if (type == GL_FLOAT) { + texObj->_IsFloat = GL_TRUE; + } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) { + texObj->_IsHalfFloat = GL_TRUE; + } + + internalFormat = adjust_for_oes_float_texture(format, type); + } + texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, internalFormat, format, type); } @@ -3419,13 +3436,13 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) if (!valid_target) { _mesa_error(ctx, GL_INVALID_ENUM, - "glEGLImageTargetTexture2D(target=%d)", target); + "glEGLImageTargetTexture2D(target=%d)", target); return; } if (!image) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetTexture2D(image=%p)", image); + "glEGLImageTargetTexture2D(image=%p)", image); return; } @@ -3433,11 +3450,14 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) _mesa_update_state(ctx); texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + _mesa_lock_texture(ctx, texObj); if (texObj->Immutable) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glEGLImageTargetTexture2D(texture is immutable)"); + "glEGLImageTargetTexture2D(texture is immutable)"); _mesa_unlock_texture(ctx, texObj); return; } @@ -3458,32 +3478,26 @@ _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) } - /** - * Implement all the glTexSubImage1/2/3D() functions. + * Helper that implements the glTexSubImage1/2/3D() + * and glTextureSubImage1/2/3D() functions. */ -static void -texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const GLvoid *pixels ) +void +_mesa_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + bool dsa) { - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", - dims, - _mesa_lookup_enum_by_nr(target), level, - xoffset, yoffset, zoffset, width, height, depth, - _mesa_lookup_enum_by_nr(format), - _mesa_lookup_enum_by_nr(type), pixels); - /* check target (proxies not allowed) */ - if (!legal_texsubimage_target(ctx, dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", + if (!legal_texsubimage_target(ctx, dims, target, dsa)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sSubImage%uD(target=%s)", + dsa ? "ture" : "", dims, _mesa_lookup_enum_by_nr(target)); return; } @@ -3491,18 +3505,8 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, if (ctx->NewState & _NEW_PIXEL) _mesa_update_state(ctx); - if (texsubimage_error_check(ctx, dims, target, level, - xoffset, yoffset, zoffset, - width, height, depth, format, type)) { - return; /* error was detected */ - } - - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (width > 0 && height > 0 && depth > 0) { /* If we have a border, offset=-1 is legal. Bias by border width. */ switch (dims) { @@ -3533,6 +3537,162 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, _mesa_unlock_texture(ctx, texObj); } +/** + * Implement all the glTexSubImage1/2/3D() functions. + * Must split this out this way because of GL_TEXTURE_CUBE_MAP. + */ +static void +texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + if (texsubimage_error_check(ctx, dims, texObj, target, level, + xoffset, yoffset, zoffset, + width, height, depth, format, type, false)) { + return; /* error was detected */ + } + + texImage = _mesa_select_tex_image(texObj, target, level); + /* texsubimage_error_check ensures that texImage is not NULL */ + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", + dims, + _mesa_lookup_enum_by_nr(target), level, + xoffset, yoffset, zoffset, width, height, depth, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type), pixels); + + _mesa_texture_sub_image(ctx, dims, texObj, texImage, target, level, + xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels, false); +} + + +/** + * Implement all the glTextureSubImage1/2/3D() functions. + * Must split this out this way because of GL_TEXTURE_CUBE_MAP. + */ +static void +texturesubimage(struct gl_context *ctx, GLuint dims, + GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int i; + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, + "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n", + dims, texture, level, + xoffset, yoffset, zoffset, width, height, depth, + _mesa_lookup_enum_by_nr(format), + _mesa_lookup_enum_by_nr(type), pixels); + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureSubImage%uD(texture)", + dims); + return; + } + + if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level, + xoffset, yoffset, zoffset, + width, height, depth, format, type, true)) { + return; /* error was detected */ + } + + + /* Must handle special case GL_TEXTURE_CUBE_MAP. */ + if (texObj->Target == GL_TEXTURE_CUBE_MAP) { + GLint rowStride; + + /* Error checking */ + if (texObj->NumLayers < 6) { + /* Not enough image planes for a cube map. The spec does not say + * what should happen in this case because the user has always + * specified each cube face separately (using + * GL_TEXTURE_CUBE_MAP_POSITIVE_X+i) in previous GL versions. + * This is addressed in Khronos Bug 13223. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureSubImage%uD(insufficient cube map storage)", + dims); + return; + } + + /* + * What do we do if the user created a texture with the following code + * and then called this function with its handle? + * + * GLuint tex; + * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); + * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); + * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the + * // wrong format, or given the wrong size, etc. + * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); + * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); + * + * A bug has been filed against the spec for this case. In the + * meantime, we will check for cube completeness. + * + * According to Section 8.17 Texture Completeness in the OpenGL 4.5 + * Core Profile spec (30.10.2014): + * "[A] cube map texture is cube complete if the + * following conditions all hold true: The [base level] texture + * images of each of the six cube map faces have identical, positive, + * and square dimensions. The [base level] images were each specified + * with the same internal format." + * + * It seems reasonable to check for cube completeness of an arbitrary + * level here so that the image data has a consistent format and size. + */ + if (!_mesa_cube_level_complete(texObj, level)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureSubImage%uD(cube map incomplete)", + dims); + return; + } + + rowStride = _mesa_image_image_stride(&ctx->Unpack, width, height, + format, type); + /* Copy in each face. */ + for (i = 0; i < 6; ++i) { + texImage = texObj->Image[i][level]; + _mesa_texture_sub_image(ctx, 3, texObj, texImage, texObj->Target, + level, xoffset, yoffset, zoffset, + width, height, 1, format, + type, pixels, true); + pixels = (GLubyte *) pixels + rowStride; + } + } + else { + texImage = _mesa_select_tex_image(texObj, texObj->Target, level); + if (!texImage) + return; + + _mesa_texture_sub_image(ctx, dims, texObj, texImage, texObj->Target, + level, xoffset, yoffset, zoffset, + width, height, depth, format, + type, pixels, true); + } +} + void GLAPIENTRY _mesa_TexSubImage1D( GLenum target, GLint level, @@ -3578,6 +3738,48 @@ _mesa_TexSubImage3D( GLenum target, GLint level, format, type, pixels); } +void GLAPIENTRY +_mesa_TextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage(ctx, 1, texture, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels); +} + + +void GLAPIENTRY +_mesa_TextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage(ctx, 2, texture, level, + xoffset, yoffset, 0, + width, height, 1, + format, type, pixels); +} + + +void GLAPIENTRY +_mesa_TextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + texturesubimage(ctx, 3, texture, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels); +} /** @@ -3811,40 +4013,40 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, x, y, width, height, border); } - - /** - * Implementation for glCopyTexSubImage1/2/3D() functions. + * Implementation for glCopyTex(ture)SubImage1/2/3D() functions. */ -static void -copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height) +void +_mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height, + bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; FLUSH_VERTICES(ctx, 0); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n", - dims, + _mesa_debug(ctx, "glCopyTex%sSubImage%uD %s %d %d %d %d %d %d %d %d\n", + dsa ? "ture" : "", dims, _mesa_lookup_enum_by_nr(target), level, xoffset, yoffset, zoffset, x, y, width, height); if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); - if (copytexsubimage_error_check(ctx, dims, target, level, - xoffset, yoffset, zoffset, width, height)) { + if (copytexsubimage_error_check(ctx, dims, texObj, target, level, + xoffset, yoffset, zoffset, + width, height, dsa)) { return; } - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); /* If we have a border, offset=-1 is legal. Bias by border width. */ switch (dims) { @@ -3879,13 +4081,19 @@ copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, _mesa_unlock_texture(ctx, texObj); } - void GLAPIENTRY _mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ) { + struct gl_texture_object* texObj; GET_CURRENT_CONTEXT(ctx); - copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 1, texObj, target, level, xoffset, 0, 0, + x, y, width, 1, false); } @@ -3895,9 +4103,16 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { + struct gl_texture_object* texObj; GET_CURRENT_CONTEXT(ctx); - copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y, - width, height); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 2, texObj, target, level, + xoffset, yoffset, 0, + x, y, width, height, false); } @@ -3907,9 +4122,67 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) { + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 3, texObj, target, level, + xoffset, yoffset, zoffset, + x, y, width, height, false); +} + +void GLAPIENTRY +_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage1D"); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 1, texObj, texObj->Target, level, + xoffset, 0, 0, x, y, width, 1, true); +} + +void GLAPIENTRY +_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage2D"); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 2, texObj, texObj->Target, level, + xoffset, yoffset, 0, + x, y, width, height, true); +} + + + +void GLAPIENTRY +_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_object* texObj; GET_CURRENT_CONTEXT(ctx); - copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, - x, y, width, height); + + texObj = _mesa_lookup_texture_err(ctx, texture, "glCopyTextureSubImage3D"); + if (!texObj) + return; + + _mesa_copy_texture_sub_image(ctx, 3, texObj, texObj->Target, level, + xoffset, yoffset, zoffset, + x, y, width, height, true); } static bool @@ -4031,7 +4304,7 @@ get_tex_images_for_clear(struct gl_context *ctx, for (i = 0; i < MAX_FACES; i++) { target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; - texImages[i] = _mesa_select_tex_image(ctx, texObj, target, level); + texImages[i] = _mesa_select_tex_image(texObj, target, level); if (texImages[i] == NULL) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); @@ -4042,7 +4315,7 @@ get_tex_images_for_clear(struct gl_context *ctx, return MAX_FACES; } - texImages[0] = _mesa_select_tex_image(ctx, texObj, texObj->Target, level); + texImages[0] = _mesa_select_tex_image(texObj, texObj->Target, level); if (texImages[0] == NULL) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); @@ -4186,15 +4459,22 @@ out: */ static GLboolean compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, + const struct gl_texture_object *texObj, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize) + GLenum format, GLsizei imageSize, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLint expectedSize; GLboolean targetOK; + const char *suffix = dsa ? "ture" : ""; + + if (dsa && target == GL_TEXTURE_RECTANGLE) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedSubTexture%dD(target)", dims); + return GL_TRUE; + } switch (dims) { case 2: @@ -4214,7 +4494,52 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } break; case 3: - targetOK = (target == GL_TEXTURE_2D_ARRAY); + targetOK = (target == GL_TEXTURE_3D) || + (target == GL_TEXTURE_2D_ARRAY) || + (target == GL_TEXTURE_CUBE_MAP_ARRAY) || + (target == GL_TEXTURE_CUBE_MAP && dsa); + + /* OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture + * Images: + * "An INVALID_OPERATION error is generated by + * CompressedTex*SubImage3D if the internal format of the texture is + * one of the EAC, ETC2, or RGTC formats and either border is + * non-zero, or the effective target for the texture is not + * TEXTURE_2D_ARRAY." + */ + if (target != GL_TEXTURE_2D_ARRAY) { + bool invalidformat; + switch (format) { + /* These came from _mesa_is_compressed_format in glformats.c. */ + /* EAC formats */ + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + /* ETC2 formats */ + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + /* RGTC formats */ + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + case GL_COMPRESSED_RG_RGTC2: + case GL_COMPRESSED_SIGNED_RG_RGTC2: + invalidformat = true; + break; + default: + invalidformat = false; + } + if (invalidformat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTex%sSubImage%uD(target)", suffix, dims); + return GL_TRUE; + } + } + break; default: assert(dims == 1); @@ -4224,68 +4549,67 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } if (!targetOK) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexSubImage%uD(target)", - dims); + _mesa_error(ctx, GL_INVALID_ENUM, + "glCompressedTex%sSubImage%uD(target)", suffix, dims); return GL_TRUE; } /* this will catch any invalid compressed format token */ if (!_mesa_is_compressed_format(ctx, format)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(format)", - dims); + _mesa_error(ctx, GL_INVALID_ENUM, + "glCompressedTex%sSubImage%uD(format)", suffix, dims); return GL_TRUE; } if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(level=%d)", - dims, level); + _mesa_error(ctx, GL_INVALID_VALUE, + "glCompressedTex%sSubImage%uD(level=%d)", + suffix, dims, level); return GL_TRUE; } /* Check for invalid pixel storage modes */ if (!_mesa_compressed_pixel_storage_error_check(ctx, dims, - &ctx->Unpack, - "glCompressedTexSubImage")) { + &ctx->Unpack, + dsa ? "glCompressedTextureSubImage" : + "glCompressedTexSubImage")) { return GL_TRUE; } expectedSize = compressed_tex_size(width, height, depth, format); if (expectedSize != imageSize) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(size=%d)", - dims, imageSize); - return GL_TRUE; - } - - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glCompressedTexSubImage%uD()", dims); + _mesa_error(ctx, GL_INVALID_VALUE, + "glCompressedTex%sSubImage%uD(size=%d)", + suffix, dims, imageSize); return GL_TRUE; } - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage%uD(invalid texture image)", dims); + "glCompressedTex%sSubImage%uD(invalid texture image)", + suffix, dims); return GL_TRUE; } if ((GLint) format != texImage->InternalFormat) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage%uD(format=0x%x)", dims, format); + "glCompressedTex%sSubImage%uD(format=0x%x)", + suffix, dims, format); return GL_TRUE; } if (compressedteximage_only_format(ctx, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" - , dims, format); + "glCompressedTex%sSubImage%uD(format=0x%x cannot be updated)", + suffix, dims, format); return GL_TRUE; } - if (error_check_subtexture_dimensions(ctx, "glCompressedTexSubImage", dims, + if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset, zoffset, - width, height, depth)) { + width, height, depth, + "glCompressedTexSubImage")) { return GL_TRUE; } @@ -4330,31 +4654,34 @@ _mesa_CompressedTexImage3D(GLenum target, GLint level, /** - * Common helper for glCompressedTexSubImage1/2/3D(). + * Common helper for glCompressedTexSubImage1/2/3D() and + * glCompressedTextureSubImage1/2/3D(). */ -static void -compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, const GLvoid *data) +void +_mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data, bool dsa) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (compressed_subtexture_error_check(ctx, dims, target, level, - xoffset, yoffset, zoffset, + if (compressed_subtexture_error_check(ctx, dims, texObj, target, + level, xoffset, yoffset, zoffset, width, height, depth, - format, imageSize)) { + format, imageSize, dsa)) { return; } - texObj = _mesa_get_current_tex_object(ctx, target); + FLUSH_VERTICES(ctx, 0); _mesa_lock_texture(ctx, texObj); { - texImage = _mesa_select_tex_image(ctx, texObj, target, level); + texImage = _mesa_select_tex_image(texObj, target, level); assert(texImage); if (width > 0 && height > 0 && depth > 0) { @@ -4376,33 +4703,116 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, void GLAPIENTRY _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, - GLsizei width, GLenum format, - GLsizei imageSize, const GLvoid *data) + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, - format, imageSize, data); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 1, texObj, target, level, + xoffset, 0, 0, width, 1, 1, + format, imageSize, data, false); +} + +void GLAPIENTRY +_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glCompressedTextureSubImage1D"); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 1, texObj, texObj->Target, level, + xoffset, 0, 0, width, 1, 1, + format, imageSize, data, true); } void GLAPIENTRY _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data) + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) { - compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, - width, height, 1, format, imageSize, data); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 2, texObj, target, level, + xoffset, yoffset, 0, width, height, 1, + format, imageSize, data, false); } +void GLAPIENTRY +_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glCompressedTextureSubImage2D"); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 2, texObj, texObj->Target, level, + xoffset, yoffset, 0, width, height, 1, + format, imageSize, data, true); +} void GLAPIENTRY _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, - GLsizei imageSize, const GLvoid *data) + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) { - compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, - width, height, depth, format, imageSize, data); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 3, texObj, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, false); +} + +void GLAPIENTRY +_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glCompressedTextureSubImage3D"); + if (!texObj) + return; + + _mesa_compressed_texture_sub_image(ctx, 3, texObj, texObj->Target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, true); } static mesa_format @@ -4461,9 +4871,9 @@ get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) case GL_LUMINANCE_ALPHA8I_EXT: return MESA_FORMAT_LA_SINT8; case GL_LUMINANCE_ALPHA16I_EXT: - return MESA_FORMAT_LA_SINT8; - case GL_LUMINANCE_ALPHA32I_EXT: return MESA_FORMAT_LA_SINT16; + case GL_LUMINANCE_ALPHA32I_EXT: + return MESA_FORMAT_LA_SINT32; case GL_LUMINANCE_ALPHA8UI_EXT: return MESA_FORMAT_LA_UINT8; case GL_LUMINANCE_ALPHA16UI_EXT: @@ -4619,30 +5029,26 @@ _mesa_validate_texbuffer_format(const struct gl_context *ctx, } -static void -texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat, - struct gl_buffer_object *bufObj, - GLintptr offset, GLsizeiptr size) +void +_mesa_texture_buffer_range(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + GLenum internalFormat, + struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr size, bool range, + bool dsa) { - struct gl_texture_object *texObj; mesa_format format; FLUSH_VERTICES(ctx, 0); - if (target != GL_TEXTURE_BUFFER_ARB) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); - return; - } - format = _mesa_validate_texbuffer_format(ctx, internalFormat); if (format == MESA_FORMAT_NONE) { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)", - internalFormat); + _mesa_error(ctx, GL_INVALID_ENUM, + "glTex%sBuffer%s(internalFormat 0x%x)", dsa ? "ture" : "", + range ? "Range" : "", internalFormat); return; } - texObj = _mesa_get_current_tex_object(ctx, target); - _mesa_lock_texture(ctx, texObj); { _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj); @@ -4665,10 +5071,17 @@ texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat, void GLAPIENTRY _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) { + struct gl_texture_object *texObj; struct gl_buffer_object *bufObj; GET_CURRENT_CONTEXT(ctx); + /* Need to catch this before it gets to _mesa_get_current_tex_object */ + if (target != GL_TEXTURE_BUFFER_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); + return; + } + /* NOTE: ARB_texture_buffer_object has interactions with * the compatibility profile that are not implemented. */ @@ -4684,7 +5097,12 @@ _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) return; } - texbufferrange(ctx, target, internalFormat, bufObj, 0, buffer ? -1 : 0); + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj, 0, + buffer ? -1 : 0, false, false); } @@ -4693,10 +5111,17 @@ void GLAPIENTRY _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size) { + struct gl_texture_object *texObj; struct gl_buffer_object *bufObj; GET_CURRENT_CONTEXT(ctx); + /* Need to catch this before it gets to _mesa_get_current_tex_object */ + if (target != GL_TEXTURE_BUFFER_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexBufferRange(target)"); + return; + } + if (!(ctx->API == API_OPENGL_CORE && ctx->Extensions.ARB_texture_buffer_range)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBufferRange"); @@ -4725,9 +5150,52 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, size = 0; } - texbufferrange(ctx, target, internalFormat, bufObj, offset, size); + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_buffer_range(ctx, texObj, target, internalFormat, bufObj, + offset, size, true, false); } +void GLAPIENTRY +_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) +{ + struct gl_texture_object *texObj; + struct gl_buffer_object *bufObj; + + GET_CURRENT_CONTEXT(ctx); + + /* NOTE: ARB_texture_buffer_object has interactions with + * the compatibility profile that are not implemented. + */ + if (!(ctx->API == API_OPENGL_CORE && + ctx->Extensions.ARB_texture_buffer_object)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!bufObj && buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureBuffer(buffer %u)", + buffer); + return; + } + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture_err(ctx, texture, + "glTextureBuffer(texture)"); + if (!texObj) + return; + + if (texObj->Target != GL_TEXTURE_BUFFER_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTextureBuffer(target)"); + return; + } + + _mesa_texture_buffer_range(ctx, texObj, texObj->Target, internalFormat, + bufObj, 0, buffer ? -1 : 0, false, true); +} static GLboolean is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat) @@ -4742,16 +5210,18 @@ is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat) /** GL_ARB_texture_multisample */ static GLboolean -check_multisample_target(GLuint dims, GLenum target) +check_multisample_target(GLuint dims, GLenum target, bool dsa) { switch(target) { case GL_TEXTURE_2D_MULTISAMPLE: - case GL_PROXY_TEXTURE_2D_MULTISAMPLE: return dims == 2; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + return dims == 2 && !dsa; case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: - case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: return dims == 3; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + return dims == 3 && !dsa; default: return GL_FALSE; @@ -4759,19 +5229,20 @@ check_multisample_target(GLuint dims, GLenum target) } -static void -teximagemultisample(GLuint dims, GLenum target, GLsizei samples, - GLint internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLboolean fixedsamplelocations, - GLboolean immutable, const char *func) +void +_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations, + GLboolean immutable, const char *func) { - struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLboolean sizeOK, dimensionsOK, samplesOK; mesa_format texFormat; GLenum sample_count_error; - - GET_CURRENT_CONTEXT(ctx); + bool dsa = strstr(func, "ture") ? true : false; if (!(ctx->Extensions.ARB_texture_multisample && _mesa_is_desktop_gl(ctx))) { @@ -4779,9 +5250,15 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, return; } - if (!check_multisample_target(dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); - return; + if (!check_multisample_target(dims, target, dsa)) { + if (dsa) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", func); + return; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); + return; + } } /* check that the specified internalformat is color/depth/stencil-renderable; @@ -4819,8 +5296,6 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, return; } - texObj = _mesa_get_current_tex_object(ctx, target); - if (immutable && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture object 0)", @@ -4893,7 +5368,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples, } } - texObj->Immutable = immutable; + texObj->Immutable |= immutable; if (immutable) { _mesa_set_texture_view_state(ctx, texObj, target, 1); @@ -4909,9 +5384,17 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - teximagemultisample(2, target, samples, internalformat, - width, height, 1, fixedsamplelocations, GL_FALSE, - "glTexImage2DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 2, texObj, target, samples, + internalformat, width, height, 1, + fixedsamplelocations, GL_FALSE, + "glTexImage2DMultisample"); } @@ -4921,9 +5404,17 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - teximagemultisample(3, target, samples, internalformat, - width, height, depth, fixedsamplelocations, GL_FALSE, - "glTexImage3DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 3, texObj, target, samples, + internalformat, width, height, depth, + fixedsamplelocations, GL_FALSE, + "glTexImage3DMultisample"); } @@ -4932,9 +5423,17 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - teximagemultisample(2, target, samples, internalformat, - width, height, 1, fixedsamplelocations, GL_TRUE, - "glTexStorage2DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 2, texObj, target, samples, + internalformat, width, height, 1, + fixedsamplelocations, GL_TRUE, + "glTexStorage2DMultisample"); } void GLAPIENTRY @@ -4943,7 +5442,56 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - teximagemultisample(3, target, samples, internalformat, - width, height, depth, fixedsamplelocations, GL_TRUE, - "glTexStorage3DMultisample"); + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 3, texObj, target, samples, + internalformat, width, height, depth, + fixedsamplelocations, GL_TRUE, + "glTexStorage3DMultisample"); +} + +void GLAPIENTRY +_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glTextureStorage2DMultisample"); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 2, texObj, texObj->Target, samples, + internalformat, width, height, 1, + fixedsamplelocations, GL_TRUE, + "glTextureStorage2DMultisample"); +} + +void GLAPIENTRY +_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture_err(ctx, texture, + "glTextureStorage3DMultisample"); + if (!texObj) + return; + + _mesa_texture_image_multisample(ctx, 3, texObj, texObj->Target, samples, + internalformat, width, height, depth, + fixedsamplelocations, GL_TRUE, + "glTextureStorage3DMultisample"); } diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 4b27381a0..02b0eda38 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -47,7 +47,7 @@ _mesa_is_cube_face(GLenum target) target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB); } -/** Is any of the dimensions of given texture equal to zero? */ +/** Are any of the dimensions of given texture equal to zero? */ static inline GLboolean _mesa_is_zero_size_texture(const struct gl_texture_image *texImage) { @@ -99,13 +99,8 @@ _mesa_clear_texture_image(struct gl_context *ctx, struct gl_texture_image *texImage); -extern struct gl_texture_object * -_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target); - - extern struct gl_texture_image * -_mesa_select_tex_image(struct gl_context *ctx, - const struct gl_texture_object *texObj, +_mesa_select_tex_image(const struct gl_texture_object *texObj, GLenum target, GLint level); @@ -114,6 +109,16 @@ _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, GLenum target, GLint level); +/** + * Return the base-level texture image for the given texture object. + */ +static inline const struct gl_texture_image * +_mesa_base_tex_image(const struct gl_texture_object *texObj) +{ + return texObj->Image[0][texObj->BaseLevel]; +} + + extern GLint _mesa_max_texture_levels(struct gl_context *ctx, GLenum target); @@ -160,24 +165,51 @@ _mesa_legal_texture_base_format_for_target(struct gl_context *ctx, unsigned dimensions, const char *caller); -/** - * Lock a texture for updating. See also _mesa_lock_context_textures(). - */ -static inline void -_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - mtx_lock(&ctx->Shared->TexMutex); - ctx->Shared->TextureStateStamp++; - (void) texObj; -} +extern void +_mesa_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + bool dsa); -static inline void -_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - (void) texObj; - mtx_unlock(&ctx->Shared->TexMutex); -} +extern void +_mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data, bool dsa); + +extern void +_mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height, bool dsa); + +extern void +_mesa_texture_image_multisample(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations, + GLboolean immutable, const char *func); +extern void +_mesa_texture_buffer_range(struct gl_context *ctx, + struct gl_texture_object *texObj, GLenum target, + GLenum internalFormat, + struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr size, bool range, + bool dsa); /*@}*/ @@ -233,10 +265,31 @@ _mesa_TexSubImage3D( GLenum target, GLint level, GLenum format, GLenum type, const GLvoid *pixels ); +extern void GLAPIENTRY +_mesa_TextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels); + extern void GLAPIENTRY -_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLint border ); +_mesa_TextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels); + +extern void GLAPIENTRY +_mesa_TextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels); + + +extern void GLAPIENTRY +_mesa_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border); extern void GLAPIENTRY @@ -261,7 +314,21 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ); +extern void GLAPIENTRY +_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); +extern void GLAPIENTRY +_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); + +extern void GLAPIENTRY +_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height); extern void GLAPIENTRY _mesa_ClearTexSubImage( GLuint texture, GLint level, @@ -297,17 +364,36 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei imageSize, const GLvoid *data); extern void GLAPIENTRY +_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data); + +extern void GLAPIENTRY _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); extern void GLAPIENTRY +_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data); + +extern void GLAPIENTRY _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void GLAPIENTRY +_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *data); extern void GLAPIENTRY _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer); @@ -316,6 +402,9 @@ extern void GLAPIENTRY _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, GLintptr offset, GLsizeiptr size); +extern void GLAPIENTRY +_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer); + extern void GLAPIENTRY _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, @@ -339,6 +428,17 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +void GLAPIENTRY +_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + +void GLAPIENTRY +_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations); /*@}*/ #ifdef __cplusplus diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index f0ff605fc..59090db4e 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -49,6 +49,54 @@ /** \name Internal functions */ /*@{*/ +/** + * This function checks for all valid combinations of Min and Mag filters for + * Float types, when extensions like OES_texture_float and + * OES_texture_float_linear are supported. OES_texture_float mentions support + * for NEAREST, NEAREST_MIPMAP_NEAREST magnification and minification filters. + * Mag filters like LINEAR and min filters like NEAREST_MIPMAP_LINEAR, + * LINEAR_MIPMAP_NEAREST and LINEAR_MIPMAP_LINEAR are only valid in case + * OES_texture_float_linear is supported. + * + * Returns true in case the filter is valid for given Float type else false. + */ +static bool +valid_filter_for_float(const struct gl_context *ctx, + const struct gl_texture_object *obj) +{ + switch (obj->Sampler.MagFilter) { + case GL_LINEAR: + if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { + return false; + } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { + return false; + } + case GL_NEAREST: + case GL_NEAREST_MIPMAP_NEAREST: + break; + default: + unreachable("Invalid mag filter"); + } + + switch (obj->Sampler.MinFilter) { + case GL_LINEAR: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_LINEAR: + if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { + return false; + } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { + return false; + } + case GL_NEAREST: + case GL_NEAREST_MIPMAP_NEAREST: + break; + default: + unreachable("Invalid min filter"); + } + + return true; +} /** * Return the gl_texture_object for a given ID. @@ -60,6 +108,22 @@ _mesa_lookup_texture(struct gl_context *ctx, GLuint id) _mesa_HashLookup(ctx->Shared->TexObjects, id); } +/** + * Wrapper around _mesa_lookup_texture that throws GL_INVALID_OPERATION if id + * is not in the hash table. After calling _mesa_error, it returns NULL. + */ +struct gl_texture_object * +_mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func) +{ + struct gl_texture_object *texObj; + + texObj = _mesa_lookup_texture(ctx, id); /* Returns NULL if not found. */ + + if (!texObj) + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture)", func); + + return texObj; +} void _mesa_begin_texture_lookups(struct gl_context *ctx) @@ -82,6 +146,87 @@ _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) _mesa_HashLookupLocked(ctx->Shared->TexObjects, id); } +/** + * Return a pointer to the current texture object for the given target + * on the current texture unit. + * Note: all <target> error checking should have been done by this point. + */ +struct gl_texture_object * +_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) +{ + struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); + const GLboolean arrayTex = ctx->Extensions.EXT_texture_array; + + switch (target) { + case GL_TEXTURE_1D: + return texUnit->CurrentTex[TEXTURE_1D_INDEX]; + case GL_PROXY_TEXTURE_1D: + return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; + case GL_TEXTURE_2D: + return texUnit->CurrentTex[TEXTURE_2D_INDEX]; + case GL_PROXY_TEXTURE_2D: + return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; + case GL_TEXTURE_3D: + return texUnit->CurrentTex[TEXTURE_3D_INDEX]; + case GL_PROXY_TEXTURE_3D: + return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_ARB: + return ctx->Extensions.ARB_texture_cube_map + ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + return ctx->Extensions.ARB_texture_cube_map + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: + return ctx->Extensions.ARB_texture_cube_map_array + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; + case GL_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle + ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; + case GL_PROXY_TEXTURE_RECTANGLE_NV: + return ctx->Extensions.NV_texture_rectangle + ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; + case GL_TEXTURE_1D_ARRAY_EXT: + return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_1D_ARRAY_EXT: + return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; + case GL_TEXTURE_2D_ARRAY_EXT: + return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_2D_ARRAY_EXT: + return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; + case GL_TEXTURE_BUFFER: + return ctx->API == API_OPENGL_CORE && + ctx->Extensions.ARB_texture_buffer_object ? + texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; + case GL_TEXTURE_EXTERNAL_OES: + return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external + ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; + case GL_TEXTURE_2D_MULTISAMPLE: + return ctx->Extensions.ARB_texture_multisample + ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + return ctx->Extensions.ARB_texture_multisample + ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + return ctx->Extensions.ARB_texture_multisample + ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + return ctx->Extensions.ARB_texture_multisample + ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; + default: + _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()"); + return NULL; + } +} + /** * Allocate and initialize a new texture object. But don't put it into the @@ -311,6 +456,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, dest->_MipmapComplete = src->_MipmapComplete; COPY_4V(dest->Swizzle, src->Swizzle); dest->_Swizzle = src->_Swizzle; + dest->_IsHalfFloat = src->_IsHalfFloat; + dest->_IsFloat = src->_IsFloat; dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits; } @@ -405,6 +552,9 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr, mtx_unlock(&oldTex->Mutex); if (deleteFlag) { + /* Passing in the context drastically changes the driver code for + * framebuffer deletion. + */ GET_CURRENT_CONTEXT(ctx); if (ctx) ctx->Driver.DeleteTexture(ctx, oldTex); @@ -541,6 +691,14 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT; } + /* Check if the texture type is Float or HalfFloatOES and ensure Min and Mag + * filters are supported in this case. + */ + if (_mesa_is_gles(ctx) && !valid_filter_for_float(ctx, t)) { + incomplete(t, BASE, "Filter is not supported with Float types."); + return; + } + /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state). */ @@ -710,25 +868,21 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } -/** - * Check if the given cube map texture is "cube complete" as defined in - * the OpenGL specification. - */ GLboolean -_mesa_cube_complete(const struct gl_texture_object *texObj) +_mesa_cube_level_complete(const struct gl_texture_object *texObj, + const GLint level) { - const GLint baseLevel = texObj->BaseLevel; const struct gl_texture_image *img0, *img; GLuint face; if (texObj->Target != GL_TEXTURE_CUBE_MAP) return GL_FALSE; - if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) + if ((level < 0) || (level >= MAX_TEXTURE_LEVELS)) return GL_FALSE; /* check first face */ - img0 = texObj->Image[0][baseLevel]; + img0 = texObj->Image[0][level]; if (!img0 || img0->Width < 1 || img0->Width != img0->Height) @@ -736,7 +890,7 @@ _mesa_cube_complete(const struct gl_texture_object *texObj) /* check remaining faces vs. first face */ for (face = 1; face < 6; face++) { - img = texObj->Image[face][baseLevel]; + img = texObj->Image[face][level]; if (!img || img->Width != img0->Width || img->Height != img0->Height || @@ -747,6 +901,15 @@ _mesa_cube_complete(const struct gl_texture_object *texObj) return GL_TRUE; } +/** + * Check if the given cube map texture is "cube complete" as defined in + * the OpenGL specification. + */ +GLboolean +_mesa_cube_complete(const struct gl_texture_object *texObj) +{ + return _mesa_cube_level_complete(texObj, texObj->BaseLevel); +} /** * Mark a texture object dirty. It forces the object to be incomplete @@ -954,6 +1117,20 @@ _mesa_total_texture_memory(struct gl_context *ctx) } +/** + * Return the base format for the given texture object by looking + * at the base texture image. + * \return base format (such as GL_RGBA) or GL_NONE if it can't be determined + */ +GLenum +_mesa_texture_base_format(const struct gl_texture_object *texObj) +{ + const struct gl_texture_image *texImage = _mesa_base_tex_image(texObj); + + return texImage ? texImage->_BaseFormat : GL_NONE; +} + + static struct gl_texture_object * invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture, GLint level, const char *name) @@ -1007,38 +1184,46 @@ invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture, return t; } -/*@}*/ +/** + * Wrapper for the driver function. Need this because _mesa_new_texture_object + * permits a target of 0 and does not initialize targetIndex. + */ +struct gl_texture_object * +_mesa_create_nameless_texture(struct gl_context *ctx, GLenum target) +{ + struct gl_texture_object *texObj = NULL; + GLint targetIndex; + if (target == 0) + return texObj; -/***********************************************************************/ -/** \name API functions */ -/*@{*/ + texObj = ctx->Driver.NewTextureObject(ctx, 0, target); + targetIndex = _mesa_tex_target_to_index(ctx, texObj->Target); + assert(targetIndex < NUM_TEXTURE_TARGETS); + texObj->TargetIndex = targetIndex; + return texObj; +} /** - * Generate texture names. - * - * \param n number of texture names to be generated. - * \param textures an array in which will hold the generated texture names. - * - * \sa glGenTextures(). - * - * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture - * IDs which are stored in \p textures. Corresponding empty texture - * objects are also generated. + * Helper function for glCreateTextures and glGenTextures. Need this because + * glCreateTextures should throw errors if target = 0. This is not exposed to + * the rest of Mesa to encourage Mesa internals to use nameless textures, + * which do not require expensive hash lookups. */ -void GLAPIENTRY -_mesa_GenTextures( GLsizei n, GLuint *textures ) +static void +create_textures(struct gl_context *ctx, GLenum target, + GLsizei n, GLuint *textures, bool dsa) { - GET_CURRENT_CONTEXT(ctx); GLuint first; GLint i; + const char *func = dsa ? "Create" : "Gen"; if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glGenTextures %d\n", n); + _mesa_debug(ctx, "gl%sTextures %d\n", func, n); if (n < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" ); + _mesa_error( ctx, GL_INVALID_VALUE, "gl%sTextures(n < 0)", func ); return; } @@ -1055,15 +1240,28 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) /* Allocate new, empty texture objects */ for (i = 0; i < n; i++) { struct gl_texture_object *texObj; + GLint targetIndex; GLuint name = first + i; - GLenum target = 0; texObj = ctx->Driver.NewTextureObject(ctx, name, target); if (!texObj) { mtx_unlock(&ctx->Shared->Mutex); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sTextures", func); return; } + /* Initialize the target index if target is non-zero. */ + if (target != 0) { + targetIndex = _mesa_tex_target_to_index(ctx, texObj->Target); + if (targetIndex < 0) { /* Bad Target */ + mtx_unlock(&ctx->Shared->Mutex); + _mesa_error(ctx, GL_INVALID_ENUM, "gl%sTextures(target = %s)", + func, _mesa_lookup_enum_by_nr(texObj->Target)); + return; + } + assert(targetIndex < NUM_TEXTURE_TARGETS); + texObj->TargetIndex = targetIndex; + } + /* insert into hash table */ _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); @@ -1073,6 +1271,65 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) mtx_unlock(&ctx->Shared->Mutex); } +/*@}*/ + + +/***********************************************************************/ +/** \name API functions */ +/*@{*/ + + +/** + * Generate texture names. + * + * \param n number of texture names to be generated. + * \param textures an array in which will hold the generated texture names. + * + * \sa glGenTextures(), glCreateTextures(). + * + * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture + * IDs which are stored in \p textures. Corresponding empty texture + * objects are also generated. + */ +void GLAPIENTRY +_mesa_GenTextures(GLsizei n, GLuint *textures) +{ + GET_CURRENT_CONTEXT(ctx); + create_textures(ctx, 0, n, textures, false); +} + +/** + * Create texture objects. + * + * \param target the texture target for each name to be generated. + * \param n number of texture names to be generated. + * \param textures an array in which will hold the generated texture names. + * + * \sa glCreateTextures(), glGenTextures(). + * + * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture + * IDs which are stored in \p textures. Corresponding empty texture + * objects are also generated. + */ +void GLAPIENTRY +_mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures) +{ + GLint targetIndex; + GET_CURRENT_CONTEXT(ctx); + + /* + * The 4.5 core profile spec (30.10.2014) doesn't specify what + * glCreateTextures should do with invalid targets, which was probably an + * oversight. This conforms to the spec for glBindTexture. + */ + targetIndex = _mesa_tex_target_to_index(ctx, target); + if (targetIndex < 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCreateTextures(target)"); + return; + } + + create_textures(ctx, target, n, textures, true); +} /** * Check if the given texture object is bound to the current draw or @@ -1207,8 +1464,18 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glDeleteTextures %d\n", n); + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTextures(n < 0)"); + return; + } + FLUSH_VERTICES(ctx, 0); /* too complex */ + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTextures(n)"); + return; + } + if (!textures) return; @@ -1257,6 +1524,47 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) } } +/** + * This deletes a texObj without altering the hash table. + */ +void +_mesa_delete_nameless_texture(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + if (!texObj) + return; + + FLUSH_VERTICES(ctx, 0); + + _mesa_lock_texture(ctx, texObj); + { + /* Check if texture is bound to any framebuffer objects. + * If so, unbind. + * See section 4.4.2.3 of GL_EXT_framebuffer_object. + */ + unbind_texobj_from_fbo(ctx, texObj); + + /* Check if this texture is currently bound to any texture units. + * If so, unbind it. + */ + unbind_texobj_from_texunits(ctx, texObj); + + /* Check if this texture is currently bound to any shader + * image unit. If so, unbind it. + * See section 3.9.X of GL_ARB_shader_image_load_store. + */ + unbind_texobj_from_image_units(ctx, texObj); + } + _mesa_unlock_texture(ctx, texObj); + + ctx->NewState |= _NEW_TEXTURE; + + /* Unreference the texobj. If refcount hits zero, the texture + * will be deleted. + */ + _mesa_reference_texobj(&texObj, NULL); +} + /** * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D @@ -1428,6 +1736,107 @@ _mesa_BindTexture( GLenum target, GLuint texName ) ctx->Driver.BindTexture(ctx, ctx->Texture.CurrentUnit, target, newTexObj); } +/** + * Do the actual binding to a numbered texture unit. + * The refcount on the previously bound + * texture object will be decremented. It'll be deleted if the + * count hits zero. + */ +void +_mesa_bind_texture_unit(struct gl_context *ctx, + GLuint unit, + struct gl_texture_object *texObj) +{ + struct gl_texture_unit *texUnit; + + /* Get the texture unit (this is an array look-up) */ + texUnit = _mesa_get_tex_unit_err(ctx, unit, "glBindTextureUnit"); + if (!texUnit) + return; + + /* Check if this texture is only used by this context and is already bound. + * If so, just return. + */ + { + bool early_out; + mtx_lock(&ctx->Shared->Mutex); + early_out = ((ctx->Shared->RefCount == 1) + && (texObj == texUnit->CurrentTex[texObj->TargetIndex])); + mtx_unlock(&ctx->Shared->Mutex); + if (early_out) { + return; + } + } + + /* flush before changing binding */ + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + + _mesa_reference_texobj(&texUnit->CurrentTex[texObj->TargetIndex], + texObj); + ASSERT(texUnit->CurrentTex[texObj->TargetIndex]); + ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed, + unit + 1); + texUnit->_BoundTextures |= (1 << texObj->TargetIndex); + + + /* Pass BindTexture call to device driver */ + if (ctx->Driver.BindTexture) { + ctx->Driver.BindTexture(ctx, unit, texObj->Target, texObj); + } +} + +/** + * Bind a named texture to the specified texture unit. + * + * \param unit texture unit. + * \param texture texture name. + * + * \sa glBindTexture(). + * + * If the named texture is 0, this will reset each target for the specified + * texture unit to its default texture. + * If the named texture is not 0 or a recognized texture name, this throws + * GL_INVALID_OPERATION. + */ +void GLAPIENTRY +_mesa_BindTextureUnit(GLuint unit, GLuint texture) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glBindTextureUnit %s %d\n", + _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit), (GLint) texture); + + /* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec + * (20141030) says: + * "When texture is zero, each of the targets enumerated at the + * beginning of this section is reset to its default texture for the + * corresponding texture image unit." + */ + if (texture == 0) { + unbind_textures_from_unit(ctx, unit); + return; + } + + /* Get the non-default texture object */ + texObj = _mesa_lookup_texture(ctx, texture); + + /* Error checking */ + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindTextureUnit(non-gen name)"); + return; + } + if (texObj->Target == 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBindTextureUnit(target)"); + return; + } + assert(valid_texture_object(texObj)); + + _mesa_bind_texture_unit(ctx, unit, texObj); +} + void GLAPIENTRY _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) diff --git a/mesalib/src/mesa/main/texobj.h b/mesalib/src/mesa/main/texobj.h index efcd7661e..ec5ccb276 100644 --- a/mesalib/src/mesa/main/texobj.h +++ b/mesalib/src/mesa/main/texobj.h @@ -51,6 +51,9 @@ extern "C" { extern struct gl_texture_object * _mesa_lookup_texture(struct gl_context *ctx, GLuint id); +extern struct gl_texture_object * +_mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func); + extern void _mesa_begin_texture_lookups(struct gl_context *ctx); @@ -61,6 +64,9 @@ extern struct gl_texture_object * _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id); extern struct gl_texture_object * +_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target); + +extern struct gl_texture_object * _mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target ); extern void @@ -95,6 +101,24 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, _mesa_reference_texobj_(ptr, tex); } +/** + * Lock a texture for updating. See also _mesa_lock_context_textures(). + */ +static inline void +_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + mtx_lock(&ctx->Shared->TexMutex); + ctx->Shared->TextureStateStamp++; + (void) texObj; +} + +static inline void +_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + (void) texObj; + mtx_unlock(&ctx->Shared->TexMutex); +} + /** * Return number of faces for a texture target. This will be 6 for @@ -154,6 +178,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, struct gl_texture_object *obj ); extern GLboolean +_mesa_cube_level_complete(const struct gl_texture_object *texObj, + const GLint level); + +extern GLboolean _mesa_cube_complete(const struct gl_texture_object *texObj); extern void @@ -165,12 +193,27 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex); extern GLuint _mesa_total_texture_memory(struct gl_context *ctx); +extern GLenum +_mesa_texture_base_format(const struct gl_texture_object *texObj); + extern void _mesa_unlock_context_textures( struct gl_context *ctx ); extern void _mesa_lock_context_textures( struct gl_context *ctx ); +extern struct gl_texture_object * +_mesa_create_nameless_texture(struct gl_context *ctx, GLenum target); + +extern void +_mesa_delete_nameless_texture(struct gl_context *ctx, + struct gl_texture_object *texObj); + +extern void +_mesa_bind_texture_unit(struct gl_context *ctx, + GLuint unit, + struct gl_texture_object *texObj); + /*@}*/ /** @@ -179,8 +222,10 @@ _mesa_lock_context_textures( struct gl_context *ctx ); /*@{*/ extern void GLAPIENTRY -_mesa_GenTextures( GLsizei n, GLuint *textures ); +_mesa_GenTextures(GLsizei n, GLuint *textures); +extern void GLAPIENTRY +_mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures); extern void GLAPIENTRY _mesa_DeleteTextures( GLsizei n, const GLuint *textures ); @@ -189,6 +234,8 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures ); extern void GLAPIENTRY _mesa_BindTexture( GLenum target, GLuint texture ); +extern void GLAPIENTRY +_mesa_BindTextureUnit(GLuint unit, GLuint texture); extern void GLAPIENTRY _mesa_BindTextures( GLuint first, GLsizei count, const GLuint *textures ); diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index e40fb249e..c4a5841c5 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -123,7 +123,7 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) * Only the glGetTexLevelParameter() functions accept proxy targets. */ static struct gl_texture_object * -get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) +get_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get) { struct gl_texture_unit *texUnit; int targetIndex; @@ -147,6 +147,46 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) return texUnit->CurrentTex[targetIndex]; } +/** + * Get current texture object for given name. + * Return NULL if any error (and record the error). + * Note that proxy targets are not accepted. + * Only the glGetTexLevelParameter() functions accept proxy targets. + */ +static struct gl_texture_object * +get_texobj_by_name(struct gl_context *ctx, GLuint texture, GLboolean get) +{ + struct gl_texture_object *texObj; + + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + /* + * User passed a non-generated name. + * Throw the error in the caller. + */ + return NULL; + } + + switch (texObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_RECTANGLE: + return texObj; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "gl%sTextureParameter(target)", get ? "Get" : ""); + return NULL; + } + +} + /** * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. @@ -189,7 +229,7 @@ set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) /** * This is called just prior to changing any texture object state which - * will not effect texture completeness. + * will not affect texture completeness. */ static inline void flush(struct gl_context *ctx) @@ -200,7 +240,7 @@ flush(struct gl_context *ctx) /** * This is called just prior to changing any texture object state which - * can effect texture completeness (texture base level, max level). + * could affect texture completeness (texture base level, max level). * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE * state flag and then mark the texture object as 'incomplete' so that any * per-texture derived state gets recomputed. @@ -234,12 +274,14 @@ target_allows_setting_sampler_parameters(GLenum target) static GLboolean set_tex_parameteri(struct gl_context *ctx, struct gl_texture_object *texObj, - GLenum pname, const GLint *params) + GLenum pname, const GLint *params, bool dsa) { + const char *suffix = dsa ? "ture" : ""; + switch (pname) { case GL_TEXTURE_MIN_FILTER: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MinFilter == params[0]) return GL_FALSE; @@ -267,7 +309,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_MAG_FILTER: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MagFilter == params[0]) return GL_FALSE; @@ -284,7 +326,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_WRAP_S: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.WrapS == params[0]) return GL_FALSE; @@ -297,7 +339,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_WRAP_T: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.WrapT == params[0]) return GL_FALSE; @@ -310,7 +352,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_WRAP_R: if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.WrapR == params[0]) return GL_FALSE; @@ -332,10 +374,15 @@ set_tex_parameteri(struct gl_context *ctx, texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) goto invalid_operation; - if (params[0] < 0 || - (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { + if (params[0] < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexParameter(param=%d)", params[0]); + "glTex%sParameter(param=%d)", suffix, params[0]); + return GL_FALSE; + } + if (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTex%sParameter(target=%s, param=%d)", suffix, + _mesa_lookup_enum_by_nr(texObj->Target), params[0]); return GL_FALSE; } incomplete(ctx, texObj); @@ -355,7 +402,8 @@ set_tex_parameteri(struct gl_context *ctx, if (params[0] < 0 || (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexParameter(param=%d)", params[0]); + "glTex%sParameter(param=%d)", suffix, + params[0]); return GL_FALSE; } incomplete(ctx, texObj); @@ -392,7 +440,7 @@ set_tex_parameteri(struct gl_context *ctx, || _mesa_is_gles3(ctx)) { if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.CompareMode == params[0]) return GL_FALSE; @@ -411,7 +459,7 @@ set_tex_parameteri(struct gl_context *ctx, || _mesa_is_gles3(ctx)) { if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.CompareFunc == params[0]) return GL_FALSE; @@ -486,7 +534,7 @@ set_tex_parameteri(struct gl_context *ctx, const GLint swz = comp_to_swizzle(params[0]); if (swz < 0) { _mesa_error(ctx, GL_INVALID_ENUM, - "glTexParameter(swizzle 0x%x)", params[0]); + "glTex%sParameter(swizzle 0x%x)", suffix, params[0]); return GL_FALSE; } ASSERT(comp < 4); @@ -511,7 +559,8 @@ set_tex_parameteri(struct gl_context *ctx, } else { _mesa_error(ctx, GL_INVALID_ENUM, - "glTexParameter(swizzle 0x%x)", params[comp]); + "glTex%sParameter(swizzle 0x%x)", + suffix, params[comp]); return GL_FALSE; } } @@ -525,7 +574,7 @@ set_tex_parameteri(struct gl_context *ctx, GLenum decode = params[0]; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { if (texObj->Sampler.sRGBDecode != decode) { @@ -543,7 +592,7 @@ set_tex_parameteri(struct gl_context *ctx, GLenum param = params[0]; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (param != GL_TRUE && param != GL_FALSE) { goto invalid_param; @@ -561,18 +610,23 @@ set_tex_parameteri(struct gl_context *ctx, } invalid_pname: - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; invalid_param: - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)", - _mesa_lookup_enum_by_nr(params[0])); + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)", + suffix, _mesa_lookup_enum_by_nr(params[0])); return GL_FALSE; invalid_operation: - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); + return GL_FALSE; + +invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; } @@ -584,15 +638,17 @@ invalid_operation: static GLboolean set_tex_parameterf(struct gl_context *ctx, struct gl_texture_object *texObj, - GLenum pname, const GLfloat *params) + GLenum pname, const GLfloat *params, bool dsa) { + const char *suffix = dsa ? "ture" : ""; + switch (pname) { case GL_TEXTURE_MIN_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MinLod == params[0]) return GL_FALSE; @@ -605,7 +661,7 @@ set_tex_parameterf(struct gl_context *ctx, goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MaxLod == params[0]) return GL_FALSE; @@ -624,12 +680,13 @@ set_tex_parameterf(struct gl_context *ctx, case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.MaxAnisotropy == params[0]) return GL_FALSE; if (params[0] < 1.0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)", + suffix); return GL_FALSE; } flush(ctx); @@ -651,7 +708,7 @@ set_tex_parameterf(struct gl_context *ctx, goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; if (texObj->Sampler.LodBias != params[0]) { flush(ctx); @@ -665,7 +722,7 @@ set_tex_parameterf(struct gl_context *ctx, goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) - goto invalid_operation; + goto invalid_enum; flush(ctx); /* ARB_texture_float disables clamping */ @@ -688,27 +745,23 @@ set_tex_parameterf(struct gl_context *ctx, return GL_FALSE; invalid_pname: - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; -invalid_operation: - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", - _mesa_lookup_enum_by_nr(pname)); +invalid_enum: + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", + suffix, _mesa_lookup_enum_by_nr(pname)); return GL_FALSE; } -void GLAPIENTRY -_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) +void +_mesa_texture_parameterf(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLfloat param, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; switch (pname) { case GL_TEXTURE_MIN_FILTER: @@ -736,16 +789,21 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); p[1] = p[2] = p[3] = 0; - need_update = set_tex_parameteri(ctx, texObj, pname, p); + need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); } break; + case GL_TEXTURE_BORDER_COLOR: + case GL_TEXTURE_SWIZZLE_RGBA: + _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)", + dsa ? "ture" : ""); + return; default: { /* this will generate an error if pname is illegal */ GLfloat p[4]; p[0] = param; p[1] = p[2] = p[3] = 0.0F; - need_update = set_tex_parameterf(ctx, texObj, pname, p); + need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa); } } @@ -755,17 +813,12 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) } -void GLAPIENTRY -_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) +void +_mesa_texture_parameterfv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; - switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: @@ -786,7 +839,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) GLint p[4]; p[0] = (GLint) params[0]; p[1] = p[2] = p[3] = 0; - need_update = set_tex_parameteri(ctx, texObj, pname, p); + need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); } break; case GL_TEXTURE_CROP_RECT_OES: @@ -797,7 +850,7 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) iparams[1] = (GLint) params[1]; iparams[2] = (GLint) params[2]; iparams[3] = (GLint) params[3]; - need_update = set_tex_parameteri(ctx, texObj, pname, iparams); + need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa); } break; case GL_TEXTURE_SWIZZLE_R_EXT: @@ -813,12 +866,12 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) p[2] = (GLint) params[2]; p[3] = (GLint) params[3]; } - need_update = set_tex_parameteri(ctx, texObj, pname, p); + need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); } break; default: /* this will generate an error if pname is illegal */ - need_update = set_tex_parameterf(ctx, texObj, pname, params); + need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa); } if (ctx->Driver.TexParameter && need_update) { @@ -827,17 +880,12 @@ _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) } -void GLAPIENTRY -_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) +void +_mesa_texture_parameteri(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLint param, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; - switch (pname) { case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: @@ -850,16 +898,24 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) fparam[0] = (GLfloat) param; fparam[1] = fparam[2] = fparam[3] = 0.0F; /* convert int param to float */ - need_update = set_tex_parameterf(ctx, texObj, pname, fparam); + need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa); } break; + case GL_TEXTURE_BORDER_COLOR: + case GL_TEXTURE_SWIZZLE_RGBA: + { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTex%sParameteri(non-scalar pname)", + dsa ? "ture" : ""); + return; + } default: /* this will generate an error if pname is illegal */ { GLint iparam[4]; iparam[0] = param; iparam[1] = iparam[2] = iparam[3] = 0; - need_update = set_tex_parameteri(ctx, texObj, pname, iparam); + need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa); } } @@ -870,16 +926,12 @@ _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) } -void GLAPIENTRY -_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) +void +_mesa_texture_parameteriv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa) { GLboolean need_update; - struct gl_texture_object *texObj; - GET_CURRENT_CONTEXT(ctx); - - texObj = get_texobj(ctx, target, GL_FALSE); - if (!texObj) - return; switch (pname) { case GL_TEXTURE_BORDER_COLOR: @@ -890,7 +942,7 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) fparams[1] = INT_TO_FLOAT(params[1]); fparams[2] = INT_TO_FLOAT(params[2]); fparams[3] = INT_TO_FLOAT(params[3]); - need_update = set_tex_parameterf(ctx, texObj, pname, fparams); + need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); } break; case GL_TEXTURE_MIN_LOD: @@ -904,12 +956,12 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) GLfloat fparams[4]; fparams[0] = (GLfloat) params[0]; fparams[1] = fparams[2] = fparams[3] = 0.0F; - need_update = set_tex_parameterf(ctx, texObj, pname, fparams); + need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); } break; default: /* this will generate an error if pname is illegal */ - need_update = set_tex_parameteri(ctx, texObj, pname, params); + need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa); } if (ctx->Driver.TexParameter && need_update) { @@ -925,6 +977,94 @@ _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) } } +void +_mesa_texture_parameterIiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* set the integer-valued border color */ + COPY_4V(texObj->Sampler.BorderColor.i, params); + break; + default: + _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa); + break; + } + /* XXX no driver hook for TexParameterIiv() yet */ +} + +void +_mesa_texture_parameterIuiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLuint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* set the unsigned integer-valued border color */ + COPY_4V(texObj->Sampler.BorderColor.ui, params); + break; + default: + _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params, + dsa); + break; + } + /* XXX no driver hook for TexParameterIuiv() yet */ +} + +void GLAPIENTRY +_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameterf(ctx, texObj, pname, param, false); +} + +void GLAPIENTRY +_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameterfv(ctx, texObj, pname, params, false); +} + +void GLAPIENTRY +_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameteri(ctx, texObj, pname, param, false); +} + +void GLAPIENTRY +_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_target(ctx, target, GL_FALSE); + if (!texObj) + return; + + _mesa_texture_parameteriv(ctx, texObj, pname, params, false); +} /** * Set tex parameter to integer value(s). Primarily intended to set @@ -937,24 +1077,13 @@ _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_FALSE); + texObj = get_texobj_by_target(ctx, target, GL_FALSE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - /* set the integer-valued border color */ - COPY_4V(texObj->Sampler.BorderColor.i, params); - break; - default: - _mesa_TexParameteriv(target, pname, params); - break; - } - /* XXX no driver hook for TexParameterIiv() yet */ + _mesa_texture_parameterIiv(ctx, texObj, pname, params, false); } - /** * Set tex parameter to unsigned integer value(s). Primarily intended to set * uint-valued texture border color (for integer-valued textures). @@ -966,26 +1095,117 @@ _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_FALSE); + texObj = get_texobj_by_target(ctx, target, GL_FALSE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - /* set the unsigned integer-valued border color */ - COPY_4V(texObj->Sampler.BorderColor.ui, params); - break; - default: - _mesa_TexParameteriv(target, pname, (const GLint *) params); - break; + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false); +} + + +void GLAPIENTRY +_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfv(texture)"); + return; } - /* XXX no driver hook for TexParameterIuiv() yet */ + + _mesa_texture_parameterfv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterf(texture)"); + return; + } + + _mesa_texture_parameterf(ctx, texObj, pname, param, true); } +void GLAPIENTRY +_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteri(texture)"); + return; + } + + _mesa_texture_parameteri(ctx, texObj, pname, param, true); +} + +void GLAPIENTRY +_mesa_TextureParameteriv(GLuint texture, GLenum pname, + const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriv(texture)"); + return; + } + + _mesa_texture_parameteriv(ctx, texObj, pname, params, true); +} + + +void GLAPIENTRY +_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureParameterIiv(texture)"); + return; + } + + _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); +} + +void GLAPIENTRY +_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_FALSE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureParameterIuiv(texture)"); + return; + } + + _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); +} static GLboolean -legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) +legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target, + bool dsa) { switch (target) { case GL_TEXTURE_1D: @@ -1038,6 +1258,16 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) case GL_PROXY_TEXTURE_2D_MULTISAMPLE: case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: return ctx->Extensions.ARB_texture_multisample; + + /* This is a valid target for dsa, but the OpenGL 4.5 core spec + * (30.10.2014) Section 8.11 Texture Queries says: + * "For GetTextureLevelParameter* only, texture may also be a cube + * map texture object. In this case the query is always performed + * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there + * is no way to specify another face." + */ + case GL_TEXTURE_CUBE_MAP: + return dsa; default: return GL_FALSE; } @@ -1048,13 +1278,15 @@ static void get_tex_level_parameter_image(struct gl_context *ctx, const struct gl_texture_object *texObj, GLenum target, GLint level, - GLenum pname, GLint *params) + GLenum pname, GLint *params, + bool dsa) { const struct gl_texture_image *img = NULL; struct gl_texture_image dummy_image; mesa_format texFormat; + const char *suffix = dsa ? "ture" : ""; - img = _mesa_select_tex_image(ctx, texObj, target, level); + img = _mesa_select_tex_image(texObj, target, level); if (!img || img->TexFormat == MESA_FORMAT_NONE) { /* In case of undefined texture image return the default values. * @@ -1160,11 +1392,12 @@ get_tex_level_parameter_image(struct gl_context *ctx, !_mesa_is_proxy_texture(target)) { *params = _mesa_format_image_size(texFormat, img->Width, img->Height, img->Depth); - } - else { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameter[if]v(pname)"); - } + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, + _mesa_lookup_enum_by_nr(pname)); + } break; case GL_TEXTURE_COMPRESSED: *params = (GLint) _mesa_is_format_compressed(texFormat); @@ -1211,7 +1444,7 @@ get_tex_level_parameter_image(struct gl_context *ctx, invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTexLevelParameter[if]v(pname=%s)", + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, _mesa_lookup_enum_by_nr(pname)); } @@ -1219,12 +1452,13 @@ invalid_pname: static void get_tex_level_parameter_buffer(struct gl_context *ctx, const struct gl_texture_object *texObj, - GLenum pname, GLint *params) + GLenum pname, GLint *params, bool dsa) { const struct gl_buffer_object *bo = texObj->BufferObject; mesa_format texFormat = texObj->_BufferObjectFormat; GLenum internalFormat = texObj->BufferObjectFormat; GLenum baseFormat = _mesa_get_format_base_format(texFormat); + const char *suffix = dsa ? "ture" : ""; if (!bo) { /* undefined texture buffer object */ @@ -1294,7 +1528,8 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: /* Always illegal for GL_TEXTURE_BUFFER */ _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameter[if]v(pname)"); + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, + _mesa_lookup_enum_by_nr(pname)); break; /* GL_ARB_texture_float */ @@ -1322,38 +1557,37 @@ get_tex_level_parameter_buffer(struct gl_context *ctx, invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTexLevelParameter[if]v(pname=%s)", + "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, _mesa_lookup_enum_by_nr(pname)); } -void GLAPIENTRY -_mesa_GetTexLevelParameterfv( GLenum target, GLint level, - GLenum pname, GLfloat *params ) -{ - GLint iparam; - _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); - *params = (GLfloat) iparam; -} - - -void GLAPIENTRY -_mesa_GetTexLevelParameteriv( GLenum target, GLint level, - GLenum pname, GLint *params ) +/** + * This isn't exposed to the rest of the driver because it is a part of the + * OpenGL API that is rarely used. + */ +static void +get_tex_level_parameteriv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLenum pname, GLint *params, + bool dsa) { - struct gl_texture_object *texObj; GLint maxLevels; - GET_CURRENT_CONTEXT(ctx); + const char *suffix = dsa ? "ture" : ""; + /* Check for errors */ if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexLevelParameteriv(current unit)"); + "glGetTex%sLevelParameter[if]v(" + "current unit >= max combined texture units)", suffix); return; } - if (!legal_get_tex_level_parameter_target(ctx, target)) { + if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) { _mesa_error(ctx, GL_INVALID_ENUM, - "glGetTexLevelParameter[if]v(target=0x%x)", target); + "glGetTex%sLevelParameter[if]v(target=%s)", suffix, + _mesa_lookup_enum_by_nr(target)); return; } @@ -1361,29 +1595,98 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, assert(maxLevels != 0); if (level < 0 || level >= maxLevels) { - _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetTex%sLevelParameter[if]v(level out of range)", suffix); return; } + /* Get the level parameter */ + if (target == GL_TEXTURE_BUFFER) { + get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa); + } + else { + get_tex_level_parameter_image(ctx, texObj, target, + level, pname, params, dsa); + } +} + +void GLAPIENTRY +_mesa_GetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ) +{ + struct gl_texture_object *texObj; + GLint iparam; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + get_tex_level_parameteriv(ctx, texObj, target, level, + pname, &iparam, false); + + *params = (GLfloat) iparam; +} + +void GLAPIENTRY +_mesa_GetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; - if (target == GL_TEXTURE_BUFFER) - get_tex_level_parameter_buffer(ctx, texObj, pname, params); - else - get_tex_level_parameter_image(ctx, texObj, target, level, pname, params); + get_tex_level_parameteriv(ctx, texObj, target, level, + pname, params, false); } +void GLAPIENTRY +_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, + GLenum pname, GLfloat *params) +{ + struct gl_texture_object *texObj; + GLint iparam; + GET_CURRENT_CONTEXT(ctx); + + texObj = _mesa_lookup_texture_err(ctx, texture, + "glGetTextureLevelParameterfv"); + if (!texObj) + return; + + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, &iparam, true); + + *params = (GLfloat) iparam; +} void GLAPIENTRY -_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) +_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, + GLenum pname, GLint *params) { - struct gl_texture_object *obj; + struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - obj = get_texobj(ctx, target, GL_TRUE); - if (!obj) + texObj = _mesa_lookup_texture_err(ctx, texture, + "glGetTextureLevelParameteriv"); + if (!texObj) return; + get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, + pname, params, true); +} + +/** + * This isn't exposed to the rest of the driver because it is a part of the + * OpenGL API that is rarely used. + */ +static void +get_tex_parameterfv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLfloat *params, bool dsa) +{ _mesa_lock_context_textures(ctx); switch (pname) { case GL_TEXTURE_MAG_FILTER: @@ -1596,20 +1899,16 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) invalid_pname: _mesa_unlock_context_textures(ctx); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)", + dsa ? "ture" : "", pname); } -void GLAPIENTRY -_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) +static void +get_tex_parameteriv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLint *params, bool dsa) { - struct gl_texture_object *obj; - GET_CURRENT_CONTEXT(ctx); - - obj = get_texobj(ctx, target, GL_TRUE); - if (!obj) - return; - _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: @@ -1658,14 +1957,18 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) case GL_TEXTURE_MIN_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; - - *params = (GLint) obj->Sampler.MinLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.MinLod); break; case GL_TEXTURE_MAX_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; - - *params = (GLint) obj->Sampler.MaxLod; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.MaxLod); break; case GL_TEXTURE_BASE_LEVEL: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) @@ -1679,7 +1982,10 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (!ctx->Extensions.EXT_texture_filter_anisotropic) goto invalid_pname; - *params = (GLint) obj->Sampler.MaxAnisotropy; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.MaxAnisotropy); break; case GL_GENERATE_MIPMAP_SGIS: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) @@ -1818,9 +2124,73 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) invalid_pname: _mesa_unlock_texture(ctx, obj); - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)", + dsa ? "ture" : "", pname); +} + +static void +get_tex_parameterIiv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + COPY_4V(params, obj->Sampler.BorderColor.i); + break; + default: + get_tex_parameteriv(ctx, obj, pname, params, dsa); + } +} + +static void +get_tex_parameterIuiv(struct gl_context *ctx, + struct gl_texture_object *obj, + GLenum pname, GLuint *params, bool dsa) +{ + switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + COPY_4V(params, obj->Sampler.BorderColor.i); + break; + default: + { + GLint ip[4]; + get_tex_parameteriv(ctx, obj, pname, ip, dsa); + params[0] = ip[0]; + if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || + pname == GL_TEXTURE_CROP_RECT_OES) { + params[1] = ip[1]; + params[2] = ip[2]; + params[3] = ip[3]; + } + } + } +} + +void GLAPIENTRY +_mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_target(ctx, target, GL_TRUE); + if (!obj) + return; + + get_tex_parameterfv(ctx, obj, pname, params, false); } +void GLAPIENTRY +_mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_target(ctx, target, GL_TRUE); + if (!obj) + return; + + get_tex_parameteriv(ctx, obj, pname, params, false); +} /** New in GL 3.0 */ void GLAPIENTRY @@ -1829,17 +2199,11 @@ _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_TRUE); + texObj = get_texobj_by_target(ctx, target, GL_TRUE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - COPY_4V(params, texObj->Sampler.BorderColor.i); - break; - default: - _mesa_GetTexParameteriv(target, pname, params); - } + get_tex_parameterIiv(ctx, texObj, pname, params, false); } @@ -1850,25 +2214,79 @@ _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = get_texobj(ctx, target, GL_TRUE); + texObj = get_texobj_by_target(ctx, target, GL_TRUE); if (!texObj) return; - switch (pname) { - case GL_TEXTURE_BORDER_COLOR: - COPY_4V(params, texObj->Sampler.BorderColor.i); - break; - default: - { - GLint ip[4]; - _mesa_GetTexParameteriv(target, pname, ip); - params[0] = ip[0]; - if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || - pname == GL_TEXTURE_CROP_RECT_OES) { - params[1] = ip[1]; - params[2] = ip[2]; - params[3] = ip[3]; - } - } + get_tex_parameterIuiv(ctx, texObj, pname, params, false); +} + + +void GLAPIENTRY +_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!obj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameterfv(texture)"); + return; + } + + get_tex_parameterfv(ctx, obj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params) +{ + struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!obj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameteriv(texture)"); + return; + } + + get_tex_parameteriv(ctx, obj, pname, params, true); +} + +void GLAPIENTRY +_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameterIiv(texture)"); + return; } + + get_tex_parameterIiv(ctx, texObj, pname, params, true); +} + + +void GLAPIENTRY +_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + texObj = get_texobj_by_name(ctx, texture, GL_TRUE); + if (!texObj) { + /* User passed a non-generated name. */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTextureParameterIuiv(texture)"); + return; + } + + get_tex_parameterIuiv(ctx, texObj, pname, params, true); } diff --git a/mesalib/src/mesa/main/texparam.h b/mesalib/src/mesa/main/texparam.h index 557a7bcb4..96defbec2 100644 --- a/mesalib/src/mesa/main/texparam.h +++ b/mesalib/src/mesa/main/texparam.h @@ -29,6 +29,49 @@ #include "main/glheader.h" +/** + * \name Internal functions + */ +/*@{*/ + +extern void +_mesa_texture_parameterf(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLfloat param, bool dsa); + +extern void +_mesa_texture_parameterfv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params, bool dsa); + + +extern void +_mesa_texture_parameteri(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, GLint param, bool dsa); + +extern void +_mesa_texture_parameteriv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa); + +extern void +_mesa_texture_parameterIiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLint *params, bool dsa); + +extern void +_mesa_texture_parameterIuiv(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname, const GLuint *params, bool dsa); + +/*@}*/ + +/** + * \name API functions + */ +/*@{*/ + extern void GLAPIENTRY _mesa_GetTexLevelParameterfv( GLenum target, GLint level, @@ -39,6 +82,15 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ); extern void GLAPIENTRY +_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, + GLenum pname, GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, + GLenum pname, GLint *params); + + +extern void GLAPIENTRY _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ); extern void GLAPIENTRY @@ -52,24 +104,52 @@ _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params); extern void GLAPIENTRY +_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params); + + +extern void GLAPIENTRY _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ); extern void GLAPIENTRY _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ); - extern void GLAPIENTRY _mesa_TexParameteri( GLenum target, GLenum pname, GLint param ); extern void GLAPIENTRY _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ); - extern void GLAPIENTRY _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params); extern void GLAPIENTRY _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params); +extern void GLAPIENTRY +_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params); + +extern void GLAPIENTRY +_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param); + +extern void GLAPIENTRY +_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param); + +extern void GLAPIENTRY +_mesa_TextureParameteriv(GLuint texture, GLenum pname, const GLint *params); + +extern void GLAPIENTRY +_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params); + +extern void GLAPIENTRY +_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params); #endif /* TEXPARAM_H */ diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index e0f085218..99c7c8178 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -22,7 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/** +/** * \file texstate.c * * Texture state handling. @@ -40,7 +40,7 @@ #include "teximage.h" #include "texstate.h" #include "mtypes.h" -#include "bitset.h" +#include "util/bitset.h" /** @@ -153,7 +153,7 @@ _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit ) /** * Convert "classic" texture environment to ARB_texture_env_combine style * environments. - * + * * \param state texture_env_combine state vector to be filled-in. * \param mode Classic texture environment mode (i.e., \c GL_REPLACE, * \c GL_BLEND, \c GL_DECAL, etc.). @@ -186,7 +186,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, case GL_YCBCR_MESA: state->SourceA[0] = GL_PREVIOUS; break; - + default: _mesa_problem(NULL, "Invalid texBaseFormat 0x%x in calculate_derived_texenv", @@ -203,7 +203,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode; mode_a = mode; break; - + case GL_DECAL: mode_rgb = GL_INTERPOLATE; mode_a = GL_REPLACE; @@ -272,7 +272,7 @@ calculate_derived_texenv( struct gl_tex_env_combine_state *state, mode); return; } - + state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS) ? mode_rgb : GL_REPLACE; state->ModeA = (state->SourceA[0] != GL_PREVIOUS) @@ -290,9 +290,7 @@ _mesa_ActiveTexture(GLenum texture) GLuint k; GET_CURRENT_CONTEXT(ctx); - /* See OpenGL spec for glActiveTexture: */ - k = MAX2(ctx->Const.MaxCombinedTextureImageUnits, - ctx->Const.MaxTextureCoordUnits); + k = _mesa_max_tex_unit(ctx); ASSERT(k <= Elements(ctx->Texture.Unit)); @@ -769,11 +767,11 @@ _mesa_update_texture( struct gl_context *ctx, GLuint new_state ) /** * Allocate the proxy textures for the given context. - * + * * \param ctx the context to allocate proxies for. - * + * * \return GL_TRUE on success, or GL_FALSE on failure - * + * * If run out of memory part way through the allocations, clean up and return * GL_FALSE. */ @@ -944,7 +942,7 @@ _mesa_free_texture_data(struct gl_context *ctx) /** * Update the default texture objects in the given context to reference those - * specified in the shared state and release those referencing the old + * specified in the shared state and release those referencing the old * shared state. */ void diff --git a/mesalib/src/mesa/main/texstate.h b/mesalib/src/mesa/main/texstate.h index 5cd1684f2..abc07eafb 100644 --- a/mesalib/src/mesa/main/texstate.h +++ b/mesalib/src/mesa/main/texstate.h @@ -33,9 +33,18 @@ #include "compiler.h" +#include "enums.h" +#include "macros.h" #include "mtypes.h" +static inline struct gl_texture_unit * +_mesa_get_tex_unit(struct gl_context *ctx, GLuint unit) +{ + ASSERT(unit < Elements(ctx->Texture.Unit)); + return &(ctx->Texture.Unit[unit]); +} + /** * Return pointer to current texture unit. * This the texture unit set by glActiveTexture(), not glClientActiveTexture(). @@ -43,8 +52,33 @@ static inline struct gl_texture_unit * _mesa_get_current_tex_unit(struct gl_context *ctx) { - ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit)); - return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); + return _mesa_get_tex_unit(ctx, ctx->Texture.CurrentUnit); +} + +static inline GLuint +_mesa_max_tex_unit(struct gl_context *ctx) +{ + /* See OpenGL spec for glActiveTexture: */ + return MAX2(ctx->Const.MaxCombinedTextureImageUnits, + ctx->Const.MaxTextureCoordUnits); +} + +static inline struct gl_texture_unit * +_mesa_get_tex_unit_err(struct gl_context *ctx, GLuint unit, const char *func) +{ + if (unit < _mesa_max_tex_unit(ctx)) + return _mesa_get_tex_unit(ctx, unit); + + /* Note: This error is a precedent set by glBindTextures. From the GL 4.5 + * specification (30.10.2014) Section 8.1 ("Texture Objects"): + * + * "An INVALID_OPERATION error is generated if first + count is greater + * than the number of texture image units supported by the + * implementation." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unit=%s)", func, + _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit)); + return NULL; } diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 897d5891a..3ace5e8bb 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -42,7 +42,7 @@ #include "textureview.h" #include "mtypes.h" #include "glformats.h" - +#include "hash.h" /** @@ -242,10 +242,10 @@ _mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat) * checks at glTexImage* time. */ GLboolean -_mesa_alloc_texture_storage(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth) +_mesa_AllocTextureStorage_sw(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLsizei levels, GLsizei width, + GLsizei height, GLsizei depth) { const int numFaces = _mesa_num_tex_faces(texObj->Target); int face; @@ -274,34 +274,26 @@ _mesa_alloc_texture_storage(struct gl_context *ctx, * \return GL_TRUE if any error, GL_FALSE otherwise. */ static GLboolean -tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, +tex_storage_error_check(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) + GLsizei width, GLsizei height, GLsizei depth, + bool dsa) { - struct gl_texture_object *texObj; + const char* suffix = dsa ? "ture" : ""; - if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexStorage%uD(internalformat = %s)", dims, - _mesa_lookup_enum_by_nr(internalformat)); - return GL_TRUE; - } + /* Legal format checking has been moved to texstorage and texturestorage in + * order to allow meta functions to use legacy formats. */ /* size check */ if (width < 1 || height < 1 || depth < 1) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexStorage%uD(width, height or depth < 1)", dims); + "glTex%sStorage%uD(width, height or depth < 1)", + suffix, dims); return GL_TRUE; } - /* target check */ - if (!legal_texobj_target(ctx, dims, target)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexStorage%uD(illegal target=%s)", - dims, _mesa_lookup_enum_by_nr(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 @@ -315,50 +307,54 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, && !_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)", + "glTex%sStorage%dD(internalformat = %s)", suffix, dims, _mesa_lookup_enum_by_nr(internalformat)); } /* levels check */ if (levels < 1) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)", - dims); + _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)", + suffix, dims); return GL_TRUE; } /* check levels against maximum (note different error than above) */ if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(levels too large)", dims); + "glTex%sStorage%uD(levels too large)", + suffix, dims); return GL_TRUE; } /* check levels against width/height/depth */ if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(too many levels for max texture dimension)", - dims); + "glTex%sStorage%uD(too many levels" + " for max texture dimension)", + suffix, dims); return GL_TRUE; } /* non-default texture object check */ - texObj = _mesa_get_current_tex_object(ctx, target); if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glTexStorage%uD(texture object 0)", dims); + "glTex%sStorage%uD(texture object 0)", + suffix, dims); return GL_TRUE; } /* Check if texObj->Immutable is set */ if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)", - dims); + _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", + suffix, dims); return GL_TRUE; } /* additional checks for depth textures */ if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat, - dims, "glTexStorage")) + dims, dsa ? + "glTextureStorage" : + "glTexStorage")) return GL_TRUE; return GL_FALSE; @@ -366,32 +362,27 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target, /** - * Helper used by _mesa_TexStorage1/2/3D(). + * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() + * and _mesa_TextureStorage1/2/3D(). */ -static void -texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) +void +_mesa_texture_storage(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, bool dsa) { - struct gl_texture_object *texObj; GLboolean sizeOK, dimensionsOK; mesa_format texFormat; + const char* suffix = dsa ? "ture" : ""; - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", - dims, - _mesa_lookup_enum_by_nr(target), levels, - _mesa_lookup_enum_by_nr(internalformat), - width, height, depth); + assert(texObj); - if (tex_storage_error_check(ctx, dims, target, levels, - internalformat, width, height, depth)) { + if (tex_storage_error_check(ctx, texObj, dims, target, levels, + internalformat, width, height, depth, dsa)) { return; /* error was recorded */ } - texObj = _mesa_get_current_tex_object(ctx, target); - assert(texObj); texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, internalformat, GL_NONE, GL_NONE); @@ -404,7 +395,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, width, height, depth, 0); - if (_mesa_is_proxy_texture(texObj->Target)) { + if (_mesa_is_proxy_texture(target)) { if (dimensionsOK && sizeOK) { initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat); @@ -417,13 +408,15 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, else { if (!dimensionsOK) { _mesa_error(ctx, GL_INVALID_VALUE, - "glTexStorage%uD(invalid width, height or depth)", dims); + "glTex%sStorage%uD(invalid width, height or depth)", + suffix, dims); return; } if (!sizeOK) { _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glTexStorage%uD(texture too large)", dims); + "glTex%sStorage%uD(texture too large)", + suffix, dims); } assert(levels > 0); @@ -445,7 +438,8 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, * state but this puts things in a consistent state. */ clear_texture_fields(ctx, texObj); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD", + suffix, dims); return; } @@ -454,6 +448,94 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, } } +/** + * Helper used by _mesa_TexStorage1/2/3D(). + */ +static void +texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + /* target check */ + /* This is done here so that _mesa_texture_storage can receive unsized + * formats. */ + if (!legal_texobj_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexStorage%uD(illegal target=%s)", + dims, _mesa_lookup_enum_by_nr(target)); + return; + } + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", + dims, + _mesa_lookup_enum_by_nr(target), levels, + _mesa_lookup_enum_by_nr(internalformat), + width, height, depth); + /* Check the format to make sure it is sized. */ + if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexStorage%uD(internalformat = %s)", dims, + _mesa_lookup_enum_by_nr(internalformat)); + return; + } + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + + _mesa_texture_storage(ctx, dims, texObj, target, levels, + internalformat, width, height, depth, false); +} + +/** + * Helper used by _mesa_TextureStorage1/2/3D(). + */ +static void +texturestorage(GLuint dims, GLuint texture, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth) +{ + struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n", + dims, texture, levels, + _mesa_lookup_enum_by_nr(internalformat), + width, height, depth); + + /* Check the format to make sure it is sized. */ + if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTextureStorage%uD(internalformat = %s)", dims, + _mesa_lookup_enum_by_nr(internalformat)); + return; + } + + /* Get the texture object by Name. */ + texObj = _mesa_lookup_texture(ctx, texture); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureStorage%uD(texture = %d)", dims, texture); + return; + } + + /* target check */ + /* This is done here so that _mesa_texture_storage can receive unsized + * formats. */ + if (!legal_texobj_target(ctx, dims, texObj->Target)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTextureStorage%uD(illegal target=%s)", + dims, _mesa_lookup_enum_by_nr(texObj->Target)); + return; + } + + _mesa_texture_storage(ctx, dims, texObj, texObj->Target, + levels, internalformat, width, height, depth, true); +} void GLAPIENTRY _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, @@ -478,6 +560,28 @@ _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, texstorage(3, target, levels, internalformat, width, height, depth); } +void GLAPIENTRY +_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width) +{ + texturestorage(1, texture, levels, internalformat, width, 1, 1); +} + + +void GLAPIENTRY +_mesa_TextureStorage2D(GLuint texture, GLsizei levels, + GLenum internalformat, + GLsizei width, GLsizei height) +{ + texturestorage(2, texture, levels, internalformat, width, height, 1); +} + +void GLAPIENTRY +_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) +{ + texturestorage(3, texture, levels, internalformat, width, height, depth); +} /* diff --git a/mesalib/src/mesa/main/texstorage.h b/mesalib/src/mesa/main/texstorage.h index ec4f71374..6f5495f38 100644 --- a/mesalib/src/mesa/main/texstorage.h +++ b/mesalib/src/mesa/main/texstorage.h @@ -26,6 +26,24 @@ #ifndef TEXSTORAGE_H #define TEXSTORAGE_H +/** + * \name Internal functions + */ +/*@{*/ + +extern void +_mesa_texture_storage(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, bool dsa); + +/*@}*/ + +/** + * \name API functions + */ +/*@{*/ extern void GLAPIENTRY _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, @@ -41,6 +59,19 @@ extern void GLAPIENTRY _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +extern void GLAPIENTRY +_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width); + + +extern void GLAPIENTRY +_mesa_TextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height); + + +extern void GLAPIENTRY +_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth); extern void GLAPIENTRY @@ -62,9 +93,9 @@ extern GLboolean _mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat); extern GLboolean -_mesa_alloc_texture_storage(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth); +_mesa_AllocTextureStorage_sw(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLsizei levels, GLsizei width, + GLsizei height, GLsizei depth); #endif /* TEXSTORAGE_H */ diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 50aa1fd5e..7039cdf81 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -73,6 +73,7 @@ #include "texstore.h" #include "enums.h" #include "glformats.h" +#include "pixeltransfer.h" #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" @@ -87,577 +88,6 @@ enum { * Texture image storage function. */ typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); - - -enum { - IDX_LUMINANCE = 0, - IDX_ALPHA, - IDX_INTENSITY, - IDX_LUMINANCE_ALPHA, - IDX_RGB, - IDX_RGBA, - IDX_RED, - IDX_GREEN, - IDX_BLUE, - IDX_BGR, - IDX_BGRA, - IDX_ABGR, - IDX_RG, - MAX_IDX -}; - -#define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) -#define MAP2(x,y) MAP4(x, y, ZERO, ZERO) -#define MAP3(x,y,z) MAP4(x, y, z, ZERO) -#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } - - -static const struct { - GLubyte format_idx; - GLubyte to_rgba[6]; - GLubyte from_rgba[6]; -} mappings[MAX_IDX] = -{ - { - IDX_LUMINANCE, - MAP4(0,0,0,ONE), - MAP1(0) - }, - - { - IDX_ALPHA, - MAP4(ZERO, ZERO, ZERO, 0), - MAP1(3) - }, - - { - IDX_INTENSITY, - MAP4(0, 0, 0, 0), - MAP1(0), - }, - - { - IDX_LUMINANCE_ALPHA, - MAP4(0,0,0,1), - MAP2(0,3) - }, - - { - IDX_RGB, - MAP4(0,1,2,ONE), - MAP3(0,1,2) - }, - - { - IDX_RGBA, - MAP4(0,1,2,3), - MAP4(0,1,2,3), - }, - - { - IDX_RED, - MAP4(0, ZERO, ZERO, ONE), - MAP1(0), - }, - - { - IDX_GREEN, - MAP4(ZERO, 0, ZERO, ONE), - MAP1(1), - }, - - { - IDX_BLUE, - MAP4(ZERO, ZERO, 0, ONE), - MAP1(2), - }, - - { - IDX_BGR, - MAP4(2,1,0,ONE), - MAP3(2,1,0) - }, - - { - IDX_BGRA, - MAP4(2,1,0,3), - MAP4(2,1,0,3) - }, - - { - IDX_ABGR, - MAP4(3,2,1,0), - MAP4(3,2,1,0) - }, - - { - IDX_RG, - MAP4(0, 1, ZERO, ONE), - MAP2(0, 1) - }, -}; - - - -/** - * Convert a GL image format enum to an IDX_* value (see above). - */ -static int -get_map_idx(GLenum value) -{ - switch (value) { - 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 %s", - _mesa_lookup_enum_by_nr(value)); - return 0; - } -} - - -/** - * When promoting texture formats (see below) we need to compute the - * mapping of dest components back to source components. - * This function does that. - * \param inFormat the incoming format of the texture - * \param outFormat the final texture format - * \return map[6] a full 6-component map - */ -static void -compute_component_mapping(GLenum inFormat, GLenum outFormat, - GLubyte *map) -{ - const int inFmt = get_map_idx(inFormat); - const int outFmt = get_map_idx(outFormat); - const GLubyte *in2rgba = mappings[inFmt].to_rgba; - const GLubyte *rgba2out = mappings[outFmt].from_rgba; - int i; - - for (i = 0; i < 4; i++) - map[i] = in2rgba[rgba2out[i]]; - - map[ZERO] = ZERO; - map[ONE] = ONE; - -#if 0 - printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", - inFormat, _mesa_lookup_enum_by_nr(inFormat), - outFormat, _mesa_lookup_enum_by_nr(outFormat), - map[0], - map[1], - map[2], - map[3], - map[4], - map[5]); -#endif -} - - -/** - * Make a temporary (color) texture image with GLfloat components. - * Apply all needed pixel unpacking and pixel transfer operations. - * Note that there are both logicalBaseFormat and textureBaseFormat parameters. - * Suppose the user specifies GL_LUMINANCE as the internal texture format - * but the graphics hardware doesn't support luminance textures. So, we might - * use an RGB hardware format instead. - * If logicalBaseFormat != textureBaseFormat we have some extra work to do. - * - * \param ctx the rendering context - * \param dims image dimensions: 1, 2 or 3 - * \param logicalBaseFormat basic texture derived from the user's - * internal texture format value - * \param textureBaseFormat the actual basic format of the texture - * \param srcWidth source image width - * \param srcHeight source image height - * \param srcDepth source image depth - * \param srcFormat source image format - * \param srcType source image type - * \param srcAddr source image address - * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLfloat. - */ -GLfloat * -_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps) -{ - GLfloat *tempImage; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLfloat *dst; - GLint img, row; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_ALPHA || - logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_DEPTH_COMPONENT); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_ALPHA || - textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_DEPTH_COMPONENT); - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLfloat)); - if (!tempImage) - return NULL; - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLubyte *src - = (const GLubyte *) _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, logicalBaseFormat, - dst, srcFormat, srcType, src, - srcPacking, transferOps); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* more work */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLfloat *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLfloat)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0.0F; - else if (j == ONE) - newImage[i * texComponents + k] = 1.0F; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - -/** - * Make temporary image with uint pixel values. Used for unsigned - * integer-valued textures. - */ -static GLuint * -make_temp_uint_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint *tempImage; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - GLuint *dst; - GLint img, row; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_INTENSITY || - logicalBaseFormat == GL_ALPHA); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_INTENSITY || - textureBaseFormat == GL_ALPHA); - - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLuint)); - if (!tempImage) - return NULL; - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLubyte *src - = (const GLubyte *) _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, logicalBaseFormat, - dst, srcFormat, srcType, src, - srcPacking); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* more work */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLuint *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLuint)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0; - else if (j == ONE) - newImage[i * texComponents + k] = 1; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - - -/** - * Make a temporary (color) texture image with GLubyte components. - * Apply all needed pixel unpacking and pixel transfer operations. - * Note that there are both logicalBaseFormat and textureBaseFormat parameters. - * Suppose the user specifies GL_LUMINANCE as the internal texture format - * but the graphics hardware doesn't support luminance textures. So, we might - * use an RGB hardware format instead. - * If logicalBaseFormat != textureBaseFormat we have some extra work to do. - * - * \param ctx the rendering context - * \param dims image dimensions: 1, 2 or 3 - * \param logicalBaseFormat basic texture derived from the user's - * internal texture format value - * \param textureBaseFormat the actual basic format of the texture - * \param srcWidth source image width - * \param srcHeight source image height - * \param srcDepth source image depth - * \param srcFormat source image format - * \param srcType source image type - * \param srcAddr source image address - * \param srcPacking source image pixel packing - * \return resulting image with format = textureBaseFormat and type = GLubyte. - */ -GLubyte * -_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) -{ - GLuint transferOps = ctx->_ImageTransferState; - const GLint components = _mesa_components_in_format(logicalBaseFormat); - GLint img, row; - GLubyte *tempImage, *dst; - - ASSERT(dims >= 1 && dims <= 3); - - ASSERT(logicalBaseFormat == GL_RGBA || - logicalBaseFormat == GL_RGB || - logicalBaseFormat == GL_RG || - logicalBaseFormat == GL_RED || - logicalBaseFormat == GL_LUMINANCE_ALPHA || - logicalBaseFormat == GL_LUMINANCE || - logicalBaseFormat == GL_ALPHA || - logicalBaseFormat == GL_INTENSITY); - - ASSERT(textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_RGB || - textureBaseFormat == GL_RG || - textureBaseFormat == GL_RED || - textureBaseFormat == GL_LUMINANCE_ALPHA || - textureBaseFormat == GL_LUMINANCE || - textureBaseFormat == GL_ALPHA || - textureBaseFormat == GL_INTENSITY); - - /* unpack and transfer the source image */ - tempImage = malloc(srcWidth * srcHeight * srcDepth - * components * sizeof(GLubyte)); - if (!tempImage) { - return NULL; - } - - dst = tempImage; - for (img = 0; img < srcDepth; img++) { - const GLint srcStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLubyte *src = - (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, - srcWidth, srcHeight, - srcFormat, srcType, - img, 0, 0); - for (row = 0; row < srcHeight; row++) { - _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst, - srcFormat, srcType, src, srcPacking, - transferOps); - dst += srcWidth * components; - src += srcStride; - } - } - - if (logicalBaseFormat != textureBaseFormat) { - /* one more conversion step */ - GLint texComponents = _mesa_components_in_format(textureBaseFormat); - GLint logComponents = _mesa_components_in_format(logicalBaseFormat); - GLubyte *newImage; - GLint i, n; - GLubyte map[6]; - - /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ - ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || - textureBaseFormat == GL_LUMINANCE_ALPHA); - - /* The actual texture format should have at least as many components - * as the logical texture format. - */ - ASSERT(texComponents >= logComponents); - - newImage = malloc(srcWidth * srcHeight * srcDepth - * texComponents * sizeof(GLubyte)); - if (!newImage) { - free(tempImage); - return NULL; - } - - compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); - - n = srcWidth * srcHeight * srcDepth; - for (i = 0; i < n; i++) { - GLint k; - for (k = 0; k < texComponents; k++) { - GLint j = map[k]; - if (j == ZERO) - newImage[i * texComponents + k] = 0; - else if (j == ONE) - newImage[i * texComponents + k] = 255; - else - newImage[i * texComponents + k] = tempImage[i * logComponents + j]; - } - } - - free(tempImage); - tempImage = newImage; - } - - return tempImage; -} - - static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE }; @@ -716,46 +146,6 @@ memcpy_texture(struct gl_context *ctx, /** - * General-case function for storing a color texture images with - * components that can be represented with ubytes. Example destination - * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565. - */ -static GLboolean -store_ubyte_texture(TEXSTORE_PARAMS) -{ - const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte); - GLubyte *tempImage, *src; - GLint img; - - tempImage = _mesa_make_temp_ubyte_image(ctx, dims, - baseInternalFormat, - GL_RGBA, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, - srcPacking); - 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, - src, srcRowStride, - dstSlices[img], dstRowStride); - src += srcHeight * srcRowStride; - } - free(tempImage); - - return GL_TRUE; -} - - - - -/** * Store a 32-bit integer or float depth component texture image. */ static GLboolean @@ -888,56 +278,6 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) /** - * Store an rgb565 or rgb565_rev texture image. - */ -static GLboolean -_mesa_texstore_rgb565(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM || - dstFormat == MESA_FORMAT_R5G6B5_UNORM); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_BYTE && - dims == 2) { - /* do optimized tex store */ - const GLint srcRowStride = - _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLubyte *src = (const GLubyte *) - _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, - srcFormat, srcType, 0, 0, 0); - GLubyte *dst = dstSlices[0]; - GLint row, col; - for (row = 0; row < srcHeight; row++) { - const GLubyte *srcUB = (const GLubyte *) src; - GLushort *dstUS = (GLushort *) dst; - /* check for byteswapped format */ - if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] ); - srcUB += 3; - } - } - else { - for (col = 0; col < srcWidth; col++) { - dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] ); - srcUB += 3; - } - } - dst += dstRowStride; - src += srcRowStride; - } - return GL_TRUE; - } else { - return GL_FALSE; - } -} - - -/** * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. */ static GLboolean @@ -1245,119 +585,6 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) } static GLboolean -_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* 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, col; - 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++) { - GLuint *dstUI = (GLuint *) dstRow; - if (is_unsigned) { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = MIN2(src[RCOMP], 0x3ff); - g = MIN2(src[GCOMP], 0x3ff); - b = MIN2(src[BCOMP], 0x3ff); - a = MIN2(src[ACOMP], 0x003); - dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); - src += 4; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); - g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); - b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); - a = CLAMP((GLint) src[ACOMP], 0, 0x003); - dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) -{ - const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); - - ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT); - ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - - { - /* 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, col; - 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++) { - GLuint *dstUI = (GLuint *) dstRow; - if (is_unsigned) { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = MIN2(src[RCOMP], 0x3ff); - g = MIN2(src[GCOMP], 0x3ff); - b = MIN2(src[BCOMP], 0x3ff); - a = MIN2(src[ACOMP], 0x003); - dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); - src += 4; - } - } else { - for (col = 0; col < srcWidth; col++) { - GLushort a,r,g,b; - r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); - g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); - b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); - a = CLAMP((GLint) src[ACOMP], 0, 0x003); - dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); - src += 4; - } - } - dstRow += dstRowStride; - } - } - free((void *) tempImage); - } - return GL_TRUE; -} - - -static GLboolean texstore_depth_stencil(TEXSTORE_PARAMS) { static StoreTexImageFunc table[MESA_FORMAT_COUNT]; @@ -1446,329 +673,149 @@ texstore_compressed(TEXSTORE_PARAMS) 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) +texstore_rgba(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; - - if (srcFormat == GL_COLOR_INDEX) - return GL_FALSE; - - if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) - 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; + void *tempImage = NULL, *tempRGBA = NULL; + int srcRowStride, img; + GLubyte *src, *dst; + uint32_t srcMesaFormat; + uint8_t rebaseSwizzle[4]; + bool needRebase; + bool transferOpsDone = false; + + /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case + * and _mesa_format_convert does not support it. In this case the we only + * allow conversions between YCBCR formats and it is mostly a memcpy. + */ + if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) { + return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat, + dstFormat, dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, + srcPacking); } - 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]]]]; - } + /* We have to deal with GL_COLOR_INDEX manually because + * _mesa_format_convert does not handle this format. So what we do here is + * convert it to RGBA ubyte first and then convert from that to dst as usual. + */ + if (srcFormat == GL_COLOR_INDEX) { + /* Notice that this will already handle byte swapping if necessary */ + tempImage = + _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims, + srcAddr, srcFormat, srcType, + srcWidth, srcHeight, srcDepth, + srcPacking, + ctx->_ImageTransferState); + if (!tempImage) + return GL_FALSE; - /* Is it normalized? */ - normalized |= !_mesa_is_enum_format_integer(srcFormat); + /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops + * if needed. + */ + transferOpsDone = true; - 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; - } + /* Now we only have to adjust our src info for a conversion from + * the RGBA ubyte and then we continue as usual. + */ + srcAddr = tempImage; + srcFormat = GL_RGBA; + srcType = GL_UNSIGNED_BYTE; + } else if (srcPacking->SwapBytes) { + /* We have to handle byte-swapping scenarios before calling + * _mesa_format_convert + */ + GLint swapSize = _mesa_sizeof_packed_type(srcType); + if (swapSize == 2 || swapSize == 4) { + int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType); + int swapsPerPixel = bytesPerPixel / swapSize; + int elementCount = srcWidth * srcHeight * srcDepth; + assert(bytesPerPixel % swapSize == 0); + tempImage = malloc(elementCount * bytesPerPixel); + if (!tempImage) + return GL_FALSE; + if (swapSize == 2) + _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, + elementCount * swapsPerPixel); + else + _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, + elementCount * swapsPerPixel); + srcAddr = tempImage; } - 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 = + srcRowStride = _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. - */ + srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType); 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; + /* If we have transferOps then we need to convert to RGBA float first, + then apply transferOps, then do the conversion to dst + */ + if (!transferOpsDone && + _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) { + /* Allocate RGBA float image */ + int elementCount = srcWidth * srcHeight * srcDepth; + tempRGBA = malloc(4 * elementCount * sizeof(float)); + if (!tempRGBA) { + free(tempImage); + free(tempRGBA); + return GL_FALSE; } - } - 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; + /* Convert from src to RGBA float */ + src = (GLubyte *) srcAddr; + dst = (GLubyte *) tempRGBA; + for (img = 0; img < srcDepth; img++) { + _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float), + src, srcMesaFormat, srcRowStride, + srcWidth, srcHeight, NULL); + src += srcHeight * srcRowStride; + dst += srcHeight * 4 * srcWidth * sizeof(float); } - } - free(tmp_row); - - return GL_TRUE; -} + /* Apply transferOps */ + _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount, + (float(*)[4]) tempRGBA); -/** 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) { - free(tmp_row); - return GL_FALSE; + /* Now we have to adjust our src info for a conversion from + * the RGBA float image and then we continue as usual. + */ + srcAddr = tempRGBA; + srcFormat = GL_RGBA; + srcType = GL_FLOAT; + srcRowStride = srcWidth * 4 * sizeof(float); + srcMesaFormat = RGBA32_FLOAT; } - 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]]]; - } + src = (GLubyte *) + _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, + srcFormat, srcType, 0, 0, 0); - if (_mesa_is_type_unsigned(srcType)) { - tmp_type = GL_UNSIGNED_INT; + if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) { + needRebase = + _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat, + rebaseSwizzle); } else { - tmp_type = GL_INT; + needRebase = false; } 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; - } + _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride, + src, srcMesaFormat, srcRowStride, + srcWidth, srcHeight, + needRebase ? rebaseSwizzle : NULL); + src += srcHeight * srcRowStride; } - free(tmp_row); + free(tempImage); + free(tempRGBA); 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; - - initialized = GL_TRUE; - } - - 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, GLenum baseInternalFormat, diff --git a/mesalib/src/mesa/main/texstore.h b/mesalib/src/mesa/main/texstore.h index 4c41d1fcd..2c974f74a 100644 --- a/mesalib/src/mesa/main/texstore.h +++ b/mesalib/src/mesa/main/texstore.h @@ -81,25 +81,6 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx, const struct gl_pixelstore_attrib *srcPacking); -extern GLubyte * -_mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking); - -GLfloat * -_mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, - GLenum logicalBaseFormat, - GLenum textureBaseFormat, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking, - GLbitfield transferOps); - extern void _mesa_store_teximage(struct gl_context *ctx, GLuint dims, diff --git a/mesalib/src/mesa/main/textureview.c b/mesalib/src/mesa/main/textureview.c index 6e86a9a44..cd87a27d2 100644 --- a/mesalib/src/mesa/main/textureview.c +++ b/mesalib/src/mesa/main/textureview.c @@ -355,7 +355,7 @@ _mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_image *texImage; /* Get a reference to what will become this View's base level */ - texImage = _mesa_select_tex_image(ctx, texObj, target, 0); + texImage = _mesa_select_tex_image(texObj, target, 0); /* When an immutable texture is created via glTexStorage or glTexImageMultisample, * TEXTURE_IMMUTABLE_FORMAT becomes TRUE. @@ -527,8 +527,7 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + minlayer; /* Get a reference to what will become this View's base level */ - origTexImage = _mesa_select_tex_image(ctx, origTexObj, - faceTarget, minlevel); + origTexImage = _mesa_select_tex_image(origTexObj, faceTarget, minlevel); width = origTexImage->Width; height = origTexImage->Height; depth = origTexImage->Depth; diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 32870d0c4..40327fba4 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -45,9 +45,14 @@ _mesa_GetActiveUniform(GLuint program, GLuint index, GLenum *type, GLcharARB *nameOut) { GET_CURRENT_CONTEXT(ctx); - struct gl_shader_program *shProg = - _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); + struct gl_shader_program *shProg; + + if (maxLength < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)"); + return; + } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); if (!shProg) return; @@ -85,16 +90,16 @@ _mesa_GetActiveUniformsiv(GLuint program, struct gl_shader_program *shProg; GLsizei i; - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); - if (!shProg) - return; - if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(uniformCount < 0)"); return; } + shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); + if (!shProg) + return; + for (i = 0; i < uniformCount; i++) { GLuint index = uniformIndices[i]; @@ -464,6 +469,9 @@ log_uniform(const void *values, enum glsl_base_type basicType, case GLSL_TYPE_FLOAT: printf("%g ", v[i].f); break; + case GLSL_TYPE_DOUBLE: + printf("%g ", *(double* )&v[i * 2].f); + break; default: assert(!"Should not get here."); break; @@ -524,11 +532,12 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, */ const unsigned components = MAX2(1, uni->type->vector_elements); const unsigned vectors = MAX2(1, uni->type->matrix_columns); + const int dmul = uni->type->base_type == GLSL_TYPE_DOUBLE ? 2 : 1; /* Store the data in the driver's requested type in the driver's storage * areas. */ - unsigned src_vector_byte_stride = components * 4; + unsigned src_vector_byte_stride = components * 4 * dmul; for (i = 0; i < uni->num_driver_storage; i++) { struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; @@ -536,7 +545,7 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, const unsigned extra_stride = store->element_stride - (vectors * store->vector_stride); const uint8_t *src = - (uint8_t *) (&uni->storage[array_index * (components * vectors)].i); + (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i); #if 0 printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " @@ -603,6 +612,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, unsigned src_components) { unsigned offset; + int size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1; struct gl_uniform_storage *const uni = validate_uniform_parameters(ctx, shProg, location, count, @@ -618,7 +628,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, bool match; switch (uni->type->base_type) { case GLSL_TYPE_BOOL: - match = true; + match = (basicType != GLSL_TYPE_DOUBLE); break; case GLSL_TYPE_SAMPLER: case GLSL_TYPE_IMAGE: @@ -705,8 +715,8 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, /* Store the data in the "actual type" backing storage for the uniform. */ if (!uni->type->is_boolean()) { - memcpy(&uni->storage[components * offset], values, - sizeof(uni->storage[0]) * components * count); + memcpy(&uni->storage[size_mul * components * offset], values, + sizeof(uni->storage[0]) * components * count * size_mul); } else { const union gl_constant_value *src = (const union gl_constant_value *) values; @@ -803,13 +813,14 @@ extern "C" void _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, GLuint cols, GLuint rows, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *values) + GLboolean transpose, + const GLvoid *values, GLenum type) { unsigned offset; unsigned vectors; unsigned components; unsigned elements; - + int size_mul; struct gl_uniform_storage *const uni = validate_uniform_parameters(ctx, shProg, location, count, &offset, "glUniformMatrix"); @@ -822,6 +833,9 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, return; } + assert(type == GL_FLOAT || type == GL_DOUBLE); + size_mul = type == GL_DOUBLE ? 2 : 1; + assert(!uni->type->is_sampler()); vectors = uni->type->matrix_columns; components = uni->type->vector_elements; @@ -847,7 +861,7 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, } if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { - log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count, + log_uniform(values, uni->type->base_type, components, vectors, count, bool(transpose), shProg, location, uni); } @@ -874,11 +888,11 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, if (!transpose) { memcpy(&uni->storage[elements * offset], values, - sizeof(uni->storage[0]) * elements * count); - } else { + sizeof(uni->storage[0]) * elements * count * size_mul); + } else if (type == GL_FLOAT) { /* Copy and transpose the matrix. */ - const float *src = values; + const float *src = (const float *)values; float *dst = &uni->storage[elements * offset].f; for (int i = 0; i < count; i++) { @@ -891,6 +905,21 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, dst += elements; src += elements; } + } else { + assert(type == GL_DOUBLE); + const double *src = (const double *)values; + double *dst = (double *)&uni->storage[elements * offset].f; + + for (int i = 0; i < count; i++) { + for (unsigned r = 0; r < rows; r++) { + for (unsigned c = 0; c < cols; c++) { + dst[(c * components) + r] = src[c + (r * vectors)]; + } + } + + dst += elements; + src += elements; + } } uni->initialized = true; diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index d2d70e7f7..e471b878c 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -553,7 +553,7 @@ _mesa_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 2, 2, location, count, transpose, value); + 2, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -562,7 +562,7 @@ _mesa_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 3, 3, location, count, transpose, value); + 3, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -571,7 +571,7 @@ _mesa_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 4, 4, location, count, transpose, value); + 4, 4, location, count, transpose, value, GL_FLOAT); } /** Same as above with direct state access **/ @@ -683,7 +683,7 @@ _mesa_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix2fv"); - _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -694,7 +694,7 @@ _mesa_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix3fv"); - _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -705,7 +705,7 @@ _mesa_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix4fv"); - _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_FLOAT); } @@ -718,7 +718,7 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 2, 3, location, count, transpose, value); + 2, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -727,7 +727,7 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 3, 2, location, count, transpose, value); + 3, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -736,7 +736,7 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 2, 4, location, count, transpose, value); + 2, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -745,7 +745,7 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 4, 2, location, count, transpose, value); + 4, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -754,7 +754,7 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 3, 4, location, count, transpose, value); + 3, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -763,7 +763,7 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, { GET_CURRENT_CONTEXT(ctx); _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, - 4, 3, location, count, transpose, value); + 4, 3, location, count, transpose, value, GL_FLOAT); } /** Same as above with direct state access **/ @@ -776,7 +776,7 @@ _mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix2x3fv"); - _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -787,7 +787,7 @@ _mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix3x2fv"); - _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -798,7 +798,7 @@ _mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix2x4fv"); - _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -809,7 +809,7 @@ _mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix4x2fv"); - _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -820,7 +820,7 @@ _mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix3x4fv"); - _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_FLOAT); } void GLAPIENTRY @@ -831,7 +831,7 @@ _mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniformMatrix4x3fv"); - _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value); + _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_FLOAT); } @@ -1338,3 +1338,347 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, return; } } + +void GLAPIENTRY +_mesa_Uniform1d(GLint location, GLdouble v0) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_Uniform2d(GLint location, GLdouble v0, GLdouble v1) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[2]; + v[0] = v0; + v[1] = v1; + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_Uniform3d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_Uniform4d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2, + GLdouble v3) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_Uniform1dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_Uniform2dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_Uniform3dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_Uniform4dv(GLint location, GLsizei count, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 2, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 3, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 4, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 2, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 3, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 2, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 4, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 3, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram, + 4, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniform1d(GLuint program, GLint location, GLdouble v0) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform1d"); + _mesa_uniform(ctx, shProg, location, 1, &v0, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_ProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[2]; + struct gl_shader_program *shProg; + v[0] = v0; + v[1] = v1; + shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2d"); + _mesa_uniform(ctx, shProg, location, 1, v, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_ProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1, + GLdouble v2) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[3]; + struct gl_shader_program *shProg; + v[0] = v0; + v[1] = v1; + v[2] = v2; + shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3d"); + _mesa_uniform(ctx, shProg, location, 1, v, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_ProgramUniform4d(GLuint program, GLint location, GLdouble v0, GLdouble v1, + GLdouble v2, GLdouble v3) +{ + GET_CURRENT_CONTEXT(ctx); + GLdouble v[4]; + struct gl_shader_program *shProg; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4d"); + _mesa_uniform(ctx, shProg, location, 1, v, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_ProgramUniform1dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform1dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 1); +} + +void GLAPIENTRY +_mesa_ProgramUniform2dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform2dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 2); +} + +void GLAPIENTRY +_mesa_ProgramUniform3dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform3dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 3); +} + +void GLAPIENTRY +_mesa_ProgramUniform4dv(GLuint program, GLint location, GLsizei count, + const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniform4dv"); + _mesa_uniform(ctx, shProg, location, count, value, GLSL_TYPE_DOUBLE, 4); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix2dv"); + _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix3dv"); + _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix4dv"); + _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix2x3dv"); + _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix3x2dv"); + _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix2x4dv"); + _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix4x2dv"); + _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix3x4dv"); + _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_DOUBLE); +} + +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble * value) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glProgramUniformMatrix4x3dv"); + _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_DOUBLE); +} diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h index 0a9ee7de9..0e6113fe9 100644 --- a/mesalib/src/mesa/main/uniforms.h +++ b/mesalib/src/mesa/main/uniforms.h @@ -254,6 +254,95 @@ _mesa_GetActiveUniformsiv(GLuint program, void GLAPIENTRY _mesa_GetUniformiv(GLuint, GLint, GLint *); +void GLAPIENTRY +_mesa_Uniform1d(GLint, GLdouble); +void GLAPIENTRY +_mesa_Uniform2d(GLint, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_Uniform3d(GLint, GLdouble, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_Uniform4d(GLint, GLdouble, GLdouble, GLdouble, GLdouble); + +void GLAPIENTRY +_mesa_Uniform1dv(GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_Uniform2dv(GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_Uniform3dv(GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_Uniform4dv(GLint, GLsizei, const GLdouble *); + +void GLAPIENTRY +_mesa_UniformMatrix2dv(GLint, GLsizei, GLboolean, const GLdouble *); +void GLAPIENTRY +_mesa_UniformMatrix3dv(GLint, GLsizei, GLboolean, const GLdouble *); +void GLAPIENTRY +_mesa_UniformMatrix4dv(GLint, GLsizei, GLboolean, const GLdouble *); +void GLAPIENTRY +_mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); +void GLAPIENTRY +_mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, + const GLdouble *value); + +void GLAPIENTRY +_mesa_ProgramUniform1d(GLuint program, GLint, GLdouble); +void GLAPIENTRY +_mesa_ProgramUniform2d(GLuint program, GLint, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_ProgramUniform3d(GLuint program, GLint, GLdouble, GLdouble, GLdouble); +void GLAPIENTRY +_mesa_ProgramUniform4d(GLuint program, GLint, GLdouble, GLdouble, GLdouble, GLdouble); + +void GLAPIENTRY +_mesa_ProgramUniform1dv(GLuint program, GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniform2dv(GLuint program, GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniform3dv(GLuint program, GLint, GLsizei, const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniform4dv(GLuint program, GLint, GLsizei, const GLdouble *); + +void GLAPIENTRY +_mesa_ProgramUniformMatrix2dv(GLuint program, GLint, GLsizei, GLboolean, + const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniformMatrix3dv(GLuint program, GLint, GLsizei, GLboolean, + const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniformMatrix4dv(GLuint program, GLint, GLsizei, GLboolean, + const GLdouble *); +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); +void GLAPIENTRY +_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value); + long _mesa_parse_program_resource_name(const GLchar *name, const GLchar **out_base_name_end); @@ -273,7 +362,8 @@ void _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, GLuint cols, GLuint rows, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *values); + GLboolean transpose, + const GLvoid *values, GLenum type); void _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 89aaad1aa..978ec7b53 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -255,7 +255,7 @@ update_array_format(struct gl_context *ctx, { struct gl_vertex_attrib_array *array; GLbitfield typeBit; - GLuint elementSize; + GLint elementSize; GLenum format = GL_RGBA; if (ctx->Array.LegalTypesMask == 0 || ctx->Array.LegalTypesMaskAPI != ctx->API) { diff --git a/mesalib/src/mesa/main/vdpau.c b/mesalib/src/mesa/main/vdpau.c index e1c3e00ba..0efa56e4f 100644 --- a/mesalib/src/mesa/main/vdpau.c +++ b/mesalib/src/mesa/main/vdpau.c @@ -33,9 +33,9 @@ #include <stdbool.h> #include "util/hash_table.h" +#include "util/set.h" #include "context.h" #include "glformats.h" -#include "set.h" #include "texobj.h" #include "teximage.h" #include "vdpau.h" @@ -73,7 +73,8 @@ _mesa_VDPAUInitNV(const GLvoid *vdpDevice, const GLvoid *getProcAddress) ctx->vdpDevice = vdpDevice; ctx->vdpGetProcAddress = getProcAddress; - ctx->vdpSurfaces = _mesa_set_create(NULL, _mesa_key_pointer_equal); + ctx->vdpSurfaces = _mesa_set_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); } static void @@ -179,7 +180,7 @@ register_surface(struct gl_context *ctx, GLboolean isOutput, _mesa_reference_texobj(&surf->textures[i], tex); } - _mesa_set_add(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf); + _mesa_set_add(ctx->vdpSurfaces, surf); return (GLintptr)surf; } @@ -227,7 +228,7 @@ _mesa_VDPAUIsSurfaceNV(GLintptr surface) return false; } - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { return false; } @@ -251,7 +252,7 @@ _mesa_VDPAUUnregisterSurfaceNV(GLintptr surface) if (surface == 0) return; - entry = _mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf); + entry = _mesa_set_search(ctx->vdpSurfaces, surf); if (!entry) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUUnregisterSurfaceNV"); return; @@ -280,7 +281,7 @@ _mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize, return; } - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUGetSurfaceivNV"); return; } @@ -312,7 +313,7 @@ _mesa_VDPAUSurfaceAccessNV(GLintptr surface, GLenum access) return; } - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } @@ -346,7 +347,7 @@ _mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) for (i = 0; i < numSurfaces; ++i) { struct vdp_surface *surf = (struct vdp_surface *)surfaces[i]; - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } @@ -400,7 +401,7 @@ _mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) for (i = 0; i < numSurfaces; ++i) { struct vdp_surface *surf = (struct vdp_surface *)surfaces[i]; - if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) { + if (!_mesa_set_search(ctx->vdpSurfaces, surf)) { _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV"); return; } @@ -422,7 +423,7 @@ _mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) _mesa_lock_texture(ctx, tex); - image = _mesa_select_tex_image(ctx, tex, surf->target, 0); + image = _mesa_select_tex_image(tex, surf->target, 0); ctx->Driver.VDPAUUnmapSurface(ctx, surf->target, surf->access, surf->output, tex, image, |