s/Tungsten Graphics/VMware/
[mesa.git] / src / mesa / state_tracker / st_cb_blit.c
index ddef2707a977d8ed6c310a03343ec5db01b2191d..a5a0d2d8d2649aab3ecabc9dfa5d92ba5c388585 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * 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
@@ -18,7 +18,7 @@
  * 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.
@@ -33,7 +33,6 @@
 #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_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)
+static void
+st_adjust_blit_for_msaa_resolve(struct pipe_blit_info *blit)
 {
-   util_destroy_blit(st->blit);
-   st->blit = NULL;
+   /* Even though we do multisample resolves at the time of the blit, OpenGL
+    * specification defines them as if they happen at the time of rendering,
+    * which means that the type of averaging we do during the resolve should
+    * only depend on the source format; the destination format should be
+    * ignored. But, specification doesn't seem to be strict about it.
+    *
+    * It has been observed that mulitisample resolves produce slightly better
+    * looking images when averaging is done using destination format. NVIDIA's
+    * proprietary OpenGL driver also follows this approach.
+    *
+    * When multisampling, if the source and destination formats are equal
+    * (aside from the color space), we choose to blit in sRGB space to get
+    * this higher quality image.
+    */
+   if (blit->src.resource->nr_samples > 1 &&
+       blit->dst.resource->nr_samples <= 1) {
+      blit->dst.format = blit->dst.resource->format;
+
+      if (util_format_is_srgb(blit->dst.resource->format))
+         blit->src.format = util_format_srgb(blit->src.resource->format);
+      else
+         blit->src.format = util_format_linear(blit->src.resource->format);
+   }
 }
 
-
 static void
 st_BlitFramebuffer(struct gl_context *ctx,
                    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -209,6 +220,8 @@ st_BlitFramebuffer(struct gl_context *ctx,
                   blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
                   blit.src.format = util_format_linear(srcObj->pt->format);
 
+                  st_adjust_blit_for_msaa_resolve(&blit);
+
                   st->pipe->blit(st->pipe, &blit);
                }
             }
@@ -244,6 +257,8 @@ st_BlitFramebuffer(struct gl_context *ctx,
                   blit.src.box.z = srcSurf->u.tex.first_layer;
                   blit.src.format = util_format_linear(srcSurf->format);
 
+                  st_adjust_blit_for_msaa_resolve(&blit);
+
                   st->pipe->blit(st->pipe, &blit);
                }
             }
@@ -255,31 +270,22 @@ 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(srcDepth->Renderbuffer);
+         st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
       struct st_renderbuffer *dstDepthRb = 
-         st_renderbuffer(dstDepth->Renderbuffer);
+         st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
       struct pipe_surface *dstDepthSurf =
          dstDepthRb ? dstDepthRb->surface : NULL;
 
       struct st_renderbuffer *srcStencilRb =
-         st_renderbuffer(srcStencil->Renderbuffer);
+         st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
       struct st_renderbuffer *dstStencilRb =
-         st_renderbuffer(dstStencil->Renderbuffer);
+         st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
       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;