Enables ReadFromSubresource() to succeed in cases where it would have failed otherwise.
Signed-off-by: Conor McCarthy cmccarthy@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