[Mesa-dev] [PATCH 15/33] intel/blorp: Add support for RGB destinations in copies

Pohjolainen, Topi topi.pohjolainen at gmail.com
Sat Sep 3 17:36:49 UTC 2016


On Sat, Sep 03, 2016 at 10:32:55AM -0700, Jason Ekstrand wrote:
>    On Sat, Sep 3, 2016 at 10:19 AM, Pohjolainen, Topi
>    <[1]topi.pohjolainen at gmail.com> wrote:
> 
>    On Wed, Aug 31, 2016 at 02:22:34PM -0700, Jason Ekstrand wrote:
>    > ---
>    >  src/intel/blorp/blorp_blit.c | 61 ++++++++++++++++++++++++++++++
>    ++++++++++++++
>    >  src/intel/blorp/blorp_priv.h |  6 +++++
>    >  2 files changed, 67 insertions(+)
>    >
>    > diff --git a/src/intel/blorp/blorp_blit.c
>    b/src/intel/blorp/blorp_blit.c
>    > index 42a502c..1790f0b 100644
>    > --- a/src/intel/blorp/blorp_blit.c
>    > +++ b/src/intel/blorp/blorp_blit.c
>    > @@ -1191,6 +1191,27 @@ brw_blorp_build_nir_shader(struct
>    blorp_context *blorp,
>    >        }
>    >     }
>    >
>    > +   if (key->dst_rgb) {
>    > +      /* The destination image is bound as a red texture three times
>    as wide
>    > +       * as the actual image.  Our shader is effectively running one
>    color
>    > +       * component at a time.  We need to pick off the appropriate
>    component
>    > +       * from the source color and write that to destination red.
>    > +       */
>    > +      assert(dst_pos->num_components == 2);
>    > +      nir_ssa_def *comp =
>    > +         nir_umod(&b, nir_channel(&b, dst_pos, 0), nir_imm_int(&b,
>    3));
>    > +
>    > +      nir_ssa_def *color_component =
>    > +         nir_bcsel(&b, nir_ieq(&b, comp, nir_imm_int(&b, 0)),
>    > +                       nir_channel(&b, color, 0),
>    > +                       nir_bcsel(&b, nir_ieq(&b, comp,
>    nir_imm_int(&b, 1)),
>    > +                                     nir_channel(&b, color, 1),
>    > +                                     nir_channel(&b, color, 2)));
>    > +
>    > +      nir_ssa_def *u = nir_ssa_undef(&b, 1, 32);
>    > +      color = nir_vec4(&b, color_component, u, u, u);
>    > +   }
>    > +
>    >     nir_store_var(&b, v.color_out, color, 0xf);
>    >
>    >     return b.shader;
>    > @@ -1767,6 +1788,40 @@ surf_convert_to_uncompressed(const struct
>    isl_device *isl_dev,
>    >     info->surf.format = get_copy_format_for_bpb(fmtl->bpb);
>    >  }
>    >
>    > +static void
>    > +surf_fake_rgb_with_red(const struct isl_device *isl_dev,
>    > +                       struct brw_blorp_surface_info *info,
>    > +                       uint32_t *x, uint32_t *width)
>    > +{
>    > +   surf_convert_to_single_slice(isl_dev, info);
>    > +
>    > +   info->surf.logical_level0_px.width *= 3;
>    > +   info->surf.phys_level0_sa.width *= 3;
>    > +   *x *= 3;
>    > +   *width *= 3;
>    > +
>    > +   enum isl_format red_format;
>    > +   switch (info->view.format) {
>    > +   case ISL_FORMAT_R8G8B8_UNORM:
>    > +      red_format = ISL_FORMAT_R8_UNORM;
>    > +      break;
>    > +   case ISL_FORMAT_R16G16B16_UNORM:
>    > +      red_format = ISL_FORMAT_R16_UNORM;
>    > +      break;
>    > +   case ISL_FORMAT_R32G32B32_UINT:
>    > +      red_format = ISL_FORMAT_R32_UINT;
>    > +      break;
>    > +   default:
>    > +      unreachable("Invalid RGB copy destination format");
>    > +   }
>    > +   assert(isl_format_get_layout(red_format)->channels.r.type ==
>    > +          isl_format_get_layout(info->view.format)->channels.r.type)
>    ;
>    > +   assert(isl_format_get_layout(red_format)->channels.r.bits ==
>    > +          isl_format_get_layout(info->view.format)->channels.r.bits)
>    ;
>    > +
>    > +   info->surf.format = info->view.format = red_format;
>    > +}
>    > +
>    >  void
>    >  blorp_copy(struct blorp_batch *batch,
>    >             const struct blorp_surf *src_surf,
>    > @@ -1813,6 +1868,12 @@ blorp_copy(struct blorp_batch *batch,
>    >     uint32_t dst_width = src_width;
>    >     uint32_t dst_height = src_height;
>    >
>    > +   if (dst_fmtl->bpb % 3 == 0) {
>    > +      surf_fake_rgb_with_red(batch->blorp->isl_dev, &params.dst,
>    > +                             &dst_x, &dst_width);
>    > +      wm_prog_key.dst_rgb = true;
>    > +   }
>    > +
>    >     do_blorp_blit(batch, &params, &wm_prog_key,
>    >                   src_x, src_y, src_x + src_width, src_y +
>    src_height,
>    >                   dst_x, dst_y, dst_x + dst_width, dst_y +
>    dst_height,
>    > diff --git a/src/intel/blorp/blorp_priv.h
>    b/src/intel/blorp/blorp_priv.h
>    > index 46ff272..99d45a9 100644
>    > --- a/src/intel/blorp/blorp_priv.h
>    > +++ b/src/intel/blorp/blorp_priv.h
>    > @@ -245,6 +245,12 @@ struct brw_blorp_blit_prog_key
>    >      */
>    >     bool dst_tiled_w;
>    >
>    > +   /* True if the destination is an RGB format.  If true, the
>    surface state
>    > +    * for the render target must be configured as red with three
>    times the
>    > +    * normal width.
> 
>      And this is because we don't have any native renderable RGB formats?
> 
>    Yes, you can only render to power-of-two formats

Makes sense. You could add that to the comment also (gives rational to why
"must be configured as red")?

Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>

I think all are now reviewed?

> 
>      > +    */
>      > +   bool dst_rgb;
>      > +
>      >     /* True if all source samples should be blended together to
>      produce each
>      >      * destination pixel.  If true, src_tiled_w must be false,
>      tex_samples must
>      >      * equal src_samples, and tex_samples must be nonzero.
>      > --
>      > 2.5.0.400.gff86faf
>      >
>      > _______________________________________________
>      > mesa-dev mailing list
>      > [2]mesa-dev at lists.freedesktop.org
>      > [3]https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 
> References
> 
>    1. mailto:topi.pohjolainen at gmail.com
>    2. mailto:mesa-dev at lists.freedesktop.org
>    3. https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list