From 67258a44d2c7d77509e0983e5925940bcee277cf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 26 Nov 2019 10:56:57 -0800 Subject: [PATCH] tu: Move our image layout into a freedreno_layout struct. This lets us start using some of the fdl_* helpers and have more obviously matching code between gallium and turnip. We can't yet use the fdl_* UBWC helpers, since the gallium driver doesn't do UBWC mipmaps (which I'm working on in another branch). Reviewed-by: Kristian H. Kristensen --- src/freedreno/fdl/freedreno_layout.h | 6 ++- src/freedreno/vulkan/tu_blit.h | 2 +- src/freedreno/vulkan/tu_cmd_buffer.c | 13 ++++--- src/freedreno/vulkan/tu_image.c | 74 +++++++++++++++++++----------------- src/freedreno/vulkan/tu_private.h | 26 +++++-------- src/freedreno/vulkan/tu_wsi.c | 4 +- 6 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/freedreno/fdl/freedreno_layout.h b/src/freedreno/fdl/freedreno_layout.h index 4704a5f..714a6fc 100644 --- a/src/freedreno/fdl/freedreno_layout.h +++ b/src/freedreno/fdl/freedreno_layout.h @@ -68,6 +68,8 @@ * texture. */ +#define FDL_MAX_MIP_LEVELS 14 + struct fdl_slice { uint32_t offset; /* offset of first layer in slice */ uint32_t pitch; @@ -80,8 +82,8 @@ struct fdl_slice { * to derive this. */ struct fdl_layout { - struct fdl_slice slices[MAX_MIP_LEVELS]; - struct fdl_slice ubwc_slices[MAX_MIP_LEVELS]; + struct fdl_slice slices[FDL_MAX_MIP_LEVELS]; + struct fdl_slice ubwc_slices[FDL_MAX_MIP_LEVELS]; uint32_t layer_size; bool layer_first : 1; /* see above description */ diff --git a/src/freedreno/vulkan/tu_blit.h b/src/freedreno/vulkan/tu_blit.h index 9897aae..acceb1a 100644 --- a/src/freedreno/vulkan/tu_blit.h +++ b/src/freedreno/vulkan/tu_blit.h @@ -60,7 +60,7 @@ tu_blit_surf(struct tu_image *image, return (struct tu_blit_surf) { .fmt = image->vk_format, .tile_mode = tu6_get_image_tile_mode(image, subres.mipLevel), - .tiled = image->tile_mode != TILE6_LINEAR, + .tiled = image->layout.tile_mode != TILE6_LINEAR, .va = tu_image_base(image, subres.mipLevel, layer), .pitch = tu_image_stride(image, subres.mipLevel), .layer_size = tu_layer_size(image, subres.mipLevel), diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index fe460f1..e30bc36f 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -403,7 +403,7 @@ tu6_emit_flag_buffer(struct tu_cs *cs, const struct tu_image_view *iview) uint64_t va = tu_image_ubwc_base(iview->image, iview->base_mip, iview->base_layer); uint32_t pitch = tu_image_ubwc_pitch(iview->image, iview->base_mip); uint32_t size = tu_image_ubwc_size(iview->image, iview->base_mip); - if (iview->image->ubwc_size) { + if (iview->image->layout.ubwc_size) { tu_cs_emit_qw(cs, va); tu_cs_emit(cs, A6XX_RB_DEPTH_FLAG_BUFFER_PITCH_PITCH(pitch) | A6XX_RB_DEPTH_FLAG_BUFFER_PITCH_ARRAY_PITCH(size >> 2)); @@ -453,7 +453,7 @@ tu6_emit_zs(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6); tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_INFO_DEPTH_FORMAT(fmt)); tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_PITCH(tu_image_stride(iview->image, iview->base_mip))); - tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(iview->image->layer_size)); + tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH(iview->image->layout.layer_size)); tu_cs_emit_qw(cs, tu_image_base(iview->image, iview->base_mip, iview->base_layer)); tu_cs_emit(cs, tiling->gmem_offsets[subpass->color_count]); @@ -508,7 +508,7 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd, struct tu_cs *cs) A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) | A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(format->swap)); tu_cs_emit(cs, A6XX_RB_MRT_PITCH(tu_image_stride(iview->image, iview->base_mip))); - tu_cs_emit(cs, A6XX_RB_MRT_ARRAY_PITCH(iview->image->layer_size)); + tu_cs_emit(cs, A6XX_RB_MRT_ARRAY_PITCH(iview->image->layout.layer_size)); tu_cs_emit_qw(cs, tu_image_base(iview->image, iview->base_mip, iview->base_layer)); tu_cs_emit( cs, tiling->gmem_offsets[i]); /* RB_MRT[i].BASE_GMEM */ @@ -649,12 +649,13 @@ tu6_emit_blit_info(struct tu_cmd_buffer *cmd, A6XX_RB_BLIT_DST_INFO_SAMPLES(tu_msaa_samples(iview->image->samples)) | A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format->rb) | A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(format->swap) | - COND(iview->image->ubwc_size, A6XX_RB_BLIT_DST_INFO_FLAGS)); + COND(iview->image->layout.ubwc_size, + A6XX_RB_BLIT_DST_INFO_FLAGS)); tu_cs_emit_qw(cs, tu_image_base(iview->image, iview->base_mip, iview->base_layer)); tu_cs_emit(cs, A6XX_RB_BLIT_DST_PITCH(tu_image_stride(iview->image, iview->base_mip))); - tu_cs_emit(cs, A6XX_RB_BLIT_DST_ARRAY_PITCH(iview->image->layer_size)); + tu_cs_emit(cs, A6XX_RB_BLIT_DST_ARRAY_PITCH(iview->image->layout.layer_size)); - if (iview->image->ubwc_size) { + if (iview->image->layout.ubwc_size) { tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_FLAG_DST_LO, 3); tu6_emit_flag_buffer(cs, iview); } diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 3d6ca56..307ae2c 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -44,10 +44,10 @@ image_level_linear(struct tu_image *image, int level, bool ubwc) enum a6xx_tile_mode tu6_get_image_tile_mode(struct tu_image *image, int level) { - if (image_level_linear(image, level, !!image->ubwc_size)) + if (image_level_linear(image, level, !!image->layout.ubwc_size)) return TILE6_LINEAR; else - return image->tile_mode; + return image->layout.tile_mode; } /* indexed by cpp, including msaa 2x and 4x: */ @@ -90,15 +90,18 @@ setup_slices(struct tu_image *image, enum util_format_layout layout = vk_format_description(format)->layout; uint32_t layer_size = 0; uint32_t ubwc_size = 0; - int ta = image->cpp; + int ta = image->layout.cpp; + + if (image->type != VK_IMAGE_TYPE_3D) + image->layout.layer_first = true; /* The r8g8 format seems to not play by the normal tiling rules: */ - if (image->cpp == 2 && vk_format_get_nr_components(format) == 2) + if (image->layout.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]; - struct tu_image_level *ubwc_slice = &image->ubwc_levels[level]; + struct fdl_slice *slice = &image->layout.slices[level]; + struct fdl_slice *ubwc_slice = &image->layout.ubwc_slices[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); @@ -106,7 +109,8 @@ setup_slices(struct tu_image *image, uint32_t blocks; uint32_t pitchalign; - if (image->tile_mode && !image_level_linear(image, level, ubwc_enabled)) { + if (image->layout.tile_mode && + !image_level_linear(image, level, ubwc_enabled)) { /* 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); @@ -144,16 +148,16 @@ setup_slices(struct tu_image *image, * range gets into range, we stop reducing it. */ if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D) { - if (level < 1 || image->levels[level - 1].size > 0xf000) { - slice->size = align(blocks * image->cpp, 4096); + if (level < 1 || image->layout.slices[level - 1].size0 > 0xf000) { + slice->size0 = align(blocks * image->layout.cpp, 4096); } else { - slice->size = image->levels[level - 1].size; + slice->size0 = image->layout.slices[level - 1].size0; } } else { - slice->size = blocks * image->cpp; + slice->size0 = blocks * image->layout.cpp; } - layer_size += slice->size * depth; + layer_size += slice->size0 * depth; if (ubwc_enabled) { /* with UBWC every level is aligned to 4K */ layer_size = align(layer_size, 4096); @@ -177,14 +181,14 @@ setup_slices(struct tu_image *image, ubwc_size += align(meta_pitch * meta_height, UBWC_PLANE_SIZE_ALIGNMENT); } } - image->layer_size = align(layer_size, 4096); + image->layout.layer_size = align(layer_size, 4096); VkDeviceSize offset = ubwc_size * pCreateInfo->arrayLayers; for (unsigned level = 0; level < pCreateInfo->mipLevels; level++) - image->levels[level].offset += offset; + image->layout.slices[level].offset += offset; - image->size = offset + image->layer_size * pCreateInfo->arrayLayers; - image->ubwc_size = ubwc_size; + image->size = offset + image->layout.layer_size * pCreateInfo->arrayLayers; + image->layout.ubwc_size = ubwc_size; } VkResult @@ -220,7 +224,7 @@ tu_image_create(VkDevice _device, 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->layout.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) { @@ -237,14 +241,14 @@ tu_image_create(VkDevice _device, vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL; - image->tile_mode = TILE6_3; + image->layout.tile_mode = TILE6_3; bool ubwc_enabled = true; /* disable tiling when linear is requested and for compressed formats */ if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR || modifier == DRM_FORMAT_MOD_LINEAR || vk_format_is_compressed(image->vk_format)) { - image->tile_mode = TILE6_LINEAR; + image->layout.tile_mode = TILE6_LINEAR; ubwc_enabled = false; } @@ -264,8 +268,8 @@ tu_image_create(VkDevice _device, ubwc_enabled = false; } - if (!tile_alignment[image->cpp].ubwc_blockwidth) { - tu_finishme("UBWC for cpp=%d", image->cpp); + if (!tile_alignment[image->layout.cpp].ubwc_blockwidth) { + tu_finishme("UBWC for cpp=%d", image->layout.cpp); ubwc_enabled = false; } @@ -401,7 +405,7 @@ tu_image_view_init(struct tu_image_view *iview, COND(vk_format_is_srgb(iview->vk_format), A6XX_TEX_CONST_0_SRGB) | A6XX_TEX_CONST_0_FMT(fmt->tex) | A6XX_TEX_CONST_0_SAMPLES(tu_msaa_samples(image->samples)) | - A6XX_TEX_CONST_0_SWAP(image->tile_mode ? WZYX : fmt->swap) | + A6XX_TEX_CONST_0_SWAP(image->layout.tile_mode ? WZYX : fmt->swap) | tu6_texswiz(&pCreateInfo->components, vk_format_description(iview->vk_format)->swizzle) | A6XX_TEX_CONST_0_MIPLVLS(iview->level_count - 1); iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height); @@ -413,9 +417,9 @@ tu_image_view_init(struct tu_image_view *iview, iview->descriptor[4] = base_addr; iview->descriptor[5] = base_addr >> 32; - if (image->ubwc_size) { - uint32_t block_width = tile_alignment[image->cpp].ubwc_blockwidth; - uint32_t block_height = tile_alignment[image->cpp].ubwc_blockheight; + if (image->layout.ubwc_size) { + uint32_t block_width = tile_alignment[image->layout.cpp].ubwc_blockwidth; + uint32_t block_height = tile_alignment[image->layout.cpp].ubwc_blockheight; iview->descriptor[3] |= A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_TILE_ALL; iview->descriptor[7] = ubwc_addr; @@ -431,7 +435,7 @@ tu_image_view_init(struct tu_image_view *iview, iview->descriptor[5] |= A6XX_TEX_CONST_5_DEPTH(iview->layer_count); } else { iview->descriptor[3] |= - A6XX_TEX_CONST_3_MIN_LAYERSZ(image->levels[image->level_count - 1].size); + A6XX_TEX_CONST_3_MIN_LAYERSZ(image->layout.slices[image->level_count - 1].size0); iview->descriptor[5] |= A6XX_TEX_CONST_5_DEPTH(u_minify(image->extent.depth, iview->base_mip)); } @@ -506,18 +510,18 @@ tu_GetImageSubresourceLayout(VkDevice _device, { TU_FROM_HANDLE(tu_image, image, _image); - const uint32_t layer_offset = image->layer_size * pSubresource->arrayLayer; - const struct tu_image_level *level = - image->levels + pSubresource->mipLevel; + const struct fdl_slice *slice = image->layout.slices + pSubresource->mipLevel; - pLayout->offset = layer_offset + level->offset; - pLayout->size = level->size; + pLayout->offset = fdl_surface_offset(&image->layout, + pSubresource->mipLevel, + pSubresource->arrayLayer); + pLayout->size = slice->size0; pLayout->rowPitch = - level->pitch * vk_format_get_blocksize(image->vk_format); - pLayout->arrayPitch = image->layer_size; - pLayout->depthPitch = level->size; + slice->pitch * vk_format_get_blocksize(image->vk_format); + pLayout->arrayPitch = image->layout.layer_size; + pLayout->depthPitch = slice->size0; - if (image->ubwc_size) { + if (image->layout.ubwc_size) { /* UBWC starts at offset 0 */ pLayout->offset = 0; /* UBWC scanout won't match what the kernel wants if we have levels/layers */ diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 72048e6..a555dbe 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -58,6 +58,7 @@ #include "adreno_common.xml.h" #include "adreno_pm4.xml.h" #include "a6xx.xml.h" +#include "fdl/freedreno_layout.h" #include "tu_descriptor_set.h" #include "tu_extensions.h" @@ -1295,13 +1296,7 @@ struct tu_image VkDeviceSize size; uint32_t alignment; - /* memory layout */ - VkDeviceSize layer_size; - struct tu_image_level levels[15]; - unsigned tile_mode; - unsigned cpp; - struct tu_image_level ubwc_levels[15]; - uint32_t ubwc_size; + struct fdl_layout layout; unsigned queue_family_mask; bool exclusive; @@ -1341,40 +1336,39 @@ tu_get_levelCount(const struct tu_image *image, static inline VkDeviceSize tu_layer_size(struct tu_image *image, int level) { - if (image->type == VK_IMAGE_TYPE_3D) - return image->levels[level].size; - return image->layer_size; + return fdl_layer_stride(&image->layout, level); } static inline uint32_t tu_image_stride(struct tu_image *image, int level) { - return image->levels[level].pitch * image->cpp; + return image->layout.slices[level].pitch * image->layout.cpp; } static inline uint64_t tu_image_base(struct tu_image *image, int level, int layer) { - return image->bo->iova + image->bo_offset + image->levels[level].offset + - layer * tu_layer_size(image, level); + return image->bo->iova + image->bo_offset + + fdl_surface_offset(&image->layout, level, layer); } static inline VkDeviceSize tu_image_ubwc_size(struct tu_image *image, int level) { - return image->ubwc_size; + return image->layout.ubwc_size; } static inline uint32_t tu_image_ubwc_pitch(struct tu_image *image, int level) { - return image->ubwc_levels[level].pitch; + return image->layout.ubwc_slices[level].pitch; } static inline uint64_t tu_image_ubwc_base(struct tu_image *image, int level, int layer) { - return image->bo->iova + image->bo_offset + image->ubwc_levels[level].offset + + return image->bo->iova + image->bo_offset + + image->layout.ubwc_slices[level].offset + layer * tu_image_ubwc_size(image, level); } diff --git a/src/freedreno/vulkan/tu_wsi.c b/src/freedreno/vulkan/tu_wsi.c index c80e489..7117f67 100644 --- a/src/freedreno/vulkan/tu_wsi.c +++ b/src/freedreno/vulkan/tu_wsi.c @@ -40,10 +40,10 @@ tu_wsi_image_get_modifier(VkImage _image) { TU_FROM_HANDLE(tu_image, image, _image); - if (!image->tile_mode) + if (!image->layout.tile_mode) return DRM_FORMAT_MOD_LINEAR; - if (image->ubwc_size) + if (image->layout.ubwc_size) return DRM_FORMAT_MOD_QCOM_COMPRESSED; /* TODO invent a modifier for tiled but not UBWC buffers: */ -- 2.7.4