- assert(swrast->_IntegerAccumScaler > 0.0);
- assert(swrast->_IntegerAccumScaler <= 1.0);
- for (j = 0; j < height; j++) {
- const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
- GLint i, i4;
- for (i = i4 = 0; i < width; i++, i4 += 4) {
- ASSERT(acc[i4+0] < max);
- ASSERT(acc[i4+1] < max);
- ASSERT(acc[i4+2] < max);
- ASSERT(acc[i4+3] < max);
- rgba[i][RCOMP] = multTable[acc[i4+0]];
- rgba[i][GCOMP] = multTable[acc[i4+1]];
- rgba[i][BCOMP] = multTable[acc[i4+2]];
- rgba[i][ACOMP] = multTable[acc[i4+3]];
- }
- if (colorMask != 0xffffffff) {
- _swrast_mask_rgba_array( ctx, width, xpos, ypos, rgba );
- }
- (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
- (const GLchan (*)[4])rgba, NULL );
- if (ctx->DrawBuffer->UseSoftwareAlphaBuffers
- && ctx->Color.ColorMask[ACOMP]) {
- _swrast_write_alpha_span(ctx, width, xpos, ypos,
- (CONST GLchan (*)[4]) rgba, NULL);
- }
- ypos++;
- }
- }
- else
-#endif /* USE_OPTIMIZED_ACCUM */
- {
- /* scaled integer (or float) accum buffer */
- const GLfloat rscale = value / acc_scale * CHAN_MAXF;
- const GLfloat gscale = value / acc_scale * CHAN_MAXF;
- const GLfloat bscale = value / acc_scale * CHAN_MAXF;
- const GLfloat ascale = value / acc_scale * CHAN_MAXF;
- GLint i, j;
- for (j=0;j<height;j++) {
- const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
- for (i=0;i<width;i++) {
- GLint r = IROUND( (GLfloat) (acc[0]) * rscale );
- GLint g = IROUND( (GLfloat) (acc[1]) * gscale );
- GLint b = IROUND( (GLfloat) (acc[2]) * bscale );
- GLint a = IROUND( (GLfloat) (acc[3]) * ascale );
- acc += 4;
- rgba[i][RCOMP] = CLAMP( r, 0, CHAN_MAX );
- rgba[i][GCOMP] = CLAMP( g, 0, CHAN_MAX );
- rgba[i][BCOMP] = CLAMP( b, 0, CHAN_MAX );
- rgba[i][ACOMP] = CLAMP( a, 0, CHAN_MAX );
- }
- if (colorMask != 0xffffffff) {
- _swrast_mask_rgba_array( ctx, width, xpos, ypos, rgba );
- }
- (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
- (const GLchan (*)[4])rgba, NULL );
- if (ctx->DrawBuffer->UseSoftwareAlphaBuffers
- && ctx->Color.ColorMask[ACOMP]) {
- _swrast_write_alpha_span(ctx, width, xpos, ypos,
- (CONST GLchan (*)[4]) rgba, NULL);
- }
- ypos++;
- }
+/**
+ * Software fallback for glAccum.
+ */
+void
+_swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLint xpos, ypos, width, height;
+
+ if (SWRAST_CONTEXT(ctx)->NewState)
+ _swrast_validate_derived( ctx );
+
+ if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) {
+ _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer");
+ return;
+ }
+
+ RENDER_START(swrast, ctx);
+
+ /* Compute region after calling RENDER_START so that we know the
+ * drawbuffer's size/bounds are up to date.
+ */
+ xpos = ctx->DrawBuffer->_Xmin;
+ ypos = ctx->DrawBuffer->_Ymin;
+ width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+ height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
+
+ switch (op) {
+ case GL_ADD:
+ if (value != 0.0F) {
+ accum_add(ctx, value, xpos, ypos, width, height);