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:
committed by
Marge Bot
parent
300d0e2b80
commit
2437808671
@@ -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,
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user