From d68acdb3b9cc614f909bae40af60d08dc8fe51ea Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Mon, 18 Nov 2019 18:41:23 -0500 Subject: [PATCH] turnip: implement CmdClearColorImage/CmdClearDepthStencilImage Signed-off-by: Jonathan Marek Reviewed-by: Kristian H. Kristensen --- src/freedreno/vulkan/tu_blit.c | 61 ++++++++++++-------- src/freedreno/vulkan/tu_blit.h | 22 ++++++-- src/freedreno/vulkan/tu_cmd_buffer.c | 6 +- src/freedreno/vulkan/tu_formats.c | 69 +++++++++++++++++++++++ src/freedreno/vulkan/tu_meta_blit.c | 2 +- src/freedreno/vulkan/tu_meta_clear.c | 50 ++++++++++++++++ src/freedreno/vulkan/tu_meta_copy.c | 9 ++- src/freedreno/vulkan/tu_meta_resolve.c | 2 +- src/freedreno/vulkan/tu_private.h | 7 +++ src/freedreno/vulkan/vk_format_layout.csv | 2 +- 10 files changed, 195 insertions(+), 35 deletions(-) diff --git a/src/freedreno/vulkan/tu_blit.c b/src/freedreno/vulkan/tu_blit.c index 15de704a339..6a43a9fbe9b 100644 --- a/src/freedreno/vulkan/tu_blit.c +++ b/src/freedreno/vulkan/tu_blit.c @@ -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; diff --git a/src/freedreno/vulkan/tu_blit.h b/src/freedreno/vulkan/tu_blit.h index 1f4967e845f..b01f62c7685 100644 --- a/src/freedreno/vulkan/tu_blit.h +++ b/src/freedreno/vulkan/tu_blit.h @@ -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 */ diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 200ba002939..f7081e88fc2 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -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); + }); } } diff --git a/src/freedreno/vulkan/tu_formats.c b/src/freedreno/vulkan/tu_formats.c index 6cedf24b61f..35dfe04b124 100644 --- a/src/freedreno/vulkan/tu_formats.c +++ b/src/freedreno/vulkan/tu_formats.c @@ -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, diff --git a/src/freedreno/vulkan/tu_meta_blit.c b/src/freedreno/vulkan/tu_meta_blit.c index d624eef88b4..ec45e011a12 100644 --- a/src/freedreno/vulkan/tu_meta_blit.c +++ b/src/freedreno/vulkan/tu_meta_blit.c @@ -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 diff --git a/src/freedreno/vulkan/tu_meta_clear.c b/src/freedreno/vulkan/tu_meta_clear.c index 2beed543359..fdfd0ec36e8 100644 --- a/src/freedreno/vulkan/tu_meta_clear.c +++ b/src/freedreno/vulkan/tu_meta_clear.c @@ -22,6 +22,35 @@ */ #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"); } diff --git a/src/freedreno/vulkan/tu_meta_copy.c b/src/freedreno/vulkan/tu_meta_copy.c index 616151b751f..dedfab2559b 100644 --- a/src/freedreno/vulkan/tu_meta_copy.c +++ b/src/freedreno/vulkan/tu_meta_copy.c @@ -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 diff --git a/src/freedreno/vulkan/tu_meta_resolve.c b/src/freedreno/vulkan/tu_meta_resolve.c index 74ce766aacf..b879f84bdd5 100644 --- a/src/freedreno/vulkan/tu_meta_resolve.c +++ b/src/freedreno/vulkan/tu_meta_resolve.c @@ -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 diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index ef306c92aea..958fc169aaa 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -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); diff --git a/src/freedreno/vulkan/vk_format_layout.csv b/src/freedreno/vulkan/vk_format_layout.csv index 6baa8c3861f..9e85ff5d258 100644 --- a/src/freedreno/vulkan/vk_format_layout.csv +++ b/src/freedreno/vulkan/vk_format_layout.csv @@ -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 -- 2.30.2