Image offset is really a triple: aligned byte offset, intra-tile x and intra-tile y. Taking intra-tile offsets into account in the caller side of emit_miptree_blit() and then applying tile-aligned byte offset in emit_miptree_blit() is confusing. Now both are handled in single location: get_blit_intratile_offset_el().
Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- src/mesa/drivers/dri/i965/intel_blit.c | 106 ++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index e7338bdf46..d308cfb416 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -42,6 +42,7 @@ static void intel_miptree_set_alpha_to_one(struct brw_context *brw, struct intel_mipmap_tree *mt, + unsigned level, unsigned layer, int x, int y, int width, int height); static GLuint translate_raster_op(GLenum logicop) @@ -164,15 +165,68 @@ intel_miptree_blit_compatible_formats(mesa_format src, mesa_format dst) static void get_blit_intratile_offset_el(const struct brw_context *brw, - struct intel_mipmap_tree *mt, + const struct intel_mipmap_tree *mt, + unsigned level, unsigned layer, uint32_t total_x_offset_el, uint32_t total_y_offset_el, struct isl_image_offset *image_offset) { + struct isl_image_offset base_offset; + intel_miptree_get_tile_offsets(mt, level, layer, &base_offset); + + /* Given offsets are relative to the start of the slice and we need the + * offset that is relative to the beginning of the buffer. + * + * Image offset is really a triple: aligned byte offset, intra-tile + * x and intra-tile y. In order to simply add the page aligned offset of + * the start of the image and the page aligned offset of the given position + * (total_x_offset_el, total_y_offset_el) within the image, we need to + * first augment the position within the image with the intra-tile start + * position (x,y) of the image itself. Otherwise we might get intra-tile + * offsets that don't actually fit into one page: + * + * +-------------------------------------+ page N + * / \ | | + * d_1 | | | + * \ / | | + * + + start of the image + * | | + * | | + * +-------------------------------------+ page N + 1 + * | | + * . . + * . . + * +-------------------------------------+ page N + M + * / \ | | + * d_2 | | | + * \ / | | + * + + (total_x_offset_el, + * | | total_y_offset_el) + * | | + * +-------------------------------------+ page N + M + 1 + * + * Consider a case where d_1 + d_2 > sizeof(page). If one calculates the + * triple separately for the start of the image and for the position + * within the image, one gets page aligned of N + M and d_1 + d_2. If in + * turn one takes d_1 into account as offsetting the position _within_ the + * image, one gets page aligned of N + M + 1 and d_1 + d_2 - sizeof(page) + * where 0 <= d_1 + d_2 - sizeof(page) < sizeof(page). + */ + total_x_offset_el += base_offset.intra_tile_x; + total_y_offset_el += base_offset.intra_tile_y; + isl_tiling_get_intratile_offset_el(mt->surf.tiling, mt->cpp * 8, mt->surf.row_pitch, total_x_offset_el, total_y_offset_el, image_offset); + + /* Finally add the byte offset of the page aligned start of the image to + * the page aligned offset with the image giving page aligned offset + * relative to the beginning of the buffer. + */ + image_offset->tile_aligned_byte_offset += + base_offset.tile_aligned_byte_offset; + if (mt->surf.tiling == ISL_TILING_LINEAR) { /* From the Broadwell PRM docs for XY_SRC_COPY_BLT::SourceBaseAddress: * @@ -197,8 +251,10 @@ get_blit_intratile_offset_el(const struct brw_context *brw, static bool emit_miptree_blit(struct brw_context *brw, struct intel_mipmap_tree *src_mt, + unsigned src_level, unsigned src_layer, uint32_t src_x, uint32_t src_y, struct intel_mipmap_tree *dst_mt, + unsigned dst_level, unsigned dst_layer, uint32_t dst_x, uint32_t dst_y, uint32_t width, uint32_t height, bool reverse, GLenum logicop) @@ -237,12 +293,12 @@ emit_miptree_blit(struct brw_context *brw, const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y); struct isl_image_offset src_offset; - get_blit_intratile_offset_el(brw, src_mt, + get_blit_intratile_offset_el(brw, src_mt, src_level, src_layer, src_x + chunk_x, src_y + chunk_y, &src_offset); struct isl_image_offset dst_offset; - get_blit_intratile_offset_el(brw, dst_mt, + get_blit_intratile_offset_el(brw, dst_mt, dst_level, dst_layer, dst_x + chunk_x, dst_y + chunk_y, &dst_offset); @@ -251,13 +307,11 @@ emit_miptree_blit(struct brw_context *brw, reverse ? -src_mt->surf.row_pitch : src_mt->surf.row_pitch, src_mt->bo, - src_mt->offset + - src_offset.tile_aligned_byte_offset, + src_offset.tile_aligned_byte_offset, src_mt->surf.tiling, dst_mt->surf.row_pitch, dst_mt->bo, - dst_mt->offset + - dst_offset.tile_aligned_byte_offset, + dst_offset.tile_aligned_byte_offset, dst_mt->surf.tiling, src_offset.intra_tile_x, src_offset.intra_tile_y, @@ -341,18 +395,11 @@ intel_miptree_blit(struct brw_context *brw, dst_y = minify(h0, dst_level - dst_mt->first_level) - dst_y - height; } - uint32_t src_image_x, src_image_y, dst_image_x, dst_image_y; - intel_miptree_get_image_offset(src_mt, src_level, src_slice, - &src_image_x, &src_image_y); - intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice, - &dst_image_x, &dst_image_y); - src_x += src_image_x; - src_y += src_image_y; - dst_x += dst_image_x; - dst_y += dst_image_y; - - if (!emit_miptree_blit(brw, src_mt, src_x, src_y, - dst_mt, dst_x, dst_y, width, height, + if (!emit_miptree_blit(brw, src_mt, src_level, src_slice, + src_x, src_y, + dst_mt, dst_level, dst_slice, + dst_x, dst_y, + width, height, src_flip != dst_flip, logicop)) { return false; } @@ -360,7 +407,7 @@ intel_miptree_blit(struct brw_context *brw, /* XXX This could be done in a single pass using XY_FULL_MONO_PATTERN_BLT */ if (_mesa_get_format_bits(src_format, GL_ALPHA_BITS) == 0 && _mesa_get_format_bits(dst_format, GL_ALPHA_BITS) > 0) { - intel_miptree_set_alpha_to_one(brw, dst_mt, + intel_miptree_set_alpha_to_one(brw, dst_mt, dst_level, dst_slice, dst_x, dst_y, width, height); } @@ -391,10 +438,6 @@ intel_miptree_copy(struct brw_context *brw, intel_miptree_access_raw(brw, src_mt, src_level, src_slice, false); intel_miptree_access_raw(brw, dst_mt, dst_level, dst_slice, true); - uint32_t src_image_x, src_image_y; - intel_miptree_get_image_offset(src_mt, src_level, src_slice, - &src_image_x, &src_image_y); - if (_mesa_is_format_compressed(src_mt->format)) { GLuint bw, bh; _mesa_get_format_block_size(src_mt->format, &bw, &bh); @@ -420,12 +463,6 @@ intel_miptree_copy(struct brw_context *brw, src_width = DIV_ROUND_UP(src_width, (int)bw); src_height = DIV_ROUND_UP(src_height, (int)bh); } - src_x += src_image_x; - src_y += src_image_y; - - uint32_t dst_image_x, dst_image_y; - intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice, - &dst_image_x, &dst_image_y); if (_mesa_is_format_compressed(dst_mt->format)) { GLuint bw, bh; @@ -437,11 +474,9 @@ intel_miptree_copy(struct brw_context *brw, dst_x /= (int)bw; dst_y /= (int)bh; } - dst_x += dst_image_x; - dst_y += dst_image_y; - return emit_miptree_blit(brw, src_mt, src_x, src_y, - dst_mt, dst_x, dst_y, + return emit_miptree_blit(brw, src_mt, src_level, src_slice, src_x, src_y, + dst_mt, dst_level, dst_slice, dst_x, dst_y, src_width, src_height, false, GL_COPY); } @@ -778,6 +813,7 @@ intel_emit_linear_blit(struct brw_context *brw, static void intel_miptree_set_alpha_to_one(struct brw_context *brw, struct intel_mipmap_tree *mt, + unsigned level, unsigned layer, int x, int y, int width, int height) { uint32_t BR13, CMD; @@ -820,7 +856,7 @@ intel_miptree_set_alpha_to_one(struct brw_context *brw, const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y); struct isl_image_offset image_offset; - get_blit_intratile_offset_el(brw, mt, + get_blit_intratile_offset_el(brw, mt, level, layer, x + chunk_x, y + chunk_y, &image_offset); -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev