From a44744e01d73f7187406200d57dd67aa235a7d13 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 28 Nov 2017 08:49:29 -0800 Subject: [PATCH] anv: Require a dedicated allocation for modified images This lets us set the BO tiling when we allocate the memory. This is required for GL to work properly. Reviewed-by: Dave Airlie Reviewed-by: Chad Versace --- src/intel/vulkan/anv_device.c | 53 ++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 1ee54cddaf6..fc5554ea2aa 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "anv_private.h" #include "util/strtod.h" @@ -1612,6 +1613,40 @@ VkResult anv_AllocateMemory( &mem->bo); if (result != VK_SUCCESS) goto fail; + + const VkMemoryDedicatedAllocateInfoKHR *dedicated_info = + vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO_KHR); + if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) { + ANV_FROM_HANDLE(anv_image, image, dedicated_info->image); + + /* For images using modifiers, we require a dedicated allocation + * and we set the BO tiling to match the tiling of the underlying + * modifier. This is a bit unfortunate as this is completely + * pointless for Vulkan. However, GL needs to be able to map things + * so it needs the tiling to be set. The only way to do this in a + * non-racy way is to set the tiling in the creator of the BO so that + * makes it our job. + * + * One of these days, once the GL driver learns to not map things + * through the GTT in random places, we can drop this and start + * allowing multiple modified images in the same BO. + */ + if (image->drm_format_mod != DRM_FORMAT_MOD_INVALID) { + assert(isl_drm_modifier_get_info(image->drm_format_mod)->tiling == + image->planes[0].surface.isl.tiling); + const uint32_t i915_tiling = + isl_tiling_to_i915_tiling(image->planes[0].surface.isl.tiling); + int ret = anv_gem_set_tiling(device, mem->bo->gem_handle, + image->planes[0].surface.isl.row_pitch, + i915_tiling); + if (ret) { + anv_bo_cache_release(device, &device->bo_cache, mem->bo); + return vk_errorf(device->instance, NULL, + VK_ERROR_OUT_OF_DEVICE_MEMORY, + "failed to set BO tiling: %m"); + } + } + } } assert(mem->type->heapIndex < pdevice->memory.heap_count); @@ -1904,14 +1939,15 @@ void anv_GetImageMemoryRequirements2KHR( const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements) { + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_image, image, pInfo->image); + anv_GetImageMemoryRequirements(_device, pInfo->image, &pMemoryRequirements->memoryRequirements); vk_foreach_struct_const(ext, pInfo->pNext) { switch (ext->sType) { case VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR: { - ANV_FROM_HANDLE(anv_image, image, pInfo->image); - ANV_FROM_HANDLE(anv_device, device, _device); struct anv_physical_device *pdevice = &device->instance->physicalDevice; const VkImagePlaneMemoryRequirementsInfoKHR *plane_reqs = (const VkImagePlaneMemoryRequirementsInfoKHR *) ext; @@ -1949,8 +1985,17 @@ void anv_GetImageMemoryRequirements2KHR( switch (ext->sType) { case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR: { VkMemoryDedicatedRequirementsKHR *requirements = (void *)ext; - requirements->prefersDedicatedAllocation = VK_FALSE; - requirements->requiresDedicatedAllocation = VK_FALSE; + if (image->drm_format_mod != DRM_FORMAT_MOD_INVALID) { + /* Require a dedicated allocation for images with modifiers. + * + * See also anv_AllocateMemory. + */ + requirements->prefersDedicatedAllocation = VK_TRUE; + requirements->requiresDedicatedAllocation = VK_TRUE; + } else { + requirements->prefersDedicatedAllocation = VK_FALSE; + requirements->requiresDedicatedAllocation = VK_FALSE; + } break; } -- 2.30.2