<p dir="ltr"></p>
<p dir="ltr">On Sep 1, 2016 1:31 AM, "Pohjolainen, Topi" <<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a>> wrote:<br>
><br>
> On Wed, Aug 31, 2016 at 02:22:31PM -0700, Jason Ekstrand wrote:<br>
> > While it can be useful, the field has substantial limtations.  In<br>
> > particular, the bittom 2 or 3 bits is missing so your offset always has to<br>
><br>
>                   bottom<br>
><br>
> > be a multiple of 4 or 8.  While surface alignments usually work out to make<br>
> > this ok, when you start trying to fake compressed surfaces as uncompressed<br>
> > (which we will want to do) this falls apart.  The easiest solution is to<br>
> > simply align all offsets to a tile boundary and munge the regions we're<br>
> > copying to account for the intratile offset.<br>
> > ---<br>
> >  src/intel/blorp/blorp_blit.c      | 67 ++++++++++++++++++++++++++++++++++++---<br>
> >  src/intel/blorp/blorp_genX_exec.h |  4 +--<br>
> >  src/intel/blorp/blorp_priv.h      | 20 +++++++++++-<br>
> >  3 files changed, 82 insertions(+), 9 deletions(-)<br>
> ><br>
> > diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c<br>
> > index 2838a26..a8b38de 100644<br>
> > --- a/src/intel/blorp/blorp_blit.c<br>
> > +++ b/src/intel/blorp/blorp_blit.c<br>
> > @@ -49,6 +49,8 @@ struct brw_blorp_blit_vars {<br>
> >     nir_variable *v_rect_grid;<br>
> >     nir_variable *v_coord_transform;<br>
> >     nir_variable *v_src_z;<br>
> > +   nir_variable *v_src_offset;<br>
> > +   nir_variable *v_dst_offset;<br>
> ><br>
> >     /* gl_FragCoord */<br>
> >     nir_variable *frag_coord;<br>
> > @@ -69,12 +71,16 @@ brw_blorp_blit_vars_init(nir_builder *b, struct brw_blorp_blit_vars *v,<br>
> >                                       type, #name); \<br>
> >     v->v_##name->data.interpolation = INTERP_MODE_FLAT; \<br>
> >     v->v_##name->data.location = VARYING_SLOT_VAR0 + \<br>
> > -      offsetof(struct brw_blorp_wm_inputs, name) / (4 * sizeof(float));<br>
> > +      offsetof(struct brw_blorp_wm_inputs, name) / (4 * sizeof(float)); \<br>
> > +   v->v_##name->data.location_frac = \<br>
> > +      (offsetof(struct brw_blorp_wm_inputs, name) / sizeof(float)) % 4;<br>
> ><br>
> >     LOAD_INPUT(discard_rect, glsl_vec4_type())<br>
> >     LOAD_INPUT(rect_grid, glsl_vec4_type())<br>
> >     LOAD_INPUT(coord_transform, glsl_vec4_type())<br>
> >     LOAD_INPUT(src_z, glsl_uint_type())<br>
> > +   LOAD_INPUT(src_offset, glsl_vector_type(GLSL_TYPE_UINT, 2))<br>
> > +   LOAD_INPUT(dst_offset, glsl_vector_type(GLSL_TYPE_UINT, 2))<br>
> ><br>
> >  #undef LOAD_INPUT<br>
> ><br>
> > @@ -95,6 +101,10 @@ blorp_blit_get_frag_coords(nir_builder *b,<br>
> >  {<br>
> >     nir_ssa_def *coord = nir_f2i(b, nir_load_var(b, v->frag_coord));<br>
> ><br>
> > +   /* Account for destination surface intratile offset */<br>
> > +   if (key->need_dst_offset)<br>
> > +      coord = nir_isub(b, coord, nir_load_var(b, v->v_dst_offset));<br>
><br>
> We need to subtract instead of add due to coordinate origin being upper-left,<br>
> right?</p>
<p dir="ltr">Both src_offset and dst_offset are offsets into the surface where the part of the surface we care about is. Let's call them the physical and logical surfaces. gl_FragCoord is going to give the currently being rendered coordinate on the physical surface but we need it converted to a position on the logical surface before we go any further.  When texturing, on the other hand, we get a logical position and need to covert it to a physical one.  The conversion from logical to phi l physical of an addition and the other direction (which we're doing here) is a subtraction.</p>
<p dir="ltr">> Otherwise this looks quite clear:<br>
><br>
> Reviewed-by: Topi Pohjolainen <<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a>><br>
><br>
> > +<br>
> >     if (key->persample_msaa_dispatch) {<br>
> >        return nir_vec3(b, nir_channel(b, coord, 0), nir_channel(b, coord, 1),<br>
> >                        nir_load_sample_id(b));<br>
> > @@ -1160,6 +1170,9 @@ brw_blorp_build_nir_shader(struct blorp_context *blorp,<br>
> >                                              key->tex_layout);<br>
> >           }<br>
> ><br>
> > +         if (key->need_src_offset)<br>
> > +            src_pos = nir_iadd(&b, src_pos, nir_load_var(&b, v.v_src_offset));<br>
> > +<br>
> >           /* Now (X, Y, S) = decode_msaa(tex_samples, detile(tex_tiling, offset)).<br>
> >            *<br>
> >            * In other words: X, Y, and S now contain values which, when passed to<br>
> > @@ -1247,6 +1260,23 @@ brw_blorp_setup_coord_transform(struct brw_blorp_coord_transform *xform,<br>
> >     }<br>
> >  }<br>
> ><br>
> > +static inline void<br>
> > +surf_get_intratile_offset_px(struct brw_blorp_surface_info *info,<br>
> > +                             uint32_t *tile_x_px, uint32_t *tile_y_px)<br>
> > +{<br>
> > +   if (info->surf.msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED) {<br>
> > +      struct isl_extent2d px_size_sa =<br>
> > +         isl_get_interleaved_msaa_px_size_sa(info->surf.samples);<br>
> > +      assert(info->tile_x_sa % px_size_sa.width == 0);<br>
> > +      assert(info->tile_y_sa % px_size_sa.height == 0);<br>
> > +      *tile_x_px = info->tile_x_sa / px_size_sa.width;<br>
> > +      *tile_y_px = info->tile_y_sa / px_size_sa.height;<br>
> > +   } else {<br>
> > +      *tile_x_px = info->tile_x_sa;<br>
> > +      *tile_y_px = info->tile_y_sa;<br>
> > +   }<br>
> > +}<br>
> > +<br>
> >  static void<br>
> >  surf_convert_to_single_slice(const struct isl_device *isl_dev,<br>
> >                               struct brw_blorp_surface_info *info)<br>
> > @@ -1283,6 +1313,14 @@ surf_convert_to_single_slice(const struct isl_device *isl_dev,<br>
> >                                        &info->tile_x_sa, &info->tile_y_sa);<br>
> >     info->addr.offset += byte_offset;<br>
> ><br>
> > +   const uint32_t slice_width_px =<br>
> > +      minify(info->surf.logical_level0_px.width, info->view.base_level);<br>
> > +   const uint32_t slice_height_px =<br>
> > +      minify(info->surf.logical_level0_px.height, info->view.base_level);<br>
> > +<br>
> > +   uint32_t tile_x_px, tile_y_px;<br>
> > +   surf_get_intratile_offset_px(info, &tile_x_px, &tile_y_px);<br>
> > +<br>
> >     /* TODO: Once this file gets converted to C, we shouls just use designated<br>
> >      * initializers.<br>
> >      */<br>
> > @@ -1290,10 +1328,8 @@ surf_convert_to_single_slice(const struct isl_device *isl_dev,<br>
> ><br>
> >     init_info.dim = ISL_SURF_DIM_2D;<br>
> >     init_info.format = info->surf.format;<br>
> > -   init_info.width =<br>
> > -      minify(info->surf.logical_level0_px.width, info->view.base_level);<br>
> > -   init_info.height =<br>
> > -      minify(info->surf.logical_level0_px.height, info->view.base_level);<br>
> > +   init_info.width = slice_width_px + tile_x_px;<br>
> > +   init_info.height = slice_height_px + tile_y_px;<br>
> >     init_info.depth = 1;<br>
> >     init_info.levels = 1;<br>
> >     init_info.array_len = 1;<br>
> > @@ -1497,6 +1533,7 @@ blorp_blit(struct blorp_batch *batch,<br>
> >        surf_fake_interleaved_msaa(batch->blorp->isl_dev, &params.dst);<br>
> ><br>
> >        wm_prog_key.use_kill = true;<br>
> > +      wm_prog_key.need_dst_offset = true;<br>
> >     }<br>
> ><br>
> >     if (params.dst.surf.tiling == ISL_TILING_W) {<br>
> > @@ -1557,6 +1594,7 @@ blorp_blit(struct blorp_batch *batch,<br>
> ><br>
> >        wm_prog_key.dst_tiled_w = true;<br>
> >        wm_prog_key.use_kill = true;<br>
> > +      wm_prog_key.need_dst_offset = true;<br>
> ><br>
> >        if (params.dst.surf.samples > 1) {<br>
> >           /* If the destination surface is a W-tiled multisampled stencil<br>
> > @@ -1581,6 +1619,7 @@ blorp_blit(struct blorp_batch *batch,<br>
> >        surf_retile_w_to_y(batch->blorp->isl_dev, &params.src);<br>
> ><br>
> >        wm_prog_key.src_tiled_w = true;<br>
> > +      wm_prog_key.need_src_offset = true;<br>
> >     }<br>
> ><br>
> >     /* tex_samples and rt_samples are the sample counts that are set up in<br>
> > @@ -1604,6 +1643,24 @@ blorp_blit(struct blorp_batch *batch,<br>
> >        wm_prog_key.persample_msaa_dispatch = true;<br>
> >     }<br>
> ><br>
> > +   if (params.src.tile_x_sa || params.src.tile_y_sa) {<br>
> > +      assert(wm_prog_key.need_src_offset);<br>
> > +      surf_get_intratile_offset_px(&params.src,<br>
> > +                                   &params.wm_inputs.src_offset.x,<br>
> > +                                   &params.wm_inputs.src_offset.y);<br>
> > +   }<br>
> > +<br>
> > +   if (params.dst.tile_x_sa || params.dst.tile_y_sa) {<br>
> > +      assert(wm_prog_key.need_dst_offset);<br>
> > +      surf_get_intratile_offset_px(&params.dst,<br>
> > +                                   &params.wm_inputs.dst_offset.x,<br>
> > +                                   &params.wm_inputs.dst_offset.y);<br>
> > +      params.x0 += params.wm_inputs.dst_offset.x;<br>
> > +      params.y0 += params.wm_inputs.dst_offset.y;<br>
> > +      params.x1 += params.wm_inputs.dst_offset.x;<br>
> > +      params.y1 += params.wm_inputs.dst_offset.y;<br>
> > +   }<br>
> > +<br>
> >     brw_blorp_get_blit_kernel(batch->blorp, &params, &wm_prog_key);<br>
> ><br>
> >     params.src.view.swizzle = src_swizzle;<br>
> > diff --git a/src/intel/blorp/blorp_genX_exec.h b/src/intel/blorp/blorp_genX_exec.h<br>
> > index d049eb0..1129929 100644<br>
> > --- a/src/intel/blorp/blorp_genX_exec.h<br>
> > +++ b/src/intel/blorp/blorp_genX_exec.h<br>
> > @@ -908,9 +908,7 @@ blorp_emit_surface_state(struct blorp_batch *batch,<br>
> >     isl_surf_fill_state(batch->blorp->isl_dev, state,<br>
> >                         .surf = &surf, .view = &surface->view,<br>
> >                         .aux_surf = &surface->aux_surf, .aux_usage = aux_usage,<br>
> > -                       .mocs = mocs, .clear_color = surface->clear_color,<br>
> > -                       .x_offset_sa = surface->tile_x_sa,<br>
> > -                       .y_offset_sa = surface->tile_y_sa);<br>
> > +                       .mocs = mocs, .clear_color = surface->clear_color);<br>
> ><br>
> >     blorp_surface_reloc(batch, state_offset + ss_info.reloc_dw * 4,<br>
> >                         surface->addr, 0);<br>
> > diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h<br>
> > index 33f197b..46ff272 100644<br>
> > --- a/src/intel/blorp/blorp_priv.h<br>
> > +++ b/src/intel/blorp/blorp_priv.h<br>
> > @@ -112,19 +112,27 @@ struct brw_blorp_rect_grid<br>
> >     float pad[2];<br>
> >  };<br>
> ><br>
> > +struct blorp_surf_offset {<br>
> > +   uint32_t x;<br>
> > +   uint32_t y;<br>
> > +};<br>
> > +<br>
> >  struct brw_blorp_wm_inputs<br>
> >  {<br>
> >     struct brw_blorp_discard_rect discard_rect;<br>
> >     struct brw_blorp_rect_grid rect_grid;<br>
> >     struct brw_blorp_coord_transform coord_transform[2];<br>
> ><br>
> > +   struct blorp_surf_offset src_offset;<br>
> > +   struct blorp_surf_offset dst_offset;<br>
> > +<br>
> >     /* Minimum layer setting works for all the textures types but texture_3d<br>
> >      * for which the setting has no effect. Use the z-coordinate instead.<br>
> >      */<br>
> >     uint32_t src_z;<br>
> ><br>
> >     /* Pad out to an integral number of registers */<br>
> > -   uint32_t pad[3];<br>
> > +   uint32_t pad[1];<br>
> >  };<br>
> ><br>
> >  struct brw_blorp_prog_data<br>
> > @@ -258,6 +266,16 @@ struct brw_blorp_blit_prog_key<br>
> >     /* True for scaled blitting. */<br>
> >     bool blit_scaled;<br>
> ><br>
> > +   /* True if this blit operation may involve intratile offsets on the source.<br>
> > +    * In this case, we need to add the offset before texturing.<br>
> > +    */<br>
> > +   bool need_src_offset;<br>
> > +<br>
> > +   /* True if this blit operation may involve intratile offsets on the<br>
> > +    * destination.  In this case, we need to add the offset to gl_FragCoord.<br>
> > +    */<br>
> > +   bool need_dst_offset;<br>
> > +<br>
> >     /* Scale factors between the pixel grid and the grid of samples. We're<br>
> >      * using grid of samples for bilinear filetring in multisample scaled blits.<br>
> >      */<br>
> > --<br>
> > 2.5.0.400.gff86faf<br>
> ><br>
> > _______________________________________________<br>
> > mesa-dev mailing list<br>
> > <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> > <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br></p>