X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Ffreedreno%2Fvulkan%2Ftu_image.c;h=6f2dc0421d064013b339d0ff90814e88e04e63a8;hb=76f711d09d2f8c9b3bcd9f8c1694e553a486ac1f;hp=9087806fe47fd06f53421f6f755fcb96a3a6397f;hpb=8fff8afb1343c934b4212ee1b0517dd2045a5c8c;p=mesa.git diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 9087806fe47..6f2dc0421d0 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -43,6 +43,7 @@ tu6_plane_count(VkFormat format) 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; @@ -58,13 +59,15 @@ tu6_plane_format(VkFormat format, uint32_t plane) 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: @@ -73,6 +76,8 @@ tu6_plane_index(VkImageAspectFlags aspect_mask) 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; } } @@ -194,6 +199,23 @@ tu_image_create(VkDevice _device, 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); @@ -211,6 +233,10 @@ tu_image_create(VkDevice _device, 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; } @@ -300,7 +326,8 @@ static uint32_t 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, @@ -321,10 +348,16 @@ tu6_texswiz(const VkComponentMapping *comps, 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; @@ -348,6 +381,14 @@ tu_cs_image_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32_t la 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) { @@ -365,7 +406,8 @@ tu_cs_image_flag_ref(struct tu_cs *cs, const struct tu_image_view *iview, uint32 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; @@ -385,7 +427,7 @@ tu_image_view_init(struct tu_image_view *iview, 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"); @@ -395,7 +437,8 @@ tu_image_view_init(struct tu_image_view *iview, 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); @@ -422,6 +465,9 @@ tu_image_view_init(struct tu_image_view *iview, 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 @@ -430,12 +476,18 @@ tu_image_view_init(struct tu_image_view *iview, 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 ? */ } @@ -445,7 +497,7 @@ tu_image_view_init(struct tu_image_view *iview, 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] = @@ -551,6 +603,9 @@ tu_image_view_init(struct tu_image_view *iview, 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)); @@ -589,6 +644,7 @@ tu_image_view_init(struct tu_image_view *iview, .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), @@ -607,6 +663,14 @@ tu_image_view_init(struct tu_image_view *iview, .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 @@ -685,7 +749,7 @@ tu_GetImageSubresourceLayout(VkDevice _device, 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 = @@ -740,7 +804,7 @@ tu_CreateImageView(VkDevice _device, 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); @@ -797,7 +861,7 @@ tu_buffer_view_init(struct tu_buffer_view *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)) |