[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