summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/accum.c19
-rw-r--r--src/mesa/main/attrib.c7
-rw-r--r--src/mesa/main/blend.c2
-rw-r--r--src/mesa/main/bufferobj.c2
-rw-r--r--src/mesa/main/buffers.c548
-rw-r--r--src/mesa/main/buffers.h7
-rw-r--r--src/mesa/main/config.h13
-rw-r--r--src/mesa/main/context.c241
-rw-r--r--src/mesa/main/context.h36
-rw-r--r--src/mesa/main/dd.h15
-rw-r--r--src/mesa/main/depth.c5
-rw-r--r--src/mesa/main/dlist.c13
-rw-r--r--src/mesa/main/enable.c21
-rw-r--r--src/mesa/main/extensions.c2
-rw-r--r--src/mesa/main/fbobject.c379
-rw-r--r--src/mesa/main/fbobject.h141
-rw-r--r--src/mesa/main/framebuffer.c513
-rw-r--r--src/mesa/main/framebuffer.h67
-rw-r--r--src/mesa/main/get.c114
-rw-r--r--src/mesa/main/get_gen.py54
-rw-r--r--src/mesa/main/matrix.c16
-rw-r--r--src/mesa/main/mtypes.h297
-rw-r--r--src/mesa/main/pixel.c2
-rw-r--r--src/mesa/main/polygon.c3
-rw-r--r--src/mesa/main/rastpos.c2
-rw-r--r--src/mesa/main/renderbuffer.c1863
-rw-r--r--src/mesa/main/renderbuffer.h84
-rw-r--r--src/mesa/main/state.c4
-rw-r--r--src/mesa/main/texformat.c67
-rw-r--r--src/mesa/main/texformat_tmp.h730
-rw-r--r--src/mesa/main/texrender.c197
-rw-r--r--src/mesa/main/texrender.h12
-rw-r--r--src/mesa/main/texstore.c31
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;