summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan/anv_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel/vulkan/anv_device.c')
-rw-r--r--src/intel/vulkan/anv_device.c53
1 files 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 <unistd.h>
#include <fcntl.h>
#include <xf86drm.h>
+#include <drm_fourcc.h>
#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;
}