i965: Enable EGL_KHR_gl_texture_3D_image
[mesa.git] / src / mesa / drivers / dri / i965 / intel_copy_image.c
index a94f17196cd5116c2f8c7451c63fe381f1b841d7..7698d8ed90bad4c398eb3212ab428e0cc51792da 100644 (file)
@@ -25,6 +25,7 @@
  *    Jason Ekstrand <jason.ekstrand@intel.com>
  */
 
+#include "brw_blorp.h"
 #include "intel_fbo.h"
 #include "intel_tex.h"
 #include "intel_blit.h"
@@ -48,6 +49,9 @@ copy_image_with_blitter(struct brw_context *brw,
    if (src_mt->num_samples > 0 || dst_mt->num_samples > 0)
       return false;
 
+   if (src_mt->format == MESA_FORMAT_S_UINT8)
+      return false;
+
    /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
     * Data Size Limitations):
     *
@@ -198,6 +202,66 @@ copy_image_with_memcpy(struct brw_context *brw,
    }
 }
 
+static void
+copy_miptrees(struct brw_context *brw,
+              struct intel_mipmap_tree *src_mt,
+              int src_x, int src_y, int src_z, unsigned src_level,
+              struct intel_mipmap_tree *dst_mt,
+              int dst_x, int dst_y, int dst_z, unsigned dst_level,
+              int src_width, int src_height)
+{
+   unsigned bw, bh;
+
+   if (brw->gen >= 6) {
+      brw_blorp_copy_miptrees(brw,
+                              src_mt, src_level, src_z,
+                              dst_mt, dst_level, dst_z,
+                              src_x, src_y, dst_x, dst_y,
+                              src_width, src_height);
+      return;
+   }
+
+   /* We are now going to try and copy the texture using the blitter.  If
+    * that fails, we will fall back mapping the texture and using memcpy.
+    * In either case, we need to do a full resolve.
+    */
+   intel_miptree_all_slices_resolve_hiz(brw, src_mt);
+   intel_miptree_all_slices_resolve_depth(brw, src_mt);
+   intel_miptree_resolve_color(brw, src_mt, 0);
+
+   intel_miptree_all_slices_resolve_hiz(brw, dst_mt);
+   intel_miptree_all_slices_resolve_depth(brw, dst_mt);
+   intel_miptree_resolve_color(brw, dst_mt, 0);
+
+   _mesa_get_format_block_size(src_mt->format, &bw, &bh);
+
+   /* It's legal to have a WxH that's smaller than a compressed block. This
+    * happens for example when you are using a higher level LOD. For this case,
+    * we still want to copy the entire block, or else the decompression will be
+    * incorrect.
+    */
+   if (src_width < bw)
+      src_width = ALIGN_NPOT(src_width, bw);
+
+   if (src_height < bh)
+      src_height = ALIGN_NPOT(src_height, bh);
+
+   if (copy_image_with_blitter(brw, src_mt, src_level,
+                               src_x, src_y, src_z,
+                               dst_mt, dst_level,
+                               dst_x, dst_y, dst_z,
+                               src_width, src_height))
+      return;
+
+   /* This is a worst-case scenario software fallback that maps the two
+    * textures and does a memcpy between them.
+    */
+   copy_image_with_memcpy(brw, src_mt, src_level,
+                          src_x, src_y, src_z,
+                          dst_mt, dst_level,
+                          dst_x, dst_y, dst_z,
+                          src_width, src_height);
+}
 
 static void
 intel_copy_image_sub_data(struct gl_context *ctx,
@@ -212,9 +276,9 @@ intel_copy_image_sub_data(struct gl_context *ctx,
    struct brw_context *brw = brw_context(ctx);
    struct intel_mipmap_tree *src_mt, *dst_mt;
    unsigned src_level, dst_level;
-   GLuint bw, bh;
 
-   if (_mesa_meta_CopyImageSubData_uncompressed(ctx,
+   if (brw->gen < 6 &&
+       _mesa_meta_CopyImageSubData_uncompressed(ctx,
                                                 src_image, src_renderbuffer,
                                                 src_x, src_y, src_z,
                                                 dst_image, dst_renderbuffer,
@@ -256,51 +320,24 @@ intel_copy_image_sub_data(struct gl_context *ctx,
       dst_level = 0;
    }
 
-   if (src_mt->num_samples > 0 || dst_mt->num_samples > 0) {
-      _mesa_problem(ctx, "Failed to copy multisampled texture with BLORP\n");
-      return;
-   }
+   copy_miptrees(brw, src_mt, src_x, src_y, src_z, src_level,
+                 dst_mt, dst_x, dst_y, dst_z, dst_level,
+                 src_width, src_height);
 
-   /* We are now going to try and copy the texture using the blitter.  If
-    * that fails, we will fall back mapping the texture and using memcpy.
-    * In either case, we need to do a full resolve.
-    */
-   intel_miptree_all_slices_resolve_hiz(brw, src_mt);
-   intel_miptree_all_slices_resolve_depth(brw, src_mt);
-   intel_miptree_resolve_color(brw, src_mt, 0);
-
-   intel_miptree_all_slices_resolve_hiz(brw, dst_mt);
-   intel_miptree_all_slices_resolve_depth(brw, dst_mt);
-   intel_miptree_resolve_color(brw, dst_mt, 0);
-
-   _mesa_get_format_block_size(src_mt->format, &bw, &bh);
-
-   /* It's legal to have a WxH that's smaller than a compressed block. This
-    * happens for example when you are using a higher level LOD. For this case,
-    * we still want to copy the entire block, or else the decompression will be
-    * incorrect.
+   /* CopyImage only works for equal formats, texture view equivalence
+    * classes, and a couple special cases for compressed textures.
+    *
+    * Notably, GL_DEPTH_STENCIL does not appear in any equivalence
+    * classes, so we know the formats must be the same, and thus both
+    * will either have stencil, or not.  They can't be mismatched.
     */
-   if (src_width < bw)
-      src_width = ALIGN_NPOT(src_width, bw);
-
-   if (src_height < bh)
-      src_height = ALIGN_NPOT(src_height, bh);
-
-   if (copy_image_with_blitter(brw, src_mt, src_level,
-                               src_x, src_y, src_z,
-                               dst_mt, dst_level,
-                               dst_x, dst_y, dst_z,
-                               src_width, src_height))
-      return;
+   assert((src_mt->stencil_mt != NULL) == (dst_mt->stencil_mt != NULL));
 
-   /* This is a worst-case scenario software fallback that maps the two
-    * textures and does a memcpy between them.
-    */
-   copy_image_with_memcpy(brw, src_mt, src_level,
-                          src_x, src_y, src_z,
-                          dst_mt, dst_level,
-                          dst_x, dst_y, dst_z,
-                          src_width, src_height);
+   if (dst_mt->stencil_mt) {
+      copy_miptrees(brw, src_mt->stencil_mt, src_x, src_y, src_z, src_level,
+                    dst_mt->stencil_mt, dst_x, dst_y, dst_z, dst_level,
+                    src_width, src_height);
+   }
 }
 
 void