* \author Brian Paul
*/
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "macros.h"
-#include "imports.h"
-#include "image.h"
+#include "main/glheader.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/image.h"
#include "s_atifragshader.h"
#include "s_alpha.h"
const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
if (ctx->DrawBuffer->Visual.depthBits <= 16)
span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F);
- else
- span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F);
+ else {
+ GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax;
+ tmpf = MIN2(tmpf, depthMax);
+ span->z = (GLint)tmpf;
+ }
span->zStep = 0;
span->interpMask |= SPAN_Z;
}
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);
}
}
}
#endif
/* we have to wait until after occlusion to do this test */
- if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
+ if (ctx->Color.IndexMask == 0) {
/* write no pixels */
span->arrayMask = origArrayMask;
return;
* 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]));
ASSERT(!ctx->FragmentProgram._Current);
ASSERT(span->arrayMask & SPAN_RGBA);
ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1);
+ (void) swrast; /* silence warning */
if (span->array->ChanType == GL_FLOAT) {
if ((span->arrayAttribs & FRAG_BIT_COL0) == 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
*/
if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) {
convert_color_type(span, GL_FLOAT, 0);
}
- if (span->primitive != GL_POINT) {
- /* for points, we populated the arrays already */
+ if (span->primitive != GL_POINT ||
+ (span->interpMask & SPAN_RGBA) ||
+ ctx->Point.PointSprite) {
+ /* for single-pixel points, we populated the arrays already */
interpolate_active_attribs(ctx, span, ~0);
}
span->array->ChanType = GL_FLOAT;
|| 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__,
/* Do the alpha test */
if (ctx->Color.AlphaEnabled) {
if (!_swrast_alpha_test(ctx, span)) {
+ /* all fragments failed test */
goto end;
}
}
if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) {
/* Combined Z/stencil tests */
if (!_swrast_stencil_and_ztest_span(ctx, span)) {
+ /* all fragments failed test */
goto end;
}
}
ASSERT(ctx->Depth.Test);
ASSERT(span->arrayMask & SPAN_Z);
if (!_swrast_depth_test_span(ctx, span)) {
+ /* all fragments failed test */
goto end;
}
}
* the occlusion test.
*/
if (colorMask == 0x0) {
+ /* no colors to write */
goto end;
}
/*
* 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 GLuint numBuffers = fb->_NumColorDrawBuffers;
+ const GLboolean multiFragOutputs = numBuffers > 1;
+ 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 */