turnip: implement CmdClearColorImage/CmdClearDepthStencilImage
authorJonathan Marek <jonathan@marek.ca>
Mon, 18 Nov 2019 23:41:23 +0000 (18:41 -0500)
committerJonathan Marek <jonathan@marek.ca>
Tue, 19 Nov 2019 21:35:37 +0000 (21:35 +0000)
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
src/freedreno/vulkan/tu_blit.c
src/freedreno/vulkan/tu_blit.h
src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_formats.c
src/freedreno/vulkan/tu_meta_blit.c
src/freedreno/vulkan/tu_meta_clear.c
src/freedreno/vulkan/tu_meta_copy.c
src/freedreno/vulkan/tu_meta_resolve.c
src/freedreno/vulkan/tu_private.h
src/freedreno/vulkan/vk_format_layout.csv

index 15de704a339a07592fd59b0c6f30745d2e71753a..6a43a9fbe9bcec34809940033425076b89ae32d3 100644 (file)
@@ -96,6 +96,7 @@ emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
    }
 
    uint32_t blit_cntl = A6XX_RB_2D_BLIT_CNTL_ROTATE(blt->rotation) |
+                        COND(blt->type == TU_BLIT_CLEAR, A6XX_RB_2D_BLIT_CNTL_SOLID_COLOR) |
                         A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(fmt) | /* not required? */
                         COND(fmt == RB6_Z24_UNORM_S8_UINT_AS_R8G8B8A8, A6XX_RB_2D_BLIT_CNTL_D24S8) |
                         A6XX_RB_2D_BLIT_CNTL_MASK(0xf) |
@@ -110,23 +111,31 @@ emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
    /*
     * Emit source:
     */
-   tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
-   tu_cs_emit(cs, blit_image_info(&blt->src, true, blt->stencil_read) |
-                  A6XX_SP_PS_2D_SRC_INFO_SAMPLES(tu_msaa_samples(blt->src.samples)) |
-                  /* TODO: should disable this bit for integer formats ? */
-                  COND(blt->src.samples > 1, A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) |
-                  COND(blt->filter, A6XX_SP_PS_2D_SRC_INFO_FILTER) |
-                  0x500000);
-   tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(blt->src.x + blt->src.width) |
-                  A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(blt->src.y + blt->src.height));
-   tu_cs_emit_qw(cs, blt->src.va);
-   tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(blt->src.pitch));
-
-   tu_cs_emit(cs, 0x00000000);
-   tu_cs_emit(cs, 0x00000000);
-   tu_cs_emit(cs, 0x00000000);
-   tu_cs_emit(cs, 0x00000000);
-   tu_cs_emit(cs, 0x00000000);
+   if (blt->type == TU_BLIT_CLEAR) {
+      tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_SRC_SOLID_C0, 4);
+      tu_cs_emit(cs, blt->clear_value[0]);
+      tu_cs_emit(cs, blt->clear_value[1]);
+      tu_cs_emit(cs, blt->clear_value[2]);
+      tu_cs_emit(cs, blt->clear_value[3]);
+   } else {
+      tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
+      tu_cs_emit(cs, blit_image_info(&blt->src, true, blt->stencil_read) |
+                     A6XX_SP_PS_2D_SRC_INFO_SAMPLES(tu_msaa_samples(blt->src.samples)) |
+                     /* TODO: should disable this bit for integer formats ? */
+                     COND(blt->src.samples > 1, A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) |
+                     COND(blt->filter, A6XX_SP_PS_2D_SRC_INFO_FILTER) |
+                     0x500000);
+      tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(blt->src.x + blt->src.width) |
+                     A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(blt->src.y + blt->src.height));
+      tu_cs_emit_qw(cs, blt->src.va);
+      tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(blt->src.pitch));
+
+      tu_cs_emit(cs, 0x00000000);
+      tu_cs_emit(cs, 0x00000000);
+      tu_cs_emit(cs, 0x00000000);
+      tu_cs_emit(cs, 0x00000000);
+      tu_cs_emit(cs, 0x00000000);
+   }
 
    /*
     * Emit destination:
@@ -182,9 +191,10 @@ emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
    tu_cs_emit(cs, 0);
 }
 
-void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
+void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt)
 {
-   if (copy) {
+   switch (blt->type) {
+   case TU_BLIT_COPY:
       blt->stencil_read =
          blt->dst.fmt == VK_FORMAT_R8_UINT &&
          blt->src.fmt == VK_FORMAT_D24_UNORM_S8_UINT;
@@ -225,7 +235,14 @@ void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
       blt->dst.width *= blt->dst.samples;
       blt->src.samples = 1;
       blt->dst.samples = 1;
-   } else {
+      break;
+   case TU_BLIT_CLEAR:
+      /* unsupported format cleared as UINT32 */
+      if (blt->dst.fmt == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
+         blt->dst.fmt = blt->src.fmt = VK_FORMAT_R32_UINT;
+      assert(blt->dst.samples == 1); /* TODO */
+      break;
+   default:
       assert(blt->dst.samples == 1);
    }
 
@@ -244,7 +261,7 @@ void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
    for (unsigned layer = 0; layer < blt->layers; layer++) {
       if ((blt->src.va & 63) || (blt->src.pitch & 63)) {
          /* per line copy path (buffer_to_image) */
-         assert(copy && !blt->src.tiled);
+         assert(blt->type == TU_BLIT_COPY && !blt->src.tiled);
          struct tu_blit line_blt = *blt;
          uint64_t src_va = line_blt.src.va + blt->src.pitch * blt->src.y;
 
@@ -264,7 +281,7 @@ void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy)
          }
       } else if ((blt->dst.va & 63) || (blt->dst.pitch & 63)) {
          /* per line copy path (image_to_buffer) */
-         assert(copy && !blt->dst.tiled);
+         assert(blt->type == TU_BLIT_COPY && !blt->dst.tiled);
          struct tu_blit line_blt = *blt;
          uint64_t dst_va = line_blt.dst.va + blt->dst.pitch * blt->dst.y;
 
index 1f4967e845f76e7a5189a9887145b66b58ea65f2..b01f62c76850dbd2d699a4fe91d83d529fc87049 100644 (file)
@@ -79,13 +79,25 @@ tu_blit_surf_ext(struct tu_image *image,
 }
 
 static inline struct tu_blit_surf
-tu_blit_surf_whole(struct tu_image *image)
+tu_blit_surf_whole(struct tu_image *image, int level, int layer)
 {
-   return tu_blit_surf(image, (VkImageSubresourceLayers){}, (VkOffset3D[]) {
-      {}, {image->extent.width, image->extent.height}
+   return tu_blit_surf(image, (VkImageSubresourceLayers){
+      .mipLevel = level,
+      .baseArrayLayer = layer,
+   }, (VkOffset3D[]) {
+      {}, {
+         u_minify(image->extent.width, level),
+         u_minify(image->extent.height, level),
+      }
    });
 }
 
+enum tu_blit_type {
+   TU_BLIT_DEFAULT,
+   TU_BLIT_COPY,
+   TU_BLIT_CLEAR,
+};
+
 struct tu_blit {
    struct tu_blit_surf dst;
    struct tu_blit_surf src;
@@ -93,8 +105,10 @@ struct tu_blit {
    bool filter;
    bool stencil_read;
    enum a6xx_rotation rotation;
+   uint32_t clear_value[4];
+   enum tu_blit_type type;
 };
 
-void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt, bool copy);
+void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt);
 
 #endif /* TU_BLIT_H */
index 200ba002939bdcdf787e0dec60e17d00435226fa..f7081e88fc26ec518658cb9ee040897c2d0a8e58 100644 (file)
@@ -1153,10 +1153,10 @@ tu6_render_end(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
          tu_bo_list_add(&cmd->bo_list, dst_img->bo, MSM_SUBMIT_BO_WRITE);
 
          tu_blit(cmd, &(struct tu_blit) {
-            .dst = tu_blit_surf_whole(dst_img),
-            .src = tu_blit_surf_whole(src_img),
+            .dst = tu_blit_surf_whole(dst_img, 0, 0),
+            .src = tu_blit_surf_whole(src_img, 0, 0),
             .layers = 1,
-         }, false);
+         });
       }
    }
 
index 6cedf24b61fe7b29bcc23e48c693c3ffe01cb396..35dfe04b1240efc41bd087bcb01f64a1bbcc25f6 100644 (file)
@@ -631,6 +631,75 @@ tu_pack_clear_value(const VkClearValue *val, VkFormat format, uint32_t buf[4])
    }
 }
 
+void
+tu_2d_clear_color(const VkClearColorValue *val, VkFormat format, uint32_t buf[4])
+{
+   const struct vk_format_description *desc = vk_format_description(format);
+
+   /* not supported by 2D engine, cleared as U32 */
+   if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
+      buf[0] = float3_to_rgb9e5(val->float32);
+      return;
+   }
+
+   enum a6xx_2d_ifmt ifmt = tu6_rb_fmt_to_ifmt(tu6_get_native_format(format)->rb);
+
+   assert(desc && desc->layout == VK_FORMAT_LAYOUT_PLAIN);
+
+   for (unsigned i = 0; i < desc->nr_channels; i++) {
+      const struct vk_format_channel_description *ch = &desc->channel[i];
+
+      switch (ifmt) {
+      case R2D_INT32:
+      case R2D_INT16:
+      case R2D_INT8:
+      case R2D_FLOAT32:
+         buf[i] = val->uint32[i];
+         break;
+      case R2D_FLOAT16:
+         buf[i] = util_float_to_half(val->float32[i]);
+         break;
+      case R2D_UNORM8: {
+         float linear = val->float32[i];
+         if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB && i < 3)
+            linear = util_format_linear_to_srgb_float(val->float32[i]);
+
+         if (ch->type == VK_FORMAT_TYPE_SIGNED)
+            buf[i] = tu_pack_float32_for_snorm(linear, 8);
+         else
+            buf[i] = tu_pack_float32_for_unorm(linear, 8);
+      } break;
+      default:
+         unreachable("unexpected ifmt");
+         break;
+      }
+   }
+}
+
+void
+tu_2d_clear_zs(const VkClearDepthStencilValue *val, VkFormat format, uint32_t buf[4])
+{
+   switch (format) {
+   case VK_FORMAT_X8_D24_UNORM_PACK32:
+   case VK_FORMAT_D24_UNORM_S8_UINT:
+      buf[0] = tu_pack_float32_for_unorm(val->depth, 24);
+      buf[1] = buf[0] >> 8;
+      buf[2] = buf[0] >> 16;
+      buf[3] = val->stencil;
+      return;
+   case VK_FORMAT_D16_UNORM:
+   case VK_FORMAT_D32_SFLOAT:
+      buf[0] = fui(val->depth);
+      return;
+   case VK_FORMAT_S8_UINT:
+      buf[0] = val->stencil;
+      return;
+   default:
+      unreachable("unexpected zs format");
+      break;
+   }
+}
+
 static void
 tu_physical_device_get_format_properties(
    struct tu_physical_device *physical_device,
index d624eef88b4fc20af7378912c73ed96b44277bdc..ec45e011a12528fbbfe0926dd99338c7a22da3ba 100644 (file)
@@ -64,7 +64,7 @@ tu_blit_image(struct tu_cmd_buffer *cmdbuf,
       .rotation = rotate[mirror_y][mirror_x],
    };
 
-   tu_blit(cmdbuf, &blt, false);
+   tu_blit(cmdbuf, &blt);
 }
 
 void
index 2beed54335986f35bdb3942532ac4cdf9b9d4faf..fdfd0ec36e80f4f4067922a3919ec326fa8a7dbc 100644 (file)
  */
 
 #include "tu_private.h"
+#include "tu_blit.h"
+
+static void
+clear_image(struct tu_cmd_buffer *cmdbuf,
+            struct tu_image *image,
+            uint32_t clear_value[4],
+            const VkImageSubresourceRange *range)
+{
+   uint32_t level_count = tu_get_levelCount(image, range);
+   uint32_t layer_count = tu_get_layerCount(image, range);
+
+   if (image->type == VK_IMAGE_TYPE_3D) {
+      assert(layer_count == 1);
+      assert(range->baseArrayLayer == 0);
+   }
+
+   for (unsigned j = 0; j < level_count; j++) {
+      if (image->type == VK_IMAGE_TYPE_3D)
+         layer_count = u_minify(image->extent.depth, range->baseMipLevel + j);
+
+      tu_blit(cmdbuf, &(struct tu_blit) {
+         .dst = tu_blit_surf_whole(image, range->baseMipLevel + j, range->baseArrayLayer),
+         .src = tu_blit_surf_whole(image, range->baseMipLevel + j, range->baseArrayLayer),
+         .layers = layer_count,
+         .clear_value = {clear_value[0], clear_value[1], clear_value[2], clear_value[3]},
+         .type = TU_BLIT_CLEAR,
+      });
+   }
+}
 
 void
 tu_CmdClearColorImage(VkCommandBuffer commandBuffer,
@@ -31,6 +60,16 @@ tu_CmdClearColorImage(VkCommandBuffer commandBuffer,
                       uint32_t rangeCount,
                       const VkImageSubresourceRange *pRanges)
 {
+   TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
+   TU_FROM_HANDLE(tu_image, image, image_h);
+   uint32_t clear_value[4] = {};
+
+   tu_2d_clear_color(pColor, image->vk_format, clear_value);
+
+   tu_bo_list_add(&cmdbuf->bo_list, image->bo, MSM_SUBMIT_BO_WRITE);
+
+   for (unsigned i = 0; i < rangeCount; i++)
+      clear_image(cmdbuf, image, clear_value, pRanges + i);
 }
 
 void
@@ -41,6 +80,16 @@ tu_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
                              uint32_t rangeCount,
                              const VkImageSubresourceRange *pRanges)
 {
+   TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, commandBuffer);
+   TU_FROM_HANDLE(tu_image, image, image_h);
+   uint32_t clear_value[4] = {};
+
+   tu_2d_clear_zs(pDepthStencil, image->vk_format, clear_value);
+
+   tu_bo_list_add(&cmdbuf->bo_list, image->bo, MSM_SUBMIT_BO_WRITE);
+
+   for (unsigned i = 0; i < rangeCount; i++)
+      clear_image(cmdbuf, image, clear_value, pRanges + i);
 }
 
 void
@@ -50,4 +99,5 @@ tu_CmdClearAttachments(VkCommandBuffer commandBuffer,
                        uint32_t rectCount,
                        const VkClearRect *pRects)
 {
+   tu_finishme("CmdClearAttachments");
 }
index 616151b751fb6fb384c8b360a8f344ccbdabc631..dedfab2559bebe9d7949fe5c2c788021fb32328a 100644 (file)
@@ -233,7 +233,8 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmdbuf,
       .dst = tu_blit_surf_ext(dst_image, info->imageSubresource, info->imageOffset, info->imageExtent),
       .src = tu_blit_buffer(src_buffer, dst_image->vk_format, info),
       .layers = MAX2(info->imageExtent.depth, info->imageSubresource.layerCount),
-   }, true);
+      .type = TU_BLIT_COPY,
+   });
 }
 
 static void
@@ -246,7 +247,8 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmdbuf,
       .dst = tu_blit_buffer(dst_buffer, src_image->vk_format, info),
       .src = tu_blit_surf_ext(src_image, info->imageSubresource, info->imageOffset, info->imageExtent),
       .layers = MAX2(info->imageExtent.depth, info->imageSubresource.layerCount),
-   }, true);
+      .type = TU_BLIT_COPY,
+   });
 }
 
 static void
@@ -267,7 +269,8 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmdbuf,
       .dst = tu_blit_surf_ext(dst_image, info->dstSubresource, info->dstOffset, info->extent),
       .src = tu_blit_surf_ext(src_image, info->srcSubresource, info->srcOffset, info->extent),
       .layers = info->extent.depth,
-   }, true);
+      .type = TU_BLIT_COPY,
+   });
 }
 
 void
index 74ce766aacf65d9547983dcab45348378fe5f89e..b879f84bdd5ef9319dcf8e9943fcdc21a67379be 100644 (file)
@@ -43,7 +43,7 @@ tu_resolve_image(struct tu_cmd_buffer *cmdbuf,
       .dst = tu_blit_surf_ext(dst_image, info->dstSubresource, info->dstOffset, info->extent),
       .src = tu_blit_surf_ext(src_image, info->srcSubresource, info->srcOffset, info->extent),
       .layers = MAX2(info->extent.depth, info->dstSubresource.layerCount)
-   }, false);
+   });
 }
 
 void
index ef306c92aeaad6606f28697f2a080d861e6c2fa7..958fc169aaa297595455cc4fcd35e4ba060e560d 100644 (file)
@@ -1229,6 +1229,13 @@ void
 tu_pack_clear_value(const VkClearValue *val,
                     VkFormat format,
                     uint32_t buf[4]);
+
+void
+tu_2d_clear_color(const VkClearColorValue *val, VkFormat format, uint32_t buf[4]);
+
+void
+tu_2d_clear_zs(const VkClearDepthStencilValue *val, VkFormat format, uint32_t buf[4]);
+
 enum a6xx_2d_ifmt tu6_rb_fmt_to_ifmt(enum a6xx_color_fmt fmt);
 enum a6xx_depth_format tu6_pipe2depth(VkFormat format);
 
index 6baa8c3861f7ed7c7f1cfdc6ece16ae6895386a6..9e85ff5d258b4845b346ca2bb25c69301db658ca 100644 (file)
@@ -123,7 +123,7 @@ VK_FORMAT_R64G64B64_SFLOAT           , plain, 1, 1, f64 , f64 , f64 ,     , xyz1
 VK_FORMAT_R64G64B64A64_UINT          , plain, 1, 1, up64, up64, up64, up64, xyzw, rgb
 VK_FORMAT_R64G64B64A64_SINT          , plain, 1, 1, sp64, sp64, sp64, sp64, xyzw, rgb
 VK_FORMAT_R64G64B64A64_SFLOAT        , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
-VK_FORMAT_B10G11R11_UFLOAT_PACK32    , other, 1, 1, x32 ,     ,     ,     , xyz1, rgb
+VK_FORMAT_B10G11R11_UFLOAT_PACK32    , plain, 1, 1, f10 , f11 , f11 ,     , xyz1, rgb
 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32     , other, 1, 1, x32 ,     ,     ,     , xyz1, rgb
 VK_FORMAT_D16_UNORM                  , plain, 1, 1, un16,     ,     ,     , x___, zs
 VK_FORMAT_X8_D24_UNORM_PACK32        , plain, 1, 1, un24, x8  ,     ,     , x___, zs