r600g: Implement GL_ARB_texture_gather
[mesa.git] / src / mesa / swrast / s_blit.c
index 051354dc8c7fc9899654c317615271100385e869..e3b45f14682f75a02e61af72592b46043fbe84b2 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
  *
  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 
@@ -29,6 +29,7 @@
 #include "main/macros.h"
 #include "main/format_unpack.h"
 #include "main/format_pack.h"
+#include "main/condrender.h"
 #include "s_context.h"
 
 
@@ -166,8 +167,8 @@ blit_nearest(struct gl_context *ctx,
        * using the core helpers for pack/unpack, we avoid needing to handle
        * masking for things like DEPTH copies of Z24S8.
        */
-      if (readRb->Format == MESA_FORMAT_Z32_FLOAT ||
-         readRb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+      if (readRb->Format == MESA_FORMAT_Z_FLOAT32 ||
+         readRb->Format == MESA_FORMAT_Z32_FLOAT_S8X24_UINT) {
         mode = UNPACK_Z_FLOAT;
       } else {
         mode = UNPACK_Z_INT;
@@ -188,6 +189,12 @@ blit_nearest(struct gl_context *ctx,
       return;
    }
 
+   /* allocate the src/dst row buffers */
+   srcBuffer = malloc(MAX_PIXEL_BYTES * srcWidth);
+   dstBuffer = malloc(MAX_PIXEL_BYTES * dstWidth);
+   if (!srcBuffer || !dstBuffer)
+      goto fail_no_memory;
+
    /* Blit to all the draw buffers */
    for (i = 0; i < numDrawBuffers; i++) {
       if (buffer == GL_COLOR_BUFFER_BIT) {
@@ -229,7 +236,7 @@ blit_nearest(struct gl_context *ctx,
       default:
          _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest",
                        pixelSize);
-         return;
+         goto fail;
       }
 
       if ((readRb == drawRb) ||
@@ -248,8 +255,7 @@ blit_nearest(struct gl_context *ctx,
                                      GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
                                      &map, &rowStride);
          if (!map) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
-            return;
+            goto fail_no_memory;
          }
 
          srcMap = map + srcYpos * rowStride + srcXpos * formatSize;
@@ -276,8 +282,7 @@ blit_nearest(struct gl_context *ctx,
                                      srcWidth, srcHeight,
                                      GL_MAP_READ_BIT, &srcMap, &srcRowStride);
          if (!srcMap) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
-            return;
+            goto fail_no_memory;
          }
          ctx->Driver.MapRenderbuffer(ctx, drawRb,
                                      dstXpos, dstYpos,
@@ -285,24 +290,10 @@ blit_nearest(struct gl_context *ctx,
                                      GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
          if (!dstMap) {
             ctx->Driver.UnmapRenderbuffer(ctx, readRb);
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
-            return;
+            goto fail_no_memory;
          }
       }
 
-      /* allocate the src/dst row buffers */
-      srcBuffer = malloc(pixelSize * srcWidth);
-      if (!srcBuffer) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
-         return;
-      }
-      dstBuffer = malloc(pixelSize * dstWidth);
-      if (!dstBuffer) {
-         free(srcBuffer);
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
-         return;
-      }
-
       for (dstRow = 0; dstRow < dstHeight; dstRow++) {
          GLfloat srcRowF = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F;
          GLint srcRow = IROUND(srcRowF);
@@ -369,14 +360,21 @@ blit_nearest(struct gl_context *ctx,
          }
       }
 
-      free(srcBuffer);
-      free(dstBuffer);
-
       ctx->Driver.UnmapRenderbuffer(ctx, readRb);
       if (drawRb != readRb) {
          ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
       }
    }
+
+fail:
+   free(srcBuffer);
+   free(dstBuffer);
+   return;
+
+fail_no_memory:
+   free(srcBuffer);
+   free(dstBuffer);
+   _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBuffer");
 }
 
 
@@ -539,7 +537,7 @@ blit_linear(struct gl_context *ctx,
    GLint srcBufferY0 = -1, srcBufferY1 = -1;
    GLvoid *dstBuffer;
 
-   gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format);
+   mesa_format readFormat = _mesa_get_srgb_format_linear(readRb->Format);
    GLuint bpp = _mesa_get_format_bytes(readFormat);
 
    GLenum pixelType;
@@ -564,29 +562,17 @@ blit_linear(struct gl_context *ctx,
     * Keep two adjacent src rows around for bilinear sampling.
     */
    srcBuffer0 = malloc(pixelSize * srcWidth);
-   if (!srcBuffer0) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
-      return;
-   }
    srcBuffer1 = malloc(pixelSize * srcWidth);
-   if (!srcBuffer1) {
-      free(srcBuffer0);
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
-      return;
-   }
    dstBuffer = malloc(pixelSize * dstWidth);
-   if (!dstBuffer) {
-      free(srcBuffer0);
-      free(srcBuffer1);
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
-      return;
+   if (!srcBuffer0 || !srcBuffer1 || !dstBuffer) {
+      goto fail_no_memory;
    }
 
    for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) {
       GLint idx = drawFb->_ColorDrawBufferIndexes[i];
       struct gl_renderbuffer_attachment *drawAtt;
       struct gl_renderbuffer *drawRb;
-      gl_format drawFormat;
+      mesa_format drawFormat;
 
       if (idx == -1)
          continue;
@@ -610,11 +596,7 @@ blit_linear(struct gl_context *ctx,
                                      GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
                                      &srcMap, &srcRowStride);
          if (!srcMap) {
-            free(srcBuffer0);
-            free(srcBuffer1);
-            free(dstBuffer);
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
-            return;
+            goto fail_no_memory;
          }
 
          dstMap = srcMap;
@@ -629,22 +611,14 @@ blit_linear(struct gl_context *ctx,
                                      0, 0, readRb->Width, readRb->Height,
                                      GL_MAP_READ_BIT, &srcMap, &srcRowStride);
          if (!srcMap) {
-            free(srcBuffer0);
-            free(srcBuffer1);
-            free(dstBuffer);
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
-            return;
+            goto fail_no_memory;
          }
          ctx->Driver.MapRenderbuffer(ctx, drawRb,
                                      0, 0, drawRb->Width, drawRb->Height,
                                      GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
          if (!dstMap) {
             ctx->Driver.UnmapRenderbuffer(ctx, readRb);
-            free(srcBuffer0);
-            free(srcBuffer1);
-            free(dstBuffer);
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
-            return;
+            goto fail_no_memory;
          }
       }
 
@@ -734,15 +708,22 @@ blit_linear(struct gl_context *ctx,
          }
       }
 
-      free(srcBuffer0);
-      free(srcBuffer1);
-      free(dstBuffer);
-
       ctx->Driver.UnmapRenderbuffer(ctx, readRb);
       if (drawRb != readRb) {
          ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
       }
    }
+
+   free(srcBuffer0);
+   free(srcBuffer1);
+   free(dstBuffer);
+   return;
+
+fail_no_memory:
+   free(srcBuffer0);
+   free(srcBuffer1);
+   free(dstBuffer);
+   _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
 }
 
 
@@ -768,6 +749,13 @@ _swrast_BlitFramebuffer(struct gl_context *ctx,
    };
    GLint i;
 
+   /* Page 679 of OpenGL 4.4 spec says:
+    *    "Added BlitFramebuffer to commands affected by conditional rendering in
+    *     section 10.10 (Bug 9562)."
+    */
+   if (!_mesa_check_conditional_render(ctx))
+      return; /* Do not blit */
+
    if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
                         &dstX0, &dstY0, &dstX1, &dstY1)) {
       return;