turnip: update setup_slices
authorJonathan Marek <jonathan@marek.ca>
Fri, 4 Oct 2019 19:56:32 +0000 (15:56 -0400)
committerJonathan Marek <jonathan@marek.ca>
Tue, 15 Oct 2019 11:56:19 +0000 (07:56 -0400)
Deal with tiled r8g8 having different alignment and other updates taken
from fd6_resource. Additionally track image samples/cpp.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_image.c
src/freedreno/vulkan/tu_private.h

index e9d4d37e1fce44b8a56c99691877392c13942594..34da6d0e88c8034528deba57829b2441535fffb2 100644 (file)
@@ -454,7 +454,7 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
       assert(format && format->rb >= 0);
 
       offset = slice->offset + slice->size * iview->base_layer;
-      stride = slice->pitch * vk_format_get_blocksize(iview->vk_format);
+      stride = slice->pitch * iview->image->cpp;
 
       tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
       tu_cs_emit(cs, A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format->rb) |
@@ -604,8 +604,7 @@ tu6_emit_blit_info(struct tu_cmd_buffer *cmd,
    const struct tu_image_level *slice =
       &iview->image->levels[iview->base_mip];
    const uint32_t offset = slice->offset + slice->size * iview->base_layer;
-   const uint32_t stride =
-      slice->pitch * vk_format_get_blocksize(iview->vk_format);
+   const uint32_t stride = slice->pitch * iview->image->cpp;
    const enum a3xx_msaa_samples samples = tu6_msaa_samples(1);
 
    tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_INFO, 1);
index 9f2fa4a7569dab2c983386a73aa0199c795214c3..9c558407309c934a0abf2c286ec51e4ab06aa410 100644 (file)
@@ -39,86 +39,97 @@ image_level_linear(struct tu_image *image, int level)
    return w < 16;
 }
 
-/* indexed by cpp: */
-static const struct
-{
+/* indexed by cpp, including msaa 2x and 4x: */
+static const struct {
    unsigned pitchalign;
    unsigned heightalign;
 } tile_alignment[] = {
-   [1] = { 128, 32 }, [2] = { 128, 16 }, [3] = { 128, 16 }, [4] = { 64, 16 },
-   [8] = { 64, 16 },  [12] = { 64, 16 }, [16] = { 64, 16 },
+   [1]  = { 128, 32 },
+   [2]  = { 128, 16 },
+   [3]  = {  64, 32 },
+   [4]  = {  64, 16 },
+   [6]  = {  64, 16 },
+   [8]  = {  64, 16 },
+   [12] = {  64, 16 },
+   [16] = {  64, 16 },
+   [24] = {  64, 16 },
+   [32] = {  64, 16 },
+   [48] = {  64, 16 },
+   [64] = {  64, 16 },
+
+   /* special case for r8g8: */
+   [0]  = { 64, 32 },
 };
 
 static void
 setup_slices(struct tu_image *image, const VkImageCreateInfo *pCreateInfo)
 {
-   enum vk_format_layout layout =
-      vk_format_description(pCreateInfo->format)->layout;
+   VkFormat format = pCreateInfo->format;
+   enum vk_format_layout layout = vk_format_description(format)->layout;
    uint32_t layer_size = 0;
-   uint32_t width = pCreateInfo->extent.width;
-   uint32_t height = pCreateInfo->extent.height;
-   uint32_t depth = pCreateInfo->extent.depth;
-   bool layer_first = pCreateInfo->imageType != VK_IMAGE_TYPE_3D;
-   uint32_t alignment = pCreateInfo->imageType == VK_IMAGE_TYPE_3D ? 4096 : 1;
-   uint32_t cpp = vk_format_get_blocksize(pCreateInfo->format);
+   int ta = image->cpp;
 
-   uint32_t heightalign = tile_alignment[cpp].heightalign;
+   /* The r8g8 format seems to not play by the normal tiling rules: */
+   if (image->cpp == 2 && vk_format_get_nr_components(format) == 2)
+      ta = 0;
 
    for (unsigned level = 0; level < pCreateInfo->mipLevels; level++) {
       struct tu_image_level *slice = &image->levels[level];
-      bool linear_level = image_level_linear(image, level);
+      uint32_t width = u_minify(pCreateInfo->extent.width, level);
+      uint32_t height = u_minify(pCreateInfo->extent.height, level);
+      uint32_t depth = u_minify(pCreateInfo->extent.depth, level);
       uint32_t aligned_height = height;
       uint32_t blocks;
       uint32_t pitchalign;
 
-      if (image->tile_mode && !linear_level) {
-         pitchalign = tile_alignment[cpp].pitchalign;
-         aligned_height = align(aligned_height, heightalign);
+      if (image->tile_mode && !image_level_linear(image, level)) {
+         /* tiled levels of 3D textures are rounded up to PoT dimensions: */
+         if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D) {
+            width = util_next_power_of_two(width);
+            height = aligned_height = util_next_power_of_two(height);
+         }
+         pitchalign = tile_alignment[ta].pitchalign;
+         aligned_height = align(aligned_height, tile_alignment[ta].heightalign);
       } else {
          pitchalign = 64;
-
-         /* The blits used for mem<->gmem work at a granularity of
-          * 32x32, which can cause faults due to over-fetch on the
-          * last level.  The simple solution is to over-allocate a
-          * bit the last level to ensure any over-fetch is harmless.
-          * The pitch is already sufficiently aligned, but height
-          * may not be:
-          */
-         if ((level + 1 == pCreateInfo->mipLevels))
-            aligned_height = align(aligned_height, 32);
       }
 
+      /* The blits used for mem<->gmem work at a granularity of
+       * 32x32, which can cause faults due to over-fetch on the
+       * last level.  The simple solution is to over-allocate a
+       * bit the last level to ensure any over-fetch is harmless.
+       * The pitch is already sufficiently aligned, but height
+       * may not be:
+       */
+      if (level + 1 == pCreateInfo->mipLevels)
+         aligned_height = align(aligned_height, 32);
+
       if (layout == VK_FORMAT_LAYOUT_ASTC)
-         slice->pitch = util_align_npot(
-            width,
-            pitchalign * vk_format_get_blockwidth(pCreateInfo->format));
+         slice->pitch =
+            util_align_npot(width, pitchalign * vk_format_get_blockwidth(format));
       else
          slice->pitch = align(width, pitchalign);
 
       slice->offset = layer_size;
-      blocks = vk_format_get_block_count(pCreateInfo->format, slice->pitch,
-                                         aligned_height);
+      blocks = vk_format_get_block_count(format, slice->pitch, aligned_height);
 
       /* 1d array and 2d array textures must all have the same layer size
-       * for each miplevel on a3xx. 3d textures can have different layer
+       * for each miplevel on a6xx. 3d textures can have different layer
        * sizes for high levels, but the hw auto-sizer is buggy (or at least
        * different than what this code does), so as soon as the layer size
        * range gets into range, we stop reducing it.
        */
-      if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
-          (level == 1 ||
-           (level > 1 && image->levels[level - 1].size > 0xf000)))
-         slice->size = align(blocks * cpp, alignment);
-      else if (level == 0 || layer_first || alignment == 1)
-         slice->size = align(blocks * cpp, alignment);
-      else
-         slice->size = image->levels[level - 1].size;
+      if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D) {
+         if (level < 1 || image->levels[level - 1].size > 0xf000) {
+            slice->size = align(blocks * image->cpp, 4096);
+         } else {
+            slice->size = image->levels[level - 1].size;
+         }
+      } else {
+         slice->size = blocks * image->cpp;
+      }
 
       layer_size += slice->size * depth;
-
-      width = u_minify(width, 1);
-      height = u_minify(height, 1);
-      depth = u_minify(depth, 1);
    }
 
    image->layer_size = align(layer_size, 4096);
@@ -156,6 +167,8 @@ tu_image_create(VkDevice _device,
    image->extent = pCreateInfo->extent;
    image->level_count = pCreateInfo->mipLevels;
    image->layer_count = pCreateInfo->arrayLayers;
+   image->samples = pCreateInfo->samples;
+   image->cpp = vk_format_get_blocksize(image->vk_format) * image->samples;
 
    image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
    if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
index 2537c3df9f9e055b0cb744fe18320b636677a6a9..feb460db566043c9a36b7b9731284c94bdde539c 100644 (file)
@@ -1250,6 +1250,8 @@ struct tu_image
    VkExtent3D extent;
    uint32_t level_count;
    uint32_t layer_count;
+   VkSampleCountFlagBits samples;
+
 
    VkDeviceSize size;
    uint32_t alignment;
@@ -1258,6 +1260,7 @@ struct tu_image
    VkDeviceSize layer_size;
    struct tu_image_level levels[15];
    unsigned tile_mode;
+   unsigned cpp;
 
    unsigned queue_family_mask;
    bool exclusive;