diff options
-rw-r--r-- | src/intel/blorp/blorp_blit.c | 74 | ||||
-rw-r--r-- | src/intel/blorp/blorp_genX_exec.h | 4 | ||||
-rw-r--r-- | src/intel/blorp/blorp_priv.h | 20 |
3 files changed, 89 insertions, 9 deletions
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index fdcd29d68c7..dba49b9c207 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,17 @@ 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 + * + * Transformation parameters giving translation from destination to source + * coordinates don't take into account possible intra-tile destination + * offset. Therefore it has to be first subtracted from the incoming + * coordinates. Vertices are set up based on coordinates containing the + * intra-tile offset. + */ + if (key->need_dst_offset) + coord = nir_isub(b, coord, nir_load_var(b, v->v_dst_offset)); + 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 +1177,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 +1267,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) @@ -1280,6 +1317,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. */ @@ -1287,10 +1332,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; @@ -1492,6 +1535,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) { @@ -1552,6 +1596,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 @@ -1576,6 +1621,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 @@ -1599,6 +1645,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; + } + /* For some texture types, we need to pass the layer through the sampler. */ params.wm_inputs.src_z = params.src.z_offset; diff --git a/src/intel/blorp/blorp_genX_exec.h b/src/intel/blorp/blorp_genX_exec.h index 65a981d4ce2..8f26925e6cb 100644 --- a/src/intel/blorp/blorp_genX_exec.h +++ b/src/intel/blorp/blorp_genX_exec.h @@ -926,9 +926,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 33f197b523d..46ff272630a 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. */ |