default:
return 1;
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
return 2;
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
return 3;
return plane ? VK_FORMAT_R8G8_UNORM : VK_FORMAT_R8_UNORM;
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
return VK_FORMAT_R8_UNORM;
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return plane ? VK_FORMAT_S8_UINT : VK_FORMAT_D32_SFLOAT;
default:
return format;
}
}
static uint32_t
-tu6_plane_index(VkImageAspectFlags aspect_mask)
+tu6_plane_index(VkFormat format, VkImageAspectFlags aspect_mask)
{
switch (aspect_mask) {
default:
return 1;
case VK_IMAGE_ASPECT_PLANE_2_BIT:
return 2;
+ case VK_IMAGE_ASPECT_STENCIL_BIT:
+ return format == VK_FORMAT_D32_SFLOAT_S8_UINT;
}
}
if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT)
ubwc_enabled = false;
+ /* Disable UBWC for D24S8 on A630 in some cases
+ *
+ * VK_IMAGE_ASPECT_STENCIL_BIT image view requires to be able to sample
+ * from the stencil component as UINT, however no format allows this
+ * on a630 (the special FMT6_Z24_UINT_S8_UINT format is missing)
+ *
+ * It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible
+ *
+ * Additionally, the special AS_R8G8B8A8 format is broken without UBWC,
+ * so we have to fallback to 8_8_8_8_UNORM when UBWC is disabled
+ */
+ if (device->physical_device->limited_z24s8 &&
+ image->vk_format == VK_FORMAT_D24_UNORM_S8_UINT &&
+ (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
+ ubwc_enabled = false;
+ }
+
/* expect UBWC enabled if we asked for it */
assert(modifier != DRM_FORMAT_MOD_QCOM_COMPRESSED || ubwc_enabled);
width0 = (width0 + 1) >> 1;
height0 = (height0 + 1) >> 1;
break;
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ /* no UBWC for separate stencil */
+ ubwc_enabled = false;
+ break;
default:
break;
}
tu6_texswiz(const VkComponentMapping *comps,
const struct tu_sampler_ycbcr_conversion *conversion,
VkFormat format,
- VkImageAspectFlagBits aspect_mask)
+ VkImageAspectFlagBits aspect_mask,
+ bool limited_z24s8)
{
unsigned char swiz[4] = {
A6XX_TEX_X, A6XX_TEX_Y, A6XX_TEX_Z, A6XX_TEX_W,
swiz[3] = A6XX_TEX_ONE;
break;
case VK_FORMAT_D24_UNORM_S8_UINT:
- /* for D24S8, stencil is in the 2nd channel of the hardware format */
if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
- swiz[0] = A6XX_TEX_Y;
- swiz[1] = A6XX_TEX_ZERO;
+ if (limited_z24s8) {
+ /* using FMT6_8_8_8_8_UINT */
+ swiz[0] = A6XX_TEX_W;
+ swiz[1] = A6XX_TEX_ZERO;
+ } else {
+ /* using FMT6_Z24_UINT_S8_UINT */
+ swiz[0] = A6XX_TEX_Y;
+ swiz[1] = A6XX_TEX_ZERO;
+ }
}
default:
break;
tu_cs_emit_qw(cs, iview->base_addr + iview->layer_size * layer);
}
+void
+tu_cs_image_stencil_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer)
+{
+ tu_cs_emit(cs, iview->stencil_PITCH);
+ tu_cs_emit(cs, iview->stencil_layer_size >> 6);
+ tu_cs_emit_qw(cs, iview->stencil_base_addr + iview->stencil_layer_size * layer);
+}
+
void
tu_cs_image_ref_2d(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t layer, bool src)
{
void
tu_image_view_init(struct tu_image_view *iview,
- const VkImageViewCreateInfo *pCreateInfo)
+ const VkImageViewCreateInfo *pCreateInfo,
+ bool limited_z24s8)
{
TU_FROM_HANDLE(tu_image, image, pCreateInfo->image);
const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
break;
case VK_IMAGE_TYPE_3D:
assert(range->baseArrayLayer + tu_get_layerCount(image, range) <=
- tu_minify(image->extent.depth, range->baseMipLevel));
+ u_minify(image->extent.depth, range->baseMipLevel));
break;
default:
unreachable("bad VkImageType");
memset(iview->descriptor, 0, sizeof(iview->descriptor));
- struct fdl_layout *layout = &image->layout[tu6_plane_index(aspect_mask)];
+ struct fdl_layout *layout =
+ &image->layout[tu6_plane_index(image->vk_format, aspect_mask)];
uint32_t width = u_minify(layout->width0, range->baseMipLevel);
uint32_t height = u_minify(layout->height0, range->baseMipLevel);
uint32_t ubwc_pitch = fdl_ubwc_pitch(layout, range->baseMipLevel);
uint32_t layer_size = fdl_layer_stride(layout, range->baseMipLevel);
+ if (aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT)
+ format = tu6_plane_format(format, tu6_plane_index(format, aspect_mask));
+
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
bool ubwc_enabled = fdl_ubwc_enabled(layout, range->baseMipLevel);
+ bool is_d24s8 = (format == VK_FORMAT_D24_UNORM_S8_UINT ||
+ format == VK_FORMAT_X8_D24_UNORM_PACK32);
+
+ if (is_d24s8 && ubwc_enabled)
+ fmt.fmt = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
+
unsigned fmt_tex = fmt.fmt;
- if (fmt_tex == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8) {
+ if (is_d24s8) {
if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
fmt_tex = FMT6_Z24_UNORM_S8_UINT;
if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
- fmt_tex = FMT6_S8Z24_UINT;
+ fmt_tex = limited_z24s8 ? FMT6_8_8_8_8_UINT : FMT6_Z24_UINT_S8_UINT;
/* TODO: also use this format with storage descriptor ? */
}
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, conversion, format, aspect_mask) |
+ tu6_texswiz(&pCreateInfo->components, conversion, format, aspect_mask, limited_z24s8) |
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] =
struct tu_native_format cfmt = tu6_format_color(format, layout->tile_mode);
cfmt.tile_mode = fmt.tile_mode;
+ if (is_d24s8 && ubwc_enabled)
+ cfmt.fmt = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
+
if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
memset(iview->storage_descriptor, 0, sizeof(iview->storage_descriptor));
.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_format = cfmt.fmt,
.color_swap = cfmt.swap,
.flags = ubwc_enabled).value;
+
+ if (image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
+ layout = &image->layout[1];
+ iview->stencil_base_addr = image->bo->iova + image->bo_offset +
+ fdl_surface_offset(layout, range->baseMipLevel, range->baseArrayLayer);
+ iview->stencil_layer_size = fdl_layer_stride(layout, range->baseMipLevel);
+ iview->stencil_PITCH = A6XX_RB_STENCIL_BUFFER_PITCH(fdl_pitch(layout, range->baseMipLevel)).value;
+ }
}
VkResult
TU_FROM_HANDLE(tu_image, image, _image);
struct fdl_layout *layout =
- &image->layout[tu6_plane_index(pSubresource->aspectMask)];
+ &image->layout[tu6_plane_index(image->vk_format, pSubresource->aspectMask)];
const struct fdl_slice *slice = layout->slices + pSubresource->mipLevel;
pLayout->offset =
if (view == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
- tu_image_view_init(view, pCreateInfo);
+ tu_image_view_init(view, pCreateInfo, device->physical_device->limited_z24s8);
*pView = tu_image_view_to_handle(view);
A6XX_TEX_CONST_0_SWAP(fmt.swap) |
A6XX_TEX_CONST_0_FMT(fmt.fmt) |
A6XX_TEX_CONST_0_MIPLVLS(0) |
- tu6_texswiz(&components, NULL, vfmt, VK_IMAGE_ASPECT_COLOR_BIT);
+ tu6_texswiz(&components, NULL, vfmt, VK_IMAGE_ASPECT_COLOR_BIT, false);
COND(vk_format_is_srgb(vfmt), A6XX_TEX_CONST_0_SRGB);
view->descriptor[1] =
A6XX_TEX_CONST_1_WIDTH(elements & MASK(15)) |