i965/fs: Lower 32x32 bit multiplication on BXT.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_blorp_blit.cpp
index 92c92aa6e00170e9ae36031ed6fc6853f34c0809..205c905b447e0655d8c21d2f5f372ae03956129e 100644 (file)
@@ -56,8 +56,10 @@ void
 brw_blorp_blit_miptrees(struct brw_context *brw,
                         struct intel_mipmap_tree *src_mt,
                         unsigned src_level, unsigned src_layer,
+                        mesa_format src_format,
                         struct intel_mipmap_tree *dst_mt,
                         unsigned dst_level, unsigned dst_layer,
+                        mesa_format dst_format,
                         float src_x0, float src_y0,
                         float src_x1, float src_y1,
                         float dst_x0, float dst_y0,
@@ -76,7 +78,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
 
    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__,
+       __func__,
        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,
        dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt,
@@ -84,8 +86,8 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
        mirror_x, mirror_y);
 
    brw_blorp_blit_params params(brw,
-                                src_mt, src_level, src_layer,
-                                dst_mt, dst_level, dst_layer,
+                                src_mt, src_level, src_layer, src_format,
+                                dst_mt, dst_level, dst_layer, dst_format,
                                 src_x0, src_y0,
                                 src_x1, src_y1,
                                 dst_x0, dst_y0,
@@ -98,8 +100,8 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
 
 static void
 do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,
-              struct intel_renderbuffer *src_irb,
-              struct intel_renderbuffer *dst_irb,
+              struct intel_renderbuffer *src_irb, mesa_format src_format,
+              struct intel_renderbuffer *dst_irb, mesa_format dst_format,
               GLfloat srcX0, GLfloat srcY0, GLfloat srcX1, GLfloat srcY1,
               GLfloat dstX0, GLfloat dstY0, GLfloat dstX1, GLfloat dstY1,
               GLenum filter, bool mirror_x, bool mirror_y)
@@ -111,7 +113,9 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,
    /* Do the blit */
    brw_blorp_blit_miptrees(brw,
                            src_mt, src_irb->mt_level, src_irb->mt_layer,
+                           src_format,
                            dst_mt, dst_irb->mt_level, dst_irb->mt_layer,
+                           dst_format,
                            srcX0, srcY0, srcX1, srcY1,
                            dstX0, dstY0, dstX1, dstY1,
                            filter, mirror_x, mirror_y);
@@ -121,6 +125,8 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,
 
 static bool
 try_blorp_blit(struct brw_context *brw,
+               const struct gl_framebuffer *read_fb,
+               const struct gl_framebuffer *draw_fb,
                GLfloat srcX0, GLfloat srcY0, GLfloat srcX1, GLfloat srcY1,
                GLfloat dstX0, GLfloat dstY0, GLfloat dstX1, GLfloat dstY1,
                GLenum filter, GLbitfield buffer_bit)
@@ -132,11 +138,8 @@ try_blorp_blit(struct brw_context *brw,
     */
    intel_prepare_render(brw);
 
-   const struct gl_framebuffer *read_fb = ctx->ReadBuffer;
-   const struct gl_framebuffer *draw_fb = ctx->DrawBuffer;
-
    bool mirror_x, mirror_y;
-   if (brw_meta_mirror_clip_and_scissor(ctx,
+   if (brw_meta_mirror_clip_and_scissor(ctx, read_fb, draw_fb,
                                         &srcX0, &srcY0, &srcX1, &srcY1,
                                         &dstX0, &dstY0, &dstX1, &dstY1,
                                         &mirror_x, &mirror_y))
@@ -150,11 +153,14 @@ try_blorp_blit(struct brw_context *brw,
    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]);
+      for (unsigned i = 0; i < draw_fb->_NumColorDrawBuffers; ++i) {
+         dst_irb = intel_renderbuffer(draw_fb->_ColorDrawBuffers[i]);
         if (dst_irb)
-            do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,
-                          srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+            do_blorp_blit(brw, buffer_bit,
+                          src_irb, src_irb->Base.Base.Format,
+                          dst_irb, dst_irb->Base.Base.Format,
+                          srcX0, srcY0, srcX1, srcY1,
+                          dstX0, dstY0, dstX1, dstY1,
                           filter, mirror_x, mirror_y);
       }
       break;
@@ -174,7 +180,8 @@ try_blorp_blit(struct brw_context *brw,
           (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT))
          return false;
 
-      do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,
+      do_blorp_blit(brw, buffer_bit, src_irb, MESA_FORMAT_NONE,
+                    dst_irb, MESA_FORMAT_NONE, srcX0, srcY0,
                     srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
                     filter, mirror_x, mirror_y);
       break;
@@ -183,7 +190,8 @@ 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);
-      do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,
+      do_blorp_blit(brw, buffer_bit, src_irb, MESA_FORMAT_NONE,
+                    dst_irb, MESA_FORMAT_NONE, srcX0, srcY0,
                     srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
                     filter, mirror_x, mirror_y);
       break;
@@ -215,12 +223,12 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
    struct intel_mipmap_tree *src_mt = src_irb->mt;
    struct intel_mipmap_tree *dst_mt = intel_image->mt;
 
-   /* BLORP is not supported before Gen6. */
-   if (brw->gen < 6 || brw->gen >= 8)
+   /* BLORP is only supported for Gen6-7. */
+   if (brw->gen < 6 || brw->gen > 7)
       return false;
 
-   if (_mesa_get_format_base_format(src_mt->format) !=
-       _mesa_get_format_base_format(dst_mt->format)) {
+   if (_mesa_get_format_base_format(src_rb->Format) !=
+       _mesa_get_format_base_format(dst_image->TexFormat)) {
       return false;
    }
 
@@ -233,7 +241,7 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
       return false;
    }
 
-   if (!brw->format_supported_as_render_target[dst_mt->format])
+   if (!brw->format_supported_as_render_target[dst_image->TexFormat])
       return false;
 
    /* Source clipping shouldn't be necessary, since copytexsubimage (in
@@ -268,7 +276,9 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
 
    brw_blorp_blit_miptrees(brw,
                            src_mt, src_irb->mt_level, src_irb->mt_layer,
+                           src_rb->Format,
                            dst_mt, dst_level, dst_slice,
+                           dst_image->TexFormat,
                            srcX0, srcY0, srcX1, srcY1,
                            dstX0, dstY0, dstX1, dstY1,
                            GL_NEAREST, false, mirror_y);
@@ -291,7 +301,9 @@ 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,
+                                 src_mt->format,
                                  dst_mt, dst_level, dst_slice,
+                                 dst_mt->format,
                                  srcX0, srcY0, srcX1, srcY1,
                                  dstX0, dstY0, dstX1, dstY1,
                                  GL_NEAREST, false, mirror_y);
@@ -304,6 +316,8 @@ brw_blorp_copytexsubimage(struct brw_context *brw,
 
 GLbitfield
 brw_blorp_framebuffer(struct brw_context *brw,
+                      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)
@@ -320,7 +334,7 @@ brw_blorp_framebuffer(struct brw_context *brw,
 
    for (unsigned int i = 0; i < ARRAY_SIZE(buffer_bits); ++i) {
       if ((mask & buffer_bits[i]) &&
-       try_blorp_blit(brw,
+       try_blorp_blit(brw, readFb, drawFb,
                       srcX0, srcY0, srcX1, srcY1,
                       dstX0, dstY0, dstX1, dstY1,
                       filter, buffer_bits[i])) {
@@ -1241,10 +1255,8 @@ brw_blorp_blit_program::translate_dst_to_src()
    emit_mov(Xp_f, X);
    emit_mov(Yp_f, Y);
    /* Scale and offset */
-   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);
+   emit_mad(X_f, x_transform.offset, Xp_f, x_transform.multiplier);
+   emit_mad(Y_f, y_transform.offset, Yp_f, y_transform.multiplier);
    if (key->blit_scaled && key->blend) {
       /* Translate coordinates to lay out the samples in a rectangular  grid
        * roughly corresponding to sample locations.
@@ -1273,8 +1285,8 @@ brw_blorp_blit_program::translate_dst_to_src()
       /* Round the float coordinates down to nearest integer */
       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));
+      emit_mul(X_f, Xp_f, brw_imm_f(1.0f / key->x_scale));
+      emit_mul(Y_f, Yp_f, brw_imm_f(1.0f / key->y_scale));
       SWAP_XY_AND_XPYP();
    } else if (!key->bilinear_filter) {
       /* Round the float coordinates down to nearest integer by moving to
@@ -1294,10 +1306,10 @@ brw_blorp_blit_program::clamp_tex_coords(struct brw_reg regX,
                                          struct brw_reg clampX1,
                                          struct brw_reg clampY1)
 {
-   emit_cond_mov(regX, clampX0, BRW_CONDITIONAL_L, regX, clampX0);
-   emit_cond_mov(regX, clampX1, BRW_CONDITIONAL_G, regX, clampX1);
-   emit_cond_mov(regY, clampY0, BRW_CONDITIONAL_L, regY, clampY0);
-   emit_cond_mov(regY, clampY1, BRW_CONDITIONAL_G, regY, clampY1);
+   emit_max(regX, regX, clampX0);
+   emit_max(regY, regY, clampY0);
+   emit_min(regX, regX, clampX1);
+   emit_min(regY, regY, clampY1);
 }
 
 /**
@@ -1330,7 +1342,7 @@ brw_blorp_blit_program::single_to_blend()
  */
 inline int count_trailing_one_bits(unsigned value)
 {
-#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+#ifdef HAVE___BUILTIN_CTZ
    return __builtin_ctz(~value);
 #else
    return _mesa_bitcount(value & ~(value + 1));
@@ -1430,7 +1442,7 @@ brw_blorp_blit_program::manual_blend_average(unsigned num_samples)
       for (int j = 0; j < 4; ++j) {
          emit_mul(offset(texture_data[0], 2*j),
                  offset(vec8(texture_data[0]), 2*j),
-                 brw_imm_f(1.0/num_samples));
+                 brw_imm_f(1.0f / num_samples));
       }
    }
 
@@ -1463,9 +1475,9 @@ brw_blorp_blit_program::manual_blend_bilinear(unsigned num_samples)
 
       /* Compute pixel coordinates */
       emit_add(vec16(x_sample_coords), Xp_f,
-              brw_imm_f((float)(i & 0x1) * (1.0 / key->x_scale)));
+              brw_imm_f((float)(i & 0x1) * (1.0f / key->x_scale)));
       emit_add(vec16(y_sample_coords), Yp_f,
-              brw_imm_f((float)((i >> 1) & 0x1) * (1.0 / key->y_scale)));
+              brw_imm_f((float)((i >> 1) & 0x1) * (1.0f / key->y_scale)));
       emit_mov(vec16(X), x_sample_coords);
       emit_mov(vec16(Y), y_sample_coords);
 
@@ -1777,7 +1789,7 @@ brw_blorp_coord_transform_params::setup(GLfloat src0, GLfloat src1,
        * so 0.5 provides the necessary correction.
        */
       multiplier = scale;
-      offset = src0 + (-dst0 + 0.5) * scale;
+      offset = src0 + (-dst0 + 0.5f) * scale;
    } else {
       /* When mirroring X we need:
        *   src_x - src_x0 = dst_x1 - dst_x - 0.5
@@ -1785,7 +1797,7 @@ brw_blorp_coord_transform_params::setup(GLfloat src0, GLfloat src1,
        *   src_x = src_x0 + (dst_x1 -dst_x - 0.5) * scale
        */
       multiplier = -scale;
-      offset = src0 + (dst1 - 0.5) * scale;
+      offset = src0 + (dst1 - 0.5f) * scale;
    }
 }
 
@@ -1822,8 +1834,10 @@ compute_msaa_layout_for_pipeline(struct brw_context *brw, unsigned num_samples,
 brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
                                              struct intel_mipmap_tree *src_mt,
                                              unsigned src_level, unsigned src_layer,
+                                             mesa_format src_format,
                                              struct intel_mipmap_tree *dst_mt,
                                              unsigned dst_level, unsigned dst_layer,
+                                             mesa_format dst_format,
                                              GLfloat src_x0, GLfloat src_y0,
                                              GLfloat src_x1, GLfloat src_y1,
                                              GLfloat dst_x0, GLfloat dst_y0,
@@ -1831,8 +1845,8 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
                                              GLenum filter,
                                              bool mirror_x, bool mirror_y)
 {
-   src.set(brw, src_mt, src_level, src_layer, false);
-   dst.set(brw, dst_mt, dst_level, dst_layer, true);
+   src.set(brw, src_mt, src_level, src_layer, src_format, false);
+   dst.set(brw, dst_mt, dst_level, dst_layer, dst_format, true);
 
    /* 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,
@@ -1853,8 +1867,9 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
        _mesa_get_format_color_encoding(dst_mt->format) == GL_SRGB &&
        _mesa_get_srgb_format_linear(src_mt->format) ==
        _mesa_get_srgb_format_linear(dst_mt->format)) {
-      dst.brw_surfaceformat = brw_format_for_mesa_format(dst_mt->format);
-      src.brw_surfaceformat = dst.brw_surfaceformat;
+      assert(brw->format_supported_as_render_target[dst_mt->format]);
+      dst.brw_surfaceformat = brw->render_target_format[dst_mt->format];
+      src.brw_surfaceformat = brw_format_for_mesa_format(dst_mt->format);
    }
 
    /* When doing a multisample resolve of a GL_LUMINANCE32F or GL_INTENSITY32F
@@ -1937,8 +1952,8 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
    /* Scaling factors used for bilinear filtering in multisample scaled
     * blits.
     */
-   wm_prog_key.x_scale = 2.0;
-   wm_prog_key.y_scale = src_mt->num_samples / 2.0;
+   wm_prog_key.x_scale = 2.0f;
+   wm_prog_key.y_scale = src_mt->num_samples / 2.0f;
 
    if (filter == GL_LINEAR && src.num_samples <= 1 && dst.num_samples <= 1)
       wm_prog_key.bilinear_filter = true;
@@ -1977,14 +1992,17 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
 
    wm_prog_key.src_tiled_w = src.map_stencil_as_y_tiled;
    wm_prog_key.dst_tiled_w = dst.map_stencil_as_y_tiled;
-   x0 = wm_push_consts.dst_x0 = dst_x0;
-   y0 = wm_push_consts.dst_y0 = dst_y0;
-   x1 = wm_push_consts.dst_x1 = dst_x1;
-   y1 = wm_push_consts.dst_y1 = dst_y1;
+   /* Round floating point values to nearest integer to avoid "off by one texel"
+    * kind of errors when blitting.
+    */
+   x0 = wm_push_consts.dst_x0 = roundf(dst_x0);
+   y0 = wm_push_consts.dst_y0 = roundf(dst_y0);
+   x1 = wm_push_consts.dst_x1 = roundf(dst_x1);
+   y1 = wm_push_consts.dst_y1 = roundf(dst_y1);
    wm_push_consts.rect_grid_x1 = (minify(src_mt->logical_width0, src_level) *
-                                  wm_prog_key.x_scale - 1.0);
+                                  wm_prog_key.x_scale - 1.0f);
    wm_push_consts.rect_grid_y1 = (minify(src_mt->logical_height0, src_level) *
-                                  wm_prog_key.y_scale - 1.0);
+                                  wm_prog_key.y_scale - 1.0f);
 
    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);
@@ -2104,14 +2122,14 @@ brw_blorp_blit_params::get_wm_prog(struct brw_context *brw,
                                    brw_blorp_prog_data **prog_data) const
 {
    uint32_t prog_offset = 0;
-   if (!brw_search_cache(&brw->cache, BRW_BLORP_BLIT_PROG,
+   if (!brw_search_cache(&brw->cache, BRW_CACHE_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,
                                   INTEL_DEBUG & DEBUG_BLORP);
       GLuint program_size;
       const GLuint *program = prog.compile(brw, &program_size);
-      brw_upload_cache(&brw->cache, BRW_BLORP_BLIT_PROG,
+      brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_BLIT_PROG,
                        &this->wm_prog_key, sizeof(this->wm_prog_key),
                        program, program_size,
                        &prog.prog_data, sizeof(prog.prog_data),