From 010589a699da1637c8985ce34900f5b1cc1d12e5 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Wed, 25 Mar 2020 08:57:12 +0100 Subject: [PATCH] v3dv: fix clearing of 3D images We were not considering that the depth of the image is minified according to its miplevel. For some reason this only seemed to show up for tiled images. Fixes (except a1r5g5b5 format): dEQP-VK.api.image_clearing.core.clear_color_image.3d.optimal.* Part-of: --- src/broadcom/vulkan/v3dv_meta_copy.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c index 79d71ac6c0c..723498f938a 100644 --- a/src/broadcom/vulkan/v3dv_meta_copy.c +++ b/src/broadcom/vulkan/v3dv_meta_copy.c @@ -1019,6 +1019,16 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, hw_clear_value.s = clear_value->depthStencil.stencil; } + uint32_t level_count = range->levelCount == VK_REMAINING_MIP_LEVELS ? + image->levels - range->baseMipLevel : + range->levelCount; + uint32_t min_level = range->baseMipLevel; + uint32_t max_level = range->baseMipLevel + level_count; + + /* For 3D images baseArrayLayer and layerCount must be 0 and 1 respectively. + * Instead, we need to consider the full depth dimension of the image, which + * goes from 0 up to the level's depth extent. + */ uint32_t min_layer; uint32_t max_layer; if (image->type != VK_IMAGE_TYPE_3D) { @@ -1029,17 +1039,12 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, max_layer = range->baseArrayLayer + layer_count; } else { min_layer = 0; - max_layer = image->extent.depth; } - uint32_t level_count = range->levelCount == VK_REMAINING_MIP_LEVELS ? - image->levels - range->baseMipLevel : - range->levelCount; - uint32_t min_level = range->baseMipLevel; - uint32_t max_level = range->baseMipLevel + level_count; - - for (uint32_t layer = min_layer; layer < max_layer; layer++) { - for (uint32_t level = min_level; level < max_level; level++) { + for (uint32_t level = min_level; level < max_level; level++) { + if (image->type == VK_IMAGE_TYPE_3D) + max_layer = u_minify(image->extent.depth, level); + for (uint32_t layer = min_layer; layer < max_layer; layer++) { uint32_t width = u_minify(image->extent.width, level); uint32_t height = u_minify(image->extent.height, level); @@ -1047,6 +1052,7 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer, if (!job) return; + /* We start a a new job for each layer so the frame "depth" is 1 */ v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp); struct framebuffer_data framebuffer;