mesa: move PBO-related functions into a new file
[mesa.git] / src / mesa / main / readpix.c
index feea1d375f66d7a173ae7af8dc7b80416aeda8fc..6e09a52c88a1614423d0943ae7ecd4ee323b7dc8 100644 (file)
 #include "imports.h"
 #include "bufferobj.h"
 #include "context.h"
+#include "enums.h"
 #include "readpix.h"
 #include "framebuffer.h"
+#include "formats.h"
 #include "image.h"
+#include "mtypes.h"
+#include "pbo.h"
 #include "state.h"
 
 
@@ -40,7 +44,7 @@
  * \return GL_TRUE if error detected, GL_FALSE if no errors
  */
 GLboolean
-_mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
+_mesa_error_check_format_type(struct gl_context *ctx, GLenum format, GLenum type,
                               GLboolean drawing)
 {
    const char *readDraw = drawing ? "Draw" : "Read";
@@ -66,6 +70,7 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
 
    /* additional checks */
    switch (format) {
+   case GL_RG:
    case GL_RED:
    case GL_GREEN:
    case GL_BLUE:
@@ -77,14 +82,17 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
    case GL_RGBA:
    case GL_BGRA:
    case GL_ABGR_EXT:
-      if (drawing) {
-         if (!ctx->DrawBuffer->Visual.rgbMode) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                   "glDrawPixels(drawing RGB pixels into color index buffer)");
-            return GL_TRUE;
-         }
-      }
-      else {
+   case GL_RED_INTEGER_EXT:
+   case GL_GREEN_INTEGER_EXT:
+   case GL_BLUE_INTEGER_EXT:
+   case GL_ALPHA_INTEGER_EXT:
+   case GL_RGB_INTEGER_EXT:
+   case GL_RGBA_INTEGER_EXT:
+   case GL_BGR_INTEGER_EXT:
+   case GL_BGRA_INTEGER_EXT:
+   case GL_LUMINANCE_INTEGER_EXT:
+   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+      if (!drawing) {
          /* reading */
          if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
@@ -95,10 +103,9 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
       break;
    case GL_COLOR_INDEX:
       if (drawing) {
-         if (ctx->DrawBuffer->Visual.rgbMode &&
-             (ctx->PixelMaps.ItoR.Size == 0 ||
-              ctx->PixelMaps.ItoG.Size == 0 ||
-              ctx->PixelMaps.ItoB.Size == 0)) {
+         if (ctx->PixelMaps.ItoR.Size == 0 ||
+            ctx->PixelMaps.ItoG.Size == 0 ||
+            ctx->PixelMaps.ItoB.Size == 0) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                    "glDrawPixels(drawing color index pixels into RGB buffer)");
             return GL_TRUE;
@@ -111,6 +118,12 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
                         "glReadPixels(no color buffer)");
             return GL_TRUE;
          }
+         /* We no longer support CI-mode color buffers so trying to read
+          * GL_COLOR_INDEX pixels is always an error.
+          */
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glReadPixels(color buffer is RGB)");
+         return GL_TRUE;
       }
       break;
    case GL_STENCIL_INDEX:
@@ -162,6 +175,13 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
 
    FLUSH_CURRENT(ctx, 0);
 
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
+                  width, height,
+                  _mesa_lookup_enum_by_nr(format),
+                  _mesa_lookup_enum_by_nr(type),
+                  pixels);
+
    if (width < 0 || height < 0) {
       _mesa_error( ctx, GL_INVALID_VALUE,
                    "glReadPixels(width=%d height=%d)", width, height );
@@ -176,6 +196,20 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
       return;
    }
 
+   /* Check that the destination format and source buffer are both
+    * integer-valued or both non-integer-valued.
+    */
+   if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
+      const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
+      const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
+      const GLboolean dstInteger = _mesa_is_integer_format(format);
+      if (dstInteger != srcInteger) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glReadPixels(integer / non-integer format mismatch");
+         return;
+      }
+   }
+
    if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
       _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
                   "glReadPixels(incomplete framebuffer)" );