mesa: add _mesa_program_state_value_size() helper
[mesa.git] / src / mesa / state_tracker / st_cb_blit.c
index 603c8d4b441be15d351f84070019c93037bff8ec..d91cc9623ac16adca5e827064839bbbfbdcd932e 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2007 VMware, Inc.
  * 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"), to deal in the Software without restriction, including
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
- * 
+ *
  **************************************************************************/
 
  /*
   *   Brian Paul
   */
 
-#include "main/imports.h"
+
 #include "main/image.h"
 #include "main/macros.h"
-#include "main/mfeatures.h"
 
 #include "st_context.h"
 #include "st_texture.h"
+#include "st_cb_bitmap.h"
 #include "st_cb_blit.h"
 #include "st_cb_fbo.h"
-#include "st_atom.h"
-
-#include "util/u_blit.h"
-#include "util/u_format.h"
-
-
-void
-st_init_blit(struct st_context *st)
-{
-   st->blit = util_create_blit(st->pipe, st->cso_context);
-}
-
-
-void
-st_destroy_blit(struct st_context *st)
-{
-   util_destroy_blit(st->blit);
-   st->blit = NULL;
-}
+#include "st_manager.h"
+#include "st_scissor.h"
+#include "st_util.h"
 
+#include "util/format/u_format.h"
 
 static void
 st_BlitFramebuffer(struct gl_context *ctx,
+                   struct gl_framebuffer *readFB,
+                   struct gl_framebuffer *drawFB,
                    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                    GLbitfield mask, GLenum filter)
@@ -72,15 +59,17 @@ st_BlitFramebuffer(struct gl_context *ctx,
    const uint pFilter = ((filter == GL_NEAREST)
                          ? PIPE_TEX_FILTER_NEAREST
                          : PIPE_TEX_FILTER_LINEAR);
-   struct gl_framebuffer *readFB = ctx->ReadBuffer;
-   struct gl_framebuffer *drawFB = ctx->DrawBuffer;
    struct {
       GLint srcX0, srcY0, srcX1, srcY1;
       GLint dstX0, dstY0, dstX1, dstY1;
    } clip;
    struct pipe_blit_info blit;
 
-   st_validate_state(st);
+   st_manager_validate_framebuffers(st);
+
+   /* Make sure bitmap rendering has landed in the framebuffers */
+   st_flush_bitmap_cache(st);
+   st_invalidate_readpix_cache(st);
 
    clip.srcX0 = srcX0;
    clip.srcY0 = srcY0;
@@ -97,11 +86,12 @@ st_BlitFramebuffer(struct gl_context *ctx,
     *
     * XXX: This should depend on mask !
     */
-   if (!_mesa_clip_blit(ctx,
+   if (!_mesa_clip_blit(ctx, readFB, drawFB,
                         &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1,
                         &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) {
       return; /* nothing to draw/blit */
    }
+   memset(&blit, 0, sizeof(struct pipe_blit_info));
    blit.scissor_enable =
       (dstX0 != clip.dstX0) ||
       (dstY0 != clip.dstY0) ||
@@ -175,57 +165,77 @@ st_BlitFramebuffer(struct gl_context *ctx,
       blit.src.box.height = srcY0 - srcY1;
    }
 
+   if (drawFB != ctx->WinSysDrawBuffer)
+      st_window_rectangles_to_blit(ctx, &blit);
+
    blit.filter = pFilter;
+   blit.render_condition_enable = TRUE;
+   blit.alpha_blend = FALSE;
 
    if (mask & GL_COLOR_BUFFER_BIT) {
       struct gl_renderbuffer_attachment *srcAtt =
          &readFB->Attachment[readFB->_ColorReadBufferIndex];
+      GLuint i;
 
       blit.mask = PIPE_MASK_RGBA;
 
       if (srcAtt->Type == GL_TEXTURE) {
-         struct st_texture_object *srcObj =
-            st_texture_object(srcAtt->Texture);
-         struct st_renderbuffer *dstRb =
-            st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
-         struct pipe_surface *dstSurf = dstRb->surface;
+         struct st_texture_object *srcObj = st_texture_object(srcAtt->Texture);
 
-         assert(srcObj->pt);
-         if (!srcObj->pt) {
+         if (!srcObj || !srcObj->pt) {
             return;
          }
 
-         blit.dst.resource = dstSurf->texture;
-         blit.dst.level = dstSurf->u.tex.level;
-         blit.dst.box.z = dstSurf->u.tex.first_layer;
-         blit.dst.format = util_format_linear(dstSurf->format);
-
          blit.src.resource = srcObj->pt;
          blit.src.level = srcAtt->TextureLevel;
          blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
-         blit.src.format = util_format_linear(srcObj->pt->format);
+         blit.src.format = srcObj->pt->format;
 
-         st->pipe->blit(st->pipe, &blit);
+         if (!ctx->Color.sRGBEnabled)
+            blit.src.format = util_format_linear(blit.src.format);
       }
       else {
          struct st_renderbuffer *srcRb =
             st_renderbuffer(readFB->_ColorReadBuffer);
-         struct st_renderbuffer *dstRb =
-            st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
-         struct pipe_surface *srcSurf = srcRb->surface;
-         struct pipe_surface *dstSurf = dstRb->surface;
+         struct pipe_surface *srcSurf;
+
+         if (!srcRb)
+            return;
+
+         st_update_renderbuffer_surface(st, srcRb);
 
-         blit.dst.resource = dstSurf->texture;
-         blit.dst.level = dstSurf->u.tex.level;
-         blit.dst.box.z = dstSurf->u.tex.first_layer;
-         blit.dst.format = util_format_linear(dstSurf->format);
+         if (!srcRb->surface)
+            return;
+
+         srcSurf = srcRb->surface;
 
          blit.src.resource = srcSurf->texture;
          blit.src.level = srcSurf->u.tex.level;
          blit.src.box.z = srcSurf->u.tex.first_layer;
-         blit.src.format = util_format_linear(srcSurf->format);
+         blit.src.format = srcSurf->format;
+      }
 
-         st->pipe->blit(st->pipe, &blit);
+      for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
+         struct st_renderbuffer *dstRb =
+            st_renderbuffer(drawFB->_ColorDrawBuffers[i]);
+
+         if (dstRb) {
+            struct pipe_surface *dstSurf;
+
+            st_update_renderbuffer_surface(st, dstRb);
+
+            dstSurf = dstRb->surface;
+
+            if (dstSurf) {
+               blit.dst.resource = dstSurf->texture;
+               blit.dst.level = dstSurf->u.tex.level;
+               blit.dst.box.z = dstSurf->u.tex.first_layer;
+               blit.dst.format = dstSurf->format;
+
+               st->pipe->blit(st->pipe, &blit);
+               dstRb->defined = true; /* front buffer tracking */
+            }
+         }
       }
    }
 
@@ -233,18 +243,9 @@ st_BlitFramebuffer(struct gl_context *ctx,
       /* depth and/or stencil blit */
 
       /* get src/dst depth surfaces */
-      struct gl_renderbuffer_attachment *srcDepth =
-         &readFB->Attachment[BUFFER_DEPTH];
-      struct gl_renderbuffer_attachment *dstDepth =
-         &drawFB->Attachment[BUFFER_DEPTH];
-      struct gl_renderbuffer_attachment *srcStencil =
-         &readFB->Attachment[BUFFER_STENCIL];
-      struct gl_renderbuffer_attachment *dstStencil =
-         &drawFB->Attachment[BUFFER_STENCIL];
-
       struct st_renderbuffer *srcDepthRb =
          st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
-      struct st_renderbuffer *dstDepthRb = 
+      struct st_renderbuffer *dstDepthRb =
          st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
       struct pipe_surface *dstDepthSurf =
          dstDepthRb ? dstDepthRb->surface : NULL;
@@ -256,8 +257,8 @@ st_BlitFramebuffer(struct gl_context *ctx,
       struct pipe_surface *dstStencilSurf =
          dstStencilRb ? dstStencilRb->surface : NULL;
 
-      if (st_is_depth_stencil_combined(srcDepth, srcStencil) &&
-          st_is_depth_stencil_combined(dstDepth, dstStencil)) {
+      if (_mesa_has_depthstencil_combined(readFB) &&
+          _mesa_has_depthstencil_combined(drawFB)) {
          blit.mask = 0;
          if (mask & GL_DEPTH_BUFFER_BIT)
             blit.mask |= PIPE_MASK_Z;