main: Add check_texture_buffer_range.
[mesa.git] / src / mesa / main / clear.c
index 077c5fca3b75211a7071f8894db0273cd32ccbf7..8d707bc34a1869e78f1f8a32f4ae0a018c8b1b71 100644 (file)
@@ -33,7 +33,6 @@
 #include "glheader.h"
 #include "clear.h"
 #include "context.h"
-#include "colormac.h"
 #include "enums.h"
 #include "macros.h"
 #include "mtypes.h"
@@ -59,10 +58,6 @@ _mesa_ClearIndex( GLfloat c )
  * \param alpha alpha component.
  *
  * \sa glClearColor().
- *
- * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor.  On a
- * change, flushes the vertices and notifies the driver via the
- * dd_function_table::ClearColor callback.
  */
 void GLAPIENTRY
 _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
@@ -106,16 +101,42 @@ _mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a)
 }
 
 
+/**
+ * Returns true if color writes are enabled for the given color attachment.
+ *
+ * Beyond checking ColorMask, this uses _mesa_format_has_color_component to
+ * ignore components that don't actually exist in the format (such as X in
+ * XRGB).
+ */
+static bool
+color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx)
+{
+   struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[idx];
+   GLuint c;
+   GLubyte colorMask = 0;
+
+   if (rb) {
+      for (c = 0; c < 4; c++) {
+         if (_mesa_format_has_color_component(rb->Format, c))
+            colorMask |= ctx->Color.ColorMask[idx][c];
+      }
+   }
+
+   return colorMask != 0;
+}
+
+
 /**
  * Clear buffers.
- * 
+ *
  * \param mask bit-mask indicating the buffers to be cleared.
  *
- * Flushes the vertices and verifies the parameter. If __struct gl_contextRec::NewState
- * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin,
- * etc. If the rasterization mode is set to GL_RENDER then requests the driver
- * to clear the buffers, via the dd_function_table::Clear callback.
- */ 
+ * Flushes the vertices and verifies the parameter.
+ * If __struct gl_contextRec::NewState is set then calls _mesa_update_state()
+ * to update gl_frame_buffer::_Xmin, etc.  If the rasterization mode is set to
+ * GL_RENDER then requests the driver to clear the buffers, via the
+ * dd_function_table::Clear callback.
+ */
 void GLAPIENTRY
 _mesa_Clear( GLbitfield mask )
 {
@@ -155,11 +176,6 @@ _mesa_Clear( GLbitfield mask )
       return;
    }
 
-   if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||
-       ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||
-       ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)
-      return;
-
    if (ctx->RasterDiscard)
       return;
 
@@ -181,7 +197,7 @@ _mesa_Clear( GLbitfield mask )
          for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
             GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
 
-            if (buf >= 0) {
+            if (buf >= 0 && color_buffer_writes_enabled(ctx, i)) {
                bufferMask |= 1 << buf;
             }
          }
@@ -202,14 +218,14 @@ _mesa_Clear( GLbitfield mask )
          bufferMask |= BUFFER_BIT_ACCUM;
       }
 
-      ASSERT(ctx->Driver.Clear);
+      assert(ctx->Driver.Clear);
       ctx->Driver.Clear(ctx, bufferMask);
    }
 }
 
 
 /** Returned by make_color_buffer_mask() for errors */
-#define INVALID_MASK ~0x0
+#define INVALID_MASK ~0x0U
 
 
 /**
@@ -321,7 +337,8 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
                      drawbuffer);
          return;
       }
-      else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) {
+      else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer
+               && !ctx->RasterDiscard) {
          /* Save current stencil clear value, set to 'value', do the
           * stencil clear and restore the clear value.
           * XXX in the future we may have a new ctx->Driver.ClearBuffer()
@@ -484,7 +501,8 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
                      drawbuffer);
          return;
       }
-      else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) {
+      else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer
+               && !ctx->RasterDiscard) {
          /* Save current depth clear value, set to 'value', do the
           * depth clear and restore the clear value.
           * XXX in the future we may have a new ctx->Driver.ClearBuffer()