diff --git a/src/freedreno/vulkan/tu_clear_blit.cc b/src/freedreno/vulkan/tu_clear_blit.cc index ebbd159f988..4754c2c9b9c 100644 --- a/src/freedreno/vulkan/tu_clear_blit.cc +++ b/src/freedreno/vulkan/tu_clear_blit.cc @@ -2096,8 +2096,9 @@ tu6_clear_lrz(struct tu_cmd_buffer *cmd, ops->dst_buffer(cs, PIPE_FORMAT_Z16_UNORM, image->iova + image->lrz_offset, image->lrz_pitch * 2, PIPE_FORMAT_Z16_UNORM); + uint32_t lrz_height = image->lrz_height * image->vk.array_layers; ops->coords(cmd, cs, (VkOffset2D) {}, blt_no_coord, - (VkExtent2D) { image->lrz_pitch, image->lrz_height }); + (VkExtent2D) { image->lrz_pitch, lrz_height }); ops->run(cmd, cs); ops->teardown(cmd, cs); diff --git a/src/freedreno/vulkan/tu_image.cc b/src/freedreno/vulkan/tu_image.cc index 866fd3e16d1..8c28078193d 100644 --- a/src/freedreno/vulkan/tu_image.cc +++ b/src/freedreno/vulkan/tu_image.cc @@ -596,13 +596,15 @@ tu_image_update_layout(struct tu_device *device, struct tu_image *image, image->lrz_height = lrz_height; image->lrz_pitch = lrz_pitch; image->lrz_offset = image->total_size; - unsigned lrz_size = lrz_pitch * lrz_height * sizeof(uint16_t); + image->lrz_layer_size = lrz_pitch * lrz_height * sizeof(uint16_t); + uint32_t lrz_size = image->lrz_layer_size * image->vk.array_layers; unsigned nblocksx = DIV_ROUND_UP(DIV_ROUND_UP(width, 8), 16); unsigned nblocksy = DIV_ROUND_UP(DIV_ROUND_UP(height, 8), 4); /* Fast-clear buffer is 1bit/block */ - unsigned lrz_fc_size = DIV_ROUND_UP(nblocksx * nblocksy, 8); + unsigned lrz_fc_size = + DIV_ROUND_UP(nblocksx * nblocksy, 8) * image->vk.array_layers; /* Fast-clear buffer cannot be larger than 512 bytes on A6XX and 1024 bytes on A7XX (HW limitation) */ image->has_lrz_fc = @@ -615,6 +617,13 @@ tu_image_update_layout(struct tu_device *device, struct tu_image *image, lrz_size += sizeof(fd_lrzfc_layout); } + uint32_t lrz_clear_height = lrz_height * image->vk.array_layers; + if (((lrz_clear_height - 1) >> 14) > 0) { + /* For simplicity bail out if LRZ cannot be cleared in one go. */ + image->lrz_height = 0; + lrz_size = 0; + } + image->total_size += lrz_size; } else { image->lrz_height = 0; diff --git a/src/freedreno/vulkan/tu_image.h b/src/freedreno/vulkan/tu_image.h index 78fb8481206..569039cf2ab 100644 --- a/src/freedreno/vulkan/tu_image.h +++ b/src/freedreno/vulkan/tu_image.h @@ -44,6 +44,7 @@ struct tu_image uint32_t lrz_height; uint32_t lrz_pitch; uint32_t lrz_offset; + uint32_t lrz_layer_size; uint32_t lrz_fc_offset; bool has_lrz_fc; diff --git a/src/freedreno/vulkan/tu_lrz.cc b/src/freedreno/vulkan/tu_lrz.cc index 1a7cc7a7f47..053b44a2ba2 100644 --- a/src/freedreno/vulkan/tu_lrz.cc +++ b/src/freedreno/vulkan/tu_lrz.cc @@ -79,10 +79,11 @@ tu6_emit_lrz_buffer(struct tu_cs *cs, struct tu_image *depth_image) if (!depth_image->lrz_fc_offset) lrz_fc_iova = 0; - tu_cs_emit_regs(cs, - A6XX_GRAS_LRZ_BUFFER_BASE(.qword = lrz_iova), - A6XX_GRAS_LRZ_BUFFER_PITCH(.pitch = depth_image->lrz_pitch), - A6XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE(.qword = lrz_fc_iova)); + tu_cs_emit_regs( + cs, A6XX_GRAS_LRZ_BUFFER_BASE(.qword = lrz_iova), + A6XX_GRAS_LRZ_BUFFER_PITCH(.pitch = depth_image->lrz_pitch, + .array_pitch = depth_image->lrz_layer_size), + A6XX_GRAS_LRZ_FAST_CLEAR_BUFFER_BASE(.qword = lrz_fc_iova)); if (CHIP >= A7XX) { tu_cs_emit_regs(cs, A7XX_GRAS_LRZ_DEPTH_BUFFER_INFO(