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 <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4581>
This commit is contained in:
Jonathan Marek
2020-04-07 21:12:45 -04:00
committed by Marge Bot
parent 300d0e2b80
commit 2437808671
4 changed files with 322 additions and 379 deletions
+148 -191
View File
@@ -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_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_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_FLAG_BUFFER(0), 3);
tu_cs_image_flag_ref(cs, iview, layer);
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_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,
@@ -1118,6 +1050,47 @@ coords(const struct blit_ops *ops,
ops->coords(cs, (const VkOffset2D*) dst, (const VkOffset2D*) src, (const VkExtent2D*) extent);
}
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,
@@ -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,
+16 -34
View File
@@ -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;
}
+125 -52
View File
@@ -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,
@@ -231,13 +216,37 @@ 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);
+33 -102
View File
@@ -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