isl: Rework the get_intratile_offset function
The old function tried to work in elements which isn't, strictly speaking, a valid thing to do. In the case of a non-power-of-two format, there is no guarantee that the x offset into the tile is a multiple of the format block size. This commit refactors it to work entirely in terms of a tiling (not a surface) and bytes/rows. Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
This commit is contained in:
@@ -1417,33 +1417,39 @@ isl_surf_get_image_offset_el(const struct isl_surf *surf,
|
||||
}
|
||||
|
||||
void
|
||||
isl_surf_get_image_intratile_offset_el_xy(const struct isl_device *dev,
|
||||
const struct isl_surf *surf,
|
||||
uint32_t total_x_offset_el,
|
||||
uint32_t total_y_offset_el,
|
||||
uint32_t *base_address_offset,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el)
|
||||
isl_tiling_get_intratile_offset_el(const struct isl_device *dev,
|
||||
enum isl_tiling tiling,
|
||||
uint8_t bs,
|
||||
uint32_t row_pitch,
|
||||
uint32_t total_x_offset_el,
|
||||
uint32_t total_y_offset_el,
|
||||
uint32_t *base_address_offset,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el)
|
||||
{
|
||||
const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format);
|
||||
|
||||
struct isl_tile_info tile_info;
|
||||
isl_surf_get_tile_info(dev, surf, &tile_info);
|
||||
isl_tiling_get_info(dev, tiling, bs, &tile_info);
|
||||
|
||||
/* This function only really works for power-of-two surfaces. In
|
||||
* theory, we could make it work for non-power-of-two surfaces by going
|
||||
* to the left until we find a block that is bs-aligned. The Vulkan
|
||||
* driver doesn't use non-power-of-two tiled surfaces so we'll leave
|
||||
* this unimplemented for now.
|
||||
*/
|
||||
assert(tiling == ISL_TILING_LINEAR || isl_is_pow2(bs));
|
||||
|
||||
uint32_t small_y_offset_el = total_y_offset_el % tile_info.height;
|
||||
uint32_t big_y_offset_el = total_y_offset_el - small_y_offset_el;
|
||||
uint32_t big_y_offset_B = big_y_offset_el * surf->row_pitch;
|
||||
uint32_t big_y_offset_B = big_y_offset_el * row_pitch;
|
||||
|
||||
uint32_t total_x_offset_B = total_x_offset_el * fmtl->bs;
|
||||
uint32_t total_x_offset_B = total_x_offset_el * bs;
|
||||
uint32_t small_x_offset_B = total_x_offset_B % tile_info.width;
|
||||
uint32_t small_x_offset_el = small_x_offset_B / fmtl->bs;
|
||||
uint32_t small_x_offset_el = small_x_offset_B / bs;
|
||||
uint32_t big_x_offset_B = (total_x_offset_B / tile_info.width) * tile_info.size;
|
||||
|
||||
*base_address_offset = big_y_offset_B + big_x_offset_B;
|
||||
*x_offset_el = small_x_offset_el;
|
||||
*y_offset_el = small_y_offset_el;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1456,6 +1462,8 @@ isl_surf_get_image_intratile_offset_el(const struct isl_device *dev,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el)
|
||||
{
|
||||
const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format);
|
||||
|
||||
uint32_t total_x_offset_el;
|
||||
uint32_t total_y_offset_el;
|
||||
isl_surf_get_image_offset_el(surf, level,
|
||||
@@ -1464,12 +1472,14 @@ isl_surf_get_image_intratile_offset_el(const struct isl_device *dev,
|
||||
&total_x_offset_el,
|
||||
&total_y_offset_el);
|
||||
|
||||
isl_surf_get_image_intratile_offset_el_xy(dev, surf,
|
||||
total_x_offset_el,
|
||||
total_y_offset_el,
|
||||
base_address_offset,
|
||||
x_offset_el,
|
||||
y_offset_el);
|
||||
|
||||
isl_tiling_get_intratile_offset_el(dev, surf->tiling, fmtl->bs,
|
||||
surf->row_pitch,
|
||||
total_x_offset_el,
|
||||
total_y_offset_el,
|
||||
base_address_offset,
|
||||
x_offset_el,
|
||||
y_offset_el);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@@ -1142,6 +1142,27 @@ isl_surf_get_image_offset_el(const struct isl_surf *surf,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el);
|
||||
|
||||
/**
|
||||
* @brief Calculate the intratile offsets to a surface.
|
||||
*
|
||||
* In @a base_address_offset return the offset from the base of the surface to
|
||||
* the base address of the first tile of the subimage. In @a x_offset_B and
|
||||
* @a y_offset_rows, return the offset, in units of bytes and rows, from the
|
||||
* tile's base to the subimage's first surface element. The x and y offsets
|
||||
* are intratile offsets; that is, they do not exceed the boundary of the
|
||||
* surface's tiling format.
|
||||
*/
|
||||
void
|
||||
isl_tiling_get_intratile_offset_el(const struct isl_device *dev,
|
||||
enum isl_tiling tiling,
|
||||
uint8_t bs,
|
||||
uint32_t row_pitch,
|
||||
uint32_t total_x_offset_B,
|
||||
uint32_t total_y_offset_rows,
|
||||
uint32_t *base_address_offset,
|
||||
uint32_t *x_offset_B,
|
||||
uint32_t *y_offset_rows);
|
||||
|
||||
/**
|
||||
* @brief Calculate the intratile offsets to a subimage in the surface.
|
||||
*
|
||||
@@ -1162,18 +1183,6 @@ isl_surf_get_image_intratile_offset_el(const struct isl_device *dev,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el);
|
||||
|
||||
/**
|
||||
* See above.
|
||||
*/
|
||||
void
|
||||
isl_surf_get_image_intratile_offset_el_xy(const struct isl_device *dev,
|
||||
const struct isl_surf *surf,
|
||||
uint32_t total_x_offset_el,
|
||||
uint32_t total_y_offset_el,
|
||||
uint32_t *base_address_offset,
|
||||
uint32_t *x_offset_el,
|
||||
uint32_t *y_offset_el);
|
||||
|
||||
/**
|
||||
* @brief Get value of 3DSTATE_DEPTH_BUFFER.SurfaceFormat
|
||||
*
|
||||
|
@@ -145,12 +145,15 @@ create_iview(struct anv_cmd_buffer *cmd_buffer,
|
||||
/* Create a VkImageView that starts at the tile aligned offset closest
|
||||
* to the provided x/y offset into the surface.
|
||||
*/
|
||||
struct isl_surf *isl_surf = &anv_image_from_handle(*img)->color_surface.isl;
|
||||
|
||||
uint32_t img_o = 0;
|
||||
isl_surf_get_image_intratile_offset_el_xy(&cmd_buffer->device->isl_dev,
|
||||
&anv_image_from_handle(*img)->
|
||||
color_surface.isl,
|
||||
*rect_x, *rect_y,
|
||||
&img_o, rect_x, rect_y);
|
||||
isl_tiling_get_intratile_offset_el(&cmd_buffer->device->isl_dev,
|
||||
isl_surf->tiling, surf->bs,
|
||||
isl_surf->row_pitch,
|
||||
*rect_x * surf->bs, *rect_y,
|
||||
&img_o, rect_x, rect_y);
|
||||
|
||||
anv_image_view_init(iview, cmd_buffer->device,
|
||||
&(VkImageViewCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
|
Reference in New Issue
Block a user