fixed pointer arithmetic error in glCopyPixels
[mesa.git] / src / mesa / main / buffers.c
index 410524e3352622530a7e046200459e1af2e9333f..b4feb219fbff64f3834042cad4c752cf001284a3 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: buffers.c,v 1.23 2001/01/23 23:39:36 brianp Exp $ */
+/* $Id: buffers.c,v 1.32 2002/02/15 16:25:16 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  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"),
 #include "glheader.h"
 #include "accum.h"
 #include "buffers.h"
+#include "colormac.h"
 #include "context.h"
 #include "depth.h"
 #include "enums.h"
 #include "macros.h"
-#include "masking.h"
 #include "mem.h"
 #include "stencil.h"
 #include "state.h"
 #include "mtypes.h"
-#include "swrast/swrast.h"
 #endif
 
 
@@ -51,14 +50,13 @@ _mesa_ClearIndex( GLfloat c )
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (ctx->Color.ClearIndex == (GLuint)c)
+   if (ctx->Color.ClearIndex == (GLuint) c)
       return;
-   
 
    FLUSH_VERTICES(ctx, _NEW_COLOR);
    ctx->Color.ClearIndex = (GLuint) c;
 
-   if (!ctx->Visual.rgbMode) {
+   if (!ctx->Visual.rgbMode && ctx->Driver.ClearIndex) {
       /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
       (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
    }
@@ -67,38 +65,31 @@ _mesa_ClearIndex( GLfloat c )
 
 
 void
-_mesa_ClearColor( GLclampf red, GLclampf green,
-                  GLclampf blue, GLclampf alpha )
+_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
 {
-   GLfloat tmp[4];
+   GLchan tmp[4];
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   tmp[0] = CLAMP( red,   0.0, 1.0 );
-   tmp[1] = CLAMP( green, 0.0, 1.0 );
-   tmp[2] = CLAMP( blue,  0.0, 1.0 );
-   tmp[3] = CLAMP( alpha, 0.0, 1.0 );
+   UNCLAMPED_FLOAT_TO_CHAN(tmp[0], red);
+   UNCLAMPED_FLOAT_TO_CHAN(tmp[1], green);
+   UNCLAMPED_FLOAT_TO_CHAN(tmp[2], blue);
+   UNCLAMPED_FLOAT_TO_CHAN(tmp[3], alpha);
 
    if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))
       return;
 
    FLUSH_VERTICES(ctx, _NEW_COLOR);
-   COPY_4FV( ctx->Color.ClearColor, tmp );
-
-   if (ctx->Visual.rgbMode) {
-      GLchan r = (GLint) (ctx->Color.ClearColor[0] * CHAN_MAXF);
-      GLchan g = (GLint) (ctx->Color.ClearColor[1] * CHAN_MAXF);
-      GLchan b = (GLint) (ctx->Color.ClearColor[2] * CHAN_MAXF);
-      GLchan a = (GLint) (ctx->Color.ClearColor[3] * CHAN_MAXF);
-      (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
+   COPY_CHAN4(ctx->Color.ClearColor, tmp);
+
+   if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) {
+      /* it's OK to call glClearColor in CI mode but it should be a NOP */
+      (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor);
    }
 }
 
 
 
-
-
-
 void
 _mesa_Clear( GLbitfield mask )
 {
@@ -108,8 +99,17 @@ _mesa_Clear( GLbitfield mask )
    if (MESA_VERBOSE & VERBOSE_API)
       fprintf(stderr, "glClear 0x%x\n", mask);
 
+   if (mask & ~(GL_COLOR_BUFFER_BIT |
+                GL_DEPTH_BUFFER_BIT |
+                GL_STENCIL_BUFFER_BIT |
+                GL_ACCUM_BUFFER_BIT)) {
+      /* invalid bit set */
+      _mesa_error( ctx, GL_INVALID_VALUE, "glClear(mask)");
+      return;
+   }
+
    if (ctx->NewState) {
-      gl_update_state( ctx );  /* update _Xmin, etc */
+      _mesa_update_state( ctx );       /* update _Xmin, etc */
    }
 
    if (ctx->RenderMode==GL_RENDER) {
@@ -118,7 +118,6 @@ _mesa_Clear( GLbitfield mask )
       const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
       const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
       GLbitfield ddMask;
-      GLbitfield newMask;
 
       /* don't clear depth buffer if depth writing disabled */
       if (!ctx->Depth.Mask)
@@ -133,25 +132,8 @@ _mesa_Clear( GLbitfield mask )
       }
 
       ASSERT(ctx->Driver.Clear);
-      newMask = (*ctx->Driver.Clear)( ctx, ddMask, !ctx->Scissor.Enabled,
-                                      x, y, width, height );
-
-#ifdef DEBUG
-      {
-         GLbitfield legalBits = DD_FRONT_LEFT_BIT |
-                                DD_FRONT_RIGHT_BIT |
-                                DD_BACK_LEFT_BIT |
-                                DD_BACK_RIGHT_BIT |
-                                DD_DEPTH_BIT |
-                                DD_STENCIL_BIT |
-                                DD_ACCUM_BIT;
-         assert((newMask & (~legalBits)) == 0);
-      }
-#endif
-
-      if (newMask)
-        _swrast_Clear( ctx, newMask, !ctx->Scissor.Enabled,
-                       x, y, width, height );
+      ctx->Driver.Clear( ctx, ddMask, (GLboolean) !ctx->Scissor.Enabled,
+                        x, y, width, height );
    }
 }
 
@@ -164,7 +146,7 @@ _mesa_DrawBuffer( GLenum mode )
 
 
    if (MESA_VERBOSE & VERBOSE_API)
-      fprintf(stderr, "glDrawBuffer %s\n", gl_lookup_enum_by_nr(mode));
+      fprintf(stderr, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
 
    switch (mode) {
       case GL_AUX0:
@@ -172,11 +154,11 @@ _mesa_DrawBuffer( GLenum mode )
       case GL_AUX2:
       case GL_AUX3:
          /* AUX buffers not implemented in Mesa at this time */
-         gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+         _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
          return;
       case GL_RIGHT:
          if (!ctx->Visual.stereoMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;}
          if (ctx->Visual.doubleBufferMode)
             ctx->Color.DrawDestMask = FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
@@ -185,32 +167,32 @@ _mesa_DrawBuffer( GLenum mode )
          break;
       case GL_FRONT_RIGHT:
          if (!ctx->Visual.stereoMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;
          }
          ctx->Color.DrawDestMask = FRONT_RIGHT_BIT;
          break;
       case GL_BACK_RIGHT:
          if (!ctx->Visual.stereoMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;
          }
          if (!ctx->Visual.doubleBufferMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;
          }
          ctx->Color.DrawDestMask = BACK_RIGHT_BIT;
          break;
       case GL_BACK_LEFT:
          if (!ctx->Visual.doubleBufferMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;
          }
          ctx->Color.DrawDestMask = BACK_LEFT_BIT;
          break;
       case GL_FRONT_AND_BACK:
          if (!ctx->Visual.doubleBufferMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;
          }
          if (ctx->Visual.stereoMode)
@@ -221,7 +203,7 @@ _mesa_DrawBuffer( GLenum mode )
          break;
       case GL_BACK:
          if (!ctx->Visual.doubleBufferMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
             return;
          }
          if (ctx->Visual.stereoMode)
@@ -252,7 +234,7 @@ _mesa_DrawBuffer( GLenum mode )
          ctx->Color.DrawDestMask = 0;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
          return;
    }
 
@@ -316,7 +298,7 @@ _mesa_ReadBuffer( GLenum mode )
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & VERBOSE_API)
-      fprintf(stderr, "glReadBuffer %s\n", gl_lookup_enum_by_nr(mode));
+      fprintf(stderr, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
 
    switch (mode) {
       case GL_AUX0:
@@ -324,7 +306,7 @@ _mesa_ReadBuffer( GLenum mode )
       case GL_AUX2:
       case GL_AUX3:
          /* AUX buffers not implemented in Mesa at this time */
-         gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
+         _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
          return;
       case GL_LEFT:
       case GL_FRONT:
@@ -336,7 +318,7 @@ _mesa_ReadBuffer( GLenum mode )
       case GL_BACK_LEFT:
          /* Back-Left buffer, requires double buffering */
          if (!ctx->Visual.doubleBufferMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
             return;
          }
          ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
@@ -344,20 +326,20 @@ _mesa_ReadBuffer( GLenum mode )
       case GL_FRONT_RIGHT:
       case GL_RIGHT:
          if (!ctx->Visual.stereoMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
             return;
          }
          ctx->Pixel.DriverReadBuffer = GL_FRONT_RIGHT;
          break;
       case GL_BACK_RIGHT:
          if (!ctx->Visual.stereoMode || !ctx->Visual.doubleBufferMode) {
-            gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
+            _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
             return;
          }
          ctx->Pixel.DriverReadBuffer = GL_BACK_RIGHT;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
          return;
    }
 
@@ -394,5 +376,57 @@ _mesa_ResizeBuffersMESA( void )
    ctx->DrawBuffer->Width = buf_width;
    ctx->DrawBuffer->Height = buf_height;
 
-   _swrast_alloc_buffers( ctx );
+   ctx->Driver.ResizeBuffersMESA( ctx );
+}
+
+
+void
+_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (width < 0 || height < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
+      return;
+   }
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      fprintf(stderr, "glScissor %d %d %d %d\n", x, y, width, height);
+
+   if (x == ctx->Scissor.X &&
+       y == ctx->Scissor.Y &&
+       width == ctx->Scissor.Width &&
+       height == ctx->Scissor.Height)
+      return;
+
+   FLUSH_VERTICES(ctx, _NEW_SCISSOR);
+   ctx->Scissor.X = x;
+   ctx->Scissor.Y = y;
+   ctx->Scissor.Width = width;
+   ctx->Scissor.Height = height;
+
+   if (ctx->Driver.Scissor)
+      ctx->Driver.Scissor( ctx, x, y, width, height );
+}
+
+
+/*
+ * XXX move somewhere else someday?
+ */
+void
+_mesa_SampleCoverageARB(GLclampf value, GLboolean invert)
+{
+   GLcontext *ctx = _mesa_get_current_context();
+
+   if (!ctx->Extensions.ARB_multisample) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleCoverageARB");
+      return;
+   }
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
+   ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0);
+   ctx->Multisample.SampleCoverageInvert = invert;
+   ctx->NewState |= _NEW_MULTISAMPLE;
 }
+