tu: Fix stencil border color with has_z24uint_s8uint

On a650+ we use the new Z24UINT_S8UINT format to sample the stencil
aspect of D24S8, which returns stencil in the second component and also
uses the second integer component for the border color. However Vulkan
mandates that the first component is used for the stencil border color.
There's no workaround we know of, so we have to fall back to the old
behavior where there is a workaround. If we know the format, we can
fixup the border color ourselves though.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17177>
This commit is contained in:
Connor Abbott 2022-06-22 00:08:49 +02:00 committed by Marge Bot
parent 74d09cac98
commit 8183a728a2
5 changed files with 40 additions and 10 deletions

View File

@ -110,8 +110,10 @@ fdl6_format_swiz(enum pipe_format format, bool has_z24uint_s8uint,
format_swiz[2] = PIPE_SWIZZLE_0;
format_swiz[3] = PIPE_SWIZZLE_1;
} else {
/* using FMT6_Z24_UINT_S8_UINT, which is (d, s, 0, 1), so need to
* swizzle away the d.
/* Using FMT6_Z24_UINT_S8_UINT, which is (d, s, 0, 1), so need to
* swizzle away the d. We don't use this if
* customBorderColorWithoutFormat is enabled, so we can fix up the
* border color, and there's a workaround in freedreno.
*/
format_swiz[0] = PIPE_SWIZZLE_Y;
format_swiz[1] = PIPE_SWIZZLE_0;

View File

@ -1734,12 +1734,15 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
bool custom_border_colors = false;
bool perf_query_pools = false;
bool robust_buffer_access2 = false;
bool border_color_without_format = false;
vk_foreach_struct_const(ext, pCreateInfo->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
const VkPhysicalDeviceCustomBorderColorFeaturesEXT *border_color_features = (const void *)ext;
custom_border_colors = border_color_features->customBorderColors;
border_color_without_format =
border_color_features->customBorderColorWithoutFormat;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {
@ -1962,6 +1965,10 @@ tu_CreateDevice(VkPhysicalDevice physicalDevice,
mtx_init(&device->mutex, mtx_plain);
device->use_z24uint_s8uint =
physical_device->info->a6xx.has_z24uint_s8uint &&
!border_color_without_format;
device->submit_count = 0;
u_trace_context_init(&device->trace_context, device,
tu_trace_create_ts_buffer,
@ -2638,8 +2645,22 @@ tu_init_sampler(struct tu_device *device,
assert(border_color < TU_BORDER_COLOR_COUNT);
BITSET_CLEAR(device->custom_border_color, border_color);
mtx_unlock(&device->mutex);
VkClearColorValue color = custom_border_color->customBorderColor;
if (custom_border_color->format == VK_FORMAT_D24_UNORM_S8_UINT &&
pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT &&
device->use_z24uint_s8uint) {
/* When sampling stencil using the special Z24UINT_S8UINT format, the
* border color is in the second component. Note: if
* customBorderColorWithoutFormat is enabled, we may miss doing this
* here if the format isn't specified, which is why we don't use that
* format.
*/
color.uint32[1] = color.uint32[0];
}
tu6_pack_border_color(device->global_bo->map + gb_offset(bcolor[border_color]),
&custom_border_color->customBorderColor,
&color,
pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
border_color += TU_BORDER_COLOR_BUILTIN;
}

View File

@ -348,7 +348,7 @@ tu_GetPhysicalDeviceFormatProperties2(
/* note: ubwc_possible() argument values to be ignored except for format */
if (pFormatProperties->formatProperties.optimalTilingFeatures &&
tiling_possible(format) &&
ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, 0, physical_device->info, VK_SAMPLE_COUNT_1_BIT)) {
ubwc_possible(format, VK_IMAGE_TYPE_2D, 0, 0, physical_device->info, VK_SAMPLE_COUNT_1_BIT, false)) {
vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mod_props) {
mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
mod_props->drmFormatModifierPlaneCount = tu6_plane_count(format);
@ -399,7 +399,7 @@ tu_get_image_format_properties(
return VK_ERROR_FORMAT_NOT_SUPPORTED;
if (!ubwc_possible(info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts))
if (!ubwc_possible(info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts, false))
return VK_ERROR_FORMAT_NOT_SUPPORTED;
format_feature_flags = format_props.optimalTilingFeatures;

View File

@ -286,7 +286,7 @@ tiling_possible(VkFormat format)
bool
ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage,
VkImageUsageFlags stencil_usage, const struct fd_dev_info *info,
VkSampleCountFlagBits samples)
VkSampleCountFlagBits samples, bool use_z24uint_s8uint)
{
/* no UBWC with compressed formats, E5B9G9R9, S8_UINT
* (S8_UINT because separate stencil doesn't have UBWC-enable bit)
@ -336,10 +336,13 @@ ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage,
*
* It must be sampled as FMT6_8_8_8_8_UINT, which is not UBWC-compatible
*
* If we wish to get the border colors correct without knowing the format
* when creating the sampler, we also have to use the A630 workaround.
*
* 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 (!info->a6xx.has_z24uint_s8uint &&
if (!use_z24uint_s8uint &&
format == VK_FORMAT_D24_UNORM_S8_UINT &&
(stencil_usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))
return false;
@ -452,7 +455,8 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
if (!ubwc_possible(image->vk_format, pCreateInfo->imageType, pCreateInfo->usage,
stencil_usage_info ? stencil_usage_info->stencilUsage : pCreateInfo->usage,
device->physical_device->info, pCreateInfo->samples))
device->physical_device->info, pCreateInfo->samples,
device->use_z24uint_s8uint))
ubwc_enabled = false;
/* expect UBWC enabled if we asked for it */
@ -827,7 +831,7 @@ tu_CreateImageView(VkDevice _device,
if (view == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
tu_image_view_init(view, pCreateInfo, device->physical_device->info->a6xx.has_z24uint_s8uint);
tu_image_view_init(view, pCreateInfo, device->use_z24uint_s8uint);
*pView = tu_image_view_to_handle(view);

View File

@ -614,6 +614,8 @@ struct tu_device
#ifdef HAVE_PERFETTO
struct tu_perfetto_state perfetto;
#endif
bool use_z24uint_s8uint;
};
void tu_init_clear_blit_shaders(struct tu_device *dev);
@ -1851,7 +1853,8 @@ tiling_possible(VkFormat format);
bool
ubwc_possible(VkFormat format, VkImageType type, VkImageUsageFlags usage, VkImageUsageFlags stencil_usage,
const struct fd_dev_info *info, VkSampleCountFlagBits samples);
const struct fd_dev_info *info, VkSampleCountFlagBits samples,
bool use_z24uint_s8uint);
struct tu_buffer_view
{