diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c index 445eecd8d55..3f22a5730d4 100644 --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -86,6 +86,8 @@ static void get_features(const struct panvk_physical_device *device, struct vk_features *features) { + unsigned arch = pan_arch(device->kmod.props.gpu_prod_id); + *features = (struct vk_features){ /* Vulkan 1.0 */ .robustBufferAccess = true, @@ -199,7 +201,13 @@ get_features(const struct panvk_physical_device *device, /* VK_EXT_custom_border_color */ .customBorderColors = true, - .customBorderColorWithoutFormat = true, + + /* v7 doesn't support AFBC(BGR). We need to tweak the texture swizzle to + * make it work, which forces us to apply the same swizzle on the border + * color, meaning we need to know the format when preparing the border + * color. + */ + .customBorderColorWithoutFormat = arch != 7, /* VK_KHR_shader_expect_assume */ .shaderExpectAssume = true, diff --git a/src/panfrost/vulkan/panvk_vX_sampler.c b/src/panfrost/vulkan/panvk_vX_sampler.c index b1fbfa0eb6e..42e7ecbd0d1 100644 --- a/src/panfrost/vulkan/panvk_vX_sampler.c +++ b/src/panfrost/vulkan/panvk_vX_sampler.c @@ -10,7 +10,9 @@ #include "panvk_sampler.h" #include "pan_encoder.h" +#include "pan_format.h" +#include "vk_format.h" #include "vk_log.h" static enum mali_mipmap_mode @@ -54,6 +56,26 @@ panvk_translate_sampler_compare_func(const VkSamplerCreateInfo *pCreateInfo) return panfrost_flip_compare_func((enum mali_func)pCreateInfo->compareOp); } +static void +swizzle_border_color(VkClearColorValue *border_color, VkFormat fmt) +{ + if (PAN_ARCH != 7) + return; + + enum pipe_format pfmt = vk_format_to_pipe_format(fmt); + if (panfrost_format_is_yuv(pfmt) || util_format_is_depth_or_stencil(pfmt)) + return; + + const struct util_format_description *fdesc = util_format_description(pfmt); + if (fdesc->swizzle[0] == PIPE_SWIZZLE_Z && + fdesc->swizzle[2] == PIPE_SWIZZLE_X) { + uint32_t red = border_color->uint32[0]; + + border_color->uint32[0] = border_color->uint32[2]; + border_color->uint32[2] = red; + } +} + VKAPI_ATTR VkResult VKAPI_CALL panvk_per_arch(CreateSampler)(VkDevice _device, const VkSamplerCreateInfo *pCreateInfo, @@ -72,8 +94,11 @@ panvk_per_arch(CreateSampler)(VkDevice _device, STATIC_ASSERT(sizeof(sampler->desc) >= pan_size(SAMPLER)); + VkFormat fmt; VkClearColorValue border_color = - vk_sampler_border_color_value(pCreateInfo, NULL); + vk_sampler_border_color_value(pCreateInfo, &fmt); + + swizzle_border_color(&border_color, fmt); pan_pack(sampler->desc.opaque, SAMPLER, cfg) { cfg.magnify_nearest = pCreateInfo->magFilter == VK_FILTER_NEAREST;