intel: Move XRGB->ARGB blit logic into intel_miptree_blit().
authorEric Anholt <eric@anholt.net>
Tue, 4 Jun 2013 05:55:39 +0000 (22:55 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 17 Jun 2013 22:43:23 +0000 (15:43 -0700)
Now any caller (such as glCopyPixels()) can benefit from it, and it only
changes the correct subset of the destination instead of a whole teximage.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/mesa/drivers/dri/intel/intel_blit.c
src/mesa/drivers/dri/intel/intel_blit.h
src/mesa/drivers/dri/intel/intel_pixel_copy.c
src/mesa/drivers/dri/intel/intel_tex_copy.c

index b36f07007a75b88aa970e8373a67c25b036e37a4..da56f55c4df323082c347c7b744eb709cabf3689 100644 (file)
 
 #define FILE_DEBUG_FLAG DEBUG_BLIT
 
+static void
+intel_miptree_set_alpha_to_one(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               int x, int y, int width, int height);
+
 static GLuint translate_raster_op(GLenum logicop)
 {
    switch(logicop) {
@@ -152,10 +157,29 @@ intel_miptree_blit(struct intel_context *intel,
                    uint32_t width, uint32_t height,
                    GLenum logicop)
 {
-   /* We don't assert on format because we may blit from ARGB8888 to XRGB8888,
-    * for example.
+   /* No sRGB decode or encode is done by the hardware blitter, which is
+    * consistent with what we want in the callers (glCopyTexSubImage(),
+    * glBlitFramebuffer(), texture validation, etc.).
+    */
+   gl_format src_format = _mesa_get_srgb_format_linear(src_mt->format);
+   gl_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format);
+
+   /* The blitter doesn't support doing any format conversions.  We do also
+    * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into
+    * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
+    * channel to 1.0 at the end.
     */
-   assert(src_mt->cpp == dst_mt->cpp);
+   if (src_format != dst_format &&
+      ((src_format != MESA_FORMAT_ARGB8888 &&
+        src_format != MESA_FORMAT_XRGB8888) ||
+       (dst_format != MESA_FORMAT_ARGB8888 &&
+        dst_format != MESA_FORMAT_XRGB8888))) {
+      perf_debug("%s: Can't use hardware blitter from %s to %s, "
+                 "falling back.\n", __FUNCTION__,
+                 _mesa_get_format_name(src_format),
+                 _mesa_get_format_name(dst_format));
+      return false;
+   }
 
    /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
     * Data Size Limitations):
@@ -211,18 +235,29 @@ intel_miptree_blit(struct intel_context *intel,
    dst_x += dst_image_x;
    dst_y += dst_image_y;
 
-   return intelEmitCopyBlit(intel,
-                            src_mt->cpp,
-                            src_pitch,
-                            src_mt->region->bo, src_mt->offset,
-                            src_mt->region->tiling,
-                            dst_mt->region->pitch,
-                            dst_mt->region->bo, dst_mt->offset,
-                            dst_mt->region->tiling,
-                            src_x, src_y,
-                            dst_x, dst_y,
-                            width, height,
-                            logicop);
+   if (!intelEmitCopyBlit(intel,
+                          src_mt->cpp,
+                          src_pitch,
+                          src_mt->region->bo, src_mt->offset,
+                          src_mt->region->tiling,
+                          dst_mt->region->pitch,
+                          dst_mt->region->bo, dst_mt->offset,
+                          dst_mt->region->tiling,
+                          src_x, src_y,
+                          dst_x, dst_y,
+                          width, height,
+                          logicop)) {
+      return false;
+   }
+
+   if (src_mt->format == MESA_FORMAT_XRGB8888 &&
+       dst_mt->format == MESA_FORMAT_ARGB8888) {
+      intel_miptree_set_alpha_to_one(intel, dst_mt,
+                                     dst_x, dst_y,
+                                     width, height);
+   }
+
+   return true;
 }
 
 /* Copy BitBlt
@@ -673,52 +708,29 @@ intel_emit_linear_blit(struct intel_context *intel,
 }
 
 /**
- * Used to initialize the alpha value of an ARGB8888 teximage after
- * loading it from an XRGB8888 source.
+ * Used to initialize the alpha value of an ARGB8888 miptree after copying
+ * into it from an XRGB8888 source.
  *
- * This is very common with glCopyTexImage2D().
+ * This is very common with glCopyTexImage2D().  Note that the coordinates are
+ * relative to the start of the miptree, not relative to a slice within the
+ * miptree.
  */
-void
-intel_set_teximage_alpha_to_one(struct gl_context *ctx,
-                               struct intel_texture_image *intel_image)
+static void
+intel_miptree_set_alpha_to_one(struct intel_context *intel,
+                              struct intel_mipmap_tree *mt,
+                              int x, int y, int width, int height)
 {
-   struct intel_context *intel = intel_context(ctx);
-   unsigned int image_x, image_y;
-   uint32_t x1, y1, x2, y2;
+   struct intel_region *region = mt->region;
    uint32_t BR13, CMD;
    int pitch, cpp;
    drm_intel_bo *aper_array[2];
-   struct intel_region *region = intel_image->mt->region;
-   int width, height, depth;
    BATCH_LOCALS;
 
-   /* This target would require iterating over the slices, which we don't do */
-   assert(intel_image->base.Base.TexObject->Target != GL_TEXTURE_1D_ARRAY);
-
-   intel_miptree_get_dimensions_for_image(&intel_image->base.Base,
-                                          &width, &height, &depth);
-   assert(depth == 1);
-
-   assert(intel_image->base.Base.TexFormat == MESA_FORMAT_ARGB8888);
-
-   /* get dest x/y in destination texture */
-   intel_miptree_get_image_offset(intel_image->mt,
-                                 intel_image->base.Base.Level,
-                                 intel_image->base.Base.Face,
-                                 &image_x, &image_y);
-
-   x1 = image_x;
-   y1 = image_y;
-   x2 = image_x + width;
-   y2 = image_y + height;
-
    pitch = region->pitch;
    cpp = region->cpp;
 
    DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
-       __FUNCTION__,
-       intel_image->mt->region->bo, pitch,
-       x1, y1, x2 - x1, y2 - y1);
+       __FUNCTION__, region->bo, pitch, x, y, width, height);
 
    BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
    CMD = XY_COLOR_BLT_CMD;
@@ -746,8 +758,8 @@ intel_set_teximage_alpha_to_one(struct gl_context *ctx,
    BEGIN_BATCH_BLT_TILED(6, dst_y_tiled, false);
    OUT_BATCH(CMD | (6 - 2));
    OUT_BATCH(BR13);
-   OUT_BATCH((y1 << 16) | x1);
-   OUT_BATCH((y2 << 16) | x2);
+   OUT_BATCH((y << 16) | x);
+   OUT_BATCH(((y + height) << 16) | (x + width));
    OUT_RELOC_FENCED(region->bo,
                    I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
                    0);
index 9bfe91d5fcc15db4f6f0fb1132471c41029ec33a..0decc80a6e0bcf0bfc862803b0cdb2ba5b4bd62e 100644 (file)
@@ -79,7 +79,5 @@ void intel_emit_linear_blit(struct intel_context *intel,
                            drm_intel_bo *src_bo,
                            unsigned int src_offset,
                            unsigned int size);
-void intel_set_teximage_alpha_to_one(struct gl_context *ctx,
-                                    struct intel_texture_image *intel_image);
 
 #endif
index 22285c07ed8af4d22b7e6d5e7d3063ec7b205228..ac625a683afcc3b324dd0444e58cd72b3d2a60c6 100644 (file)
@@ -89,7 +89,6 @@ do_blit_copypixels(struct gl_context * ctx,
    GLint orig_srcy;
    struct intel_renderbuffer *draw_irb = NULL;
    struct intel_renderbuffer *read_irb = NULL;
-   gl_format read_format, draw_format;
 
    /* Update draw buffer bounds */
    _mesa_update_state(ctx);
@@ -130,18 +129,6 @@ do_blit_copypixels(struct gl_context * ctx,
       return false;
    }
 
-   read_format = intel_rb_format(read_irb);
-   draw_format = intel_rb_format(draw_irb);
-
-   if (draw_format != read_format &&
-       !(draw_format == MESA_FORMAT_XRGB8888 &&
-        read_format == MESA_FORMAT_ARGB8888)) {
-      perf_debug("glCopyPixels() fallback: mismatched formats (%s -> %s\n",
-                 _mesa_get_format_name(read_format),
-                 _mesa_get_format_name(draw_format));
-      return false;
-   }
-
    /* Copypixels can be more than a straight copy.  Ensure all the
     * extra operations are disabled:
     */
index 3ab66d97b542df285fd660a12719988d1d039e0e..4f01c587b6e613722779c05b22ac81824b903467 100644 (file)
@@ -55,10 +55,7 @@ intel_copy_texsubimage(struct intel_context *intel,
                        struct intel_renderbuffer *irb,
                        GLint x, GLint y, GLsizei width, GLsizei height)
 {
-   struct gl_context *ctx = &intel->ctx;
    const GLenum internalFormat = intelImage->base.Base.InternalFormat;
-   bool copy_supported = false;
-   bool copy_supported_with_alpha_override = false;
 
    intel_prepare_render(intel);
 
@@ -86,34 +83,6 @@ intel_copy_texsubimage(struct intel_context *intel,
       return false;
    }
 
-   /* glCopyTexImage (and the glBlitFramebuffer() path that reuses this)
-    * doesn't do any sRGB conversions.
-    */
-   gl_format src_format = _mesa_get_srgb_format_linear(intel_rb_format(irb));
-   gl_format dst_format = _mesa_get_srgb_format_linear(intelImage->base.Base.TexFormat);
-
-   copy_supported = src_format == dst_format;
-
-   /* Converting ARGB8888 to XRGB8888 is trivial: ignore the alpha bits */
-   if (src_format == MESA_FORMAT_ARGB8888 &&
-       dst_format == MESA_FORMAT_XRGB8888) {
-      copy_supported = true;
-   }
-
-   /* Converting XRGB8888 to ARGB8888 requires setting the alpha bits to 1.0 */
-   if (src_format == MESA_FORMAT_XRGB8888 &&
-       dst_format == MESA_FORMAT_ARGB8888) {
-      copy_supported_with_alpha_override = true;
-   }
-
-   if (!copy_supported && !copy_supported_with_alpha_override) {
-      perf_debug("%s mismatched formats %s, %s\n",
-                __FUNCTION__,
-                _mesa_get_format_name(intelImage->base.Base.TexFormat),
-                _mesa_get_format_name(intel_rb_format(irb)));
-      return false;
-   }
-
    /* blit from src buffer to texture */
    if (!intel_miptree_blit(intel,
                            irb->mt, irb->mt_level, irb->mt_layer,
@@ -125,9 +94,6 @@ intel_copy_texsubimage(struct intel_context *intel,
       return false;
    }
 
-   if (copy_supported_with_alpha_override)
-      intel_set_teximage_alpha_to_one(ctx, intelImage);
-
    return true;
 }