<div dir="ltr">fixed subject line<br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 14, 2013 at 4:15 PM, Mark Mueller <span dir="ltr"><<a href="mailto:markkmueller@gmail.com" target="_blank">markkmueller@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This patch consolidates the decision about formats that blorp_blt does and<br>
does not support to blorp instead of leaving that decision to callers. This<br>
opens the door to adding more functionality to blorp, including support for<br>
using GPU acceleration of processing and loading textures.<br>
<br>
This patch fixes piglit generated_tests/spec/glsl-1.50/compiler/-<br>
built-in-functions/op-div-mat4x3-float.geom.<br>
<br>
<br>
Signed-off-by: Mark Mueller <<a href="mailto:MarkKMueller@gmail.com">MarkKMueller@gmail.com</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_blorp.h             |   8 +-<br>
 src/mesa/drivers/dri/i965/brw_blorp_blit.cpp      | 149 ++++++++++++++--------<br>
 src/mesa/drivers/dri/i965/brw_state.h             |   5 +-<br>
 src/mesa/drivers/dri/i965/brw_surface_formats.c   |  26 ++--<br>
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c  |  12 +-<br>
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c |   4 +-<br>
 6 files changed, 131 insertions(+), 73 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h<br>
index 85bf099..5344851 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_blorp.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h<br>
@@ -34,8 +34,7 @@ struct brw_context;<br>
 extern "C" {<br>
 #endif<br>
<br>
-void<br>
-brw_blorp_blit_miptrees(struct brw_context *brw,<br>
+bool brw_blorp_blit_miptrees(struct brw_context *brw,<br>
                         struct intel_mipmap_tree *src_mt,<br>
                         unsigned src_level, unsigned src_layer,<br>
                         struct intel_mipmap_tree *dst_mt,<br>
@@ -356,8 +355,13 @@ public:<br>
    virtual uint32_t get_wm_prog(struct brw_context *brw,<br>
                                 brw_blorp_prog_data **prog_data) const;<br>
<br>
+   bool is_valid() {<br>
+       return valid_parameters;<br>
+   }<br>
+<br>
 private:<br>
    brw_blorp_blit_prog_key wm_prog_key;<br>
+   bool valid_parameters;<br>
 };<br>
<br>
 /**<br>
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp<br>
index d54b926..00461a4 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp<br>
@@ -123,7 +123,7 @@ find_miptree(GLbitfield buffer_bit, struct intel_renderbuffer *irb)<br>
    return mt;<br>
 }<br>
<br>
-void<br>
+bool<br>
 brw_blorp_blit_miptrees(struct brw_context *brw,<br>
                         struct intel_mipmap_tree *src_mt,<br>
                         unsigned src_level, unsigned src_layer,<br>
@@ -135,16 +135,6 @@ brw_blorp_blit_miptrees(struct brw_context *brw,<br>
                         float dst_x1, float dst_y1,<br>
                         GLenum filter, bool mirror_x, bool mirror_y)<br>
 {<br>
-   /* Get ready to blit.  This includes depth resolving the src and dst<br>
-    * buffers if necessary.  Note: it's not necessary to do a color resolve on<br>
-    * the destination buffer because we use the standard render path to render<br>
-    * to destination color buffers, and the standard render path is<br>
-    * fast-color-aware.<br>
-    */<br>
-   intel_miptree_resolve_color(brw, src_mt);<br>
-   intel_miptree_slice_resolve_depth(brw, src_mt, src_level, src_layer);<br>
-   intel_miptree_slice_resolve_depth(brw, dst_mt, dst_level, dst_layer);<br>
-<br>
    DBG("%s from %s mt %p %d %d (%f,%f) (%f,%f)"<br>
        "to %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n",<br>
        __FUNCTION__,<br>
@@ -162,12 +152,28 @@ brw_blorp_blit_miptrees(struct brw_context *brw,<br>
                                 dst_x0, dst_y0,<br>
                                 dst_x1, dst_y1,<br>
                                 filter, mirror_x, mirror_y);<br>
+<br>
+   if (!params.is_valid()) {<br>
+       return false;<br>
+   }<br>
+<br>
+   /* Get ready to blit.  This includes depth resolving the src and dst<br>
+    * buffers if necessary.  Note: it's not necessary to do a color resolve on<br>
+    * the destination buffer because we use the standard render path to render<br>
+    * to destination color buffers, and the standard render path is<br>
+    * fast-color-aware.<br>
+    */<br>
+   intel_miptree_resolve_color(brw, src_mt);<br>
+   intel_miptree_slice_resolve_depth(brw, src_mt, src_level, src_layer);<br>
+   intel_miptree_slice_resolve_depth(brw, dst_mt, dst_level, dst_layer);<br>
+<br>
    brw_blorp_exec(brw, &params);<br>
<br>
    intel_miptree_slice_set_needs_hiz_resolve(dst_mt, dst_level, dst_layer);<br>
+   return true;<br>
 }<br>
<br>
-static void<br>
+static bool<br>
 do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,<br>
               struct intel_renderbuffer *src_irb,<br>
               struct intel_renderbuffer *dst_irb,<br>
@@ -180,14 +186,17 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit,<br>
    struct intel_mipmap_tree *dst_mt = find_miptree(buffer_bit, dst_irb);<br>
<br>
    /* Do the blit */<br>
-   brw_blorp_blit_miptrees(brw,<br>
-                           src_mt, src_irb->mt_level, src_irb->mt_layer,<br>
-                           dst_mt, dst_irb->mt_level, dst_irb->mt_layer,<br>
-                           srcX0, srcY0, srcX1, srcY1,<br>
-                           dstX0, dstY0, dstX1, dstY1,<br>
-                           filter, mirror_x, mirror_y);<br>
+   if (!brw_blorp_blit_miptrees(brw,<br>
+                                src_mt, src_irb->mt_level, src_irb->mt_layer,<br>
+                                dst_mt, dst_irb->mt_level, dst_irb->mt_layer,<br>
+                                srcX0, srcY0, srcX1, srcY1,<br>
+                                dstX0, dstY0, dstX1, dstY1,<br>
+                                filter, mirror_x, mirror_y)) {<br>
+      return false;<br>
+   }<br>
<br>
    intel_renderbuffer_set_needs_downsample(dst_irb);<br>
+   return true;<br>
 }<br>
<br>
 static bool<br>
@@ -293,10 +302,13 @@ try_blorp_blit(struct brw_context *brw,<br>
       }<br>
       for (unsigned i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; ++i) {<br>
          dst_irb = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);<br>
-        if (dst_irb)<br>
-            do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,<br>
-                          srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,<br>
-                          filter, mirror_x, mirror_y);<br>
+         if (dst_irb) {<br>
+            if (!do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,<br>
+                               srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,<br>
+                               filter, mirror_x, mirror_y)) {<br>
+               return false;<br>
+            }<br>
+         }<br>
       }<br>
       break;<br>
    case GL_DEPTH_BUFFER_BIT:<br>
@@ -306,9 +318,11 @@ try_blorp_blit(struct brw_context *brw,<br>
          intel_renderbuffer(draw_fb->Attachment[BUFFER_DEPTH].Renderbuffer);<br>
       if (!formats_match(buffer_bit, src_irb, dst_irb))<br>
          return false;<br>
-      do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,<br>
-                    srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,<br>
-                    filter, mirror_x, mirror_y);<br>
+      if (!do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,<br>
+                         srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,<br>
+                         filter, mirror_x, mirror_y)) {<br>
+         return false;<br>
+      }<br>
       break;<br>
    case GL_STENCIL_BUFFER_BIT:<br>
       src_irb =<br>
@@ -317,9 +331,11 @@ try_blorp_blit(struct brw_context *brw,<br>
          intel_renderbuffer(draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer);<br>
       if (!formats_match(buffer_bit, src_irb, dst_irb))<br>
          return false;<br>
-      do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,<br>
-                    srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,<br>
-                    filter, mirror_x, mirror_y);<br>
+      if (!do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0,<br>
+                         srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,<br>
+                         filter, mirror_x, mirror_y)) {<br>
+         return false;<br>
+      }<br>
       break;<br>
    default:<br>
       assert(false);<br>
@@ -349,27 +365,11 @@ brw_blorp_copytexsubimage(struct brw_context *brw,<br>
    struct intel_mipmap_tree *src_mt = src_irb->mt;<br>
    struct intel_mipmap_tree *dst_mt = intel_image->mt;<br>
<br>
-   /* BLORP is not supported before Gen6. */<br>
-   if (brw->gen < 6)<br>
-      return false;<br>
-<br>
    if (_mesa_get_format_base_format(src_mt->format) !=<br>
        _mesa_get_format_base_format(dst_mt->format)) {<br>
       return false;<br>
    }<br>
<br>
-   /* We can't handle format conversions between Z24 and other formats since<br>
-    * we have to lie about the surface format.  See the comments in<br>
-    * brw_blorp_surface_info::set().<br>
-    */<br>
-   if ((src_mt->format == MESA_FORMAT_X8_Z24) !=<br>
-       (dst_mt->format == MESA_FORMAT_X8_Z24)) {<br>
-      return false;<br>
-   }<br>
-<br>
-   if (!brw->format_supported_as_render_target[dst_mt->format])<br>
-      return false;<br>
-<br>
    /* Source clipping shouldn't be necessary, since copytexsubimage (in<br>
     * src/mesa/main/teximage.c) calls _mesa_clip_copytexsubimage() which<br>
     * takes care of it.<br>
@@ -396,12 +396,14 @@ brw_blorp_copytexsubimage(struct brw_context *brw,<br>
       mirror_y = true;<br>
    }<br>
<br>
-   brw_blorp_blit_miptrees(brw,<br>
-                           src_mt, src_irb->mt_level, src_irb->mt_layer,<br>
-                           dst_mt, dst_image->Level, dst_image->Face + slice,<br>
-                           srcX0, srcY0, srcX1, srcY1,<br>
-                           dstX0, dstY0, dstX1, dstY1,<br>
-                           GL_NEAREST, false, mirror_y);<br>
+   if (!brw_blorp_blit_miptrees(brw,<br>
+                                src_mt, src_irb->mt_level, src_irb->mt_layer,<br>
+                                dst_mt, dst_image->Level, dst_image->Face + slice,<br>
+                                srcX0, srcY0, srcX1, srcY1,<br>
+                                dstX0, dstY0, dstX1, dstY1,<br>
+                                GL_NEAREST, false, mirror_y)) {<br>
+      return false;<br>
+   }<br>
<br>
    /* If we're copying to a packed depth stencil texture and the source<br>
     * framebuffer has separate stencil, we need to also copy the stencil data<br>
@@ -2069,10 +2071,52 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,<br>
                                              GLfloat dst_x1, GLfloat dst_y1,<br>
                                              GLenum filter,<br>
                                              bool mirror_x, bool mirror_y)<br>
+    : valid_parameters(false)<br>
 {<br>
    struct gl_context *ctx = &brw->ctx;<br>
-   const struct gl_framebuffer *read_fb = ctx->ReadBuffer;<br>
<br>
+   /* BLORP is not supported before Gen6. */<br>
+   if (brw->gen < 6)<br>
+      return;<br>
+<br>
+   if (MESA_FORMAT_NONE == src_mt->format || MESA_FORMAT_COUNT <= src_mt->format) {<br>
+      perf_debug("%s: Blorp doesn't yet support provided source format.\n", __FUNCTION__);<br>
+      return;<br>
+   }<br>
+<br>
+   /* We can't handle format conversions between Z24 and other formats since<br>
+    * we have to lie about the surface format.  See the comments in<br>
+    * brw_blorp_surface_info::set().<br>
+    */<br>
+   if ((src_mt->format == MESA_FORMAT_X8_Z24) !=<br>
+       (dst_mt->format == MESA_FORMAT_X8_Z24)) {<br>
+      return;<br>
+   }<br>
+<br>
+   /* blorp lies about some formats to placate the GPU. */<br>
+   const GLint srcFormatTranslated = translate_tex_format(brw, src_mt->format, 0, true);<br>
+   const GLint dstFormatTranslated = translate_tex_format(brw, dst_mt->format, 0, true);<br>
+   if (0 == srcFormatTranslated || 0 == dstFormatTranslated) {<br>
+      perf_debug("%s: compatible brw_surface format not found for source or target "<br>
+                  "texture mip tree. Source: %s Target: %s\n",<br>
+                  __FUNCTION__, _mesa_get_format_name(src_mt->format),<br>
+                  _mesa_get_format_name(dst_mt->format));<br>
+      return;<br>
+   }<br>
+<br>
+   if (!brw->format_supported_as_render_target[dst_mt->format]) {<br>
+      perf_debug("%s: The translated target miptree format is not supported as a render target: %s.\n",<br>
+                  __FUNCTION__, _mesa_get_format_name(dst_mt->format));<br>
+      return;<br>
+   }<br>
+<br>
+   if (!brw_format_for_sampling(brw, srcFormatTranslated)) {<br>
+      perf_debug("%s: The translated source miptree format is not supported for sampling: %s.\n",<br>
+                  __FUNCTION__, _mesa_get_format_name(src_mt->format));<br>
+      return;<br>
+   }<br>
+<br>
+   const struct gl_framebuffer *read_fb = ctx->ReadBuffer;<br>
    src.set(brw, src_mt, src_level, src_layer, false);<br>
    dst.set(brw, dst_mt, dst_level, dst_layer, true);<br>
<br>
@@ -2123,7 +2167,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,<br>
       wm_prog_key.texture_data_type = BRW_REGISTER_TYPE_D;<br>
       break;<br>
    default:<br>
-      assert(!"Unrecognized blorp format");<br>
+      _mesa_debug(&brw->ctx, "Unrecognized blorp format");<br>
       break;<br>
    }<br>
<br>
@@ -2329,6 +2373,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,<br>
       src.x_offset *= 2;<br>
       src.y_offset /= 2;<br>
    }<br>
+   valid_parameters = true;<br>
 }<br>
<br>
 uint32_t<br>
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h<br>
index 471f1da..49b02b6 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_state.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_state.h<br>
@@ -188,13 +188,14 @@ uint32_t brw_get_surface_tiling_bits(uint32_t tiling);<br>
 uint32_t brw_get_surface_num_multisamples(unsigned num_samples);<br>
<br>
 uint32_t brw_format_for_mesa_format(gl_format mesa_format);<br>
+bool brw_format_for_sampling(struct brw_context *brw, const unsigned brw_surface_sel);<br>
<br>
 GLuint translate_tex_target(GLenum target);<br>
<br>
 GLuint translate_tex_format(struct brw_context *brw,<br>
                             gl_format mesa_format,<br>
-                           GLenum depth_mode,<br>
-                           GLenum srgb_decode);<br>
+                            GLenum srgb_decode,<br>
+                            bool for_render);<br>
<br>
 int brw_get_texture_swizzle(const struct gl_context *ctx,<br>
                             const struct gl_texture_object *t);<br>
diff --git a/src/mesa/drivers/dri/i965/brw_surface_formats.c b/src/mesa/drivers/dri/i965/brw_surface_formats.c<br>
index 7afca79..c9715a7 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_surface_formats.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_surface_formats.c<br>
@@ -306,6 +306,13 @@ const struct surface_format_info surface_formats[] = {<br>
    SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8_UINT)<br>
    SF( x,  x,  x,  x,  x,  x,  x,  x,  x, BRW_SURFACEFORMAT_R8G8B8_SINT)<br>
 };<br>
+<br>
+bool<br>
+brw_format_for_sampling(struct brw_context *brw, const unsigned brw_surface_sel)<br>
+{<br>
+   return (brw_surface_sel && surface_formats[brw_surface_sel].sampling <= brw->gen * 10);<br>
+}<br>
+<br>
 #undef x<br>
 #undef Y<br>
<br>
@@ -686,24 +693,26 @@ brw_render_target_supported(struct brw_context *brw,<br>
 GLuint<br>
 translate_tex_format(struct brw_context *brw,<br>
                      gl_format mesa_format,<br>
-                    GLenum depth_mode,<br>
-                    GLenum srgb_decode)<br>
+                     GLenum srgb_decode,<br>
+                     bool for_render)<br>
 {<br>
-   struct gl_context *ctx = &brw->ctx;<br>
    if (srgb_decode == GL_SKIP_DECODE_EXT)<br>
       mesa_format = _mesa_get_srgb_format_linear(mesa_format);<br>
<br>
    switch( mesa_format ) {<br>
<br>
+   case MESA_FORMAT_S8:<br>
+      return BRW_SURFACEFORMAT_R8_UNORM;<br>
+<br>
    case MESA_FORMAT_Z16:<br>
-      return BRW_SURFACEFORMAT_I16_UNORM;<br>
+      return for_render ? BRW_SURFACEFORMAT_R16_UNORM : BRW_SURFACEFORMAT_I16_UNORM;<br>
<br>
    case MESA_FORMAT_S8_Z24:<br>
    case MESA_FORMAT_X8_Z24:<br>
-      return BRW_SURFACEFORMAT_I24X8_UNORM;<br>
+      return for_render ? BRW_SURFACEFORMAT_B8G8R8A8_UNORM : BRW_SURFACEFORMAT_I24X8_UNORM;<br>
<br>
    case MESA_FORMAT_Z32_FLOAT:<br>
-      return BRW_SURFACEFORMAT_I32_FLOAT;<br>
+      return for_render ? BRW_SURFACEFORMAT_R32_FLOAT : BRW_SURFACEFORMAT_I32_FLOAT;<br>
<br>
    case MESA_FORMAT_Z32_FLOAT_X24S8:<br>
       return BRW_SURFACEFORMAT_R32G32_FLOAT;<br>
@@ -712,7 +721,7 @@ translate_tex_format(struct brw_context *brw,<br>
       /* The value of this BRW_SURFACEFORMAT is 0, which tricks the<br>
        * assertion below.<br>
        */<br>
-      return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;<br>
+      return for_render ? BRW_SURFACEFORMAT_B8G8R8A8_UNORM : BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;<br>
<br>
    case MESA_FORMAT_SRGB_DXT1:<br>
       if (brw->gen == 4 && !brw->is_g4x) {<br>
@@ -720,13 +729,12 @@ translate_tex_format(struct brw_context *brw,<br>
           * skipping SRGB decode.  It's not worth not supporting sRGB in<br>
           * general to prevent this.<br>
           */<br>
+         struct gl_context *ctx = &brw->ctx;<br>
          WARN_ONCE(true, "Demoting sRGB DXT1 texture to non-sRGB\n");<br>
          mesa_format = MESA_FORMAT_RGB_DXT1;<br>
       }<br>
-      return brw_format_for_mesa_format(mesa_format);<br>
<br>
    default:<br>
-      assert(brw_format_for_mesa_format(mesa_format) != 0);<br>
       return brw_format_for_mesa_format(mesa_format);<br>
    }<br>
 }<br>
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
index 662c975..4873353 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
@@ -285,13 +285,13 @@ brw_update_texture_surface(struct gl_context *ctx,<br>
    (void) for_gather;   /* no w/a to apply for this gen */<br>
<br>
    surf[0] = (translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |<br>
-             BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |<br>
-             BRW_SURFACE_CUBEFACE_ENABLES |<br>
-             (translate_tex_format(brw,<br>
+              BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |<br>
+              BRW_SURFACE_CUBEFACE_ENABLES |<br>
+              (translate_tex_format(brw,<br>
                                     mt->format,<br>
-                                   tObj->DepthMode,<br>
-                                   sampler->sRGBDecode) <<<br>
-              BRW_SURFACE_FORMAT_SHIFT));<br>
+                                    sampler->sRGBDecode,<br>
+                                    false) <<<br>
+               BRW_SURFACE_FORMAT_SHIFT));<br>
<br>
    surf[1] = intelObj->mt->region->bo->offset + intelObj->mt->offset; /* reloc */<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c<br>
index 3f4817d..13065ec 100644<br>
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c<br>
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c<br>
@@ -291,8 +291,8 @@ gen7_update_texture_surface(struct gl_context *ctx,<br>
<br>
    uint32_t tex_format = translate_tex_format(brw,<br>
                                               mt->format,<br>
-                                              tObj->DepthMode,<br>
-                                              sampler->sRGBDecode);<br>
+                                              sampler->sRGBDecode,<br>
+                                              false);<br>
<br>
    if (for_gather && tex_format == BRW_SURFACEFORMAT_R32G32_FLOAT)<br>
       tex_format = BRW_SURFACEFORMAT_R32G32_FLOAT_LD;<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.1<br>
<br>
</font></span></blockquote></div><br></div></div>