if (ctx->DrawBuffer->Name) {
/* User created FBO */
struct intel_renderbuffer *irb
- = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
+ = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
if (irb && !irb->RenderToTexture) {
/* y=0=top */
yScale = -1.0;
/* We can only handle a single draw buffer at the moment, and only as the
* first color buffer.
*/
- for (i = 0; i < MAX_DRAW_BUFFERS; i++) {
- if (fb->_NumColorDrawBuffers[i] > (i == 0 ? 1 : 0)) {
- DBG("FALLBACK: draw buffer %d: 0x%08x\n",
- i, ctx->DrawBuffer->_ColorDrawBufferMask[i]);
- return GL_TRUE;
- }
+ if (fb->_NumColorDrawBuffers > 1) {
+ DBG("FALLBACK: multiple color draw buffers\n");
+ return GL_TRUE;
}
/* _NEW_RENDERMODE
const GLfloat depth_scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
struct brw_sf_viewport sfv;
struct intel_renderbuffer *irb =
- intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
+ intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
GLfloat y_scale, y_bias;
memset(&sfv, 0, sizeof(sfv));
intel_drawbuf_region(struct intel_context *intel)
{
struct intel_renderbuffer *irbColor =
- intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]);
+ intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);
if (irbColor)
return irbColor->region;
else
/*
* How many color buffers are we drawing into?
*/
- if (fb->_NumColorDrawBuffers[0] != 1) {
+ if (fb->_NumColorDrawBuffers != 1) {
/* writing to 0 or 2 or 4 color buffers */
/*_mesa_debug(ctx, "Software rendering\n");*/
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
/* drawing to user-created FBO */
struct intel_renderbuffer *irb;
intelSetRenderbufferClipRects(intel);
- irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]);
+ irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
colorRegion = (irb && irb->region) ? irb->region : NULL;
}
}
struct intel_renderbuffer *irb;
/* color draw buffers */
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) {
- struct gl_renderbuffer *rb =
- ctx->DrawBuffer->_ColorDrawBuffers[i][j];
- irb = intel_renderbuffer(rb);
- if (irb) {
- /* this is a user-created intel_renderbuffer */
- if (irb->region) {
- if (map)
- intel_region_map(intel, irb->region);
- else
- intel_region_unmap(intel, irb->region);
- irb->pfMap = irb->region->map;
- irb->pfPitch = irb->region->pitch;
- }
+ for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[j];
+ irb = intel_renderbuffer(rb);
+ if (irb) {
+ /* this is a user-created intel_renderbuffer */
+ if (irb->region) {
+ if (map)
+ intel_region_map(intel, irb->region);
+ else
+ intel_region_unmap(intel, irb->region);
+ irb->pfMap = irb->region->map;
+ irb->pfPitch = irb->region->pitch;
}
}
}
clear_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]);
if (ctx->DrawBuffer) {
- /* FIXME: find correct color buffer, instead of [0][0] */
- if (ctx->DrawBuffer->_ColorDrawBuffers[0][0]) {
- color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0][0]->RedBits;
- color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->GreenBits;
- color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->BlueBits;
- color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0][0]->AlphaBits;
+ /* FIXME: find correct color buffer, instead of [0] */
+ if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
+ color_bits = ctx->DrawBuffer->_ColorDrawBuffers[0]->RedBits;
+ color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->GreenBits;
+ color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->BlueBits;
+ color_bits += ctx->DrawBuffer->_ColorDrawBuffers[0]->AlphaBits;
}
}
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
nouveau_renderbuffer_t *nrb;
- nrb = (nouveau_renderbuffer_t *)
- ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ nrb = (nouveau_renderbuffer_t *) ctx->DrawBuffer->_ColorDrawBuffers[0];
if (!nrb)
return;
_mesa_update_framebuffer(ctx);
_mesa_update_draw_buffer_bounds(ctx);
- color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0][0];
+ color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0];
if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped)
depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer->Wrapped;
else
r128ContextPtr rmesa = R128_CONTEXT(ctx);
int x = rmesa->driDrawable->x;
int y = rmesa->driDrawable->y;
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
driRenderbuffer *drb = (driRenderbuffer *) rb;
rmesa->setup.window_xy_offset = (((y & 0xFFF) << R128_WINDOW_Y_SHIFT) |
r200ContextPtr rmesa = R200_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
drm_clip_rect_t *box = dPriv->pClipRects;
- struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0][0];
+ struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorDrawBuffers[0];
driRenderbuffer *drb = (driRenderbuffer *) rb;
int nbox = dPriv->numClipRects;
int i;
fprintf(stderr, "%s\n", __FUNCTION__);
/* check that we're drawing to exactly one color buffer */
- if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1)
+ if (ctx->DrawBuffer->_NumColorDrawBuffers != 1)
return GL_FALSE;
switch (format) {
{
int p;
driRenderbuffer *drb =
- (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0][0];
+ (driRenderbuffer *) ctx->WinSysDrawBuffer->_ColorDrawBuffers[0];
volatile int *buf =
(volatile int *)(rmesa->dri.screen->pFB + drb->offset);
p = *buf;
const GLvoid *pixels )
{
const SWcontext *swrast = SWRAST_CONTEXT( ctx );
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped);
if (swrast->NewState)
const GLvoid *pixels )
{
struct xmesa_renderbuffer *xrb
- = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+ = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
const XMesaContext xmesa = XMESA_CONTEXT(ctx);
const SWcontext *swrast = SWRAST_CONTEXT( ctx );
XMesaDisplay *dpy = xmesa->xm_visual->display;
struct xmesa_renderbuffer *srcXrb
= xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped);
struct xmesa_renderbuffer *dstXrb
- = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+ = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
ASSERT(dpy);
ASSERT(gc);
#define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
- xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
+ xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped)
/*
if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL;
if (xmbuf->swAlpha) return (swrast_line_func) NULL;
- xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+ xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
if (xrb->ximage
&& swrast->_RasterMask==DEPTH_BIT
}
#ifndef XFree86Server
- if (ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1
+ if (ctx->DrawBuffer->_NumColorDrawBuffers == 1
&& ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT
&& swrast->_RasterMask == LOGIC_OP_BIT
&& ctx->Color.LogicOp == GL_XOR
#define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
- xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped)
+ xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped)
/**********************************************************************/
if (xmbuf->swAlpha)
return (swrast_tri_func) NULL;
- xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped);
+ xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]->Wrapped);
if (xrb->ximage) {
if ( ctx->Light.ShadeModel==GL_SMOOTH
/* Set per-FBO state */
fb->ColorDrawBuffer[output] = buffer;
fb->_ColorDrawBufferMask[output] = destMask;
- /* not really needed, will be set later */
- fb->_NumColorDrawBuffers[output] = 0;
+
+ /* this will be computed later, but zero to be safe */
+ fb->_NumColorDrawBuffers = 0;
if (fb->Name == 0) {
/* Only set the per-context DrawBuffer state if we're currently
}
+/*
+ * Example DrawBuffers scenarios:
+ *
+ * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to
+ * "gl_FragColor" or program writes to the "result.color" register:
+ *
+ * fragment color output renderbuffer
+ * --------------------- ---------------
+ * color[0] Front, Back
+ *
+ *
+ * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to
+ * gl_FragData[i] or program writes to result.color[i] registers:
+ *
+ * fragment color output renderbuffer
+ * --------------------- ---------------
+ * color[0] Front
+ * color[1] Aux0
+ * color[3] Aux1
+ *
+ *
+ * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to
+ * gl_FragColor, or fixed function:
+ *
+ * fragment color output renderbuffer
+ * --------------------- ---------------
+ * color[0] Front, Aux0, Aux1
+ *
+ *
+ * In either case, the list of renderbuffers is stored in the
+ * framebuffer->_ColorDrawBuffers[] array and
+ * framebuffer->_NumColorDrawBuffers indicates the number of buffers.
+ * The renderer (like swrast) has to look at the current fragment shader
+ * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine
+ * how to map color outputs to renderbuffers.
+ *
+ * Note that these two calls are equivalent (for fixed function fragment
+ * shading anyway):
+ * a) glDrawBuffer(GL_FRONT_AND_BACK); (assuming non-stereo framebuffer)
+ * b) glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]);
+ */
+
+
+
+
/**
* Update the (derived) list of color drawing renderbuffer pointers.
* Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
static void
update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
{
- GLuint output;
+ GLuint output, count = 0;
- /*
- * Fragment programs can write to multiple colorbuffers with
- * the GL_ARB_draw_buffers extension.
+ /* First, interpret _ColorDrawBufferMask[] in the manner that would be
+ * used if the fragment program/shader writes to gl_FragData[]
*/
for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
- GLbitfield bufferMask = fb->_ColorDrawBufferMask[output];
- GLuint count = 0;
+ GLuint buf = _mesa_ffs(fb->_ColorDrawBufferMask[output]);
+ if (buf) {
+ struct gl_renderbuffer *rb = fb->Attachment[buf - 1].Renderbuffer;
+ fb->_ColorDrawBuffers[output] = rb; /* may be NULL */
+ if (rb)
+ count = output + 1;
+ }
+ }
+
+ /* Second, handle the GL_FRONT_AND_BACK case, overwriting the above
+ * if needed.
+ */
+ GLbitfield bufferMask = fb->_ColorDrawBufferMask[0];
+ if (_mesa_bitcount(bufferMask) > 1) {
GLuint i;
- if (!fb->DeletePending) {
- /* We need the inner loop here because glDrawBuffer(GL_FRONT_AND_BACK)
- * can specify writing to two or four color buffers (for example).
- */
- for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
- const GLuint bufferBit = 1 << i;
- if (bufferBit & bufferMask) {
- struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
- if (rb && rb->Width > 0 && rb->Height > 0) {
- fb->_ColorDrawBuffers[output][count] = rb;
- count++;
- }
- else {
- /*
- _mesa_warning(ctx, "DrawBuffer names a missing buffer!\n");
- */
- }
- bufferMask &= ~bufferBit;
- }
+ count = 0;
+ for (i = 0; bufferMask && i < BUFFER_COUNT; i++) {
+ if (bufferMask & (1 << i)) {
+ struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
+ fb->_ColorDrawBuffers[count] = rb;
+ count++;
}
+ bufferMask &= ~(1 << i);
}
- fb->_NumColorDrawBuffers[output] = count;
}
+
+ fb->_NumColorDrawBuffers = count;
}
GLint _ColorReadBufferIndex; /* -1 = None */
/* These are computed from _ColorDrawBufferMask and _ColorReadBufferIndex */
- GLuint _NumColorDrawBuffers[MAX_DRAW_BUFFERS];
- struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS][4];
+ GLuint _NumColorDrawBuffers;
+ struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS];
struct gl_renderbuffer *_ColorReadBuffer;
/** The Actual depth/stencil buffers to use. May be wrappers around the
}
/* store colors */
- for (buffer = 0; buffer < fb->_NumColorDrawBuffers[0]; buffer++) {
- struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[0][buffer];
+ for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) {
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buffer];
if (masking) {
_swrast_mask_rgba_span(ctx, rb, &span);
}
switch (buffer) {
case GL_COLOR_BUFFER_BIT:
readRb = ctx->ReadBuffer->_ColorReadBuffer;
- drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
comps = 4;
break;
case GL_DEPTH_BUFFER_BIT:
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
{
struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
- struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
const GLint srcWidth = ABS(srcX1 - srcX0);
const GLint dstWidth = ABS(dstX1 - dstX0);
switch (buffer) {
case GL_COLOR_BUFFER_BIT:
readRb = ctx->ReadBuffer->_ColorReadBuffer;
- drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];
comps = 4;
break;
case GL_DEPTH_BUFFER_BIT:
clear_color_buffers(GLcontext *ctx)
{
GLboolean masking;
- GLuint i;
+ GLuint buf;
if (ctx->Visual.rgbMode) {
if (ctx->Color.ColorMask[0] &&
}
}
else {
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
const GLuint indexBits = (1 << rb->IndexBits) - 1;
if ((ctx->Color.IndexMask & indexBits) == indexBits) {
masking = GL_FALSE;
}
}
- for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers[0]; i++) {
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][i];
+ for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[buf];
if (ctx->Visual.rgbMode) {
if (masking) {
clear_rgba_buffer_with_masking(ctx, rb);
/* do software clearing here */
if (buffers) {
- if (buffers & ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
+ if (buffers & ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
clear_color_buffers(ctx);
}
if (buffers & BUFFER_BIT_DEPTH) {
* MULTI_DRAW_BIT flag. Also set it if we're drawing to no
* buffers or the RGBA or CI mask disables all writes.
*/
- if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) {
+ if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
/* more than one color buffer designated for writing (or zero buffers) */
rasterMask |= MULTI_DRAW_BIT;
}
}
-/**
- * Update the swrast->_ColorOutputsMask which indicates which color
- * renderbuffers (aka rendertargets) are being written to by the current
- * fragment program.
- * We also take glDrawBuffers() into account to skip outputs that are
- * set to GL_NONE.
- */
-static void
-_swrast_update_color_outputs(GLcontext *ctx)
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const struct gl_framebuffer *fb = ctx->DrawBuffer;
-
- swrast->_ColorOutputsMask = 0;
- swrast->_NumColorOutputs = 0;
-
- if (ctx->FragmentProgram._Current) {
- const GLbitfield outputsWritten
- = ctx->FragmentProgram._Current->Base.OutputsWritten;
- GLuint output;
- for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) {
- if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output)))
- && (fb->_NumColorDrawBuffers[output] > 0)) {
- swrast->_ColorOutputsMask |= (1 << output);
- swrast->_NumColorOutputs = output + 1;
- }
- }
- }
- if (swrast->_ColorOutputsMask == 0x0) {
- /* no fragment program, or frag prog didn't write to gl_FragData[] */
- if (fb->_NumColorDrawBuffers[0] > 0) {
- swrast->_ColorOutputsMask = 0x1;
- swrast->_NumColorOutputs = 1;
- }
- }
-}
-
-
void
_swrast_validate_derived( GLcontext *ctx )
{
_NEW_TEXTURE))
_swrast_update_active_attribs(ctx);
- if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
- _swrast_update_color_outputs(ctx);
-
swrast->NewState = 0;
swrast->StateChanges = 0;
swrast->InvalidateState = _swrast_invalidate_state;
GLboolean _DeferredTexture;
GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */
- /** Multiple render targets */
- GLbitfield _ColorOutputsMask;
- GLuint _NumColorOutputs;
-
/** List/array of the fragment attributes to interpolate */
GLuint _ActiveAttribs[FRAG_ATTRIB_MAX];
/** Same info, but as a bitmask */
}
if (type == GL_COLOR) {
- if (dstFb->_NumColorDrawBuffers[0] != 1)
+ if (dstFb->_NumColorDrawBuffers != 1)
return GL_FALSE;
srcRb = srcFb->_ColorReadBuffer;
- dstRb = dstFb->_ColorDrawBuffers[0][0];
+ dstRb = dstFb->_ColorDrawBuffers[0];
}
else if (type == GL_STENCIL) {
srcRb = srcFb->_StencilBuffer;
const GLvoid *pixels)
{
const GLint imgX = x, imgY = y;
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
const GLenum rbType = rb->DataType;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
SWspan span;
IMAGE_POST_CONVOLUTION_SCALE_BIAS);
}
- if (ctx->DrawBuffer->_NumColorDrawBuffers[0] > 0 &&
- ctx->DrawBuffer->_ColorDrawBuffers[0][0]->DataType != GL_FLOAT &&
+ if (ctx->DrawBuffer->_NumColorDrawBuffers > 0 &&
+ ctx->DrawBuffer->_ColorDrawBuffers[0]->DataType != GL_FLOAT &&
ctx->Color.ClampFragmentColor != GL_FALSE) {
/* need to clamp colors before applying fragment ops */
transferOps |= IMAGE_CLAMP_BIT;
* Note that colors beyond 0 and 1 will overwrite other
* attributes, such as FOGC, TEX0, TEX1, etc. That's OK.
*/
- GLuint output;
- for (output = 0; output < swrast->_NumColorOutputs; output++) {
- if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) {
- COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i],
- machine->Outputs[FRAG_RESULT_DATA0 + output]);
+ GLuint buf;
+ for (buf = 0; buf < ctx->DrawBuffer->_NumColorDrawBuffers; buf++) {
+ if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + buf))) {
+ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0 + buf][i],
+ machine->Outputs[FRAG_RESULT_DATA0 + buf]);
}
}
}
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLbitfield origInterpMask = span->interpMask;
const GLbitfield origArrayMask = span->arrayMask;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
ASSERT(span->end <= MAX_WIDTH);
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
}
/* Depth bounds test */
- if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) {
+ if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) {
if (!_swrast_depth_bounds_test(ctx, span)) {
return;
}
GLuint i;
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) {
- assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
- assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
- assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
- assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
+ assert(span->array->x[i] >= fb->_Xmin);
+ assert(span->array->x[i] < fb->_Xmax);
+ assert(span->array->y[i] >= fb->_Ymin);
+ assert(span->array->y[i] < fb->_Ymax);
}
}
}
* Write to renderbuffers
*/
{
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- const GLuint output = 0; /* only frag progs can write to other outputs */
- const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
- GLuint indexSave[MAX_WIDTH];
+ const GLuint numBuffers = fb->_NumColorDrawBuffers;
GLuint buf;
- if (numDrawBuffers > 1) {
- /* save indexes for second, third renderbuffer writes */
- _mesa_memcpy(indexSave, span->array->index,
- span->end * sizeof(indexSave[0]));
- }
+ for (buf = 0; buf < numBuffers; buf++) {
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
+ GLuint indexSave[MAX_WIDTH];
- for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) {
- struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
ASSERT(rb->_BaseFormat == GL_COLOR_INDEX);
+ if (numBuffers > 1) {
+ /* save indexes for second, third renderbuffer writes */
+ _mesa_memcpy(indexSave, span->array->index,
+ span->end * sizeof(indexSave[0]));
+ }
+
if (ctx->Color.IndexLogicOpEnabled) {
_swrast_logicop_ci_span(ctx, rb, span);
}
}
}
- if (buf + 1 < numDrawBuffers) {
+ if (buf + 1 < numBuffers) {
/* restore original span values */
_mesa_memcpy(span->array->index, indexSave,
span->end * sizeof(indexSave[0]));
/**
* Convert the span's color arrays to the given type.
- * The only way 'output' can be greater than one is when we have a fragment
+ * The only way 'output' can be greater than zero is when we have a fragment
* program that writes to gl_FragData[1] or higher.
* \param output which fragment program color output is being processed
*/
|| ctx->ATIFragmentShader._Enabled);
const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits;
struct gl_framebuffer *fb = ctx->DrawBuffer;
- GLuint output;
/*
printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__,
/*
* Write to renderbuffers
*/
- /* Loop over color outputs (GL_ARB_draw_buffers) written by frag prog */
- for (output = 0; output < swrast->_NumColorOutputs; output++) {
- if (swrast->_ColorOutputsMask & (1 << output)) {
- const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output];
- GLchan rgbaSave[MAX_WIDTH][4];
- GLuint buf;
-
- ASSERT(numDrawBuffers > 0);
-
- if (fb->_ColorDrawBuffers[output][0]->DataType
- != span->array->ChanType || output > 0) {
- convert_color_type(span,
- fb->_ColorDrawBuffers[output][0]->DataType,
- output);
- }
-
- if (numDrawBuffers > 1) {
- /* save colors for second, third renderbuffer writes */
- _mesa_memcpy(rgbaSave, span->array->rgba,
- 4 * span->end * sizeof(GLchan));
- }
-
- /* Loop over renderbuffers (i.e. GL_FRONT_AND_BACK) */
- for (buf = 0; buf < numDrawBuffers; buf++) {
- struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf];
- ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
-
- if (ctx->Color._LogicOpEnabled) {
- _swrast_logicop_rgba_span(ctx, rb, span);
- }
- else if (ctx->Color.BlendEnabled) {
- _swrast_blend_span(ctx, rb, span);
- }
-
- if (colorMask != 0xffffffff) {
- _swrast_mask_rgba_span(ctx, rb, span);
- }
-
- if (span->arrayMask & SPAN_XY) {
- /* array of pixel coords */
- ASSERT(rb->PutValues);
- rb->PutValues(ctx, rb, span->end,
- span->array->x, span->array->y,
- span->array->rgba, span->array->mask);
- }
- else {
- /* horizontal run of pixels */
- ASSERT(rb->PutRow);
- rb->PutRow(ctx, rb, span->end, span->x, span->y,
- span->array->rgba,
- span->writeAll ? NULL: span->array->mask);
- }
-
- if (buf + 1 < numDrawBuffers) {
- /* restore original span values */
- _mesa_memcpy(span->array->rgba, rgbaSave,
- 4 * span->end * sizeof(GLchan));
- }
- } /* for buf */
- } /* if output is written to */
- } /* for output */
+ {
+ const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
+ const GLboolean multiFragOutputs
+ = fp && fp->Base.InputsRead >= (1 << FRAG_RESULT_DATA0);
+ const GLuint numBuffers = fb->_NumColorDrawBuffers;
+ GLuint buf;
+
+ for (buf = 0; buf < numBuffers; buf++) {
+ struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
+
+ /* color[fragOutput] will be written to buffer[buf] */
+
+ if (rb) {
+ GLchan rgbaSave[MAX_WIDTH][4];
+ const GLuint fragOutput = multiFragOutputs ? buf : 0;
+
+ if (rb->DataType != span->array->ChanType || fragOutput > 0) {
+ convert_color_type(span, rb->DataType, fragOutput);
+ }
+
+ if (!multiFragOutputs && numBuffers > 1) {
+ /* save colors for second, third renderbuffer writes */
+ _mesa_memcpy(rgbaSave, span->array->rgba,
+ 4 * span->end * sizeof(GLchan));
+ }
+
+ ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);
+
+ if (ctx->Color._LogicOpEnabled) {
+ _swrast_logicop_rgba_span(ctx, rb, span);
+ }
+ else if (ctx->Color.BlendEnabled) {
+ _swrast_blend_span(ctx, rb, span);
+ }
+
+ if (colorMask != 0xffffffff) {
+ _swrast_mask_rgba_span(ctx, rb, span);
+ }
+
+ if (span->arrayMask & SPAN_XY) {
+ /* array of pixel coords */
+ ASSERT(rb->PutValues);
+ rb->PutValues(ctx, rb, span->end,
+ span->array->x, span->array->y,
+ span->array->rgba, span->array->mask);
+ }
+ else {
+ /* horizontal run of pixels */
+ ASSERT(rb->PutRow);
+ rb->PutRow(ctx, rb, span->end, span->x, span->y,
+ span->array->rgba,
+ span->writeAll ? NULL: span->array->mask);
+ }
+
+ if (!multiFragOutputs && numBuffers > 1) {
+ /* restore original span values */
+ _mesa_memcpy(span->array->rgba, rgbaSave,
+ 4 * span->end * sizeof(GLchan));
+ }
+
+ } /* if rb */
+ } /* for buf */
+ }
end:
/* restore these values before returning */
#define T_SCALE theight
#define SETUP_CODE \
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];\
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \
#define T_SCALE theight
#define SETUP_CODE \
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];\
+ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];\
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \