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