diff options
author | Jonathan Marek <[email protected]> | 2020-04-07 21:12:45 -0400 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-04-16 14:04:18 +0000 |
commit | 24378086710bae7eb7b6d0cb4ec0e718d36ba32c (patch) | |
tree | 4da3050b8bc6c47fa2f4fa0b87498acdbaaaff9f /src | |
parent | 300d0e2b809644262481c30cf205761abd2234bb (diff) |
turnip: image_view rework
Instead of exposing various layout functions, move image-related logic
into tu_image.c and have the image_view pre-fill relevant register values.
This changes the clear/blit code to use image_view.
This will make it much easier to deal with aspect masks, in particular for
planar formats and D32_S8.
Signed-off-by: Jonathan Marek <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4581>
Diffstat (limited to 'src')
-rw-r--r-- | src/freedreno/vulkan/tu_clear_blit.c | 339 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_cmd_buffer.c | 50 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_image.c | 177 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_private.h | 135 |
4 files changed, 322 insertions, 379 deletions
diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c index 35469bf363b..c07e7e0bd0e 100644 --- a/src/freedreno/vulkan/tu_clear_blit.c +++ b/src/freedreno/vulkan/tu_clear_blit.c @@ -344,46 +344,18 @@ r2d_clear_value(struct tu_cs *cs, VkFormat format, const VkClearValue *val) static void r2d_src(struct tu_cmd_buffer *cmd, struct tu_cs *cs, - struct tu_image *image, - VkFormat vk_format, - uint32_t level, + const struct tu_image_view *iview, uint32_t layer, - bool linear_filter, - bool stencil_read) + bool linear_filter) { - struct tu_native_format format = tu6_format_image_src(image, vk_format, level); + tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 5); + tu_cs_emit(cs, iview->SP_PS_2D_SRC_INFO | + COND(linear_filter, A6XX_SP_PS_2D_SRC_INFO_FILTER)); + tu_cs_emit(cs, iview->SP_PS_2D_SRC_SIZE); + tu_cs_image_ref_2d(cs, iview, layer, true); - /* stencil readout path fails with UBWC enabled (why?) */ - assert(!stencil_read || !image->layout.ubwc_layer_size); - - if (stencil_read) - format.swap = XYZW; - - tu_cs_emit_regs(cs, - A6XX_SP_PS_2D_SRC_INFO( - .color_format = format.fmt, - .tile_mode = format.tile_mode, - .color_swap = format.swap, - .flags = image->layout.ubwc_layer_size != 0, - .srgb = vk_format_is_srgb(vk_format), - .samples = tu_msaa_samples(image->samples), - .filter = linear_filter, - .samples_average = image->samples > 1 && - !vk_format_is_int(vk_format) && - !vk_format_is_depth_or_stencil(vk_format), - .unk20 = 1, - .unk22 = 1), - A6XX_SP_PS_2D_SRC_SIZE( - .width = tu_minify(image->extent.width, level), - .height = tu_minify(image->extent.height, level)), - A6XX_SP_PS_2D_SRC(tu_image_base_ref(image, level, layer)), - A6XX_SP_PS_2D_SRC_PITCH(.pitch = tu_image_pitch(image, level))); - - if (image->layout.ubwc_layer_size) { - tu_cs_emit_regs(cs, - A6XX_SP_PS_2D_SRC_FLAGS(tu_image_ubwc_base_ref(image, level, layer)), - A6XX_SP_PS_2D_SRC_FLAGS_PITCH(.pitch = tu_image_ubwc_pitch(image, level))); - } + tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 3); + tu_cs_image_flag_ref(cs, iview, layer); } static void @@ -409,31 +381,16 @@ r2d_src_buffer(struct tu_cmd_buffer *cmd, } static void -r2d_dst(struct tu_cs *cs, - struct tu_image *image, - VkFormat vk_format, - uint32_t level, - uint32_t layer) +r2d_dst(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) { - struct tu_native_format format = tu6_format_image(image, vk_format, level); + assert(iview->image->samples == 1); - assert(image->samples == 1); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_INFO, 4); + tu_cs_emit(cs, iview->RB_2D_DST_INFO); + tu_cs_image_ref_2d(cs, iview, layer, false); - tu_cs_emit_regs(cs, - A6XX_RB_2D_DST_INFO( - .color_format = format.fmt, - .tile_mode = format.tile_mode, - .color_swap = format.swap, - .flags = image->layout.ubwc_layer_size != 0, - .srgb = vk_format_is_srgb(image->vk_format)), - A6XX_RB_2D_DST(tu_image_base_ref(image, level, layer)), - A6XX_RB_2D_DST_SIZE(.pitch = tu_image_pitch(image, level))); - - if (image->layout.ubwc_layer_size) { - tu_cs_emit_regs(cs, - A6XX_RB_2D_DST_FLAGS(tu_image_ubwc_base_ref(image, level, layer)), - A6XX_RB_2D_DST_FLAGS_PITCH(.pitch = tu_image_ubwc_pitch(image, level))); - } + tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_FLAGS_LO, 3); + tu_cs_image_flag_ref(cs, iview, layer); } static void @@ -806,7 +763,12 @@ r3d_clear_value(struct tu_cs *cs, VkFormat format, const VkClearValue *val) } static void -r3d_src_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t *tex_const, bool linear_filter) +r3d_src_common(struct tu_cmd_buffer *cmd, + struct tu_cs *cs, + const uint32_t *tex_const, + uint32_t offset_base, + uint32_t offset_ubwc, + bool linear_filter) { struct ts_cs_memory texture = { }; VkResult result = tu_cs_alloc(&cmd->sub_cs, @@ -816,6 +778,12 @@ r3d_src_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t *tex_const, memcpy(texture.map, tex_const, A6XX_TEX_CONST_DWORDS * 4); + /* patch addresses for layer offset */ + *(uint64_t*) (texture.map + 4) += offset_base; + uint64_t ubwc_addr = (texture.map[7] | (uint64_t) texture.map[8] << 32) + offset_ubwc; + texture.map[7] = ubwc_addr; + texture.map[8] = ubwc_addr >> 32; + texture.map[A6XX_TEX_CONST_DWORDS + 0] = A6XX_TEX_SAMP_0_XY_MAG(linear_filter ? A6XX_TEX_LINEAR : A6XX_TEX_NEAREST) | A6XX_TEX_SAMP_0_XY_MIN(linear_filter ? A6XX_TEX_LINEAR : A6XX_TEX_NEAREST) | @@ -858,31 +826,14 @@ r3d_src_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, uint32_t *tex_const, static void r3d_src(struct tu_cmd_buffer *cmd, struct tu_cs *cs, - struct tu_image *image, - VkFormat format, - uint32_t level, + const struct tu_image_view *iview, uint32_t layer, - bool linear_filter, - bool stencil_read) + bool linear_filter) { - struct tu_image_view view; - - /* use tu_image_view_init to fill out a view descriptor */ - tu_image_view_init(&view, cmd->device, &(VkImageViewCreateInfo) { - .image = tu_image_to_handle(image), - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = format, - /* image_to_buffer from d24s8 with stencil aspect mask writes out to r8 */ - .components.r = stencil_read ? VK_COMPONENT_SWIZZLE_A : VK_COMPONENT_SWIZZLE_R, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = level, - .levelCount = 1, - .baseArrayLayer = layer, - .layerCount = 1, - }, - }); - r3d_src_common(cmd, cs, view.descriptor, linear_filter); + r3d_src_common(cmd, cs, iview->descriptor, + iview->layer_size * layer, + iview->ubwc_layer_size * layer, + linear_filter); } static void @@ -916,35 +867,23 @@ r3d_src_buffer(struct tu_cmd_buffer *cmd, for (uint32_t i = 6; i < A6XX_TEX_CONST_DWORDS; i++) desc[i] = 0; - r3d_src_common(cmd, cs, desc, false); + r3d_src_common(cmd, cs, desc, 0, 0, false); } static void -r3d_dst(struct tu_cs *cs, - struct tu_image *image, - VkFormat vk_format, - uint32_t level, - uint32_t layer) +r3d_dst(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) { - tu6_emit_msaa(cs, image->samples); /* TODO: move to setup */ + tu6_emit_msaa(cs, iview->image->samples); /* TODO: move to setup */ - struct tu_native_format format = tu6_format_image(image, vk_format, level); - - tu_cs_emit_regs(cs, - A6XX_RB_MRT_BUF_INFO(0, - .color_tile_mode = format.tile_mode, - .color_format = format.fmt, - .color_swap = format.swap), - A6XX_RB_MRT_PITCH(0, tu_image_pitch(image, level)), - A6XX_RB_MRT_ARRAY_PITCH(0, image->layout.layer_size), - A6XX_RB_MRT_BASE(0, tu_image_base_ref(image, level, layer)), - A6XX_RB_MRT_BASE_GMEM(0, 0)); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(0), 6); + tu_cs_emit(cs, iview->RB_MRT_BUF_INFO); + tu_cs_image_ref(cs, iview, layer); + tu_cs_emit(cs, 0); - tu_cs_emit_regs(cs, - A6XX_RB_MRT_FLAG_BUFFER_ADDR(0, tu_image_ubwc_base_ref(image, level, layer)), - A6XX_RB_MRT_FLAG_BUFFER_PITCH(0, .pitch = tu_image_ubwc_pitch(image, level))); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER(0), 3); + tu_cs_image_flag_ref(cs, iview, layer); - tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL(.flag_mrts = image->layout.ubwc_layer_size != 0)); + tu_cs_emit_regs(cs, A6XX_RB_RENDER_CNTL(.flag_mrts = iview->ubwc_enabled)); } static void @@ -1060,21 +999,14 @@ struct blit_ops { void (*src)( struct tu_cmd_buffer *cmd, struct tu_cs *cs, - struct tu_image *image, - VkFormat format, - uint32_t level, + const struct tu_image_view *iview, uint32_t layer, - bool linear_filter, - bool stencil_read); + bool linear_filter); void (*src_buffer)(struct tu_cmd_buffer *cmd, struct tu_cs *cs, VkFormat vk_format, uint64_t va, uint32_t pitch, uint32_t width, uint32_t height); - void (*dst)(struct tu_cs *cs, - struct tu_image *image, - VkFormat format, - uint32_t level, - uint32_t layer); + void (*dst)(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); void (*dst_buffer)(struct tu_cs *cs, VkFormat vk_format, uint64_t va, uint32_t pitch); void (*setup)(struct tu_cmd_buffer *cmd, struct tu_cs *cs, @@ -1119,6 +1051,47 @@ coords(const struct blit_ops *ops, } static void +tu_image_view_blit2(struct tu_image_view *iview, + struct tu_image *image, + VkFormat format, + const VkImageSubresourceLayers *subres, + uint32_t layer, + bool stencil_read) +{ + VkImageAspectFlags aspect_mask = subres->aspectMask; + + /* always use the AS_R8G8B8A8 format for these */ + if (format == VK_FORMAT_D24_UNORM_S8_UINT || + format == VK_FORMAT_X8_D24_UNORM_PACK32) { + aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT; + } + + tu_image_view_init(iview, &(VkImageViewCreateInfo) { + .image = tu_image_to_handle(image), + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = format, + /* image_to_buffer from d24s8 with stencil aspect mask writes out to r8 */ + .components.r = stencil_read ? VK_COMPONENT_SWIZZLE_A : VK_COMPONENT_SWIZZLE_R, + .subresourceRange = { + .aspectMask = aspect_mask, + .baseMipLevel = subres->mipLevel, + .levelCount = 1, + .baseArrayLayer = subres->baseArrayLayer + layer, + .layerCount = 1, + }, + }); +} + +static void +tu_image_view_blit(struct tu_image_view *iview, + struct tu_image *image, + const VkImageSubresourceLayers *subres, + uint32_t layer) +{ + tu_image_view_blit2(iview, image, image->vk_format, subres, layer, false); +} + +static void tu6_blit_image(struct tu_cmd_buffer *cmd, struct tu_image *src_image, struct tu_image *dst_image, @@ -1197,14 +1170,13 @@ tu6_blit_image(struct tu_cmd_buffer *cmd, A6XX_GRAS_2D_SRC_BR_Y(.y = MAX2(info->srcOffsets[0].y, info->srcOffsets[1].y) - 1)); } + struct tu_image_view dst, src; + tu_image_view_blit(&dst, dst_image, &info->dstSubresource, info->dstOffsets[0].z); + tu_image_view_blit(&src, src_image, &info->srcSubresource, info->srcOffsets[0].z); + for (uint32_t i = 0; i < layers; i++) { - ops->src(cmd, cs, src_image, src_image->vk_format, - info->srcSubresource.mipLevel, - info->srcSubresource.baseArrayLayer + info->srcOffsets[0].z + i, - filter == VK_FILTER_LINEAR, false); - ops->dst(cs, dst_image, dst_image->vk_format, - info->dstSubresource.mipLevel, - info->dstSubresource.baseArrayLayer + info->dstOffsets[0].z + i); + ops->dst(cs, &dst, i); + ops->src(cmd, cs, &src, i, filter == VK_FILTER_LINEAR); ops->run(cmd, cs); } } @@ -1283,6 +1255,7 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd, VkFormat dst_format = dst_image->vk_format; VkFormat src_format = dst_image->vk_format; const struct blit_ops *ops = &r2d_ops; + uint8_t mask = 0xf; if (dst_image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) { @@ -1304,7 +1277,7 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd, (info->bufferRowLength ?: extent.width) * vk_format_get_blocksize(src_format); uint32_t layer_size = (info->bufferImageHeight ?: extent.height) * pitch; - if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(dst_format)) { + if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(src_format)) { assert(src_format == dst_format); copy_compressed(dst_format, &offset, &extent, &pitch, &layer_size); src_format = dst_format = copy_format(dst_format); @@ -1316,10 +1289,11 @@ tu_copy_buffer_to_image(struct tu_cmd_buffer *cmd, ops->setup(cmd, cs, dst_format, ROTATE_0, false, mask); + struct tu_image_view dst; + tu_image_view_blit2(&dst, dst_image, dst_format, &info->imageSubresource, offset.z, false); + for (uint32_t i = 0; i < layers; i++) { - ops->dst(cs, dst_image, dst_format, - info->imageSubresource.mipLevel, - info->imageSubresource.baseArrayLayer + info->imageOffset.z + i); + ops->dst(cs, &dst, i); uint64_t src_va = tu_buffer_iova(src_buffer) + info->bufferOffset + layer_size * i; if ((src_va & 63) || (pitch & 63)) { @@ -1383,7 +1357,7 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd, uint32_t pitch = (info->bufferRowLength ?: extent.width) * vk_format_get_blocksize(dst_format); uint32_t layer_size = (info->bufferImageHeight ?: extent.height) * pitch; - if (src_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(src_format)) { + if (dst_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 || vk_format_is_compressed(dst_format)) { assert(src_format == dst_format); copy_compressed(dst_format, &offset, &extent, &pitch, &layer_size); src_format = dst_format = copy_format(dst_format); @@ -1395,11 +1369,11 @@ tu_copy_image_to_buffer(struct tu_cmd_buffer *cmd, ops->setup(cmd, cs, dst_format, ROTATE_0, false, 0xf); + struct tu_image_view src; + tu_image_view_blit2(&src, src_image, src_format, &info->imageSubresource, offset.z, stencil_read); + for (uint32_t i = 0; i < layers; i++) { - ops->src(cmd, cs, src_image, src_format, - info->imageSubresource.mipLevel, - info->imageSubresource.baseArrayLayer + info->imageOffset.z + i, - false, stencil_read); + ops->src(cmd, cs, &src, i, false); uint64_t dst_va = tu_buffer_iova(dst_buffer) + info->bufferOffset + layer_size * i; if ((dst_va & 63) || (pitch & 63)) { @@ -1489,14 +1463,13 @@ tu_copy_image_to_image(struct tu_cmd_buffer *cmd, ops->setup(cmd, cs, format, ROTATE_0, false, mask); coords(ops, cs, &dst_offset, &src_offset, &extent); + struct tu_image_view dst, src; + tu_image_view_blit2(&dst, dst_image, format, &info->dstSubresource, dst_offset.z, false); + tu_image_view_blit2(&src, src_image, format, &info->srcSubresource, src_offset.z, false); + for (uint32_t i = 0; i < info->extent.depth; i++) { - ops->src(cmd, cs, src_image, format, - info->srcSubresource.mipLevel, - info->srcSubresource.baseArrayLayer + info->srcOffset.z + i, - false, false); - ops->dst(cs, dst_image, format, - info->dstSubresource.mipLevel, - info->dstSubresource.baseArrayLayer + info->dstOffset.z + i); + ops->src(cmd, cs, &src, i, false); + ops->dst(cs, &dst, i); ops->run(cmd, cs); } } @@ -1661,14 +1634,13 @@ tu_CmdResolveImage(VkCommandBuffer commandBuffer, coords(ops, cs, &info->dstOffset, &info->srcOffset, &info->extent); + struct tu_image_view dst, src; + tu_image_view_blit(&dst, dst_image, &info->dstSubresource, info->dstOffset.z); + tu_image_view_blit(&src, src_image, &info->srcSubresource, info->srcOffset.z); + for (uint32_t i = 0; i < layers; i++) { - ops->src(cmd, cs, src_image, src_image->vk_format, - info->srcSubresource.mipLevel, - info->srcSubresource.baseArrayLayer + info->srcOffset.z + i, - false, false); - ops->dst(cs, dst_image, dst_image->vk_format, - info->dstSubresource.mipLevel, - info->dstSubresource.baseArrayLayer + info->dstOffset.z + i); + ops->src(cmd, cs, &src, i, false); + ops->dst(cs, &dst, i); ops->run(cmd, cs); } } @@ -1687,19 +1659,14 @@ tu_resolve_sysmem(struct tu_cmd_buffer *cmd, tu_bo_list_add(&cmd->bo_list, src->image->bo, MSM_SUBMIT_BO_READ); tu_bo_list_add(&cmd->bo_list, dst->image->bo, MSM_SUBMIT_BO_WRITE); - assert(src->vk_format == dst->vk_format); + assert(src->image->vk_format == dst->image->vk_format); - ops->setup(cmd, cs, dst->vk_format, ROTATE_0, false, 0xf); + ops->setup(cmd, cs, dst->image->vk_format, ROTATE_0, false, 0xf); ops->coords(cs, &rect->offset, &rect->offset, &rect->extent); for (uint32_t i = 0; i < layers; i++) { - ops->src(cmd, cs, src->image, src->vk_format, - src->base_mip, - src->base_layer + i, - false, false); - ops->dst(cs, dst->image, dst->vk_format, - dst->base_mip, - dst->base_layer + i); + ops->src(cmd, cs, src, i, false); + ops->dst(cs, dst, i); ops->run(cmd, cs); } } @@ -1745,8 +1712,16 @@ clear_image(struct tu_cmd_buffer *cmd, u_minify(image->extent.height, range->baseMipLevel + j) }); + struct tu_image_view dst; + tu_image_view_blit2(&dst, image, format, &(VkImageSubresourceLayers) { + .aspectMask = range->aspectMask, + .mipLevel = range->baseMipLevel + j, + .baseArrayLayer = range->baseArrayLayer, + .layerCount = 1, + }, 0, false); + for (uint32_t i = 0; i < layer_count; i++) { - ops->dst(cs, image, format, range->baseMipLevel + j, range->baseArrayLayer + i); + ops->dst(cs, &dst, i); ops->run(cmd, cs); } } @@ -1828,14 +1803,13 @@ tu_clear_sysmem_attachments_2d(struct tu_cmd_buffer *cmd, const struct tu_image_view *iview = cmd->state.framebuffer->attachments[a].attachment; - ops->setup(cmd, cs, iview->vk_format, ROTATE_0, true, mask); - ops->clear_value(cs, iview->vk_format, &attachments[j].clearValue); + ops->setup(cmd, cs, iview->image->vk_format, ROTATE_0, true, mask); + ops->clear_value(cs, iview->image->vk_format, &attachments[j].clearValue); for (uint32_t i = 0; i < rect_count; i++) { ops->coords(cs, &rects[i].rect.offset, NULL, &rects[i].rect.extent); for (uint32_t layer = 0; layer < rects[i].layerCount; layer++) { - ops->dst(cs, iview->image, iview->vk_format, iview->base_mip, - iview->base_layer + rects[i].baseArrayLayer + layer); + ops->dst(cs, iview, rects[i].baseArrayLayer + layer); ops->run(cmd, cs); } } @@ -2152,7 +2126,7 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd, if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) mask = 0xf; - if (iview->vk_format == VK_FORMAT_D24_UNORM_S8_UINT) { + if (attachment->format == VK_FORMAT_D24_UNORM_S8_UINT) { mask &= 0x7; if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) mask |= 0x8; @@ -2166,12 +2140,12 @@ tu_clear_sysmem_attachment(struct tu_cmd_buffer *cmd, if (attachment->samples > 1) ops = &r3d_ops; - ops->setup(cmd, cs, iview->vk_format, ROTATE_0, true, mask); + ops->setup(cmd, cs, attachment->format, ROTATE_0, true, mask); ops->coords(cs, &info->renderArea.offset, NULL, &info->renderArea.extent); - ops->clear_value(cs, iview->vk_format, &info->pClearValues[a]); + ops->clear_value(cs, attachment->format, &info->pClearValues[a]); for (uint32_t i = 0; i < fb->layers; i++) { - ops->dst(cs, iview->image, iview->vk_format, iview->base_mip, iview->base_layer + i); + ops->dst(cs, iview, i); ops->run(cmd, cs); } } @@ -2182,8 +2156,6 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd, uint32_t a, const VkRenderPassBeginInfo *info) { - const struct tu_framebuffer *fb = cmd->state.framebuffer; - const struct tu_image_view *iview = fb->attachments[a].attachment; const struct tu_render_pass_attachment *attachment = &cmd->state.pass->attachments[a]; unsigned clear_mask = 0; @@ -2195,7 +2167,7 @@ tu_clear_gmem_attachment(struct tu_cmd_buffer *cmd, if (attachment->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) clear_mask = 0xf; - if (vk_format_has_stencil(iview->vk_format)) { + if (vk_format_has_stencil(attachment->format)) { clear_mask &= 0x7; if (attachment->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) clear_mask |= 0x8; @@ -2216,9 +2188,6 @@ tu_emit_blit(struct tu_cmd_buffer *cmd, struct tu_render_pass_attachment *attachment, bool resolve) { - const struct tu_native_format format = - tu6_format_image(iview->image, iview->vk_format, iview->base_mip); - tu_cs_emit_regs(cs, A6XX_RB_MSAA_CNTL(tu_msaa_samples(attachment->samples))); @@ -2226,24 +2195,14 @@ tu_emit_blit(struct tu_cmd_buffer *cmd, .unk0 = !resolve, .gmem = !resolve, /* "integer" bit disables msaa resolve averaging */ - .integer = vk_format_is_int(iview->vk_format))); + .integer = vk_format_is_int(attachment->format))); - tu_cs_emit_regs(cs, - A6XX_RB_BLIT_DST_INFO( - .tile_mode = format.tile_mode, - .samples = tu_msaa_samples(iview->image->samples), - .color_format = format.fmt, - .color_swap = format.swap, - .flags = iview->image->layout.ubwc_layer_size != 0), - A6XX_RB_BLIT_DST(tu_image_view_base_ref(iview)), - A6XX_RB_BLIT_DST_PITCH(tu_image_stride(iview->image, iview->base_mip)), - A6XX_RB_BLIT_DST_ARRAY_PITCH(iview->image->layout.layer_size)); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_DST_INFO, 4); + tu_cs_emit(cs, iview->RB_BLIT_DST_INFO); + tu_cs_image_ref_2d(cs, iview, 0, false); - if (iview->image->layout.ubwc_layer_size) { - tu_cs_emit_regs(cs, - A6XX_RB_BLIT_FLAG_DST(tu_image_view_ubwc_base_ref(iview)), - A6XX_RB_BLIT_FLAG_DST_PITCH(tu_image_view_ubwc_pitches(iview))); - } + tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLIT_FLAG_DST_LO, 3); + tu_cs_image_flag_ref(cs, iview, 0); tu_cs_emit_regs(cs, A6XX_RB_BLIT_BASE_GMEM(attachment->gmem_offset)); @@ -2336,16 +2295,14 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd, * required y padding in the layout (except for the last level) */ bool need_y2_align = - y2 != iview->extent.height || - (tu6_get_image_tile_mode(iview->image, iview->base_mip) == TILE6_LINEAR && - iview->base_mip != iview->image->level_count - 1); + y2 != iview->extent.height || iview->need_y2_align; bool unaligned = x1 % GMEM_ALIGN_W || (x2 % GMEM_ALIGN_W && x2 != iview->extent.width) || y1 % GMEM_ALIGN_H || (y2 % GMEM_ALIGN_H && need_y2_align); /* use fast path when render area is aligned, except for unsupported resolve cases */ - if (!unaligned && (a == gmem_a || blit_can_resolve(iview->vk_format))) { + if (!unaligned && (a == gmem_a || blit_can_resolve(dst->format))) { tu_emit_blit(cmd, cs, iview, src, true); return; } @@ -2358,8 +2315,8 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd, return; } - r2d_setup_common(cmd, cs, iview->vk_format, ROTATE_0, false, 0xf, true); - r2d_dst(cs, iview->image, iview->vk_format, iview->base_mip, iview->base_layer); + r2d_setup_common(cmd, cs, dst->format, ROTATE_0, false, 0xf, true); + r2d_dst(cs, iview, 0); r2d_coords(cs, &render_area->offset, &render_area->offset, &render_area->extent); tu_cs_emit_regs(cs, diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 179abefbdd2..d89a553fd9f 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -387,22 +387,18 @@ tu6_emit_zs(struct tu_cmd_buffer *cmd, } const struct tu_image_view *iview = fb->attachments[a].attachment; - enum a6xx_depth_format fmt = tu6_pipe2depth(iview->vk_format); + enum a6xx_depth_format fmt = tu6_pipe2depth(cmd->state.pass->attachments[a].format); - tu_cs_emit_regs(cs, - A6XX_RB_DEPTH_BUFFER_INFO(.depth_format = fmt), - A6XX_RB_DEPTH_BUFFER_PITCH(tu_image_stride(iview->image, iview->base_mip)), - A6XX_RB_DEPTH_BUFFER_ARRAY_PITCH( - fdl_layer_stride(&iview->image->layout, iview->base_mip)), - A6XX_RB_DEPTH_BUFFER_BASE(tu_image_view_base_ref(iview)), - A6XX_RB_DEPTH_BUFFER_BASE_GMEM(cmd->state.pass->attachments[a].gmem_offset)); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_BUFFER_INFO, 6); + tu_cs_emit(cs, A6XX_RB_DEPTH_BUFFER_INFO(.depth_format = fmt).value); + tu_cs_image_ref(cs, iview, 0); + tu_cs_emit(cs, cmd->state.pass->attachments[a].gmem_offset); tu_cs_emit_regs(cs, A6XX_GRAS_SU_DEPTH_BUFFER_INFO(.depth_format = fmt)); - tu_cs_emit_regs(cs, - A6XX_RB_DEPTH_FLAG_BUFFER_BASE(tu_image_view_ubwc_base_ref(iview)), - A6XX_RB_DEPTH_FLAG_BUFFER_PITCH(tu_image_view_ubwc_pitches(iview))); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_DEPTH_FLAG_BUFFER_BASE_LO, 3); + tu_cs_image_flag_ref(cs, iview, 0); tu_cs_emit_regs(cs, A6XX_GRAS_LRZ_BUFFER_BASE(0), @@ -429,30 +425,16 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd, const struct tu_image_view *iview = fb->attachments[a].attachment; - - struct tu_native_format format = - tu6_format_image(iview->image, iview->vk_format, iview->base_mip); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_BUF_INFO(i), 6); + tu_cs_emit(cs, iview->RB_MRT_BUF_INFO); + tu_cs_image_ref(cs, iview, 0); + tu_cs_emit(cs, cmd->state.pass->attachments[a].gmem_offset); tu_cs_emit_regs(cs, - A6XX_RB_MRT_BUF_INFO(i, - .color_tile_mode = format.tile_mode, - .color_format = format.fmt, - .color_swap = format.swap), - A6XX_RB_MRT_PITCH(i, tu_image_stride(iview->image, iview->base_mip)), - A6XX_RB_MRT_ARRAY_PITCH(i, - fdl_layer_stride(&iview->image->layout, iview->base_mip)), - A6XX_RB_MRT_BASE(i, tu_image_view_base_ref(iview)), - A6XX_RB_MRT_BASE_GMEM(i, cmd->state.pass->attachments[a].gmem_offset)); + A6XX_SP_FS_MRT_REG(i, .dword = iview->SP_FS_MRT_REG)); - tu_cs_emit_regs(cs, - A6XX_SP_FS_MRT_REG(i, - .color_format = format.fmt, - .color_sint = vk_format_is_sint(iview->vk_format), - .color_uint = vk_format_is_uint(iview->vk_format))); - - tu_cs_emit_regs(cs, - A6XX_RB_MRT_FLAG_BUFFER_ADDR(i, tu_image_view_ubwc_base_ref(iview)), - A6XX_RB_MRT_FLAG_BUFFER_PITCH(i, tu_image_view_ubwc_pitches(iview))); + tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER_ADDR_LO(i), 3); + tu_cs_image_flag_ref(cs, iview, 0); } tu_cs_emit_regs(cs, @@ -532,7 +514,7 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd, continue; const struct tu_image_view *iview = fb->attachments[a].attachment; - if (iview->image->layout.ubwc_layer_size != 0) + if (iview->ubwc_enabled) mrts_ubwc_enable |= 1 << i; } @@ -541,7 +523,7 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd, const uint32_t a = subpass->depth_stencil_attachment.attachment; if (a != VK_ATTACHMENT_UNUSED) { const struct tu_image_view *iview = fb->attachments[a].attachment; - if (iview->image->layout.ubwc_layer_size != 0) + if (iview->ubwc_enabled) cntl |= A6XX_RB_RENDER_CNTL_FLAG_DEPTH; } diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 4e2b8692605..f53566774a3 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -34,22 +34,7 @@ #include "vk_util.h" #include "drm-uapi/drm_fourcc.h" -static inline bool -image_level_linear(struct tu_image *image, int level, bool ubwc) -{ - unsigned w = u_minify(image->extent.width, level); - /* all levels are tiled/compressed with UBWC */ - return ubwc ? false : (w < 16); -} - -enum a6xx_tile_mode -tu6_get_image_tile_mode(struct tu_image *image, int level) -{ - if (image_level_linear(image, level, !!image->layout.ubwc_layer_size)) - return TILE6_LINEAR; - else - return image->layout.tile_mode; -} +#include "tu_cs.h" VkResult tu_image_create(VkDevice _device, @@ -232,12 +217,36 @@ tu6_tex_type(VkImageViewType type) } void +tu_cs_image_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) +{ + tu_cs_emit(cs, iview->PITCH); + tu_cs_emit(cs, iview->layer_size >> 6); + tu_cs_emit_qw(cs, iview->base_addr + iview->layer_size * layer); +} + +void +tu_cs_image_ref_2d(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer, bool src) +{ + tu_cs_emit_qw(cs, iview->base_addr + iview->layer_size * layer); + /* SP_PS_2D_SRC_PITCH has shifted pitch field */ + tu_cs_emit(cs, iview->PITCH << (src ? 9 : 0)); +} + +void +tu_cs_image_flag_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer) +{ + tu_cs_emit_qw(cs, iview->ubwc_addr + iview->ubwc_layer_size * layer); + tu_cs_emit(cs, iview->FLAG_BUFFER_PITCH); +} + +void tu_image_view_init(struct tu_image_view *iview, - struct tu_device *device, const VkImageViewCreateInfo *pCreateInfo) { TU_FROM_HANDLE(tu_image, image, pCreateInfo->image); const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; + VkFormat format = pCreateInfo->format; + VkImageAspectFlagBits aspect_mask = pCreateInfo->subresourceRange.aspectMask; switch (image->type) { case VK_IMAGE_TYPE_1D: @@ -254,59 +263,61 @@ tu_image_view_init(struct tu_image_view *iview, } iview->image = image; - iview->type = pCreateInfo->viewType; - iview->vk_format = pCreateInfo->format; - iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask; - - iview->base_layer = range->baseArrayLayer; - iview->layer_count = tu_get_layerCount(image, range); - iview->base_mip = range->baseMipLevel; - iview->level_count = tu_get_levelCount(image, range); - - iview->extent.width = u_minify(image->extent.width, iview->base_mip); - iview->extent.height = u_minify(image->extent.height, iview->base_mip); - iview->extent.depth = u_minify(image->extent.depth, iview->base_mip); memset(iview->descriptor, 0, sizeof(iview->descriptor)); - struct tu_native_format fmt = - tu6_format_image_src(image, iview->vk_format, iview->base_mip); - uint64_t base_addr = tu_image_base(image, iview->base_mip, iview->base_layer); - uint64_t ubwc_addr = tu_image_ubwc_base(image, iview->base_mip, iview->base_layer); + struct fdl_layout *layout = &image->layout; - uint32_t pitch = tu_image_pitch(image, iview->base_mip); - uint32_t width = iview->extent.width; - uint32_t height = iview->extent.height; + uint32_t width = u_minify(image->extent.width, range->baseMipLevel); + uint32_t height = u_minify(image->extent.height, range->baseMipLevel); uint32_t depth = pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D ? - iview->extent.depth : iview->layer_count; + u_minify(image->extent.depth, range->baseMipLevel) : tu_get_layerCount(image, range); + + uint64_t base_addr = image->bo->iova + image->bo_offset + + fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer); + uint64_t ubwc_addr = image->bo->iova + image->bo_offset + + fdl_ubwc_offset(layout, range->baseMipLevel, range->baseArrayLayer); + + uint32_t pitch = layout->slices[range->baseMipLevel].pitch * layout->cpp / + util_format_get_blockwidth(layout->format); + uint32_t ubwc_pitch = layout->ubwc_slices[range->baseMipLevel].pitch; + uint32_t layer_size = fdl_layer_stride(layout, range->baseMipLevel); + + struct tu_native_format fmt = tu6_format_texture(format, layout->tile_mode); + /* note: freedreno layout assumes no TILE_ALL bit for non-UBWC + * this means smaller mipmap levels have a linear tile mode + */ + fmt.tile_mode = fdl_tile_mode(layout, range->baseMipLevel); + + bool ubwc_enabled = fdl_ubwc_enabled(layout, range->baseMipLevel); unsigned fmt_tex = fmt.fmt; if (fmt_tex == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8) { - if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) + if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) fmt_tex = FMT6_Z24_UNORM_S8_UINT; - if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) + if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) fmt_tex = FMT6_S8Z24_UINT; /* TODO: also use this format with storage descriptor ? */ } iview->descriptor[0] = A6XX_TEX_CONST_0_TILE_MODE(fmt.tile_mode) | - COND(vk_format_is_srgb(iview->vk_format), A6XX_TEX_CONST_0_SRGB) | + COND(vk_format_is_srgb(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(fmt.swap) | - tu6_texswiz(&pCreateInfo->components, iview->vk_format, iview->aspect_mask) | - A6XX_TEX_CONST_0_MIPLVLS(iview->level_count - 1); + tu6_texswiz(&pCreateInfo->components, format, aspect_mask) | + A6XX_TEX_CONST_0_MIPLVLS(tu_get_levelCount(image, range) - 1); iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height); iview->descriptor[2] = - A6XX_TEX_CONST_2_FETCHSIZE(tu6_fetchsize(iview->vk_format)) | + A6XX_TEX_CONST_2_FETCHSIZE(tu6_fetchsize(format)) | A6XX_TEX_CONST_2_PITCH(pitch) | A6XX_TEX_CONST_2_TYPE(tu6_tex_type(pCreateInfo->viewType)); - iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(tu_layer_size(image, iview->base_mip)); + iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size); iview->descriptor[4] = base_addr; iview->descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(depth); - if (image->layout.ubwc_layer_size) { + if (ubwc_enabled) { uint32_t block_width, block_height; fdl6_get_ubwc_blockwidth(&image->layout, &block_width, &block_height); @@ -314,9 +325,9 @@ tu_image_view_init(struct tu_image_view *iview, iview->descriptor[3] |= A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_TILE_ALL; iview->descriptor[7] = ubwc_addr; iview->descriptor[8] = ubwc_addr >> 32; - iview->descriptor[9] |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(tu_image_ubwc_size(image, iview->base_mip) >> 2); + iview->descriptor[9] |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(layout->ubwc_layer_size >> 2); iview->descriptor[10] |= - A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(tu_image_ubwc_pitch(image, iview->base_mip)) | + A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_pitch) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(width, block_width))) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(height, block_height))); } @@ -326,6 +337,13 @@ tu_image_view_init(struct tu_image_view *iview, A6XX_TEX_CONST_3_MIN_LAYERSZ(image->layout.slices[image->level_count - 1].size0); } + /* only texture descriptor is valid for TEXTURE-only formats */ + if (!(fmt.supported & FMT_COLOR)) + return; + + struct tu_native_format cfmt = tu6_format_color(format, layout->tile_mode); + cfmt.tile_mode = fmt.tile_mode; + if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) { memset(iview->storage_descriptor, 0, sizeof(iview->storage_descriptor)); @@ -338,20 +356,75 @@ tu_image_view_init(struct tu_image_view *iview, iview->storage_descriptor[2] = A6XX_IBO_2_PITCH(pitch) | A6XX_IBO_2_TYPE(tu6_tex_type(pCreateInfo->viewType)); - iview->storage_descriptor[3] = A6XX_IBO_3_ARRAY_PITCH(tu_layer_size(image, iview->base_mip)); + iview->storage_descriptor[3] = A6XX_IBO_3_ARRAY_PITCH(layer_size); iview->storage_descriptor[4] = base_addr; iview->storage_descriptor[5] = (base_addr >> 32) | A6XX_IBO_5_DEPTH(depth); - if (image->layout.ubwc_layer_size) { + if (ubwc_enabled) { iview->storage_descriptor[3] |= A6XX_IBO_3_FLAG | A6XX_IBO_3_UNK27; iview->storage_descriptor[7] |= ubwc_addr; iview->storage_descriptor[8] |= ubwc_addr >> 32; - iview->storage_descriptor[9] = A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(tu_image_ubwc_size(image, iview->base_mip) >> 2); + iview->storage_descriptor[9] = A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(layout->ubwc_layer_size >> 2); iview->storage_descriptor[10] = - A6XX_IBO_10_FLAG_BUFFER_PITCH(tu_image_ubwc_pitch(image, iview->base_mip)); + A6XX_IBO_10_FLAG_BUFFER_PITCH(ubwc_pitch); } } + + iview->base_addr = base_addr; + iview->ubwc_addr = ubwc_addr; + iview->layer_size = layer_size; + iview->ubwc_layer_size = layout->ubwc_layer_size; + + iview->extent.width = width; + iview->extent.height = height; + iview->need_y2_align = + (fmt.tile_mode == TILE6_LINEAR && range->baseMipLevel != image->level_count - 1); + + iview->ubwc_enabled = ubwc_enabled; + + /* note: these have same encoding for MRT and 2D (except 2D PITCH src) */ + iview->PITCH = A6XX_RB_DEPTH_BUFFER_PITCH(pitch).value; + iview->FLAG_BUFFER_PITCH = A6XX_RB_DEPTH_FLAG_BUFFER_PITCH( + .pitch = ubwc_pitch, .array_pitch = layout->ubwc_layer_size >> 2).value; + + iview->RB_MRT_BUF_INFO = A6XX_RB_MRT_BUF_INFO(0, + .color_tile_mode = cfmt.tile_mode, + .color_format = cfmt.fmt, + .color_swap = cfmt.swap).value; + iview->SP_FS_MRT_REG = A6XX_SP_FS_MRT_REG(0, + .color_format = cfmt.fmt, + .color_sint = vk_format_is_sint(format), + .color_uint = vk_format_is_uint(format)).value; + + iview->SP_PS_2D_SRC_INFO = A6XX_SP_PS_2D_SRC_INFO( + .color_format = fmt.fmt, + .tile_mode = fmt.tile_mode, + .color_swap = fmt.swap, + .flags = ubwc_enabled, + .srgb = vk_format_is_srgb(format), + .samples = tu_msaa_samples(image->samples), + .samples_average = image->samples > 1 && + !vk_format_is_int(format) && + !vk_format_is_depth_or_stencil(format), + .unk20 = 1, + .unk22 = 1).value; + iview->SP_PS_2D_SRC_SIZE = + A6XX_SP_PS_2D_SRC_SIZE(.width = width, .height = height).value; + + iview->RB_2D_DST_INFO = A6XX_RB_2D_DST_INFO( + .color_format = cfmt.fmt, + .tile_mode = cfmt.tile_mode, + .color_swap = cfmt.swap, + .flags = ubwc_enabled, + .srgb = vk_format_is_srgb(format)).value; + + iview->RB_BLIT_DST_INFO = A6XX_RB_BLIT_DST_INFO( + .tile_mode = cfmt.tile_mode, + .samples = tu_msaa_samples(iview->image->samples), + .color_format = cfmt.fmt, + .color_swap = cfmt.swap, + .flags = ubwc_enabled).value; } unsigned @@ -485,7 +558,7 @@ tu_CreateImageView(VkDevice _device, if (view == NULL) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - tu_image_view_init(view, device, pCreateInfo); + tu_image_view_init(view, pCreateInfo); *pView = tu_image_view_to_handle(view); diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 1c081a2ddda..4953075375f 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1433,116 +1433,25 @@ tu_get_levelCount(const struct tu_image *image, : range->levelCount; } -static inline VkDeviceSize -tu_layer_size(struct tu_image *image, int level) -{ - return fdl_layer_stride(&image->layout, level); -} - -static inline uint32_t -tu_image_stride(struct tu_image *image, int level) -{ - return image->layout.slices[level].pitch * image->layout.cpp; -} - -/* to get the right pitch for compressed formats */ -static inline uint32_t -tu_image_pitch(struct tu_image *image, int level) -{ - uint32_t stride = tu_image_stride(image, level); - return stride / vk_format_get_blockwidth(image->vk_format); -} - -static inline uint64_t -tu_image_base(struct tu_image *image, int level, int layer) -{ - return image->bo->iova + image->bo_offset + - fdl_surface_offset(&image->layout, level, layer); -} - -#define tu_image_base_ref(image, level, layer) \ - .bo = image->bo, \ - .bo_offset = (image->bo_offset + fdl_surface_offset(&image->layout, \ - level, layer)) - -#define tu_image_view_base_ref(iview) \ - tu_image_base_ref(iview->image, iview->base_mip, iview->base_layer) - -static inline VkDeviceSize -tu_image_ubwc_size(struct tu_image *image, int level) -{ - return image->layout.ubwc_layer_size; -} - -static inline uint32_t -tu_image_ubwc_pitch(struct tu_image *image, int level) -{ - return image->layout.ubwc_slices[level].pitch; -} - -static inline uint64_t -tu_image_ubwc_surface_offset(struct tu_image *image, int level, int layer) -{ - return image->layout.ubwc_slices[level].offset + - layer * tu_image_ubwc_size(image, level); -} - -static inline uint64_t -tu_image_ubwc_base(struct tu_image *image, int level, int layer) -{ - return image->bo->iova + image->bo_offset + - tu_image_ubwc_surface_offset(image, level, layer); -} - -#define tu_image_ubwc_base_ref(image, level, layer) \ - .bo = image->bo, \ - .bo_offset = (image->bo_offset + tu_image_ubwc_surface_offset(image, \ - level, layer)) - -#define tu_image_view_ubwc_base_ref(iview) \ - tu_image_ubwc_base_ref(iview->image, iview->base_mip, iview->base_layer) - -#define tu_image_view_ubwc_pitches(iview) \ - .pitch = tu_image_ubwc_pitch(iview->image, iview->base_mip), \ - .array_pitch = tu_image_ubwc_size(iview->image, iview->base_mip) >> 2 - -enum a6xx_tile_mode -tu6_get_image_tile_mode(struct tu_image *image, int level); enum a3xx_msaa_samples tu_msaa_samples(uint32_t samples); enum a6xx_tex_fetchsize tu6_fetchsize(VkFormat format); -static inline struct tu_native_format -tu6_format_image(struct tu_image *image, VkFormat format, uint32_t level) -{ - struct tu_native_format fmt = - tu6_format_color(format, image->layout.tile_mode); - fmt.tile_mode = tu6_get_image_tile_mode(image, level); - return fmt; -} - -static inline struct tu_native_format -tu6_format_image_src(struct tu_image *image, VkFormat format, uint32_t level) -{ - struct tu_native_format fmt = - tu6_format_texture(format, image->layout.tile_mode); - fmt.tile_mode = tu6_get_image_tile_mode(image, level); - return fmt; -} - struct tu_image_view { struct tu_image *image; /**< VkImageViewCreateInfo::image */ - VkImageViewType type; - VkImageAspectFlags aspect_mask; - VkFormat vk_format; - uint32_t base_layer; - uint32_t layer_count; - uint32_t base_mip; - uint32_t level_count; - VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */ + uint64_t base_addr; + uint64_t ubwc_addr; + uint32_t layer_size; + uint32_t ubwc_layer_size; + + /* used to determine if fast gmem store path can be used */ + VkExtent2D extent; + bool need_y2_align; + + bool ubwc_enabled; uint32_t descriptor[A6XX_TEX_CONST_DWORDS]; @@ -1550,12 +1459,35 @@ struct tu_image_view * This has a few differences for cube maps (e.g. type). */ uint32_t storage_descriptor[A6XX_TEX_CONST_DWORDS]; + + /* pre-filled register values */ + uint32_t PITCH; + uint32_t FLAG_BUFFER_PITCH; + + uint32_t RB_MRT_BUF_INFO; + uint32_t SP_FS_MRT_REG; + + uint32_t SP_PS_2D_SRC_INFO; + uint32_t SP_PS_2D_SRC_SIZE; + + uint32_t RB_2D_DST_INFO; + + uint32_t RB_BLIT_DST_INFO; }; struct tu_sampler { uint32_t descriptor[A6XX_TEX_SAMP_DWORDS]; }; +void +tu_cs_image_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); + +void +tu_cs_image_ref_2d(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer, bool src); + +void +tu_cs_image_flag_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer); + VkResult tu_image_create(VkDevice _device, const VkImageCreateInfo *pCreateInfo, @@ -1572,7 +1504,6 @@ tu_image_from_gralloc(VkDevice device_h, void tu_image_view_init(struct tu_image_view *view, - struct tu_device *device, const VkImageViewCreateInfo *pCreateInfo); struct tu_buffer_view |