diff --git a/src/freedreno/fdl/fd6_view.c b/src/freedreno/fdl/fd6_view.c index 851533de789..34dd9a8d26c 100644 --- a/src/freedreno/fdl/fd6_view.c +++ b/src/freedreno/fdl/fd6_view.c @@ -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; diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 7e5e8505754..9c09bbd647d 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -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; } diff --git a/src/freedreno/vulkan/tu_formats.c b/src/freedreno/vulkan/tu_formats.c index 3e4e6d5cd7b..c24648bf3b5 100644 --- a/src/freedreno/vulkan/tu_formats.c +++ b/src/freedreno/vulkan/tu_formats.c @@ -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; diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c index 5dcc5c1bd71..bf892ccbdf8 100644 --- a/src/freedreno/vulkan/tu_image.c +++ b/src/freedreno/vulkan/tu_image.c @@ -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); diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 8b2ccd8b5ec..38735010d83 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -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 {