Mesa (master): turnip: image_view rework

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 16 14:19:39 UTC 2020


Module: Mesa
Branch: master
Commit: 24378086710bae7eb7b6d0cb4ec0e718d36ba32c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=24378086710bae7eb7b6d0cb4ec0e718d36ba32c

Author: Jonathan Marek <jonathan at marek.ca>
Date:   Tue Apr  7 21:12:45 2020 -0400

turnip: image_view rework

Instead of exposing various layout functions, move image-related logic
into tu_image.c and have the image_view pre-fill relevant register values.

This changes the clear/blit code to use image_view.

This will make it much easier to deal with aspect masks, in particular for
planar formats and D32_S8.

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4581>

---

 src/freedreno/vulkan/tu_clear_blit.c | 339 +++++++++++++++--------------------
 src/freedreno/vulkan/tu_cmd_buffer.c |  50 ++----
 src/freedreno/vulkan/tu_image.c      | 177 ++++++++++++------
 src/freedreno/vulkan/tu_private.h    | 135 ++++----------
 4 files changed, 322 insertions(+), 379 deletions(-)

diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c
index 35469bf363b..c07e7e0bd0e 100644
--- a/src/freedreno/vulkan/tu_clear_blit.c
+++ b/src/freedreno/vulkan/tu_clear_blit.c
@@ -344,46 +344,18 @@ r2d_clear_value(struct tu_cs *cs, VkFormat format, const VkClearValue *val)
 static void
 r2d_src(struct tu_cmd_buffer *cmd,
         struct tu_cs *cs,
-        struct tu_image *image,
-        VkFormat vk_format,
-        uint32_t level,
+        const struct tu_image_view *iview,
         uint32_t layer,
-        bool linear_filter,
-        bool stencil_read)
+        bool linear_filter)
 {
-   struct tu_native_format format = tu6_format_image_src(image, vk_format, level);
+   tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 5);
+   tu_cs_emit(cs, iview->SP_PS_2D_SRC_INFO |
+                  COND(linear_filter, A6XX_SP_PS_2D_SRC_INFO_FILTER));
+   tu_cs_emit(cs, iview->SP_PS_2D_SRC_SIZE);
+   tu_cs_image_ref_2d(cs, iview, layer, true);
 
-   /* stencil readout path fails with UBWC enabled (why?) */
-   assert(!stencil_read || !image->layout.ubwc_layer_size);
-
-   if (stencil_read)
-      format.swap = XYZW;
-
-   tu_cs_emit_regs(cs,
-                   A6XX_SP_PS_2D_SRC_INFO(
-                     .color_format = format.fmt,
-                     .tile_mode = format.tile_mode,
-                     .color_swap = format.swap,
-                     .flags = image->layout.ubwc_layer_size != 0,
-                     .srgb = vk_format_is_srgb(vk_format),
-                     .samples = tu_msaa_samples(image->samples),
-                     .filter = linear_filter,
-                     .samples_average = image->samples > 1 &&
-                                        !vk_format_is_int(vk_format) &&
-                                        !vk_format_is_depth_or_stencil(vk_format),
-                     .unk20 = 1,
-                     .unk22 = 1),
-                   A6XX_SP_PS_2D_SRC_SIZE(
-                     .width = tu_minify(image->extent.width, level),
-                     .height = tu_minify(image->extent.height, level)),
-                   A6XX_SP_PS_2D_SRC(tu_image_base_ref(image, level, layer)),
-                   A6XX_SP_PS_2D_SRC_PITCH(.pitch = tu_image_pitch(image, level)));
-
-   if (image->layout.ubwc_layer_size) {
-      tu_cs_emit_regs(cs,
-                      A6XX_SP_PS_2D_SRC_FLAGS(tu_image_ubwc_base_ref(image, level, layer)),
-                      A6XX_SP_PS_2D_SRC_FLAGS_PITCH(.pitch = tu_image_ubwc_pitch(image, level)));
-   }
+   tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 3);
+   tu_cs_image_flag_ref(cs, iview, layer);
 }
 
 static void
@@ -409,31 +381,16 @@ r2d_src_buffer(struct tu_cmd_buffer *cmd,
 }
 
 static void
-r2d_dst(struct tu_cs *cs,
-        struct tu_image *image,
-        VkFormat vk_format,
-        uint32_t level,
-        uint32_t layer)
+r2d_dst(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
 {
-   struct tu_native_format format = tu6_format_image(image, vk_format, level);
+   assert(iview->image->samples == 1);
 
-   assert(image->samples == 1);
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_INFO, 4);
+   tu_cs_emit(cs, iview->RB_2D_DST_INFO);
+   tu_cs_image_ref_2d(cs, iview, layer, false);
 
-   tu_cs_emit_regs(cs,
-                   A6XX_RB_2D_DST_INFO(
-                      .color_format = format.fmt,
-                      .tile_mode = format.tile_mode,
-                      .color_swap = format.swap,
-                      .flags = image->layout.ubwc_layer_size != 0,
-                      .srgb = vk_format_is_srgb(image->vk_format)),
-                   A6XX_RB_2D_DST(tu_image_base_ref(image, level, layer)),
-                   A6XX_RB_2D_DST_SIZE(.pitch = tu_image_pitch(image, level)));
-
-   if (image->layout.ubwc_layer_size) {
-      tu_cs_emit_regs(cs,
-                      A6XX_RB_2D_DST_FLAGS(tu_image_ubwc_base_ref(image, level, layer)),
-                      A6XX_RB_2D_DST_FLAGS_PITCH(.pitch = tu_image_ubwc_pitch(image, level)));
-   }
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_FLAGS_LO, 3);
+   tu_cs_image_flag_ref(cs, iview, layer);
 }
 
 static void
@@ -806,7 +763,12 @@ r3d_clear_value(struct tu_cs *cs, VkFormat format, const VkClearValue *val)
 }
 
 static void
-r3d_src_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t *tex_const, bool linear_filter)
+r3d_src_common(struct tu_cmd_buffer *cmd,
+               struct tu_cs *cs,
+               const uint32_t *tex_const,
+               uint32_t offset_base,
+               uint32_t offset_ubwc,
+               bool linear_filter)
 {
    struct ts_cs_memory texture = { };
    VkResult result = tu_cs_alloc(&cmd->sub_cs,
@@ -816,6 +778,12 @@ r3d_src_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t *tex_const,
 
    memcpy(texture.map, tex_const, A6XX_TEX_CONST_DWORDS * 4);
 
+   /* patch addresses for layer offset */
+   *(uint64_t*) (texture.map + 4) += offset_base;
+   uint64_t ubwc_addr = (texture.map[7] | (uint64_t) texture.map[8] << 32) + offset_ubwc;
+   texture.map[7] = ubwc_addr;
+   texture.map[8] = ubwc_addr >> 32;
+
    texture.map[A6XX_TEX_CONST_DWORDS + 0] =
       A6XX_TEX_SAMP_0_XY_MAG(linear_filter ? A6XX_TEX_LINEAR : A6XX_TEX_NEAREST) |
       A6XX_TEX_SAMP_0_XY_MIN(linear_filter ? A6XX_TEX_LINEAR : A6XX_TEX_NEAREST) |
@@ -858,31 +826,14 @@ r3d_src_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t *tex_const,
 static void
 r3d_src(struct tu_cmd_buffer *cmd,
         struct tu_cs *cs,
-        struct tu_image *image,
-        VkFormat format,
-        uint32_t level,
+        const struct tu_image_view *iview,
         uint32_t layer,
-        bool linear_filter,
-        bool stencil_read)
+        bool linear_filter)
 {
-   struct tu_image_view view;
-
-   /* use tu_image_view_init to fill out a view descriptor */
-   tu_image_view_init(&view, cmd->device, &(VkImageViewCreateInfo) {
-      .image = tu_image_to_handle(image),
-      .viewType = VK_IMAGE_VIEW_TYPE_2D,
-      .format = format,
-      /* image_to_buffer from d24s8 with stencil aspect mask writes out to r8 */
-      .components.r = stencil_read ? VK_COMPONENT_SWIZZLE_A : VK_COMPONENT_SWIZZLE_R,
-      .subresourceRange = {
-         .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-         .baseMipLevel = level,
-         .levelCount = 1,
-         .baseArrayLayer = layer,
-         .layerCount = 1,
-      },
-   });
-   r3d_src_common(cmd, cs, view.descriptor, linear_filter);
+   r3d_src_common(cmd, cs, iview->descriptor,
+                  iview->layer_size * layer,
+                  iview->ubwc_layer_size * layer,
+                  linear_filter);
 }
 
 static void
@@ -916,35 +867,23 @@ r3d_src_buffer(struct tu_cmd_buffer *cmd,
    for (uint32_t i = 6; i < A6XX_TEX_CONST_DWORDS; i++)
       desc[i] = 0;
 
-   r3d_src_common(cmd, cs, desc, false);
+   r3d_src_common(cmd, cs, desc, 0, 0, false);
 }
 
 static void
-r3d_dst(struct tu_cs *cs,
-        struct tu_image *image,
-        VkFormat vk_format,
-        uint32_t level,
-        uint32_t layer)
+r3d_dst(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
 {
-   tu6_emit_msaa(cs, image->samples); /* TODO: move to setup */
+   tu6_emit_msaa(cs, iview->image->samples); /* TODO: move to setup */
 
-   struct tu_native_format format = tu6_format_image(image, vk_format, level);
-
-   tu_cs_emit_regs(cs,
-                   A6XX_RB_MRT_BUF_INFO(0,
-                     .color_tile_mode = format.tile_mode,
-                     .color_format = format.fmt,
-                     .color_swap = format.swap),
-                   A6XX_RB_MRT_PITCH(0, tu_image_pitch(image, level)),
-                   A6XX_RB_MRT_ARRAY_PITCH(0, image->layout.layer_size),
-                   A6XX_RB_MRT_BASE(0, tu_image_base_ref(image, level, layer)),
-                   A6XX_RB_MRT_BASE_GMEM(0, 0));
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(0), 6);
+   tu_cs_emit(cs, iview->RB_MRT_BUF_INFO);
+   tu_cs_image_ref(cs, iview, layer);
+   tu_cs_emit(cs, 0);
 
-   tu_cs_emit_regs(cs,
-                   A6XX_RB_MRT_FLAG_BUFFER_ADDR(0, tu_image_ubwc_base_ref(image, level, layer)),
-                   A6XX_RB_MRT_FLAG_BUFFER_PITCH(0, .pitch = tu_image_ubwc_pitch(image, level)));
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER(0), 3);
+   tu_cs_image_flag_ref(cs, iview, layer);
 
-   tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL(.flag_mrts = image->layout.ubwc_layer_size != 0));
+   tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL(.flag_mrts = iview->ubwc_enabled));
 }
 
 static void
@@ -1060,21 +999,14 @@ struct blit_ops {
    void (*src)(
         struct tu_cmd_buffer *cmd,
         struct tu_cs *cs,
-        struct tu_image *image,
-        VkFormat format,
-        uint32_t level,
+        const struct tu_image_view *iview,
         uint32_t layer,
-        bool linear_filter,
-        bool stencil_read);
+        bool linear_filter);
    void (*src_buffer)(struct tu_cmd_buffer *cmd, struct tu_cs *cs,
                       VkFormat vk_format,
                       uint64_t va, uint32_t pitch,
                       uint32_t width, uint32_t height);
-   void (*dst)(struct tu_cs *cs,
-               struct tu_image *image,
-               VkFormat format,
-               uint32_t level,
-               uint32_t layer);
+   void (*dst)(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer);
    void (*dst_buffer)(struct tu_cs *cs, VkFormat vk_format, uint64_t va, uint32_t pitch);
    void (*setup)(struct tu_cmd_buffer *cmd,
                  struct tu_cs *cs,
@@ -1118,6 +1050,47 @@ coords(const struct blit_ops *ops,
    ops->coords(cs, (const VkOffset2D*) dst, (const VkOffset2D*) src, (const VkExtent2D*) extent);
 }
 
+static void
+tu_image_view_blit2(struct tu_image_view *iview,
+                    struct tu_image *image,
+                    VkFormat format,
+                    const VkImageSubresourceLayers *subres,
+                    uint32_t layer,
+                    bool stencil_read)
+{
+   VkImageAspectFlags aspect_mask = subres->aspectMask;
+
+   /* always use the AS_R8G8B8A8 format for these */
+   if (format == VK_FORMAT_D24_UNORM_S8_UINT ||
+       format == VK_FORMAT_X8_D24_UNORM_PACK32) {
+      aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
+   }
+
+   tu_image_view_init(iview, &(VkImageViewCreateInfo) {
+      .image = tu_image_to_handle(image),
+      .viewType = VK_IMAGE_VIEW_TYPE_2D,
+      .format = format,
+      /* image_to_buffer from d24s8 with stencil aspect mask writes out to r8 */
+      .components.r = stencil_read ? VK_COMPONENT_SWIZZLE_A : VK_COMPONENT_SWIZZLE_R,
+      .subresourceRange = {
+         .aspectMask = aspect_mask,
+         .baseMipLevel = subres->mipLevel,
+         .levelCount = 1,
+         .baseArrayLayer = subres->baseArrayLayer + layer,
+         .layerCount = 1,
+      },
+   });
+}
+
+static void
+tu_image_view_blit(struct tu_image_view *iview,
+                   struct tu_image *image,
+                   const VkImageSubresourceLayers *subres,
+                   uint32_t layer)
+{
+   tu_image_view_blit2(iview, image, image->vk_format, subres, layer, false);
+}
+
 static void
 tu6_blit_image(struct tu_cmd_buffer *cmd,
                struct tu_image *src_image,
@@ -1197,14 +1170,13 @@ tu6_blit_image(struct tu_cmd_buffer *cmd,
          A6XX_GRAS_2D_SRC_BR_Y(.y = MAX2(info->srcOffsets[0].y, info->srcOffsets[1].y) - 1));
    }
 
+   struct tu_image_view dst, src;
+   tu_image_view_blit(&dst, dst_image, &info->dstSubresource, info->dstOffsets[0].z);
+   tu_image_view_blit(&src, src_image, &info->srcSubresource, info->srcOffsets[0].z);
+
    for (uint32_t i = 0; i < layers; i++) {
-      ops->src(cmd, cs, src_image, src_image->vk_format,
-               info->srcSubresource.mipLevel,
-               info->srcSubresource.baseArrayLayer + info->srcOffsets[0].z + i,
-               filter == VK_FILTER_LINEAR, false);
-      ops->dst(cs, dst_image, dst_image->vk_format,
-               info->dstSubresource.mipLevel,
-               info->dstSubresource.baseArrayLayer + info->dstOffsets[0].z + i);
+      ops->dst(cs, &dst, i);
+      ops->src(cmd, cs, &src, i, filter == VK_FILTER_LINEAR);
       ops->run(cmd, cs);
    }
 }
@@ -1283,6 +1255,7 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd,
    VkFormat dst_format = dst_image->vk_format;
    VkFormat src_format = dst_image->vk_format;
    const struct blit_ops *ops = &r2d_ops;
+
    uint8_t mask = 0xf;
 
    if (dst_image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
@@ -1304,7 +1277,7 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd,
       (info->bufferRowLength ?: extent.width) * vk_format_get_blocksize(src_format);
    uint32_t layer_size = (info->bufferImageHeight ?: extent.height) * pitch;
 
-   if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(dst_format)) {
+   if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(src_format)) {
       assert(src_format == dst_format);
       copy_compressed(dst_format, &offset, &extent, &pitch, &layer_size);
       src_format = dst_format = copy_format(dst_format);
@@ -1316,10 +1289,11 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd,
 
    ops->setup(cmd, cs, dst_format, ROTATE_0, false, mask);
 
+   struct tu_image_view dst;
+   tu_image_view_blit2(&dst, dst_image, dst_format, &info->imageSubresource, offset.z, false);
+
    for (uint32_t i = 0; i < layers; i++) {
-      ops->dst(cs, dst_image, dst_format,
-               info->imageSubresource.mipLevel,
-               info->imageSubresource.baseArrayLayer + info->imageOffset.z + i);
+      ops->dst(cs, &dst, i);
 
       uint64_t src_va = tu_buffer_iova(src_buffer) + info->bufferOffset + layer_size * i;
       if ((src_va & 63) || (pitch & 63)) {
@@ -1383,7 +1357,7 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd,
    uint32_t pitch = (info->bufferRowLength ?: extent.width) * vk_format_get_blocksize(dst_format);
    uint32_t layer_size = (info->bufferImageHeight ?: extent.height) * pitch;
 
-   if (src_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(src_format)) {
+   if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(dst_format)) {
       assert(src_format == dst_format);
       copy_compressed(dst_format, &offset, &extent, &pitch, &layer_size);
       src_format = dst_format = copy_format(dst_format);
@@ -1395,11 +1369,11 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd,
 
    ops->setup(cmd, cs, dst_format, ROTATE_0, false, 0xf);
 
+   struct tu_image_view src;
+   tu_image_view_blit2(&src, src_image, src_format, &info->imageSubresource, offset.z, stencil_read);
+
    for (uint32_t i = 0; i < layers; i++) {
-      ops->src(cmd, cs, src_image, src_format,
-               info->imageSubresource.mipLevel,
-               info->imageSubresource.baseArrayLayer + info->imageOffset.z + i,
-               false, stencil_read);
+      ops->src(cmd, cs, &src, i, false);
 
       uint64_t dst_va = tu_buffer_iova(dst_buffer) + info->bufferOffset + layer_size * i;
       if ((dst_va & 63) || (pitch & 63)) {
@@ -1489,14 +1463,13 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmd,
    ops->setup(cmd, cs, format, ROTATE_0, false, mask);
    coords(ops, cs, &dst_offset, &src_offset, &extent);
 
+   struct tu_image_view dst, src;
+   tu_image_view_blit2(&dst, dst_image, format, &info->dstSubresource, dst_offset.z, false);
+   tu_image_view_blit2(&src, src_image, format, &info->srcSubresource, src_offset.z, false);
+
    for (uint32_t i = 0; i < info->extent.depth; i++) {
-      ops->src(cmd, cs, src_image, format,
-               info->srcSubresource.mipLevel,
-               info->srcSubresource.baseArrayLayer + info->srcOffset.z + i,
-               false, false);
-      ops->dst(cs, dst_image, format,
-               info->dstSubresource.mipLevel,
-               info->dstSubresource.baseArrayLayer + info->dstOffset.z + i);
+      ops->src(cmd, cs, &src, i, false);
+      ops->dst(cs, &dst, i);
       ops->run(cmd, cs);
    }
 }
@@ -1661,14 +1634,13 @@ tu_CmdResolveImage(VkCommandBuffer commandBuffer,
 
       coords(ops, cs, &info->dstOffset, &info->srcOffset, &info->extent);
 
+      struct tu_image_view dst, src;
+      tu_image_view_blit(&dst, dst_image, &info->dstSubresource, info->dstOffset.z);
+      tu_image_view_blit(&src, src_image, &info->srcSubresource, info->srcOffset.z);
+
       for (uint32_t i = 0; i < layers; i++) {
-         ops->src(cmd, cs, src_image, src_image->vk_format,
-                  info->srcSubresource.mipLevel,
-                  info->srcSubresource.baseArrayLayer + info->srcOffset.z + i,
-                  false, false);
-         ops->dst(cs, dst_image, dst_image->vk_format,
-                  info->dstSubresource.mipLevel,
-                  info->dstSubresource.baseArrayLayer + info->dstOffset.z + i);
+         ops->src(cmd, cs, &src, i, false);
+         ops->dst(cs, &dst, i);
          ops->run(cmd, cs);
       }
    }
@@ -1687,19 +1659,14 @@ tu_resolve_sysmem(struct tu_cmd_buffer *cmd,
    tu_bo_list_add(&cmd->bo_list, src->image->bo, MSM_SUBMIT_BO_READ);
    tu_bo_list_add(&cmd->bo_list, dst->image->bo, MSM_SUBMIT_BO_WRITE);
 
-   assert(src->vk_format == dst->vk_format);
+   assert(src->image->vk_format == dst->image->vk_format);
 
-   ops->setup(cmd, cs, dst->vk_format, ROTATE_0, false, 0xf);
+   ops->setup(cmd, cs, dst->image->vk_format, ROTATE_0, false, 0xf);
    ops->coords(cs, &rect->offset, &rect->offset, &rect->extent);
 
    for (uint32_t i = 0; i < layers; i++) {
-      ops->src(cmd, cs, src->image, src->vk_format,
-               src->base_mip,
-               src->base_layer + i,
-               false, false);
-      ops->dst(cs, dst->image, dst->vk_format,
-               dst->base_mip,
-               dst->base_layer + i);
+      ops->src(cmd, cs, src, i, false);
+      ops->dst(cs, dst, i);
       ops->run(cmd, cs);
    }
 }
@@ -1745,8 +1712,16 @@ clear_image(struct tu_cmd_buffer *cmd,
                      u_minify(image->extent.height, range->baseMipLevel + j)
                   });
 
+      struct tu_image_view dst;
+      tu_image_view_blit2(&dst, image, format, &(VkImageSubresourceLayers) {
+         .aspectMask = range->aspectMask,
+         .mipLevel = range->baseMipLevel + j,
+         .baseArrayLayer = range->baseArrayLayer,
+         .layerCount = 1,
+      }, 0, false);
+
       for (uint32_t i = 0; i < layer_count; i++) {
-         ops->dst(cs, image, format, range->baseMipLevel + j, range->baseArrayLayer + i);
+         ops->dst(cs, &dst, i);
          ops->run(cmd, cs);
       }
    }
@@ -1828,14 +1803,13 @@ tu_clear_sysmem_attachments_2d(struct tu_cmd_buffer *cmd,
          const struct tu_image_view *iview =
             cmd->state.framebuffer->attachments[a].attachment;
 
-         ops->setup(cmd, cs, iview->vk_format, ROTATE_0, true, mask);
-         ops->clear_value(cs, iview->vk_format, &attachments[j].clearValue);
+         ops->setup(cmd, cs, iview->image->vk_format, ROTATE_0, true, mask);
+         ops->clear_value(cs, iview->image->vk_format, &attachments[j].clearValue);
 
          for (uint32_t i = 0; i < rect_count; i++) {
             ops->coords(cs, &rects[i].rect.offset, NULL, &rects[i].rect.extent);
             for (uint32_t layer = 0; layer < rects[i].layerCount; layer++) {
-               ops->dst(cs, iview->image, iview->vk_format, iview->base_mip,
-                        iview->base_layer + rects[i].baseArrayLayer + layer);
+               ops->dst(cs, iview, rects[i].baseArrayLayer + layer);
                ops->run(cmd, cs);
             }
          }
@@ -2152,7 +2126,7 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd,
    if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
       mask = 0xf;
 
-   if (iview->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) {
+   if (attachment->format == VK_FORMAT_D24_UNORM_S8_UINT) {
       mask &= 0x7;
       if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
          mask |= 0x8;
@@ -2166,12 +2140,12 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd,
    if (attachment->samples > 1)
       ops = &r3d_ops;
 
-   ops->setup(cmd, cs, iview->vk_format, ROTATE_0, true, mask);
+   ops->setup(cmd, cs, attachment->format, ROTATE_0, true, mask);
    ops->coords(cs, &info->renderArea.offset, NULL, &info->renderArea.extent);
-   ops->clear_value(cs, iview->vk_format, &info->pClearValues[a]);
+   ops->clear_value(cs, attachment->format, &info->pClearValues[a]);
 
    for (uint32_t i = 0; i < fb->layers; i++) {
-      ops->dst(cs, iview->image, iview->vk_format, iview->base_mip, iview->base_layer + i);
+      ops->dst(cs, iview, i);
       ops->run(cmd, cs);
    }
 }
@@ -2182,8 +2156,6 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd,
                          uint32_t a,
                          const VkRenderPassBeginInfo *info)
 {
-   const struct tu_framebuffer *fb = cmd->state.framebuffer;
-   const struct tu_image_view *iview = fb->attachments[a].attachment;
    const struct tu_render_pass_attachment *attachment =
       &cmd->state.pass->attachments[a];
    unsigned clear_mask = 0;
@@ -2195,7 +2167,7 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd,
    if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
       clear_mask = 0xf;
 
-   if (vk_format_has_stencil(iview->vk_format)) {
+   if (vk_format_has_stencil(attachment->format)) {
       clear_mask &= 0x7;
       if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
          clear_mask |= 0x8;
@@ -2216,9 +2188,6 @@ tu_emit_blit(struct tu_cmd_buffer *cmd,
              struct tu_render_pass_attachment *attachment,
              bool resolve)
 {
-   const struct tu_native_format format =
-      tu6_format_image(iview->image, iview->vk_format, iview->base_mip);
-
    tu_cs_emit_regs(cs,
                    A6XX_RB_MSAA_CNTL(tu_msaa_samples(attachment->samples)));
 
@@ -2226,24 +2195,14 @@ tu_emit_blit(struct tu_cmd_buffer *cmd,
       .unk0 = !resolve,
       .gmem = !resolve,
       /* "integer" bit disables msaa resolve averaging */
-      .integer = vk_format_is_int(iview->vk_format)));
+      .integer = vk_format_is_int(attachment->format)));
 
-   tu_cs_emit_regs(cs,
-                   A6XX_RB_BLIT_DST_INFO(
-                      .tile_mode = format.tile_mode,
-                      .samples = tu_msaa_samples(iview->image->samples),
-                      .color_format = format.fmt,
-                      .color_swap = format.swap,
-                      .flags = iview->image->layout.ubwc_layer_size != 0),
-                   A6XX_RB_BLIT_DST(tu_image_view_base_ref(iview)),
-                   A6XX_RB_BLIT_DST_PITCH(tu_image_stride(iview->image, iview->base_mip)),
-                   A6XX_RB_BLIT_DST_ARRAY_PITCH(iview->image->layout.layer_size));
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 4);
+   tu_cs_emit(cs, iview->RB_BLIT_DST_INFO);
+   tu_cs_image_ref_2d(cs, iview, 0, false);
 
-   if (iview->image->layout.ubwc_layer_size) {
-      tu_cs_emit_regs(cs,
-                      A6XX_RB_BLIT_FLAG_DST(tu_image_view_ubwc_base_ref(iview)),
-                      A6XX_RB_BLIT_FLAG_DST_PITCH(tu_image_view_ubwc_pitches(iview)));
-   }
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_FLAG_DST_LO, 3);
+   tu_cs_image_flag_ref(cs, iview, 0);
 
    tu_cs_emit_regs(cs,
                    A6XX_RB_BLIT_BASE_GMEM(attachment->gmem_offset));
@@ -2336,16 +2295,14 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd,
     * required y padding in the layout (except for the last level)
     */
    bool need_y2_align =
-      y2 != iview->extent.height ||
-      (tu6_get_image_tile_mode(iview->image, iview->base_mip) == TILE6_LINEAR &&
-       iview->base_mip != iview->image->level_count - 1);
+      y2 != iview->extent.height || iview->need_y2_align;
 
    bool unaligned =
       x1 % GMEM_ALIGN_W || (x2 % GMEM_ALIGN_W && x2 != iview->extent.width) ||
       y1 % GMEM_ALIGN_H || (y2 % GMEM_ALIGN_H && need_y2_align);
 
    /* use fast path when render area is aligned, except for unsupported resolve cases */
-   if (!unaligned && (a == gmem_a || blit_can_resolve(iview->vk_format))) {
+   if (!unaligned && (a == gmem_a || blit_can_resolve(dst->format))) {
       tu_emit_blit(cmd, cs, iview, src, true);
       return;
    }
@@ -2358,8 +2315,8 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd,
       return;
    }
 
-   r2d_setup_common(cmd, cs, iview->vk_format, ROTATE_0, false, 0xf, true);
-   r2d_dst(cs, iview->image, iview->vk_format, iview->base_mip, iview->base_layer);
+   r2d_setup_common(cmd, cs, dst->format, ROTATE_0, false, 0xf, true);
+   r2d_dst(cs, iview, 0);
    r2d_coords(cs, &render_area->offset, &render_area->offset, &render_area->extent);
 
    tu_cs_emit_regs(cs,
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 179abefbdd2..d89a553fd9f 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -387,22 +387,18 @@ tu6_emit_zs(struct tu_cmd_buffer *cmd,
    }
 
    const struct tu_image_view *iview = fb->attachments[a].attachment;
-   enum a6xx_depth_format fmt = tu6_pipe2depth(iview->vk_format);
+   enum a6xx_depth_format fmt = tu6_pipe2depth(cmd->state.pass->attachments[a].format);
 
-   tu_cs_emit_regs(cs,
-                   A6XX_RB_DEPTH_BUFFER_INFO(.depth_format = fmt),
-                   A6XX_RB_DEPTH_BUFFER_PITCH(tu_image_stride(iview->image, iview->base_mip)),
-                   A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(
-                           fdl_layer_stride(&iview->image->layout, iview->base_mip)),
-                   A6XX_RB_DEPTH_BUFFER_BASE(tu_image_view_base_ref(iview)),
-                   A6XX_RB_DEPTH_BUFFER_BASE_GMEM(cmd->state.pass->attachments[a].gmem_offset));
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6);
+   tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_INFO(.depth_format = fmt).value);
+   tu_cs_image_ref(cs, iview, 0);
+   tu_cs_emit(cs, cmd->state.pass->attachments[a].gmem_offset);
 
    tu_cs_emit_regs(cs,
                    A6XX_GRAS_SU_DEPTH_BUFFER_INFO(.depth_format = fmt));
 
-   tu_cs_emit_regs(cs,
-                   A6XX_RB_DEPTH_FLAG_BUFFER_BASE(tu_image_view_ubwc_base_ref(iview)),
-                   A6XX_RB_DEPTH_FLAG_BUFFER_PITCH(tu_image_view_ubwc_pitches(iview)));
+   tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE_LO, 3);
+   tu_cs_image_flag_ref(cs, iview, 0);
 
    tu_cs_emit_regs(cs,
                    A6XX_GRAS_LRZ_BUFFER_BASE(0),
@@ -429,30 +425,16 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd,
 
       const struct tu_image_view *iview = fb->attachments[a].attachment;
 
-
-      struct tu_native_format format =
-         tu6_format_image(iview->image, iview->vk_format, iview->base_mip);
+      tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
+      tu_cs_emit(cs, iview->RB_MRT_BUF_INFO);
+      tu_cs_image_ref(cs, iview, 0);
+      tu_cs_emit(cs, cmd->state.pass->attachments[a].gmem_offset);
 
       tu_cs_emit_regs(cs,
-                      A6XX_RB_MRT_BUF_INFO(i,
-                                           .color_tile_mode = format.tile_mode,
-                                           .color_format = format.fmt,
-                                           .color_swap = format.swap),
-                      A6XX_RB_MRT_PITCH(i, tu_image_stride(iview->image, iview->base_mip)),
-                      A6XX_RB_MRT_ARRAY_PITCH(i,
-                              fdl_layer_stride(&iview->image->layout, iview->base_mip)),
-                      A6XX_RB_MRT_BASE(i, tu_image_view_base_ref(iview)),
-                      A6XX_RB_MRT_BASE_GMEM(i, cmd->state.pass->attachments[a].gmem_offset));
+                      A6XX_SP_FS_MRT_REG(i, .dword = iview->SP_FS_MRT_REG));
 
-      tu_cs_emit_regs(cs,
-                      A6XX_SP_FS_MRT_REG(i,
-                                         .color_format = format.fmt,
-                                         .color_sint = vk_format_is_sint(iview->vk_format),
-                                         .color_uint = vk_format_is_uint(iview->vk_format)));
-
-      tu_cs_emit_regs(cs,
-                      A6XX_RB_MRT_FLAG_BUFFER_ADDR(i, tu_image_view_ubwc_base_ref(iview)),
-                      A6XX_RB_MRT_FLAG_BUFFER_PITCH(i, tu_image_view_ubwc_pitches(iview)));
+      tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER_ADDR_LO(i), 3);
+      tu_cs_image_flag_ref(cs, iview, 0);
    }
 
    tu_cs_emit_regs(cs,
@@ -532,7 +514,7 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
             continue;
 
          const struct tu_image_view *iview = fb->attachments[a].attachment;
-         if (iview->image->layout.ubwc_layer_size != 0)
+         if (iview->ubwc_enabled)
             mrts_ubwc_enable |= 1 << i;
       }
 
@@ -541,7 +523,7 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
       const uint32_t a = subpass->depth_stencil_attachment.attachment;
       if (a != VK_ATTACHMENT_UNUSED) {
          const struct tu_image_view *iview = fb->attachments[a].attachment;
-         if (iview->image->layout.ubwc_layer_size != 0)
+         if (iview->ubwc_enabled)
             cntl |= A6XX_RB_RENDER_CNTL_FLAG_DEPTH;
       }
 
diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c
index 4e2b8692605..f53566774a3 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -34,22 +34,7 @@
 #include "vk_util.h"
 #include "drm-uapi/drm_fourcc.h"
 
-static inline bool
-image_level_linear(struct tu_image *image, int level, bool ubwc)
-{
-   unsigned w = u_minify(image->extent.width, level);
-   /* all levels are tiled/compressed with UBWC */
-   return ubwc ? false : (w < 16);
-}
-
-enum a6xx_tile_mode
-tu6_get_image_tile_mode(struct tu_image *image, int level)
-{
-   if (image_level_linear(image, level, !!image->layout.ubwc_layer_size))
-      return TILE6_LINEAR;
-   else
-      return image->layout.tile_mode;
-}
+#include "tu_cs.h"
 
 VkResult
 tu_image_create(VkDevice _device,
@@ -231,13 +216,37 @@ tu6_tex_type(VkImageViewType type)
    }
 }
 
+void
+tu_cs_image_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
+{
+   tu_cs_emit(cs, iview->PITCH);
+   tu_cs_emit(cs, iview->layer_size >> 6);
+   tu_cs_emit_qw(cs, iview->base_addr + iview->layer_size * layer);
+}
+
+void
+tu_cs_image_ref_2d(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer, bool src)
+{
+   tu_cs_emit_qw(cs, iview->base_addr + iview->layer_size * layer);
+   /* SP_PS_2D_SRC_PITCH has shifted pitch field */
+   tu_cs_emit(cs, iview->PITCH << (src ? 9 : 0));
+}
+
+void
+tu_cs_image_flag_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
+{
+   tu_cs_emit_qw(cs, iview->ubwc_addr + iview->ubwc_layer_size * layer);
+   tu_cs_emit(cs, iview->FLAG_BUFFER_PITCH);
+}
+
 void
 tu_image_view_init(struct tu_image_view *iview,
-                   struct tu_device *device,
                    const VkImageViewCreateInfo *pCreateInfo)
 {
    TU_FROM_HANDLE(tu_image, image, pCreateInfo->image);
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+   VkFormat format = pCreateInfo->format;
+   VkImageAspectFlagBits aspect_mask = pCreateInfo->subresourceRange.aspectMask;
 
    switch (image->type) {
    case VK_IMAGE_TYPE_1D:
@@ -254,59 +263,61 @@ tu_image_view_init(struct tu_image_view *iview,
    }
 
    iview->image = image;
-   iview->type = pCreateInfo->viewType;
-   iview->vk_format = pCreateInfo->format;
-   iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
-
-   iview->base_layer = range->baseArrayLayer;
-   iview->layer_count = tu_get_layerCount(image, range);
-   iview->base_mip = range->baseMipLevel;
-   iview->level_count = tu_get_levelCount(image, range);
-
-   iview->extent.width = u_minify(image->extent.width, iview->base_mip);
-   iview->extent.height = u_minify(image->extent.height, iview->base_mip);
-   iview->extent.depth = u_minify(image->extent.depth, iview->base_mip);
 
    memset(iview->descriptor, 0, sizeof(iview->descriptor));
 
-   struct tu_native_format fmt =
-      tu6_format_image_src(image, iview->vk_format, iview->base_mip);
-   uint64_t base_addr = tu_image_base(image, iview->base_mip, iview->base_layer);
-   uint64_t ubwc_addr = tu_image_ubwc_base(image, iview->base_mip, iview->base_layer);
+   struct fdl_layout *layout = &image->layout;
 
-   uint32_t pitch = tu_image_pitch(image, iview->base_mip);
-   uint32_t width = iview->extent.width;
-   uint32_t height = iview->extent.height;
+   uint32_t width = u_minify(image->extent.width, range->baseMipLevel);
+   uint32_t height = u_minify(image->extent.height, range->baseMipLevel);
    uint32_t depth = pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D ?
-      iview->extent.depth : iview->layer_count;
+      u_minify(image->extent.depth, range->baseMipLevel) : tu_get_layerCount(image, range);
+
+   uint64_t base_addr = image->bo->iova + image->bo_offset +
+      fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer);
+   uint64_t ubwc_addr = image->bo->iova + image->bo_offset +
+      fdl_ubwc_offset(layout, range->baseMipLevel, range->baseArrayLayer);
+
+   uint32_t pitch = layout->slices[range->baseMipLevel].pitch * layout->cpp /
+                     util_format_get_blockwidth(layout->format);
+   uint32_t ubwc_pitch = layout->ubwc_slices[range->baseMipLevel].pitch;
+   uint32_t layer_size = fdl_layer_stride(layout, range->baseMipLevel);
+
+   struct tu_native_format fmt = tu6_format_texture(format, layout->tile_mode);
+   /* note: freedreno layout assumes no TILE_ALL bit for non-UBWC
+    * this means smaller mipmap levels have a linear tile mode
+    */
+   fmt.tile_mode = fdl_tile_mode(layout, range->baseMipLevel);
+
+   bool ubwc_enabled = fdl_ubwc_enabled(layout, range->baseMipLevel);
 
    unsigned fmt_tex = fmt.fmt;
    if (fmt_tex == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8) {
-      if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
+      if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
          fmt_tex = FMT6_Z24_UNORM_S8_UINT;
-      if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
+      if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
          fmt_tex = FMT6_S8Z24_UINT;
       /* TODO: also use this format with storage descriptor ? */
    }
 
    iview->descriptor[0] =
       A6XX_TEX_CONST_0_TILE_MODE(fmt.tile_mode) |
-      COND(vk_format_is_srgb(iview->vk_format), A6XX_TEX_CONST_0_SRGB) |
+      COND(vk_format_is_srgb(format), A6XX_TEX_CONST_0_SRGB) |
       A6XX_TEX_CONST_0_FMT(fmt_tex) |
       A6XX_TEX_CONST_0_SAMPLES(tu_msaa_samples(image->samples)) |
       A6XX_TEX_CONST_0_SWAP(fmt.swap) |
-      tu6_texswiz(&pCreateInfo->components, iview->vk_format, iview->aspect_mask) |
-      A6XX_TEX_CONST_0_MIPLVLS(iview->level_count - 1);
+      tu6_texswiz(&pCreateInfo->components, format, aspect_mask) |
+      A6XX_TEX_CONST_0_MIPLVLS(tu_get_levelCount(image, range) - 1);
    iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height);
    iview->descriptor[2] =
-      A6XX_TEX_CONST_2_FETCHSIZE(tu6_fetchsize(iview->vk_format)) |
+      A6XX_TEX_CONST_2_FETCHSIZE(tu6_fetchsize(format)) |
       A6XX_TEX_CONST_2_PITCH(pitch) |
       A6XX_TEX_CONST_2_TYPE(tu6_tex_type(pCreateInfo->viewType));
-   iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(tu_layer_size(image, iview->base_mip));
+   iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size);
    iview->descriptor[4] = base_addr;
    iview->descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(depth);
 
-   if (image->layout.ubwc_layer_size) {
+   if (ubwc_enabled) {
       uint32_t block_width, block_height;
       fdl6_get_ubwc_blockwidth(&image->layout,
                                &block_width, &block_height);
@@ -314,9 +325,9 @@ tu_image_view_init(struct tu_image_view *iview,
       iview->descriptor[3] |= A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_TILE_ALL;
       iview->descriptor[7] = ubwc_addr;
       iview->descriptor[8] = ubwc_addr >> 32;
-      iview->descriptor[9] |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(tu_image_ubwc_size(image, iview->base_mip) >> 2);
+      iview->descriptor[9] |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(layout->ubwc_layer_size >> 2);
       iview->descriptor[10] |=
-         A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(tu_image_ubwc_pitch(image, iview->base_mip)) |
+         A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_pitch) |
          A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(width, block_width))) |
          A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(height, block_height)));
    }
@@ -326,6 +337,13 @@ tu_image_view_init(struct tu_image_view *iview,
          A6XX_TEX_CONST_3_MIN_LAYERSZ(image->layout.slices[image->level_count - 1].size0);
    }
 
+   /* only texture descriptor is valid for TEXTURE-only formats */
+   if (!(fmt.supported & FMT_COLOR))
+      return;
+
+   struct tu_native_format cfmt = tu6_format_color(format, layout->tile_mode);
+   cfmt.tile_mode = fmt.tile_mode;
+
    if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
       memset(iview->storage_descriptor, 0, sizeof(iview->storage_descriptor));
 
@@ -338,20 +356,75 @@ tu_image_view_init(struct tu_image_view *iview,
       iview->storage_descriptor[2] =
          A6XX_IBO_2_PITCH(pitch) |
          A6XX_IBO_2_TYPE(tu6_tex_type(pCreateInfo->viewType));
-      iview->storage_descriptor[3] = A6XX_IBO_3_ARRAY_PITCH(tu_layer_size(image, iview->base_mip));
+      iview->storage_descriptor[3] = A6XX_IBO_3_ARRAY_PITCH(layer_size);
 
       iview->storage_descriptor[4] = base_addr;
       iview->storage_descriptor[5] = (base_addr >> 32) | A6XX_IBO_5_DEPTH(depth);
 
-      if (image->layout.ubwc_layer_size) {
+      if (ubwc_enabled) {
          iview->storage_descriptor[3] |= A6XX_IBO_3_FLAG | A6XX_IBO_3_UNK27;
          iview->storage_descriptor[7] |= ubwc_addr;
          iview->storage_descriptor[8] |= ubwc_addr >> 32;
-         iview->storage_descriptor[9] = A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(tu_image_ubwc_size(image, iview->base_mip) >> 2);
+         iview->storage_descriptor[9] = A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(layout->ubwc_layer_size >> 2);
          iview->storage_descriptor[10] =
-            A6XX_IBO_10_FLAG_BUFFER_PITCH(tu_image_ubwc_pitch(image, iview->base_mip));
+            A6XX_IBO_10_FLAG_BUFFER_PITCH(ubwc_pitch);
       }
    }
+
+   iview->base_addr = base_addr;
+   iview->ubwc_addr = ubwc_addr;
+   iview->layer_size = layer_size;
+   iview->ubwc_layer_size = layout->ubwc_layer_size;
+
+   iview->extent.width = width;
+   iview->extent.height = height;
+   iview->need_y2_align =
+      (fmt.tile_mode == TILE6_LINEAR && range->baseMipLevel != image->level_count - 1);
+
+   iview->ubwc_enabled = ubwc_enabled;
+
+   /* note: these have same encoding for MRT and 2D (except 2D PITCH src) */
+   iview->PITCH = A6XX_RB_DEPTH_BUFFER_PITCH(pitch).value;
+   iview->FLAG_BUFFER_PITCH = A6XX_RB_DEPTH_FLAG_BUFFER_PITCH(
+      .pitch = ubwc_pitch, .array_pitch = layout->ubwc_layer_size >> 2).value;
+
+   iview->RB_MRT_BUF_INFO = A6XX_RB_MRT_BUF_INFO(0,
+                              .color_tile_mode = cfmt.tile_mode,
+                              .color_format = cfmt.fmt,
+                              .color_swap = cfmt.swap).value;
+   iview->SP_FS_MRT_REG = A6XX_SP_FS_MRT_REG(0,
+                              .color_format = cfmt.fmt,
+                              .color_sint = vk_format_is_sint(format),
+                              .color_uint = vk_format_is_uint(format)).value;
+
+   iview->SP_PS_2D_SRC_INFO = A6XX_SP_PS_2D_SRC_INFO(
+      .color_format = fmt.fmt,
+      .tile_mode = fmt.tile_mode,
+      .color_swap = fmt.swap,
+      .flags = ubwc_enabled,
+      .srgb = vk_format_is_srgb(format),
+      .samples = tu_msaa_samples(image->samples),
+      .samples_average = image->samples > 1 &&
+                           !vk_format_is_int(format) &&
+                           !vk_format_is_depth_or_stencil(format),
+      .unk20 = 1,
+      .unk22 = 1).value;
+   iview->SP_PS_2D_SRC_SIZE =
+      A6XX_SP_PS_2D_SRC_SIZE(.width = width, .height = height).value;
+
+   iview->RB_2D_DST_INFO = A6XX_RB_2D_DST_INFO(
+      .color_format = cfmt.fmt,
+      .tile_mode = cfmt.tile_mode,
+      .color_swap = cfmt.swap,
+      .flags = ubwc_enabled,
+      .srgb = vk_format_is_srgb(format)).value;
+
+   iview->RB_BLIT_DST_INFO = A6XX_RB_BLIT_DST_INFO(
+      .tile_mode = cfmt.tile_mode,
+      .samples = tu_msaa_samples(iview->image->samples),
+      .color_format = cfmt.fmt,
+      .color_swap = cfmt.swap,
+      .flags = ubwc_enabled).value;
 }
 
 unsigned
@@ -485,7 +558,7 @@ tu_CreateImageView(VkDevice _device,
    if (view == NULL)
       return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   tu_image_view_init(view, device, pCreateInfo);
+   tu_image_view_init(view, pCreateInfo);
 
    *pView = tu_image_view_to_handle(view);
 
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 1c081a2ddda..4953075375f 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1433,116 +1433,25 @@ tu_get_levelCount(const struct tu_image *image,
              : range->levelCount;
 }
 
-static inline VkDeviceSize
-tu_layer_size(struct tu_image *image, int level)
-{
-   return fdl_layer_stride(&image->layout, level);
-}
-
-static inline uint32_t
-tu_image_stride(struct tu_image *image, int level)
-{
-   return image->layout.slices[level].pitch * image->layout.cpp;
-}
-
-/* to get the right pitch for compressed formats */
-static inline uint32_t
-tu_image_pitch(struct tu_image *image, int level)
-{
-   uint32_t stride = tu_image_stride(image, level);
-   return stride / vk_format_get_blockwidth(image->vk_format);
-}
-
-static inline uint64_t
-tu_image_base(struct tu_image *image, int level, int layer)
-{
-   return image->bo->iova + image->bo_offset +
-      fdl_surface_offset(&image->layout, level, layer);
-}
-
-#define tu_image_base_ref(image, level, layer)                          \
-   .bo = image->bo,                                                     \
-   .bo_offset = (image->bo_offset + fdl_surface_offset(&image->layout,  \
-                                                       level, layer))
-
-#define tu_image_view_base_ref(iview)                                   \
-   tu_image_base_ref(iview->image, iview->base_mip, iview->base_layer)
-
-static inline VkDeviceSize
-tu_image_ubwc_size(struct tu_image *image, int level)
-{
-   return image->layout.ubwc_layer_size;
-}
-
-static inline uint32_t
-tu_image_ubwc_pitch(struct tu_image *image, int level)
-{
-   return image->layout.ubwc_slices[level].pitch;
-}
-
-static inline uint64_t
-tu_image_ubwc_surface_offset(struct tu_image *image, int level, int layer)
-{
-   return image->layout.ubwc_slices[level].offset +
-      layer * tu_image_ubwc_size(image, level);
-}
-
-static inline uint64_t
-tu_image_ubwc_base(struct tu_image *image, int level, int layer)
-{
-   return image->bo->iova + image->bo_offset +
-      tu_image_ubwc_surface_offset(image, level, layer);
-}
-
-#define tu_image_ubwc_base_ref(image, level, layer)                     \
-   .bo = image->bo,                                                     \
-   .bo_offset = (image->bo_offset + tu_image_ubwc_surface_offset(image, \
-                                                                 level, layer))
-
-#define tu_image_view_ubwc_base_ref(iview) \
-   tu_image_ubwc_base_ref(iview->image, iview->base_mip, iview->base_layer)
-
-#define tu_image_view_ubwc_pitches(iview)                                \
-   .pitch = tu_image_ubwc_pitch(iview->image, iview->base_mip),          \
-   .array_pitch = tu_image_ubwc_size(iview->image, iview->base_mip) >> 2
-
-enum a6xx_tile_mode
-tu6_get_image_tile_mode(struct tu_image *image, int level);
 enum a3xx_msaa_samples
 tu_msaa_samples(uint32_t samples);
 enum a6xx_tex_fetchsize
 tu6_fetchsize(VkFormat format);
 
-static inline struct tu_native_format
-tu6_format_image(struct tu_image *image, VkFormat format, uint32_t level)
-{
-   struct tu_native_format fmt =
-      tu6_format_color(format, image->layout.tile_mode);
-   fmt.tile_mode = tu6_get_image_tile_mode(image, level);
-   return fmt;
-}
-
-static inline struct tu_native_format
-tu6_format_image_src(struct tu_image *image, VkFormat format, uint32_t level)
-{
-   struct tu_native_format fmt =
-      tu6_format_texture(format, image->layout.tile_mode);
-   fmt.tile_mode = tu6_get_image_tile_mode(image, level);
-   return fmt;
-}
-
 struct tu_image_view
 {
    struct tu_image *image; /**< VkImageViewCreateInfo::image */
 
-   VkImageViewType type;
-   VkImageAspectFlags aspect_mask;
-   VkFormat vk_format;
-   uint32_t base_layer;
-   uint32_t layer_count;
-   uint32_t base_mip;
-   uint32_t level_count;
-   VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
+   uint64_t base_addr;
+   uint64_t ubwc_addr;
+   uint32_t layer_size;
+   uint32_t ubwc_layer_size;
+
+   /* used to determine if fast gmem store path can be used */
+   VkExtent2D extent;
+   bool need_y2_align;
+
+   bool ubwc_enabled;
 
    uint32_t descriptor[A6XX_TEX_CONST_DWORDS];
 
@@ -1550,12 +1459,35 @@ struct tu_image_view
     * This has a few differences for cube maps (e.g. type).
     */
    uint32_t storage_descriptor[A6XX_TEX_CONST_DWORDS];
+
+   /* pre-filled register values */
+   uint32_t PITCH;
+   uint32_t FLAG_BUFFER_PITCH;
+
+   uint32_t RB_MRT_BUF_INFO;
+   uint32_t SP_FS_MRT_REG;
+
+   uint32_t SP_PS_2D_SRC_INFO;
+   uint32_t SP_PS_2D_SRC_SIZE;
+
+   uint32_t RB_2D_DST_INFO;
+
+   uint32_t RB_BLIT_DST_INFO;
 };
 
 struct tu_sampler {
    uint32_t descriptor[A6XX_TEX_SAMP_DWORDS];
 };
 
+void
+tu_cs_image_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer);
+
+void
+tu_cs_image_ref_2d(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer, bool src);
+
+void
+tu_cs_image_flag_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer);
+
 VkResult
 tu_image_create(VkDevice _device,
                 const VkImageCreateInfo *pCreateInfo,
@@ -1572,7 +1504,6 @@ tu_image_from_gralloc(VkDevice device_h,
 
 void
 tu_image_view_init(struct tu_image_view *view,
-                   struct tu_device *device,
                    const VkImageViewCreateInfo *pCreateInfo);
 
 struct tu_buffer_view



More information about the mesa-commit mailing list