i965: Implement fast color clears using meta operations
[mesa.git] / src / mesa / drivers / dri / i965 / brw_blorp_blit.cpp
index 432c11c5372e07cd5d3cb9b88a0e9a5320b0081f..1cf2d186462ebe6fa61bef942cdc9f66e402e34a 100644 (file)
 #include "brw_context.h"
 #include "brw_blorp_blit_eu.h"
 #include "brw_state.h"
+#include "brw_meta_util.h"
 
 #define FILE_DEBUG_FLAG DEBUG_BLORP
 
-/**
- * Helper function for handling mirror image blits.
- *
- * If coord0 > coord1, swap them and invert the "mirror" boolean.
- */
-static inline void
-fixup_mirroring(bool &mirror, GLfloat &coord0, GLfloat &coord1)
-{
-   if (coord0 > coord1) {
-      mirror = !mirror;
-      GLfloat tmp = coord0;
-      coord0 = coord1;
-      coord1 = tmp;
-   }
-}
-
-
-/**
- * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of
- * destination coordinates.
- *
- * Return true if there is still blitting to do, false if all pixels got
- * rejected by the clip and/or scissor.
- *
- * For clarity, the nomenclature of this function assumes we are clipping and
- * scissoring the X coordinate; the exact same logic applies for Y
- * coordinates.
- *
- * Note: this function may also be used to account for clipping of source
- * coordinates, by swapping the roles of src and dst.
- */
-static inline bool
-clip_or_scissor(bool mirror, GLfloat &src_x0, GLfloat &src_x1, GLfloat &dst_x0,
-                GLfloat &dst_x1, GLfloat fb_xmin, GLfloat fb_xmax)
-{
-   float scale = (float) (src_x1 - src_x0) / (dst_x1 - dst_x0);
-   /* If we are going to scissor everything away, stop. */
-   if (!(fb_xmin < fb_xmax &&
-         dst_x0 < fb_xmax &&
-         fb_xmin < dst_x1 &&
-         dst_x0 < dst_x1)) {
-      return false;
-   }
-
-   /* Clip the destination rectangle, and keep track of how many pixels we
-    * clipped off of the left and right sides of it.
-    */
-   GLint pixels_clipped_left = 0;
-   GLint pixels_clipped_right = 0;
-   if (dst_x0 < fb_xmin) {
-      pixels_clipped_left = fb_xmin - dst_x0;
-      dst_x0 = fb_xmin;
-   }
-   if (fb_xmax < dst_x1) {
-      pixels_clipped_right = dst_x1 - fb_xmax;
-      dst_x1 = fb_xmax;
-   }
-
-   /* If we are mirrored, then before applying pixels_clipped_{left,right} to
-    * the source coordinates, we need to flip them to account for the
-    * mirroring.
-    */
-   if (mirror) {
-      GLint tmp = pixels_clipped_left;
-      pixels_clipped_left = pixels_clipped_right;
-      pixels_clipped_right = tmp;
-   }
-
-   /* Adjust the source rectangle to remove the pixels corresponding to those
-    * that were clipped/scissored out of the destination rectangle.
-    */
-   src_x0 += pixels_clipped_left * scale;
-   src_x1 -= pixels_clipped_right * scale;
-
-   return true;
-}
-
-
 static struct intel_mipmap_tree *
 find_miptree(GLbitfield buffer_bit, struct intel_renderbuffer *irb)
 {
@@ -151,12 +74,12 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
    intel_miptree_slice_resolve_depth(brw, src_mt, src_level, src_layer);
    intel_miptree_slice_resolve_depth(brw, dst_mt, dst_level, dst_layer);
 
-   DBG("%s from %s mt %p %d %d (%f,%f) (%f,%f)"
-       "to %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n",
+   DBG("%s from %dx %s mt %p %d %d (%f,%f) (%f,%f)"
+       "to %dx %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n",
        __FUNCTION__,
-       _mesa_get_format_name(src_mt->format), src_mt,
+       src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt,
        src_level, src_layer, src_x0, src_y0, src_x1, src_y1,
-       _mesa_get_format_name(dst_mt->format), dst_mt,
+       dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt,
        dst_level, dst_layer, dst_x0, dst_y0, dst_x1, dst_y1,
        mirror_x, mirror_y);
 
@@ -193,39 +116,7 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,
                            dstX0, dstY0, dstX1, dstY1,
                            filter, mirror_x, mirror_y);
 
-   intel_renderbuffer_set_needs_downsample(dst_irb);
-}
-
-static bool
-color_formats_match(gl_format src_format, gl_format dst_format)
-{
-   gl_format linear_src_format = _mesa_get_srgb_format_linear(src_format);
-   gl_format linear_dst_format = _mesa_get_srgb_format_linear(dst_format);
-
-   /* Normally, we require the formats to be equal.  However, we also support
-    * blitting from ARGB to XRGB (discarding alpha), and from XRGB to ARGB
-    * (overriding alpha to 1.0 via blending).
-    */
-   return linear_src_format == linear_dst_format ||
-          (linear_src_format == MESA_FORMAT_XRGB8888 &&
-           linear_dst_format == MESA_FORMAT_ARGB8888) ||
-          (linear_src_format == MESA_FORMAT_ARGB8888 &&
-           linear_dst_format == MESA_FORMAT_XRGB8888);
-}
-
-static bool
-formats_match(GLbitfield buffer_bit, struct intel_renderbuffer *src_irb,
-              struct intel_renderbuffer *dst_irb)
-{
-   /* Note: don't just check gl_renderbuffer::Format, because in some cases
-    * multiple gl_formats resolve to the same native type in the miptree (for
-    * example MESA_FORMAT_X8_Z24 and MESA_FORMAT_S8_Z24), and we can blit
-    * between those formats.
-    */
-   gl_format src_format = find_miptree(buffer_bit, src_irb)->format;
-   gl_format dst_format = find_miptree(buffer_bit, dst_irb)->format;
-
-   return color_formats_match(src_format, dst_format);
+   dst_irb->need_downsample = true;
 }
 
 static bool
@@ -244,59 +135,21 @@ try_blorp_blit(struct brw_context *brw,
    const struct gl_framebuffer *read_fb = ctx->ReadBuffer;
    const struct gl_framebuffer *draw_fb = ctx->DrawBuffer;
 
-   /* Detect if the blit needs to be mirrored */
-   bool mirror_x = false, mirror_y = false;
-   fixup_mirroring(mirror_x, srcX0, srcX1);
-   fixup_mirroring(mirror_x, dstX0, dstX1);
-   fixup_mirroring(mirror_y, srcY0, srcY1);
-   fixup_mirroring(mirror_y, dstY0, dstY1);
-
-   /* If the destination rectangle needs to be clipped or scissored, do so.
-    */
-   if (!(clip_or_scissor(mirror_x, srcX0, srcX1, dstX0, dstX1,
-                         draw_fb->_Xmin, draw_fb->_Xmax) &&
-         clip_or_scissor(mirror_y, srcY0, srcY1, dstY0, dstY1,
-                         draw_fb->_Ymin, draw_fb->_Ymax))) {
-      /* Everything got clipped/scissored away, so the blit was successful. */
+   bool mirror_x, mirror_y;
+   if (brw_meta_mirror_clip_and_scissor(ctx,
+                                        &srcX0, &srcY0, &srcX1, &srcY1,
+                                        &dstX0, &dstY0, &dstX1, &dstY1,
+                                        &mirror_x, &mirror_y))
       return true;
-   }
-
-   /* If the source rectangle needs to be clipped or scissored, do so. */
-   if (!(clip_or_scissor(mirror_x, dstX0, dstX1, srcX0, srcX1,
-                         0, read_fb->Width) &&
-         clip_or_scissor(mirror_y, dstY0, dstY1, srcY0, srcY1,
-                         0, read_fb->Height))) {
-      /* Everything got clipped/scissored away, so the blit was successful. */
-      return true;
-   }
-
-   /* Account for the fact that in the system framebuffer, the origin is at
-    * the lower left.
-    */
-   if (_mesa_is_winsys_fbo(read_fb)) {
-      GLint tmp = read_fb->Height - srcY0;
-      srcY0 = read_fb->Height - srcY1;
-      srcY1 = tmp;
-      mirror_y = !mirror_y;
-   }
-   if (_mesa_is_winsys_fbo(draw_fb)) {
-      GLint tmp = draw_fb->Height - dstY0;
-      dstY0 = draw_fb->Height - dstY1;
-      dstY1 = tmp;
-      mirror_y = !mirror_y;
-   }
 
    /* Find buffers */
    struct intel_renderbuffer *src_irb;
    struct intel_renderbuffer *dst_irb;
+   struct intel_mipmap_tree *src_mt;
+   struct intel_mipmap_tree *dst_mt;
    switch (buffer_bit) {
    case GL_COLOR_BUFFER_BIT:
       src_irb = intel_renderbuffer(read_fb->_ColorReadBuffer);
-      for (unsigned i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; ++i) {
-         dst_irb = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
-         if (dst_irb && !formats_match(buffer_bit, src_irb, dst_irb))
-            return false;
-      }
       for (unsigned i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; ++i) {
          dst_irb = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
         if (dst_irb)
@@ -310,8 +163,17 @@ try_blorp_blit(struct brw_context *brw,
          intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer);
       dst_irb =
          intel_renderbuffer(draw_fb->Attachment[BUFFER_DEPTH].Renderbuffer);
-      if (!formats_match(buffer_bit, src_irb, dst_irb))
+      src_mt = find_miptree(buffer_bit, src_irb);
+      dst_mt = find_miptree(buffer_bit, dst_irb);
+
+      /* We can't handle format conversions between Z24 and other formats
+       * since we have to lie about the surface format. See the comments in
+       * brw_blorp_surface_info::set().
+       */
+      if ((src_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT) !=
+          (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT))
          return false;
+
       do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,
                     srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
                     filter, mirror_x, mirror_y);
@@ -321,14 +183,12 @@ try_blorp_blit(struct brw_context *brw,
          intel_renderbuffer(read_fb->Attachment[BUFFER_STENCIL].Renderbuffer);
       dst_irb =
          intel_renderbuffer(draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer);
-      if (!formats_match(buffer_bit, src_irb, dst_irb))
-         return false;
       do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,
                     srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
                     filter, mirror_x, mirror_y);
       break;
    default:
-      assert(false);
+      unreachable("not reached");
    }
 
    return true;
@@ -368,8 +228,8 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
     * we have to lie about the surface format.  See the comments in
     * brw_blorp_surface_info::set().
     */
-   if ((src_mt->format == MESA_FORMAT_X8_Z24) !=
-       (dst_mt->format == MESA_FORMAT_X8_Z24)) {
+   if ((src_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT) !=
+       (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT)) {
       return false;
    }
 
@@ -402,13 +262,21 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
       mirror_y = true;
    }
 
+   /* Account for face selection and texture view MinLayer */
+   int dst_slice = slice + dst_image->TexObject->MinLayer + dst_image->Face;
+   int dst_level = dst_image->Level + dst_image->TexObject->MinLevel;
+
+   _mesa_unlock_texture(ctx, dst_image->TexObject);
+
    brw_blorp_blit_miptrees(brw,
                            src_mt, src_irb->mt_level, src_irb->mt_layer,
-                           dst_mt, dst_image->Level, dst_image->Face + slice,
+                           dst_mt, dst_level, dst_slice,
                            srcX0, srcY0, srcX1, srcY1,
                            dstX0, dstY0, dstX1, dstY1,
                            GL_NEAREST, false, mirror_y);
 
+   _mesa_lock_texture(ctx, dst_image->TexObject);
+
    /* If we're copying to a packed depth stencil texture and the source
     * framebuffer has separate stencil, we need to also copy the stencil data
     * over.
@@ -427,8 +295,7 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
       if (src_mt != dst_mt) {
          brw_blorp_blit_miptrees(brw,
                                  src_mt, src_irb->mt_level, src_irb->mt_layer,
-                                 dst_mt, dst_image->Level,
-                                 dst_image->Face + slice,
+                                 dst_mt, dst_level, dst_slice,
                                  srcX0, srcY0, srcX1, srcY1,
                                  dstX0, dstY0, dstX1, dstY1,
                                  GL_NEAREST, false, mirror_y);
@@ -626,10 +493,9 @@ class brw_blorp_blit_program : public brw_blorp_eu_emitter
 {
 public:
    brw_blorp_blit_program(struct brw_context *brw,
-                          const brw_blorp_blit_prog_key *key);
+                          const brw_blorp_blit_prog_key *key, bool debug_flag);
 
-   const GLuint *compile(struct brw_context *brw, GLuint *program_size,
-                         FILE *dump_file = stdout);
+   const GLuint *compile(struct brw_context *brw, GLuint *program_size);
 
    brw_blorp_prog_data prog_data;
 
@@ -654,11 +520,6 @@ private:
                        const sampler_message_arg *args, int num_args);
    void render_target_write();
 
-   void emit_lrp(const struct brw_reg &dst,
-                 const struct brw_reg &src1,
-                 const struct brw_reg &src2,
-                 const struct brw_reg &src3);
-
    /**
     * Base-2 logarithm of the maximum number of samples that can be blended.
     */
@@ -738,8 +599,9 @@ private:
 
 brw_blorp_blit_program::brw_blorp_blit_program(
       struct brw_context *brw,
-      const brw_blorp_blit_prog_key *key)
-   : brw_blorp_eu_emitter(brw),
+      const brw_blorp_blit_prog_key *key,
+      bool debug_flag)
+   : brw_blorp_eu_emitter(brw, debug_flag),
      brw(brw),
      key(key)
 {
@@ -747,8 +609,7 @@ brw_blorp_blit_program::brw_blorp_blit_program(
 
 const GLuint *
 brw_blorp_blit_program::compile(struct brw_context *brw,
-                                GLuint *program_size,
-                                FILE *dump_file)
+                                GLuint *program_size)
 {
    /* Sanity checks */
    if (key->dst_tiled_w && key->rt_samples > 0) {
@@ -903,7 +764,7 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
     */
    render_target_write();
 
-   return get_program(program_size, dump_file);
+   return get_program(program_size);
 }
 
 void
@@ -1097,9 +958,8 @@ brw_blorp_blit_program::compute_frag_coords()
          break;
       }
       default:
-         assert(!"Unrecognized sample count in "
-                "brw_blorp_blit_program::compute_frag_coords()");
-         break;
+         unreachable("Unrecognized sample count in "
+                     "brw_blorp_blit_program::compute_frag_coords()");
       }
       s_is_zero = false;
    } else {
@@ -1167,17 +1027,17 @@ brw_blorp_blit_program::translate_tiling(bool old_tiled_w, bool new_tiled_w)
       emit_shr(t1, t1, brw_imm_uw(1)); /* (X & ~0b1011) >> 1 */
       emit_and(t2, Y, brw_imm_uw(1)); /* Y & 0b1 */
       emit_shl(t2, t2, brw_imm_uw(2)); /* (Y & 0b1) << 2 */
-      brw_OR(&func, t1, t1, t2); /* (X & ~0b1011) >> 1 | (Y & 0b1) << 2 */
+      emit_or(t1, t1, t2); /* (X & ~0b1011) >> 1 | (Y & 0b1) << 2 */
       emit_and(t2, X, brw_imm_uw(1)); /* X & 0b1 */
-      brw_OR(&func, Xp, t1, t2);
+      emit_or(Xp, t1, t2);
       emit_and(t1, Y, brw_imm_uw(0xfffe)); /* Y & ~0b1 */
       emit_shl(t1, t1, brw_imm_uw(1)); /* (Y & ~0b1) << 1 */
       emit_and(t2, X, brw_imm_uw(8)); /* X & 0b1000 */
       emit_shr(t2, t2, brw_imm_uw(2)); /* (X & 0b1000) >> 2 */
-      brw_OR(&func, t1, t1, t2); /* (Y & ~0b1) << 1 | (X & 0b1000) >> 2 */
+      emit_or(t1, t1, t2); /* (Y & ~0b1) << 1 | (X & 0b1000) >> 2 */
       emit_and(t2, X, brw_imm_uw(2)); /* X & 0b10 */
       emit_shr(t2, t2, brw_imm_uw(1)); /* (X & 0b10) >> 1 */
-      brw_OR(&func, Yp, t1, t2);
+      emit_or(Yp, t1, t2);
       SWAP_XY_AND_XPYP();
    } else {
       /* Applying the same logic as above, but in reverse, we obtain the
@@ -1190,18 +1050,18 @@ brw_blorp_blit_program::translate_tiling(bool old_tiled_w, bool new_tiled_w)
       emit_shl(t1, t1, brw_imm_uw(1)); /* (X & ~0b101) << 1 */
       emit_and(t2, Y, brw_imm_uw(2)); /* Y & 0b10 */
       emit_shl(t2, t2, brw_imm_uw(2)); /* (Y & 0b10) << 2 */
-      brw_OR(&func, t1, t1, t2); /* (X & ~0b101) << 1 | (Y & 0b10) << 2 */
+      emit_or(t1, t1, t2); /* (X & ~0b101) << 1 | (Y & 0b10) << 2 */
       emit_and(t2, Y, brw_imm_uw(1)); /* Y & 0b1 */
       emit_shl(t2, t2, brw_imm_uw(1)); /* (Y & 0b1) << 1 */
-      brw_OR(&func, t1, t1, t2); /* (X & ~0b101) << 1 | (Y & 0b10) << 2
+      emit_or(t1, t1, t2); /* (X & ~0b101) << 1 | (Y & 0b10) << 2
                                     | (Y & 0b1) << 1 */
       emit_and(t2, X, brw_imm_uw(1)); /* X & 0b1 */
-      brw_OR(&func, Xp, t1, t2);
+      emit_or(Xp, t1, t2);
       emit_and(t1, Y, brw_imm_uw(0xfffc)); /* Y & ~0b11 */
       emit_shr(t1, t1, brw_imm_uw(1)); /* (Y & ~0b11) >> 1 */
       emit_and(t2, X, brw_imm_uw(4)); /* X & 0b100 */
       emit_shr(t2, t2, brw_imm_uw(2)); /* (X & 0b100) >> 2 */
-      brw_OR(&func, Yp, t1, t2);
+      emit_or(Yp, t1, t2);
       SWAP_XY_AND_XPYP();
    }
 }
@@ -1229,8 +1089,7 @@ brw_blorp_blit_program::encode_msaa(unsigned num_samples,
       /* We can't compensate for compressed layout since at this point in the
        * program we haven't read from the MCS buffer.
        */
-      assert(!"Bad layout in encode_msaa");
-      break;
+      unreachable("Bad layout in encode_msaa");
    case INTEL_MSAA_LAYOUT_UMS:
       /* No translation necessary. */
       break;
@@ -1244,20 +1103,20 @@ brw_blorp_blit_program::encode_msaa(unsigned num_samples,
          emit_and(t1, X, brw_imm_uw(0xfffe)); /* X & ~0b1 */
          if (!s_is_zero) {
             emit_and(t2, S, brw_imm_uw(1)); /* S & 0b1 */
-            brw_OR(&func, t1, t1, t2); /* (X & ~0b1) | (S & 0b1) */
+            emit_or(t1, t1, t2); /* (X & ~0b1) | (S & 0b1) */
          }
          emit_shl(t1, t1, brw_imm_uw(1)); /* (X & ~0b1) << 1
                                                    | (S & 0b1) << 1 */
          emit_and(t2, X, brw_imm_uw(1)); /* X & 0b1 */
-         brw_OR(&func, Xp, t1, t2);
+         emit_or(Xp, t1, t2);
          emit_and(t1, Y, brw_imm_uw(0xfffe)); /* Y & ~0b1 */
          emit_shl(t1, t1, brw_imm_uw(1)); /* (Y & ~0b1) << 1 */
          if (!s_is_zero) {
             emit_and(t2, S, brw_imm_uw(2)); /* S & 0b10 */
-            brw_OR(&func, t1, t1, t2); /* (Y & ~0b1) << 1 | (S & 0b10) */
+            emit_or(t1, t1, t2); /* (Y & ~0b1) << 1 | (S & 0b10) */
          }
          emit_and(t2, Y, brw_imm_uw(1)); /* Y & 0b1 */
-         brw_OR(&func, Yp, t1, t2);
+         emit_or(Yp, t1, t2);
          break;
       case 8:
          /* encode_msaa(8, IMS, X, Y, S) = (X', Y', 0)
@@ -1269,22 +1128,22 @@ brw_blorp_blit_program::encode_msaa(unsigned num_samples,
          emit_shl(t1, t1, brw_imm_uw(2)); /* (X & ~0b1) << 2 */
          if (!s_is_zero) {
             emit_and(t2, S, brw_imm_uw(4)); /* S & 0b100 */
-            brw_OR(&func, t1, t1, t2); /* (X & ~0b1) << 2 | (S & 0b100) */
+            emit_or(t1, t1, t2); /* (X & ~0b1) << 2 | (S & 0b100) */
             emit_and(t2, S, brw_imm_uw(1)); /* S & 0b1 */
             emit_shl(t2, t2, brw_imm_uw(1)); /* (S & 0b1) << 1 */
-            brw_OR(&func, t1, t1, t2); /* (X & ~0b1) << 2 | (S & 0b100)
+            emit_or(t1, t1, t2); /* (X & ~0b1) << 2 | (S & 0b100)
                                           | (S & 0b1) << 1 */
          }
          emit_and(t2, X, brw_imm_uw(1)); /* X & 0b1 */
-         brw_OR(&func, Xp, t1, t2);
+         emit_or(Xp, t1, t2);
          emit_and(t1, Y, brw_imm_uw(0xfffe)); /* Y & ~0b1 */
          emit_shl(t1, t1, brw_imm_uw(1)); /* (Y & ~0b1) << 1 */
          if (!s_is_zero) {
             emit_and(t2, S, brw_imm_uw(2)); /* S & 0b10 */
-            brw_OR(&func, t1, t1, t2); /* (Y & ~0b1) << 1 | (S & 0b10) */
+            emit_or(t1, t1, t2); /* (Y & ~0b1) << 1 | (S & 0b10) */
          }
          emit_and(t2, Y, brw_imm_uw(1)); /* Y & 0b1 */
-         brw_OR(&func, Yp, t1, t2);
+         emit_or(Yp, t1, t2);
          break;
       }
       SWAP_XY_AND_XPYP();
@@ -1316,8 +1175,7 @@ brw_blorp_blit_program::decode_msaa(unsigned num_samples,
       /* We can't compensate for compressed layout since at this point in the
        * program we don't have access to the MCS buffer.
        */
-      assert(!"Bad layout in encode_msaa");
-      break;
+      unreachable("Bad layout in encode_msaa");
    case INTEL_MSAA_LAYOUT_UMS:
       /* No translation necessary. */
       break;
@@ -1333,15 +1191,15 @@ brw_blorp_blit_program::decode_msaa(unsigned num_samples,
          emit_and(t1, X, brw_imm_uw(0xfffc)); /* X & ~0b11 */
          emit_shr(t1, t1, brw_imm_uw(1)); /* (X & ~0b11) >> 1 */
          emit_and(t2, X, brw_imm_uw(1)); /* X & 0b1 */
-         brw_OR(&func, Xp, t1, t2);
+         emit_or(Xp, t1, t2);
          emit_and(t1, Y, brw_imm_uw(0xfffc)); /* Y & ~0b11 */
          emit_shr(t1, t1, brw_imm_uw(1)); /* (Y & ~0b11) >> 1 */
          emit_and(t2, Y, brw_imm_uw(1)); /* Y & 0b1 */
-         brw_OR(&func, Yp, t1, t2);
+         emit_or(Yp, t1, t2);
          emit_and(t1, Y, brw_imm_uw(2)); /* Y & 0b10 */
          emit_and(t2, X, brw_imm_uw(2)); /* X & 0b10 */
          emit_shr(t2, t2, brw_imm_uw(1)); /* (X & 0b10) >> 1 */
-         brw_OR(&func, S, t1, t2);
+         emit_or(S, t1, t2);
          break;
       case 8:
          /* decode_msaa(8, IMS, X, Y, 0) = (X', Y', S)
@@ -1352,17 +1210,17 @@ brw_blorp_blit_program::decode_msaa(unsigned num_samples,
          emit_and(t1, X, brw_imm_uw(0xfff8)); /* X & ~0b111 */
          emit_shr(t1, t1, brw_imm_uw(2)); /* (X & ~0b111) >> 2 */
          emit_and(t2, X, brw_imm_uw(1)); /* X & 0b1 */
-         brw_OR(&func, Xp, t1, t2);
+         emit_or(Xp, t1, t2);
          emit_and(t1, Y, brw_imm_uw(0xfffc)); /* Y & ~0b11 */
          emit_shr(t1, t1, brw_imm_uw(1)); /* (Y & ~0b11) >> 1 */
          emit_and(t2, Y, brw_imm_uw(1)); /* Y & 0b1 */
-         brw_OR(&func, Yp, t1, t2);
+         emit_or(Yp, t1, t2);
          emit_and(t1, X, brw_imm_uw(4)); /* X & 0b100 */
          emit_and(t2, Y, brw_imm_uw(2)); /* Y & 0b10 */
-         brw_OR(&func, t1, t1, t2); /* (X & 0b100) | (Y & 0b10) */
+         emit_or(t1, t1, t2); /* (X & 0b100) | (Y & 0b10) */
          emit_and(t2, X, brw_imm_uw(2)); /* X & 0b10 */
          emit_shr(t2, t2, brw_imm_uw(1)); /* (X & 0b10) >> 1 */
-         brw_OR(&func, S, t1, t2);
+         emit_or(S, t1, t2);
          break;
       }
       s_is_zero = false;
@@ -1387,16 +1245,16 @@ brw_blorp_blit_program::translate_dst_to_src()
    emit_mov(Xp_f, X);
    emit_mov(Yp_f, Y);
    /* Scale and offset */
-   brw_MUL(&func, X_f, Xp_f, x_transform.multiplier);
-   brw_MUL(&func, Y_f, Yp_f, y_transform.multiplier);
+   emit_mul(X_f, Xp_f, x_transform.multiplier);
+   emit_mul(Y_f, Yp_f, y_transform.multiplier);
    emit_add(X_f, X_f, x_transform.offset);
    emit_add(Y_f, Y_f, y_transform.offset);
    if (key->blit_scaled && key->blend) {
       /* Translate coordinates to lay out the samples in a rectangular  grid
        * roughly corresponding to sample locations.
        */
-      brw_MUL(&func, X_f, X_f, brw_imm_f(key->x_scale));
-      brw_MUL(&func, Y_f, Y_f, brw_imm_f(key->y_scale));
+      emit_mul(X_f, X_f, brw_imm_f(key->x_scale));
+      emit_mul(Y_f, Y_f, brw_imm_f(key->y_scale));
      /* Adjust coordinates so that integers represent pixel centers rather
       * than pixel edges.
       */
@@ -1413,14 +1271,14 @@ brw_blorp_blit_program::translate_dst_to_src()
       /* Store the fractional parts to be used as bilinear interpolation
        *  coefficients.
       */
-      brw_FRC(&func, x_frac, X_f);
-      brw_FRC(&func, y_frac, Y_f);
+      emit_frc(x_frac, X_f);
+      emit_frc(y_frac, Y_f);
 
       /* Round the float coordinates down to nearest integer */
-      brw_RNDD(&func, Xp_f, X_f);
-      brw_RNDD(&func, Yp_f, Y_f);
-      brw_MUL(&func, X_f, Xp_f, brw_imm_f(1 / key->x_scale));
-      brw_MUL(&func, Y_f, Yp_f, brw_imm_f(1 / key->y_scale));
+      emit_rndd(Xp_f, X_f);
+      emit_rndd(Yp_f, Y_f);
+      emit_mul(X_f, Xp_f, brw_imm_f(1 / key->x_scale));
+      emit_mul(Y_f, Yp_f, brw_imm_f(1 / key->y_scale));
       SWAP_XY_AND_XPYP();
    } else if (!key->bilinear_filter) {
       /* Round the float coordinates down to nearest integer by moving to
@@ -1548,9 +1406,7 @@ brw_blorp_blit_program::manual_blend_average(unsigned num_samples)
           * Since we have already sampled from sample 0, all we need to do is
           * skip the remaining fetches and averaging if MCS is zero.
           */
-         brw_CMP(&func, vec16(brw_null_reg()), BRW_CONDITIONAL_NZ,
-                 mcs_data, brw_imm_ud(0));
-         brw_IF(&func, BRW_EXECUTE_16);
+         emit_cmp_if(BRW_CONDITIONAL_NZ, mcs_data, brw_imm_ud(0));
       }
 
       /* Do count_trailing_one_bits(i) times */
@@ -1576,29 +1432,14 @@ brw_blorp_blit_program::manual_blend_average(unsigned num_samples)
       /* Scale the result down by a factor of num_samples */
       /* TODO: should use a smaller loop bound for non-RGBA formats */
       for (int j = 0; j < 4; ++j) {
-         brw_MUL(&func, offset(texture_data[0], 2*j),
+         emit_mul(offset(texture_data[0], 2*j),
                  offset(vec8(texture_data[0]), 2*j),
                  brw_imm_f(1.0/num_samples));
       }
    }
 
    if (key->tex_layout == INTEL_MSAA_LAYOUT_CMS)
-      brw_ENDIF(&func);
-}
-
-void
-brw_blorp_blit_program::emit_lrp(const struct brw_reg &dst,
-                                 const struct brw_reg &src1,
-                                 const struct brw_reg &src2,
-                                 const struct brw_reg &src3)
-{
-   brw_set_access_mode(&func, BRW_ALIGN_16);
-   brw_set_compression_control(&func, BRW_COMPRESSION_NONE);
-   brw_LRP(&func, dst, src1, src2, src3);
-   brw_set_compression_control(&func, BRW_COMPRESSION_2NDHALF);
-   brw_LRP(&func, sechalf(dst), sechalf(src1), sechalf(src2), sechalf(src3));
-   brw_set_compression_control(&func, BRW_COMPRESSION_COMPRESSED);
-   brw_set_access_mode(&func, BRW_ALIGN_1);
+      emit_endif();
 }
 
 void
@@ -1664,32 +1505,30 @@ brw_blorp_blit_program::manual_blend_bilinear(unsigned num_samples)
       *                        | 6 | 7 |                            | 7 | 1 |
       *                        ---------                            ---------
       */
-      brw_FRC(&func, vec16(t1_f), x_sample_coords);
-      brw_FRC(&func, vec16(t2_f), y_sample_coords);
-      brw_MUL(&func, vec16(t1_f), t1_f, brw_imm_f(key->x_scale));
-      brw_MUL(&func, vec16(t2_f), t2_f, brw_imm_f(key->x_scale * key->y_scale));
+      emit_frc(vec16(t1_f), x_sample_coords);
+      emit_frc(vec16(t2_f), y_sample_coords);
+      emit_mul(vec16(t1_f), t1_f, brw_imm_f(key->x_scale));
+      emit_mul(vec16(t2_f), t2_f, brw_imm_f(key->x_scale * key->y_scale));
       emit_add(vec16(t1_f), t1_f, t2_f);
       emit_mov(vec16(S), t1_f);
 
       if (num_samples == 8) {
          /* Map the sample index to a sample number */
-         brw_CMP(&func, vec16(brw_null_reg()), BRW_CONDITIONAL_L,
-                 S, brw_imm_d(4));
-         brw_IF(&func, BRW_EXECUTE_16);
+         emit_cmp_if(BRW_CONDITIONAL_L, S, brw_imm_d(4));
          {
             emit_mov(vec16(t2), brw_imm_d(5));
             emit_if_eq_mov(S, 1, vec16(t2), 2);
             emit_if_eq_mov(S, 2, vec16(t2), 4);
             emit_if_eq_mov(S, 3, vec16(t2), 6);
          }
-         brw_ELSE(&func);
+         emit_else();
          {
             emit_mov(vec16(t2), brw_imm_d(0));
             emit_if_eq_mov(S, 5, vec16(t2), 3);
             emit_if_eq_mov(S, 6, vec16(t2), 7);
             emit_if_eq_mov(S, 7, vec16(t2), 1);
          }
-         brw_ENDIF(&func);
+         emit_endif();
          emit_mov(vec16(S), t2);
       }
       texel_fetch(texture_data[i]);
@@ -1795,8 +1634,7 @@ brw_blorp_blit_program::texel_fetch(struct brw_reg dst)
       }
       break;
    default:
-      assert(!"Should not get here.");
-      break;
+      unreachable("Should not get here.");
    };
 }
 
@@ -1997,9 +1835,6 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
                                              GLenum filter,
                                              bool mirror_x, bool mirror_y)
 {
-   struct gl_context *ctx = &brw->ctx;
-   const struct gl_framebuffer *read_fb = ctx->ReadBuffer;
-
    src.set(brw, src_mt, src_level, src_layer, false);
    dst.set(brw, dst_mt, dst_level, dst_layer, true);
 
@@ -2054,7 +1889,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
       wm_prog_key.texture_data_type = BRW_REGISTER_TYPE_F;
       break;
    case GL_UNSIGNED_INT:
-      if (src_mt->format == MESA_FORMAT_S8) {
+      if (src_mt->format == MESA_FORMAT_S_UINT8) {
          /* We process stencil as though it's an unsigned normalized color */
          wm_prog_key.texture_data_type = BRW_REGISTER_TYPE_F;
       } else {
@@ -2065,8 +1900,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
       wm_prog_key.texture_data_type = BRW_REGISTER_TYPE_D;
       break;
    default:
-      assert(!"Unrecognized blorp format");
-      break;
+      unreachable("Unrecognized blorp format");
    }
 
    if (brw->gen > 6) {
@@ -2151,8 +1985,10 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
    y0 = wm_push_consts.dst_y0 = dst_y0;
    x1 = wm_push_consts.dst_x1 = dst_x1;
    y1 = wm_push_consts.dst_y1 = dst_y1;
-   wm_push_consts.rect_grid_x1 = read_fb->Width * wm_prog_key.x_scale - 1.0;
-   wm_push_consts.rect_grid_y1 = read_fb->Height * wm_prog_key.y_scale - 1.0;
+   wm_push_consts.rect_grid_x1 = (minify(src_mt->logical_width0, src_level) *
+                                  wm_prog_key.x_scale - 1.0);
+   wm_push_consts.rect_grid_y1 = (minify(src_mt->logical_height0, src_level) *
+                                  wm_prog_key.y_scale - 1.0);
 
    wm_push_consts.x_transform.setup(src_x0, src_x1, dst_x0, dst_x1, mirror_x);
    wm_push_consts.y_transform.setup(src_y0, src_y1, dst_y0, dst_y1, mirror_y);
@@ -2185,8 +2021,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
          y1 = ALIGN(y1 * 2, 4);
          break;
       default:
-         assert(!"Unrecognized sample count in brw_blorp_blit_params ctor");
-         break;
+         unreachable("Unrecognized sample count in brw_blorp_blit_params ctor");
       }
       wm_prog_key.use_kill = true;
    }
@@ -2276,9 +2111,10 @@ brw_blorp_blit_params::get_wm_prog(struct brw_context *brw,
    if (!brw_search_cache(&brw->cache, BRW_BLORP_BLIT_PROG,
                          &this->wm_prog_key, sizeof(this->wm_prog_key),
                          &prog_offset, prog_data)) {
-      brw_blorp_blit_program prog(brw, &this->wm_prog_key);
+      brw_blorp_blit_program prog(brw, &this->wm_prog_key,
+                                  INTEL_DEBUG & DEBUG_BLORP);
       GLuint program_size;
-      const GLuint *program = prog.compile(brw, &program_size, stdout);
+      const GLuint *program = prog.compile(brw, &program_size);
       brw_upload_cache(&brw->cache, BRW_BLORP_BLIT_PROG,
                        &this->wm_prog_key, sizeof(this->wm_prog_key),
                        program, program_size,
@@ -2287,14 +2123,3 @@ brw_blorp_blit_params::get_wm_prog(struct brw_context *brw,
    }
    return prog_offset;
 }
-
-void
-brw_blorp_blit_test_compile(struct brw_context *brw,
-                            const brw_blorp_blit_prog_key *key,
-                            FILE *out)
-{
-   GLuint program_size;
-   brw_blorp_blit_program prog(brw, key);
-   INTEL_DEBUG |= DEBUG_BLORP;
-   prog.compile(brw, &program_size, out);
-}