diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index 06ed73dfe97..8a65c65d942 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -772,61 +772,65 @@ nvk_GetPhysicalDeviceSparseImageFormatProperties2( } } -/* To use compression and larger page sizes, we need to signal to the kernel - * that the memory requested is going to be VRAM resident. However, this - * comes with an issue where said memory can't be evicted to host RAM under - * pressure, so we work around this by going with a dedicated allocation for - * color, Z/S, and storage image targets which are the main types that would - * benefit from compression as they're heavy on writes. Additionally, they - * also aren't the majority of memory used, so they can be safely pinned in - * VRAM without worrying about eviction under high pressure. - * - * There are some additional restrictions we need to keep in mind, however: - * 1. We can only enable this for Turing onwards because prior architectures - * relied on firmware to manage the compression tags, and it's impossible to - * do this on nouveau. Additionally, since compression needs kernel changes, - * we can only enable it if the detected kernel supports it. - * - * 2. Given our approach depends on dedicated allocations, we can't enable - * compression for sparse images as dedicated allocations are not compatible - * with sparse. - * - * 3. In similar vein, we currently don't do multiplanar dedicated allocations - * so we can't do compression for multi-plane YCbCr images. - * - * 4. Host copies are a complete no-go for compression as the host doesn't know - * about the modified data layout nor the compression tags. - * - * 5. The API for VK_EXT_image_drm_format_modifier requires that we report the - * supported modifiers in GetPhysicalDeviceFormatProperties2(). However, - * since we can only know whether an image is compressed or not at bind time - * we can't actually expose any of the compressed modifiers in case the app - * chooses a compressed modifier for a non-compressed image. So for now, we - * have to disable compression for TILING_DRM_FORMAT_MODIFIER_EXT images. - * - * This helper enforces these restrictions and also makes sure to enable - * compression for storage, color, and Z/S targets only so as to avoid pinning - * too many things to VRAM. - */ static bool nvk_image_can_compress(const struct nvkmd_pdev *nvkmd_pdev, const struct nvk_image *image) { - if (nvkmd_pdev->kmd_info.has_compression) { - if (image->plane_count > 1 || - image->vk.usage & (VK_IMAGE_USAGE_HOST_TRANSFER_BIT) || - image->vk.create_flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | - VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) - return false; - else if (image->vk.usage & (VK_IMAGE_USAGE_STORAGE_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && - image->vk.tiling == VK_IMAGE_TILING_OPTIMAL) - return true; - else - return false; - } else + if (!nvkmd_pdev->kmd_info.has_compression) return false; + + /* Our host copy code does not understand compression */ + if (image->vk.usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT) + return false; + + /* Our compression strategy depends on dedicated allocations, so we can't + * enable compression for sparse images as dedicated allocations are not + * compatible with sparse. + */ + if (image->vk.create_flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | + VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) + return false; + + /* In similar vein, we currently don't do multiplanar dedicated allocations + * so we can't do compression for multi-plane YCbCr images. + */ + if (image->plane_count > 1) + return false; + + /* Linear images cannot be compressed. */ + if (image->vk.tiling == VK_IMAGE_TILING_LINEAR) + return false; + + /* The API for VK_EXT_image_drm_format_modifier requires that we report the + * supported modifiers in GetPhysicalDeviceFormatProperties2(). However, + * since we can only know whether an image is compressed or not at bind + * time we can't actually expose any of the compressed modifiers in case + * the app chooses a compressed modifier for a non-compressed image. So for + * now, we have to disable compression for TILING_DRM_FORMAT_MODIFIER_EXT + * images. + */ + if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) + return false; + + assert(image->vk.tiling == VK_IMAGE_TILING_OPTIMAL); + + /* To use compression and larger page sizes, we need to signal to the + * kernel that the memory requested is going to be VRAM resident. However, + * this comes with an issue where said memory can't be evicted to host RAM + * under pressure. + * + * So we work around this by only allowing compression for color, Z/S, and + * storage image targets which are the main types that would benefit from + * compression as they're heavy on writes. Additionally, they also aren't + * the majority of memory used, so they can be safely pinned in VRAM + * without worrying about eviction under high pressure. + */ + if (!(image->vk.usage & (VK_IMAGE_USAGE_STORAGE_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))) + return false; + + return true; } static VkResult