diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2005-05-04 20:11:35 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2005-05-04 20:11:35 +0000 |
commit | e4b2356c07d31fbeeabb13b2fb47db703b473080 (patch) | |
tree | d8b7f1c7c9e7c84d84349485f942dd205dd4c16d /src/mesa/main | |
parent | ebef61f5c0950572f9c6a81b08f447957461675c (diff) |
Major check-in of changes for GL_EXT_framebuffer_object extension.
Main driver impacts:
- new code for creating the Mesa GLframebuffer
- new span/pixel read/write code
Some drivers not yet updated/tested.
Diffstat (limited to 'src/mesa/main')
33 files changed, 4328 insertions, 1179 deletions
diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c index 315bd33b61..c1346bab4c 100644 --- a/src/mesa/main/accum.c +++ b/src/mesa/main/accum.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.3 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -63,6 +63,19 @@ _mesa_Accum( GLenum op, GLfloat value ) return; } + switch (op) { + case GL_ADD: + case GL_MULT: + case GL_ACCUM: + case GL_LOAD: + case GL_RETURN: + /* OK */ + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glAccum(op)"); + return; + } + if (ctx->NewState) _mesa_update_state( ctx ); @@ -89,6 +102,8 @@ _mesa_Accum( GLenum op, GLfloat value ) ctx->Driver.Accum( ctx, op, value, xpos, ypos, width, height ); } + + void _mesa_init_accum( GLcontext *ctx ) { diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index d45593cc99..da6011c1ce 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -833,8 +833,13 @@ _mesa_PopAttrib(void) (GLboolean) (color->ColorMask[1] != 0), (GLboolean) (color->ColorMask[2] != 0), (GLboolean) (color->ColorMask[3] != 0)); +#if 0 _mesa_DrawBuffersARB(ctx->Const.MaxDrawBuffers, color->DrawBuffer); +#else + _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, + color->DrawBuffer, NULL); +#endif _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef); _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); @@ -992,6 +997,8 @@ _mesa_PopAttrib(void) break; case GL_PIXEL_MODE_BIT: MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); + /* XXX what other pixel state needs to be set by function calls? */ + _mesa_ReadBuffer(ctx->Pixel.ReadBuffer); ctx->NewState |= _NEW_PIXEL; break; case GL_POINT_BIT: diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index 8fadef61b4..61b2b17c0c 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -570,11 +570,9 @@ void _mesa_init_color( GLcontext * ctx ) if (ctx->Visual.doubleBufferMode) { ctx->Color.DrawBuffer[0] = GL_BACK; - ctx->Color._DrawDestMask[0] = DD_BACK_LEFT_BIT; } else { ctx->Color.DrawBuffer[0] = GL_FRONT; - ctx->Color._DrawDestMask[0] = DD_FRONT_LEFT_BIT; } } diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 185d841f81..07b2341ff7 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -900,7 +900,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params) switch (pname) { case GL_BUFFER_SIZE_ARB: - *params = bufObj->Size; + *params = (GLint) bufObj->Size; break; case GL_BUFFER_USAGE_ARB: *params = bufObj->Usage; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 41a1fdb7cc..12f58ff662 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -29,16 +29,15 @@ #include "glheader.h" -#include "imports.h" #include "buffers.h" #include "colormac.h" #include "context.h" -#include "depth.h" #include "enums.h" #include "fbobject.h" -#include "stencil.h" #include "state.h" -#include "mtypes.h" + + +#define BAD_MASK ~0u #if _HAVE_FULL_GL @@ -133,12 +132,12 @@ _mesa_Clear( GLbitfield mask ) _mesa_update_state( ctx ); /* update _Xmin, etc */ } - if (ctx->RenderMode==GL_RENDER) { + if (ctx->RenderMode == GL_RENDER) { const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - GLbitfield ddMask; + GLbitfield bufferMask; /* don't clear depth buffer if depth writing disabled */ if (!ctx->Depth.Mask) @@ -146,20 +145,31 @@ _mesa_Clear( GLbitfield mask ) /* Build the bitmask to send to device driver's Clear function. * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4 - * of the FRONT/BACK_LEFT/RIGHT_BIT flags. + * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the + * BUFFER_BIT_COLORn flags. */ - ddMask = 0; - if (mask & GL_COLOR_BUFFER_BIT) - ddMask |= ctx->Color._DrawDestMask[0]; - if ((mask & GL_DEPTH_BUFFER_BIT) && ctx->Visual.depthBits > 0) - ddMask |= GL_DEPTH_BUFFER_BIT; - if ((mask & GL_STENCIL_BUFFER_BIT) && ctx->Visual.stencilBits > 0) - ddMask |= GL_STENCIL_BUFFER_BIT; - if ((mask & GL_ACCUM_BUFFER_BIT) && ctx->Visual.accumRedBits > 0) - ddMask |= GL_ACCUM_BUFFER_BIT; + bufferMask = 0; + if (mask & GL_COLOR_BUFFER_BIT) { + bufferMask |= ctx->DrawBuffer->_ColorDrawBufferMask[0]; + } + + if ((mask & GL_DEPTH_BUFFER_BIT) + && ctx->DrawBuffer->Visual.haveDepthBuffer) { + bufferMask |= BUFFER_BIT_DEPTH; + } + + if ((mask & GL_STENCIL_BUFFER_BIT) + && ctx->DrawBuffer->Visual.haveStencilBuffer) { + bufferMask |= BUFFER_BIT_STENCIL; + } + + if ((mask & GL_ACCUM_BUFFER_BIT) + && ctx->DrawBuffer->Visual.haveAccumBuffer) { + bufferMask |= BUFFER_BIT_ACCUM; + } ASSERT(ctx->Driver.Clear); - ctx->Driver.Clear( ctx, ddMask, (GLboolean) !ctx->Scissor.Enabled, + ctx->Driver.Clear( ctx, bufferMask, (GLboolean) !ctx->Scissor.Enabled, x, y, width, height ); } } @@ -167,27 +177,41 @@ _mesa_Clear( GLbitfield mask ) /** - * Return bitmask of DD_* flags indicating which color buffers are - * available to the rendering context; + * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are + * available to the rendering context. + * This depends on the framebuffer we're writing to. For window system + * framebuffers we look at the framebuffer's visual. But for user- + * create framebuffers we look at the number of supported color attachments. */ static GLuint -supported_buffer_bitmask(const GLcontext *ctx) +supported_buffer_bitmask(const GLcontext *ctx, GLuint framebufferID) { - GLuint mask = DD_FRONT_LEFT_BIT; /* always have this */ + GLuint mask = 0x0; GLint i; - if (ctx->Visual.stereoMode) { - mask |= DD_FRONT_RIGHT_BIT; - if (ctx->Visual.doubleBufferMode) { - mask |= DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT; + if (framebufferID > 0) { + /* A user-created renderbuffer */ + ASSERT(ctx->Extensions.EXT_framebuffer_object); + for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { + mask |= (BUFFER_BIT_COLOR0 << i); } } - else if (ctx->Visual.doubleBufferMode) { - mask |= DD_BACK_LEFT_BIT; - } + else { + /* A window system renderbuffer */ + mask = BUFFER_BIT_FRONT_LEFT; /* always have this */ + if (ctx->Visual.stereoMode) { + mask |= BUFFER_BIT_FRONT_RIGHT; + if (ctx->Visual.doubleBufferMode) { + mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; + } + } + else if (ctx->Visual.doubleBufferMode) { + mask |= BUFFER_BIT_BACK_LEFT; + } - for (i = 0; i < ctx->Visual.numAuxBuffers; i++) { - mask |= (DD_AUX0_BIT << i); + for (i = 0; i < ctx->Visual.numAuxBuffers; i++) { + mask |= (BUFFER_BIT_AUX0 << i); + } } return mask; @@ -196,45 +220,53 @@ supported_buffer_bitmask(const GLcontext *ctx) /** * Helper routine used by glDrawBuffer and glDrawBuffersARB. - * Given a GLenum naming (a) color buffer(s), return the corresponding - * bitmask of DD_* flags. + * Given a GLenum naming one or more color buffers (such as + * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags. */ static GLuint draw_buffer_enum_to_bitmask(GLenum buffer) { switch (buffer) { - case GL_FRONT: - return DD_FRONT_LEFT_BIT | DD_FRONT_RIGHT_BIT; - case GL_BACK: - return DD_BACK_LEFT_BIT | DD_BACK_RIGHT_BIT; case GL_NONE: return 0; + case GL_FRONT: + return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT; + case GL_BACK: + return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT; case GL_RIGHT: - return DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; case GL_FRONT_RIGHT: - return DD_FRONT_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT; case GL_BACK_RIGHT: - return DD_BACK_RIGHT_BIT; + return BUFFER_BIT_BACK_RIGHT; case GL_BACK_LEFT: - return DD_BACK_LEFT_BIT; + return BUFFER_BIT_BACK_LEFT; case GL_FRONT_AND_BACK: - return DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT - | DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT; + return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT + | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT; case GL_LEFT: - return DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT; case GL_FRONT_LEFT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_AUX0: - return DD_AUX0_BIT; + return BUFFER_BIT_AUX0; case GL_AUX1: - return DD_AUX1_BIT; + return BUFFER_BIT_AUX1; case GL_AUX2: - return DD_AUX2_BIT; + return BUFFER_BIT_AUX2; case GL_AUX3: - return DD_AUX3_BIT; + return BUFFER_BIT_AUX3; + case GL_COLOR_ATTACHMENT0_EXT: + return BUFFER_BIT_COLOR0; + case GL_COLOR_ATTACHMENT1_EXT: + return BUFFER_BIT_COLOR1; + case GL_COLOR_ATTACHMENT2_EXT: + return BUFFER_BIT_COLOR2; + case GL_COLOR_ATTACHMENT3_EXT: + return BUFFER_BIT_COLOR3; default: /* error */ - return ~0; + return BAD_MASK; } } @@ -249,43 +281,48 @@ read_buffer_enum_to_bitmask(GLenum buffer) { switch (buffer) { case GL_FRONT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_BACK: - return DD_BACK_LEFT_BIT; + return BUFFER_BIT_BACK_LEFT; case GL_RIGHT: - return DD_FRONT_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT; case GL_FRONT_RIGHT: - return DD_FRONT_RIGHT_BIT; + return BUFFER_BIT_FRONT_RIGHT; case GL_BACK_RIGHT: - return DD_BACK_RIGHT_BIT; + return BUFFER_BIT_BACK_RIGHT; case GL_BACK_LEFT: - return DD_BACK_LEFT_BIT; + return BUFFER_BIT_BACK_LEFT; case GL_LEFT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_FRONT_LEFT: - return DD_FRONT_LEFT_BIT; + return BUFFER_BIT_FRONT_LEFT; case GL_AUX0: - return DD_AUX0_BIT; + return BUFFER_BIT_AUX0; case GL_AUX1: - return DD_AUX1_BIT; + return BUFFER_BIT_AUX1; case GL_AUX2: - return DD_AUX2_BIT; + return BUFFER_BIT_AUX2; case GL_AUX3: - return DD_AUX3_BIT; + return BUFFER_BIT_AUX3; + case GL_COLOR_ATTACHMENT0_EXT: + return BUFFER_BIT_COLOR0; + case GL_COLOR_ATTACHMENT1_EXT: + return BUFFER_BIT_COLOR1; + case GL_COLOR_ATTACHMENT2_EXT: + return BUFFER_BIT_COLOR2; + case GL_COLOR_ATTACHMENT3_EXT: + return BUFFER_BIT_COLOR3; default: /* error */ - return ~0; + return BAD_MASK; } } - /** * Specify which color buffers to draw into. * - * \param mode color buffer combination. - * - * \sa glDrawBuffer(). + * \param buffer color buffer, such as GL_LEFT or GL_FRONT_AND_BACK. * * Flushes the vertices and verifies the parameter and updates the * gl_colorbuffer_attrib::_DrawDestMask bitfield. Marks new color state in @@ -293,160 +330,180 @@ read_buffer_enum_to_bitmask(GLenum buffer) * dd_function_table::DrawBuffer callback. */ void GLAPIENTRY -_mesa_DrawBuffer( GLenum mode ) +_mesa_DrawBuffer(GLenum buffer) { + GLuint bufferID; + GLuint destMask; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */ - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); + if (MESA_VERBOSE & VERBOSE_API) { + _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); + } - if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) { - /* Set drawbuffer for a framebuffer object */ - if (mode == GL_NONE) { - ctx->CurrentFramebuffer->DrawBuffer[0] = mode; - } - else { - const GLint k = mode - GL_COLOR_ATTACHMENT0_EXT; - if (k >= 0 && k < ctx->Const.MaxColorAttachments) { - /* XXX check that the attachment point's Type != GL_NONE */ - ctx->CurrentFramebuffer->DrawBuffer[0] = mode; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)"); - return; - } - } + bufferID = ctx->DrawBuffer->Name; + + if (buffer == GL_NONE) { + destMask = 0x0; } else { - /* conventional behaviour */ - /* Do error checking and compute the _DrawDestMask bitfield. */ - GLenum destMask, supportedMask; - - destMask = draw_buffer_enum_to_bitmask(mode); - if (destMask == ~0u) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(mode)"); + const GLuint supportedMask = supported_buffer_bitmask(ctx, bufferID); + destMask = draw_buffer_enum_to_bitmask(buffer); + if (destMask == BAD_MASK) { + /* totally bogus buffer */ + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer)"); return; } - - supportedMask = supported_buffer_bitmask(ctx); destMask &= supportedMask; - - if (destMask == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(mode)"); + if (destMask == 0x0) { + /* none of the named color buffers exist! */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(buffer)"); return; } - - ctx->Color.DrawBuffer[0] = mode; - ctx->Color._DrawDestMask[0] = destMask; - ctx->NewState |= _NEW_COLOR; } - /* - * Call device driver function. - */ - if (ctx->Driver.DrawBuffer) - (*ctx->Driver.DrawBuffer)(ctx, mode); + /* if we get here, there's no error so set new state */ + _mesa_drawbuffers(ctx, 1, &buffer, &destMask); } /** * Called by glDrawBuffersARB; specifies the destination color buffers * for N fragment program color outputs. + * + * XXX This function is called by _mesa_PopAttrib() and we need to do + * some more work to deal with the current framebuffer binding state! */ void GLAPIENTRY _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) { + GLint output; + GLuint usedBufferMask, supportedMask; + GLuint bufferID; + GLuint destMask[MAX_DRAW_BUFFERS]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + if (!ctx->Extensions.ARB_draw_buffers) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB"); + return; + } if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)" ); + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)"); return; } - if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) { - /* Set drawbuffers for a framebuffer object */ - GLint i; - GLuint usedAttachments = 0x0; - for (i = 0; i < n; i++) { - if (buffers[i] == GL_NONE) { - /* OK */ - ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE; - } - else { - const GLint k = buffers[i] - GL_COLOR_ATTACHMENT0_EXT; - if (k >= 0 && k < ctx->Const.MaxColorAttachments) { - /* XXX check that the attachment point's Type != GL_NONE */ - if ((1 << k) & usedAttachments) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDrawBuffersARB(duplicated attachment)"); - return; - } - usedAttachments |= (1 << k); - ctx->CurrentFramebuffer->DrawBuffer[i] = buffers[i]; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(mode)"); - return; - } - } - } + bufferID = ctx->DrawBuffer->Name; + + supportedMask = supported_buffer_bitmask(ctx, bufferID); + usedBufferMask = 0x0; - /* set remaining color outputs to NONE */ - for (i = n; i < ctx->Const.MaxDrawBuffers; i++) { - ctx->CurrentFramebuffer->DrawBuffer[i] = GL_NONE; + /* complicated error checking... */ + for (output = 0; output < n; output++) { + if (buffers[output] == GL_NONE) { + destMask[output] = 0x0; } - } - else { - /* Conventional operation */ - GLint i; - GLuint usedBufferMask, supportedMask; - - supportedMask = supported_buffer_bitmask(ctx); - usedBufferMask = 0; - for (i = 0; i < n; i++) { - GLuint destMask = draw_buffer_enum_to_bitmask(buffers[i]); - if (destMask == ~0u ) { + else { + destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]); + if (destMask[output] == BAD_MASK + || _mesa_bitcount(destMask[output]) > 1) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); return; } - destMask &= supportedMask; - if (destMask == 0) { + destMask[output] &= supportedMask; + if (destMask[output] == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(unsupported buffer)"); return; } - if (destMask & usedBufferMask) { + if (destMask[output] & usedBufferMask) { /* can't specify a dest buffer more than once! */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(duplicated buffer)"); return; } + /* update bitmask */ - usedBufferMask |= destMask; - /* save state */ - ctx->Color.DrawBuffer[i] = buffers[i]; - ctx->Color._DrawDestMask[i] = destMask; + usedBufferMask |= destMask[output]; } + } + + /* OK, if we get here, there were no errors so set the new state */ + _mesa_drawbuffers(ctx, n, buffers, destMask); +} + - /* set remaining color outputs to NONE */ - for (i = n; i < ctx->Const.MaxDrawBuffers; i++) { - ctx->Color.DrawBuffer[i] = GL_NONE; - ctx->Color._DrawDestMask[i] = 0; +/** + * Set color output state. Traditionally, there was only one color + * output, but fragment programs can now have several distinct color + * outputs (see GL_ARB_draw_buffers). This function sets the state + * for one such color output. + */ +static void +set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, GLuint destMask) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + + ASSERT(output < ctx->Const.MaxDrawBuffers); + + fb->ColorDrawBuffer[output] = buffer; + fb->_ColorDrawBufferMask[output] = destMask; + + if (fb->Name == 0) { + /* Set traditional state var */ + ctx->Color.DrawBuffer[output] = buffer; + } + + /* not really needed, will be set later */ + fb->_NumColorDrawBuffers[output] = 0; +} + + +/** + * Helper routine used by _mesa_DrawBuffer, _mesa_DrawBuffersARB and + * _mesa_PopAttrib to set drawbuffer state. + */ +void +_mesa_drawbuffers(GLcontext *ctx, GLsizei n, const GLenum *buffers, + const GLuint *destMask) +{ + GLuint mask[MAX_DRAW_BUFFERS]; + GLint output; + + if (!destMask) { + /* compute destMask values now */ + const GLuint bufferID = ctx->DrawBuffer->Name; + const GLuint supportedMask = supported_buffer_bitmask(ctx, bufferID); + for (output = 0; output < n; output++) { + mask[output] = draw_buffer_enum_to_bitmask(buffers[output]); + ASSERT(mask[output] != BAD_MASK); + mask[output] &= supportedMask; } + destMask = mask; + } + + for (output = 0; output < n; output++) { + set_color_output(ctx, output, buffers[output], destMask[output]); + } - ctx->NewState |= _NEW_COLOR; + /* set remaining color outputs to NONE */ + for (output = n; output < ctx->Const.MaxDrawBuffers; output++) { + set_color_output(ctx, output, GL_NONE, 0x0); } + ctx->NewState |= _NEW_COLOR; + /* * Call device driver function. */ if (ctx->Driver.DrawBuffers) - (*ctx->Driver.DrawBuffers)(ctx, n, buffers); + ctx->Driver.DrawBuffers(ctx, n, buffers); + else if (ctx->Driver.DrawBuffer) + ctx->Driver.DrawBuffer(ctx, buffers[0]); } + /** * Set the color buffer source for reading pixels. * @@ -454,60 +511,53 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers) * * \sa glReadBuffer(). * - * Verifies the parameter and updates gl_pixel_attrib::_ReadSrcMask. Marks - * new pixel state in __GLcontextRec::NewState and notifies the driver via - * dd_function_table::ReadBuffer. */ void GLAPIENTRY -_mesa_ReadBuffer( GLenum mode ) +_mesa_ReadBuffer(GLenum buffer) { + struct gl_framebuffer *fb; + GLuint srcMask, supportedMask; + GLuint bufferID; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + fb = ctx->ReadBuffer; + bufferID = fb->Name; + if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); + _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); - if (ctx->Extensions.EXT_framebuffer_object && ctx->CurrentFramebuffer) { - /* Set readbuffer for a framebuffer object */ - if (mode == GL_NONE) { - ctx->CurrentFramebuffer->ReadBuffer = mode; - } - else { - const GLint k = mode - GL_COLOR_ATTACHMENT0_EXT; - if (k >= 0 && k < ctx->Const.MaxColorAttachments) { - /* XXX check that the attachment point's Type != GL_NONE */ - ctx->CurrentFramebuffer->ReadBuffer = mode; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)"); - return; - } - } + if (bufferID > 0 && buffer == GL_NONE) { + /* legal! */ + srcMask = 0x0; } else { - /* conventional operation */ - GLuint srcMask, supportedMask; - - srcMask = read_buffer_enum_to_bitmask(mode); - if (srcMask == ~0u) { - _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(mode)"); + /* general case */ + srcMask = read_buffer_enum_to_bitmask(buffer); + if (srcMask == BAD_MASK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer)"); return; } - supportedMask = supported_buffer_bitmask(ctx); + supportedMask = supported_buffer_bitmask(ctx, bufferID); if ((srcMask & supportedMask) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(mode)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer)"); return; } - ctx->Pixel._ReadSrcMask = srcMask; - ctx->Pixel.ReadBuffer = mode; - ctx->NewState |= _NEW_PIXEL; } + if (bufferID == 0) { + ctx->Pixel.ReadBuffer = buffer; + } + fb->ColorReadBuffer = buffer; + fb->_ColorReadBufferMask = srcMask; + + ctx->NewState |= _NEW_PIXEL; + /* * Call device driver function. */ if (ctx->Driver.ReadBuffer) - (*ctx->Driver.ReadBuffer)(ctx, mode); + (*ctx->Driver.ReadBuffer)(ctx, buffer); } @@ -524,53 +574,51 @@ _mesa_ReadBuffer( GLenum mode ) * \note This function may be called from within Mesa or called by the * user directly (see the GL_MESA_resize_buffers extension). */ +#if OLD_RENDERBUFFER +/* THIS FUNCTION IS OBSOLETE!!! + * See _mesa_resize_framebuffer + */ +#endif void GLAPIENTRY _mesa_ResizeBuffersMESA( void ) { GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glResizeBuffersMESA\n"); - if (ctx) { - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); - - if (ctx->DrawBuffer) { - GLuint buf_width, buf_height; - GLframebuffer *buffer = ctx->DrawBuffer; - - /* ask device driver for size of output buffer */ - (*ctx->Driver.GetBufferSize)( buffer, &buf_width, &buf_height ); + if (ctx->DrawBuffer && ctx->DrawBuffer->Name == 0) { + GLuint newWidth, newHeight; + GLframebuffer *buffer = ctx->DrawBuffer; - /* see if size of device driver's color buffer (window) has changed */ - if (buffer->Width == buf_width && buffer->Height == buf_height) - return; /* size is as expected */ + /* ask device driver for size of output buffer */ + ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); - buffer->Width = buf_width; - buffer->Height = buf_height; - - ctx->Driver.ResizeBuffers( buffer ); + /* see if size of device driver's color buffer (window) has changed */ + if (buffer->Width != newWidth || buffer->Height != newHeight) { + if (ctx->Driver.ResizeBuffers) + ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight ); } + } - if (ctx->ReadBuffer && ctx->ReadBuffer != ctx->DrawBuffer) { - GLuint buf_width, buf_height; - GLframebuffer *buffer = ctx->ReadBuffer; - - /* ask device driver for size of read buffer */ - (*ctx->Driver.GetBufferSize)( buffer, &buf_width, &buf_height ); - - /* see if size of device driver's color buffer (window) has changed */ - if (buffer->Width == buf_width && buffer->Height == buf_height) - return; /* size is as expected */ + if (ctx->ReadBuffer && ctx->ReadBuffer != ctx->DrawBuffer + && ctx->ReadBuffer->Name == 0) { + GLuint newWidth, newHeight; + GLframebuffer *buffer = ctx->ReadBuffer; - buffer->Width = buf_width; - buffer->Height = buf_height; + /* ask device driver for size of read buffer */ + ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); - ctx->Driver.ResizeBuffers( buffer ); + /* see if size of device driver's color buffer (window) has changed */ + if (buffer->Width != newWidth || buffer->Height != newHeight) { + if (ctx->Driver.ResizeBuffers) + ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight ); } - - ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ } + + ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ } @@ -642,56 +690,6 @@ _mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ) /**********************************************************************/ -/** \name State management */ -/*@{*/ - - -/** - * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields. - * These values are computed from the buffer's width and height and - * the scissor box, if it's enabled. - * \param ctx the GL context. - */ -void -_mesa_update_draw_buffer_bounds(GLcontext *ctx) -{ - GLframebuffer *buffer = ctx->DrawBuffer; - - buffer->_Xmin = 0; - buffer->_Ymin = 0; - buffer->_Xmax = buffer->Width; - buffer->_Ymax = buffer->Height; - - if (ctx->Scissor.Enabled) { - if (ctx->Scissor.X > buffer->_Xmin) { - buffer->_Xmin = ctx->Scissor.X; - } - if (ctx->Scissor.Y > buffer->_Ymin) { - buffer->_Ymin = ctx->Scissor.Y; - } - if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) { - buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width; - } - if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) { - buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height; - } - /* finally, check for empty region */ - if (buffer->_Xmin > buffer->_Xmax) { - buffer->_Xmin = buffer->_Xmax; - } - if (buffer->_Ymin > buffer->_Ymax) { - buffer->_Ymin = buffer->_Ymax; - } - } - - ASSERT(buffer->_Xmin <= buffer->_Xmax); - ASSERT(buffer->_Ymin <= buffer->_Ymax); -} - -/*@}*/ - - -/**********************************************************************/ /** \name Initialization */ /*@{*/ diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h index c436e6bf51..0c7f68ee79 100644 --- a/src/mesa/main/buffers.h +++ b/src/mesa/main/buffers.h @@ -52,6 +52,10 @@ _mesa_DrawBuffer( GLenum mode ); extern void GLAPIENTRY _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers); +extern void +_mesa_drawbuffers(GLcontext *ctx, GLsizei n, const GLenum *buffers, + const GLuint *destMask); + extern void GLAPIENTRY _mesa_ReadBuffer( GLenum mode ); @@ -65,9 +69,6 @@ extern void GLAPIENTRY _mesa_SampleCoverageARB(GLclampf value, GLboolean invert); extern void -_mesa_update_draw_buffer_bounds(GLcontext *ctx); - -extern void _mesa_init_scissor(GLcontext *ctx); extern void diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 801c10b081..456f8ce76a 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -71,7 +71,7 @@ /** Maximum pixel map lookup table size */ #define MAX_PIXEL_MAP_TABLE 256 -/** Maximum Number of auxillary color buffers */ +/** Maximum number of auxillary color buffers */ #define MAX_AUX_BUFFERS 4 /** Maximum order (degree) of curves */ @@ -223,7 +223,7 @@ /** For GL_EXT_framebuffer_object */ /*@{*/ -#define MAX_COLOR_ATTACHMENTS 4 +#define MAX_COLOR_ATTACHMENTS 8 /*@}*/ @@ -322,4 +322,9 @@ #define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1) +/* XXX these are temporary */ +#define NEW_RENDERBUFFER 1 +#define OLD_RENDERBUFFER 1 + + #endif /* CONFIG_H */ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 087cc64c33..eb2f2e0c81 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -91,6 +91,7 @@ #include "eval.h" #include "enums.h" #include "extensions.h" +#include "fbobject.h" #include "feedback.h" #include "fog.h" #include "get.h" @@ -492,13 +493,12 @@ _mesa_create_visual( GLboolean rgbFlag, /** * Makes some sanity checks and fills in the fields of the - * GLvisual structure with the given parameters. - * + * GLvisual object with the given parameters. If the caller needs + * to set additional fields, he should just probably init the whole GLvisual + * object himself. * \return GL_TRUE on success, or GL_FALSE on failure. * * \sa _mesa_create_visual() above for the parameter description. - * - * \note Need to add params for level and numAuxBuffers (at least) */ GLboolean _mesa_initialize_visual( GLvisual *vis, @@ -520,28 +520,22 @@ _mesa_initialize_visual( GLvisual *vis, { assert(vis); - /* This is to catch bad values from device drivers not updated for - * Mesa 3.3. Some device drivers just passed 1. That's a REALLY - * bad value now (a 1-bit depth buffer!?!). - */ - assert(depthBits == 0 || depthBits > 1); - if (depthBits < 0 || depthBits > 32) { return GL_FALSE; } - if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) { + if (stencilBits < 0 || stencilBits > STENCIL_BITS) { return GL_FALSE; } - if (accumRedBits < 0 || accumRedBits > (GLint) (8 * sizeof(GLaccum))) { + if (accumRedBits < 0 || accumRedBits > ACCUM_BITS) { return GL_FALSE; } - if (accumGreenBits < 0 || accumGreenBits > (GLint) (8 * sizeof(GLaccum))) { + if (accumGreenBits < 0 || accumGreenBits > ACCUM_BITS) { return GL_FALSE; } - if (accumBlueBits < 0 || accumBlueBits > (GLint) (8 * sizeof(GLaccum))) { + if (accumBlueBits < 0 || accumBlueBits > ACCUM_BITS) { return GL_FALSE; } - if (accumAlphaBits < 0 || accumAlphaBits > (GLint) (8 * sizeof(GLaccum))) { + if (accumAlphaBits < 0 || accumAlphaBits > ACCUM_BITS) { return GL_FALSE; } @@ -553,14 +547,16 @@ _mesa_initialize_visual( GLvisual *vis, vis->greenBits = greenBits; vis->blueBits = blueBits; vis->alphaBits = alphaBits; + vis->rgbBits = redBits + greenBits + blueBits; vis->indexBits = indexBits; vis->depthBits = depthBits; - vis->accumRedBits = (accumRedBits > 0) ? (8 * sizeof(GLaccum)) : 0; - vis->accumGreenBits = (accumGreenBits > 0) ? (8 * sizeof(GLaccum)) : 0; - vis->accumBlueBits = (accumBlueBits > 0) ? (8 * sizeof(GLaccum)) : 0; - vis->accumAlphaBits = (accumAlphaBits > 0) ? (8 * sizeof(GLaccum)) : 0; - vis->stencilBits = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0; + vis->stencilBits = stencilBits; + + vis->accumRedBits = accumRedBits; + vis->accumGreenBits = accumGreenBits; + vis->accumBlueBits = accumBlueBits; + vis->accumAlphaBits = accumAlphaBits; vis->haveAccumBuffer = accumRedBits > 0; vis->haveDepthBuffer = depthBits > 0; @@ -569,6 +565,7 @@ _mesa_initialize_visual( GLvisual *vis, vis->numAuxBuffers = 0; vis->level = 0; vis->pixmapMode = 0; + vis->sampleBuffers = numSamples > 0 ? 1 : 0; vis->samples = numSamples; return GL_TRUE; @@ -592,160 +589,6 @@ _mesa_destroy_visual( GLvisual *vis ) /**********************************************************************/ -/** \name GL Framebuffer allocation/destruction */ -/**********************************************************************/ -/*@{*/ - -/** - * Allocate a GLframebuffer structure and initializes it via - * _mesa_initialize_framebuffer(). - * - * A GLframebuffer is a structure which encapsulates the depth, stencil and - * accum buffers and related parameters. - * - * Note that the actual depth/stencil/accum/etc buffers are not allocated - * at this time. It's up to the device driver and/or swrast module to - * allocate them as needed. - * - * \param visual a GLvisual pointer (we copy the struct contents) - * \param softwareDepth create/use a software depth buffer? - * \param softwareStencil create/use a software stencil buffer? - * \param softwareAccum create/use a software accum buffer? - * \param softwareAlpha create/use a software alpha buffer? - * - * \return pointer to new GLframebuffer struct or NULL if error. - * - * \note Need to add softwareAuxBuffers parameter. - */ -GLframebuffer * -_mesa_create_framebuffer( const GLvisual *visual, - GLboolean softwareDepth, - GLboolean softwareStencil, - GLboolean softwareAccum, - GLboolean softwareAlpha ) -{ - GLframebuffer *buffer = CALLOC_STRUCT(gl_frame_buffer); - assert(visual); - if (buffer) { - _mesa_initialize_framebuffer(buffer, visual, - softwareDepth, softwareStencil, - softwareAccum, softwareAlpha ); - } - return buffer; -} - - -/** - * Makes some sanity checks and fills in the fields of the - * GLframebuffer structure with the given parameters. - * - * \sa _mesa_create_framebuffer() above for the parameter description. - */ -void -_mesa_initialize_framebuffer( GLframebuffer *buffer, - const GLvisual *visual, - GLboolean softwareDepth, - GLboolean softwareStencil, - GLboolean softwareAccum, - GLboolean softwareAlpha ) -{ - GLboolean softwareAux = GL_FALSE; - assert(buffer); - assert(visual); - - _mesa_bzero(buffer, sizeof(GLframebuffer)); - - /* sanity checks */ - if (softwareDepth ) { - assert(visual->depthBits > 0); - } - if (softwareStencil) { - assert(visual->stencilBits > 0); - } - if (softwareAccum) { - assert(visual->rgbMode); - assert(visual->accumRedBits > 0); - assert(visual->accumGreenBits > 0); - assert(visual->accumBlueBits > 0); - } - if (softwareAlpha) { - assert(visual->rgbMode); - assert(visual->alphaBits > 0); - } - - buffer->Visual = *visual; - buffer->UseSoftwareDepthBuffer = softwareDepth; - buffer->UseSoftwareStencilBuffer = softwareStencil; - buffer->UseSoftwareAccumBuffer = softwareAccum; - buffer->UseSoftwareAlphaBuffers = softwareAlpha; - buffer->UseSoftwareAuxBuffers = softwareAux; -} - - -/** - * Free a framebuffer struct and its buffers. - * - * Calls _mesa_free_framebuffer_data() and frees the structure. - */ -void -_mesa_destroy_framebuffer( GLframebuffer *buffer ) -{ - if (buffer) { - _mesa_free_framebuffer_data(buffer); - FREE(buffer); - } -} - - -/** - * Free the data hanging off of \p buffer, but not \p buffer itself. - * - * \param buffer framebuffer. - * - * Frees all the buffers associated with the structure. - */ -void -_mesa_free_framebuffer_data( GLframebuffer *buffer ) -{ - if (!buffer) - return; - - if (buffer->UseSoftwareDepthBuffer && buffer->DepthBuffer) { - MESA_PBUFFER_FREE( buffer->DepthBuffer ); - buffer->DepthBuffer = NULL; - } - if (buffer->UseSoftwareAccumBuffer && buffer->Accum) { - MESA_PBUFFER_FREE( buffer->Accum ); - buffer->Accum = NULL; - } - if (buffer->UseSoftwareStencilBuffer && buffer->Stencil) { - MESA_PBUFFER_FREE( buffer->Stencil ); - buffer->Stencil = NULL; - } - if (buffer->UseSoftwareAlphaBuffers){ - if (buffer->FrontLeftAlpha) { - MESA_PBUFFER_FREE( buffer->FrontLeftAlpha ); - buffer->FrontLeftAlpha = NULL; - } - if (buffer->BackLeftAlpha) { - MESA_PBUFFER_FREE( buffer->BackLeftAlpha ); - buffer->BackLeftAlpha = NULL; - } - if (buffer->FrontRightAlpha) { - MESA_PBUFFER_FREE( buffer->FrontRightAlpha ); - buffer->FrontRightAlpha = NULL; - } - if (buffer->BackRightAlpha) { - MESA_PBUFFER_FREE( buffer->BackRightAlpha ); - buffer->BackRightAlpha = NULL; - } - } -} - -/*@}*/ - - -/**********************************************************************/ /** \name Context allocation, initialization, destroying * * The purpose of the most initialization functions here is to provide the @@ -1552,6 +1395,8 @@ _mesa_initialize_context( GLcontext *ctx, ctx->Visual = *visual; ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; + ctx->WinSysDrawBuffer = NULL; + ctx->WinSysReadBuffer = NULL; /* Plug in driver functions and context pointer here. * This is important because when we call alloc_shared_state() below @@ -1662,7 +1507,7 @@ _mesa_free_context_data( GLcontext *ctx ) { /* if we're destroying the current context, unbind it first */ if (ctx == _mesa_get_current_context()) { - _mesa_make_current(NULL, NULL); + _mesa_make_current(NULL, NULL, NULL); } _mesa_free_lighting_data( ctx ); @@ -1878,20 +1723,6 @@ check_compatible(const GLcontext *ctx, const GLframebuffer *buffer) /** - * Set the current context, binding the given frame buffer to the context. - * - * \param newCtx new GL context. - * \param buffer framebuffer. - * - * Calls _mesa_make_current2() with \p buffer as read and write framebuffer. - */ -void -_mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) -{ - _mesa_make_current2( newCtx, buffer, buffer ); -} - -/** * Bind the given context to the given draw-buffer and read-buffer and * make it the current context for this thread. * @@ -1911,11 +1742,11 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) * troubleshooting. */ void -_mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, - GLframebuffer *readBuffer ) +_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ) { if (MESA_VERBOSE) - _mesa_debug(newCtx, "_mesa_make_current2()\n"); + _mesa_debug(newCtx, "_mesa_make_current()\n"); /* Check that the context's and framebuffer's visuals are compatible. */ @@ -1936,7 +1767,6 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); - if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ } @@ -1945,8 +1775,21 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, if (drawBuffer && readBuffer) { /* TODO: check if newCtx and buffer's visual match??? */ + +#if NEW_RENDERBUFFER + ASSERT(drawBuffer->Name == 0); + ASSERT(readBuffer->Name == 0); + newCtx->WinSysDrawBuffer = drawBuffer; + newCtx->WinSysReadBuffer = readBuffer; + /* don't replace user-buffer bindings with window system buffer */ + if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { + newCtx->DrawBuffer = drawBuffer; + newCtx->ReadBuffer = readBuffer; + } +#else newCtx->DrawBuffer = drawBuffer; newCtx->ReadBuffer = readBuffer; +#endif newCtx->NewState |= _NEW_BUFFERS; #if _HAVE_FULL_GL @@ -1956,9 +1799,9 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, /* ask device driver for size of the buffer */ (*newCtx->Driver.GetBufferSize)(drawBuffer, &bufWidth, &bufHeight); /* set initial buffer size */ - drawBuffer->Width = bufWidth; - drawBuffer->Height = bufHeight; - newCtx->Driver.ResizeBuffers( drawBuffer ); + if (newCtx->Driver.ResizeBuffers) + newCtx->Driver.ResizeBuffers(newCtx, drawBuffer, + bufWidth, bufHeight); drawBuffer->Initialized = GL_TRUE; } @@ -1968,9 +1811,9 @@ _mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, /* ask device driver for size of the buffer */ (*newCtx->Driver.GetBufferSize)(readBuffer, &bufWidth, &bufHeight); /* set initial buffer size */ - readBuffer->Width = bufWidth; - readBuffer->Height = bufHeight; - newCtx->Driver.ResizeBuffers( readBuffer ); + if (newCtx->Driver.ResizeBuffers) + newCtx->Driver.ResizeBuffers(newCtx, readBuffer, + bufWidth, bufHeight); readBuffer->Initialized = GL_TRUE; } #endif diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index 4b041edc6d..8b7e7c9952 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -99,34 +99,6 @@ _mesa_destroy_visual( GLvisual *vis ); /**********************************************************************/ -/** \name Create/destroy a GLframebuffer. */ -/*@{*/ - -extern GLframebuffer * -_mesa_create_framebuffer( const GLvisual *visual, - GLboolean softwareDepth, - GLboolean softwareStencil, - GLboolean softwareAccum, - GLboolean softwareAlpha ); - -extern void -_mesa_initialize_framebuffer( GLframebuffer *fb, - const GLvisual *visual, - GLboolean softwareDepth, - GLboolean softwareStencil, - GLboolean softwareAccum, - GLboolean softwareAlpha ); - -extern void -_mesa_free_framebuffer_data( GLframebuffer *buffer ); - -extern void -_mesa_destroy_framebuffer( GLframebuffer *buffer ); - -/*@}*/ - - -/**********************************************************************/ /** \name Create/destroy a GLcontext. */ /*@{*/ @@ -155,12 +127,8 @@ _mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask); extern void -_mesa_make_current( GLcontext *ctx, GLframebuffer *buffer ); - - -extern void -_mesa_make_current2( GLcontext *ctx, GLframebuffer *drawBuffer, - GLframebuffer *readBuffer ); +_mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); extern GLboolean _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 1d9d366014..3746e4685c 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -75,12 +75,10 @@ struct dd_function_table { GLuint *width, GLuint *height ); /** - * Resize the driver's depth/stencil/accum/back buffers to match the - * size given in the GLframebuffer struct. - * - * This is typically called when Mesa detects that a window size has changed. + * Resize the given framebuffer to the given size. */ - void (*ResizeBuffers)( GLframebuffer *buffer ); + void (*ResizeBuffers)( GLcontext *ctx, GLframebuffer *fb, + GLuint width, GLuint height); /** * Called whenever an error is generated. @@ -795,6 +793,13 @@ struct dd_function_table { /*@{*/ struct gl_framebuffer * (*NewFramebuffer)(GLcontext *ctx, GLuint name); struct gl_renderbuffer * (*NewRenderbuffer)(GLcontext *ctx, GLuint name); + void (*FramebufferRenderbuffer)(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_renderbuffer *rb); + void (*RenderbufferTexture)(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_texture_object *texObj, + GLenum texTarget, GLuint level, GLuint zoffset); /*@}*/ #endif diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index 6c60222096..aca471a06c 100644 --- a/src/mesa/main/depth.c +++ b/src/mesa/main/depth.c @@ -162,13 +162,15 @@ void _mesa_init_depth( GLcontext * ctx ) ctx->Depth.Mask = GL_TRUE; ctx->Depth.OcclusionTest = GL_FALSE; + /* XXX this is now per-framebuffer state */ +#if 00 /* Z buffer stuff */ if (ctx->Visual.depthBits == 0) { /* Special case. Even if we don't have a depth buffer we need * good values for DepthMax for Z vertex transformation purposes * and for per-fragment fog computation. */ - ctx->DepthMax = 1 << 16; + ctx->DepthMax = (1 << 16) - 1; ctx->DepthMaxF = (GLfloat) ctx->DepthMax; } else if (ctx->Visual.depthBits < 32) { @@ -183,4 +185,5 @@ void _mesa_init_depth( GLcontext * ctx ) ctx->DepthMaxF = (GLfloat) ctx->DepthMax; } ctx->MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */ +#endif } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index effdb7702a..2541d5c4af 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -2850,7 +2850,8 @@ static void GLAPIENTRY save_PolygonOffset( GLfloat factor, GLfloat units ) static void GLAPIENTRY save_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) { GET_CURRENT_CONTEXT(ctx); - save_PolygonOffset(factor, ctx->DepthMaxF * bias); + /* XXX mult by DepthMaxF here??? */ + save_PolygonOffset(factor, ctx->DrawBuffer->_DepthMaxF * bias); } @@ -7422,14 +7423,6 @@ static void GLAPIENTRY exec_UnlockArraysEXT( void ) ctx->Exec->UnlockArraysEXT( ); } -static void GLAPIENTRY exec_ResizeBuffersMESA( void ) -{ - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - ctx->Exec->ResizeBuffersMESA( ); -} - - static void GLAPIENTRY exec_ClientActiveTextureARB( GLenum target ) { GET_CURRENT_CONTEXT(ctx); @@ -7847,7 +7840,7 @@ _mesa_init_dlist_table( struct _glapi_table *table ) table->BlendFuncSeparateEXT = save_BlendFuncSeparateEXT; /* 196. GL_MESA_resize_buffers */ - table->ResizeBuffersMESA = exec_ResizeBuffersMESA; + table->ResizeBuffersMESA = _mesa_ResizeBuffersMESA; /* 197. GL_MESA_window_pos */ table->WindowPos2dMESA = save_WindowPos2dMESA; diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index f53ae05d17..671db68ce8 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -301,7 +301,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_DEPTH_TEST: - if (state && ctx->Visual.depthBits==0) { + if (state && ctx->DrawBuffer->Visual.depthBits == 0) { _mesa_warning(ctx,"glEnable(GL_DEPTH_TEST) but no depth buffer"); return; } @@ -575,7 +575,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) ctx->Texture.SharedPalette = state; break; case GL_STENCIL_TEST: - if (state && ctx->Visual.stencilBits==0) { + if (state && ctx->DrawBuffer->Visual.stencilBits == 0) { _mesa_warning(ctx, "glEnable(GL_STENCIL_TEST) but no stencil buffer"); return; @@ -591,7 +591,8 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) GLuint newenabled = texUnit->Enabled & ~TEXTURE_1D_BIT; if (state) newenabled |= TEXTURE_1D_BIT; - if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + if (!ctx->DrawBuffer->Visual.rgbMode + || texUnit->Enabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Enabled = newenabled; @@ -603,7 +604,8 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) GLuint newenabled = texUnit->Enabled & ~TEXTURE_2D_BIT; if (state) newenabled |= TEXTURE_2D_BIT; - if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + if (!ctx->DrawBuffer->Visual.rgbMode + || texUnit->Enabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Enabled = newenabled; @@ -615,7 +617,8 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) GLuint newenabled = texUnit->Enabled & ~TEXTURE_3D_BIT; if (state) newenabled |= TEXTURE_3D_BIT; - if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + if (!ctx->DrawBuffer->Visual.rgbMode + || texUnit->Enabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Enabled = newenabled; @@ -777,7 +780,8 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) CHECK_EXTENSION(ARB_texture_cube_map, cap); if (state) newenabled |= TEXTURE_CUBE_BIT; - if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + if (!ctx->DrawBuffer->Visual.rgbMode + || texUnit->Enabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Enabled = newenabled; @@ -938,7 +942,8 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) CHECK_EXTENSION(NV_texture_rectangle, cap); if (state) newenabled |= TEXTURE_RECT_BIT; - if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + if (!ctx->DrawBuffer->Visual.rgbMode + || texUnit->Enabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Enabled = newenabled; @@ -972,7 +977,7 @@ void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) /* GL_EXT_depth_bounds_test */ case GL_DEPTH_BOUNDS_TEST_EXT: CHECK_EXTENSION(EXT_depth_bounds_test, cap); - if (state && ctx->Visual.depthBits==0) { + if (state && ctx->DrawBuffer->Visual.depthBits == 0) { _mesa_warning(ctx, "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer"); return; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 5bbceb5ab7..150492e7c3 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -227,7 +227,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) ctx->Extensions.EXT_convolution = GL_TRUE; ctx->Extensions.EXT_depth_bounds_test = GL_TRUE; ctx->Extensions.EXT_fog_coord = GL_TRUE; - /*ctx->Extensions.EXT_framebuffer_object = GL_TRUE;*/ + ctx->Extensions.EXT_framebuffer_object = GL_TRUE; /*FALSE;*/ ctx->Extensions.EXT_histogram = GL_TRUE; ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE; ctx->Extensions.EXT_paletted_texture = GL_TRUE; diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 3480beaa47..beaf4ed942 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -31,7 +31,9 @@ #include "context.h" #include "fbobject.h" +#include "framebuffer.h" #include "hash.h" +#include "renderbuffer.h" #include "teximage.h" #include "texstore.h" @@ -95,103 +97,6 @@ lookup_framebuffer(GLcontext *ctx, GLuint id) /** - * Allocate a new gl_framebuffer. - * This is the default function for ctx->Driver.NewFramebuffer(). - */ -struct gl_framebuffer * -_mesa_new_framebuffer(GLcontext *ctx, GLuint name) -{ - struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer); - if (fb) { - fb->Name = name; - fb->RefCount = 1; - fb->Delete = _mesa_delete_framebuffer; - } - return fb; -} - - -/** - * Delete a gl_framebuffer. - * This is the default function for framebuffer->Delete(). - */ -void -_mesa_delete_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) -{ - (void) ctx; - _mesa_free(fb); -} - - -/** - * Allocate the actual storage for a renderbuffer with the given format - * and dimensions. - * This is the default function for gl_renderbuffer->AllocStorage(). - * All incoming parameters will have already been checked for errors. - * If memory allocate fails, the function must call - * _mesa_error(GL_OUT_OF_MEMORY) and then return. - * \return GL_TRUE for success, GL_FALSE for failure. - */ -static GLboolean -alloc_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, GLuint width, GLuint height) -{ - /* First, free any existing storage */ - if (rb->Data) { - _mesa_free(rb->Data); - } - - /* Now, allocate new storage */ - rb->Data = _mesa_malloc(width * height * 4); /* XXX fix size! */ - if (rb->Data == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRenderbufferStorageEXT"); - return GL_FALSE; - } - - /* We set these fields now if the allocation worked */ - rb->Width = width; - rb->Height = height; - rb->InternalFormat = internalFormat; - - return GL_TRUE; -} - - -/** - * Allocate a new gl_renderbuffer. - * This is the default function for ctx->Driver.NewRenderbuffer(). - */ -struct gl_renderbuffer * -_mesa_new_renderbuffer(GLcontext *ctx, GLuint name) -{ - struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); - if (rb) { - rb->Name = name; - rb->RefCount = 1; - rb->Delete = _mesa_delete_renderbuffer; - rb->AllocStorage = alloc_renderbuffer_storage; - /* other fields are zero */ - } - return rb; -} - - -/** - * Delete a gl_framebuffer. - * This is the default function for framebuffer->Delete(). - */ -void -_mesa_delete_renderbuffer(GLcontext *ctx, struct gl_renderbuffer *rb) -{ - (void) ctx; - if (rb->Data) { - _mesa_free(rb->Data); - } - _mesa_free(rb); -} - - -/** * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding * gl_renderbuffer_attachment object. */ @@ -221,11 +126,11 @@ get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, GLenum attachment) if (i >= ctx->Const.MaxColorAttachments) { return NULL; } - return &fb->ColorAttachment[i]; + return &fb->Attachment[BUFFER_COLOR0 + i]; case GL_DEPTH_ATTACHMENT_EXT: - return &fb->DepthAttachment; + return &fb->Attachment[BUFFER_DEPTH]; case GL_STENCIL_ATTACHMENT_EXT: - return &fb->StencilAttachment; + return &fb->Attachment[BUFFER_STENCIL]; default: return NULL; } @@ -236,12 +141,17 @@ get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, GLenum attachment) * Remove any texture or renderbuffer attached to the given attachment * point. Update reference counts, etc. */ -static void -remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) +void +_mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) { if (att->Type == GL_TEXTURE) { ASSERT(att->Texture); - ASSERT(!att->Renderbuffer); + if (att->Renderbuffer) { + /* delete/remove the 'wrapper' renderbuffer */ + /* XXX do we really want to do this??? */ + att->Renderbuffer->Delete(att->Renderbuffer); + att->Renderbuffer = NULL; + } att->Texture->RefCount--; if (att->Texture->RefCount == 0) { ctx->Driver.DeleteTexture(ctx, att->Texture); @@ -253,7 +163,7 @@ remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) ASSERT(!att->Texture); att->Renderbuffer->RefCount--; if (att->Renderbuffer->RefCount == 0) { - att->Renderbuffer->Delete(ctx, att->Renderbuffer); + att->Renderbuffer->Delete(att->Renderbuffer); } att->Renderbuffer = NULL; } @@ -266,13 +176,13 @@ remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) * Bind a texture object to an attachment point. * The previous binding, if any, will be removed first. */ -static void -set_texture_attachment(GLcontext *ctx, - struct gl_renderbuffer_attachment *att, - struct gl_texture_object *texObj, - GLenum texTarget, GLuint level, GLuint zoffset) +void +_mesa_set_texture_attachment(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_texture_object *texObj, + GLenum texTarget, GLuint level, GLuint zoffset) { - remove_attachment(ctx, att); + _mesa_remove_attachment(ctx, att); att->Type = GL_TEXTURE; att->Texture = texObj; att->TextureLevel = level; @@ -284,6 +194,7 @@ set_texture_attachment(GLcontext *ctx, } att->Zoffset = zoffset; att->Complete = GL_FALSE; + texObj->RefCount++; /* XXX when we attach to a texture, we should probably set the @@ -297,12 +208,12 @@ set_texture_attachment(GLcontext *ctx, * Bind a renderbuffer to an attachment point. * The previous binding, if any, will be removed first. */ -static void -set_renderbuffer_attachment(GLcontext *ctx, - struct gl_renderbuffer_attachment *att, - struct gl_renderbuffer *rb) +void +_mesa_set_renderbuffer_attachment(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_renderbuffer *rb) { - remove_attachment(ctx, att); + _mesa_remove_attachment(ctx, att); att->Type = GL_RENDERBUFFER_EXT; att->Renderbuffer = rb; att->Texture = NULL; /* just to be safe */ @@ -312,6 +223,26 @@ set_renderbuffer_attachment(GLcontext *ctx, /** + * Fallback for ctx->Driver.FramebufferRenderbuffer() + * Sets a framebuffer attachment to a particular renderbuffer. + * The framebuffer in question is ctx->DrawBuffer. + * \sa _mesa_renderbuffer_texture + */ +void +_mesa_framebuffer_renderbuffer(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_renderbuffer *rb) +{ + if (rb) { + _mesa_set_renderbuffer_attachment(ctx, att, rb); + } + else { + _mesa_remove_attachment(ctx, att); + } +} + + +/** * Test if an attachment point is complete and update its Complete field. * \param format if GL_COLOR, this is a color attachment point, * if GL_DEPTH, this is a depth component attachment point, @@ -326,15 +257,15 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, /* assume complete */ att->Complete = GL_TRUE; - if (att->Type == GL_NONE) - return; /* complete */ - /* Look for reasons why the attachment might be incomplete */ if (att->Type == GL_TEXTURE) { - struct gl_texture_object *texObj = att->Texture; + const struct gl_texture_object *texObj = att->Texture; struct gl_texture_image *texImage; - assert(texObj); + if (!texObj) { + att->Complete = GL_FALSE; + return; + } texImage = texObj->Image[att->CubeMapFace][att->TextureLevel]; if (!texImage) { @@ -351,13 +282,14 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, } if (format == GL_COLOR) { - if (texImage->Format != GL_RGB && texImage->Format != GL_RGBA) { + if (texImage->TexFormat->BaseFormat != GL_RGB && + texImage->TexFormat->BaseFormat != GL_RGBA) { att->Complete = GL_FALSE; return; } } else if (format == GL_DEPTH) { - if (texImage->Format != GL_DEPTH_COMPONENT) { + if (texImage->TexFormat->BaseFormat != GL_DEPTH_COMPONENT) { att->Complete = GL_FALSE; return; } @@ -368,9 +300,7 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, return; } } - else { - assert(att->Type == GL_RENDERBUFFER_EXT); - + else if (att->Type == GL_RENDERBUFFER_EXT) { if (att->Renderbuffer->Width < 1 || att->Renderbuffer->Height < 1) { att->Complete = GL_FALSE; return; @@ -396,53 +326,58 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format, } } } + else { + ASSERT(att->Type == GL_NONE); + /* complete */ + return; + } } /** * Test if the given framebuffer object is complete and update its * Status field with the results. + * Also update the framebuffer's Width and Height fields if the + * framebuffer is complete. */ -static void -test_framebuffer_completeness(GLcontext *ctx, - struct gl_framebuffer *fb) +void +_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb) { - GLint i; GLuint numImages, width = 0, height = 0; GLenum intFormat = GL_NONE; - - /* Set to COMPLETE status, then try to find reasons for being incomplete */ - fb->Status = GL_FRAMEBUFFER_COMPLETE_EXT; + GLuint w = 0, h = 0; + GLint i; numImages = 0; + fb->Width = 0; + fb->Height = 0; /* Start at -2 to more easily loop over all attachment points */ - for (i = -2; i < ctx->Const.MaxColorAttachments; i++) { + for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) { struct gl_renderbuffer_attachment *att; - GLuint w, h; GLenum f; if (i == -2) { - att = &fb->DepthAttachment; + att = &fb->Attachment[BUFFER_DEPTH]; test_attachment_completeness(ctx, GL_DEPTH, att); if (!att->Complete) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; return; } } else if (i == -1) { - att = &fb->StencilAttachment; + att = &fb->Attachment[BUFFER_STENCIL]; test_attachment_completeness(ctx, GL_STENCIL, att); if (!att->Complete) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; return; } } else { - att = &fb->ColorAttachment[i]; + att = &fb->Attachment[BUFFER_COLOR0 + i]; test_attachment_completeness(ctx, GL_COLOR, att); if (!att->Complete) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT; return; } } @@ -474,57 +409,63 @@ test_framebuffer_completeness(GLcontext *ctx, else { /* check that width, height, format are same */ if (w != width || h != height) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT; return; } - if (i >= 0 && f != intFormat) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT; + if (intFormat != GL_NONE && f != intFormat) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT; return; } - } } /* Check that all DrawBuffers are present */ for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - if (fb->DrawBuffer[i] != GL_NONE) { - struct gl_renderbuffer_attachment *att - = get_attachment(ctx, fb, fb->DrawBuffer[i]); + if (fb->ColorDrawBuffer[i] != GL_NONE) { + const struct gl_renderbuffer_attachment *att + = get_attachment(ctx, fb, fb->ColorDrawBuffer[i]); + assert(att); if (att->Type == GL_NONE) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; return; } } } /* Check that the ReadBuffer is present */ - if (fb->ReadBuffer != GL_NONE) { - struct gl_renderbuffer_attachment *att - = get_attachment(ctx, fb, fb->ReadBuffer); + if (fb->ColorReadBuffer != GL_NONE) { + const struct gl_renderbuffer_attachment *att + = get_attachment(ctx, fb, fb->ColorReadBuffer); + assert(att); if (att->Type == GL_NONE) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; return; } } if (numImages == 0) { - fb->Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT; + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT; return; } -} + /* + * If we get here, the framebuffer is complete! + */ + fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; + fb->Width = w; + fb->Height = h; +} GLboolean GLAPIENTRY _mesa_IsRenderbufferEXT(GLuint renderbuffer) { - const struct gl_renderbuffer *rb; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - - rb = lookup_renderbuffer(ctx, renderbuffer); - return rb ? GL_TRUE : GL_FALSE; + if (renderbuffer && lookup_renderbuffer(ctx, renderbuffer)) + return GL_TRUE; + else + return GL_FALSE; } @@ -535,6 +476,7 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); if (target != GL_RENDERBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, @@ -568,7 +510,7 @@ _mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer) if (oldRb) { oldRb->RefCount--; if (oldRb->RefCount == 0) { - oldRb->Delete(ctx, oldRb); + oldRb->Delete(oldRb); } } @@ -600,7 +542,7 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) */ rb->RefCount--; if (rb->RefCount == 0) { - rb->Delete(ctx, rb); + rb->Delete(rb); } } } @@ -694,6 +636,7 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); if (target != GL_RENDERBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, "glRenderbufferStorageEXT(target)"); @@ -741,6 +684,9 @@ _mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, rb->_BaseFormat = GL_NONE; } + /* + test_framebuffer_completeness(ctx, fb); + */ /* XXX if this renderbuffer is attached anywhere, invalidate attachment * points??? */ @@ -787,23 +733,23 @@ _mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params) GLboolean GLAPIENTRY _mesa_IsFramebufferEXT(GLuint framebuffer) { - const struct gl_framebuffer *fb; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - - fb = lookup_framebuffer(ctx, framebuffer); - return fb ? GL_TRUE : GL_FALSE; + if (framebuffer && lookup_framebuffer(ctx, framebuffer)) + return GL_TRUE; + else + return GL_FALSE; } void GLAPIENTRY _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) { - struct gl_framebuffer *newFb, *oldFb; + struct gl_framebuffer *newFb, *newReadFb, *oldFb; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); if (target != GL_FRAMEBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, @@ -812,6 +758,7 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) } if (framebuffer) { + /* Binding a user-created framebuffer object */ newFb = lookup_framebuffer(ctx, framebuffer); if (newFb == &DummyFramebuffer) { /* ID was reserved, but no real framebuffer object made yet */ @@ -827,22 +774,29 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb); } newFb->RefCount++; + newReadFb = newFb; } else { - newFb = NULL; + /* Binding the window system framebuffer (which was originally set + * with MakeCurrent). + */ + newFb = ctx->WinSysDrawBuffer; + newReadFb = ctx->WinSysReadBuffer; } - oldFb = ctx->CurrentFramebuffer; - if (oldFb) { + oldFb = ctx->DrawBuffer; + if (oldFb) { /* AND oldFb->Name != 0 */ oldFb->RefCount--; if (oldFb->RefCount == 0) { - oldFb->Delete(ctx, oldFb); + oldFb->Delete(oldFb); } } ASSERT(newFb != &DummyFramebuffer); - ctx->CurrentFramebuffer = newFb; + /* Note, we set both the GL_DRAW_BUFFER and GL_READ_BUFFER state: */ + ctx->DrawBuffer = newFb; + ctx->ReadBuffer = newReadFb; } @@ -859,6 +813,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) struct gl_framebuffer *fb; fb = lookup_framebuffer(ctx, framebuffers[i]); if (fb) { + ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]); /* remove from hash table immediately, to free the ID */ _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]); @@ -868,7 +823,7 @@ _mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) */ fb->RefCount--; if (fb->RefCount == 0) { - fb->Delete(ctx, fb); + fb->Delete(fb); } } } @@ -913,20 +868,20 @@ _mesa_CheckFramebufferStatusEXT(GLenum target) { GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FRAMEBUFFER_STATUS_ERROR_EXT); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); if (target != GL_FRAMEBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)"); - return GL_FRAMEBUFFER_STATUS_ERROR_EXT; + return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */ } - if (!ctx->CurrentFramebuffer) { + if (ctx->DrawBuffer->Name == 0) { /* The window system / default framebuffer is always complete */ return GL_FRAMEBUFFER_COMPLETE_EXT; } - test_framebuffer_completeness(ctx, ctx->CurrentFramebuffer); - return ctx->CurrentFramebuffer->Status; + _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer); + return ctx->DrawBuffer->_Status; } @@ -948,13 +903,14 @@ error_check_framebuffer_texture(GLcontext *ctx, GLuint dims, return GL_TRUE; } - if (ctx->CurrentFramebuffer == NULL) { + /* check framebuffer binding */ + if (ctx->DrawBuffer->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferTexture%dDEXT", dims); return GL_TRUE; } - /* only check textarget, level if texture ID is non-zero*/ + /* only check textarget, level if texture ID is non-zero */ if (texture) { if ((dims == 1 && textarget != GL_TEXTURE_1D) || (dims == 3 && textarget != GL_TEXTURE_3D) || @@ -982,9 +938,11 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { struct gl_renderbuffer_attachment *att; + struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); /* XXX check */ if (error_check_framebuffer_texture(ctx, 1, target, attachment, textarget, texture, level)) @@ -992,7 +950,7 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment, ASSERT(textarget == GL_TEXTURE_1D); - att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment); + att = get_attachment(ctx, ctx->DrawBuffer, attachment); if (att == NULL) { _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferTexture1DEXT(attachment)"); @@ -1000,7 +958,7 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment, } if (texture) { - struct gl_texture_object *texObj = (struct gl_texture_object *) + texObj = (struct gl_texture_object *) _mesa_HashLookup(ctx->Shared->TexObjects, texture); if (!texObj) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -1012,13 +970,12 @@ _mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment, "glFramebufferTexture1DEXT(texture target)"); return; } - set_texture_attachment(ctx, att, texObj, textarget, level, 0); } else { - remove_attachment(ctx, att); + /* remove texture attachment */ + texObj = NULL; } - - /* XXX call a driver function to signal new attachment? */ + ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0); } @@ -1027,9 +984,11 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { struct gl_renderbuffer_attachment *att; + struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); /* XXX check */ if (error_check_framebuffer_texture(ctx, 2, target, attachment, textarget, texture, level)) @@ -1039,7 +998,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment, textarget == GL_TEXTURE_RECTANGLE_ARB || IS_CUBE_FACE(textarget)); - att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment); + att = get_attachment(ctx, ctx->DrawBuffer, attachment); if (att == NULL) { _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferTexture2DEXT(attachment)"); @@ -1047,7 +1006,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment, } if (texture) { - struct gl_texture_object *texObj = (struct gl_texture_object *) + texObj = (struct gl_texture_object *) _mesa_HashLookup(ctx->Shared->TexObjects, texture); if (!texObj) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -1063,12 +1022,12 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment, "glFramebufferTexture2DEXT(texture target)"); return; } - set_texture_attachment(ctx, att, texObj, textarget, level, 0); } else { - remove_attachment(ctx, att); + /* remove texture attachment */ + texObj = NULL; } - + ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0); } @@ -1078,9 +1037,11 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment, GLint level, GLint zoffset) { struct gl_renderbuffer_attachment *att; + struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); /* XXX check */ if (error_check_framebuffer_texture(ctx, 3, target, attachment, textarget, texture, level)) @@ -1088,7 +1049,7 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment, ASSERT(textarget == GL_TEXTURE_3D); - att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment); + att = get_attachment(ctx, ctx->DrawBuffer, attachment); if (att == NULL) { _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferTexture1DEXT(attachment)"); @@ -1097,7 +1058,7 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment, if (texture) { const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); - struct gl_texture_object *texObj = (struct gl_texture_object *) + texObj = (struct gl_texture_object *) _mesa_HashLookup(ctx->Shared->TexObjects, texture); if (!texObj) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -1114,11 +1075,13 @@ _mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment, "glFramebufferTexture3DEXT(zoffset)"); return; } - set_texture_attachment(ctx, att, texObj, textarget, level, zoffset); } else { - remove_attachment(ctx, att); + /* remove texture attachment */ + texObj = NULL; } + ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, + level, zoffset); } @@ -1128,9 +1091,11 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLuint renderbuffer) { struct gl_renderbuffer_attachment *att; + struct gl_renderbuffer *rb; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, _NEW_BUFFERS); if (target != GL_FRAMEBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, @@ -1139,17 +1104,17 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, } if (renderbufferTarget != GL_RENDERBUFFER_EXT) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glFramebufferRenderbufferEXT(renderbufferTarget)"); + _mesa_error(ctx, GL_INVALID_ENUM, + "glFramebufferRenderbufferEXT(renderbufferTarget)"); return; } - if (ctx->CurrentFramebuffer == NULL) { + if (ctx->DrawBuffer->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT"); return; } - att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment); + att = get_attachment(ctx, ctx->DrawBuffer, attachment); if (att == NULL) { _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferRenderbufferEXT(attachment)"); @@ -1157,18 +1122,22 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, } if (renderbuffer) { - struct gl_renderbuffer *rb; rb = lookup_renderbuffer(ctx, renderbuffer); if (!rb) { - _mesa_error(ctx, GL_INVALID_VALUE, + _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT(renderbuffer)"); return; } - set_renderbuffer_attachment(ctx, att, rb); } else { - remove_attachment(ctx, att); + /* remove renderbuffer attachment */ + rb = NULL; } + + assert(ctx->Driver.FramebufferRenderbuffer); + ctx->Driver.FramebufferRenderbuffer(ctx, att, rb); + + _mesa_update_framebuffer_visual(ctx->DrawBuffer); } @@ -1187,13 +1156,13 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, return; } - if (ctx->CurrentFramebuffer == NULL) { + if (ctx->DrawBuffer->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetFramebufferAttachmentParameterivEXT"); return; } - att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment); + att = get_attachment(ctx, ctx->DrawBuffer, attachment); if (att == NULL) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetFramebufferAttachmentParameterivEXT(attachment)"); diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h index 0241da2efc..2c86ef9372 100644 --- a/src/mesa/main/fbobject.h +++ b/src/mesa/main/fbobject.h @@ -27,137 +27,28 @@ #define FBOBJECT_H -/** - * A renderbuffer stores colors or depth values or stencil values. - * A framebuffer object will have a collection of these. - * Data are read/written to the buffer with a handful of Get/Put functions. - * - * Instances of this object are allocated with the Driver's NewRenderbuffer - * hook. Drivers will likely wrap this class inside a driver-specific - * class to simulate inheritance. - */ -struct gl_renderbuffer -{ - GLuint Name; - GLint RefCount; - GLuint Width, Height; - GLenum InternalFormat; - GLenum _BaseFormat; /* Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or */ - /* GL_STENCIL_INDEX. */ - - GLenum DataType; /* GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, etc */ - GLvoid *Data; - - /* Delete this renderbuffer */ - void (*Delete)(GLcontext *ctx, struct gl_renderbuffer *rb); - - /* Allocate new storage for this renderbuffer */ - GLboolean (*AllocStorage)(GLcontext *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height); - - /* Return a pointer to the element/pixel at (x,y). - * Should return NULL if the buffer memory can't be directly addressed. - */ - void *(*GetPointer)(struct gl_renderbuffer *rb, GLint x, GLint y); - - /* Get/Read a row of values. - * The values will be of format _BaseFormat and type DataType. - */ - void (*GetRow)(struct gl_renderbuffer *rb, - GLint x, GLint y, GLuint count, void *values); - - /* Get/Read values at arbitrary locations - * The values will be of format _BaseFormat and type DataType. - */ - void (*GetValues)(struct gl_renderbuffer *rb, - const GLint x[], const GLint y[], - GLuint count, void *values); - - /* Put/Write a row of values - * The values will be of format _BaseFormat and type DataType. - */ - void (*PutRow)(struct gl_renderbuffer *rb, - GLint x, GLint y, GLuint count, - const void *values, const GLubyte *maek); - - /* Put/Write values at arbitrary locations - * The values will be of format _BaseFormat and type DataType. - */ - void (*PutValues)(struct gl_renderbuffer *rb, - const GLint x[], const GLint y[], GLuint count, - const void *values, const GLubyte *mask); -}; - - -/** - * A renderbuffer attachment point points to either a texture object - * (and specifies a mipmap level, cube face or 3D texture slice) or - * points to a renderbuffer. - */ -struct gl_renderbuffer_attachment -{ - GLenum Type; /* GL_NONE or GL_TEXTURE or GL_RENDERBUFFER_EXT */ - GLboolean Complete; - - /* IF Type == GL_RENDERBUFFER_EXT: */ - struct gl_renderbuffer *Renderbuffer; - - /* IF Type == GL_TEXTURE: */ - struct gl_texture_object *Texture; - GLuint TextureLevel; - GLuint CubeMapFace; /* 0 .. 5, for cube map textures */ - GLuint Zoffset; /* for 3D textures */ -}; - - -/** - * A framebuffer object is basically a collection of rendering buffers. - * (Though, a rendering buffer might actually be a texture image.) - * All the renderbuffers/textures which we reference must have the same - * width and height (and meet a few other requirements) in order for the - * framebufffer object to be "complete". - * - * Instances of this object are allocated with the Driver's Newframebuffer - * hook. Drivers will likely wrap this class inside a driver-specific - * class to simulate inheritance. - */ -struct gl_framebuffer -{ - GLuint Name; - GLint RefCount; - - GLenum Status; /* One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */ - - struct gl_renderbuffer_attachment ColorAttachment[MAX_COLOR_ATTACHMENTS]; - struct gl_renderbuffer_attachment DepthAttachment; - struct gl_renderbuffer_attachment StencilAttachment; - - /* In unextended OpenGL, these vars are part of the GL_COLOR_BUFFER - * attribute group and GL_PIXEL attribute group, respectively. - */ - GLenum DrawBuffer[MAX_DRAW_BUFFERS]; - GLenum ReadBuffer; - - GLuint _Width, _Height; - - /** Delete this framebuffer */ - void (*Delete)(GLcontext *ctx, struct gl_framebuffer *fb); -}; - - -extern struct gl_framebuffer * -_mesa_new_framebuffer(GLcontext *ctx, GLuint name); +extern void +_mesa_remove_attachment(GLcontext *ctx, + struct gl_renderbuffer_attachment *att); extern void -_mesa_delete_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb); +_mesa_set_texture_attachment(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_texture_object *texObj, + GLenum texTarget, GLuint level, GLuint zoffset); -extern struct gl_renderbuffer * -_mesa_new_renderbuffer(GLcontext *ctx, GLuint name); +extern void +_mesa_set_renderbuffer_attachment(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_renderbuffer *rb); extern void -_mesa_delete_renderbuffer(GLcontext *ctx, struct gl_renderbuffer *rb); +_mesa_framebuffer_renderbuffer(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_renderbuffer *rb); +extern void +_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb); extern GLboolean GLAPIENTRY _mesa_IsRenderbufferEXT(GLuint renderbuffer); diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c new file mode 100644 index 0000000000..c23c60948c --- /dev/null +++ b/src/mesa/main/framebuffer.c @@ -0,0 +1,513 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Functions for allocating/managing framebuffers and renderbuffers. + * Also, routines for reading/writing renderbuffer data as ubytes, + * ushorts, uints, etc. + */ + + +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "mtypes.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "renderbuffer.h" + + + +/** + * Compute/set the _DepthMax field for the given framebuffer. + * This value depends on the Z buffer resolution. + */ +static void +compute_depth_max(struct gl_framebuffer *fb) +{ + if (fb->Visual.depthBits == 0) { + /* Special case. Even if we don't have a depth buffer we need + * good values for DepthMax for Z vertex transformation purposes + * and for per-fragment fog computation. + */ + fb->_DepthMax = (1 << 16) - 1; + } + else if (fb->Visual.depthBits < 32) { + fb->_DepthMax = (1 << fb->Visual.depthBits) - 1; + } + else { + /* Special case since shift values greater than or equal to the + * number of bits in the left hand expression's type are undefined. + */ + fb->_DepthMax = 0xffffffff; + } + fb->_DepthMaxF = (GLfloat) fb->_DepthMax; + fb->_MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */ +} + + +/** + * Create and initialize a gl_framebuffer object. + * This is intended for creating _window_system_ framebuffers, not generic + * framebuffer objects ala GL_EXT_framebuffer_object. + * + * \sa _mesa_new_framebuffer + */ +struct gl_framebuffer * +_mesa_create_framebuffer(const GLvisual *visual) +{ + struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer); + assert(visual); + if (fb) { + _mesa_initialize_framebuffer(fb, visual); + } + return fb; +} + + +/** + * Allocate a new gl_framebuffer object. + * This is the default function for ctx->Driver.NewFramebuffer(). + * This is for allocating user-created framebuffers, not window-system + * framebuffers! + * \sa _mesa_create_framebuffer + */ +struct gl_framebuffer * +_mesa_new_framebuffer(GLcontext *ctx, GLuint name) +{ + struct gl_framebuffer *fb; + assert(name != 0); + fb = CALLOC_STRUCT(gl_framebuffer); + if (fb) { + fb->Name = name; + fb->RefCount = 1; + fb->Delete = _mesa_destroy_framebuffer; + fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT; + fb->_ColorDrawBufferMask[0] = BUFFER_BIT_COLOR0; + fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT; + fb->_ColorReadBufferMask = BUFFER_BIT_COLOR0; + fb->Delete = _mesa_destroy_framebuffer; + } + return fb; +} + + +/** + * Initialize a gl_framebuffer object. + * \sa _mesa_create_framebuffer + */ +void +_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) +{ + assert(fb); + assert(visual); + + _mesa_bzero(fb, sizeof(struct gl_framebuffer)); + + /* save the visual */ + fb->Visual = *visual; + + /* Init glRead/DrawBuffer state */ + if (visual->doubleBufferMode) { + fb->ColorDrawBuffer[0] = GL_BACK; + fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT; + fb->ColorReadBuffer = GL_BACK; + fb->_ColorReadBufferMask = BUFFER_BIT_BACK_LEFT; + } + else { + fb->ColorDrawBuffer[0] = GL_FRONT; + fb->_ColorDrawBufferMask[0] = BUFFER_BIT_FRONT_LEFT; + fb->ColorReadBuffer = GL_FRONT; + fb->_ColorReadBufferMask = BUFFER_BIT_FRONT_LEFT; + } + + fb->Delete = _mesa_destroy_framebuffer; + + compute_depth_max(fb); +} + + +/** + * 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) { + if (fb->Visual.rgbMode) { + 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); + } + else { + _mesa_add_color_index_renderbuffers(NULL, fb, + fb->Visual.indexBits, + 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.rgbMode); + 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.rgbMode); + assert(fb->Visual.numAuxBuffers > 0); + _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits, + fb->Visual.numAuxBuffers); + } + +#if 1 + if (alpha) { + assert(fb->Visual.rgbMode); + assert(fb->Visual.alphaBits > 0); + _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits, + frontLeft, backLeft, + frontRight, backRight); + } +#endif + +#if 0 + if (multisample) { + /* maybe someday */ + } +#endif +} + + +/** + * Deallocate buffer and everything attached to it. + */ +void +_mesa_destroy_framebuffer(struct gl_framebuffer *buffer) +{ + if (buffer) { + _mesa_free_framebuffer_data(buffer); + FREE(buffer); + } +} + + +/** + * Free all the data hanging off the given gl_framebuffer, but don't free + * the gl_framebuffer object itself. + */ +void +_mesa_free_framebuffer_data(struct gl_framebuffer *fb) +{ + GLuint i; + + assert(fb); + + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; + if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) { + struct gl_renderbuffer *rb = att->Renderbuffer; + rb->RefCount--; + if (rb->RefCount == 0) { + rb->Delete(rb); + } + } + att->Type = GL_NONE; + att->Renderbuffer = NULL; + } +} + + +/** + * Resize the given framebuffer's renderbuffers to the new width and height. + * This should only be used for window-system framebuffers, not + * user-created renderbuffers (i.e. made with GL_EXT_framebuffer_object). + * This will typically be called via ctx->Driver.ResizeBuffers() + */ +void +_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint width, GLuint height) +{ + GLuint i; + + /* For window system framebuffers, Name is zero */ + assert(fb->Name == 0); + + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; + if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) { + struct gl_renderbuffer *rb = att->Renderbuffer; + /* only resize if size is changing */ + if (rb->Width != width || rb->Height != height) { + if (rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height)) { + rb->Width = width; + rb->Height = height; + } + else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Resizing framebuffer"); + } + } + } + } + + fb->Width = width; + fb->Height = height; +} + + +/** + * Examine all the framebuffer's renderbuffers to update the Width/Height + * fields of the framebuffer. If we have renderbuffers with different + * sizes, set the framebuffer's width and height to zero. + * Note: this is only intended for user-created framebuffers, not + * window-system framebuffes. + */ +static void +update_framebuffer_size(struct gl_framebuffer *fb) +{ + GLboolean haveSize = GL_FALSE; + GLuint i; + + /* user-created framebuffers only */ + assert(fb->Name); + + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; + const struct gl_renderbuffer *rb = att->Renderbuffer; + if (rb) { + if (haveSize) { + if (rb->Width != fb->Width && rb->Height != fb->Height) { + /* size mismatch! */ + fb->Width = 0; + fb->Height = 0; + return; + } + } + else { + fb->Width = rb->Width; + fb->Height = rb->Height; + haveSize = GL_TRUE; + } + } + } +} + + +/** + * Update the context's current drawing buffer's Xmin, Xmax, Ymin, Ymax fields. + * These values are computed from the buffer's width and height and + * the scissor box, if it's enabled. + * \param ctx the GL context. + */ +void +_mesa_update_draw_buffer_bounds(GLcontext *ctx) +{ + struct gl_framebuffer *buffer = ctx->DrawBuffer; + + if (buffer->Name) { + /* user-created framebuffer size depends on the renderbuffers */ + update_framebuffer_size(buffer); + } + + buffer->_Xmin = 0; + buffer->_Ymin = 0; + buffer->_Xmax = buffer->Width; + buffer->_Ymax = buffer->Height; + + if (ctx->Scissor.Enabled) { + if (ctx->Scissor.X > buffer->_Xmin) { + buffer->_Xmin = ctx->Scissor.X; + } + if (ctx->Scissor.Y > buffer->_Ymin) { + buffer->_Ymin = ctx->Scissor.Y; + } + if (ctx->Scissor.X + ctx->Scissor.Width < buffer->_Xmax) { + buffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width; + } + if (ctx->Scissor.Y + ctx->Scissor.Height < buffer->_Ymax) { + buffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height; + } + /* finally, check for empty region */ + if (buffer->_Xmin > buffer->_Xmax) { + buffer->_Xmin = buffer->_Xmax; + } + if (buffer->_Ymin > buffer->_Ymax) { + buffer->_Ymin = buffer->_Ymax; + } + } + + ASSERT(buffer->_Xmin <= buffer->_Xmax); + ASSERT(buffer->_Ymin <= buffer->_Ymax); +} + + +/** + * The glGet queries of the framebuffer red/green/blue size, stencil size, + * etc. are satisfied by the fields of ctx->DrawBuffer->Visual. These can + * change depending on the renderbuffer bindings. This function update's + * the given framebuffer's Visual from the current renderbuffer bindings. + * This is only intended for user-created framebuffers. + */ +void +_mesa_update_framebuffer_visual(struct gl_framebuffer *fb) +{ + assert(fb->Name != 0); + + _mesa_bzero(&fb->Visual, sizeof(fb->Visual)); + fb->Visual.rgbMode = GL_TRUE; + + if (fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer) { + fb->Visual.redBits + = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer->ComponentSizes[0]; + fb->Visual.greenBits + = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer->ComponentSizes[1]; + fb->Visual.blueBits + = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer->ComponentSizes[2]; + fb->Visual.alphaBits + = fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer->ComponentSizes[3]; + fb->Visual.rgbBits + = fb->Visual.redBits + fb->Visual.greenBits + fb->Visual.blueBits; + fb->Visual.floatMode = GL_FALSE; + } + + if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) { + fb->Visual.haveDepthBuffer = GL_TRUE; + fb->Visual.depthBits + = fb->Attachment[BUFFER_DEPTH].Renderbuffer->ComponentSizes[0]; + } + + if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) { + fb->Visual.haveStencilBuffer = GL_TRUE; + fb->Visual.stencilBits + = fb->Attachment[BUFFER_STENCIL].Renderbuffer->ComponentSizes[0]; + } + + compute_depth_max(fb); +} + + +/** + * Given a framebuffer and a buffer bit (like BUFFER_BIT_FRONT_LEFT), return + * the corresponding renderbuffer. + */ +static struct gl_renderbuffer * +get_renderbuffer(struct gl_framebuffer *fb, GLuint bufferBit) +{ + GLuint index; + for (index = 0; index < BUFFER_COUNT; index++) { + if ((1 << index) == bufferBit) { + return fb->Attachment[index].Renderbuffer; + } + } + _mesa_problem(NULL, "Bad bufferBit in get_renderbuffer"); + return NULL; +} + + +/** + * Update state related to the current draw/read framebuffers. + * If the current framebuffer is user-created, make sure it's complete. + */ +void +_mesa_update_framebuffer(GLcontext *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint output; + + /* Completeness only matters for user-created framebuffers */ + if (fb->Name != 0) + _mesa_test_framebuffer_completeness(ctx, fb); + + /* + * Update the list of drawing renderbuffer pointers. + * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers + * writing colors. We have a loop because glDrawBuffer(GL_FRONT_AND_BACK) + * can specify writing to two or four color buffers. + */ + for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) { + GLuint bufferMask = fb->_ColorDrawBufferMask[output]; + GLuint count = 0; + GLuint bufferBit; + /* for each bit that's set in the bufferMask... */ + for (bufferBit = 1; bufferMask; bufferBit <<= 1) { + if (bufferBit & bufferMask) { + struct gl_renderbuffer *rb = get_renderbuffer(fb, bufferBit); + if (rb) { + fb->_ColorDrawBuffers[output][count] = rb; + fb->_ColorDrawBit[output][count] = bufferBit; + count++; + } + else { + _mesa_warning(ctx, "DrawBuffer names a missing buffer!"); + } + bufferMask &= ~bufferBit; + } + } + fb->_NumColorDrawBuffers[output] = count; + } + + /* + * Update the read renderbuffer pointer. + * Unlike the DrawBuffer, we can only read from one (or zero) color buffers. + */ + if (fb->_ColorReadBufferMask == 0x0) + fb->_ColorReadBuffer = NULL; /* legal! */ + else + fb->_ColorReadBuffer = get_renderbuffer(fb, fb->_ColorReadBufferMask); + + compute_depth_max(fb); +} diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h new file mode 100644 index 0000000000..11b002877c --- /dev/null +++ b/src/mesa/main/framebuffer.h @@ -0,0 +1,67 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef FRAMEBUFFER_H +#define FRAMEBUFFER_H + + +extern struct gl_framebuffer * +_mesa_create_framebuffer(const GLvisual *visual); + +extern struct gl_framebuffer * +_mesa_new_framebuffer(GLcontext *ctx, GLuint name); + +extern void +_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual); + +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_destroy_framebuffer(struct gl_framebuffer *buffer); + +extern void +_mesa_free_framebuffer_data(struct gl_framebuffer *buffer); + +extern void +_mesa_resize_framebuffer(GLcontext *ctx, struct gl_framebuffer *b, + GLuint width, GLuint height); + +extern void +_mesa_update_draw_buffer_bounds(GLcontext *ctx); + +extern void +_mesa_update_framebuffer_visual(struct gl_framebuffer *fb); + +extern void +_mesa_update_framebuffer(GLcontext *ctx); + +#endif /* FRAMEBUFFER_H */ diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 9b2981059c..b6f08efc34 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -91,16 +91,16 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) switch (pname) { case GL_ACCUM_RED_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.accumRedBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumRedBits); break; case GL_ACCUM_GREEN_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.accumGreenBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumGreenBits); break; case GL_ACCUM_BLUE_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.accumBlueBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumBlueBits); break; case GL_ACCUM_ALPHA_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.accumAlphaBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.accumAlphaBits); break; case GL_ACCUM_CLEAR_VALUE: params[0] = FLOAT_TO_BOOLEAN(ctx->Accum.ClearColor[0]); @@ -112,7 +112,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaBias); break; case GL_ALPHA_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.alphaBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.alphaBits); break; case GL_ALPHA_SCALE: params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.AlphaScale); @@ -133,7 +133,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = ctx->Eval.AutoNormal; break; case GL_AUX_BUFFERS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.numAuxBuffers); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.numAuxBuffers); break; case GL_BLEND: params[0] = ctx->Color.BlendEnabled; @@ -172,7 +172,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueBias); break; case GL_BLUE_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.blueBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.blueBits); break; case GL_BLUE_SCALE: params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.BlueScale); @@ -291,7 +291,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.DepthBias); break; case GL_DEPTH_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.depthBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.depthBits); break; case GL_DEPTH_CLEAR_VALUE: params[0] = FLOAT_TO_BOOLEAN(ctx->Depth.Clear); @@ -316,7 +316,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = ctx->Color.DitherFlag; break; case GL_DOUBLEBUFFER: - params[0] = ctx->Visual.doubleBufferMode; + params[0] = ctx->DrawBuffer->Visual.doubleBufferMode; break; case GL_DRAW_BUFFER: params[0] = ENUM_TO_BOOLEAN(ctx->Color.DrawBuffer[0]); @@ -367,19 +367,19 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenBias); break; case GL_GREEN_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.greenBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.greenBits); break; case GL_GREEN_SCALE: params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.GreenScale); break; case GL_INDEX_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.indexBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.indexBits); break; case GL_INDEX_CLEAR_VALUE: params[0] = INT_TO_BOOLEAN(ctx->Color.ClearIndex); break; case GL_INDEX_MODE: - params[0] = !ctx->Visual.rgbMode; + params[0] = !ctx->DrawBuffer->Visual.rgbMode; break; case GL_INDEX_OFFSET: params[0] = INT_TO_BOOLEAN(ctx->Pixel.IndexOffset); @@ -794,7 +794,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedBias); break; case GL_RED_BITS: - params[0] = INT_TO_BOOLEAN( ctx->Visual.redBits ); + params[0] = INT_TO_BOOLEAN( ctx->DrawBuffer->Visual.redBits ); break; case GL_RED_SCALE: params[0] = FLOAT_TO_BOOLEAN(ctx->Pixel.RedScale); @@ -806,7 +806,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = ctx->Transform.RescaleNormals; break; case GL_RGBA_MODE: - params[0] = ctx->Visual.rgbMode; + params[0] = ctx->DrawBuffer->Visual.rgbMode; break; case GL_SCISSOR_BOX: params[0] = INT_TO_BOOLEAN(ctx->Scissor.X); @@ -827,7 +827,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = ctx->Texture.SharedPalette; break; case GL_STENCIL_BITS: - params[0] = INT_TO_BOOLEAN(ctx->Visual.stencilBits); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.stencilBits); break; case GL_STENCIL_CLEAR_VALUE: params[0] = INT_TO_BOOLEAN(ctx->Stencil.Clear); @@ -857,7 +857,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = INT_TO_BOOLEAN(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]); break; case GL_STEREO: - params[0] = ctx->Visual.stereoMode; + params[0] = ctx->DrawBuffer->Visual.stereoMode; break; case GL_SUBPIXEL_BITS: params[0] = INT_TO_BOOLEAN(ctx->Const.SubPixelBits); @@ -1414,11 +1414,11 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_SAMPLE_BUFFERS_ARB: CHECK_EXTENSION_B(ARB_multisample, pname); - params[0] = INT_TO_BOOLEAN(0); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.sampleBuffers); break; case GL_SAMPLES_ARB: CHECK_EXTENSION_B(ARB_multisample, pname); - params[0] = INT_TO_BOOLEAN(0); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.samples); break; case GL_RASTER_POSITION_UNCLIPPED_IBM: CHECK_EXTENSION_B(IBM_rasterpos_clip, pname); @@ -1877,7 +1877,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_FRAMEBUFFER_BINDING_EXT: CHECK_EXTENSION_B(EXT_framebuffer_object, pname); - params[0] = INT_TO_BOOLEAN(ctx->CurrentFramebuffer ? ctx->CurrentFramebuffer->Name : 0); + params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Name); break; case GL_RENDERBUFFER_BINDING_EXT: CHECK_EXTENSION_B(EXT_framebuffer_object, pname); @@ -1935,16 +1935,16 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) switch (pname) { case GL_ACCUM_RED_BITS: - params[0] = (GLfloat)(ctx->Visual.accumRedBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumRedBits); break; case GL_ACCUM_GREEN_BITS: - params[0] = (GLfloat)(ctx->Visual.accumGreenBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumGreenBits); break; case GL_ACCUM_BLUE_BITS: - params[0] = (GLfloat)(ctx->Visual.accumBlueBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumBlueBits); break; case GL_ACCUM_ALPHA_BITS: - params[0] = (GLfloat)(ctx->Visual.accumAlphaBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.accumAlphaBits); break; case GL_ACCUM_CLEAR_VALUE: params[0] = ctx->Accum.ClearColor[0]; @@ -1956,7 +1956,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = ctx->Pixel.AlphaBias; break; case GL_ALPHA_BITS: - params[0] = (GLfloat)(ctx->Visual.alphaBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.alphaBits); break; case GL_ALPHA_SCALE: params[0] = ctx->Pixel.AlphaScale; @@ -1977,7 +1977,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = BOOLEAN_TO_FLOAT(ctx->Eval.AutoNormal); break; case GL_AUX_BUFFERS: - params[0] = (GLfloat)(ctx->Visual.numAuxBuffers); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.numAuxBuffers); break; case GL_BLEND: params[0] = BOOLEAN_TO_FLOAT(ctx->Color.BlendEnabled); @@ -2016,7 +2016,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = ctx->Pixel.BlueBias; break; case GL_BLUE_BITS: - params[0] = (GLfloat)(ctx->Visual.blueBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.blueBits); break; case GL_BLUE_SCALE: params[0] = ctx->Pixel.BlueScale; @@ -2135,7 +2135,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = ctx->Pixel.DepthBias; break; case GL_DEPTH_BITS: - params[0] = (GLfloat)(ctx->Visual.depthBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.depthBits); break; case GL_DEPTH_CLEAR_VALUE: params[0] = ctx->Depth.Clear; @@ -2160,7 +2160,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = BOOLEAN_TO_FLOAT(ctx->Color.DitherFlag); break; case GL_DOUBLEBUFFER: - params[0] = BOOLEAN_TO_FLOAT(ctx->Visual.doubleBufferMode); + params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.doubleBufferMode); break; case GL_DRAW_BUFFER: params[0] = ENUM_TO_FLOAT(ctx->Color.DrawBuffer[0]); @@ -2211,19 +2211,19 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = ctx->Pixel.GreenBias; break; case GL_GREEN_BITS: - params[0] = (GLfloat)(ctx->Visual.greenBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.greenBits); break; case GL_GREEN_SCALE: params[0] = ctx->Pixel.GreenScale; break; case GL_INDEX_BITS: - params[0] = (GLfloat)(ctx->Visual.indexBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.indexBits); break; case GL_INDEX_CLEAR_VALUE: params[0] = (GLfloat)(ctx->Color.ClearIndex); break; case GL_INDEX_MODE: - params[0] = BOOLEAN_TO_FLOAT(!ctx->Visual.rgbMode); + params[0] = BOOLEAN_TO_FLOAT(!ctx->DrawBuffer->Visual.rgbMode); break; case GL_INDEX_OFFSET: params[0] = (GLfloat)(ctx->Pixel.IndexOffset); @@ -2638,7 +2638,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = ctx->Pixel.RedBias; break; case GL_RED_BITS: - params[0] = (GLfloat)( ctx->Visual.redBits ); + params[0] = (GLfloat)( ctx->DrawBuffer->Visual.redBits ); break; case GL_RED_SCALE: params[0] = ctx->Pixel.RedScale; @@ -2650,7 +2650,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.RescaleNormals); break; case GL_RGBA_MODE: - params[0] = BOOLEAN_TO_FLOAT(ctx->Visual.rgbMode); + params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.rgbMode); break; case GL_SCISSOR_BOX: params[0] = (GLfloat)(ctx->Scissor.X); @@ -2671,7 +2671,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.SharedPalette); break; case GL_STENCIL_BITS: - params[0] = (GLfloat)(ctx->Visual.stencilBits); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.stencilBits); break; case GL_STENCIL_CLEAR_VALUE: params[0] = (GLfloat)(ctx->Stencil.Clear); @@ -2701,7 +2701,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = (GLfloat)(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]); break; case GL_STEREO: - params[0] = BOOLEAN_TO_FLOAT(ctx->Visual.stereoMode); + params[0] = BOOLEAN_TO_FLOAT(ctx->DrawBuffer->Visual.stereoMode); break; case GL_SUBPIXEL_BITS: params[0] = (GLfloat)(ctx->Const.SubPixelBits); @@ -3258,11 +3258,11 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_SAMPLE_BUFFERS_ARB: CHECK_EXTENSION_F(ARB_multisample, pname); - params[0] = (GLfloat)(0); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.sampleBuffers); break; case GL_SAMPLES_ARB: CHECK_EXTENSION_F(ARB_multisample, pname); - params[0] = (GLfloat)(0); + params[0] = (GLfloat)(ctx->DrawBuffer->Visual.samples); break; case GL_RASTER_POSITION_UNCLIPPED_IBM: CHECK_EXTENSION_F(IBM_rasterpos_clip, pname); @@ -3721,7 +3721,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_FRAMEBUFFER_BINDING_EXT: CHECK_EXTENSION_F(EXT_framebuffer_object, pname); - params[0] = (GLfloat)(ctx->CurrentFramebuffer ? ctx->CurrentFramebuffer->Name : 0); + params[0] = (GLfloat)(ctx->DrawBuffer->Name); break; case GL_RENDERBUFFER_BINDING_EXT: CHECK_EXTENSION_F(EXT_framebuffer_object, pname); @@ -3779,16 +3779,16 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) switch (pname) { case GL_ACCUM_RED_BITS: - params[0] = ctx->Visual.accumRedBits; + params[0] = ctx->DrawBuffer->Visual.accumRedBits; break; case GL_ACCUM_GREEN_BITS: - params[0] = ctx->Visual.accumGreenBits; + params[0] = ctx->DrawBuffer->Visual.accumGreenBits; break; case GL_ACCUM_BLUE_BITS: - params[0] = ctx->Visual.accumBlueBits; + params[0] = ctx->DrawBuffer->Visual.accumBlueBits; break; case GL_ACCUM_ALPHA_BITS: - params[0] = ctx->Visual.accumAlphaBits; + params[0] = ctx->DrawBuffer->Visual.accumAlphaBits; break; case GL_ACCUM_CLEAR_VALUE: params[0] = FLOAT_TO_INT(ctx->Accum.ClearColor[0]); @@ -3800,7 +3800,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = IROUND(ctx->Pixel.AlphaBias); break; case GL_ALPHA_BITS: - params[0] = ctx->Visual.alphaBits; + params[0] = ctx->DrawBuffer->Visual.alphaBits; break; case GL_ALPHA_SCALE: params[0] = IROUND(ctx->Pixel.AlphaScale); @@ -3821,7 +3821,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = BOOLEAN_TO_INT(ctx->Eval.AutoNormal); break; case GL_AUX_BUFFERS: - params[0] = ctx->Visual.numAuxBuffers; + params[0] = ctx->DrawBuffer->Visual.numAuxBuffers; break; case GL_BLEND: params[0] = BOOLEAN_TO_INT(ctx->Color.BlendEnabled); @@ -3860,7 +3860,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = IROUND(ctx->Pixel.BlueBias); break; case GL_BLUE_BITS: - params[0] = ctx->Visual.blueBits; + params[0] = ctx->DrawBuffer->Visual.blueBits; break; case GL_BLUE_SCALE: params[0] = IROUND(ctx->Pixel.BlueScale); @@ -3979,7 +3979,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = IROUND(ctx->Pixel.DepthBias); break; case GL_DEPTH_BITS: - params[0] = ctx->Visual.depthBits; + params[0] = ctx->DrawBuffer->Visual.depthBits; break; case GL_DEPTH_CLEAR_VALUE: params[0] = IROUND(ctx->Depth.Clear); @@ -4004,7 +4004,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = BOOLEAN_TO_INT(ctx->Color.DitherFlag); break; case GL_DOUBLEBUFFER: - params[0] = BOOLEAN_TO_INT(ctx->Visual.doubleBufferMode); + params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.doubleBufferMode); break; case GL_DRAW_BUFFER: params[0] = ENUM_TO_INT(ctx->Color.DrawBuffer[0]); @@ -4055,19 +4055,19 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = IROUND(ctx->Pixel.GreenBias); break; case GL_GREEN_BITS: - params[0] = ctx->Visual.greenBits; + params[0] = ctx->DrawBuffer->Visual.greenBits; break; case GL_GREEN_SCALE: params[0] = IROUND(ctx->Pixel.GreenScale); break; case GL_INDEX_BITS: - params[0] = ctx->Visual.indexBits; + params[0] = ctx->DrawBuffer->Visual.indexBits; break; case GL_INDEX_CLEAR_VALUE: params[0] = ctx->Color.ClearIndex; break; case GL_INDEX_MODE: - params[0] = BOOLEAN_TO_INT(!ctx->Visual.rgbMode); + params[0] = BOOLEAN_TO_INT(!ctx->DrawBuffer->Visual.rgbMode); break; case GL_INDEX_OFFSET: params[0] = ctx->Pixel.IndexOffset; @@ -4482,7 +4482,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = IROUND(ctx->Pixel.RedBias); break; case GL_RED_BITS: - params[0] = ctx->Visual.redBits ; + params[0] = ctx->DrawBuffer->Visual.redBits ; break; case GL_RED_SCALE: params[0] = IROUND(ctx->Pixel.RedScale); @@ -4494,7 +4494,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = BOOLEAN_TO_INT(ctx->Transform.RescaleNormals); break; case GL_RGBA_MODE: - params[0] = BOOLEAN_TO_INT(ctx->Visual.rgbMode); + params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.rgbMode); break; case GL_SCISSOR_BOX: params[0] = ctx->Scissor.X; @@ -4515,7 +4515,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = BOOLEAN_TO_INT(ctx->Texture.SharedPalette); break; case GL_STENCIL_BITS: - params[0] = ctx->Visual.stencilBits; + params[0] = ctx->DrawBuffer->Visual.stencilBits; break; case GL_STENCIL_CLEAR_VALUE: params[0] = ctx->Stencil.Clear; @@ -4545,7 +4545,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; break; case GL_STEREO: - params[0] = BOOLEAN_TO_INT(ctx->Visual.stereoMode); + params[0] = BOOLEAN_TO_INT(ctx->DrawBuffer->Visual.stereoMode); break; case GL_SUBPIXEL_BITS: params[0] = ctx->Const.SubPixelBits; @@ -5102,11 +5102,11 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_SAMPLE_BUFFERS_ARB: CHECK_EXTENSION_I(ARB_multisample, pname); - params[0] = 0; + params[0] = ctx->DrawBuffer->Visual.sampleBuffers; break; case GL_SAMPLES_ARB: CHECK_EXTENSION_I(ARB_multisample, pname); - params[0] = 0; + params[0] = ctx->DrawBuffer->Visual.samples; break; case GL_RASTER_POSITION_UNCLIPPED_IBM: CHECK_EXTENSION_I(IBM_rasterpos_clip, pname); @@ -5565,7 +5565,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_FRAMEBUFFER_BINDING_EXT: CHECK_EXTENSION_I(EXT_framebuffer_object, pname); - params[0] = ctx->CurrentFramebuffer ? ctx->CurrentFramebuffer->Name : 0; + params[0] = ctx->DrawBuffer->Name; break; case GL_RENDERBUFFER_BINDING_EXT: CHECK_EXTENSION_I(EXT_framebuffer_object, pname); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index b3e6bc5855..8259972daa 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -54,10 +54,14 @@ TypeStrings = { # - optional extension to check, or None (XXX this should be a list!) # StateVars = [ - ( "GL_ACCUM_RED_BITS", GLint, ["ctx->Visual.accumRedBits"], "", None ), - ( "GL_ACCUM_GREEN_BITS", GLint, ["ctx->Visual.accumGreenBits"], "", None ), - ( "GL_ACCUM_BLUE_BITS", GLint, ["ctx->Visual.accumBlueBits"], "", None ), - ( "GL_ACCUM_ALPHA_BITS", GLint, ["ctx->Visual.accumAlphaBits"], "", None ), + ( "GL_ACCUM_RED_BITS", GLint, ["ctx->DrawBuffer->Visual.accumRedBits"], + "", None ), + ( "GL_ACCUM_GREEN_BITS", GLint, ["ctx->DrawBuffer->Visual.accumGreenBits"], + "", None ), + ( "GL_ACCUM_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.accumBlueBits"], + "", None ), + ( "GL_ACCUM_ALPHA_BITS", GLint, ["ctx->DrawBuffer->Visual.accumAlphaBits"], + "", None ), ( "GL_ACCUM_CLEAR_VALUE", GLfloatN, [ "ctx->Accum.ClearColor[0]", "ctx->Accum.ClearColor[1]", @@ -65,14 +69,16 @@ StateVars = [ "ctx->Accum.ClearColor[3]" ], "", None ), ( "GL_ALPHA_BIAS", GLfloat, ["ctx->Pixel.AlphaBias"], "", None ), - ( "GL_ALPHA_BITS", GLint, ["ctx->Visual.alphaBits"], "", None ), + ( "GL_ALPHA_BITS", GLint, ["ctx->DrawBuffer->Visual.alphaBits"], + "", None ), ( "GL_ALPHA_SCALE", GLfloat, ["ctx->Pixel.AlphaScale"], "", None ), ( "GL_ALPHA_TEST", GLboolean, ["ctx->Color.AlphaEnabled"], "", None ), ( "GL_ALPHA_TEST_FUNC", GLenum, ["ctx->Color.AlphaFunc"], "", None ), ( "GL_ALPHA_TEST_REF", GLfloatN, ["ctx->Color.AlphaRef"], "", None ), ( "GL_ATTRIB_STACK_DEPTH", GLint, ["ctx->AttribStackDepth"], "", None ), ( "GL_AUTO_NORMAL", GLboolean, ["ctx->Eval.AutoNormal"], "", None ), - ( "GL_AUX_BUFFERS", GLint, ["ctx->Visual.numAuxBuffers"], "", None ), + ( "GL_AUX_BUFFERS", GLint, ["ctx->DrawBuffer->Visual.numAuxBuffers"], + "", None ), ( "GL_BLEND", GLboolean, ["ctx->Color.BlendEnabled"], "", None ), ( "GL_BLEND_DST", GLenum, ["ctx->Color.BlendDstRGB"], "", None ), ( "GL_BLEND_SRC", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ), @@ -89,7 +95,7 @@ StateVars = [ "ctx->Color.BlendColor[2]", "ctx->Color.BlendColor[3]"], "", None ), ( "GL_BLUE_BIAS", GLfloat, ["ctx->Pixel.BlueBias"], "", None ), - ( "GL_BLUE_BITS", GLint, ["ctx->Visual.blueBits"], "", None ), + ( "GL_BLUE_BITS", GLint, ["ctx->DrawBuffer->Visual.blueBits"], "", None ), ( "GL_BLUE_SCALE", GLfloat, ["ctx->Pixel.BlueScale"], "", None ), ( "GL_CLIENT_ATTRIB_STACK_DEPTH", GLint, ["ctx->ClientAttribStackDepth"], "", None ), @@ -165,7 +171,8 @@ StateVars = [ "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]"], "const GLuint texUnit = ctx->Texture.CurrentUnit;", None ), ( "GL_DEPTH_BIAS", GLfloat, ["ctx->Pixel.DepthBias"], "", None ), - ( "GL_DEPTH_BITS", GLint, ["ctx->Visual.depthBits"], "", None ), + ( "GL_DEPTH_BITS", GLint, ["ctx->DrawBuffer->Visual.depthBits"], + "", None ), ( "GL_DEPTH_CLEAR_VALUE", GLfloat, ["ctx->Depth.Clear"], "", None ), ( "GL_DEPTH_FUNC", GLenum, ["ctx->Depth.Func"], "", None ), ( "GL_DEPTH_RANGE", GLfloatN, @@ -174,7 +181,8 @@ StateVars = [ ( "GL_DEPTH_TEST", GLboolean, ["ctx->Depth.Test"], "", None ), ( "GL_DEPTH_WRITEMASK", GLboolean, ["ctx->Depth.Mask"], "", None ), ( "GL_DITHER", GLboolean, ["ctx->Color.DitherFlag"], "", None ), - ( "GL_DOUBLEBUFFER", GLboolean, ["ctx->Visual.doubleBufferMode"], "", None ), + ( "GL_DOUBLEBUFFER", GLboolean, + ["ctx->DrawBuffer->Visual.doubleBufferMode"], "", None ), ( "GL_DRAW_BUFFER", GLenum, ["ctx->Color.DrawBuffer[0]"], "", None ), ( "GL_EDGE_FLAG", GLboolean, ["ctx->Current.EdgeFlag"], "FLUSH_CURRENT(ctx, 0);", None ), @@ -194,11 +202,14 @@ StateVars = [ ( "GL_FOG_START", GLfloat, ["ctx->Fog.Start"], "", None ), ( "GL_FRONT_FACE", GLenum, ["ctx->Polygon.FrontFace"], "", None ), ( "GL_GREEN_BIAS", GLfloat, ["ctx->Pixel.GreenBias"], "", None ), - ( "GL_GREEN_BITS", GLint, ["ctx->Visual.greenBits"], "", None ), + ( "GL_GREEN_BITS", GLint, ["ctx->DrawBuffer->Visual.greenBits"], + "", None ), ( "GL_GREEN_SCALE", GLfloat, ["ctx->Pixel.GreenScale"], "", None ), - ( "GL_INDEX_BITS", GLint, ["ctx->Visual.indexBits"], "", None ), + ( "GL_INDEX_BITS", GLint, ["ctx->DrawBuffer->Visual.indexBits"], + "", None ), ( "GL_INDEX_CLEAR_VALUE", GLint, ["ctx->Color.ClearIndex"], "", None ), - ( "GL_INDEX_MODE", GLboolean, ["!ctx->Visual.rgbMode"], "", None ), + ( "GL_INDEX_MODE", GLboolean, ["!ctx->DrawBuffer->Visual.rgbMode"], + "", None ), ( "GL_INDEX_OFFSET", GLint, ["ctx->Pixel.IndexOffset"], "", None ), ( "GL_INDEX_SHIFT", GLint, ["ctx->Pixel.IndexShift"], "", None ), ( "GL_INDEX_WRITEMASK", GLint, ["ctx->Color.IndexMask"], "", None ), @@ -368,12 +379,13 @@ StateVars = [ ["ctx->ProjectionMatrixStack.Depth + 1"], "", None ), ( "GL_READ_BUFFER", GLenum, ["ctx->Pixel.ReadBuffer"], "", None ), ( "GL_RED_BIAS", GLfloat, ["ctx->Pixel.RedBias"], "", None ), - ( "GL_RED_BITS", GLint, [" ctx->Visual.redBits "], "", None ), + ( "GL_RED_BITS", GLint, [" ctx->DrawBuffer->Visual.redBits "], "", None ), ( "GL_RED_SCALE", GLfloat, ["ctx->Pixel.RedScale"], "", None ), ( "GL_RENDER_MODE", GLenum, ["ctx->RenderMode"], "", None ), ( "GL_RESCALE_NORMAL", GLboolean, ["ctx->Transform.RescaleNormals"], "", None ), - ( "GL_RGBA_MODE", GLboolean, ["ctx->Visual.rgbMode"], "", None ), + ( "GL_RGBA_MODE", GLboolean, ["ctx->DrawBuffer->Visual.rgbMode"], + "", None ), ( "GL_SCISSOR_BOX", GLint, ["ctx->Scissor.X", "ctx->Scissor.Y", @@ -384,7 +396,7 @@ StateVars = [ ( "GL_SHADE_MODEL", GLenum, ["ctx->Light.ShadeModel"], "", None ), ( "GL_SHARED_TEXTURE_PALETTE_EXT", GLboolean, ["ctx->Texture.SharedPalette"], "", None ), - ( "GL_STENCIL_BITS", GLint, ["ctx->Visual.stencilBits"], "", None ), + ( "GL_STENCIL_BITS", GLint, ["ctx->DrawBuffer->Visual.stencilBits"], "", None ), ( "GL_STENCIL_CLEAR_VALUE", GLint, ["ctx->Stencil.Clear"], "", None ), ( "GL_STENCIL_FAIL", GLenum, ["ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]"], "", None ), @@ -401,7 +413,8 @@ StateVars = [ ["ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]"], "", None ), ( "GL_STENCIL_WRITEMASK", GLint, ["ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]"], "", None ), - ( "GL_STEREO", GLboolean, ["ctx->Visual.stereoMode"], "", None ), + ( "GL_STEREO", GLboolean, ["ctx->DrawBuffer->Visual.stereoMode"], + "", None ), ( "GL_SUBPIXEL_BITS", GLint, ["ctx->Const.SubPixelBits"], "", None ), ( "GL_TEXTURE_1D", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_1D)"], "", None ), ( "GL_TEXTURE_2D", GLboolean, ["_mesa_IsEnabled(GL_TEXTURE_2D)"], "", None ), @@ -692,8 +705,10 @@ StateVars = [ ["ctx->Multisample.SampleCoverageValue"], "", "ARB_multisample" ), ( "GL_SAMPLE_COVERAGE_INVERT_ARB", GLboolean, ["ctx->Multisample.SampleCoverageInvert"], "", "ARB_multisample" ), - ( "GL_SAMPLE_BUFFERS_ARB", GLint, ["0"], "", "ARB_multisample" ), - ( "GL_SAMPLES_ARB", GLint, ["0"], "", "ARB_multisample" ), + ( "GL_SAMPLE_BUFFERS_ARB", GLint, + ["ctx->DrawBuffer->Visual.sampleBuffers"], "", "ARB_multisample" ), + ( "GL_SAMPLES_ARB", GLint, + ["ctx->DrawBuffer->Visual.samples"], "", "ARB_multisample" ), # GL_IBM_rasterpos_clip ( "GL_RASTER_POSITION_UNCLIPPED_IBM", GLboolean, @@ -953,8 +968,7 @@ StateVars = [ ( "GL_STENCIL_BACK_PASS_DEPTH_PASS", GLenum, ["ctx->Stencil.ZPassFunc[1]"], "", None ), # GL_EXT_framebuffer_object - ( "GL_FRAMEBUFFER_BINDING_EXT", GLint, - ["ctx->CurrentFramebuffer ? ctx->CurrentFramebuffer->Name : 0"], "", + ( "GL_FRAMEBUFFER_BINDING_EXT", GLint, ["ctx->DrawBuffer->Name"], "", "EXT_framebuffer_object" ), ( "GL_RENDERBUFFER_BINDING_EXT", GLint, ["ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0"], "", diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index 70cbee5f3d..2f0a1fa8c6 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -569,9 +569,12 @@ void _mesa_set_viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ) { + const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; const GLfloat n = ctx->Viewport.Near; const GLfloat f = ctx->Viewport.Far; + ASSERT(depthMax > 0); + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glViewport %d %d %d %d\n", x, y, width, height); @@ -606,8 +609,8 @@ _mesa_set_viewport( GLcontext *ctx, GLint x, GLint y, ctx->Viewport._WindowMap.m[MAT_TX] = ctx->Viewport._WindowMap.m[MAT_SX] + x; ctx->Viewport._WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F; ctx->Viewport._WindowMap.m[MAT_TY] = ctx->Viewport._WindowMap.m[MAT_SY] + y; - ctx->Viewport._WindowMap.m[MAT_SZ] = ctx->DepthMaxF * ((f - n) / 2.0F); - ctx->Viewport._WindowMap.m[MAT_TZ] = ctx->DepthMaxF * ((f - n) / 2.0F + n); + ctx->Viewport._WindowMap.m[MAT_SZ] = depthMax * ((f - n) / 2.0F); + ctx->Viewport._WindowMap.m[MAT_TZ] = depthMax * ((f - n) / 2.0F + n); ctx->Viewport._WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION; ctx->Viewport._WindowMap.type = MATRIX_3D_NO_ROT; ctx->NewState |= _NEW_VIEWPORT; @@ -636,10 +639,13 @@ _mesa_DepthRange( GLclampd nearval, GLclampd farval ) * specifies a linear mapping of the normalized z coords in * this range to window z coords. */ + GLfloat depthMax; GLfloat n, f; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + depthMax = ctx->DrawBuffer->_DepthMaxF; + if (MESA_VERBOSE&VERBOSE_API) _mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval); @@ -648,8 +654,8 @@ _mesa_DepthRange( GLclampd nearval, GLclampd farval ) ctx->Viewport.Near = n; ctx->Viewport.Far = f; - ctx->Viewport._WindowMap.m[MAT_SZ] = ctx->DepthMaxF * ((f - n) / 2.0F); - ctx->Viewport._WindowMap.m[MAT_TZ] = ctx->DepthMaxF * ((f - n) / 2.0F + n); + ctx->Viewport._WindowMap.m[MAT_SZ] = depthMax * ((f - n) / 2.0F); + ctx->Viewport._WindowMap.m[MAT_TZ] = depthMax * ((f - n) / 2.0F + n); ctx->NewState |= _NEW_VIEWPORT; if (ctx->Driver.DepthRange) { @@ -919,12 +925,14 @@ void _mesa_init_viewport( GLcontext *ctx ) ctx->Viewport.Far = 1.0; _math_matrix_ctr(&ctx->Viewport._WindowMap); +#if 0000 #define Sz 10 #define Tz 14 ctx->Viewport._WindowMap.m[Sz] = 0.5F * ctx->DepthMaxF; ctx->Viewport._WindowMap.m[Tz] = 0.5F * ctx->DepthMaxF; #undef Sz #undef Tz +#endif ctx->Viewport._WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION; ctx->Viewport._WindowMap.type = MATRIX_3D_NO_ROT; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b50bf0e4f1..832166d2c0 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -65,16 +65,8 @@ #endif -/** - * Accumulation buffer data type. - */ -#if ACCUM_BITS==8 - typedef GLbyte GLaccum; -#elif ACCUM_BITS==16 - typedef GLshort GLaccum; -#elif ACCUM_BITS==32 - typedef GLfloat GLaccum; -#else +#if ACCUM_BITS != 16 +/* Software accum done with GLshort at this time */ # error "illegal number of accumulation bits" #endif @@ -139,13 +131,13 @@ typedef int GLfixed; */ /*@{*/ struct _mesa_HashTable; +struct gl_pixelstore_attrib; +struct gl_texture_format; struct gl_texture_image; struct gl_texture_object; typedef struct __GLcontextRec GLcontext; typedef struct __GLcontextModesRec GLvisual; -typedef struct gl_frame_buffer GLframebuffer; -struct gl_pixelstore_attrib; -struct gl_texture_format; +typedef struct gl_framebuffer GLframebuffer; /*@}*/ @@ -282,25 +274,53 @@ enum /** - * Bits for each basic buffer in a complete framebuffer. - * When glDrawBuffer(GL_FRONT_AND_BACK) is called (non-stereo), - * _DrawDestMask will be set to (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT), - * for example. Also passed to ctx->Driver.Clear() to indicate which - * buffers to clear. - */ -/*@{*/ -#define DD_FRONT_LEFT_BIT 0x1 -#define DD_FRONT_RIGHT_BIT 0x2 -#define DD_BACK_LEFT_BIT 0x4 -#define DD_BACK_RIGHT_BIT 0x8 -#define DD_AUX0_BIT 0x10 -#define DD_AUX1_BIT 0x20 -#define DD_AUX2_BIT 0x40 -#define DD_AUX3_BIT 0x80 -#define DD_DEPTH_BIT GL_DEPTH_BUFFER_BIT /* 0x00000100 */ -#define DD_ACCUM_BIT GL_ACCUM_BUFFER_BIT /* 0x00000200 */ -#define DD_STENCIL_BIT GL_STENCIL_BUFFER_BIT /* 0x00000400 */ -/*@}*/ + * Indexes for all renderbuffers + */ +enum { + BUFFER_FRONT_LEFT = 0, /* the four standard color buffers */ + BUFFER_BACK_LEFT = 1, + BUFFER_FRONT_RIGHT = 2, + BUFFER_BACK_RIGHT = 3, + BUFFER_AUX0 = 4, /* optional aux buffer */ + BUFFER_AUX1 = 5, + BUFFER_AUX2 = 6, + BUFFER_AUX3 = 7, + BUFFER_DEPTH = 8, + BUFFER_STENCIL = 9, + BUFFER_ACCUM = 10, + BUFFER_COLOR0 = 11, /* generic renderbuffers */ + BUFFER_COLOR1 = 12, + BUFFER_COLOR2 = 13, + BUFFER_COLOR3 = 14, + BUFFER_COLOR4 = 15, + BUFFER_COLOR5 = 16, + BUFFER_COLOR6 = 17, + BUFFER_COLOR7 = 18, + BUFFER_COUNT = 19 +}; + +/** + * Bit flags for all renderbuffers + */ +#define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT) +#define BUFFER_BIT_BACK_LEFT (1 << BUFFER_BACK_LEFT) +#define BUFFER_BIT_FRONT_RIGHT (1 << BUFFER_FRONT_RIGHT) +#define BUFFER_BIT_BACK_RIGHT (1 << BUFFER_BACK_RIGHT) +#define BUFFER_BIT_AUX0 (1 << BUFFER_AUX0) +#define BUFFER_BIT_AUX1 (1 << BUFFER_AUX1) +#define BUFFER_BIT_AUX2 (1 << BUFFER_AUX2) +#define BUFFER_BIT_AUX3 (1 << BUFFER_AUX3) +#define BUFFER_BIT_DEPTH (1 << BUFFER_DEPTH) +#define BUFFER_BIT_STENCIL (1 << BUFFER_STENCIL) +#define BUFFER_BIT_ACCUM (1 << BUFFER_ACCUM) +#define BUFFER_BIT_COLOR0 (1 << BUFFER_COLOR0) +#define BUFFER_BIT_COLOR1 (1 << BUFFER_COLOR1) +#define BUFFER_BIT_COLOR2 (1 << BUFFER_COLOR2) +#define BUFFER_BIT_COLOR3 (1 << BUFFER_COLOR3) +#define BUFFER_BIT_COLOR4 (1 << BUFFER_COLOR4) +#define BUFFER_BIT_COLOR5 (1 << BUFFER_COLOR5) +#define BUFFER_BIT_COLOR6 (1 << BUFFER_COLOR6) +#define BUFFER_BIT_COLOR7 (1 << BUFFER_COLOR7) /** @@ -484,7 +504,6 @@ struct gl_colorbuffer_attrib GLubyte ColorMask[4]; /**< Each flag is 0xff or 0x0 */ GLenum DrawBuffer[MAX_DRAW_BUFFERS]; /**< Which buffer to draw into */ - GLbitfield _DrawDestMask[MAX_DRAW_BUFFERS];/**< bitmask of DD_*_BIT bits */ /** * \name alpha testing @@ -885,11 +904,7 @@ struct gl_multisample_attrib */ struct gl_pixel_attrib { - GLenum ReadBuffer; /**< source buffer for glReadPixels()/glCopyPixels() */ - GLubyte _ReadSrcMask; /**< Not really a mask, but like _DrawDestMask - * - * May be: FRONT_LEFT_BIT, BACK_LEFT_BIT, - * FRONT_RIGHT_BIT or BACK_RIGHT_BIT. */ + GLenum ReadBuffer; /**< source buffer for glRead/CopyPixels() */ GLfloat RedBias, RedScale; GLfloat GreenBias, GreenScale; GLfloat BlueBias, BlueScale; @@ -973,7 +988,7 @@ struct gl_point_attrib GLfloat Threshold; /**< GL_EXT_point_parameters */ GLboolean _Attenuated; /**< True if Params != [1, 0, 0] */ GLboolean PointSprite; /**< GL_NV_point_sprite / GL_NV_point_sprite */ - GLboolean CoordReplace[MAX_TEXTURE_UNITS]; /**< GL_NV_point_sprite / GL_NV_point_sprite */ + GLboolean CoordReplace[MAX_TEXTURE_UNITS]; /**< GL_NV/ARB_point_sprite */ GLenum SpriteRMode; /**< GL_NV_point_sprite (only!) */ GLenum SpriteOrigin; /**< GL_ARB_point_sprite */ }; @@ -1136,6 +1151,10 @@ typedef void (*FetchTexelFuncF)( const struct gl_texture_image *texImage, GLfloat *texelOut ); +typedef void (*StoreTexelFunc)(struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + const void *texel); + /** * TexImage store function. This is called by the glTex[Sub]Image * functions and is responsible for converting the user-specified texture @@ -1191,6 +1210,8 @@ struct gl_texture_format FetchTexelFuncF FetchTexel2Df; FetchTexelFuncF FetchTexel3Df; /*@}*/ + + StoreTexelFunc StoreTexel; }; @@ -2001,64 +2022,174 @@ struct gl_shared_state }; + + /** - * Frame buffer. + * A renderbuffer stores colors or depth values or stencil values. + * A framebuffer object will have a collection of these. + * Data are read/written to the buffer with a handful of Get/Put functions. * - * A "frame buffer" is a color buffer and its optional ancillary buffers: - * depth, accum, stencil, and software-simulated alpha buffers. + * Instances of this object are allocated with the Driver's NewRenderbuffer + * hook. Drivers will likely wrap this class inside a driver-specific + * class to simulate inheritance. + */ +struct gl_renderbuffer +{ + GLuint Name; + GLint RefCount; + GLuint Width, Height; + GLenum InternalFormat; /* The user-specified value */ + GLenum _BaseFormat; /* Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or */ + /* GL_STENCIL_INDEX. */ + GLenum DataType; /* Type of values passed to the Get/Put functions */ + GLubyte ComponentSizes[4]; /* bits per component or channel */ + GLvoid *Data; + + /* Delete this renderbuffer */ + void (*Delete)(struct gl_renderbuffer *rb); + + /* Allocate new storage for this renderbuffer */ + GLboolean (*AllocStorage)(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height); + + /* Lock/Unlock are called before/after calling the Get/Put functions. + * Not sure this is the right place for these yet. + void (*Lock)(GLcontext *ctx, struct gl_renderbuffer *rb); + void (*Unlock)(GLcontext *ctx, struct gl_renderbuffer *rb); + */ + + /* Return a pointer to the element/pixel at (x,y). + * Should return NULL if the buffer memory can't be directly addressed. + */ + void *(*GetPointer)(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y); + + /* Get/Read a row of values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*GetRow)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values); + + /* Get/Read values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*GetValues)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values); + + /* Put/Write a row of values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutRow)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask); + + /* Put/Write a row of RGB values. This is a special-case routine that's + * only used for RGBA renderbuffers when the source data is GL_RGB. That's + * a common case for glDrawPixels and some triangle routines. + * The values will be of format GL_RGB and type DataType. + */ + void (*PutRowRGB)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask); + + + /* Put/Write a row of identical values. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutMonoRow)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask); + + /* Put/Write values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutValues)(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask); + /* Put/Write identical values at arbitrary locations. + * The values will be of format _BaseFormat and type DataType. + */ + void (*PutMonoValues)(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask); +}; + + +/** + * A renderbuffer attachment point points to either a texture object + * (and specifies a mipmap level, cube face or 3D texture slice) or + * points to a renderbuffer. + */ +struct gl_renderbuffer_attachment +{ + GLenum Type; /* GL_NONE or GL_TEXTURE or GL_RENDERBUFFER_EXT */ + GLboolean Complete; + + /* IF Type == GL_RENDERBUFFER_EXT: */ + struct gl_renderbuffer *Renderbuffer; + + /* IF Type == GL_TEXTURE: */ + struct gl_texture_object *Texture; + GLuint TextureLevel; + GLuint CubeMapFace; /* 0 .. 5, for cube map textures */ + GLuint Zoffset; /* for 3D textures */ +}; + + +/** + * A framebuffer is a collection of renderbuffers (color, depth, stencil, etc). * In C++ terms, think of this as a base class from which device drivers * will make derived classes. */ -struct gl_frame_buffer +struct gl_framebuffer { - GLvisual Visual; /**< The corresponding visual */ + GLuint Name; /* if zero, this is a window system framebuffer */ + GLint RefCount; - GLuint Width, Height; /**< size of frame buffer in pixels */ + GLvisual Visual; /**< The corresponding visual */ GLboolean Initialized; - GLboolean UseSoftwareDepthBuffer; - GLboolean UseSoftwareAccumBuffer; - GLboolean UseSoftwareStencilBuffer; - GLboolean UseSoftwareAlphaBuffers; - GLboolean UseSoftwareAuxBuffers; - - /** \name Software depth (aka Z) buffer */ - /*@{*/ - GLvoid *DepthBuffer; /**< array [Width*Height] of GLushort or GLuint*/ - /*@}*/ + GLuint Width, Height; /**< size of frame buffer in pixels */ - /** \name Software stencil buffer */ + /** \name Drawing bounds (Intersection of buffer size and scissor box) */ /*@{*/ - GLstencil *Stencil; /**< array [Width*Height] of GLstencil values */ + GLint _Xmin, _Xmax; /**< inclusive */ + GLint _Ymin, _Ymax; /**< exclusive */ /*@}*/ - /** \name Software accumulation buffer */ + /** \name Derived Z buffer stuff */ /*@{*/ - GLaccum *Accum; /**< array [4*Width*Height] of GLaccum values */ + GLuint _DepthMax; /**< Max depth buffer value */ + GLfloat _DepthMaxF; /**< Float max depth buffer value */ + GLfloat _MRD; /**< minimum resolvable difference in Z values */ /*@}*/ - /** \name Software alpha planes */ - /*@{*/ - GLchan *FrontLeftAlpha; /**< array [Width*Height] of GLchan */ - GLchan *BackLeftAlpha; /**< array [Width*Height] of GLchan */ - GLchan *FrontRightAlpha; /**< array [Width*Height] of GLchan */ - GLchan *BackRightAlpha; /**< array [Width*Height] of GLchan */ - /*@}*/ + GLenum _Status; /* One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */ - GLchan *AuxBuffers[MAX_AUX_BUFFERS]; + /* Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ + struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; - /** - * \name Drawing bounds - * - * Intersection of window size and scissor box + /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER + * attribute group and GL_PIXEL attribute group, respectively. */ - /*@{*/ - GLint _Xmin; /**< inclusive */ - GLint _Ymin; /**< inclusive */ - GLint _Xmax; /**< exclusive */ - GLint _Ymax; /**< exclusive */ - /*@}*/ + GLenum ColorDrawBuffer[MAX_DRAW_BUFFERS]; + GLenum ColorReadBuffer; + + /* These are computed from ColorDrawBuffer and ColorReadBuffer */ + GLuint _ColorDrawBufferMask[MAX_DRAW_BUFFERS]; /* Mask of BUFFER_BIT_* flags */ + GLuint _ColorReadBufferMask; /* Zero or one of BUFFER_BIT_ flags */ + + /* These are computed from _Draw/ReadBufferMask, above. */ + GLuint _NumColorDrawBuffers[MAX_DRAW_BUFFERS]; + struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4]; + struct gl_renderbuffer *_ColorReadBuffer; + +#if OLD_RENDERBUFFER + /* XXX THIS IS TEMPORARY */ + GLuint _ColorDrawBit[MAX_DRAW_BUFFERS][4]; +#endif + + /** Delete this framebuffer */ + void (*Delete)(struct gl_framebuffer *fb); }; @@ -2545,6 +2676,8 @@ struct __GLcontextRec GLvisual Visual; GLframebuffer *DrawBuffer; /**< buffer for writing */ GLframebuffer *ReadBuffer; /**< buffer for reading */ + GLframebuffer *WinSysDrawBuffer; /**< set with MakeCurrent */ + GLframebuffer *WinSysReadBuffer; /**< set with MakeCurrent */ /** * Device driver function pointer table @@ -2663,7 +2796,7 @@ struct __GLcontextRec /*@}*/ #if FEATURE_EXT_framebuffer_object - struct gl_framebuffer *CurrentFramebuffer; + /*struct gl_framebuffer *CurrentFramebuffer;*/ struct gl_renderbuffer *CurrentRenderbuffer; #endif @@ -2696,14 +2829,6 @@ struct __GLcontextRec * We don't have a better way to communicate this value from * swrast_setup to swrast. */ - - /** \name Z buffer stuff */ - /*@{*/ - GLuint DepthMax; /**< Max depth buffer value */ - GLfloat DepthMaxF; /**< Float max depth buffer value */ - GLfloat MRD; /**< minimum resolvable difference in Z values */ - /*@}*/ - /** \name Color clamping (tentative part of GL_ARB_color_clamp_control) */ /*@{*/ GLboolean ClampFragmentColors; diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 2b1434b62a..6497813a82 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -2108,11 +2108,9 @@ _mesa_init_pixel( GLcontext *ctx ) if (ctx->Visual.doubleBufferMode) { ctx->Pixel.ReadBuffer = GL_BACK; - ctx->Pixel._ReadSrcMask = DD_BACK_LEFT_BIT; } else { ctx->Pixel.ReadBuffer = GL_FRONT; - ctx->Pixel._ReadSrcMask = DD_FRONT_LEFT_BIT; } /* Miscellaneous */ diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index 6dbf81c37d..b771408cf3 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -313,7 +313,8 @@ void GLAPIENTRY _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) { GET_CURRENT_CONTEXT(ctx); - _mesa_PolygonOffset(factor, bias * ctx->DepthMaxF ); + /* XXX mult by DepthMaxF here??? */ + _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF ); } #endif diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c index 23285d0275..507eb9f984 100644 --- a/src/mesa/main/rastpos.c +++ b/src/mesa/main/rastpos.c @@ -466,7 +466,7 @@ raster_pos4f(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) + ctx->Viewport._WindowMap.m[MAT_TY]); ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ] + ctx->Viewport._WindowMap.m[MAT_TZ]) - / ctx->DepthMaxF; + / ctx->DrawBuffer->_DepthMaxF; ctx->Current.RasterPos[3] = clip[3]; /* compute raster distance */ diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c new file mode 100644 index 0000000000..7d21a8e358 --- /dev/null +++ b/src/mesa/main/renderbuffer.c @@ -0,0 +1,1863 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Functions for allocating/managing renderbuffers. + * Also, routines for reading/writing software-based renderbuffer data as + * ubytes, ushorts, uints, etc. + * + * The 'alpha8' renderbuffer is interesting. It's used to add a software-based + * alpha channel to RGB renderbuffers. This is done by wrapping the RGB + * renderbuffer with the alpha renderbuffer. We can do this because of the + * OO-nature of renderbuffers. + * + * 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 "mtypes.h" +#include "fbobject.h" +#include "renderbuffer.h" + + +#define COLOR_INDEX32 0x424243 + + +/* + * Routines for get/put values in common buffer formats follow. + * Someday add support for arbitrary row stride to make them more + * flexible. + */ + +/********************************************************************** + * Functions for buffers of 1 X GLushort values. + * Typically stencil. + */ + +static void * +get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + if (!rb->Data) + return NULL; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + return (GLubyte *) rb->Data + y * rb->Width + x; +} + + +static void +get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + _mesa_memcpy(values, src, count * sizeof(GLubyte)); +} + + +static void +get_values_ubyte(GLcontext *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->Width + x[i]; + dst[i] = *src; + } +} + + +static void +put_row_ubyte(GLcontext *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->Width + 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 { + _mesa_memcpy(dst, values, count * sizeof(GLubyte)); + } +} + + +static void +put_mono_row_ubyte(GLcontext *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->Width + 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(GLcontext *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->Width + x[i]; + *dst = src[i]; + } + } +} + + +static void +put_mono_values_ubyte(GLcontext *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->Width + x[i]; + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 1 X GLushort values. + * Typically depth/Z. + */ + +static void * +get_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + if (!rb->Data) + return NULL; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + ASSERT(rb->Width > 0); + return (GLushort *) rb->Data + y * rb->Width + x; +} + + +static void +get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const void *src = rb->GetPointer(ctx, rb, x, y); + ASSERT(rb->DataType == GL_UNSIGNED_SHORT); + _mesa_memcpy(values, src, count * sizeof(GLushort)); +} + + +static void +get_values_ushort(GLcontext *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->Width + x[i]; + dst[i] = *src; + } +} + + +static void +put_row_ushort(GLcontext *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->Width + 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 { + _mesa_memcpy(dst, src, count * sizeof(GLushort)); + } +} + + +static void +put_mono_row_ushort(GLcontext *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->Width + 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(GLcontext *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->Width + x[i]; + *dst = src[i]; + } + } +} + + +static void +put_mono_values_ushort(GLcontext *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->Width + x[i]; + *dst = val; + } + } + } + else { + GLuint i; + for (i = 0; i < count; i++) { + GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i]; + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 1 X GLuint values. + * Typically depth/Z or color index. + */ + +static void * +get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + if (!rb->Data) + return NULL; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + return (GLuint *) rb->Data + y * rb->Width + x; +} + + +static void +get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const void *src = rb->GetPointer(ctx, rb, x, y); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + _mesa_memcpy(values, src, count * sizeof(GLuint)); +} + + +static void +get_values_uint(GLcontext *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); + for (i = 0; i < count; i++) { + const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; + dst[i] = *src; + } +} + + +static void +put_row_uint(GLcontext *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->Width + x; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = src[i]; + } + } + } + else { + _mesa_memcpy(dst, src, count * sizeof(GLuint)); + } +} + + +static void +put_mono_row_uint(GLcontext *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->Width + x; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_INT); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i] = val; + } + } +} + + +static void +put_values_uint(GLcontext *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); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i]; + *dst = src[i]; + } + } +} + + +static void +put_mono_values_uint(GLcontext *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); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + 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(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + /* 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(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x); + GLubyte *dst = (GLubyte *) values; + GLuint i; + 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(GLcontext *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 + 3 * (y[i] * rb->Width + 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(GLcontext *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->Width + x); + GLuint i; + 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(GLcontext *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->Width + x); + GLuint i; + 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(GLcontext *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->Width + x); + assert(rb->DataType == GL_UNSIGNED_BYTE); + if (!mask && val0 == val1 && val1 == val2) { + /* optimized case */ + _mesa_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(GLcontext *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->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + 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(GLcontext *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->DataType == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + 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_pointer_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + if (!rb->Data) + return NULL; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + return (GLubyte *) rb->Data + 4 * (y * rb->Width + x); +} + + +static void +get_row_ubyte4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLbyte *src = (const GLbyte *) rb->Data + 4 * (y * rb->Width + x); + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + _mesa_memcpy(values, src, 4 * count * sizeof(GLbyte)); +} + + +static void +get_values_ubyte4(GLcontext *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); + for (i = 0; i < count; i++) { + const GLuint *src = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); + dst[i] = *src; + } +} + + +static void +put_row_ubyte4(GLcontext *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->Width + 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 { + _mesa_memcpy(dst, src, 4 * count * sizeof(GLubyte)); + } +} + + +static void +put_row_rgb_ubyte4(GLcontext *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->Width + x); + GLuint i; + assert(rb->DataType == GL_UNSIGNED_BYTE); + 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(GLcontext *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->Width + x); + assert(rb->DataType == GL_UNSIGNED_BYTE); + if (!mask && val == 0) { + /* common case */ + _mesa_bzero(dst, 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(GLcontext *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); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); + *dst = src[i]; + } + } +} + + +static void +put_mono_values_ubyte4(GLcontext *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); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLuint *dst = (GLuint *) rb->Data + (y[i] * rb->Width + x[i]); + *dst = val; + } + } +} + + +/********************************************************************** + * Functions for buffers of 4 X GLushort (or GLshort) values. + * Typically accum buffer. + */ + +static void * +get_pointer_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + if (!rb->Data) + return NULL; + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + return (GLushort *) rb->Data + 4 * (y * rb->Width + x); +} + + +static void +get_row_ushort4(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + const GLshort *src = (const GLshort *) rb->Data + 4 * (y * rb->Width + x); + ASSERT(rb->DataType == GL_UNSIGNED_SHORT || rb->DataType == GL_SHORT); + _mesa_memcpy(values, src, 4 * count * sizeof(GLshort)); +} + + +static void +get_values_ushort4(GLcontext *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->Width + x[i]); + dst[i] = *src; + } +} + + +static void +put_row_ushort4(GLcontext *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->Width + 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 { + _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); + } +} + + +static void +put_row_rgb_ushort4(GLcontext *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->Width + 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 { + _mesa_memcpy(dst, src, 4 * count * sizeof(GLushort)); + } +} + + +static void +put_mono_row_ushort4(GLcontext *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->Width + 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 */ + _mesa_bzero(dst, 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(GLcontext *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->Width + 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(GLcontext *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->Width + x[i]); + dst[0] = val0; + dst[1] = val1; + dst[2] = val2; + dst[3] = val3; + } + } +} + + + +/** + * 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. + */ +static GLboolean +soft_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + GLuint pixelSize; + + 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->_BaseFormat = GL_RGB; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLubyte); + rb->ComponentSizes[1] = 8 * sizeof(GLubyte); + rb->ComponentSizes[2] = 8 * sizeof(GLubyte); + rb->ComponentSizes[3] = 0; + pixelSize = 3 * sizeof(GLchan); + break; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + rb->_BaseFormat = GL_RGBA; + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetPointer = get_pointer_ubyte4; + rb->GetRow = get_row_ubyte4; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLubyte); + rb->ComponentSizes[1] = 8 * sizeof(GLubyte); + rb->ComponentSizes[2] = 8 * sizeof(GLubyte); + rb->ComponentSizes[3] = 8 * sizeof(GLubyte); + pixelSize = 4 * sizeof(GLubyte); + break; + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + rb->_BaseFormat = GL_RGBA; + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetPointer = get_pointer_ushort4; + rb->GetRow = get_row_ushort4; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLushort); + rb->ComponentSizes[1] = 8 * sizeof(GLushort); + rb->ComponentSizes[2] = 8 * sizeof(GLushort); + rb->ComponentSizes[3] = 8 * sizeof(GLushort); + pixelSize = 4 * sizeof(GLushort); + break; +#if 00 + case ALPHA8: + rb->_BaseFormat = GL_RGBA; /* Yes, not GL_ALPHA! */ + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetPointer = get_pointer_alpha8; + rb->GetRow = get_row_alpha8; + rb->GetValues = get_values_alpha8; + rb->PutRow = put_row_alpha8; + rb->PutRowRGB = NULL; + rb->PutMonoRow = put_mono_row_alpha8; + rb->PutValues = put_values_alpha8; + rb->PutMonoValues = put_mono_values_alpha8; + rb->ComponentSizes[0] = 0; /*red*/ + rb->ComponentSizes[1] = 0; /*green*/ + rb->ComponentSizes[2] = 0; /*blue*/ + rb->ComponentSizes[3] = 8 * sizeof(GLubyte); + pixelSize = sizeof(GLubyte); + break; +#endif + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + rb->_BaseFormat = GL_STENCIL_INDEX; + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetPointer = get_pointer_ubyte; + rb->GetRow = get_row_ubyte; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLubyte); + pixelSize = sizeof(GLubyte); + break; + case GL_STENCIL_INDEX16_EXT: + rb->_BaseFormat = GL_STENCIL_INDEX; + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetPointer = get_pointer_ushort; + rb->GetRow = get_row_ushort; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLushort); + pixelSize = sizeof(GLushort); + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetPointer = get_pointer_ushort; + rb->GetRow = get_row_ushort; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLushort); + pixelSize = sizeof(GLushort); + break; + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->DataType = GL_UNSIGNED_INT; + rb->GetPointer = get_pointer_uint; + rb->GetRow = get_row_uint; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLuint); + pixelSize = sizeof(GLuint); + break; + case GL_COLOR_INDEX8_EXT: + rb->_BaseFormat = GL_COLOR_INDEX; + rb->DataType = GL_UNSIGNED_BYTE; + rb->GetPointer = get_pointer_ubyte; + rb->GetRow = get_row_ubyte; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLubyte); + pixelSize = sizeof(GLubyte); + break; + case GL_COLOR_INDEX16_EXT: + rb->_BaseFormat = GL_COLOR_INDEX; + rb->DataType = GL_UNSIGNED_SHORT; + rb->GetPointer = get_pointer_ushort; + rb->GetRow = get_row_ushort; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLushort); + pixelSize = sizeof(GLushort); + break; + case COLOR_INDEX32: + rb->_BaseFormat = GL_COLOR_INDEX; + rb->DataType = GL_UNSIGNED_INT; + rb->GetPointer = get_pointer_uint; + rb->GetRow = get_row_uint; + 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; + rb->ComponentSizes[0] = 8 * sizeof(GLuint); + pixelSize = sizeof(GLuint); + break; + default: + _mesa_problem(ctx, "Bad internalFormat in soft_renderbuffer_storage"); + return GL_FALSE; + } + + ASSERT(rb->DataType); + ASSERT(rb->GetPointer); + ASSERT(rb->GetRow); + ASSERT(rb->GetValues); + ASSERT(rb->PutRow); + ASSERT(rb->PutMonoRow); + ASSERT(rb->PutValues); + ASSERT(rb->PutMonoValues); + ASSERT(rb->ComponentSizes[0] > 0); + + /* free old buffer storage */ + if (rb->Data) + _mesa_free(rb->Data); + + /* allocate new buffer storage */ + rb->Data = _mesa_malloc(width * height * pixelSize); + if (rb->Data == NULL) { + rb->Width = 0; + rb->Height = 0; + _mesa_error(ctx, GL_OUT_OF_MEMORY, "software renderbuffer allocation"); + return GL_FALSE; + } + + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + + return GL_TRUE; +} + + +/**********************************************************************/ +/**********************************************************************/ +/**********************************************************************/ + + +/** + * The alpha_renderbuffer class is used to augment an RGB renderbuffer with + * an alpha channel. The RGB buffer can be hardware-based. + * We basically wrap the RGB buffer. When PutRow is called (for example), + * we store the alpha values in this buffer, then pass on the PutRow call + * to the wrapped RGB buffer. + */ +struct alpha_renderbuffer +{ + struct gl_renderbuffer Base; /* the alpha buffer */ + struct gl_renderbuffer *RGBbuffer; /* the wrapped RGB buffer */ +}; + + +static GLboolean +alloc_storage_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + + /* first, pass the call to the wrapped RGB buffer */ + if (!arb->RGBbuffer->AllocStorage(ctx, arb->RGBbuffer, internalFormat, + width, height)) { + return GL_FALSE; + } + + /* next, resize my alpha buffer */ + if (arb->Base.Data) { + _mesa_free(arb->Base.Data); + } + + arb->Base.Data = _mesa_malloc(width * height * sizeof(GLubyte)); + if (arb->Base.Data == NULL) { + arb->Base.Width = 0; + arb->Base.Height = 0; + _mesa_error(ctx, GL_OUT_OF_MEMORY, "software alpha buffer allocation"); + return GL_FALSE; + } + + arb->Base.Width = width; + arb->Base.Height = height; + arb->Base.InternalFormat = internalFormat; + + return GL_TRUE; +} + + +/** + * Delete an alpha_renderbuffer object, as well as the wrapped RGB buffer. + */ +static void +delete_renderbuffer_alpha8(struct gl_renderbuffer *rb) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + if (arb->Base.Data) { + _mesa_free(arb->Base.Data); + } + assert(arb->RGBbuffer); + arb->RGBbuffer->Delete(arb->RGBbuffer); + arb->RGBbuffer = NULL; + _mesa_free(arb); +} + + +static void * +get_pointer_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + return NULL; /* don't allow direct access! */ +} + + +static void +get_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + /* NOTE: 'values' is RGBA format! */ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x; + GLubyte *dst = (GLubyte *) values; + GLuint i; + ASSERT(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->GetRow(ctx, arb->RGBbuffer, count, x, y, values); + /* second, fill in alpha values from this buffer! */ + for (i = 0; i < count; i++) { + dst[i * 4 + 3] = src[i]; + } +} + + +static void +get_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + GLubyte *dst = (GLubyte *) values; + GLuint i; + assert(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->GetValues(ctx, arb->RGBbuffer, count, x, y, values); + /* second, fill in alpha values from this buffer! */ + for (i = 0; i < count; i++) { + const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; + dst[i * 4 + 3] = *src; + } +} + + +static void +put_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + const GLubyte *src = (const GLubyte *) values; + GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; + GLuint i; + assert(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->PutRow(ctx, arb->RGBbuffer, count, x, y, values, mask); + /* second, store alpha in our buffer */ + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i] = src[i * 4 + 3]; + } + } +} + + +static void +put_row_rgb_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + const GLubyte *src = (const GLubyte *) values; + GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; + GLuint i; + assert(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->PutRowRGB(ctx, arb->RGBbuffer, count, x, y, values, mask); + /* second, store alpha in our buffer */ + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + dst[i] = src[i * 4 + 3]; + } + } +} + + +static void +put_mono_row_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + const GLubyte val = ((const GLubyte *) value)[3]; + GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x; + assert(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->PutMonoRow(ctx, arb->RGBbuffer, count, x, y, value, mask); + /* second, store alpha in our buffer */ + if (mask) { + GLuint i; + for (i = 0; i < count; i++) { + if (mask[i]) { + dst[i] = val; + } + } + } + else { + _mesa_memset(dst, val, count); + } +} + + +static void +put_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], + const void *values, const GLubyte *mask) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + const GLubyte *src = (const GLubyte *) values; + GLuint i; + assert(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, values, mask); + /* second, store alpha in our buffer */ + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; + *dst = src[i * 4 + 3]; + } + } +} + + +static void +put_mono_values_alpha8(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + struct alpha_renderbuffer *arb = (struct alpha_renderbuffer *) rb; + const GLubyte val = ((const GLubyte *) value)[3]; + GLuint i; + assert(rb->DataType == GL_UNSIGNED_BYTE); + /* first, pass the call to the wrapped RGB buffer */ + arb->RGBbuffer->PutValues(ctx, arb->RGBbuffer, count, x, y, value, mask); + /* second, store alpha in our buffer */ + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i]; + *dst = val; + } + } +} + + + +/**********************************************************************/ +/**********************************************************************/ +/**********************************************************************/ + + +/** + * Default GetPointer routine. Always return NULL to indicate that + * direct buffer access is not supported. + */ +static void * +nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) +{ + return NULL; +} + + +/** + * Initialize the fields of a gl_renderbuffer to default values. + */ +void +_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) +{ + rb->Name = name; + rb->RefCount = 1; + rb->Delete = _mesa_delete_renderbuffer; + + /* The rest of these should be set later by the caller of this function or + * the AllocStorage method: + */ + rb->AllocStorage = NULL; + + rb->Width = 0; + rb->Height = 0; + rb->InternalFormat = GL_NONE; + rb->_BaseFormat = GL_NONE; + rb->DataType = GL_NONE; + rb->ComponentSizes[0] = 0; + rb->ComponentSizes[1] = 0; + rb->ComponentSizes[2] = 0; + rb->ComponentSizes[3] = 0; + rb->Data = NULL; + + rb->GetPointer = nop_get_pointer; + rb->GetRow = NULL; + rb->GetValues = NULL; + rb->PutRow = NULL; + rb->PutRowRGB = NULL; + rb->PutMonoRow = NULL; + rb->PutValues = NULL; + rb->PutMonoValues = NULL; +} + + +/** + * Allocate a new gl_renderbuffer object. This can be used for user-created + * renderbuffers or window-system renderbuffers. + */ +struct gl_renderbuffer * +_mesa_new_renderbuffer(GLcontext *ctx, GLuint name) +{ + struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); + if (rb) { + _mesa_init_renderbuffer(rb, name); + } + return rb; +} + + +/** + * Delete a gl_framebuffer. + * This is the default function for framebuffer->Delete(). + */ +void +_mesa_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + if (rb->Data) { + _mesa_free(rb->Data); + } + _mesa_free(rb); +} + + +/** + * Allocate a software-based renderbuffer. This is called via the + * ctx->Driver.NewRenderbuffer() function when the user creates a new + * renderbuffer. + */ +struct gl_renderbuffer * +_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name) +{ + struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); + if (rb) { + rb->AllocStorage = soft_renderbuffer_storage; + /* Normally, one would setup the PutRow, GetRow, etc functions here. + * But we're doing that in the 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(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint rgbBits, GLuint alphaBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight) +{ + GLuint 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; + } + + if (rgbBits <= 8) { + if (alphaBits) + rb->InternalFormat = GL_RGBA8; + else + rb->InternalFormat = GL_RGB8; + } + else { + assert(rgbBits <= 16); + if (alphaBits) + rb->InternalFormat = GL_RGBA16; + else + rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */ + } + + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, b, rb); + } + + return GL_TRUE; +} + + +/** + * Add software-based color index 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_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint indexBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight) +{ + GLuint b; + + if (indexBits > 8) { + _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; + } + + if (indexBits <= 8) { + /* only support GLuint for now */ + /*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/ + rb->InternalFormat = COLOR_INDEX32; + } + else { + rb->InternalFormat = COLOR_INDEX32; + } + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, b, rb); + } + + return GL_TRUE; +} + + +/** + * Add software-based alpha 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_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint alphaBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight) +{ + GLuint b; + + /* for window system framebuffers only! */ + assert(fb->Name == 0); + + if (alphaBits > 8) { + _mesa_problem(ctx, + "Unsupported bit depth in _mesa_add_alpha_renderbuffers"); + return GL_FALSE; + } + + assert(MAX_COLOR_ATTACHMENTS >= 4); + + for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) { + struct alpha_renderbuffer *arb; + + 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; + + /* the RGB buffer to wrap must already exist!! */ + assert(fb->Attachment[b].Renderbuffer); + + /* only GLubyte supported for now */ + assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE); + + arb = CALLOC_STRUCT(alpha_renderbuffer); + if (!arb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer"); + return GL_FALSE; + } + + _mesa_init_renderbuffer(&arb->Base, 0); + + /* wrap the RGB buffer */ + arb->RGBbuffer = fb->Attachment[b].Renderbuffer; + + /* plug in my functions */ + arb->Base.InternalFormat = arb->RGBbuffer->InternalFormat; + arb->Base._BaseFormat = arb->RGBbuffer->_BaseFormat; + arb->Base.DataType = arb->RGBbuffer->DataType; + arb->Base.AllocStorage = alloc_storage_alpha8; + arb->Base.Delete = delete_renderbuffer_alpha8; + arb->Base.GetPointer = get_pointer_alpha8; + arb->Base.GetRow = get_row_alpha8; + arb->Base.GetValues = get_values_alpha8; + arb->Base.PutRow = put_row_alpha8; + arb->Base.PutRowRGB = put_row_rgb_alpha8; + arb->Base.PutMonoRow = put_mono_row_alpha8; + arb->Base.PutValues = put_values_alpha8; + arb->Base.PutMonoValues = put_mono_values_alpha8; + + /* clear the pointer to avoid assertion/sanity check failure later */ + fb->Attachment[b].Renderbuffer = NULL; + + /* plug the alpha renderbuffer into the colorbuffer attachment */ + _mesa_add_renderbuffer(fb, b, &arb->Base); + } + + 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(GLcontext *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 { + rb->InternalFormat = GL_DEPTH_COMPONENT32; + } + + rb->AllocStorage = 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(GLcontext *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; + } + + if (stencilBits <= 8) { + rb->InternalFormat = GL_STENCIL_INDEX8_EXT; + } + else { + /* not really supported (see s_stencil.c code) */ + rb->InternalFormat = GL_STENCIL_INDEX16_EXT; + } + + rb->AllocStorage = 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(GLcontext *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; + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, BUFFER_ACCUM, 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! + * + * NOTE: color-index aux buffers not supported. + */ +GLboolean +_mesa_add_aux_renderbuffers(GLcontext *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 accum buffer"); + return GL_FALSE; + } + + if (colorBits <= 8) { + rb->InternalFormat = GL_RGBA8; + } + else { + rb->InternalFormat = GL_RGBA16; + } + + rb->AllocStorage = soft_renderbuffer_storage; + _mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb); + } + return GL_TRUE; +} + + + +/** + * Attach a renderbuffer to a framebuffer. + */ +void +_mesa_add_renderbuffer(struct gl_framebuffer *fb, + GLuint bufferName, struct gl_renderbuffer *rb) +{ + assert(fb); + assert(rb); + /* there should be no previous renderbuffer on this attachment point! */ + assert(fb->Attachment[bufferName].Renderbuffer == NULL); + assert(bufferName < BUFFER_COUNT); + + /* winsys vs. user-created buffer cross check */ + if (fb->Name) { + assert(rb->Name); + } + else { + assert(!rb->Name); + } + + fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT; + fb->Attachment[bufferName].Complete = GL_TRUE; + fb->Attachment[bufferName].Renderbuffer = rb; +} diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h new file mode 100644 index 0000000000..5c11de7c8a --- /dev/null +++ b/src/mesa/main/renderbuffer.h @@ -0,0 +1,84 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef RENDERBUFFER_H +#define RENDERBUFFER_H + + +extern void +_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name); + +extern struct gl_renderbuffer * +_mesa_new_renderbuffer(GLcontext *ctx, GLuint name); + +extern void +_mesa_delete_renderbuffer(struct gl_renderbuffer *rb); + + +extern struct gl_renderbuffer * +_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name); + + +extern GLboolean +_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint rgbBits, GLuint alphaBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight); + +extern GLboolean +_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint indexBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight); + +extern GLboolean +_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint alphaBits, + GLboolean frontLeft, GLboolean backLeft, + GLboolean frontRight, GLboolean backRight); + +extern GLboolean +_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint depthBits); + +extern GLboolean +_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint stencilBits); + + +extern GLboolean +_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint redBits, GLuint greenBits, + GLuint blueBits, GLuint alphaBits); + +extern GLboolean +_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint bits, GLuint numBuffers); + +extern void +_mesa_add_renderbuffer(struct gl_framebuffer *fb, + GLuint bufferName, struct gl_renderbuffer *rb); + +#endif /* RENDERBUFFER_H */ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 540d3ce993..561f5763a2 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -61,6 +61,7 @@ #if FEATURE_EXT_framebuffer_object #include "fbobject.h" #endif +#include "framebuffer.h" #include "hint.h" #include "histogram.h" #include "imports.h" @@ -974,6 +975,9 @@ _mesa_update_state( GLcontext *ctx ) if (new_state & (_NEW_PROGRAM|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) _mesa_update_texture( ctx, new_state ); + if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) + _mesa_update_framebuffer(ctx); + if (new_state & (_NEW_SCISSOR|_NEW_BUFFERS)) _mesa_update_draw_buffer_bounds( ctx ); diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index a496cf8cbf..3cbc7c88f8 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -82,6 +82,13 @@ static void fetch_null_texelf( const struct gl_texture_image *texImage, _mesa_warning(NULL, "fetch_null_texelf() called!"); } +static void store_null_texel(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + /* no-op */ +} + + /***************************************************************/ /** \name Default GLchan-based formats */ @@ -107,6 +114,7 @@ const struct gl_texture_format _mesa_texformat_rgba = { fetch_texel_1d_f_rgba, /* FetchTexel1Df */ fetch_texel_2d_f_rgba, /* FetchTexel2Df */ fetch_texel_3d_f_rgba, /* FetchTexel3Df */ + store_texel_rgba /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb = { @@ -129,6 +137,7 @@ const struct gl_texture_format _mesa_texformat_rgb = { fetch_texel_1d_f_rgb, /* FetchTexel1Df */ fetch_texel_2d_f_rgb, /* FetchTexel2Df */ fetch_texel_3d_f_rgb, /* FetchTexel3Df */ + store_texel_rgb /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_alpha = { @@ -151,6 +160,7 @@ const struct gl_texture_format _mesa_texformat_alpha = { fetch_texel_1d_f_alpha, /* FetchTexel1Df */ fetch_texel_2d_f_alpha, /* FetchTexel2Df */ fetch_texel_3d_f_alpha, /* FetchTexel3Df */ + store_texel_alpha /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_luminance = { @@ -173,6 +183,7 @@ const struct gl_texture_format _mesa_texformat_luminance = { fetch_texel_1d_f_luminance, /* FetchTexel1Df */ fetch_texel_2d_f_luminance, /* FetchTexel2Df */ fetch_texel_3d_f_luminance, /* FetchTexel3Df */ + store_texel_luminance /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_luminance_alpha = { @@ -195,6 +206,7 @@ const struct gl_texture_format _mesa_texformat_luminance_alpha = { fetch_texel_1d_f_luminance_alpha, /* FetchTexel1Df */ fetch_texel_2d_f_luminance_alpha, /* FetchTexel2Df */ fetch_texel_3d_f_luminance_alpha, /* FetchTexel3Df */ + store_texel_luminance_alpha /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_intensity = { @@ -217,6 +229,7 @@ const struct gl_texture_format _mesa_texformat_intensity = { fetch_texel_1d_f_intensity, /* FetchTexel1Df */ fetch_texel_2d_f_intensity, /* FetchTexel2Df */ fetch_texel_3d_f_intensity, /* FetchTexel3Df */ + store_texel_intensity /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_depth_component_float32 = { @@ -239,6 +252,7 @@ const struct gl_texture_format _mesa_texformat_depth_component_float32 = { fetch_texel_1d_f_depth_component_f32,/* FetchTexel1Df */ fetch_texel_2d_f_depth_component_f32,/* FetchTexel2Df */ fetch_texel_3d_f_depth_component_f32,/* FetchTexel3Df */ + store_texel_depth_component_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_depth_component16 = { @@ -261,6 +275,7 @@ const struct gl_texture_format _mesa_texformat_depth_component16 = { fetch_texel_1d_f_depth_component16, /* FetchTexel1Df */ fetch_texel_2d_f_depth_component16, /* FetchTexel2Df */ fetch_texel_3d_f_depth_component16, /* FetchTexel3Df */ + store_texel_depth_component16 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgba_float32 = { @@ -283,6 +298,7 @@ const struct gl_texture_format _mesa_texformat_rgba_float32 = { fetch_texel_1d_f_rgba_f32, /* FetchTexel1Df */ fetch_texel_2d_f_rgba_f32, /* FetchTexel2Df */ fetch_texel_3d_f_rgba_f32, /* FetchTexel3Df */ + store_texel_rgba_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgba_float16 = { @@ -305,6 +321,7 @@ const struct gl_texture_format _mesa_texformat_rgba_float16 = { fetch_texel_1d_f_rgba_f16, /* FetchTexel1Df */ fetch_texel_2d_f_rgba_f16, /* FetchTexel2Df */ fetch_texel_3d_f_rgba_f16, /* FetchTexel3Df */ + store_texel_rgba_f16 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb_float32 = { @@ -327,6 +344,7 @@ const struct gl_texture_format _mesa_texformat_rgb_float32 = { fetch_texel_1d_f_rgb_f32, /* FetchTexel1Df */ fetch_texel_2d_f_rgb_f32, /* FetchTexel2Df */ fetch_texel_3d_f_rgb_f32, /* FetchTexel3Df */ + store_texel_rgb_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb_float16 = { @@ -348,7 +366,8 @@ const struct gl_texture_format _mesa_texformat_rgb_float16 = { fetch_texel_3d_rgb_f16, /* FetchTexel1D */ fetch_texel_1d_f_rgb_f16, /* FetchTexel1Df */ fetch_texel_2d_f_rgb_f16, /* FetchTexel2Df */ - fetch_texel_3d_f_rgb_f16 /* FetchTexel3Df */ + fetch_texel_3d_f_rgb_f16, /* FetchTexel3Df */ + store_texel_rgb_f16 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_alpha_float32 = { @@ -370,7 +389,8 @@ const struct gl_texture_format _mesa_texformat_alpha_float32 = { fetch_texel_3d_alpha_f32, /* FetchTexel1D */ fetch_texel_1d_f_alpha_f32, /* FetchTexel1Df */ fetch_texel_2d_f_alpha_f32, /* FetchTexel2Df */ - fetch_texel_3d_f_alpha_f32 /* FetchTexel3Df */ + fetch_texel_3d_f_alpha_f32, /* FetchTexel3Df */ + store_texel_alpha_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_alpha_float16 = { @@ -392,7 +412,8 @@ const struct gl_texture_format _mesa_texformat_alpha_float16 = { fetch_texel_3d_alpha_f16, /* FetchTexel1D */ fetch_texel_1d_f_alpha_f16, /* FetchTexel1Df */ fetch_texel_2d_f_alpha_f16, /* FetchTexel2Df */ - fetch_texel_3d_f_alpha_f16 /* FetchTexel3Df */ + fetch_texel_3d_f_alpha_f16, /* FetchTexel3Df */ + store_texel_alpha_f16 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_luminance_float32 = { @@ -414,7 +435,8 @@ const struct gl_texture_format _mesa_texformat_luminance_float32 = { fetch_texel_3d_luminance_f32, /* FetchTexel3D */ fetch_texel_1d_f_luminance_f32, /* FetchTexel1Df */ fetch_texel_2d_f_luminance_f32, /* FetchTexel2Df */ - fetch_texel_3d_f_luminance_f32 /* FetchTexel3Df */ + fetch_texel_3d_f_luminance_f32, /* FetchTexel3Df */ + store_texel_luminance_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_luminance_float16 = { @@ -436,7 +458,8 @@ const struct gl_texture_format _mesa_texformat_luminance_float16 = { fetch_texel_3d_luminance_f16, /* FetchTexel3D */ fetch_texel_1d_f_luminance_f16, /* FetchTexel1Df */ fetch_texel_2d_f_luminance_f16, /* FetchTexel2Df */ - fetch_texel_3d_f_luminance_f16 /* FetchTexel3Df */ + fetch_texel_3d_f_luminance_f16, /* FetchTexel3Df */ + store_texel_luminance_f16 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_luminance_alpha_float32 = { @@ -458,7 +481,8 @@ const struct gl_texture_format _mesa_texformat_luminance_alpha_float32 = { fetch_texel_3d_luminance_alpha_f32, /* FetchTexel3D */ fetch_texel_1d_f_luminance_alpha_f32,/* FetchTexel1Df */ fetch_texel_2d_f_luminance_alpha_f32,/* FetchTexel2Df */ - fetch_texel_3d_f_luminance_alpha_f32 /* FetchTexel3Df */ + fetch_texel_3d_f_luminance_alpha_f32,/* FetchTexel3Df */ + store_texel_luminance_alpha_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_luminance_alpha_float16 = { @@ -480,7 +504,8 @@ const struct gl_texture_format _mesa_texformat_luminance_alpha_float16 = { fetch_texel_3d_luminance_alpha_f16, /* FetchTexel3D */ fetch_texel_1d_f_luminance_alpha_f16,/* FetchTexel1Df */ fetch_texel_2d_f_luminance_alpha_f16,/* FetchTexel2Df */ - fetch_texel_3d_f_luminance_alpha_f16 /* FetchTexel3Df */ + fetch_texel_3d_f_luminance_alpha_f16,/* FetchTexel3Df */ + store_texel_luminance_alpha_f16 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_intensity_float32 = { @@ -502,7 +527,8 @@ const struct gl_texture_format _mesa_texformat_intensity_float32 = { fetch_texel_3d_intensity_f32, /* FetchTexel3D */ fetch_texel_1d_f_intensity_f32, /* FetchTexel1Df */ fetch_texel_2d_f_intensity_f32, /* FetchTexel2Df */ - fetch_texel_3d_f_intensity_f32 /* FetchTexel3Df */ + fetch_texel_3d_f_intensity_f32, /* FetchTexel3Df */ + store_texel_intensity_f32 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_intensity_float16 = { @@ -524,7 +550,8 @@ const struct gl_texture_format _mesa_texformat_intensity_float16 = { fetch_texel_3d_intensity_f16, /* FetchTexel3D */ fetch_texel_1d_f_intensity_f16, /* FetchTexel1Df */ fetch_texel_2d_f_intensity_f16, /* FetchTexel2Df */ - fetch_texel_3d_f_intensity_f16 /* FetchTexel3Df */ + fetch_texel_3d_f_intensity_f16, /* FetchTexel3Df */ + store_texel_intensity_f16 /* StoreTexel */ }; @@ -555,6 +582,7 @@ const struct gl_texture_format _mesa_texformat_rgba8888 = { fetch_texel_1d_f_rgba8888, /* FetchTexel1Df */ fetch_texel_2d_f_rgba8888, /* FetchTexel2Df */ fetch_texel_3d_f_rgba8888, /* FetchTexel3Df */ + store_texel_rgba8888 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgba8888_rev = { @@ -577,6 +605,7 @@ const struct gl_texture_format _mesa_texformat_rgba8888_rev = { fetch_texel_1d_f_rgba8888_rev, /* FetchTexel1Df */ fetch_texel_2d_f_rgba8888_rev, /* FetchTexel2Df */ fetch_texel_3d_f_rgba8888_rev, /* FetchTexel3Df */ + store_texel_rgba8888_rev /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_argb8888 = { @@ -599,6 +628,7 @@ const struct gl_texture_format _mesa_texformat_argb8888 = { fetch_texel_1d_f_argb8888, /* FetchTexel1Df */ fetch_texel_2d_f_argb8888, /* FetchTexel2Df */ fetch_texel_3d_f_argb8888, /* FetchTexel3Df */ + store_texel_argb8888 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_argb8888_rev = { @@ -621,6 +651,7 @@ const struct gl_texture_format _mesa_texformat_argb8888_rev = { fetch_texel_1d_f_argb8888_rev, /* FetchTexel1Df */ fetch_texel_2d_f_argb8888_rev, /* FetchTexel2Df */ fetch_texel_3d_f_argb8888_rev, /* FetchTexel3Df */ + store_texel_argb8888_rev /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb888 = { @@ -643,6 +674,7 @@ const struct gl_texture_format _mesa_texformat_rgb888 = { fetch_texel_1d_f_rgb888, /* FetchTexel1Df */ fetch_texel_2d_f_rgb888, /* FetchTexel2Df */ fetch_texel_3d_f_rgb888, /* FetchTexel3Df */ + store_texel_rgb888 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_bgr888 = { @@ -665,6 +697,7 @@ const struct gl_texture_format _mesa_texformat_bgr888 = { fetch_texel_1d_f_bgr888, /* FetchTexel1Df */ fetch_texel_2d_f_bgr888, /* FetchTexel2Df */ fetch_texel_3d_f_bgr888, /* FetchTexel3Df */ + store_texel_bgr888 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb565 = { @@ -687,6 +720,7 @@ const struct gl_texture_format _mesa_texformat_rgb565 = { fetch_texel_1d_f_rgb565, /* FetchTexel1Df */ fetch_texel_2d_f_rgb565, /* FetchTexel2Df */ fetch_texel_3d_f_rgb565, /* FetchTexel3Df */ + store_texel_rgb565 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb565_rev = { @@ -709,6 +743,7 @@ const struct gl_texture_format _mesa_texformat_rgb565_rev = { fetch_texel_1d_f_rgb565_rev, /* FetchTexel1Df */ fetch_texel_2d_f_rgb565_rev, /* FetchTexel2Df */ fetch_texel_3d_f_rgb565_rev, /* FetchTexel3Df */ + store_texel_rgb565_rev /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_argb4444 = { @@ -731,6 +766,7 @@ const struct gl_texture_format _mesa_texformat_argb4444 = { fetch_texel_1d_f_argb4444, /* FetchTexel1Df */ fetch_texel_2d_f_argb4444, /* FetchTexel2Df */ fetch_texel_3d_f_argb4444, /* FetchTexel3Df */ + store_texel_argb4444 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_argb4444_rev = { @@ -753,6 +789,7 @@ const struct gl_texture_format _mesa_texformat_argb4444_rev = { fetch_texel_1d_f_argb4444_rev, /* FetchTexel1Df */ fetch_texel_2d_f_argb4444_rev, /* FetchTexel2Df */ fetch_texel_3d_f_argb4444_rev, /* FetchTexel3Df */ + store_texel_argb4444_rev /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_argb1555 = { @@ -775,6 +812,7 @@ const struct gl_texture_format _mesa_texformat_argb1555 = { fetch_texel_1d_f_argb1555, /* FetchTexel1Df */ fetch_texel_2d_f_argb1555, /* FetchTexel2Df */ fetch_texel_3d_f_argb1555, /* FetchTexel3Df */ + store_texel_argb1555 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_argb1555_rev = { @@ -797,6 +835,7 @@ const struct gl_texture_format _mesa_texformat_argb1555_rev = { fetch_texel_1d_f_argb1555_rev, /* FetchTexel1Df */ fetch_texel_2d_f_argb1555_rev, /* FetchTexel2Df */ fetch_texel_3d_f_argb1555_rev, /* FetchTexel3Df */ + store_texel_argb1555_rev /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_al88 = { @@ -819,6 +858,7 @@ const struct gl_texture_format _mesa_texformat_al88 = { fetch_texel_1d_f_al88, /* FetchTexel1Df */ fetch_texel_2d_f_al88, /* FetchTexel2Df */ fetch_texel_3d_f_al88, /* FetchTexel3Df */ + store_texel_al88 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_al88_rev = { @@ -841,6 +881,7 @@ const struct gl_texture_format _mesa_texformat_al88_rev = { fetch_texel_1d_f_al88_rev, /* FetchTexel1Df */ fetch_texel_2d_f_al88_rev, /* FetchTexel2Df */ fetch_texel_3d_f_al88_rev, /* FetchTexel3Df */ + store_texel_al88_rev /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_rgb332 = { @@ -863,6 +904,7 @@ const struct gl_texture_format _mesa_texformat_rgb332 = { fetch_texel_1d_f_rgb332, /* FetchTexel1Df */ fetch_texel_2d_f_rgb332, /* FetchTexel2Df */ fetch_texel_3d_f_rgb332, /* FetchTexel3Df */ + store_texel_rgb332 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_a8 = { @@ -885,6 +927,7 @@ const struct gl_texture_format _mesa_texformat_a8 = { fetch_texel_1d_f_a8, /* FetchTexel1Df */ fetch_texel_2d_f_a8, /* FetchTexel2Df */ fetch_texel_3d_f_a8, /* FetchTexel3Df */ + store_texel_a8 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_l8 = { @@ -907,6 +950,7 @@ const struct gl_texture_format _mesa_texformat_l8 = { fetch_texel_1d_f_l8, /* FetchTexel1Df */ fetch_texel_2d_f_l8, /* FetchTexel2Df */ fetch_texel_3d_f_l8, /* FetchTexel3Df */ + store_texel_l8 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_i8 = { @@ -929,6 +973,7 @@ const struct gl_texture_format _mesa_texformat_i8 = { fetch_texel_1d_f_i8, /* FetchTexel1Df */ fetch_texel_2d_f_i8, /* FetchTexel2Df */ fetch_texel_3d_f_i8, /* FetchTexel3Df */ + store_texel_i8 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_ci8 = { @@ -951,6 +996,7 @@ const struct gl_texture_format _mesa_texformat_ci8 = { fetch_texel_1d_f_ci8, /* FetchTexel1Df */ fetch_texel_2d_f_ci8, /* FetchTexel2Df */ fetch_texel_3d_f_ci8, /* FetchTexel3Df */ + store_texel_ci8 /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_ycbcr = { @@ -973,6 +1019,7 @@ const struct gl_texture_format _mesa_texformat_ycbcr = { fetch_texel_1d_f_ycbcr, /* FetchTexel1Df */ fetch_texel_2d_f_ycbcr, /* FetchTexel2Df */ fetch_texel_3d_f_ycbcr, /* FetchTexel3Df */ + store_texel_ycbcr /* StoreTexel */ }; const struct gl_texture_format _mesa_texformat_ycbcr_rev = { @@ -995,6 +1042,7 @@ const struct gl_texture_format _mesa_texformat_ycbcr_rev = { fetch_texel_1d_f_ycbcr_rev, /* FetchTexel1Df */ fetch_texel_2d_f_ycbcr_rev, /* FetchTexel2Df */ fetch_texel_3d_f_ycbcr_rev, /* FetchTexel3Df */ + store_texel_ycbcr_rev /* StoreTexel */ }; /*@}*/ @@ -1024,6 +1072,7 @@ const struct gl_texture_format _mesa_null_texformat = { fetch_null_texelf, /* FetchTexel1Df */ fetch_null_texelf, /* FetchTexel2Df */ fetch_null_texelf, /* FetchTexel3Df */ + store_null_texel /* StoreTexel */ }; /*@}*/ diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h index 3df72291a1..7351929826 100644 --- a/src/mesa/main/texformat_tmp.h +++ b/src/mesa/main/texformat_tmp.h @@ -43,22 +43,22 @@ #if DIM == 1 -#define CHAN_SRC( t, i, j, k, sz ) \ +#define CHAN_ADDR( t, i, j, k, sz ) \ ((void) (j), (void) (k), \ ((GLchan *)(t)->Data + (i) * (sz))) -#define UBYTE_SRC( t, i, j, k, sz ) \ +#define UBYTE_ADDR( t, i, j, k, sz ) \ ((void) (j), (void) (k), \ ((GLubyte *)(t)->Data + (i) * (sz))) -#define USHORT_SRC( t, i, j, k ) \ +#define USHORT_ADDR( t, i, j, k ) \ ((void) (j), (void) (k), \ ((GLushort *)(t)->Data + (i))) -#define UINT_SRC( t, i, j, k ) \ +#define UINT_ADDR( t, i, j, k ) \ ((void) (j), (void) (k), \ ((GLuint *)(t)->Data + (i))) -#define FLOAT_SRC( t, i, j, k, sz ) \ +#define FLOAT_ADDR( t, i, j, k, sz ) \ ((void) (j), (void) (k), \ ((GLfloat *)(t)->Data + (i) * (sz))) -#define HALF_SRC( t, i, j, k, sz ) \ +#define HALF_ADDR( t, i, j, k, sz ) \ ((void) (j), (void) (k), \ ((GLhalfARB *)(t)->Data + (i) * (sz))) @@ -66,22 +66,22 @@ #elif DIM == 2 -#define CHAN_SRC( t, i, j, k, sz ) \ +#define CHAN_ADDR( t, i, j, k, sz ) \ ((void) (k), \ ((GLchan *)(t)->Data + ((t)->RowStride * (j) + (i)) * (sz))) -#define UBYTE_SRC( t, i, j, k, sz ) \ +#define UBYTE_ADDR( t, i, j, k, sz ) \ ((void) (k), \ ((GLubyte *)(t)->Data + ((t)->RowStride * (j) + (i)) * (sz))) -#define USHORT_SRC( t, i, j, k ) \ +#define USHORT_ADDR( t, i, j, k ) \ ((void) (k), \ ((GLushort *)(t)->Data + ((t)->RowStride * (j) + (i)))) -#define UINT_SRC( t, i, j, k ) \ +#define UINT_ADDR( t, i, j, k ) \ ((void) (k), \ ((GLuint *)(t)->Data + ((t)->RowStride * (j) + (i)))) -#define FLOAT_SRC( t, i, j, k, sz ) \ +#define FLOAT_ADDR( t, i, j, k, sz ) \ ((void) (k), \ ((GLfloat *)(t)->Data + ((t)->RowStride * (j) + (i)) * (sz))) -#define HALF_SRC( t, i, j, k, sz ) \ +#define HALF_ADDR( t, i, j, k, sz ) \ ((void) (k), \ ((GLhalfARB *)(t)->Data + ((t)->RowStride * (j) + (i)) * (sz))) @@ -89,22 +89,22 @@ #elif DIM == 3 -#define CHAN_SRC( t, i, j, k, sz ) \ +#define CHAN_ADDR( t, i, j, k, sz ) \ (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) * \ (t)->RowStride + (i)) * (sz) -#define UBYTE_SRC( t, i, j, k, sz ) \ +#define UBYTE_ADDR( t, i, j, k, sz ) \ ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) * \ (t)->RowStride + (i)) * (sz)) -#define USHORT_SRC( t, i, j, k ) \ +#define USHORT_ADDR( t, i, j, k ) \ ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) * \ (t)->RowStride + (i))) -#define UINT_SRC( t, i, j, k ) \ +#define UINT_ADDR( t, i, j, k ) \ ((GLuint *)(t)->Data + (((t)->Height * (k) + (j)) * \ (t)->RowStride + (i))) -#define FLOAT_SRC( t, i, j, k, sz ) \ +#define FLOAT_ADDR( t, i, j, k, sz ) \ ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \ (t)->RowStride + (i)) * (sz)) -#define HALF_SRC( t, i, j, k, sz ) \ +#define HALF_ADDR( t, i, j, k, sz ) \ ((GLhalfARB *)(t)->Data + (((t)->Height * (k) + (j)) * \ (t)->RowStride + (i)) * (sz)) @@ -115,11 +115,13 @@ #endif +/* MESA_FORMAT_RGBA **********************************************************/ + /* Fetch texel from 1D, 2D or 3D RGBA texture, returning 4 GLchans */ static void FETCH(rgba)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 4 ); COPY_CHAN4( texel, src ); } @@ -127,19 +129,34 @@ static void FETCH(rgba)( const struct gl_texture_image *texImage, static void FETCH(f_rgba)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 4 ); texel[RCOMP] = CHAN_TO_FLOAT(src[0]); texel[GCOMP] = CHAN_TO_FLOAT(src[1]); texel[BCOMP] = CHAN_TO_FLOAT(src[2]); texel[ACOMP] = CHAN_TO_FLOAT(src[3]); } +#if DIM == 3 +/* Store a GLchan RGBA texel */ +static void store_texel_rgba(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLchan *rgba = (const GLchan *) texel; + GLchan *dst = CHAN_ADDR(texImage, i, j, k, 4); + dst[0] = rgba[RCOMP]; + dst[1] = rgba[GCOMP]; + dst[2] = rgba[BCOMP]; + dst[3] = rgba[ACOMP]; +} +#endif + +/* MESA_FORMAT_RGB ***********************************************************/ /* Fetch texel from 1D, 2D or 3D RGB texture, returning 4 GLchans */ static void FETCH(rgb)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 3 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = src[0]; texel[GCOMP] = src[1]; texel[BCOMP] = src[2]; @@ -150,18 +167,32 @@ static void FETCH(rgb)( const struct gl_texture_image *texImage, static void FETCH(f_rgb)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 3 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = CHAN_TO_FLOAT(src[0]); texel[GCOMP] = CHAN_TO_FLOAT(src[1]); texel[BCOMP] = CHAN_TO_FLOAT(src[2]); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLchan *rgba = (const GLchan *) texel; + GLchan *dst = CHAN_ADDR(texImage, i, j, k, 3); + dst[0] = rgba[RCOMP]; + dst[1] = rgba[GCOMP]; + dst[2] = rgba[BCOMP]; +} +#endif + +/* MESA_FORMAT_ALPHA *********************************************************/ + /* Fetch texel from 1D, 2D or 3D ALPHA texture, returning 4 GLchans */ static void FETCH(alpha)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0; @@ -172,18 +203,30 @@ static void FETCH(alpha)( const struct gl_texture_image *texImage, static void FETCH(f_alpha)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0.0; texel[ACOMP] = CHAN_TO_FLOAT(src[0]); } +#if DIM == 3 +static void store_texel_alpha(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLchan *rgba = (const GLchan *) texel; + GLchan *dst = CHAN_ADDR(texImage, i, j, k, 1); + dst[0] = rgba[ACOMP]; +} +#endif + +/* MESA_FORMAT_LUMINANCE *****************************************************/ + /* Fetch texel from 1D, 2D or 3D LUMIN texture, returning 4 GLchans */ static void FETCH(luminance)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = src[0]; @@ -194,18 +237,30 @@ static void FETCH(luminance)( const struct gl_texture_image *texImage, static void FETCH(f_luminance)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = CHAN_TO_FLOAT(src[0]); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_luminance(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLchan *rgba = (const GLchan *) texel; + GLchan *dst = CHAN_ADDR(texImage, i, j, k, 1); + dst[0] = rgba[RCOMP]; +} +#endif + +/* MESA_FORMAT_LUMINANCE_ALPHA ***********************************************/ + /* Fetch texel from 1D, 2D or 3D L_A texture, returning 4 GLchans */ static void FETCH(luminance_alpha)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 2 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 2 ); texel[RCOMP] = src[0]; texel[GCOMP] = src[0]; texel[BCOMP] = src[0]; @@ -216,19 +271,31 @@ static void FETCH(luminance_alpha)( const struct gl_texture_image *texImage, static void FETCH(f_luminance_alpha)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 2 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 2 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = CHAN_TO_FLOAT(src[0]); texel[ACOMP] = CHAN_TO_FLOAT(src[1]); } +#if DIM == 3 +static void store_texel_luminance_alpha(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLchan *rgba = (const GLchan *) texel; + GLchan *dst = CHAN_ADDR(texImage, i, j, k, 2); + dst[0] = rgba[RCOMP]; + dst[1] = rgba[ACOMP]; +} +#endif + +/* MESA_FORMAT_INTENSITY *****************************************************/ /* Fetch texel from 1D, 2D or 3D INT. texture, returning 4 GLchans */ static void FETCH(intensity)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = src[0]; texel[GCOMP] = src[0]; texel[BCOMP] = src[0]; @@ -239,13 +306,25 @@ static void FETCH(intensity)( const struct gl_texture_image *texImage, static void FETCH(f_intensity)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + const GLchan *src = CHAN_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = texel[ACOMP] = CHAN_TO_FLOAT(src[0]); } +#if DIM == 3 +static void store_texel_intensity(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLchan *rgba = (const GLchan *) texel; + GLchan *dst = CHAN_ADDR(texImage, i, j, k, 1); + dst[0] = rgba[RCOMP]; +} +#endif + + +/* MESA_FORMAT_DEPTH_COMPONENT_F32 *******************************************/ /* Fetch depth texel from 1D, 2D or 3D float32 DEPTH texture, * returning 1 GLfloat. @@ -254,56 +333,94 @@ static void FETCH(f_intensity)( const struct gl_texture_image *texImage, static void FETCH(f_depth_component_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); texel[0] = src[0]; } +#if DIM == 3 +static void store_texel_depth_component_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *depth = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 1); + dst[0] = *depth; +} +#endif + + +/* MESA_FORMAT_DEPTH_COMPONENT16 *********************************************/ /* Fetch depth texel from 1D, 2D or 3D float32 DEPTH texture, * returning 1 GLfloat. * Note: no GLchan version of this function. */ -static void FETCH(f_depth_component16)( const struct gl_texture_image *texImage, +static void FETCH(f_depth_component16)(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); texel[0] = src[0] * (1.0F / 65535.0F); } +#if DIM == 3 +static void store_texel_depth_component16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLushort *depth = (const GLushort *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + dst[0] = *depth; +} +#endif + -/* Fetch texel from 1D, 2D or 3D RGBA_FLOAT32 texture, - * returning 4 GLchans. +/* MESA_FORMAT_RGBA_F32 ******************************************************/ + +/* Fetch texel from 1D, 2D or 3D RGBA_FLOAT32 texture, returning 4 GLchans. */ static void FETCH(rgba_f32)( const struct gl_texture_image *texImage, - GLint i, GLint j, GLint k, GLchan *texel ) + GLint i, GLint j, GLint k, GLchan *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 4 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 4 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], src[0]); UNCLAMPED_FLOAT_TO_CHAN(texel[GCOMP], src[1]); UNCLAMPED_FLOAT_TO_CHAN(texel[BCOMP], src[2]); UNCLAMPED_FLOAT_TO_CHAN(texel[ACOMP], src[3]); } -/* Fetch texel from 1D, 2D or 3D RGBA_FLOAT32 texture, - * returning 4 GLfloats. +/* Fetch texel from 1D, 2D or 3D RGBA_FLOAT32 texture, returning 4 GLfloats. */ static void FETCH(f_rgba_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 4 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 4 ); texel[RCOMP] = src[0]; texel[GCOMP] = src[1]; texel[BCOMP] = src[2]; texel[ACOMP] = src[3]; } +#if DIM == 3 +static void store_texel_rgba_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *depth = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 1); + dst[0] = depth[RCOMP]; + dst[1] = depth[GCOMP]; + dst[2] = depth[BCOMP]; + dst[3] = depth[ACOMP]; +} +#endif + + +/* MESA_FORMAT_RGBA_F16 ******************************************************/ + /* Fetch texel from 1D, 2D or 3D RGBA_FLOAT16 texture, * returning 4 GLchans. */ static void FETCH(rgba_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 4 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 4 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], _mesa_half_to_float(src[0])); UNCLAMPED_FLOAT_TO_CHAN(texel[GCOMP], _mesa_half_to_float(src[1])); UNCLAMPED_FLOAT_TO_CHAN(texel[BCOMP], _mesa_half_to_float(src[2])); @@ -316,20 +433,32 @@ static void FETCH(rgba_f16)( const struct gl_texture_image *texImage, static void FETCH(f_rgba_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 4 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 4 ); texel[RCOMP] = _mesa_half_to_float(src[0]); texel[GCOMP] = _mesa_half_to_float(src[1]); texel[BCOMP] = _mesa_half_to_float(src[2]); texel[ACOMP] = _mesa_half_to_float(src[3]); } +#if DIM == 3 +static void store_texel_rgba_f16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *depth = (const GLfloat *) texel; + GLhalfARB *dst = HALF_ADDR(texImage, i, j, k, 1); + dst[0] = _mesa_float_to_half(*depth); +} +#endif + +/* MESA_FORMAT_RGB_F32 *******************************************************/ + /* Fetch texel from 1D, 2D or 3D RGB_FLOAT32 texture, * returning 4 GLchans. */ static void FETCH(rgb_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 3 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 3 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], src[0]); UNCLAMPED_FLOAT_TO_CHAN(texel[GCOMP], src[1]); UNCLAMPED_FLOAT_TO_CHAN(texel[BCOMP], src[2]); @@ -342,20 +471,33 @@ static void FETCH(rgb_f32)( const struct gl_texture_image *texImage, static void FETCH(f_rgb_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 3 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = src[0]; texel[GCOMP] = src[1]; texel[BCOMP] = src[2]; texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *depth = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 1); + dst[0] = *depth; +} +#endif + + +/* MESA_FORAMT_RGB_F16 *******************************************************/ + /* Fetch texel from 1D, 2D or 3D RGBA_FLOAT16 texture, * returning 4 GLchans. */ static void FETCH(rgb_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 3 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 3 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], _mesa_half_to_float(src[0])); UNCLAMPED_FLOAT_TO_CHAN(texel[GCOMP], _mesa_half_to_float(src[1])); UNCLAMPED_FLOAT_TO_CHAN(texel[BCOMP], _mesa_half_to_float(src[2])); @@ -368,20 +510,33 @@ static void FETCH(rgb_f16)( const struct gl_texture_image *texImage, static void FETCH(f_rgb_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 3 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = _mesa_half_to_float(src[0]); texel[GCOMP] = _mesa_half_to_float(src[1]); texel[BCOMP] = _mesa_half_to_float(src[2]); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb_f16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *depth = (const GLfloat *) texel; + GLhalfARB *dst = HALF_ADDR(texImage, i, j, k, 1); + dst[0] = _mesa_float_to_half(*depth); +} +#endif + + +/* MESA_FORMAT_ALPHA_F32 *****************************************************/ + /* Fetch texel from 1D, 2D or 3D ALPHA_FLOAT32 texture, * returning 4 GLchans. */ static void FETCH(alpha_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0; @@ -394,20 +549,33 @@ static void FETCH(alpha_f32)( const struct gl_texture_image *texImage, static void FETCH(f_alpha_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0.0F; texel[ACOMP] = src[0]; } +#if DIM == 3 +static void store_texel_alpha_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 1); + dst[0] = rgba[ACOMP]; +} +#endif + + +/* MESA_FORMAT_ALPHA_F32 *****************************************************/ + /* Fetch texel from 1D, 2D or 3D ALPHA_FLOAT16 texture, * returning 4 GLchans. */ static void FETCH(alpha_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 1 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0; @@ -420,20 +588,33 @@ static void FETCH(alpha_f16)( const struct gl_texture_image *texImage, static void FETCH(f_alpha_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 1 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0.0F; texel[ACOMP] = _mesa_half_to_float(src[0]); } +#if DIM == 3 +static void store_texel_alpha_f16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLhalfARB *dst = HALF_ADDR(texImage, i, j, k, 1); + dst[0] = _mesa_float_to_half(rgba[ACOMP]); +} +#endif + + +/* MESA_FORMAT_LUMINANCE_F32 *************************************************/ + /* Fetch texel from 1D, 2D or 3D LUMINANCE_FLOAT32 texture, * returning 4 GLchans. */ static void FETCH(luminance_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], src[0]); texel[GCOMP] = texel[BCOMP] = texel[RCOMP]; @@ -446,20 +627,33 @@ static void FETCH(luminance_f32)( const struct gl_texture_image *texImage, static void FETCH(f_luminance_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = src[0]; texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_luminance_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 1); + dst[0] = rgba[RCOMP]; +} +#endif + + +/* MESA_FORMAT_LUMINANCE_F16 *************************************************/ + /* Fetch texel from 1D, 2D or 3D LUMINANCE_FLOAT16 texture, * returning 4 GLchans. */ static void FETCH(luminance_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 1 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 1 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], _mesa_half_to_float(src[0])); texel[GCOMP] = texel[BCOMP] = texel[RCOMP]; @@ -472,20 +666,33 @@ static void FETCH(luminance_f16)( const struct gl_texture_image *texImage, static void FETCH(f_luminance_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 1 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = _mesa_half_to_float(src[0]); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_luminance_f16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLhalfARB *dst = HALF_ADDR(texImage, i, j, k, 1); + dst[0] = _mesa_float_to_half(rgba[RCOMP]); +} +#endif + + +/* MESA_FORMAT_LUMINANCE_ALPHA_F32 *******************************************/ + /* Fetch texel from 1D, 2D or 3D LUMINANCE_ALPHA_FLOAT32 texture, * returning 4 GLchans. */ static void FETCH(luminance_alpha_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 2 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 2 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], src[0]); texel[GCOMP] = texel[BCOMP] = texel[RCOMP]; @@ -498,20 +705,34 @@ static void FETCH(luminance_alpha_f32)( const struct gl_texture_image *texImage, static void FETCH(f_luminance_alpha_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 2 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 2 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = src[0]; texel[ACOMP] = src[1]; } +#if DIM == 3 +static void store_texel_luminance_alpha_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 2); + dst[0] = rgba[RCOMP]; + dst[1] = rgba[ACOMP]; +} +#endif + + +/* MESA_FORMAT_LUMINANCE_ALPHA_F16 *******************************************/ + /* Fetch texel from 1D, 2D or 3D LUMINANCE_ALPHA_FLOAT16 texture, * returning 4 GLfloats. */ static void FETCH(luminance_alpha_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 2 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 2 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], _mesa_half_to_float(src[0])); texel[GCOMP] = texel[BCOMP] = texel[RCOMP]; @@ -524,20 +745,34 @@ static void FETCH(luminance_alpha_f16)( const struct gl_texture_image *texImage, static void FETCH(f_luminance_alpha_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 2 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 2 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = _mesa_half_to_float(src[0]); texel[ACOMP] = _mesa_half_to_float(src[1]); } +#if DIM == 3 +static void store_texel_luminance_alpha_f16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLhalfARB *dst = HALF_ADDR(texImage, i, j, k, 2); + dst[0] = _mesa_float_to_half(rgba[RCOMP]); + dst[1] = _mesa_float_to_half(rgba[ACOMP]); +} +#endif + + +/* MESA_FORMAT_INTENSITY_F32 *************************************************/ + /* Fetch texel from 1D, 2D or 3D INTENSITY_FLOAT32 texture, * returning 4 GLchans. */ static void FETCH(intensity_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], src[0]); texel[GCOMP] = texel[BCOMP] = @@ -550,20 +785,33 @@ static void FETCH(intensity_f32)( const struct gl_texture_image *texImage, static void FETCH(f_intensity_f32)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLfloat *src = FLOAT_SRC( texImage, i, j, k, 1 ); + const GLfloat *src = FLOAT_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = texel[ACOMP] = src[0]; } +#if DIM == 3 +static void store_texel_intensity_f32(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLfloat *dst = FLOAT_ADDR(texImage, i, j, k, 1); + dst[0] = rgba[RCOMP]; +} +#endif + + +/* MESA_FORMAT_INTENSITY_F16 *************************************************/ + /* Fetch texel from 1D, 2D or 3D INTENSITY_FLOAT16 texture, * returning 4 GLchans. */ static void FETCH(intensity_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 1 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 1 ); UNCLAMPED_FLOAT_TO_CHAN(texel[RCOMP], _mesa_half_to_float(src[0])); texel[GCOMP] = texel[BCOMP] = @@ -576,24 +824,37 @@ static void FETCH(intensity_f16)( const struct gl_texture_image *texImage, static void FETCH(f_intensity_f16)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLhalfARB *src = HALF_SRC( texImage, i, j, k, 1 ); + const GLhalfARB *src = HALF_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = texel[ACOMP] = _mesa_half_to_float(src[0]); } +#if DIM == 3 +static void store_texel_intensity_f16(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLfloat *rgba = (const GLfloat *) texel; + GLhalfARB *dst = HALF_ADDR(texImage, i, j, k, 1); + dst[0] = _mesa_float_to_half(rgba[RCOMP]); +} +#endif + + /* * Begin Hardware formats */ +/* MESA_FORMAT_RGBA8888 ******************************************************/ + /* Fetch texel from 1D, 2D or 3D rgba8888 texture, return 4 GLchans */ static void FETCH(rgba8888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_CHAN( (s >> 24) ); texel[GCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff ); texel[BCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff ); @@ -604,19 +865,31 @@ static void FETCH(rgba8888)( const struct gl_texture_image *texImage, static void FETCH(f_rgba8888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 24) ); texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); texel[ACOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); } +#if DIM == 3 +static void store_texel_rgba8888(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLuint *dst = UINT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_8888(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]); +} +#endif + + +/* MESA_FORMAT_RGBA888_REV ***************************************************/ /* Fetch texel from 1D, 2D or 3D abgr8888 texture, return 4 GLchans */ static void FETCH(rgba8888_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_CHAN( (s ) & 0xff ); texel[GCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff ); texel[BCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff ); @@ -627,19 +900,31 @@ static void FETCH(rgba8888_rev)( const struct gl_texture_image *texImage, static void FETCH(f_rgba8888_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); } +#if DIM == 3 +static void store_texel_rgba8888_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLuint *dst = UINT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_8888_REV(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]); +} +#endif + + +/* MESA_FORMAT_ARGB8888 ******************************************************/ /* Fetch texel from 1D, 2D or 3D argb8888 texture, return 4 GLchans */ static void FETCH(argb8888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff ); texel[GCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff ); texel[BCOMP] = UBYTE_TO_CHAN( (s ) & 0xff ); @@ -650,43 +935,66 @@ static void FETCH(argb8888)( const struct gl_texture_image *texImage, static void FETCH(f_argb8888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); texel[BCOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); texel[ACOMP] = UBYTE_TO_FLOAT( (s >> 24) ); } +#if DIM == 3 +static void store_texel_argb8888(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLuint *dst = UINT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_8888(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + +/* MESA_FORMAT_ARGB8888_REV **************************************************/ /* Fetch texel from 1D, 2D or 3D argb8888_rev texture, return 4 GLchans */ static void FETCH(argb8888_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_CHAN( (s >> 8) & 0xff ); texel[GCOMP] = UBYTE_TO_CHAN( (s >> 16) & 0xff ); texel[BCOMP] = UBYTE_TO_CHAN( (s >> 24) ); texel[ACOMP] = UBYTE_TO_CHAN( (s ) & 0xff ); } - /* Fetch texel from 1D, 2D or 3D argb8888_rev texture, return 4 GLfloats */ static void FETCH(f_argb8888_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLuint s = *UINT_SRC( texImage, i, j, k ); + const GLuint s = *UINT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_FLOAT( (s >> 8) & 0xff ); texel[GCOMP] = UBYTE_TO_FLOAT( (s >> 16) & 0xff ); texel[BCOMP] = UBYTE_TO_FLOAT( (s >> 24) ); texel[ACOMP] = UBYTE_TO_FLOAT( (s ) & 0xff ); } +#if DIM == 3 +static void store_texel_argb8888_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLuint *dst = UINT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_8888(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + +/* MESA_FORMAT_RGB888 ********************************************************/ /* Fetch texel from 1D, 2D or 3D rgb888 texture, return 4 GLchans */ static void FETCH(rgb888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 3 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = UBYTE_TO_CHAN( src[2] ); texel[GCOMP] = UBYTE_TO_CHAN( src[1] ); texel[BCOMP] = UBYTE_TO_CHAN( src[0] ); @@ -697,19 +1005,33 @@ static void FETCH(rgb888)( const struct gl_texture_image *texImage, static void FETCH(f_rgb888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 3 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = UBYTE_TO_FLOAT( src[2] ); texel[GCOMP] = UBYTE_TO_FLOAT( src[1] ); texel[BCOMP] = UBYTE_TO_FLOAT( src[0] ); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb888(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 3); + dst[0] = rgba[RCOMP]; + dst[1] = rgba[GCOMP]; + dst[2] = rgba[BCOMP]; +} +#endif + + +/* MESA_FORMAT_BGR888 ********************************************************/ /* Fetch texel from 1D, 2D or 3D bgr888 texture, return 4 GLchans */ static void FETCH(bgr888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 3 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = UBYTE_TO_CHAN( src[0] ); texel[GCOMP] = UBYTE_TO_CHAN( src[1] ); texel[BCOMP] = UBYTE_TO_CHAN( src[2] ); @@ -720,19 +1042,33 @@ static void FETCH(bgr888)( const struct gl_texture_image *texImage, static void FETCH(f_bgr888)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 3 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 3 ); texel[RCOMP] = UBYTE_TO_FLOAT( src[0] ); texel[GCOMP] = UBYTE_TO_FLOAT( src[1] ); texel[BCOMP] = UBYTE_TO_FLOAT( src[2] ); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_bgr888(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 3); + dst[0] = rgba[BCOMP]; + dst[1] = rgba[GCOMP]; + dst[2] = rgba[RCOMP]; +} +#endif + + +/* MESA_FORMAT_RGB565 ********************************************************/ /* Fetch texel from 1D, 2D or 3D rgb565 texture, return 4 GLchans */ static void FETCH(rgb565)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = *src; texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) * 255 / 0xf8 ); texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) * 255 / 0xfc ); @@ -744,7 +1080,7 @@ static void FETCH(rgb565)( const struct gl_texture_image *texImage, static void FETCH(f_rgb565)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = *src; texel[RCOMP] = ((s >> 8) & 0xf8) * (1.0F / 248.0F); texel[GCOMP] = ((s >> 3) & 0xfc) * (1.0F / 252.0F); @@ -752,12 +1088,24 @@ static void FETCH(f_rgb565)( const struct gl_texture_image *texImage, texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb565(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_565(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + +/* MESA_FORMAT_RGB565_REV ****************************************************/ /* Fetch texel from 1D, 2D or 3D rgb565_rev texture, return 4 GLchans */ static void FETCH(rgb565_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = (*src >> 8) | (*src << 8); /* byte swap */ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) * 255 / 0xf8 ); texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) * 255 / 0xfc ); @@ -769,7 +1117,7 @@ static void FETCH(rgb565_rev)( const struct gl_texture_image *texImage, static void FETCH(f_rgb565_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = (*src >> 8) | (*src << 8); /* byte swap */ texel[RCOMP] = ((s >> 8) & 0xf8) * (1.0F / 248.0F); texel[GCOMP] = ((s >> 3) & 0xfc) * (1.0F / 252.0F); @@ -777,12 +1125,24 @@ static void FETCH(f_rgb565_rev)( const struct gl_texture_image *texImage, texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb565_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_565(rgba[BCOMP], rgba[GCOMP], rgba[RCOMP]); +} +#endif + + +/* MESA_FORMAT_ARGB4444 ******************************************************/ /* Fetch texel from 1D, 2D or 3D argb444 texture, return 4 GLchans */ static void FETCH(argb4444)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = *src; texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); @@ -794,7 +1154,7 @@ static void FETCH(argb4444)( const struct gl_texture_image *texImage, static void FETCH(f_argb4444)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = *src; texel[RCOMP] = ((s >> 8) & 0xf) * (1.0F / 15.0F); texel[GCOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); @@ -802,12 +1162,24 @@ static void FETCH(f_argb4444)( const struct gl_texture_image *texImage, texel[ACOMP] = ((s >> 12) & 0xf) * (1.0F / 15.0F); } +#if DIM == 3 +static void store_texel_argb4444(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_4444(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP], rgba[ACOMP]); +} +#endif + + +/* MESA_FORMAT_ARGB4444_REV **************************************************/ /* Fetch texel from 1D, 2D or 3D argb4444_rev texture, return 4 GLchans */ static void FETCH(argb4444_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort s = *USHORT_SRC( texImage, i, j, k ); + const GLushort s = *USHORT_ADDR( texImage, i, j, k ); texel[RCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 12) & 0xf) * 255 / 0xf ); texel[BCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); @@ -818,19 +1190,31 @@ static void FETCH(argb4444_rev)( const struct gl_texture_image *texImage, static void FETCH(f_argb4444_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort s = *USHORT_SRC( texImage, i, j, k ); + const GLushort s = *USHORT_ADDR( texImage, i, j, k ); texel[RCOMP] = ((s ) & 0xf) * (1.0F / 15.0F); texel[GCOMP] = ((s >> 12) & 0xf) * (1.0F / 15.0F); texel[BCOMP] = ((s >> 8) & 0xf) * (1.0F / 15.0F); texel[ACOMP] = ((s >> 4) & 0xf) * (1.0F / 15.0F); } +#if DIM == 3 +static void store_texel_argb4444_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_4444(rgba[ACOMP], rgba[BCOMP], rgba[GCOMP], rgba[RCOMP]); +} +#endif + + +/* MESA_FORMAT_ARGB1555 ******************************************************/ /* Fetch texel from 1D, 2D or 3D argb1555 texture, return 4 GLchans */ static void FETCH(argb1555)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = *src; texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0x1f) * 255 / 0x1f ); texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0x1f) * 255 / 0x1f ); @@ -842,7 +1226,7 @@ static void FETCH(argb1555)( const struct gl_texture_image *texImage, static void FETCH(f_argb1555)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = *src; texel[RCOMP] = ((s >> 10) & 0x1f) * (1.0F / 31.0F); texel[GCOMP] = ((s >> 5) & 0x1f) * (1.0F / 31.0F); @@ -850,12 +1234,24 @@ static void FETCH(f_argb1555)( const struct gl_texture_image *texImage, texel[ACOMP] = ((s >> 15) & 0x01); } +#if DIM == 3 +static void store_texel_argb1555(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_1555(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + +/* MESA_FORMAT_ARGB1555_REV **************************************************/ /* Fetch texel from 1D, 2D or 3D argb1555_rev texture, return 4 GLchans */ static void FETCH(argb1555_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = (*src << 8) | (*src >> 8); /* byteswap */ texel[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0x1f) * 255 / 0x1f ); texel[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0x1f) * 255 / 0x1f ); @@ -867,7 +1263,7 @@ static void FETCH(argb1555_rev)( const struct gl_texture_image *texImage, static void FETCH(f_argb1555_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src = USHORT_SRC( texImage, i, j, k ); + const GLushort *src = USHORT_ADDR( texImage, i, j, k ); const GLushort s = (*src << 8) | (*src >> 8); /* byteswap */ texel[RCOMP] = ((s >> 10) & 0x1f) * (1.0F / 31.0F); texel[GCOMP] = ((s >> 5) & 0x1f) * (1.0F / 31.0F); @@ -875,12 +1271,24 @@ static void FETCH(f_argb1555_rev)( const struct gl_texture_image *texImage, texel[ACOMP] = ((s >> 15) & 0x01); } +#if DIM == 3 +static void store_texel_argb1555_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_1555_REV(rgba[ACOMP], rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + +/* MESA_FORMAT_AL88 **********************************************************/ /* Fetch texel from 1D, 2D or 3D al88 texture, return 4 GLchans */ static void FETCH(al88)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort s = *USHORT_SRC( texImage, i, j, k ); + const GLushort s = *USHORT_ADDR( texImage, i, j, k ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = UBYTE_TO_CHAN( s & 0xff ); @@ -891,19 +1299,31 @@ static void FETCH(al88)( const struct gl_texture_image *texImage, static void FETCH(f_al88)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort s = *USHORT_SRC( texImage, i, j, k ); + const GLushort s = *USHORT_ADDR( texImage, i, j, k ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = UBYTE_TO_FLOAT( s & 0xff ); texel[ACOMP] = UBYTE_TO_FLOAT( s >> 8 ); } +#if DIM == 3 +static void store_texel_al88(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_88(rgba[ACOMP], rgba[RCOMP]); +} +#endif + + +/* MESA_FORMAT_AL88_REV ******************************************************/ /* Fetch texel from 1D, 2D or 3D al88_rev texture, return 4 GLchans */ static void FETCH(al88_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort s = *USHORT_SRC( texImage, i, j, k ); + const GLushort s = *USHORT_ADDR( texImage, i, j, k ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = UBYTE_TO_CHAN( s >> 8 ); @@ -914,19 +1334,31 @@ static void FETCH(al88_rev)( const struct gl_texture_image *texImage, static void FETCH(f_al88_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort s = *USHORT_SRC( texImage, i, j, k ); + const GLushort s = *USHORT_ADDR( texImage, i, j, k ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = UBYTE_TO_FLOAT( s >> 8 ); texel[ACOMP] = UBYTE_TO_FLOAT( s & 0xff ); } +#if DIM == 3 +static void store_texel_al88_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLushort *dst = USHORT_ADDR(texImage, i, j, k); + *dst = PACK_COLOR_88(rgba[RCOMP], rgba[ACOMP]); +} +#endif + + +/* MESA_FORMAT_RGB332 ********************************************************/ /* Fetch texel from 1D, 2D or 3D rgb332 texture, return 4 GLchans */ static void FETCH(rgb332)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); const GLubyte s = *src; texel[RCOMP] = UBYTE_TO_CHAN( ((s ) & 0xe0) * 255 / 0xe0 ); texel[GCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xe0) * 255 / 0xe0 ); @@ -938,7 +1370,7 @@ static void FETCH(rgb332)( const struct gl_texture_image *texImage, static void FETCH(f_rgb332)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); const GLubyte s = *src; texel[RCOMP] = ((s ) & 0xe0) * (1.0F / 224.0F); texel[GCOMP] = ((s << 3) & 0xe0) * (1.0F / 224.0F); @@ -946,12 +1378,24 @@ static void FETCH(f_rgb332)( const struct gl_texture_image *texImage, texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_rgb332(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 1); + *dst = PACK_COLOR_332(rgba[RCOMP], rgba[GCOMP], rgba[BCOMP]); +} +#endif + + +/* MESA_FORMAT_A8 ************************************************************/ /* Fetch texel from 1D, 2D or 3D a8 texture, return 4 GLchans */ static void FETCH(a8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0; @@ -962,19 +1406,31 @@ static void FETCH(a8)( const struct gl_texture_image *texImage, static void FETCH(f_a8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = 0.0; texel[ACOMP] = UBYTE_TO_FLOAT( src[0] ); } +#if DIM == 3 +static void store_texel_a8(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 1); + *dst = rgba[ACOMP]; +} +#endif + + +/* MESA_FORMAT_L8 ************************************************************/ /* Fetch texel from 1D, 2D or 3D l8 texture, return 4 GLchans */ static void FETCH(l8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = UBYTE_TO_CHAN( src[0] ); @@ -985,19 +1441,31 @@ static void FETCH(l8)( const struct gl_texture_image *texImage, static void FETCH(f_l8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = UBYTE_TO_FLOAT( src[0] ); texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_l8(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 1); + *dst = rgba[RCOMP]; +} +#endif + + +/* MESA_FORMAT_I8 ************************************************************/ /* Fetch texel from 1D, 2D or 3D i8 texture, return 4 GLchans */ static void FETCH(i8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = @@ -1008,13 +1476,25 @@ static void FETCH(i8)( const struct gl_texture_image *texImage, static void FETCH(f_i8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); texel[RCOMP] = texel[GCOMP] = texel[BCOMP] = texel[ACOMP] = UBYTE_TO_FLOAT( src[0] ); } +#if DIM == 3 +static void store_texel_i8(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *rgba = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 1); + *dst = rgba[RCOMP]; +} +#endif + + +/* MESA_FORMAT_CI8 ***********************************************************/ /* Fetch CI texel from 1D, 2D or 3D ci8 texture, lookup the index in a * color table, and return 4 GLchans. @@ -1022,7 +1502,7 @@ static void FETCH(f_i8)( const struct gl_texture_image *texImage, static void FETCH(ci8)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + const GLubyte *src = UBYTE_ADDR( texImage, i, j, k, 1 ); const struct gl_color_table *palette; const GLchan *table; GLuint index; @@ -1101,6 +1581,18 @@ static void FETCH(f_ci8)( const struct gl_texture_image *texImage, texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]); } +#if DIM == 3 +static void store_texel_ci8(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + const GLubyte *index = (const GLubyte *) texel; + GLubyte *dst = UBYTE_ADDR(texImage, i, j, k, 1); + *dst = *index; +} +#endif + + +/* MESA_FORMAT_YCBCR *********************************************************/ /* Fetch texel from 1D, 2D or 3D ycbcr texture, return 4 GLchans */ /* We convert YCbCr to RGB here */ @@ -1108,7 +1600,7 @@ static void FETCH(f_ci8)( const struct gl_texture_image *texImage, static void FETCH(ycbcr)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src0 = USHORT_SRC( texImage, (i & ~1), j, k ); /* even */ + const GLushort *src0 = USHORT_ADDR( texImage, (i & ~1), j, k ); /* even */ const GLushort *src1 = src0 + 1; /* odd */ const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ const GLubyte cb = *src0 & 0xff; /* chroma U */ @@ -1138,7 +1630,7 @@ static void FETCH(ycbcr)( const struct gl_texture_image *texImage, static void FETCH(f_ycbcr)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src0 = USHORT_SRC( texImage, (i & ~1), j, k ); /* even */ + const GLushort *src0 = USHORT_ADDR( texImage, (i & ~1), j, k ); /* even */ const GLushort *src1 = src0 + 1; /* odd */ const GLubyte y0 = (*src0 >> 8) & 0xff; /* luminance */ const GLubyte cb = *src0 & 0xff; /* chroma U */ @@ -1168,6 +1660,16 @@ static void FETCH(f_ycbcr)( const struct gl_texture_image *texImage, texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_ycbcr(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + /* XXX to do */ +} +#endif + + +/* MESA_FORMAT_YCBCR_REV *****************************************************/ /* Fetch texel from 1D, 2D or 3D ycbcr_rev texture, return 4 GLchans */ /* We convert YCbCr to RGB here */ @@ -1175,7 +1677,7 @@ static void FETCH(f_ycbcr)( const struct gl_texture_image *texImage, static void FETCH(ycbcr_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *texel ) { - const GLushort *src0 = USHORT_SRC( texImage, (i & ~1), j, k ); /* even */ + const GLushort *src0 = USHORT_ADDR( texImage, (i & ~1), j, k ); /* even */ const GLushort *src1 = src0 + 1; /* odd */ const GLubyte y0 = *src0 & 0xff; /* luminance */ const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ @@ -1205,7 +1707,7 @@ static void FETCH(ycbcr_rev)( const struct gl_texture_image *texImage, static void FETCH(f_ycbcr_rev)( const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLfloat *texel ) { - const GLushort *src0 = USHORT_SRC( texImage, (i & ~1), j, k ); /* even */ + const GLushort *src0 = USHORT_ADDR( texImage, (i & ~1), j, k ); /* even */ const GLushort *src1 = src0 + 1; /* odd */ const GLubyte y0 = *src0 & 0xff; /* luminance */ const GLubyte cr = (*src0 >> 8) & 0xff; /* chroma V */ @@ -1235,13 +1737,21 @@ static void FETCH(f_ycbcr_rev)( const struct gl_texture_image *texImage, texel[ACOMP] = 1.0F; } +#if DIM == 3 +static void store_texel_ycbcr_rev(struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, const void *texel) +{ + /* XXX to do */ +} +#endif + -#undef CHAN_SRC -#undef UBYTE_SRC -#undef USHORT_SRC -#undef UINT_SRC -#undef FLOAT_SRC -#undef HALF_SRC +#undef CHAN_ADDR +#undef UBYTE_ADDR +#undef USHORT_ADDR +#undef UINT_ADDR +#undef FLOAT_ADDR +#undef HALF_ADDR #undef FETCH #undef DIM diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c new file mode 100644 index 0000000000..12afa93d01 --- /dev/null +++ b/src/mesa/main/texrender.c @@ -0,0 +1,197 @@ + +#include "context.h" +#include "fbobject.h" +#include "texrender.h" +#include "renderbuffer.h" + + +/* + * Render-to-texture code for GL_EXT_framebuffer_object + */ + + +/** + * Derived from gl_renderbuffer class + */ +struct texture_renderbuffer +{ + struct gl_renderbuffer Base; /* Base class object */ + struct gl_texture_image *TexImage; + StoreTexelFunc Store; + GLint Zoffset; +}; + + + +static void +texture_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, void *values) +{ + /* XXX unfinished */ +} + +static void +texture_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], void *values) +{ + /* XXX unfinished */ +} + +static void +texture_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *values, const GLubyte *mask) +{ + const struct texture_renderbuffer *trb + = (const struct texture_renderbuffer *) rb; + const GLint z = trb->Zoffset; + const GLchan *rgba = (const GLchan *) values; + GLuint i; + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + trb->Store(trb->TexImage, x + i, y, z, rgba); + } + rgba += 4; + } +} + +static void +texture_put_mono_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + GLint x, GLint y, const void *value, const GLubyte *mask) +{ + const struct texture_renderbuffer *trb + = (const struct texture_renderbuffer *) rb; + const GLint z = trb->Zoffset; + const GLchan *rgba = (const GLchan *) value; + GLuint i; + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + trb->Store(trb->TexImage, x + i, y, z, rgba); + } + } +} + +static void +texture_put_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, + const GLint x[], const GLint y[], const void *values, + const GLubyte *mask) +{ + const struct texture_renderbuffer *trb + = (const struct texture_renderbuffer *) rb; + const GLint z = trb->Zoffset; + const GLchan *rgba = (const GLchan *) values; + GLuint i; + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + trb->Store(trb->TexImage, x[i], y[i], z, rgba); + } + rgba += 4; + } +} + +static void +texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte *mask) +{ + const struct texture_renderbuffer *trb + = (const struct texture_renderbuffer *) rb; + const GLint z = trb->Zoffset; + const GLchan *rgba = (const GLchan *) value; + GLuint i; + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { + trb->Store(trb->TexImage, x[i], y[i], z, rgba); + } + } +} + + +static void +delete_texture_wrapper(struct gl_renderbuffer *rb) +{ + _mesa_free(rb); +} + + +/** + * If a render buffer attachment specifies a texture image, we'll use + * this function to make a gl_renderbuffer wrapper around the texture image. + * This allows other parts of Mesa to access the texture image as if it + * was a renderbuffer. + */ +static void +wrap_texture(GLcontext *ctx, struct gl_renderbuffer_attachment *att) +{ + struct texture_renderbuffer *trb; + const GLuint name = 0; + + ASSERT(att->Type == GL_TEXTURE); + ASSERT(att->Renderbuffer == NULL); + /* + ASSERT(att->Complete); + */ + + trb = CALLOC_STRUCT(texture_renderbuffer); + if (!trb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "wrap_texture"); + return; + } + + _mesa_init_renderbuffer(&trb->Base, name); + + trb->TexImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + assert(trb->TexImage); + + trb->Store = trb->TexImage->TexFormat->StoreTexel; + assert(trb->Store); + + trb->Zoffset = att->Zoffset; + + trb->Base.Width = trb->TexImage->Width; + trb->Base.Height = trb->TexImage->Height; + trb->Base.InternalFormat = trb->TexImage->IntFormat; /* XXX fix? */ + trb->Base._BaseFormat = trb->TexImage->TexFormat->BaseFormat; + assert(trb->Base._BaseFormat == GL_RGB || + trb->Base._BaseFormat == GL_RGBA || + trb->Base._BaseFormat == GL_DEPTH_COMPONENT); + trb->Base.DataType = GL_UNSIGNED_BYTE; /* XXX fix! */ + trb->Base.Data = trb->TexImage->Data; + + trb->Base.GetRow = texture_get_row; + trb->Base.GetValues = texture_get_values; + trb->Base.PutRow = texture_put_row; + trb->Base.PutMonoRow = texture_put_mono_row; + trb->Base.PutValues = texture_put_values; + trb->Base.PutMonoValues = texture_put_mono_values; + + trb->Base.Delete = delete_texture_wrapper; + trb->Base.AllocStorage = NULL; /* illegal! */ + + att->Renderbuffer = &(trb->Base); +} + + + +/** + * Software fallback for ctx->Driver.RenderbufferTexture. + * This is called via the glRenderbufferTexture1D/2D/3D() functions. + * If we're unbinding a texture, texObj will be NULL. + * The framebuffer of interest is ctx->DrawBuffer. + * \sa _mesa_framebuffer_renderbuffer + */ +void +_mesa_renderbuffer_texture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_texture_object *texObj, + GLenum texTarget, GLuint level, GLuint zoffset) +{ + if (texObj) { + _mesa_set_texture_attachment(ctx, att, texObj, + texTarget, level, zoffset); + + wrap_texture(ctx, att); + } + else { + _mesa_remove_attachment(ctx, att); + } +} diff --git a/src/mesa/main/texrender.h b/src/mesa/main/texrender.h new file mode 100644 index 0000000000..6d8bc96414 --- /dev/null +++ b/src/mesa/main/texrender.h @@ -0,0 +1,12 @@ +#ifndef TEXRENDER_H +#define TEXRENDER_H + + +extern void +_mesa_renderbuffer_texture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att, + struct gl_texture_object *texObj, + GLenum texTarget, GLuint level, GLuint zoffset); + + +#endif /* TEXRENDER_H */ diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 3a8ccb3984..02f2dbe69f 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -2200,8 +2200,8 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, return; } - pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels, - packing, "glTexImage1D"); + pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, + pixels, packing, "glTexImage1D"); if (!pixels) { /* Note: we check for a NULL image pointer here, _after_ we allocated * memory for the texture. That's what the GL spec calls for. @@ -2289,7 +2289,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, } pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, - pixels, packing, "glTexImage2D"); + pixels, packing, "glTexImage2D"); if (!pixels) { /* Note: we check for a NULL image pointer here, _after_ we allocated * memory for the texture. That's what the GL spec calls for. @@ -2368,8 +2368,8 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, return; } - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, type, - pixels, packing, "glTexImage3D"); + pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, + type, pixels, packing, "glTexImage3D"); if (!pixels) { /* Note: we check for a NULL image pointer here, _after_ we allocated * memory for the texture. That's what the GL spec calls for. @@ -2425,8 +2425,8 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, pixels, - packing, "glTexSubImage1D"); + pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, + pixels, packing, "glTexSubImage1D"); if (!pixels) return; @@ -2472,7 +2472,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, - pixels, packing, "glTexSubImage2D"); + pixels, packing, "glTexSubImage2D"); if (!pixels) return; @@ -2523,8 +2523,9 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, type, - pixels, packing, "glTexSubImage3D"); + pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, + type, pixels, packing, + "glTexSubImage3D"); if (!pixels) return; @@ -2625,8 +2626,9 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, return; } - data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack, - "glCompressedTexImage2D"); + data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, + &ctx->Unpack, + "glCompressedTexImage2D"); if (!data) return; @@ -2719,8 +2721,9 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, ASSERT((xoffset & 3) == 0); ASSERT((yoffset & 3) == 0); - data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, &ctx->Unpack, - "glCompressedTexSubImage2D"); + data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, + &ctx->Unpack, + "glCompressedTexSubImage2D"); if (!data) return; |