From 5efb0a5e19b75137b7294b27f4e7878aeb8f0927 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 12 Dec 2011 12:23:04 +0100 Subject: libxtrans libX11 libxcb xserver mesa git update 12 dec 2011 --- mesalib/src/mesa/main/accum.c | 386 ++++- mesalib/src/mesa/main/accum.h | 18 + mesalib/src/mesa/main/dd.h | 18 - mesalib/src/mesa/main/depthstencil.c | 155 -- mesalib/src/mesa/main/depthstencil.h | 16 - mesalib/src/mesa/main/format_pack.c | 2496 +++++++++++++++++++++++++++++++++ mesalib/src/mesa/main/format_pack.h | 98 ++ mesalib/src/mesa/main/format_unpack.c | 8 +- mesalib/src/mesa/main/formats.c | 2 + mesalib/src/mesa/main/formats.h | 8 + mesalib/src/mesa/main/framebuffer.c | 1 + mesalib/src/mesa/main/image.c | 104 +- mesalib/src/mesa/main/image.h | 7 + mesalib/src/mesa/main/pack.c | 4 + mesalib/src/mesa/main/pbo.c | 29 +- mesalib/src/mesa/main/readpix.c | 23 +- mesalib/src/mesa/main/renderbuffer.c | 2036 +-------------------------- mesalib/src/mesa/main/renderbuffer.h | 57 - mesalib/src/mesa/main/texobj.c | 23 +- mesalib/src/mesa/main/texparam.c | 6 +- mesalib/src/mesa/main/texstore.c | 17 +- 21 files changed, 3150 insertions(+), 2362 deletions(-) create mode 100644 mesalib/src/mesa/main/format_pack.c create mode 100644 mesalib/src/mesa/main/format_pack.h (limited to 'mesalib/src/mesa/main') diff --git a/mesalib/src/mesa/main/accum.c b/mesalib/src/mesa/main/accum.c index d7ed3a849..eb06bbb6e 100644 --- a/mesalib/src/mesa/main/accum.c +++ b/mesalib/src/mesa/main/accum.c @@ -24,7 +24,10 @@ #include "glheader.h" #include "accum.h" +#include "condrender.h" #include "context.h" +#include "format_unpack.h" +#include "format_pack.h" #include "imports.h" #include "macros.h" #include "mfeatures.h" @@ -101,7 +104,7 @@ _mesa_Accum( GLenum op, GLfloat value ) return; if (ctx->RenderMode == GL_RENDER) { - ctx->Driver.Accum(ctx, op, value); + _mesa_accum(ctx, op, value); } } @@ -123,3 +126,384 @@ _mesa_init_accum( struct gl_context *ctx ) /* Accumulate buffer group */ ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 ); } + + + + +/** + * Clear the accumulation buffer by mapping the renderbuffer and + * writing the clear color to it. Called by the driver's implementation + * of the glClear function. + */ +void +_mesa_clear_accum_buffer(struct gl_context *ctx) +{ + GLuint x, y, width, height; + GLubyte *accMap; + GLint accRowStride; + struct gl_renderbuffer *accRb; + + if (!ctx->DrawBuffer) + return; + + accRb = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + if (!accRb) + return; /* missing accum buffer, not an error */ + + /* bounds, with scissor */ + x = ctx->DrawBuffer->_Xmin; + y = ctx->DrawBuffer->_Ymin; + width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + + ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height, + GL_MAP_WRITE_BIT, &accMap, &accRowStride); + + if (!accMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + return; + } + + if (accRb->Format == MESA_FORMAT_SIGNED_RGBA_16) { + const GLshort clearR = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]); + const GLshort clearG = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]); + const GLshort clearB = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]); + const GLshort clearA = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]); + GLuint i, j; + + for (j = 0; j < height; j++) { + GLshort *row = (GLshort *) accMap; + + for (i = 0; i < width; i++) { + row[i * 4 + 0] = clearR; + row[i * 4 + 1] = clearG; + row[i * 4 + 2] = clearB; + row[i * 4 + 3] = clearA; + } + accMap += accRowStride; + } + } + else { + /* other types someday? */ + _mesa_warning(ctx, "unexpected accum buffer type"); + } + + ctx->Driver.UnmapRenderbuffer(ctx, accRb); +} + + +/** + * if (bias) + * Accum += value + * else + * Accum *= value + */ +static void +accum_scale_or_bias(struct gl_context *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height, + GLboolean bias) +{ + struct gl_renderbuffer *accRb = + ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + GLubyte *accMap; + GLint accRowStride; + + assert(accRb); + + ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &accMap, &accRowStride); + + if (!accMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + return; + } + + if (accRb->Format == MESA_FORMAT_SIGNED_RGBA_16) { + const GLshort incr = (GLshort) (value * 32767.0f); + GLuint i, j; + if (bias) { + for (j = 0; j < height; j++) { + GLshort *acc = (GLshort *) accMap; + for (i = 0; i < 4 * width; i++) { + acc[i] += incr; + } + accMap += accRowStride; + } + } + else { + /* scale */ + for (j = 0; j < height; j++) { + GLshort *acc = (GLshort *) accMap; + for (i = 0; i < 4 * width; i++) { + acc[i] = (GLshort) (acc[i] * value); + } + accMap += accRowStride; + } + } + } + else { + /* other types someday? */ + } + + ctx->Driver.UnmapRenderbuffer(ctx, accRb); +} + + +/** + * if (load) + * Accum = ColorBuf * value + * else + * Accum += ColorBuf * value + */ +static void +accum_or_load(struct gl_context *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height, + GLboolean load) +{ + struct gl_renderbuffer *accRb = + ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; + struct gl_renderbuffer *colorRb = ctx->ReadBuffer->_ColorReadBuffer; + GLubyte *accMap, *colorMap; + GLint accRowStride, colorRowStride; + GLbitfield mappingFlags; + + if (!colorRb) { + /* no read buffer - OK */ + return; + } + + assert(accRb); + + mappingFlags = GL_MAP_WRITE_BIT; + if (!load) /* if we're accumulating */ + mappingFlags |= GL_MAP_READ_BIT; + + /* Map accum buffer */ + ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, + mappingFlags, &accMap, &accRowStride); + if (!accMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + return; + } + + /* Map color buffer */ + ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height, + GL_MAP_READ_BIT, + &colorMap, &colorRowStride); + if (!colorMap) { + ctx->Driver.UnmapRenderbuffer(ctx, accRb); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + return; + } + + if (accRb->Format == MESA_FORMAT_SIGNED_RGBA_16) { + const GLfloat scale = value * 32767.0f; + GLuint i, j; + GLfloat (*rgba)[4]; + + rgba = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat)); + if (rgba) { + for (j = 0; j < height; j++) { + GLshort *acc = (GLshort *) accMap; + + /* read colors from source color buffer */ + _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, rgba); + + if (load) { + for (i = 0; i < width; i++) { + acc[i * 4 + 0] = (GLshort) (rgba[i][RCOMP] * scale); + acc[i * 4 + 1] = (GLshort) (rgba[i][GCOMP] * scale); + acc[i * 4 + 2] = (GLshort) (rgba[i][BCOMP] * scale); + acc[i * 4 + 3] = (GLshort) (rgba[i][ACOMP] * scale); + } + } + else { + /* accumulate */ + for (i = 0; i < width; i++) { + acc[i * 4 + 0] += (GLshort) (rgba[i][RCOMP] * scale); + acc[i * 4 + 1] += (GLshort) (rgba[i][GCOMP] * scale); + acc[i * 4 + 2] += (GLshort) (rgba[i][BCOMP] * scale); + acc[i * 4 + 3] += (GLshort) (rgba[i][ACOMP] * scale); + } + } + + colorMap += colorRowStride; + accMap += accRowStride; + } + + free(rgba); + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + } + } + else { + /* other types someday? */ + } + + ctx->Driver.UnmapRenderbuffer(ctx, accRb); + ctx->Driver.UnmapRenderbuffer(ctx, colorRb); +} + + +/** + * ColorBuffer = Accum * value + */ +static void +accum_return(struct gl_context *ctx, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *accRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer; + GLubyte *accMap, *colorMap; + GLint accRowStride, colorRowStride; + GLuint buffer; + + /* Map accum buffer */ + ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, + GL_MAP_READ_BIT, + &accMap, &accRowStride); + if (!accMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + return; + } + + /* Loop over destination buffers */ + for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) { + struct gl_renderbuffer *colorRb = fb->_ColorDrawBuffers[buffer]; + const GLboolean masking = (!ctx->Color.ColorMask[buffer][RCOMP] || + !ctx->Color.ColorMask[buffer][GCOMP] || + !ctx->Color.ColorMask[buffer][BCOMP] || + !ctx->Color.ColorMask[buffer][ACOMP]); + GLbitfield mappingFlags = GL_MAP_WRITE_BIT; + + if (masking) + mappingFlags |= GL_MAP_READ_BIT; + + /* Map color buffer */ + ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height, + mappingFlags, &colorMap, &colorRowStride); + if (!colorMap) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + continue; + } + + if (accRb->Format == MESA_FORMAT_SIGNED_RGBA_16) { + const GLfloat scale = value / 32767.0f; + GLint i, j; + GLfloat (*rgba)[4], (*dest)[4]; + + rgba = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat)); + dest = (GLfloat (*)[4]) malloc(width * 4 * sizeof(GLfloat)); + + if (rgba && dest) { + for (j = 0; j < height; j++) { + GLshort *acc = (GLshort *) accMap; + + for (i = 0; i < width; i++) { + rgba[i][0] = acc[i * 4 + 0] * scale; + rgba[i][1] = acc[i * 4 + 1] * scale; + rgba[i][2] = acc[i * 4 + 2] * scale; + rgba[i][3] = acc[i * 4 + 3] * scale; + } + + if (masking) { + + /* get existing colors from dest buffer */ + _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, dest); + + /* use the dest colors where mask[channel] = 0 */ + if (ctx->Color.ColorMask[buffer][RCOMP] == 0) { + for (i = 0; i < width; i++) + rgba[i][RCOMP] = dest[i][RCOMP]; + } + if (ctx->Color.ColorMask[buffer][GCOMP] == 0) { + for (i = 0; i < width; i++) + rgba[i][GCOMP] = dest[i][GCOMP]; + } + if (ctx->Color.ColorMask[buffer][BCOMP] == 0) { + for (i = 0; i < width; i++) + rgba[i][BCOMP] = dest[i][BCOMP]; + } + if (ctx->Color.ColorMask[buffer][ACOMP] == 0) { + for (i = 0; i < width; i++) + rgba[i][ACOMP] = dest[i][ACOMP]; + } + } + + _mesa_pack_float_rgba_row(colorRb->Format, width, + (const GLfloat (*)[4]) rgba, colorMap); + + accMap += accRowStride; + colorMap += colorRowStride; + } + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); + } + free(rgba); + free(dest); + } + else { + /* other types someday? */ + } + + ctx->Driver.UnmapRenderbuffer(ctx, colorRb); + } + + ctx->Driver.UnmapRenderbuffer(ctx, accRb); +} + + + +/** + * Software fallback for glAccum. A hardware driver that supports + * signed 16-bit color channels could implement hardware accumulation + * operations, but no driver does so at this time. + */ +void +_mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value) +{ + GLint xpos, ypos, width, height; + + if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) { + _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer"); + return; + } + + if (!_mesa_check_conditional_render(ctx)) + return; + + xpos = ctx->DrawBuffer->_Xmin; + ypos = ctx->DrawBuffer->_Ymin; + width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + + switch (op) { + case GL_ADD: + if (value != 0.0F) { + accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_TRUE); + } + break; + case GL_MULT: + if (value != 1.0F) { + accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_FALSE); + } + break; + case GL_ACCUM: + if (value != 0.0F) { + accum_or_load(ctx, value, xpos, ypos, width, height, GL_FALSE); + } + break; + case GL_LOAD: + accum_or_load(ctx, value, xpos, ypos, width, height, GL_TRUE); + break; + case GL_RETURN: + accum_return(ctx, value, xpos, ypos, width, height); + break; + default: + _mesa_problem(ctx, "invalid mode in _mesa_accum()"); + break; + } +} diff --git a/mesalib/src/mesa/main/accum.h b/mesalib/src/mesa/main/accum.h index f16378cc1..5b3f06aa9 100644 --- a/mesalib/src/mesa/main/accum.h +++ b/mesalib/src/mesa/main/accum.h @@ -42,6 +42,7 @@ struct _glapi_table; struct gl_context; +struct gl_renderbuffer; #if FEATURE_accum @@ -51,6 +52,12 @@ _mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); extern void _mesa_init_accum_dispatch(struct _glapi_table *disp); +extern void +_mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value); + +extern void +_mesa_clear_accum_buffer(struct gl_context *ctx); + #else /* FEATURE_accum */ #include "main/compiler.h" @@ -67,6 +74,17 @@ _mesa_init_accum_dispatch(struct _glapi_table *disp) { } +static inline void +_mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value) +{ +} + +static inline void +_mesa_clear_accum_buffer(struct gl_context *ctx) +{ +} + + #endif /* FEATURE_accum */ extern void diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index 9842540da..d6f70d1c4 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -532,24 +532,6 @@ struct dd_function_table { void (*UnmapRenderbuffer)(struct gl_context *ctx, struct gl_renderbuffer *rb); - /** - * Note: no context argument. This function doesn't initially look - * like it belongs here, except that the driver is the only entity - * that knows for sure how the texture memory is allocated - via - * the above callbacks. There is then an argument that the driver - * knows what memcpy paths might be fast. Typically this is invoked with - * - * to -- a pointer into texture memory allocated by NewTextureImage() above. - * from -- a pointer into client memory or a mesa temporary. - * sz -- nr bytes to copy. - */ - void* (*TextureMemCpy)( void *to, const void *from, size_t sz ); - - /** - * Called by glAreTextureResident(). - */ - GLboolean (*IsTextureResident)( struct gl_context *ctx, - struct gl_texture_object *t ); /*@}*/ diff --git a/mesalib/src/mesa/main/depthstencil.c b/mesalib/src/mesa/main/depthstencil.c index 40d6c9612..af5c12f67 100644 --- a/mesalib/src/mesa/main/depthstencil.c +++ b/mesalib/src/mesa/main/depthstencil.c @@ -957,158 +957,3 @@ _mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer return s8rb; } - - - -/** - ** The following functions are useful for hardware drivers that only - ** implement combined depth/stencil buffers. - ** The GL_EXT_framebuffer_object extension allows indepedent depth and - ** stencil buffers to be used in any combination. - ** Therefore, we sometimes have to merge separate depth and stencil - ** renderbuffers into a single depth+stencil renderbuffer. And sometimes - ** we have to split combined depth+stencil renderbuffers into separate - ** renderbuffers. - **/ - - -/** - * Extract stencil values from the combined depth/stencil renderbuffer, storing - * the values into a separate stencil renderbuffer. - * \param dsRb the source depth/stencil renderbuffer - * \param stencilRb the destination stencil renderbuffer - * (either 8-bit or 32-bit) - */ -void -_mesa_extract_stencil(struct gl_context *ctx, - struct gl_renderbuffer *dsRb, - struct gl_renderbuffer *stencilRb) -{ - GLuint row, width, height; - - ASSERT(dsRb); - ASSERT(stencilRb); - - ASSERT(dsRb->Format == MESA_FORMAT_Z24_S8); - ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT); - ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8 || - stencilRb->Format == MESA_FORMAT_S8); - ASSERT(dsRb->Width == stencilRb->Width); - ASSERT(dsRb->Height == stencilRb->Height); - - width = dsRb->Width; - height = dsRb->Height; - - for (row = 0; row < height; row++) { - GLuint depthStencil[MAX_WIDTH]; - dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil); - if (stencilRb->Format == MESA_FORMAT_S8) { - /* 8bpp stencil */ - GLubyte stencil[MAX_WIDTH]; - GLuint i; - for (i = 0; i < width; i++) { - stencil[i] = depthStencil[i] & 0xff; - } - stencilRb->PutRow(ctx, stencilRb, width, 0, row, stencil, NULL); - } - else { - /* 32bpp stencil */ - /* the 24 depth bits will be ignored */ - ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8); - ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT); - stencilRb->PutRow(ctx, stencilRb, width, 0, row, depthStencil, NULL); - } - } -} - - -/** - * Copy stencil values from a stencil renderbuffer into a combined - * depth/stencil renderbuffer. - * \param dsRb the destination depth/stencil renderbuffer - * \param stencilRb the source stencil buffer (either 8-bit or 32-bit) - */ -void -_mesa_insert_stencil(struct gl_context *ctx, - struct gl_renderbuffer *dsRb, - struct gl_renderbuffer *stencilRb) -{ - GLuint row, width, height; - - ASSERT(dsRb); - ASSERT(stencilRb); - - ASSERT(dsRb->Format == MESA_FORMAT_Z24_S8); - ASSERT(dsRb->DataType == GL_UNSIGNED_INT_24_8_EXT); - ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8 || - stencilRb->Format == MESA_FORMAT_S8); - - ASSERT(dsRb->Width == stencilRb->Width); - ASSERT(dsRb->Height == stencilRb->Height); - - width = dsRb->Width; - height = dsRb->Height; - - for (row = 0; row < height; row++) { - GLuint depthStencil[MAX_WIDTH]; - - dsRb->GetRow(ctx, dsRb, width, 0, row, depthStencil); - - if (stencilRb->Format == MESA_FORMAT_S8) { - /* 8bpp stencil */ - GLubyte stencil[MAX_WIDTH]; - GLuint i; - stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil); - for (i = 0; i < width; i++) { - depthStencil[i] = (depthStencil[i] & 0xffffff00) | stencil[i]; - } - } - else { - /* 32bpp stencil buffer */ - GLuint stencil[MAX_WIDTH], i; - ASSERT(stencilRb->Format == MESA_FORMAT_Z24_S8); - ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT); - stencilRb->GetRow(ctx, stencilRb, width, 0, row, stencil); - for (i = 0; i < width; i++) { - depthStencil[i] - = (depthStencil[i] & 0xffffff00) | (stencil[i] & 0xff); - } - } - - dsRb->PutRow(ctx, dsRb, width, 0, row, depthStencil, NULL); - } -} - - -/** - * Convert the stencil buffer from 8bpp to 32bpp depth/stencil. - * \param stencilRb the stencil renderbuffer to promote - */ -void -_mesa_promote_stencil(struct gl_context *ctx, struct gl_renderbuffer *stencilRb) -{ - const GLsizei width = stencilRb->Width; - const GLsizei height = stencilRb->Height; - GLubyte *data; - GLint i, j, k; - - ASSERT(stencilRb->Format == MESA_FORMAT_S8); - ASSERT(stencilRb->Data); - - data = (GLubyte *) stencilRb->Data; - stencilRb->Data = NULL; - stencilRb->AllocStorage(ctx, stencilRb, GL_DEPTH24_STENCIL8_EXT, - width, height); - - ASSERT(stencilRb->DataType == GL_UNSIGNED_INT_24_8_EXT); - - k = 0; - for (i = 0; i < height; i++) { - GLuint depthStencil[MAX_WIDTH]; - for (j = 0; j < width; j++) { - depthStencil[j] = data[k++]; - } - stencilRb->PutRow(ctx, stencilRb, width, 0, i, depthStencil, NULL); - } - free(data); -} diff --git a/mesalib/src/mesa/main/depthstencil.h b/mesalib/src/mesa/main/depthstencil.h index b47a2e482..c3871d805 100644 --- a/mesalib/src/mesa/main/depthstencil.h +++ b/mesalib/src/mesa/main/depthstencil.h @@ -43,20 +43,4 @@ _mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer *dsrb); -extern void -_mesa_extract_stencil(struct gl_context *ctx, - struct gl_renderbuffer *dsRb, - struct gl_renderbuffer *stencilRb); - - -extern void -_mesa_insert_stencil(struct gl_context *ctx, - struct gl_renderbuffer *dsRb, - struct gl_renderbuffer *stencilRb); - - -extern void -_mesa_promote_stencil(struct gl_context *ctx, struct gl_renderbuffer *stencilRb); - - #endif /* DEPTHSTENCIL_H */ diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c new file mode 100644 index 000000000..390b494c0 --- /dev/null +++ b/mesalib/src/mesa/main/format_pack.c @@ -0,0 +1,2496 @@ +/* + * 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 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" + + +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); + + + +static inline GLfloat +linear_to_srgb(GLfloat cl) +{ + if (cl < 0.0f) + return 0.0f; + else if (cl < 0.0031308f) + return 12.92f * cl; + else if (cl < 1.0f) + return 1.055f * powf(cl, 0.41666f) - 0.055f; + else + return 1.0f; +} + + +static inline GLubyte +linear_float_to_srgb_ubyte(GLfloat cl) +{ + GLubyte res = FLOAT_TO_UBYTE(linear_to_srgb(cl)); + return res; +} + + +static inline GLubyte +linear_ubyte_to_srgb_ubyte(GLubyte cl) +{ + GLubyte res = FLOAT_TO_UBYTE(linear_to_srgb(cl / 255.0f)); + return res; +} + + + + +/* + * MESA_FORMAT_RGBA8888 + */ + +static void +pack_ubyte_RGBA8888(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_RGBA8888(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_RGBA8888(v, dst); +} + +static void +pack_row_ubyte_RGBA8888(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_RGBA8888(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_RGBA8888(v, d + i); + } +} + + + +/* + * MESA_FORMAT_RGBA8888_REV + */ + +static void +pack_ubyte_RGBA8888_REV(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_RGBA8888_REV(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_RGBA8888_REV(v, dst); +} + +static void +pack_row_ubyte_RGBA8888_REV(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_RGBA8888_REV(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_RGBA8888_REV(v, d + i); + } +} + + +/* + * MESA_FORMAT_ARGB8888 + */ + +static void +pack_ubyte_ARGB8888(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_ARGB8888(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_ARGB8888(v, dst); +} + +static void +pack_row_ubyte_ARGB8888(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_ARGB8888(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_ARGB8888(v, d + i); + } +} + + +/* + * MESA_FORMAT_ARGB8888_REV + */ + +static void +pack_ubyte_ARGB8888_REV(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_ARGB8888_REV(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_ARGB8888_REV(v, dst); +} + +static void +pack_row_ubyte_ARGB8888_REV(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_ARGB8888_REV(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_ARGB8888_REV(v, d + i); + } +} + + +/* + * MESA_FORMAT_XRGB8888 + */ + +static void +pack_ubyte_XRGB8888(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_XRGB8888(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_XRGB8888(v, dst); +} + +static void +pack_row_ubyte_XRGB8888(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_XRGB8888(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_XRGB8888(v, d + i); + } +} + + +/* + * MESA_FORMAT_XRGB8888_REV + */ + +static void +pack_ubyte_XRGB8888_REV(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_XRGB8888_REV(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_XRGB8888_REV(v, dst); +} + +static void +pack_row_ubyte_XRGB8888_REV(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_XRGB8888_REV(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_XRGB8888_REV(v, d + i); + } +} + + +/* + * MESA_FORMAT_RGB888 + */ + +static void +pack_ubyte_RGB888(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_RGB888(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_RGB888(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_RGB888(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_BGR888 + */ + +static void +pack_ubyte_BGR888(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_BGR888(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_BGR888(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_BGR888(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_RGB565 + */ + +static void +pack_ubyte_RGB565(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = PACK_COLOR_565(src[RCOMP], src[GCOMP], src[BCOMP]); +} + +static void +pack_float_RGB565(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_RGB565(v, dst); +} + +static void +pack_row_ubyte_RGB565(GLuint n, const GLubyte src[][4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + GLuint i; + for (i = 0; i < n; i++) { + pack_ubyte_RGB565(src[i], d + i); + } +} + +static void +pack_row_float_RGB565(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_RGB565(v, d + i); + } +} + + +/* + * MESA_FORMAT_RGB565_REV + */ + +static void +pack_ubyte_RGB565_REV(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_RGB565_REV(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_RGB565_REV(GLuint n, const GLubyte src[][4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + GLuint i; + for (i = 0; i < n; i++) { + pack_ubyte_RGB565_REV(src[i], d + i); + } +} + +static void +pack_row_float_RGB565_REV(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_RGB565_REV(v, d + i); + } +} + + +/* + * MESA_FORMAT_ARGB4444 + */ + +static void +pack_ubyte_ARGB4444(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_ARGB4444(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_ARGB4444(v, dst); +} + +/* use fallback row packing functions */ + + +/* + * MESA_FORMAT_ARGB4444_REV + */ + +static void +pack_ubyte_ARGB4444_REV(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = PACK_COLOR_4444(src[GCOMP], src[BCOMP], src[ACOMP], src[RCOMP]); +} + +static void +pack_float_ARGB4444_REV(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_ARGB4444_REV(v, dst); +} + +/* use fallback row packing functions */ + + +/* + * MESA_FORMAT_RGBA5551 + */ + +static void +pack_ubyte_RGBA5551(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_RGBA5551(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_RGBA5551(v, dst); +} + +/* use fallback row packing functions */ + + +/* + * MESA_FORMAT_ARGB1555 + */ + +static void +pack_ubyte_ARGB1555(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_ARGB1555(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_ARGB1555(v, dst); +} + + +/* MESA_FORMAT_ARGB1555_REV */ + +static void +pack_ubyte_ARGB1555_REV(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_ARGB1555_REV(const GLfloat src[4], void *dst) +{ + GLubyte v[4]; + _mesa_unclamped_float_rgba_to_ubyte(v, src); + pack_ubyte_ARGB1555_REV(v, dst); +} + + +/* MESA_FORMAT_AL44 */ + +static void +pack_ubyte_AL44(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = PACK_COLOR_44(src[ACOMP], src[RCOMP]); +} + +static void +pack_float_AL44(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_AL44(v, dst); +} + + +/* MESA_FORMAT_AL88 */ + +static void +pack_ubyte_AL88(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = PACK_COLOR_88(src[ACOMP], src[RCOMP]); +} + +static void +pack_float_AL88(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_AL88(v, dst); +} + + +/* MESA_FORMAT_AL88_REV */ + +static void +pack_ubyte_AL88_REV(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = PACK_COLOR_88(src[RCOMP], src[ACOMP]); +} + +static void +pack_float_AL88_REV(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_AL88_REV(v, dst); +} + + +/* MESA_FORMAT_AL1616 */ + +static void +pack_ubyte_AL1616(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_AL1616(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_AL1616_REV */ + +static void +pack_ubyte_AL1616_REV(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_AL1616_REV(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_RGB332 */ + +static void +pack_ubyte_RGB332(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = PACK_COLOR_332(src[RCOMP], src[GCOMP], src[BCOMP]); +} + +static void +pack_float_RGB332(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_RGB332(v, dst); +} + + +/* MESA_FORMAT_A8 */ + +static void +pack_ubyte_A8(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = src[ACOMP]; +} + +static void +pack_float_A8(const GLfloat src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[ACOMP]); +} + + +/* MESA_FORMAT_A16 */ + +static void +pack_ubyte_A16(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = UBYTE_TO_USHORT(src[ACOMP]); +} + +static void +pack_float_A16(const GLfloat src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + UNCLAMPED_FLOAT_TO_USHORT(d[0], src[ACOMP]); +} + + +/* MESA_FORMAT_L8 */ + +static void +pack_ubyte_L8(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = src[RCOMP]; +} + +static void +pack_float_L8(const GLfloat src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + UNCLAMPED_FLOAT_TO_UBYTE(d[0], src[RCOMP]); +} + + +/* MESA_FORMAT_L16 */ + +static void +pack_ubyte_L16(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = UBYTE_TO_USHORT(src[RCOMP]); +} + +static void +pack_float_L16(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_R8 */ + +static void +pack_ubyte_R8(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = src[RCOMP]; +} + +static void +pack_float_R8(const GLfloat src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + GLubyte r; + UNCLAMPED_FLOAT_TO_UBYTE(r, src[RCOMP]); + d[0] = r; +} + + +/* MESA_FORMAT_GR88 */ + +static void +pack_ubyte_GR88(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = PACK_COLOR_88(src[GCOMP], src[RCOMP]); +} + +static void +pack_float_GR88(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_RG88 */ + +static void +pack_ubyte_RG88(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = PACK_COLOR_88(src[RCOMP], src[GCOMP]); +} + +static void +pack_float_RG88(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_R16 */ + +static void +pack_ubyte_R16(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = UBYTE_TO_USHORT(src[RCOMP]); +} + +static void +pack_float_R16(const GLfloat src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + UNCLAMPED_FLOAT_TO_USHORT(d[0], src[RCOMP]); +} + + +/* MESA_FORMAT_RG1616 */ + +static void +pack_ubyte_RG1616(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_RG1616(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_RG1616_REV */ + +static void +pack_ubyte_RG1616_REV(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_RG1616_REV(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_ARGB2101010 */ + +static void +pack_ubyte_ARGB2101010(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_ARGB2101010(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_SRGB8 */ + +static void +pack_ubyte_SRGB8(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + d[2] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + d[1] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + d[0] = linear_ubyte_to_srgb_ubyte(src[RCOMP]); +} + +static void +pack_float_SRGB8(const GLfloat src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + d[2] = linear_float_to_srgb_ubyte(src[RCOMP]); + d[1] = linear_float_to_srgb_ubyte(src[GCOMP]); + d[0] = linear_float_to_srgb_ubyte(src[BCOMP]); +} + + +/* MESA_FORMAT_SRGBA8 */ + +static void +pack_ubyte_SRGBA8(const GLubyte src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + GLubyte g = linear_ubyte_to_srgb_ubyte(src[GCOMP]); + GLubyte b = linear_ubyte_to_srgb_ubyte(src[BCOMP]); + *d = PACK_COLOR_8888(r, g, b, src[ACOMP]); +} + +static void +pack_float_SRGBA8(const GLfloat src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLubyte r, g, b, a; + r = linear_float_to_srgb_ubyte(src[RCOMP]); + g = linear_float_to_srgb_ubyte(src[GCOMP]); + b = linear_float_to_srgb_ubyte(src[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); + *d = PACK_COLOR_8888(r, g, b, a); +} + + +/* MESA_FORMAT_SARGB8 */ + +static void +pack_ubyte_SARGB8(const GLubyte src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLubyte r = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + GLubyte g = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + GLubyte b = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + *d = PACK_COLOR_8888(src[ACOMP], r, g, b); +} + +static void +pack_float_SARGB8(const GLfloat src[4], void *dst) +{ + GLuint *d = ((GLuint *) dst); + GLubyte r, g, b, a; + r = linear_float_to_srgb_ubyte(src[RCOMP]); + g = linear_float_to_srgb_ubyte(src[GCOMP]); + b = linear_float_to_srgb_ubyte(src[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); + *d = PACK_COLOR_8888(a, r, g, b); +} + + +/* MESA_FORMAT_SL8 */ + +static void +pack_ubyte_SL8(const GLubyte src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + *d = linear_ubyte_to_srgb_ubyte(src[RCOMP]); +} + +static void +pack_float_SL8(const GLfloat src[4], void *dst) +{ + GLubyte *d = ((GLubyte *) dst); + GLubyte l = linear_float_to_srgb_ubyte(src[RCOMP]); + *d = l; +} + + +/* MESA_FORMAT_SLA8 */ + +static void +pack_ubyte_SLA8(const GLubyte src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + GLubyte l = linear_ubyte_to_srgb_ubyte(src[RCOMP]); + *d = PACK_COLOR_88(src[ACOMP], l); +} + +static void +pack_float_SLA8(const GLfloat src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + GLubyte a, l = linear_float_to_srgb_ubyte(src[RCOMP]); + CLAMPED_FLOAT_TO_UBYTE(a, src[ACOMP]); + *d = PACK_COLOR_88(a, l); +} + + +/* 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_ALPHA_FLOAT32 */ + +static void +pack_ubyte_ALPHA_FLOAT32(const GLubyte src[4], void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[0] = UBYTE_TO_FLOAT(src[ACOMP]); +} + +static void +pack_float_ALPHA_FLOAT32(const GLfloat src[4], void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[0] = src[ACOMP]; +} + + +/* MESA_FORMAT_ALPHA_FLOAT16 */ + +static void +pack_ubyte_ALPHA_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_ALPHA_FLOAT16(const GLfloat src[4], void *dst) +{ + GLhalfARB *d = ((GLhalfARB *) dst); + d[0] = _mesa_float_to_half(src[ACOMP]); +} + + +/* MESA_FORMAT_LUMINANCE_FLOAT32 (and INTENSITY_FLOAT32, R_FLOAT32) */ + +static void +pack_ubyte_LUMINANCE_FLOAT32(const GLubyte src[4], void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[0] = UBYTE_TO_FLOAT(src[RCOMP]); +} + +static void +pack_float_LUMINANCE_FLOAT32(const GLfloat src[4], void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[0] = src[RCOMP]; +} + + +/* MESA_FORMAT_LUMINANCE_FLOAT16 (and INTENSITY_FLOAT16, R_FLOAT32) */ + +static void +pack_ubyte_LUMINANCE_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_LUMINANCE_FLOAT16(const GLfloat src[4], void *dst) +{ + GLhalfARB *d = ((GLhalfARB *) dst); + d[0] = _mesa_float_to_half(src[RCOMP]); +} + + +/* MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 */ + +static void +pack_ubyte_LUMINANCE_ALPHA_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_LUMINANCE_ALPHA_FLOAT32(const GLfloat src[4], void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + d[0] = src[RCOMP]; + d[1] = src[ACOMP]; +} + + +/* MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 */ + +static void +pack_ubyte_LUMINANCE_ALPHA_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_LUMINANCE_ALPHA_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_DUDV8 */ + +static void +pack_ubyte_DUDV8(const GLubyte src[4], void *dst) +{ + /* XXX is this ever used? */ + GLushort *d = ((GLushort *) dst); + *d = PACK_COLOR_88(src[0], src[1]); +} + +static void +pack_float_DUDV8(const GLfloat src[4], void *dst) +{ + GLushort *d = ((GLushort *) dst); + GLbyte du, dv; + du = FLOAT_TO_BYTE(CLAMP(src[0], 0.0F, 1.0F)); + dv = FLOAT_TO_BYTE(CLAMP(src[1], 0.0F, 1.0F)); + *d = PACK_COLOR_88(du, dv); +} + + +/* MESA_FORMAT_RGBA_16 */ + +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_SIGNED_R8 + */ + +static void +pack_float_SIGNED_R8(const GLfloat src[4], void *dst) +{ + GLbyte *d = (GLbyte *) dst; + *d = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); +} + + +/* + * MESA_FORMAT_SIGNED_RG88_REV + */ + +static void +pack_float_SIGNED_RG88_REV(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_SIGNED_RGBX8888 + */ + +static void +pack_float_SIGNED_RGBX8888(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_SIGNED_RGBA8888 + */ + +static void +pack_float_SIGNED_RGBA8888(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_SIGNED_RGBA8888_REV + */ + +static void +pack_float_SIGNED_RGBA8888_REV(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_SIGNED_R16 + */ + +static void +pack_float_SIGNED_R16(const GLfloat src[4], void *dst) +{ + GLshort *d = (GLshort *) dst; + *d = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); +} + + +/* + * MESA_FORMAT_SIGNED_GR1616 + */ + +static void +pack_float_SIGNED_GR1616(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_SIGNED_RGB_16 + */ + +static void +pack_float_SIGNED_RGB_16(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_SIGNED_RGBA_16 + */ + +static void +pack_float_SIGNED_RGBA_16(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_SIGNED_A8 + */ + +static void +pack_float_SIGNED_A8(const GLfloat src[4], void *dst) +{ + GLbyte *d = (GLbyte *) dst; + *d = FLOAT_TO_BYTE(CLAMP(src[ACOMP], -1.0f, 1.0f)); +} + + +/* + * MESA_FORMAT_SIGNED_L8 + */ + +static void +pack_float_SIGNED_L8(const GLfloat src[4], void *dst) +{ + GLbyte *d = (GLbyte *) dst; + *d = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f)); +} + + +/* + * MESA_FORMAT_SIGNED_AL88 + */ + +static void +pack_float_SIGNED_AL88(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_SIGNED_A16 + */ + +static void +pack_float_SIGNED_A16(const GLfloat src[4], void *dst) +{ + GLshort *d = (GLshort *) dst; + *d = FLOAT_TO_SHORT(CLAMP(src[ACOMP], -1.0f, 1.0f)); +} + + +/* + * MESA_FORMAT_SIGNED_L16 + */ + +static void +pack_float_SIGNED_L16(const GLfloat src[4], void *dst) +{ + GLshort *d = (GLshort *) dst; + *d = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f)); +} + + +/* + * MESA_FORMAT_SIGNED_AL1616 + */ + +static void +pack_float_SIGNED_AL1616(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_RGB9_E5_FLOAT; + */ + +static void +pack_float_RGB9_E5_FLOAT(const GLfloat src[4], void *dst) +{ + GLuint *d = (GLuint *) dst; + *d = float3_to_rgb9e5(src); +} + +static void +pack_ubyte_RGB9_E5_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_R11_G11_B10_FLOAT; + */ + +static void +pack_ubyte_R11_G11_B10_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_R11_G11_B10_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(gl_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_RGBA8888] = pack_ubyte_RGBA8888; + table[MESA_FORMAT_RGBA8888_REV] = pack_ubyte_RGBA8888_REV; + table[MESA_FORMAT_ARGB8888] = pack_ubyte_ARGB8888; + table[MESA_FORMAT_ARGB8888_REV] = pack_ubyte_ARGB8888_REV; + table[MESA_FORMAT_RGBX8888] = pack_ubyte_RGBA8888; /* reused */ + table[MESA_FORMAT_RGBX8888_REV] = pack_ubyte_RGBA8888_REV; /* reused */ + table[MESA_FORMAT_XRGB8888] = pack_ubyte_XRGB8888; + table[MESA_FORMAT_XRGB8888_REV] = pack_ubyte_XRGB8888_REV; + table[MESA_FORMAT_RGB888] = pack_ubyte_RGB888; + table[MESA_FORMAT_BGR888] = pack_ubyte_BGR888; + table[MESA_FORMAT_RGB565] = pack_ubyte_RGB565; + table[MESA_FORMAT_RGB565_REV] = pack_ubyte_RGB565_REV; + table[MESA_FORMAT_ARGB4444] = pack_ubyte_ARGB4444; + table[MESA_FORMAT_ARGB4444_REV] = pack_ubyte_ARGB4444_REV; + table[MESA_FORMAT_RGBA5551] = pack_ubyte_RGBA5551; + table[MESA_FORMAT_ARGB1555] = pack_ubyte_ARGB1555; + table[MESA_FORMAT_ARGB1555_REV] = pack_ubyte_ARGB1555_REV; + table[MESA_FORMAT_AL44] = pack_ubyte_AL44; + table[MESA_FORMAT_AL88] = pack_ubyte_AL88; + table[MESA_FORMAT_AL88_REV] = pack_ubyte_AL88_REV; + table[MESA_FORMAT_AL1616] = pack_ubyte_AL1616; + table[MESA_FORMAT_AL1616_REV] = pack_ubyte_AL1616_REV; + table[MESA_FORMAT_RGB332] = pack_ubyte_RGB332; + table[MESA_FORMAT_A8] = pack_ubyte_A8; + table[MESA_FORMAT_A16] = pack_ubyte_A16; + table[MESA_FORMAT_L8] = pack_ubyte_L8; + table[MESA_FORMAT_L16] = pack_ubyte_L16; + table[MESA_FORMAT_I8] = pack_ubyte_L8; /* reuse pack_ubyte_L8 */ + table[MESA_FORMAT_I16] = pack_ubyte_L16; /* reuse pack_ubyte_L16 */ + table[MESA_FORMAT_YCBCR] = pack_ubyte_YCBCR; + table[MESA_FORMAT_YCBCR_REV] = pack_ubyte_YCBCR_REV; + table[MESA_FORMAT_R8] = pack_ubyte_R8; + table[MESA_FORMAT_GR88] = pack_ubyte_GR88; + table[MESA_FORMAT_RG88] = pack_ubyte_RG88; + table[MESA_FORMAT_R16] = pack_ubyte_R16; + table[MESA_FORMAT_RG1616] = pack_ubyte_RG1616; + table[MESA_FORMAT_RG1616_REV] = pack_ubyte_RG1616_REV; + table[MESA_FORMAT_ARGB2101010] = pack_ubyte_ARGB2101010; + + /* should never convert RGBA to these formats */ + table[MESA_FORMAT_Z24_S8] = NULL; + table[MESA_FORMAT_S8_Z24] = NULL; + table[MESA_FORMAT_Z16] = NULL; + table[MESA_FORMAT_X8_Z24] = NULL; + table[MESA_FORMAT_Z24_X8] = NULL; + table[MESA_FORMAT_Z32] = NULL; + table[MESA_FORMAT_S8] = NULL; + + /* sRGB */ + table[MESA_FORMAT_SRGB8] = pack_ubyte_SRGB8; + table[MESA_FORMAT_SRGBA8] = pack_ubyte_SRGBA8; + table[MESA_FORMAT_SARGB8] = pack_ubyte_SARGB8; + table[MESA_FORMAT_SL8] = pack_ubyte_SL8; + table[MESA_FORMAT_SLA8] = pack_ubyte_SLA8; + + /* 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_ALPHA_FLOAT32] = pack_ubyte_ALPHA_FLOAT32; + table[MESA_FORMAT_ALPHA_FLOAT16] = pack_ubyte_ALPHA_FLOAT16; + table[MESA_FORMAT_LUMINANCE_FLOAT32] = pack_ubyte_LUMINANCE_FLOAT32; + table[MESA_FORMAT_LUMINANCE_FLOAT16] = pack_ubyte_LUMINANCE_FLOAT16; + table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = pack_ubyte_LUMINANCE_ALPHA_FLOAT32; + table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = pack_ubyte_LUMINANCE_ALPHA_FLOAT16; + table[MESA_FORMAT_INTENSITY_FLOAT32] = pack_ubyte_LUMINANCE_FLOAT32; + table[MESA_FORMAT_INTENSITY_FLOAT16] = pack_ubyte_LUMINANCE_FLOAT16; + table[MESA_FORMAT_R_FLOAT32] = pack_ubyte_LUMINANCE_FLOAT32; + table[MESA_FORMAT_R_FLOAT16] = pack_ubyte_LUMINANCE_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_INT8] = NULL; /* pack_ubyte_RGBA_INT8 */ + table[MESA_FORMAT_RGBA_INT16] = NULL; /* pack_ubyte_RGBA_INT16 */ + table[MESA_FORMAT_RGBA_INT32] = 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_DUDV8] = pack_ubyte_DUDV8; + + table[MESA_FORMAT_RGBA_16] = pack_ubyte_RGBA_16; + + /* n/a */ + table[MESA_FORMAT_SIGNED_R8] = NULL; + table[MESA_FORMAT_SIGNED_RG88_REV] = NULL; + table[MESA_FORMAT_SIGNED_RGBX8888] = NULL; + table[MESA_FORMAT_SIGNED_RGBA8888] = NULL; + table[MESA_FORMAT_SIGNED_RGBA8888_REV] = NULL; + table[MESA_FORMAT_SIGNED_R16] = NULL; + table[MESA_FORMAT_SIGNED_GR1616] = NULL; + table[MESA_FORMAT_SIGNED_RGB_16] = NULL; + table[MESA_FORMAT_SIGNED_RGBA_16] = NULL; + table[MESA_FORMAT_SIGNED_A8] = NULL; + table[MESA_FORMAT_SIGNED_L8] = NULL; + table[MESA_FORMAT_SIGNED_AL88] = NULL; + table[MESA_FORMAT_SIGNED_I8] = NULL; + table[MESA_FORMAT_SIGNED_A16] = NULL; + table[MESA_FORMAT_SIGNED_L16] = NULL; + table[MESA_FORMAT_SIGNED_AL1616] = NULL; + table[MESA_FORMAT_SIGNED_I16] = NULL; + + + table[MESA_FORMAT_RGBA_16] = pack_ubyte_RGBA_16; + + table[MESA_FORMAT_RGB9_E5_FLOAT] = pack_ubyte_RGB9_E5_FLOAT; + table[MESA_FORMAT_R11_G11_B10_FLOAT] = pack_ubyte_R11_G11_B10_FLOAT; + + 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(gl_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_RGBA8888] = pack_float_RGBA8888; + table[MESA_FORMAT_RGBA8888_REV] = pack_float_RGBA8888_REV; + table[MESA_FORMAT_ARGB8888] = pack_float_ARGB8888; + table[MESA_FORMAT_ARGB8888_REV] = pack_float_ARGB8888_REV; + table[MESA_FORMAT_RGBX8888] = pack_float_RGBA8888; /* reused */ + table[MESA_FORMAT_RGBX8888_REV] = pack_float_RGBA8888_REV; /* reused */ + table[MESA_FORMAT_XRGB8888] = pack_float_XRGB8888; + table[MESA_FORMAT_XRGB8888_REV] = pack_float_XRGB8888_REV; + table[MESA_FORMAT_RGB888] = pack_float_RGB888; + table[MESA_FORMAT_BGR888] = pack_float_BGR888; + table[MESA_FORMAT_RGB565] = pack_float_RGB565; + table[MESA_FORMAT_RGB565_REV] = pack_float_RGB565_REV; + table[MESA_FORMAT_ARGB4444] = pack_float_ARGB4444; + table[MESA_FORMAT_ARGB4444_REV] = pack_float_ARGB4444_REV; + table[MESA_FORMAT_RGBA5551] = pack_float_RGBA5551; + table[MESA_FORMAT_ARGB1555] = pack_float_ARGB1555; + table[MESA_FORMAT_ARGB1555_REV] = pack_float_ARGB1555_REV; + + table[MESA_FORMAT_AL44] = pack_float_AL44; + table[MESA_FORMAT_AL88] = pack_float_AL88; + table[MESA_FORMAT_AL88_REV] = pack_float_AL88_REV; + table[MESA_FORMAT_AL1616] = pack_float_AL1616; + table[MESA_FORMAT_AL1616_REV] = pack_float_AL1616_REV; + table[MESA_FORMAT_RGB332] = pack_float_RGB332; + table[MESA_FORMAT_A8] = pack_float_A8; + table[MESA_FORMAT_A16] = pack_float_A16; + table[MESA_FORMAT_L8] = pack_float_L8; + table[MESA_FORMAT_L16] = pack_float_L16; + table[MESA_FORMAT_I8] = pack_float_L8; /* reuse pack_float_L8 */ + table[MESA_FORMAT_I16] = pack_float_L16; /* reuse pack_float_L16 */ + table[MESA_FORMAT_YCBCR] = pack_float_YCBCR; + table[MESA_FORMAT_YCBCR_REV] = pack_float_YCBCR_REV; + table[MESA_FORMAT_R8] = pack_float_R8; + table[MESA_FORMAT_GR88] = pack_float_GR88; + table[MESA_FORMAT_RG88] = pack_float_RG88; + table[MESA_FORMAT_R16] = pack_float_R16; + table[MESA_FORMAT_RG1616] = pack_float_RG1616; + table[MESA_FORMAT_RG1616_REV] = pack_float_RG1616_REV; + table[MESA_FORMAT_ARGB2101010] = pack_float_ARGB2101010; + + /* should never convert RGBA to these formats */ + table[MESA_FORMAT_Z24_S8] = NULL; + table[MESA_FORMAT_S8_Z24] = NULL; + table[MESA_FORMAT_Z16] = NULL; + table[MESA_FORMAT_X8_Z24] = NULL; + table[MESA_FORMAT_Z24_X8] = NULL; + table[MESA_FORMAT_Z32] = NULL; + table[MESA_FORMAT_S8] = NULL; + + table[MESA_FORMAT_SRGB8] = pack_float_SRGB8; + table[MESA_FORMAT_SRGBA8] = pack_float_SRGBA8; + table[MESA_FORMAT_SARGB8] = pack_float_SARGB8; + table[MESA_FORMAT_SL8] = pack_float_SL8; + table[MESA_FORMAT_SLA8] = pack_float_SLA8; + + /* 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_ALPHA_FLOAT32] = pack_float_ALPHA_FLOAT32; + table[MESA_FORMAT_ALPHA_FLOAT16] = pack_float_ALPHA_FLOAT16; + table[MESA_FORMAT_LUMINANCE_FLOAT32] = pack_float_LUMINANCE_FLOAT32; + table[MESA_FORMAT_LUMINANCE_FLOAT16] = pack_float_LUMINANCE_FLOAT16; + table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = pack_float_LUMINANCE_ALPHA_FLOAT32; + table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = pack_float_LUMINANCE_ALPHA_FLOAT16; + + table[MESA_FORMAT_INTENSITY_FLOAT32] = pack_float_LUMINANCE_FLOAT32; + table[MESA_FORMAT_INTENSITY_FLOAT16] = pack_float_LUMINANCE_FLOAT16; + table[MESA_FORMAT_R_FLOAT32] = pack_float_LUMINANCE_FLOAT32; + table[MESA_FORMAT_R_FLOAT16] = pack_float_LUMINANCE_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_INT8] = NULL; + table[MESA_FORMAT_RGBA_INT16] = NULL; + table[MESA_FORMAT_RGBA_INT32] = NULL; + table[MESA_FORMAT_RGBA_UINT8] = NULL; + table[MESA_FORMAT_RGBA_UINT16] = NULL; + table[MESA_FORMAT_RGBA_UINT32] = NULL; + + table[MESA_FORMAT_DUDV8] = pack_float_DUDV8; + + table[MESA_FORMAT_RGBA_16] = pack_float_RGBA_16; + + table[MESA_FORMAT_SIGNED_R8] = pack_float_SIGNED_R8; + table[MESA_FORMAT_SIGNED_RG88_REV] = pack_float_SIGNED_RG88_REV; + table[MESA_FORMAT_SIGNED_RGBX8888] = pack_float_SIGNED_RGBX8888; + table[MESA_FORMAT_SIGNED_RGBA8888] = pack_float_SIGNED_RGBA8888; + table[MESA_FORMAT_SIGNED_RGBA8888_REV] = pack_float_SIGNED_RGBA8888_REV; + table[MESA_FORMAT_SIGNED_R16] = pack_float_SIGNED_R16; + table[MESA_FORMAT_SIGNED_GR1616] = pack_float_SIGNED_GR1616; + table[MESA_FORMAT_SIGNED_RGB_16] = pack_float_SIGNED_RGB_16; + table[MESA_FORMAT_SIGNED_RGBA_16] = pack_float_SIGNED_RGBA_16; + table[MESA_FORMAT_SIGNED_A8] = pack_float_SIGNED_A8; + table[MESA_FORMAT_SIGNED_L8] = pack_float_SIGNED_L8; + table[MESA_FORMAT_SIGNED_AL88] = pack_float_SIGNED_AL88; + table[MESA_FORMAT_SIGNED_I8] = pack_float_SIGNED_L8; /* reused */ + table[MESA_FORMAT_SIGNED_A16] = pack_float_SIGNED_A16; + table[MESA_FORMAT_SIGNED_L16] = pack_float_SIGNED_L16; + table[MESA_FORMAT_SIGNED_AL1616] = pack_float_SIGNED_AL1616; + table[MESA_FORMAT_SIGNED_I16] = pack_float_SIGNED_L16; /* reused */ + + table[MESA_FORMAT_RGB9_E5_FLOAT] = pack_float_RGB9_E5_FLOAT; + table[MESA_FORMAT_R11_G11_B10_FLOAT] = pack_float_R11_G11_B10_FLOAT; + + initialized = GL_TRUE; + } + + return table[format]; +} + + + +static pack_float_rgba_row_func +get_pack_float_rgba_row_function(gl_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_RGBA8888] = pack_row_float_RGBA8888; + table[MESA_FORMAT_RGBA8888_REV] = pack_row_float_RGBA8888_REV; + table[MESA_FORMAT_ARGB8888] = pack_row_float_ARGB8888; + table[MESA_FORMAT_ARGB8888_REV] = pack_row_float_ARGB8888_REV; + table[MESA_FORMAT_RGBX8888] = pack_row_float_RGBA8888; /* reused */ + table[MESA_FORMAT_RGBX8888_REV] = pack_row_float_RGBA8888_REV; /* reused */ + table[MESA_FORMAT_XRGB8888] = pack_row_float_XRGB8888; + table[MESA_FORMAT_XRGB8888_REV] = pack_row_float_XRGB8888_REV; + table[MESA_FORMAT_RGB888] = pack_row_float_RGB888; + table[MESA_FORMAT_BGR888] = pack_row_float_BGR888; + table[MESA_FORMAT_RGB565] = pack_row_float_RGB565; + table[MESA_FORMAT_RGB565_REV] = pack_row_float_RGB565_REV; + + initialized = GL_TRUE; + } + + return table[format]; +} + + + +static pack_ubyte_rgba_row_func +get_pack_ubyte_rgba_row_function(gl_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_RGBA8888] = pack_row_ubyte_RGBA8888; + table[MESA_FORMAT_RGBA8888_REV] = pack_row_ubyte_RGBA8888_REV; + table[MESA_FORMAT_ARGB8888] = pack_row_ubyte_ARGB8888; + table[MESA_FORMAT_ARGB8888_REV] = pack_row_ubyte_ARGB8888_REV; + table[MESA_FORMAT_RGBX8888] = pack_row_ubyte_RGBA8888; /* reused */ + table[MESA_FORMAT_RGBX8888_REV] = pack_row_ubyte_RGBA8888_REV; /* reused */ + table[MESA_FORMAT_XRGB8888] = pack_row_ubyte_XRGB8888; + table[MESA_FORMAT_XRGB8888_REV] = pack_row_ubyte_XRGB8888_REV; + table[MESA_FORMAT_RGB888] = pack_row_ubyte_RGB888; + table[MESA_FORMAT_BGR888] = pack_row_ubyte_BGR888; + table[MESA_FORMAT_RGB565] = pack_row_ubyte_RGB565; + table[MESA_FORMAT_RGB565_REV] = pack_row_ubyte_RGB565_REV; + + initialized = GL_TRUE; + } + + return table[format]; +} + + + +/** + * Pack a row of GLfloat rgba[4] values to the destination. + */ +void +_mesa_pack_float_rgba_row(gl_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(gl_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 float Z pixels + **/ + +static void +pack_float_z_Z24_S8(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_z_S8_Z24(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_Z16(const GLfloat *src, void *dst) +{ + GLushort *d = ((GLushort *) dst); + const GLfloat scale = (GLfloat) 0xffff; + *d = (GLushort) (*src * scale); +} + +static void +pack_float_z_Z32(const GLfloat *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = (GLdouble) 0xffffffff; + *d = (GLuint) (*src * scale); +} + +static void +pack_float_z_Z32_FLOAT(const GLfloat *src, void *dst) +{ + GLfloat *d = (GLfloat *) dst; + *d = *src; +} + +gl_pack_float_z_func +_mesa_get_pack_float_z_func(gl_format format) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z24_X8: + return pack_float_z_Z24_S8; + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_X8_Z24: + return pack_float_z_S8_Z24; + case MESA_FORMAT_Z16: + return pack_float_z_Z16; + case MESA_FORMAT_Z32: + return pack_float_z_Z32; + case MESA_FORMAT_Z32_FLOAT: + case MESA_FORMAT_Z32_FLOAT_X24S8: + return pack_float_z_Z32_FLOAT; + 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_z_Z24_S8(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_z_S8_Z24(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_Z16(const GLuint *src, void *dst) +{ + GLushort *d = ((GLushort *) dst); + *d = *src >> 16; +} + +static void +pack_uint_z_Z32(const GLuint *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + *d = *src; +} + +static void +pack_uint_z_Z32_FLOAT(const GLuint *src, void *dst) +{ + GLuint *d = ((GLuint *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + *d = *src * scale; + assert(*d >= 0.0f); + assert(*d <= 1.0f); +} + +static void +pack_uint_z_Z32_FLOAT_X24S8(const GLuint *src, void *dst) +{ + GLfloat *d = ((GLfloat *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + *d = *src * scale; + assert(*d >= 0.0f); + assert(*d <= 1.0f); +} + +gl_pack_uint_z_func +_mesa_get_pack_uint_z_func(gl_format format) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z24_X8: + return pack_uint_z_Z24_S8; + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_X8_Z24: + return pack_uint_z_S8_Z24; + case MESA_FORMAT_Z16: + return pack_uint_z_Z16; + case MESA_FORMAT_Z32: + return pack_uint_z_Z32; + case MESA_FORMAT_Z32_FLOAT: + return pack_uint_z_Z32_FLOAT; + case MESA_FORMAT_Z32_FLOAT_X24S8: + return pack_uint_z_Z32_FLOAT_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(gl_format format) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + return pack_ubyte_stencil_Z24_S8; + case MESA_FORMAT_S8_Z24: + return pack_ubyte_stencil_S8_Z24; + case MESA_FORMAT_S8: + return pack_ubyte_stencil_S8; + case MESA_FORMAT_Z32_FLOAT_X24S8: + 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(gl_format format, GLuint n, + const GLfloat *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z24_X8: + { + /* 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_S8_Z24: + case MESA_FORMAT_X8_Z24: + { + /* 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_Z16: + { + 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_Z32: + { + 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_Z32_FLOAT: + memcpy(dst, src, n * sizeof(GLfloat)); + break; + case MESA_FORMAT_Z32_FLOAT_X24S8: + { + GLfloat *d = ((GLfloat *) dst); + GLuint i; + for (i = 0; i < n; i++) { + d[i * 2] = 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(gl_format format, GLuint n, + const GLuint *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z24_X8: + { + /* 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_S8_Z24: + case MESA_FORMAT_X8_Z24: + { + /* 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_Z16: + { + GLushort *d = ((GLushort *) dst); + GLuint i; + for (i = 0; i < n; i++) { + d[i] = src[i] >> 16; + } + } + break; + case MESA_FORMAT_Z32: + memcpy(dst, src, n * sizeof(GLfloat)); + break; + case MESA_FORMAT_Z32_FLOAT: + { + GLuint *d = ((GLuint *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i] = src[i] * scale; + assert(d[i] >= 0.0f); + assert(d[i] <= 1.0f); + } + } + break; + case MESA_FORMAT_Z32_FLOAT_X24S8: + { + GLfloat *d = ((GLfloat *) dst); + const GLdouble scale = 1.0 / (GLdouble) 0xffffffff; + GLuint i; + for (i = 0; i < n; i++) { + d[i * 2] = src[i] * scale; + assert(d[i * 2] >= 0.0f); + assert(d[i * 2] <= 1.0f); + } + } + break; + default: + _mesa_problem(NULL, "unexpected format in _mesa_pack_uint_z_row()"); + } +} + + +void +_mesa_pack_ubyte_stencil_row(gl_format format, GLuint n, + const GLubyte *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + { + /* 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_S8_Z24: + { + /* 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_S8: + memcpy(dst, src, n * sizeof(GLubyte)); + break; + case MESA_FORMAT_Z32_FLOAT_X24S8: + { + GLfloat *d = ((GLfloat *) dst); + GLuint i; + for (i = 0; i < n; i++) { + d[i * 2 + 1] = 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(gl_format format, GLuint n, + const GLuint *src, void *dst) +{ + switch (format) { + case MESA_FORMAT_Z24_S8: + memcpy(dst, src, n * sizeof(GLuint)); + break; + case MESA_FORMAT_S8_Z24: + { + 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; + default: + _mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row", + _mesa_get_format_name(format)); + return; + } +} diff --git a/mesalib/src/mesa/main/format_pack.h b/mesalib/src/mesa/main/format_pack.h new file mode 100644 index 000000000..7df135632 --- /dev/null +++ b/mesalib/src/mesa/main/format_pack.h @@ -0,0 +1,98 @@ +/* + * 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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef FORMAT_PACK_H +#define FORMAT_PACK_H + + +#include "formats.h" + + +/** Pack a GLubyte rgba[4] color to dest address */ +typedef void (*gl_pack_ubyte_rgba_func)(const GLubyte src[4], void *dst); + +/** Pack a GLfloat rgba[4] color to dest address */ +typedef void (*gl_pack_float_rgba_func)(const GLfloat src[4], void *dst); + +/** Pack a GLfloat Z value to dest address */ +typedef void (*gl_pack_float_z_func)(const GLfloat *src, void *dst); + +/** Pack a GLuint Z value to dest address */ +typedef void (*gl_pack_uint_z_func)(const GLuint *src, void *dst); + +/** Pack a GLubyte stencil value to dest address */ +typedef void (*gl_pack_ubyte_stencil_func)(const GLubyte *src, void *dst); + + + + +extern gl_pack_ubyte_rgba_func +_mesa_get_pack_ubyte_rgba_function(gl_format format); + + +extern gl_pack_float_rgba_func +_mesa_get_pack_float_rgba_function(gl_format format); + + +extern gl_pack_float_z_func +_mesa_get_pack_float_z_func(gl_format format); + + +extern gl_pack_uint_z_func +_mesa_get_pack_uint_z_func(gl_format format); + + +extern gl_pack_ubyte_stencil_func +_mesa_get_pack_ubyte_stencil_func(gl_format format); + + + +extern void +_mesa_pack_float_rgba_row(gl_format format, GLuint n, + const GLfloat src[][4], void *dst); + +extern void +_mesa_pack_ubyte_rgba_row(gl_format format, GLuint n, + const GLubyte src[][4], void *dst); + + + +extern void +_mesa_pack_float_z_row(gl_format format, GLuint n, + const GLfloat *src, void *dst); + +extern void +_mesa_pack_uint_z_row(gl_format format, GLuint n, + const GLuint *src, void *dst); + +extern void +_mesa_pack_ubyte_stencil_row(gl_format format, GLuint n, + const GLubyte *src, void *dst); + +extern void +_mesa_pack_uint_24_8_depth_stencil_row(gl_format format, GLuint n, + const GLuint *src, void *dst); + + +#endif diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index f821c2be4..4f23f3dec 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -587,7 +587,7 @@ unpack_Z24_S8(const void *src, GLfloat dst[][4], GLuint n) { /* only return Z, not stencil data */ const GLuint *s = ((const GLuint *) src); - const GLfloat scale = 1.0F / (GLfloat) 0xffffff; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; GLuint i; for (i = 0; i < n; i++) { dst[i][0] = @@ -604,7 +604,7 @@ unpack_S8_Z24(const void *src, GLfloat dst[][4], GLuint n) { /* only return Z, not stencil data */ const GLuint *s = ((const GLuint *) src); - const GLfloat scale = 1.0F / (GLfloat) 0xffffff; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; GLuint i; for (i = 0; i < n; i++) { dst[i][0] = @@ -1761,7 +1761,7 @@ unpack_float_z_Z24_X8(GLuint n, const void *src, GLfloat *dst) { /* only return Z, not stencil data */ const GLuint *s = ((const GLuint *) src); - const GLfloat scale = 1.0F / (GLfloat) 0xffffff; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; GLuint i; for (i = 0; i < n; i++) { dst[i] = (s[i] >> 8) * scale; @@ -1775,7 +1775,7 @@ unpack_float_z_X8_Z24(GLuint n, const void *src, GLfloat *dst) { /* only return Z, not stencil data */ const GLuint *s = ((const GLuint *) src); - const GLfloat scale = 1.0F / (GLfloat) 0xffffff; + const GLdouble scale = 1.0 / (GLdouble) 0xffffff; GLuint i; for (i = 0; i < n; i++) { dst[i] = (s[i] & 0x00ffffff) * scale; diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index 595da773b..1f83a5368 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -1553,6 +1553,8 @@ _mesa_get_format_bytes(gl_format format) { const struct gl_format_info *info = _mesa_get_format_info(format); ASSERT(info->BytesPerBlock); + ASSERT(info->BytesPerBlock <= MAX_PIXEL_BYTES || + _mesa_is_format_compressed(format)); return info->BytesPerBlock; } diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h index 3960f028e..e6b429d5f 100644 --- a/mesalib/src/mesa/main/formats.h +++ b/mesalib/src/mesa/main/formats.h @@ -46,6 +46,14 @@ extern "C" { #define MESA_UNSIGNED_BYTE_4_4 (GL_UNSIGNED_BYTE<<1) +/** + * Max number of bytes for any non-compressed pixel format below, or for + * intermediate pixel storage in Mesa. This should never be less than + * 16. Maybe 32 someday? + */ +#define MAX_PIXEL_BYTES 16 + + /** * Mesa texture/renderbuffer image formats. */ diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c index 8d0763db3..e30f31a39 100644 --- a/mesalib/src/mesa/main/framebuffer.c +++ b/mesalib/src/mesa/main/framebuffer.c @@ -879,6 +879,7 @@ renderbuffer_exists(struct gl_context *ctx, case GL_BGRA: case GL_ABGR_EXT: case GL_RED_INTEGER_EXT: + case GL_RG_INTEGER: case GL_GREEN_INTEGER_EXT: case GL_BLUE_INTEGER_EXT: case GL_ALPHA_INTEGER_EXT: diff --git a/mesalib/src/mesa/main/image.c b/mesalib/src/mesa/main/image.c index b266e26c6..b37cd7e7d 100644 --- a/mesalib/src/mesa/main/image.c +++ b/mesalib/src/mesa/main/image.c @@ -238,6 +238,7 @@ _mesa_components_in_format( GLenum format ) case GL_DEPTH_STENCIL_EXT: case GL_DUDV_ATI: case GL_DU8DV8_ATI: + case GL_RG_INTEGER: return 2; case GL_RGB: @@ -527,6 +528,7 @@ _mesa_is_legal_format_and_type(const struct gl_context *ctx, case GL_GREEN_INTEGER_EXT: case GL_BLUE_INTEGER_EXT: case GL_ALPHA_INTEGER_EXT: + case GL_RG_INTEGER: switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: @@ -751,6 +753,7 @@ _mesa_is_color_format(GLenum format) case GL_RGBA_INTEGER_EXT: case GL_BGR_INTEGER_EXT: case GL_BGRA_INTEGER_EXT: + case GL_RG_INTEGER: case GL_LUMINANCE_INTEGER_EXT: case GL_LUMINANCE_ALPHA_INTEGER_EXT: /* sized integer formats */ @@ -954,6 +957,7 @@ _mesa_is_integer_format(GLenum format) case GL_BGRA_INTEGER_EXT: case GL_LUMINANCE_INTEGER_EXT: case GL_LUMINANCE_ALPHA_INTEGER_EXT: + case GL_RG_INTEGER: /* specific integer formats */ case GL_RGBA32UI_EXT: case GL_RGB32UI_EXT: @@ -1160,32 +1164,30 @@ _mesa_base_format_has_channel(GLenum base_format, GLenum pname) /** - * Return the address of a specific pixel in an image (1D, 2D or 3D). + * Return the byte offset of a specific pixel in an image (1D, 2D or 3D). * * Pixel unpacking/packing parameters are observed according to \p packing. * * \param dimensions either 1, 2 or 3 to indicate dimensionality of image - * \param image starting address of image data - * \param width the image width - * \param height theimage height - * \param format the pixel format - * \param type the pixel data type * \param packing the pixelstore attributes + * \param width the image width + * \param height the image height + * \param format the pixel format (must be validated beforehand) + * \param type the pixel data type (must be validated beforehand) * \param img which image in the volume (0 for 1D or 2D images) * \param row row of pixel in the image (0 for 1D images) * \param column column of pixel in the image - * - * \return address of pixel on success, or NULL on error. + * + * \return offset of pixel. * * \sa gl_pixelstore_attrib. */ -GLvoid * -_mesa_image_address( GLuint dimensions, - const struct gl_pixelstore_attrib *packing, - const GLvoid *image, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLint img, GLint row, GLint column ) +GLintptr +_mesa_image_offset( GLuint dimensions, + const struct gl_pixelstore_attrib *packing, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLint img, GLint row, GLint column ) { GLint alignment; /* 1, 2 or 4 */ GLint pixels_per_row; @@ -1193,7 +1195,7 @@ _mesa_image_address( GLuint dimensions, GLint skiprows; GLint skippixels; GLint skipimages; /* for 3-D volume images */ - GLubyte *pixel_addr; + GLintptr offset; ASSERT(dimensions >= 1 && dimensions <= 3); @@ -1219,30 +1221,20 @@ _mesa_image_address( GLuint dimensions, if (type == GL_BITMAP) { /* BITMAP data */ - GLint comp_per_pixel; /* components per pixel */ - GLint bytes_per_comp; /* bytes per component */ GLint bytes_per_row; GLint bytes_per_image; + /* components per pixel for color or stencil index: */ + const GLint comp_per_pixel = 1; - /* Compute bytes per component */ - bytes_per_comp = _mesa_sizeof_packed_type( type ); - if (bytes_per_comp < 0) { - return NULL; - } - - /* Compute number of components per pixel */ - comp_per_pixel = _mesa_components_in_format( format ); - if (comp_per_pixel < 0) { - return NULL; - } + /* The pixel type and format should have been error checked earlier */ + assert(format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX); bytes_per_row = alignment * CEILING( comp_per_pixel*pixels_per_row, 8*alignment ); bytes_per_image = bytes_per_row * rows_per_image; - pixel_addr = (GLubyte *) image - + (skipimages + img) * bytes_per_image + offset = (skipimages + img) * bytes_per_image + (skiprows + row) * bytes_per_row + (skippixels + column) / 8; } @@ -1275,14 +1267,50 @@ _mesa_image_address( GLuint dimensions, } /* compute final pixel address */ - pixel_addr = (GLubyte *) image - + (skipimages + img) * bytes_per_image + offset = (skipimages + img) * bytes_per_image + topOfImage + (skiprows + row) * bytes_per_row + (skippixels + column) * bytes_per_pixel; } - return (GLvoid *) pixel_addr; + return offset; +} + + +/** + * Return the address of a specific pixel in an image (1D, 2D or 3D). + * + * Pixel unpacking/packing parameters are observed according to \p packing. + * + * \param dimensions either 1, 2 or 3 to indicate dimensionality of image + * \param packing the pixelstore attributes + * \param image starting address of image data + * \param width the image width + * \param height the image height + * \param format the pixel format (must be validated beforehand) + * \param type the pixel data type (must be validated beforehand) + * \param img which image in the volume (0 for 1D or 2D images) + * \param row row of pixel in the image (0 for 1D images) + * \param column column of pixel in the image + * + * \return address of pixel. + * + * \sa gl_pixelstore_attrib. + */ +GLvoid * +_mesa_image_address( GLuint dimensions, + const struct gl_pixelstore_attrib *packing, + const GLvoid *image, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLint img, GLint row, GLint column ) +{ + const GLubyte *addr = (const GLubyte *) image; + + addr += _mesa_image_offset(dimensions, packing, width, height, + format, type, img, row, column); + + return (GLvoid *) addr; } @@ -1520,9 +1548,13 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, GLenum dstType, GLvoid *dst, GLuint count, const GLubyte mask[]) { - GLuint tempBuffer[MAX_WIDTH][4]; + GLuint *tempBuffer; const GLboolean useTemp = (src == dst); + tempBuffer = malloc(count * MAX_PIXEL_BYTES); + if (!tempBuffer) + return; + ASSERT(srcType != dstType); switch (srcType) { @@ -1624,6 +1656,8 @@ _mesa_convert_colors(GLenum srcType, const GLvoid *src, default: _mesa_problem(NULL, "Invalid datatype in _mesa_convert_colors"); } + + free(tempBuffer); } diff --git a/mesalib/src/mesa/main/image.h b/mesalib/src/mesa/main/image.h index b606545b7..e4961ed3d 100644 --- a/mesalib/src/mesa/main/image.h +++ b/mesalib/src/mesa/main/image.h @@ -87,6 +87,13 @@ _mesa_is_compressed_format(struct gl_context *ctx, GLenum format); extern GLboolean _mesa_base_format_has_channel(GLenum base_format, GLenum pname); +extern GLintptr +_mesa_image_offset( GLuint dimensions, + const struct gl_pixelstore_attrib *packing, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLint img, GLint row, GLint column ); + extern GLvoid * _mesa_image_address( GLuint dimensions, const struct gl_pixelstore_attrib *packing, diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index 0bd4ff199..2933ff638 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -467,6 +467,7 @@ _mesa_pack_rgba_span_int(struct gl_context *ctx, GLuint n, GLuint rgba[][4], case GL_GREEN_INTEGER_EXT: case GL_BLUE_INTEGER_EXT: case GL_ALPHA_INTEGER_EXT: + case GL_RG_INTEGER: case GL_RGB_INTEGER_EXT: case GL_RGBA_INTEGER_EXT: case GL_BGR_INTEGER_EXT: @@ -490,6 +491,7 @@ _mesa_pack_rgba_span_int(struct gl_context *ctx, GLuint n, GLuint rgba[][4], case GL_GREEN_INTEGER_EXT: case GL_BLUE_INTEGER_EXT: case GL_ALPHA_INTEGER_EXT: + case GL_RG_INTEGER: case GL_RGB_INTEGER_EXT: case GL_RGBA_INTEGER_EXT: case GL_BGR_INTEGER_EXT: @@ -3021,6 +3023,7 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4], srcFormat == GL_DU8DV8_ATI || srcFormat == GL_DUDV_ATI || srcFormat == GL_RED_INTEGER_EXT || + srcFormat == GL_RG_INTEGER || srcFormat == GL_GREEN_INTEGER_EXT || srcFormat == GL_BLUE_INTEGER_EXT || srcFormat == GL_ALPHA_INTEGER_EXT || @@ -3980,6 +3983,7 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx, 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 || diff --git a/mesalib/src/mesa/main/pbo.c b/mesalib/src/mesa/main/pbo.c index 41ff2ff44..d8fa9191d 100644 --- a/mesalib/src/mesa/main/pbo.c +++ b/mesalib/src/mesa/main/pbo.c @@ -68,8 +68,8 @@ _mesa_validate_pbo_access(GLuint dimensions, GLenum format, GLenum type, GLsizei clientMemSize, const GLvoid *ptr) { - const GLvoid *start, *end, *offset; - const GLubyte *sizeAddr; /* buffer size, cast to a pointer */ + /* unsigned, to detect overflow/wrap-around */ + uintptr_t start, end, offset, size; /* If no PBO is bound, 'ptr' is a pointer to client memory containing 'clientMemSize' bytes. @@ -78,10 +78,10 @@ _mesa_validate_pbo_access(GLuint dimensions, */ if (!_mesa_is_bufferobj(pack->BufferObj)) { offset = 0; - sizeAddr = ((const GLubyte *) 0) + clientMemSize; + size = clientMemSize; } else { - offset = ptr; - sizeAddr = ((const GLubyte *) 0) + pack->BufferObj->Size; + offset = (uintptr_t)ptr; + size = pack->BufferObj->Size; /* The ARB_pixel_buffer_object spec says: * "INVALID_OPERATION is generated by ColorTable, ColorSubTable, * ConvolutionFilter2D, ConvolutionFilter1D, SeparableFilter2D, @@ -93,27 +93,30 @@ _mesa_validate_pbo_access(GLuint dimensions, * parameter." */ if (type != GL_BITMAP && - ((GLintptr)offset % _mesa_sizeof_packed_type(type))) + (offset % _mesa_sizeof_packed_type(type))) return GL_FALSE; } - if (sizeAddr == 0) + if (size == 0) /* no buffer! */ return GL_FALSE; /* get the offset to the first pixel we'll read/write */ - start = _mesa_image_address(dimensions, pack, offset, width, height, - format, type, 0, 0, 0); + start = _mesa_image_offset(dimensions, pack, width, height, + format, type, 0, 0, 0); /* get the offset to just past the last pixel we'll read/write */ - end = _mesa_image_address(dimensions, pack, offset, width, height, - format, type, depth-1, height-1, width); + end = _mesa_image_offset(dimensions, pack, width, height, + format, type, depth-1, height-1, width); - if ((const GLubyte *) start > sizeAddr) { + start += offset; + end += offset; + + if (start > size) { /* This will catch negative values / wrap-around */ return GL_FALSE; } - if ((const GLubyte *) end > sizeAddr) { + if (end > size) { /* Image read/write goes beyond end of buffer */ return GL_FALSE; } diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index a7b7ed7f2..38b9c64ed 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -252,10 +252,7 @@ slow_read_rgba_pixels( struct gl_context *ctx, { struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; const gl_format rbFormat = _mesa_get_srgb_format_linear(rb->Format); - union { - float f[MAX_WIDTH][4]; - unsigned int i[MAX_WIDTH][4]; - } rgba; + void *rgba; GLubyte *dst, *map; int dstStride, stride, j; @@ -270,19 +267,27 @@ slow_read_rgba_pixels( struct gl_context *ctx, return; } + rgba = malloc(width * MAX_PIXEL_BYTES); + if (!rgba) + goto done; + for (j = 0; j < height; j++) { if (_mesa_is_integer_format(format)) { - _mesa_unpack_int_rgba_row(rbFormat, width, map, rgba.i); - _mesa_pack_rgba_span_int(ctx, width, rgba.i, format, type, dst); + _mesa_unpack_int_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba); + _mesa_pack_rgba_span_int(ctx, width, (GLuint (*)[4]) rgba, format, + type, dst); } else { - _mesa_unpack_rgba_row(rbFormat, width, map, rgba.f); - _mesa_pack_rgba_span_float(ctx, width, rgba.f, format, type, dst, - packing, transferOps); + _mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba); + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, + type, dst, packing, transferOps); } dst += dstStride; map += stride; } + free(rgba); + +done: ctx->Driver.UnmapRenderbuffer(ctx, rb); } diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c index 24060e695..d82b19ad5 100644 --- a/mesalib/src/mesa/main/renderbuffer.c +++ b/mesalib/src/mesa/main/renderbuffer.c @@ -23,1719 +23,13 @@ */ -/** - * Functions for allocating/managing renderbuffers. - * Also, routines for reading/writing software-based renderbuffer data as - * ubytes, ushorts, uints, etc. - * - * Down the road we'll use this for run-time support of 8, 16 and 32-bit - * color channels. For example, Mesa may use 32-bit/float color channels - * internally (swrast) and use wrapper renderbuffers to convert 32-bit - * values down to 16 or 8-bit values for whatever kind of framebuffer we have. - */ - - -#include "glheader.h" -#include "imports.h" -#include "context.h" -#include "fbobject.h" -#include "formats.h" -#include "mtypes.h" -#include "renderbuffer.h" - - -/* - * Routines for get/put values in common buffer formats follow. - */ - -/* Returns a bytes per pixel of the DataType in the get/put span - * functions for at least a subset of the available combinations a - * renderbuffer can have. - * - * It would be nice to see gl_renderbuffer start talking about a - * gl_format instead of a GLenum DataType. - */ -static int -get_datatype_bytes(struct gl_renderbuffer *rb) -{ - int component_size; - - switch (rb->DataType) { - case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: - component_size = 8; - break; - case GL_FLOAT: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_24_8_EXT: - component_size = 4; - break; - case GL_UNSIGNED_SHORT: - component_size = 2; - break; - case GL_UNSIGNED_BYTE: - component_size = 1; - break; - default: - component_size = 1; - assert(0); - } - - switch (rb->_BaseFormat) { - case GL_DEPTH_COMPONENT: - case GL_DEPTH_STENCIL: - return component_size; - default: - return 4 * component_size; - } -} - -/* This is commonly used by most of the accessors. */ -static void * -get_pointer_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLint x, GLint y) -{ - if (!rb->Data) - return NULL; - - return ((char *) rb->Data + - (y * rb->RowStride + x) * _mesa_get_format_bytes(rb->Format)); -} - -/* GetRow() implementation for formats where DataType matches the rb->Format. - */ -static void -get_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, void *values) -{ - void *src = rb->GetPointer(ctx, rb, x, y); - memcpy(values, src, count * _mesa_get_format_bytes(rb->Format)); -} - -/* Only used for float textures currently, but might also be used for - * RGBA8888, RGBA16, etc. - */ -static void -get_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], void *values) -{ - int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); - GLuint i; - - for (i = 0; i < count; i++) { - const void *src = rb->GetPointer(ctx, rb, x[i], y[i]); - char *dst = (char *) values + i * format_bytes; - memcpy(dst, src, format_bytes); - } -} - -/* For the GL_RED/GL_RG/GL_RGB format/DataType combinations (and - * GL_LUMINANCE/GL_INTENSITY?), the Put functions are a matter of - * storing those initial components of the value per pixel into the - * destination. - */ -static void -put_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - const void *values, const GLubyte *mask) -{ - void *row = rb->GetPointer(ctx, rb, x, y); - int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); - int datatype_bytes = get_datatype_bytes(rb); - unsigned int i; - - if (mask) { - for (i = 0; i < count; i++) { - char *dst = (char *) row + i * format_bytes; - const char *src = (const char *) values + i * datatype_bytes; - - if (mask[i]) { - memcpy(dst, src, format_bytes); - } - } - } - else { - for (i = 0; i < count; i++) { - char *dst = (char *) row + i * format_bytes; - const char *src = (const char *) values + i * datatype_bytes; - memcpy(dst, src, format_bytes); - } - } -} - -static void -put_mono_row_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - const void *value, const GLubyte *mask) -{ - void *row = rb->GetPointer(ctx, rb, x, y); - int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); - unsigned int i; - - if (mask) { - for (i = 0; i < count; i++) { - char *dst = (char *) row + i * format_bytes; - if (mask[i]) { - memcpy(dst, value, format_bytes); - } - } - } - else { - for (i = 0; i < count; i++) { - char *dst = (char *) row + i * format_bytes; - memcpy(dst, value, format_bytes); - } - } -} - - -static void -put_values_generic(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *values, const GLubyte *mask) -{ - int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); - int datatype_bytes = get_datatype_bytes(rb); - unsigned int i; - - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); - const char *src = (const char *) values + i * datatype_bytes; - memcpy(dst, src, format_bytes); - } - } -} - - -static void -put_mono_values_generic(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - int format_bytes = _mesa_get_format_bytes(rb->Format) / sizeof(GLfloat); - unsigned int i; - - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - void *dst = rb->GetPointer(ctx, rb, x[i], y[i]); - memcpy(dst, value, format_bytes); - } - } -} - -/********************************************************************** - * Functions for buffers of 1 X GLubyte values. - * Typically stencil. - */ - -static void -get_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLubyte *dst = (GLubyte *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; - dst[i] = *src; - } -} - - -static void -put_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - const GLubyte *src = (const GLubyte *) values; - GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = src[i]; - } - } - } - else { - memcpy(dst, values, count * sizeof(GLubyte)); - } -} - - -static void -put_mono_row_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask) -{ - const GLubyte val = *((const GLubyte *) value); - GLubyte *dst = (GLubyte *) rb->Data + y * rb->RowStride + x; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = val; - } - } - } - else { - GLuint i; - for (i = 0; i < count; i++) { - dst[i] = val; - } - } -} - - -static void -put_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], - const void *values, const GLubyte *mask) -{ - const GLubyte *src = (const GLubyte *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = src[i]; - } - } -} - - -static void -put_mono_values_ubyte(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - const GLubyte val = *((const GLubyte *) value); - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = val; - } - } -} - - -/********************************************************************** - * Functions for buffers of 1 X GLushort values. - * Typically depth/Z. - */ - -static void -get_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLushort *dst = (GLushort *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT); - for (i = 0; i < count; i++) { - const GLushort *src = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; - dst[i] = *src; - } -} - - -static void -put_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - const GLushort *src = (const GLushort *) values; - GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = src[i]; - } - } - } - else { - memcpy(dst, src, count * sizeof(GLushort)); - } -} - - -static void -put_mono_row_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask) -{ - const GLushort val = *((const GLushort *) value); - GLushort *dst = (GLushort *) rb->Data + y * rb->RowStride + x; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = val; - } - } - } - else { - GLuint i; - for (i = 0; i < count; i++) { - dst[i] = val; - } - } -} - - -static void -put_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *values, - const GLubyte *mask) -{ - const GLushort *src = (const GLushort *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = src[i]; - } - } -} - - -static void -put_mono_values_ushort(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - const GLushort val = *((const GLushort *) value); - ASSERT(rb->DataType == GL_UNSIGNED_SHORT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = val; - } - } - } - else { - GLuint i; - for (i = 0; i < count; i++) { - GLushort *dst = (GLushort *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = val; - } - } -} - - -/********************************************************************** - * Functions for buffers of 1 X GLuint values. - * Typically depth/Z or color index. - */ - -static void -get_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLuint *dst = (GLuint *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_INT || - rb->DataType == GL_UNSIGNED_INT_24_8_EXT); - for (i = 0; i < count; i++) { - const GLuint *src = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; - dst[i] = *src; - } -} - - -static void -put_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - const GLuint *src = (const GLuint *) values; - GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; - ASSERT(rb->DataType == GL_UNSIGNED_INT || - rb->DataType == GL_UNSIGNED_INT_24_8_EXT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = src[i]; - } - } - } - else { - memcpy(dst, src, count * sizeof(GLuint)); - } -} - - -static void -put_mono_row_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask) -{ - const GLuint val = *((const GLuint *) value); - GLuint *dst = (GLuint *) rb->Data + y * rb->RowStride + x; - ASSERT(rb->DataType == GL_UNSIGNED_INT || - rb->DataType == GL_UNSIGNED_INT_24_8_EXT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = val; - } - } - } - else { - GLuint i; - for (i = 0; i < count; i++) { - dst[i] = val; - } - } -} - - -static void -put_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *values, - const GLubyte *mask) -{ - const GLuint *src = (const GLuint *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_INT || - rb->DataType == GL_UNSIGNED_INT_24_8_EXT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = src[i]; - } - } -} - - -static void -put_mono_values_uint(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *value, - const GLubyte *mask) -{ - const GLuint val = *((const GLuint *) value); - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_INT || - rb->DataType == GL_UNSIGNED_INT_24_8_EXT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLuint *dst = (GLuint *) rb->Data + y[i] * rb->RowStride + x[i]; - *dst = val; - } - } -} - - -/********************************************************************** - * Functions for buffers of 3 X GLubyte (or GLbyte) values. - * Typically color buffers. - * NOTE: the incoming and outgoing colors are RGBA! We ignore incoming - * alpha values and return 255 for outgoing alpha values. - */ - -static void * -get_pointer_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLint x, GLint y) -{ - ASSERT(rb->Format == MESA_FORMAT_RGB888); - /* No direct access since this buffer is RGB but caller will be - * treating it as if it were RGBA. - */ - return NULL; -} - - -static void -get_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values) -{ - const GLubyte *src = ((const GLubyte *) rb->Data) + - 3 * (y * rb->RowStride + x); - GLubyte *dst = (GLubyte *) values; - GLuint i; - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - dst[i * 4 + 0] = src[i * 3 + 0]; - dst[i * 4 + 1] = src[i * 3 + 1]; - dst[i * 4 + 2] = src[i * 3 + 2]; - dst[i * 4 + 3] = 255; - } -} - - -static void -get_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLubyte *dst = (GLubyte *) values; - GLuint i; - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - const GLubyte *src - = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); - dst[i * 4 + 0] = src[0]; - dst[i * 4 + 1] = src[1]; - dst[i * 4 + 2] = src[2]; - dst[i * 4 + 3] = 255; - } -} - - -static void -put_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - /* note: incoming values are RGB+A! */ - const GLubyte *src = (const GLubyte *) values; - GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); - GLuint i; - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst[i * 3 + 0] = src[i * 4 + 0]; - dst[i * 3 + 1] = src[i * 4 + 1]; - dst[i * 3 + 2] = src[i * 4 + 2]; - } - } -} - - -static void -put_row_rgb_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - /* note: incoming values are RGB+A! */ - const GLubyte *src = (const GLubyte *) values; - GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); - GLuint i; - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst[i * 3 + 0] = src[i * 3 + 0]; - dst[i * 3 + 1] = src[i * 3 + 1]; - dst[i * 3 + 2] = src[i * 3 + 2]; - } - } -} - - -static void -put_mono_row_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask) -{ - /* note: incoming value is RGB+A! */ - const GLubyte val0 = ((const GLubyte *) value)[0]; - const GLubyte val1 = ((const GLubyte *) value)[1]; - const GLubyte val2 = ((const GLubyte *) value)[2]; - GLubyte *dst = (GLubyte *) rb->Data + 3 * (y * rb->RowStride + x); - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - if (!mask && val0 == val1 && val1 == val2) { - /* optimized case */ - memset(dst, val0, 3 * count); - } - else { - GLuint i; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst[i * 3 + 0] = val0; - dst[i * 3 + 1] = val1; - dst[i * 3 + 2] = val2; - } - } - } -} - - -static void -put_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *values, - const GLubyte *mask) -{ - /* note: incoming values are RGB+A! */ - const GLubyte *src = (const GLubyte *) values; - GLuint i; - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->RowStride + x[i]); - dst[0] = src[i * 4 + 0]; - dst[1] = src[i * 4 + 1]; - dst[2] = src[i * 4 + 2]; - } - } -} - - -static void -put_mono_values_ubyte3(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - /* note: incoming value is RGB+A! */ - const GLubyte val0 = ((const GLubyte *) value)[0]; - const GLubyte val1 = ((const GLubyte *) value)[1]; - const GLubyte val2 = ((const GLubyte *) value)[2]; - GLuint i; - ASSERT(rb->Format == MESA_FORMAT_RGB888); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLubyte *dst = ((GLubyte *) rb->Data) + - 3 * (y[i] * rb->RowStride + x[i]); - dst[0] = val0; - dst[1] = val1; - dst[2] = val2; - } - } -} - - -/********************************************************************** - * Functions for buffers of 4 X GLubyte (or GLbyte) values. - * Typically color buffers. - */ - -static void -get_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - /* treat 4*GLubyte as 1*GLuint */ - GLuint *dst = (GLuint *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || - rb->Format == MESA_FORMAT_RGBA8888_REV); - for (i = 0; i < count; i++) { - const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); - dst[i] = *src; - } -} - - -static void -put_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - /* treat 4*GLubyte as 1*GLuint */ - const GLuint *src = (const GLuint *) values; - GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || - rb->Format == MESA_FORMAT_RGBA8888_REV); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = src[i]; - } - } - } - else { - memcpy(dst, src, 4 * count * sizeof(GLubyte)); - } -} - - -static void -put_row_rgb_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - /* Store RGB values in RGBA buffer */ - const GLubyte *src = (const GLubyte *) values; - GLubyte *dst = (GLubyte *) rb->Data + 4 * (y * rb->RowStride + x); - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || - rb->Format == MESA_FORMAT_RGBA8888_REV); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst[i * 4 + 0] = src[i * 3 + 0]; - dst[i * 4 + 1] = src[i * 3 + 1]; - dst[i * 4 + 2] = src[i * 3 + 2]; - dst[i * 4 + 3] = 0xff; - } - } -} - - -static void -put_mono_row_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask) -{ - /* treat 4*GLubyte as 1*GLuint */ - const GLuint val = *((const GLuint *) value); - GLuint *dst = (GLuint *) rb->Data + (y * rb->RowStride + x); - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || - rb->Format == MESA_FORMAT_RGBA8888_REV); - if (!mask && val == 0) { - /* common case */ - memset(dst, 0, count * 4 * sizeof(GLubyte)); - } - else { - /* general case */ - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = val; - } - } - } - else { - GLuint i; - for (i = 0; i < count; i++) { - dst[i] = val; - } - } - } -} - - -static void -put_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *values, - const GLubyte *mask) -{ - /* treat 4*GLubyte as 1*GLuint */ - const GLuint *src = (const GLuint *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || - rb->Format == MESA_FORMAT_RGBA8888_REV); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); - *dst = src[i]; - } - } -} - - -static void -put_mono_values_ubyte4(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - /* treat 4*GLubyte as 1*GLuint */ - const GLuint val = *((const GLuint *) value); - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_BYTE); - ASSERT(rb->Format == MESA_FORMAT_RGBA8888 || - rb->Format == MESA_FORMAT_RGBA8888_REV); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->RowStride + x[i]); - *dst = val; - } - } -} - - -/********************************************************************** - * Functions for buffers of 4 X GLushort (or GLshort) values. - * Typically accum buffer. - */ - -static void -get_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLushort *dst = (GLushort *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - for (i = 0; i < count; i++) { - const GLushort *src - = (GLushort *) rb->Data + 4 * (y[i] * rb->RowStride + x[i]); - dst[i] = *src; - } -} - - -static void -put_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - const GLushort *src = (const GLushort *) values; - GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); - ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i * 4 + 0] = src[i * 4 + 0]; - dst[i * 4 + 1] = src[i * 4 + 1]; - dst[i * 4 + 2] = src[i * 4 + 2]; - dst[i * 4 + 3] = src[i * 4 + 3]; - } - } - } - else { - memcpy(dst, src, 4 * count * sizeof(GLushort)); - } -} - - -static void -put_row_rgb_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *values, const GLubyte *mask) -{ - /* Put RGB values in RGBA buffer */ - const GLushort *src = (const GLushort *) values; - GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); - ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - if (mask) { - GLuint i; - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i * 4 + 0] = src[i * 3 + 0]; - dst[i * 4 + 1] = src[i * 3 + 1]; - dst[i * 4 + 2] = src[i * 3 + 2]; - dst[i * 4 + 3] = 0xffff; - } - } - } - else { - memcpy(dst, src, 4 * count * sizeof(GLushort)); - } -} - - -static void -put_mono_row_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, const void *value, const GLubyte *mask) -{ - const GLushort val0 = ((const GLushort *) value)[0]; - const GLushort val1 = ((const GLushort *) value)[1]; - const GLushort val2 = ((const GLushort *) value)[2]; - const GLushort val3 = ((const GLushort *) value)[3]; - GLushort *dst = (GLushort *) rb->Data + 4 * (y * rb->RowStride + x); - ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - if (!mask && val0 == 0 && val1 == 0 && val2 == 0 && val3 == 0) { - /* common case for clearing accum buffer */ - memset(dst, 0, count * 4 * sizeof(GLushort)); - } - else { - GLuint i; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst[i * 4 + 0] = val0; - dst[i * 4 + 1] = val1; - dst[i * 4 + 2] = val2; - dst[i * 4 + 3] = val3; - } - } - } -} - - -static void -put_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], const void *values, - const GLubyte *mask) -{ - const GLushort *src = (const GLushort *) values; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLushort *dst = - ((GLushort *) rb->Data) + 4 * (y[i] * rb->RowStride + x[i]); - dst[0] = src[i * 4 + 0]; - dst[1] = src[i * 4 + 1]; - dst[2] = src[i * 4 + 2]; - dst[3] = src[i * 4 + 3]; - } - } -} - - -static void -put_mono_values_ushort4(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - const GLushort val0 = ((const GLushort *) value)[0]; - const GLushort val1 = ((const GLushort *) value)[1]; - const GLushort val2 = ((const GLushort *) value)[2]; - const GLushort val3 = ((const GLushort *) value)[3]; - GLuint i; - ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - GLushort *dst = ((GLushort *) rb->Data) + - 4 * (y[i] * rb->RowStride + x[i]); - dst[0] = val0; - dst[1] = val1; - dst[2] = val2; - dst[3] = val3; - } - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_R8. - */ -static void -get_row_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values) -{ - const GLubyte *src = rb->GetPointer(ctx, rb, x, y); - GLuint *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i] = 0xff000000 | src[i]; - } -} - -static void -get_values_r8(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLuint *dst = (GLuint *) values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLubyte *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i] = 0xff000000 | *src; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_GR88. - */ -static void -get_row_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values) -{ - const GLushort *src = rb->GetPointer(ctx, rb, x, y); - GLuint *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i] = 0xff000000 | src[i]; - } -} - -static void -get_values_rg88(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], void *values) -{ - GLuint *dst = (GLuint *) values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i] = 0xff000000 | *src; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_R16. - */ -static void -get_row_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values) -{ - const GLushort *src = rb->GetPointer(ctx, rb, x, y); - GLushort *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = src[i]; - dst[i * 4 + GCOMP] = 0; - dst[i * 4 + BCOMP] = 0; - dst[i * 4 + ACOMP] = 0xffff; - } -} - -static void -get_values_r16(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - const GLint x[], const GLint y[], void *values) -{ - GLushort *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLushort *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = *src; - dst[i * 4 + GCOMP] = 0; - dst[i * 4 + BCOMP] = 0; - dst[i * 4 + ACOMP] = 0xffff; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_RG1616. - */ -static void -get_row_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count, - GLint x, GLint y, void *values) -{ - const GLushort *src = rb->GetPointer(ctx, rb, x, y); - GLushort *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = src[i * 2]; - dst[i * 4 + GCOMP] = src[i * 2 + 1]; - dst[i * 4 + BCOMP] = 0; - dst[i * 4 + ACOMP] = 0xffff; - } -} - -static void -get_values_rg1616(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], void *values) -{ - GLushort *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLshort *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = src[0]; - dst[i * 4 + GCOMP] = src[1]; - dst[i * 4 + BCOMP] = 0; - dst[i * 4 + ACOMP] = 0xffff; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_INTENSITY_FLOAT32. - */ -static void -get_row_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, void *values) -{ - const GLfloat *src = rb->GetPointer(ctx, rb, x, y); - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = - dst[i * 4 + GCOMP] = - dst[i * 4 + BCOMP] = - dst[i * 4 + ACOMP] = src[i]; - } -} - -static void -get_values_i_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values) -{ - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = - dst[i * 4 + GCOMP] = - dst[i * 4 + BCOMP] = - dst[i * 4 + ACOMP] = src[0]; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_LUMINANCE_FLOAT32. - */ -static void -get_row_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, void *values) -{ - const GLfloat *src = rb->GetPointer(ctx, rb, x, y); - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = - dst[i * 4 + GCOMP] = - dst[i * 4 + BCOMP] = src[i]; - dst[i * 4 + ACOMP] = 1.0; - } -} - -static void -get_values_l_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values) -{ - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = - dst[i * 4 + GCOMP] = - dst[i * 4 + BCOMP] = src[0]; - dst[i * 4 + ACOMP] = 1.0; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_ALPHA_FLOAT32. - */ -static void -get_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, void *values) -{ - const GLfloat *src = rb->GetPointer(ctx, rb, x, y); - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = 0.0; - dst[i * 4 + GCOMP] = 0.0; - dst[i * 4 + BCOMP] = 0.0; - dst[i * 4 + ACOMP] = src[i]; - } -} - -static void -get_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values) -{ - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = 0.0; - dst[i * 4 + GCOMP] = 0.0; - dst[i * 4 + BCOMP] = 0.0; - dst[i * 4 + ACOMP] = src[0]; - } -} - -static void -put_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - const void *values, const GLubyte *mask) -{ - float *dst = rb->GetPointer(ctx, rb, x, y); - const float *src = values; - unsigned int i; - - if (mask) { - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = src[i * 4 + ACOMP]; - } - } - } - else { - for (i = 0; i < count; i++) { - dst[i] = src[i * 4 + ACOMP]; - } - } -} - -static void -put_mono_row_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, - const void *value, const GLubyte *mask) -{ - float *dst = rb->GetPointer(ctx, rb, x, y); - const float *src = value; - unsigned int i; - - if (mask) { - for (i = 0; i < count; i++) { - if (mask[i]) { - dst[i] = src[ACOMP]; - } - } - } - else { - for (i = 0; i < count; i++) { - dst[i] = src[ACOMP]; - } - } -} - -static void -put_values_a_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *values, const GLubyte *mask) -{ - const float *src = values; - unsigned int i; - - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); - - *dst = src[i * 4 + ACOMP]; - } - } -} - -static void -put_mono_values_a_float32(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - const void *value, const GLubyte *mask) -{ - const float *src = value; - unsigned int i; - - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - float *dst = rb->GetPointer(ctx, rb, x[i], y[i]); - *dst = src[ACOMP]; - } - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_R_FLOAT32. - */ -static void -get_row_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, void *values) -{ - const GLfloat *src = rb->GetPointer(ctx, rb, x, y); - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = src[i]; - dst[i * 4 + GCOMP] = 0.0; - dst[i * 4 + BCOMP] = 0.0; - dst[i * 4 + ACOMP] = 1.0; - } -} - -static void -get_values_r_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values) -{ - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = src[0]; - dst[i * 4 + GCOMP] = 0.0; - dst[i * 4 + BCOMP] = 0.0; - dst[i * 4 + ACOMP] = 1.0; - } -} - -/********************************************************************** - * Functions for MESA_FORMAT_RG_FLOAT32. - */ -static void -get_row_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, GLint x, GLint y, void *values) -{ - const GLfloat *src = rb->GetPointer(ctx, rb, x, y); - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - dst[i * 4 + RCOMP] = src[i * 2 + 0]; - dst[i * 4 + GCOMP] = src[i * 2 + 1]; - dst[i * 4 + BCOMP] = 0.0; - dst[i * 4 + ACOMP] = 1.0; - } -} - -static void -get_values_rg_float32(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLuint count, const GLint x[], const GLint y[], - void *values) -{ - GLfloat *dst = values; - GLuint i; - - for (i = 0; i < count; i++) { - const GLfloat *src = rb->GetPointer(ctx, rb, x[i], y[i]); - dst[i * 4 + RCOMP] = src[0]; - dst[i * 4 + GCOMP] = src[1]; - dst[i * 4 + BCOMP] = 0.0; - dst[i * 4 + ACOMP] = 1.0; - } -} - -/** - * This is the default software fallback for gl_renderbuffer's span - * access functions. - * - * The assumptions are that rb->Data will be a pointer to (0,0), that pixels - * are packed in the type of rb->Format, and that subsequent rows appear - * rb->RowStride pixels later. - */ -void -_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb) -{ - rb->GetPointer = get_pointer_generic; - rb->GetRow = get_row_generic; - - switch (rb->Format) { - case MESA_FORMAT_RGB888: - rb->DataType = GL_UNSIGNED_BYTE; - rb->GetPointer = get_pointer_ubyte3; - rb->GetRow = get_row_ubyte3; - rb->GetValues = get_values_ubyte3; - rb->PutRow = put_row_ubyte3; - rb->PutRowRGB = put_row_rgb_ubyte3; - rb->PutMonoRow = put_mono_row_ubyte3; - rb->PutValues = put_values_ubyte3; - rb->PutMonoValues = put_mono_values_ubyte3; - break; - - case MESA_FORMAT_RGBA8888: - case MESA_FORMAT_RGBA8888_REV: - rb->DataType = GL_UNSIGNED_BYTE; - rb->GetValues = get_values_ubyte4; - rb->PutRow = put_row_ubyte4; - rb->PutRowRGB = put_row_rgb_ubyte4; - rb->PutMonoRow = put_mono_row_ubyte4; - rb->PutValues = put_values_ubyte4; - rb->PutMonoValues = put_mono_values_ubyte4; - break; - - case MESA_FORMAT_R8: - rb->DataType = GL_UNSIGNED_BYTE; - rb->GetValues = get_values_r8; - rb->GetRow = get_row_r8; - rb->PutRow = put_row_generic; - rb->PutRowRGB = put_row_generic; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_GR88: - rb->DataType = GL_UNSIGNED_BYTE; - rb->GetValues = get_values_rg88; - rb->GetRow = get_row_rg88; - rb->PutRow = put_row_generic; - rb->PutRowRGB = put_row_generic; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_R16: - rb->DataType = GL_UNSIGNED_SHORT; - rb->GetValues = get_values_r16; - rb->GetRow = get_row_r16; - rb->PutRow = put_row_generic; - rb->PutRowRGB = put_row_generic; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_RG1616: - rb->DataType = GL_UNSIGNED_SHORT; - rb->GetValues = get_values_rg1616; - rb->GetRow = get_row_rg1616; - rb->PutRow = put_row_generic; - rb->PutRowRGB = put_row_generic; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_SIGNED_RGBA_16: - rb->DataType = GL_SHORT; - rb->GetValues = get_values_ushort4; - rb->PutRow = put_row_ushort4; - rb->PutRowRGB = put_row_rgb_ushort4; - rb->PutMonoRow = put_mono_row_ushort4; - rb->PutValues = put_values_ushort4; - rb->PutMonoValues = put_mono_values_ushort4; - break; - - case MESA_FORMAT_S8: - rb->DataType = GL_UNSIGNED_BYTE; - rb->GetValues = get_values_ubyte; - rb->PutRow = put_row_ubyte; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_ubyte; - rb->PutValues = put_values_ubyte; - rb->PutMonoValues = put_mono_values_ubyte; - break; - - case MESA_FORMAT_Z16: - rb->DataType = GL_UNSIGNED_SHORT; - rb->GetValues = get_values_ushort; - rb->PutRow = put_row_ushort; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_ushort; - rb->PutValues = put_values_ushort; - rb->PutMonoValues = put_mono_values_ushort; - break; - - case MESA_FORMAT_Z32: - case MESA_FORMAT_X8_Z24: - case MESA_FORMAT_Z24_X8: - rb->DataType = GL_UNSIGNED_INT; - rb->GetValues = get_values_uint; - rb->PutRow = put_row_uint; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_uint; - rb->PutValues = put_values_uint; - rb->PutMonoValues = put_mono_values_uint; - break; - - case MESA_FORMAT_Z24_S8: - case MESA_FORMAT_S8_Z24: - rb->DataType = GL_UNSIGNED_INT_24_8_EXT; - rb->GetValues = get_values_uint; - rb->PutRow = put_row_uint; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_uint; - rb->PutValues = put_values_uint; - rb->PutMonoValues = put_mono_values_uint; - break; - - case MESA_FORMAT_RGBA_FLOAT32: - rb->GetRow = get_row_generic; - rb->GetValues = get_values_generic; - rb->PutRow = put_row_generic; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_INTENSITY_FLOAT32: - rb->GetRow = get_row_i_float32; - rb->GetValues = get_values_i_float32; - rb->PutRow = put_row_generic; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_LUMINANCE_FLOAT32: - rb->GetRow = get_row_l_float32; - rb->GetValues = get_values_l_float32; - rb->PutRow = put_row_generic; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_ALPHA_FLOAT32: - rb->GetRow = get_row_a_float32; - rb->GetValues = get_values_a_float32; - rb->PutRow = put_row_a_float32; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_a_float32; - rb->PutValues = put_values_a_float32; - rb->PutMonoValues = put_mono_values_a_float32; - break; - - case MESA_FORMAT_RG_FLOAT32: - rb->GetRow = get_row_rg_float32; - rb->GetValues = get_values_rg_float32; - rb->PutRow = put_row_generic; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - case MESA_FORMAT_R_FLOAT32: - rb->GetRow = get_row_r_float32; - rb->GetValues = get_values_r_float32; - rb->PutRow = put_row_generic; - rb->PutRowRGB = NULL; - rb->PutMonoRow = put_mono_row_generic; - rb->PutValues = put_values_generic; - rb->PutMonoValues = put_mono_values_generic; - break; - - default: - break; - } -} - -/** - * This is a software fallback for the gl_renderbuffer->AllocStorage - * function. - * Device drivers will typically override this function for the buffers - * which it manages (typically color buffers, Z and stencil). - * Other buffers (like software accumulation and aux buffers) which the driver - * doesn't manage can be handled with this function. - * - * This one multi-purpose function can allocate stencil, depth, accum, color - * or color-index buffers! - * - * This function also plugs in the appropriate GetPointer, Get/PutRow and - * Get/PutValues functions. - */ -GLboolean -_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) -{ - switch (internalFormat) { - 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: - rb->Format = MESA_FORMAT_RGB888; - break; - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: -#if 1 - case GL_RGB10_A2: - case GL_RGBA12: -#endif - if (_mesa_little_endian()) - rb->Format = MESA_FORMAT_RGBA8888_REV; - else - rb->Format = MESA_FORMAT_RGBA8888; - break; - case GL_RGBA16: - case GL_RGBA16_SNORM: - /* for accum buffer */ - rb->Format = MESA_FORMAT_SIGNED_RGBA_16; - break; - case GL_STENCIL_INDEX: - case GL_STENCIL_INDEX1_EXT: - case GL_STENCIL_INDEX4_EXT: - case GL_STENCIL_INDEX8_EXT: - case GL_STENCIL_INDEX16_EXT: - rb->Format = MESA_FORMAT_S8; - break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - rb->Format = MESA_FORMAT_Z16; - break; - case GL_DEPTH_COMPONENT24: - rb->Format = MESA_FORMAT_X8_Z24; - break; - case GL_DEPTH_COMPONENT32: - rb->Format = MESA_FORMAT_Z32; - break; - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - rb->Format = MESA_FORMAT_Z24_S8; - break; - default: - /* unsupported format */ - return GL_FALSE; - } - - _mesa_set_renderbuffer_accessors(rb); - - ASSERT(rb->DataType); - ASSERT(rb->GetPointer); - ASSERT(rb->GetRow); - ASSERT(rb->GetValues); - ASSERT(rb->PutRow); - ASSERT(rb->PutMonoRow); - ASSERT(rb->PutValues); - ASSERT(rb->PutMonoValues); - - /* free old buffer storage */ - if (rb->Data) { - free(rb->Data); - rb->Data = NULL; - } - - rb->RowStride = width; - - if (width > 0 && height > 0) { - /* allocate new buffer storage */ - rb->Data = malloc(width * height * _mesa_get_format_bytes(rb->Format)); - - if (rb->Data == NULL) { - rb->Width = 0; - rb->Height = 0; - rb->RowStride = 0; - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "software renderbuffer allocation (%d x %d x %d)", - width, height, _mesa_get_format_bytes(rb->Format)); - return GL_FALSE; - } - } - - rb->Width = width; - rb->Height = height; - rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); - - if (rb->Name == 0 && - internalFormat == GL_RGBA16_SNORM && - rb->_BaseFormat == 0) { - /* NOTE: This is a special case just for accumulation buffers. - * This is a very limited use case- there's no snorm texturing or - * rendering going on. - */ - rb->_BaseFormat = GL_RGBA; - } - else { - /* the internalFormat should have been error checked long ago */ - ASSERT(rb->_BaseFormat); - } - - return GL_TRUE; -} - - -void -_mesa_map_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **out_map, - GLint *out_stride) -{ - GLubyte *map = rb->Data; - int cpp = _mesa_get_format_bytes(rb->Format); - int stride = rb->RowStride * cpp; - - ASSERT(rb->Data); - - map += y * stride; - map += x * cpp; - - *out_map = map; - *out_stride = stride; -} - -void -_mesa_unmap_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb) -{ -} - - - -/**********************************************************************/ -/**********************************************************************/ -/**********************************************************************/ +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "fbobject.h" +#include "formats.h" +#include "mtypes.h" +#include "renderbuffer.h" /** @@ -1820,310 +114,6 @@ _mesa_delete_renderbuffer(struct gl_renderbuffer *rb) } -/** - * Allocate a software-based renderbuffer. This is called via the - * ctx->Driver.NewRenderbuffer() function when the user creates a new - * renderbuffer. - * This would not be used for hardware-based renderbuffers. - */ -struct gl_renderbuffer * -_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name) -{ - struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); - if (rb) { - rb->AllocStorage = _mesa_soft_renderbuffer_storage; - /* Normally, one would setup the PutRow, GetRow, etc functions here. - * But we're doing that in the _mesa_soft_renderbuffer_storage() function - * instead. - */ - } - return rb; -} - - -/** - * Add software-based color renderbuffers to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -GLboolean -_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint rgbBits, GLuint alphaBits, - GLboolean frontLeft, GLboolean backLeft, - GLboolean frontRight, GLboolean backRight) -{ - gl_buffer_index b; - - if (rgbBits > 16 || alphaBits > 16) { - _mesa_problem(ctx, - "Unsupported bit depth in _mesa_add_color_renderbuffers"); - return GL_FALSE; - } - - assert(MAX_COLOR_ATTACHMENTS >= 4); - - for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { - struct gl_renderbuffer *rb; - - if (b == BUFFER_FRONT_LEFT && !frontLeft) - continue; - else if (b == BUFFER_BACK_LEFT && !backLeft) - continue; - else if (b == BUFFER_FRONT_RIGHT && !frontRight) - continue; - else if (b == BUFFER_BACK_RIGHT && !backRight) - continue; - - assert(fb->Attachment[b].Renderbuffer == NULL); - - rb = _mesa_new_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer"); - return GL_FALSE; - } - - rb->InternalFormat = GL_RGBA; - - rb->AllocStorage = _mesa_soft_renderbuffer_storage; - _mesa_add_renderbuffer(fb, b, rb); - } - - return GL_TRUE; -} - - -/** - * Add a software-based depth renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -GLboolean -_mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint depthBits) -{ - struct gl_renderbuffer *rb; - - if (depthBits > 32) { - _mesa_problem(ctx, - "Unsupported depthBits in _mesa_add_depth_renderbuffer"); - return GL_FALSE; - } - - assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL); - - rb = _mesa_new_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer"); - return GL_FALSE; - } - - if (depthBits <= 16) { - rb->InternalFormat = GL_DEPTH_COMPONENT16; - } - else if (depthBits <= 24) { - rb->InternalFormat = GL_DEPTH_COMPONENT24; - } - else { - rb->InternalFormat = GL_DEPTH_COMPONENT32; - } - - rb->AllocStorage = _mesa_soft_renderbuffer_storage; - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); - - return GL_TRUE; -} - - -/** - * Add a software-based stencil renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -GLboolean -_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint stencilBits) -{ - struct gl_renderbuffer *rb; - - if (stencilBits > 16) { - _mesa_problem(ctx, - "Unsupported stencilBits in _mesa_add_stencil_renderbuffer"); - return GL_FALSE; - } - - assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL); - - rb = _mesa_new_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer"); - return GL_FALSE; - } - - assert(stencilBits <= 8); - rb->InternalFormat = GL_STENCIL_INDEX8; - - rb->AllocStorage = _mesa_soft_renderbuffer_storage; - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); - - return GL_TRUE; -} - - -/** - * Add a software-based accumulation renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - */ -GLboolean -_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint redBits, GLuint greenBits, - GLuint blueBits, GLuint alphaBits) -{ - struct gl_renderbuffer *rb; - - if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) { - _mesa_problem(ctx, - "Unsupported accumBits in _mesa_add_accum_renderbuffer"); - return GL_FALSE; - } - - assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL); - - rb = _mesa_new_renderbuffer(ctx, 0); - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer"); - return GL_FALSE; - } - - rb->InternalFormat = GL_RGBA16_SNORM; - rb->AllocStorage = _mesa_soft_renderbuffer_storage; - _mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb); - - return GL_TRUE; -} - - - -/** - * Add a software-based aux renderbuffer to the given framebuffer. - * This is a helper routine for device drivers when creating a - * window system framebuffer (not a user-created render/framebuffer). - * Once this function is called, you can basically forget about this - * renderbuffer; core Mesa will handle all the buffer management and - * rendering! - * - * NOTE: color-index aux buffers not supported. - */ -GLboolean -_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint colorBits, GLuint numBuffers) -{ - GLuint i; - - if (colorBits > 16) { - _mesa_problem(ctx, - "Unsupported accumBits in _mesa_add_aux_renderbuffers"); - return GL_FALSE; - } - - assert(numBuffers <= MAX_AUX_BUFFERS); - - for (i = 0; i < numBuffers; i++) { - struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0); - - assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL); - - if (!rb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating aux buffer"); - return GL_FALSE; - } - - assert (colorBits <= 8); - rb->InternalFormat = GL_RGBA; - - rb->AllocStorage = _mesa_soft_renderbuffer_storage; - _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); - } - return GL_TRUE; -} - - -/** - * Create/attach software-based renderbuffers to the given framebuffer. - * This is a helper routine for device drivers. Drivers can just as well - * call the individual _mesa_add_*_renderbuffer() routines directly. - */ -void -_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, - GLboolean color, - GLboolean depth, - GLboolean stencil, - GLboolean accum, - GLboolean alpha, - GLboolean aux) -{ - GLboolean frontLeft = GL_TRUE; - GLboolean backLeft = fb->Visual.doubleBufferMode; - GLboolean frontRight = fb->Visual.stereoMode; - GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode; - - if (color) { - assert(fb->Visual.redBits == fb->Visual.greenBits); - assert(fb->Visual.redBits == fb->Visual.blueBits); - _mesa_add_color_renderbuffers(NULL, fb, - fb->Visual.redBits, - fb->Visual.alphaBits, - frontLeft, backLeft, - frontRight, backRight); - } - - if (depth) { - assert(fb->Visual.depthBits > 0); - _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits); - } - - if (stencil) { - assert(fb->Visual.stencilBits > 0); - _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits); - } - - if (accum) { - assert(fb->Visual.accumRedBits > 0); - assert(fb->Visual.accumGreenBits > 0); - assert(fb->Visual.accumBlueBits > 0); - _mesa_add_accum_renderbuffer(NULL, fb, - fb->Visual.accumRedBits, - fb->Visual.accumGreenBits, - fb->Visual.accumBlueBits, - fb->Visual.accumAlphaBits); - } - - if (aux) { - assert(fb->Visual.numAuxBuffers > 0); - _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, - fb->Visual.numAuxBuffers); - } - -#if 0 - if (multisample) { - /* maybe someday */ - } -#endif -} - - /** * Attach a renderbuffer to a framebuffer. * \param bufferName one of the BUFFER_x tokens @@ -2166,17 +156,9 @@ void _mesa_remove_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index bufferName) { - struct gl_renderbuffer *rb; - assert(bufferName < BUFFER_COUNT); - - rb = fb->Attachment[bufferName].Renderbuffer; - if (!rb) - return; - - _mesa_reference_renderbuffer(&rb, NULL); - - fb->Attachment[bufferName].Renderbuffer = NULL; + _mesa_reference_renderbuffer(&fb->Attachment[bufferName].Renderbuffer, + NULL); } diff --git a/mesalib/src/mesa/main/renderbuffer.h b/mesalib/src/mesa/main/renderbuffer.h index 3194fc3fe..0934d85df 100644 --- a/mesalib/src/mesa/main/renderbuffer.h +++ b/mesalib/src/mesa/main/renderbuffer.h @@ -42,63 +42,6 @@ _mesa_new_renderbuffer(struct gl_context *ctx, GLuint name); extern void _mesa_delete_renderbuffer(struct gl_renderbuffer *rb); - -extern struct gl_renderbuffer * -_mesa_new_soft_renderbuffer(struct gl_context *ctx, GLuint name); - -void -_mesa_map_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **out_map, - GLint *out_stride); - -void -_mesa_unmap_soft_renderbuffer(struct gl_context *ctx, - struct gl_renderbuffer *rb); - -extern void -_mesa_set_renderbuffer_accessors(struct gl_renderbuffer *rb); - -extern GLboolean -_mesa_soft_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height); - -extern GLboolean -_mesa_add_color_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint rgbBits, GLuint alphaBits, - GLboolean frontLeft, GLboolean backLeft, - GLboolean frontRight, GLboolean backRight); - -extern GLboolean -_mesa_add_depth_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint depthBits); - -extern GLboolean -_mesa_add_stencil_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint stencilBits); - - -extern GLboolean -_mesa_add_accum_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint redBits, GLuint greenBits, - GLuint blueBits, GLuint alphaBits); - -extern GLboolean -_mesa_add_aux_renderbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, - GLuint bits, GLuint numBuffers); - -extern void -_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb, - GLboolean color, - GLboolean depth, - GLboolean stencil, - GLboolean accum, - GLboolean alpha, - GLboolean aux); - extern void _mesa_add_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index bufferName, struct gl_renderbuffer *rb); diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 17c78ce3e..8e447cabd 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -1184,10 +1184,7 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, * * \return GL_TRUE if all textures are resident and \p residences is left unchanged, * - * \sa glAreTexturesResident(). - * - * Looks up each texture in the hash and calls - * dd_function_table::IsTextureResident. + * Note: we assume all textures are always resident */ GLboolean GLAPIENTRY _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, @@ -1195,7 +1192,7 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, { GET_CURRENT_CONTEXT(ctx); GLboolean allResident = GL_TRUE; - GLint i, j; + GLint i; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (n < 0) { @@ -1206,6 +1203,7 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, if (!texName || !residences) return GL_FALSE; + /* We only do error checking on the texture names */ for (i = 0; i < n; i++) { struct gl_texture_object *t; if (texName[i] == 0) { @@ -1217,21 +1215,6 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); return GL_FALSE; } - if (!ctx->Driver.IsTextureResident || - ctx->Driver.IsTextureResident(ctx, t)) { - /* The texture is resident */ - if (!allResident) - residences[i] = GL_TRUE; - } - else { - /* The texture is not resident */ - if (allResident) { - allResident = GL_FALSE; - for (j = 0; j < i; j++) - residences[j] = GL_TRUE; - } - residences[i] = GL_FALSE; - } } return allResident; diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index f4ec63388..0f92a5b98 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -1114,8 +1114,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) } break; case GL_TEXTURE_RESIDENT: - *params = ctx->Driver.IsTextureResident ? - ctx->Driver.IsTextureResident(ctx, obj) : 1.0F; + *params = 1.0F; break; case GL_TEXTURE_PRIORITY: *params = obj->Priority; @@ -1261,8 +1260,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) } break;; case GL_TEXTURE_RESIDENT: - *params = ctx->Driver.IsTextureResident ? - ctx->Driver.IsTextureResident(ctx, obj) : 1; + *params = 1; break;; case GL_TEXTURE_PRIORITY: *params = FLOAT_TO_INT(obj->Priority); diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 37fea2156..a57a38e12 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -954,8 +954,7 @@ memcpy_texture(struct gl_context *ctx, GLubyte *dstImage = dstSlices[dstZoffset + img] + dstYoffset * dstRowStride + dstXoffset * texelBytes; - ctx->Driver.TextureMemCpy(dstImage, srcImage, - bytesPerRow * srcHeight); + memcpy(dstImage, srcImage, bytesPerRow * srcHeight); srcImage += srcImageStride; } } @@ -968,7 +967,7 @@ memcpy_texture(struct gl_context *ctx, + dstYoffset * dstRowStride + dstXoffset * texelBytes; for (row = 0; row < srcHeight; row++) { - ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow); + memcpy(dstRow, srcRow, bytesPerRow); dstRow += dstRowStride; srcRow += srcRowStride; } @@ -3569,6 +3568,8 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || @@ -3639,6 +3640,8 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || @@ -3709,6 +3712,8 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || @@ -3779,6 +3784,8 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || @@ -3847,6 +3854,8 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || @@ -3915,6 +3924,8 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32); ASSERT(baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB || + baseInternalFormat == GL_RG || + baseInternalFormat == GL_RED || baseInternalFormat == GL_ALPHA || baseInternalFormat == GL_LUMINANCE || baseInternalFormat == GL_LUMINANCE_ALPHA || -- cgit v1.2.3