anv: Add support for compressed images allocation in Xe2

Xe2 replaces auxiliary surface mapping by software to compress buffers,
instead it reserves part of the memory for the compression purpose.

To enable compression in Xe2 it is necessary bind memory with one of
the PAT indexes that has compression enabled.

It is still always returning false in anv_image_is_pat_compressible()
as it still needs more work before compression can be enabled but the
foundation for the compressed allocation is here.

Reviewed-by: Rohan Garg <rohan.garg@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28833>
This commit is contained in:
José Roberto de Souza
2024-04-16 07:38:56 -07:00
committed by Marge Bot
parent 90b223331f
commit 8aec37fe0c
4 changed files with 95 additions and 13 deletions
+27 -5
View File
@@ -372,7 +372,12 @@ get_device_extensions(const struct anv_physical_device *device,
.EXT_graphics_pipeline_library = !debug_get_bool_option("ANV_NO_GPL", false),
.EXT_host_query_reset = true,
.EXT_image_2d_view_of_3d = true,
.EXT_image_compression_control = device->instance->compression_control_enabled,
/* Because of Xe2 PAT selected compression and the Vulkan spec
* requirement to always return the same memory types for Images with
* same properties we can't support EXT_image_compression_control on Xe2+
*/
.EXT_image_compression_control = device->instance->compression_control_enabled &&
device->info.ver < 20,
.EXT_image_robustness = true,
.EXT_image_drm_format_modifier = true,
.EXT_image_sliced_view_of_3d = true,
@@ -2001,6 +2006,8 @@ anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
break;
}
assert(device->memory.type_count < ARRAY_SIZE(device->memory.types));
if (result != VK_SUCCESS)
return result;
@@ -2012,17 +2019,27 @@ anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
BITFIELD_RANGE(0, device->memory.type_count);
device->memory.protected_mem_types = 0;
device->memory.desc_buffer_mem_types = 0;
device->memory.compressed_mem_types = 0;
uint32_t base_types_count = device->memory.type_count;
const uint32_t base_types_count = device->memory.type_count;
for (int i = 0; i < base_types_count; i++) {
bool skip = false;
if (device->memory.types[i].propertyFlags &
VK_MEMORY_PROPERTY_PROTECTED_BIT) {
device->memory.protected_mem_types |= BITFIELD_BIT(i);
device->memory.default_buffer_mem_types &= (~BITFIELD_BIT(i));
continue;
skip = true;
}
assert(device->memory.type_count < ARRAY_SIZE(device->memory.types));
if (device->memory.types[i].compressed) {
device->memory.compressed_mem_types |= BITFIELD_BIT(i);
device->memory.default_buffer_mem_types &= (~BITFIELD_BIT(i));
skip = true;
}
if (skip)
continue;
device->memory.desc_buffer_mem_types |=
BITFIELD_BIT(device->memory.type_count);
@@ -4453,6 +4470,9 @@ VkResult anv_AllocateMemory(
if (mem_type->propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT)
alloc_flags |= ANV_BO_ALLOC_PROTECTED;
if (mem_type->compressed)
alloc_flags |= ANV_BO_ALLOC_COMPRESSED;
/* For now, always allocated AUX-TT aligned memory, regardless of dedicated
* allocations. An application can for example, suballocate a large
* VkDeviceMemory and try to bind an image created with a CCS modifier. In
@@ -5657,7 +5677,9 @@ anv_device_get_pat_entry(struct anv_device *device,
return &device->info->pat.writecombining;
}
if ((alloc_flags & (ANV_BO_ALLOC_HOST_CACHED_COHERENT)) == ANV_BO_ALLOC_HOST_CACHED_COHERENT)
if (alloc_flags & ANV_BO_ALLOC_COMPRESSED)
return &device->info->pat.compressed;
else if ((alloc_flags & (ANV_BO_ALLOC_HOST_CACHED_COHERENT)) == ANV_BO_ALLOC_HOST_CACHED_COHERENT)
return &device->info->pat.cached_coherent;
else if (alloc_flags & (ANV_BO_ALLOC_EXTERNAL | ANV_BO_ALLOC_SCANOUT))
return &device->info->pat.scanout;
+45 -4
View File
@@ -1984,6 +1984,43 @@ resolve_ahw_image(struct anv_device *device,
#endif
}
static bool
anv_image_is_pat_compressible(struct anv_device *device, struct anv_image *image)
{
if (INTEL_DEBUG(DEBUG_NO_CCS))
return false;
if (device->info->ver < 20)
return false;
/*
* Be aware that Vulkan spec requires that Images with some properties
* always returns the same memory types, so this function also needs to
* have the same return for the same set of properties.
*
* For images created with a color format, the memoryTypeBits member is
* identical for all VkImage objects created with the same combination
* of values for the tiling member, the
* VK_IMAGE_CREATE_SPARSE_BINDING_BIT bit of the flags member, the
* VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT bit of the flags
* member, handleTypes member of VkExternalMemoryImageCreateInfo, and
* the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT of the usage member in
* the VkImageCreateInfo structure passed to vkCreateImage.
*
* For images created with a depth/stencil format, the memoryTypeBits
* member is identical for all VkImage objects created with the same
* combination of values for the format member, the tiling member, the
* VK_IMAGE_CREATE_SPARSE_BINDING_BIT bit of the flags member, the
* VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT bit of the flags
* member, handleTypes member of VkExternalMemoryImageCreateInfo, and
* the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT of the usage member in
* the VkImageCreateInfo structure passed to vkCreateImage.
*/
/* TODO: check for other compression requirements and return true */
return false;
}
void
anv_image_get_memory_requirements(struct anv_device *device,
struct anv_image *image,
@@ -1997,10 +2034,14 @@ anv_image_get_memory_requirements(struct anv_device *device,
* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
* structure for the physical device is supported.
*/
uint32_t memory_types =
(image->vk.create_flags & VK_IMAGE_CREATE_PROTECTED_BIT) ?
device->physical->memory.protected_mem_types :
device->physical->memory.default_buffer_mem_types;
uint32_t memory_types;
if (image->vk.create_flags & VK_IMAGE_CREATE_PROTECTED_BIT)
memory_types = device->physical->memory.protected_mem_types;
else if (anv_image_is_pat_compressible(device, image))
memory_types = device->physical->memory.compressed_mem_types;
else
memory_types = device->physical->memory.default_buffer_mem_types;
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
switch (ext->sType) {
+6
View File
@@ -446,6 +446,9 @@ enum anv_bo_alloc_flags {
/** For descriptor buffer pools */
ANV_BO_ALLOC_DESCRIPTOR_BUFFER_POOL = (1 << 21),
/** Compressed buffer, only supported in Xe2+ */
ANV_BO_ALLOC_COMPRESSED = (1 << 22),
};
/** Specifies that the BO should be cached and coherent. */
@@ -943,6 +946,7 @@ struct anv_memory_type {
uint32_t heapIndex;
/* Whether this is the descriptor buffer memory type */
bool descriptor_buffer;
bool compressed;
};
struct anv_memory_heap {
@@ -1102,6 +1106,8 @@ struct anv_physical_device {
uint32_t desc_buffer_mem_types;
/** Mask of memory types of protected buffers/images */
uint32_t protected_mem_types;
/** Mask of memory types of compressed buffers/images */
uint32_t compressed_mem_types;
} memory;
struct {
+17 -4
View File
@@ -98,18 +98,24 @@ VkResult
anv_xe_physical_device_init_memory_types(struct anv_physical_device *device)
{
if (anv_physical_device_has_vram(device)) {
device->memory.type_count = 3;
device->memory.types[0] = (struct anv_memory_type) {
if (device->info.ver >= 20) {
device->memory.types[device->memory.type_count++] = (struct anv_memory_type) {
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
.heapIndex = 0,
.compressed = true,
};
}
device->memory.types[device->memory.type_count++] = (struct anv_memory_type) {
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
.heapIndex = 0,
};
device->memory.types[1] = (struct anv_memory_type) {
device->memory.types[device->memory.type_count++] = (struct anv_memory_type) {
.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
.heapIndex = 1,
};
device->memory.types[2] = (struct anv_memory_type) {
device->memory.types[device->memory.type_count++] = (struct anv_memory_type) {
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
@@ -142,6 +148,13 @@ anv_xe_physical_device_init_memory_types(struct anv_physical_device *device)
.heapIndex = 0,
};
} else {
if (device->info.ver >= 20) {
device->memory.types[device->memory.type_count++] = (struct anv_memory_type) {
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
.heapIndex = 0,
.compressed = true,
};
}
device->memory.types[device->memory.type_count++] = (struct anv_memory_type) {
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |