tu: Align GMEM resolve blit scissor
[mesa.git] / src / freedreno / vulkan / tu_image.c
index 978b1b1845359c85eb30cd45c48b834a78c87e83..4e2b86926053ad8df18853e995a7848eadd13020 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "util/debug.h"
 #include "util/u_atomic.h"
+#include "util/format/u_format.h"
 #include "vk_format.h"
 #include "vk_util.h"
 #include "drm-uapi/drm_fourcc.h"
@@ -44,7 +45,7 @@ image_level_linear(struct tu_image *image, int level, bool ubwc)
 enum a6xx_tile_mode
 tu6_get_image_tile_mode(struct tu_image *image, int level)
 {
-   if (image_level_linear(image, level, !!image->layout.ubwc_size))
+   if (image_level_linear(image, level, !!image->layout.ubwc_layer_size))
       return TILE6_LINEAR;
    else
       return image->layout.tile_mode;
@@ -110,13 +111,6 @@ tu_image_create(VkDevice _device,
       ubwc_enabled = false;
    }
 
-   /* using UBWC with D24S8 breaks the "stencil read" copy path (why?)
-    * (causes any deqp tests that need to check stencil to fail)
-    * disable UBWC for this format until we properly support copy aspect masks
-    */
-   if (image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT)
-      ubwc_enabled = false;
-
    /* UBWC can't be used with E5B9G9R9 */
    if (image->vk_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
       ubwc_enabled = false;
@@ -126,6 +120,18 @@ tu_image_create(VkDevice _device,
       ubwc_enabled = false;
    }
 
+   /* Disable UBWC for storage images.
+    *
+    * The closed GL driver skips UBWC for storage images (and additionally
+    * uses linear for writeonly images).  We seem to have image tiling working
+    * in freedreno in general, so turnip matches that.  freedreno also enables
+    * UBWC on images, but it's not really tested due to the lack of
+    * UBWC-enabled mipmaps in freedreno currently.  Just match the closed GL
+    * behavior of no UBWC.
+   */
+   if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT)
+      ubwc_enabled = false;
+
    uint32_t ubwc_blockwidth, ubwc_blockheight;
    fdl6_get_ubwc_blockwidth(&image->layout,
                             &ubwc_blockwidth, &ubwc_blockheight);
@@ -137,6 +143,8 @@ tu_image_create(VkDevice _device,
    /* expect UBWC enabled if we asked for it */
    assert(modifier != DRM_FORMAT_MOD_QCOM_COMPRESSED || ubwc_enabled);
 
+   image->layout.ubwc = ubwc_enabled;
+
    fdl6_layout(&image->layout, vk_format_to_pipe_format(image->vk_format),
                image->samples,
                pCreateInfo->extent.width,
@@ -144,15 +152,14 @@ tu_image_create(VkDevice _device,
                pCreateInfo->extent.depth,
                pCreateInfo->mipLevels,
                pCreateInfo->arrayLayers,
-               pCreateInfo->imageType == VK_IMAGE_TYPE_3D,
-               ubwc_enabled);
+               pCreateInfo->imageType == VK_IMAGE_TYPE_3D);
 
    *pImage = tu_image_to_handle(image);
 
    return VK_SUCCESS;
 }
 
-static enum a6xx_tex_fetchsize
+enum a6xx_tex_fetchsize
 tu6_fetchsize(VkFormat format)
 {
    if (vk_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC)
@@ -251,38 +258,43 @@ tu_image_view_init(struct tu_image_view *iview,
    iview->vk_format = pCreateInfo->format;
    iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
 
-   // should we minify?
-   iview->extent = image->extent;
-
    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));
 
-   const struct tu_native_format *fmt = tu6_get_native_format(iview->vk_format);
+   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);
 
-   uint32_t pitch = tu_image_stride(image, iview->base_mip) / vk_format_get_blockwidth(iview->vk_format);
-   enum a6xx_tile_mode tile_mode = tu6_get_image_tile_mode(image, iview->base_mip);
-   uint32_t width = u_minify(image->extent.width, iview->base_mip);
-   uint32_t height = u_minify(image->extent.height, iview->base_mip);
+   uint32_t pitch = tu_image_pitch(image, iview->base_mip);
+   uint32_t width = iview->extent.width;
+   uint32_t height = iview->extent.height;
    uint32_t depth = pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D ?
-      u_minify(image->extent.depth, iview->base_mip) : iview->layer_count;
-
-   unsigned fmt_tex = fmt->tex;
-   if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT &&
-       iview->vk_format == VK_FORMAT_D24_UNORM_S8_UINT)
-      fmt_tex = TFMT6_S8Z24_UINT;
+      iview->extent.depth : iview->layer_count;
+
+   unsigned fmt_tex = fmt.fmt;
+   if (fmt_tex == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8) {
+      if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
+         fmt_tex = FMT6_Z24_UNORM_S8_UINT;
+      if (iview->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(tile_mode) |
+      A6XX_TEX_CONST_0_TILE_MODE(fmt.tile_mode) |
       COND(vk_format_is_srgb(iview->vk_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(image->layout.tile_mode ? WZYX : fmt->swap) |
+      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);
    iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height);
@@ -294,7 +306,7 @@ tu_image_view_init(struct tu_image_view *iview,
    iview->descriptor[4] = base_addr;
    iview->descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(depth);
 
-   if (image->layout.ubwc_size) {
+   if (image->layout.ubwc_layer_size) {
       uint32_t block_width, block_height;
       fdl6_get_ubwc_blockwidth(&image->layout,
                                &block_width, &block_height);
@@ -318,8 +330,8 @@ tu_image_view_init(struct tu_image_view *iview,
       memset(iview->storage_descriptor, 0, sizeof(iview->storage_descriptor));
 
       iview->storage_descriptor[0] =
-         A6XX_IBO_0_FMT(fmt->tex) |
-         A6XX_IBO_0_TILE_MODE(tile_mode);
+         A6XX_IBO_0_FMT(fmt.fmt) |
+         A6XX_IBO_0_TILE_MODE(fmt.tile_mode);
       iview->storage_descriptor[1] =
          A6XX_IBO_1_WIDTH(width) |
          A6XX_IBO_1_HEIGHT(height);
@@ -331,7 +343,7 @@ tu_image_view_init(struct tu_image_view *iview,
       iview->storage_descriptor[4] = base_addr;
       iview->storage_descriptor[5] = (base_addr >> 32) | A6XX_IBO_5_DEPTH(depth);
 
-      if (image->layout.ubwc_size) {
+      if (image->layout.ubwc_layer_size) {
          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;
@@ -382,6 +394,11 @@ tu_CreateImage(VkDevice device,
          if (mod_info->pDrmFormatModifiers[i] == DRM_FORMAT_MOD_QCOM_COMPRESSED)
             modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
       }
+   } else {
+      const struct wsi_image_create_info *wsi_info =
+         vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
+      if (wsi_info && wsi_info->scanout)
+         modifier = DRM_FORMAT_MOD_LINEAR;
    }
 
    return tu_image_create(device, pCreateInfo, pAllocator, pImage, modifier);
@@ -423,7 +440,7 @@ tu_GetImageSubresourceLayout(VkDevice _device,
    pLayout->arrayPitch = image->layout.layer_size;
    pLayout->depthPitch = slice->size0;
 
-   if (image->layout.ubwc_size) {
+   if (image->layout.ubwc_layer_size) {
       /* UBWC starts at offset 0 */
       pLayout->offset = 0;
       /* UBWC scanout won't match what the kernel wants if we have levels/layers */
@@ -431,6 +448,29 @@ tu_GetImageSubresourceLayout(VkDevice _device,
    }
 }
 
+VkResult tu_GetImageDrmFormatModifierPropertiesEXT(
+    VkDevice                                    device,
+    VkImage                                     _image,
+    VkImageDrmFormatModifierPropertiesEXT*      pProperties)
+{
+   TU_FROM_HANDLE(tu_image, image, _image);
+
+   assert(pProperties->sType ==
+          VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT);
+
+   /* TODO invent a modifier for tiled but not UBWC buffers */
+
+   if (!image->layout.tile_mode)
+      pProperties->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
+   else if (image->layout.ubwc_layer_size)
+      pProperties->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
+   else
+      pProperties->drmFormatModifier = DRM_FORMAT_MOD_INVALID;
+
+   return VK_SUCCESS;
+}
+
+
 VkResult
 tu_CreateImageView(VkDevice _device,
                    const VkImageViewCreateInfo *pCreateInfo,
@@ -472,10 +512,45 @@ tu_buffer_view_init(struct tu_buffer_view *view,
 {
    TU_FROM_HANDLE(tu_buffer, buffer, pCreateInfo->buffer);
 
-   view->range = pCreateInfo->range == VK_WHOLE_SIZE
-                    ? buffer->size - pCreateInfo->offset
-                    : pCreateInfo->range;
-   view->vk_format = pCreateInfo->format;
+   view->buffer = buffer;
+
+   enum VkFormat vfmt = pCreateInfo->format;
+   enum pipe_format pfmt = vk_format_to_pipe_format(vfmt);
+   const struct tu_native_format fmt = tu6_format_texture(vfmt, TILE6_LINEAR);
+
+   uint32_t range;
+   if (pCreateInfo->range == VK_WHOLE_SIZE)
+      range = buffer->size - pCreateInfo->offset;
+   else
+      range = pCreateInfo->range;
+   uint32_t elements = range / util_format_get_blocksize(pfmt);
+
+   static const VkComponentMapping components = {
+      .r = VK_COMPONENT_SWIZZLE_R,
+      .g = VK_COMPONENT_SWIZZLE_G,
+      .b = VK_COMPONENT_SWIZZLE_B,
+      .a = VK_COMPONENT_SWIZZLE_A,
+   };
+
+   uint64_t iova = tu_buffer_iova(buffer) + pCreateInfo->offset;
+
+   memset(&view->descriptor, 0, sizeof(view->descriptor));
+
+   view->descriptor[0] =
+      A6XX_TEX_CONST_0_TILE_MODE(TILE6_LINEAR) |
+      A6XX_TEX_CONST_0_SWAP(fmt.swap) |
+      A6XX_TEX_CONST_0_FMT(fmt.fmt) |
+      A6XX_TEX_CONST_0_MIPLVLS(0) |
+      tu6_texswiz(&components, vfmt, VK_IMAGE_ASPECT_COLOR_BIT);
+      COND(vk_format_is_srgb(vfmt), A6XX_TEX_CONST_0_SRGB);
+   view->descriptor[1] =
+      A6XX_TEX_CONST_1_WIDTH(elements & MASK(15)) |
+      A6XX_TEX_CONST_1_HEIGHT(elements >> 15);
+   view->descriptor[2] =
+      A6XX_TEX_CONST_2_UNK4 |
+      A6XX_TEX_CONST_2_UNK31;
+   view->descriptor[4] = iova;
+   view->descriptor[5] = iova >> 32;
 }
 
 VkResult