[PATCH 1/3] vkd3d: Use linear tiling for images on custom heaps if supported.

Conor McCarthy cmccarthy at codeweavers.com
Tue Aug 6 08:16:56 CDT 2019


Enables ReadFromSubresource() to succeed in cases where it would have
failed otherwise.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d/resource.c      | 54 +++++++++++++++++++++++++++++++++-----
 libs/vkd3d/vkd3d_private.h |  1 +
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 0f7ce5e..22deaef 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -781,9 +781,36 @@ static unsigned int max_miplevel_count(const D3D12_RESOURCE_DESC *desc)
     return vkd3d_log2i(size) + 1;
 }
 
+static void image_create_info_adjust_tiling(struct d3d12_device *device, VkImageCreateInfo *image_info)
+{
+    const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    VkImageFormatProperties image_properties;
+    VkResult vr;
+
+    vr = VK_CALL(vkGetPhysicalDeviceImageFormatProperties(device->vk_physical_device, image_info->format,
+            image_info->imageType, VK_IMAGE_TILING_LINEAR, image_info->usage, image_info->flags, &image_properties));
+    if (vr == VK_ERROR_FORMAT_NOT_SUPPORTED)
+    {
+        /* No change. The requested parameters are not supported for linear tiling. */
+        return;
+    }
+    else if (vr != VK_SUCCESS)
+    {
+        WARN("Failed to get device image format properties, vr %d.\n", vr);
+    }
+    else if (image_info->extent.depth <= image_properties.maxExtent.depth
+            && image_info->mipLevels <= image_properties.maxMipLevels
+            && image_info->arrayLayers <= image_properties.maxArrayLayers
+            && (image_info->samples & image_properties.sampleCounts) == image_info->samples)
+    {
+        WARN("Changing layout from VK_IMAGE_TILING_OPTIMAL to VK_IMAGE_TILING_LINEAR on custom heap.\n");
+        image_info->tiling = VK_IMAGE_TILING_LINEAR;
+    }
+}
+
 static HRESULT vkd3d_create_image(struct d3d12_device *device,
         const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
-        const D3D12_RESOURCE_DESC *desc, VkImage *vk_image)
+        const D3D12_RESOURCE_DESC *desc, VkImage *vk_image, bool *is_linear)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
     const bool sparse_resource = !heap_properties;
@@ -883,8 +910,20 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
         image_info.pQueueFamilyIndices = NULL;
     }
 
-    image_info.initialLayout = heap_properties && is_cpu_accessible_heap(heap_properties) ?
-            VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED;
+    if (heap_properties && is_cpu_accessible_heap(heap_properties))
+    {
+        image_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+
+        if (image_info.tiling == VK_IMAGE_TILING_OPTIMAL)
+            image_create_info_adjust_tiling(device, &image_info);
+    }
+    else
+    {
+        image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    }
+
+    if (is_linear)
+        *is_linear = image_info.tiling == VK_IMAGE_TILING_LINEAR;
 
     if ((vr = VK_CALL(vkCreateImage(device->vk_device, &image_info, NULL, vk_image))) < 0)
     {
@@ -916,7 +955,7 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
     }
 
     /* XXX: We have to create an image to get its memory requirements. */
-    if (SUCCEEDED(hr = vkd3d_create_image(device, &heap_properties, 0, desc, &vk_image)))
+    if (SUCCEEDED(hr = vkd3d_create_image(device, &heap_properties, 0, desc, &vk_image, NULL)))
     {
         VK_CALL(vkGetImageMemoryRequirements(device->vk_device, vk_image, &requirements));
         VK_CALL(vkDestroyImage(device->vk_device, vk_image, NULL));
@@ -1385,6 +1424,7 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
     resource->internal_refcount = 1;
 
     resource->desc = *desc;
+    resource->is_linear_texture = false;
 
     if (heap_properties && !d3d12_resource_validate_heap_properties(resource, heap_properties, initial_state))
         return E_INVALIDARG;
@@ -1432,7 +1472,7 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
                 resource->desc.MipLevels = max_miplevel_count(desc);
             resource->flags |= VKD3D_RESOURCE_INITIAL_STATE_TRANSITION;
             if (FAILED(hr = vkd3d_create_image(device, heap_properties, heap_flags,
-                    &resource->desc, &resource->u.vk_image)))
+                    &resource->desc, &resource->u.vk_image, &resource->is_linear_texture)))
                 return hr;
             break;
 
@@ -3656,7 +3696,7 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources,
     resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
 
     if (FAILED(hr = vkd3d_create_image(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
-            &resource_desc, &null_resources->vk_2d_image)))
+            &resource_desc, &null_resources->vk_2d_image, NULL)))
         goto fail;
     if (FAILED(hr = vkd3d_allocate_image_memory(device, null_resources->vk_2d_image,
             &heap_properties, D3D12_HEAP_FLAG_NONE, &null_resources->vk_2d_image_memory, NULL, NULL)))
@@ -3677,7 +3717,7 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources,
     resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
 
     if (FAILED(hr = vkd3d_create_image(device, use_sparse_resources ? NULL : &heap_properties, D3D12_HEAP_FLAG_NONE,
-            &resource_desc, &null_resources->vk_2d_storage_image)))
+            &resource_desc, &null_resources->vk_2d_storage_image, NULL)))
         goto fail;
     if (!use_sparse_resources && FAILED(hr = vkd3d_allocate_image_memory(device, null_resources->vk_2d_storage_image,
             &heap_properties, D3D12_HEAP_FLAG_NONE, &null_resources->vk_2d_storage_image_memory, NULL, NULL)))
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 4398351..4640113 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -389,6 +389,7 @@ struct d3d12_resource
     LONG internal_refcount;
 
     D3D12_RESOURCE_DESC desc;
+    bool is_linear_texture;
 
     D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
     union
-- 
2.22.0




More information about the wine-devel mailing list