From 5d17f714416aba546df6862b3e3082db5cf1e029 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 25 Mar 2021 02:23:04 +0000 Subject: [PATCH] vkd3d: Handle usage and implicit views for VRS capable resources Signed-off-by: Joshua Ashton --- libs/vkd3d/resource.c | 68 ++++++++++++++++++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 2 ++ 2 files changed, 70 insertions(+) diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index defdeea8..287362d7 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -297,6 +297,54 @@ static bool vkd3d_sparse_image_may_have_mip_tail(const D3D12_RESOURCE_DESC *desc mip_extent.depth < block_extent.depth; } +static bool vkd3d_resource_can_be_vrs(struct d3d12_device *device, + const D3D12_HEAP_PROPERTIES *heap_properties, const D3D12_RESOURCE_DESC *desc) +{ + return device->device_info.fragment_shading_rate_features.attachmentFragmentShadingRate && + desc->Format == DXGI_FORMAT_R8_UINT && + desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && + desc->MipLevels == 1 && + desc->SampleDesc.Count == 1 && + desc->SampleDesc.Quality == 0 && + desc->Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN && + heap_properties && + !is_cpu_accessible_heap(heap_properties) && + !(desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | + D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL | + D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER | + D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS | + D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY)); +} + +static HRESULT vkd3d_resource_make_vrs_view(struct d3d12_device *device, + VkImage image, VkImageView* view) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkImageViewCreateInfo view_info; + VkResult vr; + + view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_info.pNext = NULL; + view_info.flags = 0; + view_info.image = image; + view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_info.format = VK_FORMAT_R8_UINT; + view_info.components = (VkComponentMapping) { + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY + }; + view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + view_info.subresourceRange.baseMipLevel = 0; + view_info.subresourceRange.levelCount = 1; + view_info.subresourceRange.baseArrayLayer = 0; + view_info.subresourceRange.layerCount = 1; + + if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_info, NULL, view))) < 0) + ERR("Failed to create implicit VRS view, vr %d.\n", vr); + + return hresult_from_vk_result(vr); +} + 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, struct d3d12_resource *resource, VkImage *vk_image) @@ -443,6 +491,9 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device, : VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; } + if (vkd3d_resource_can_be_vrs(device, heap_properties, desc)) + image_info.usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; + if (device->unique_queue_mask & (device->unique_queue_mask - 1)) { /* For multi-queue, we have to use CONCURRENT since D3D does @@ -2231,6 +2282,9 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 if ((resource->flags & VKD3D_RESOURCE_ALLOCATION) && resource->mem.vk_memory) vkd3d_free_memory(device, &device->memory_allocator, &resource->mem); + if (resource->vrs_view) + VK_CALL(vkDestroyImageView(device->vk_device, resource->vrs_view, NULL)); + vkd3d_private_store_destroy(&resource->private_store); d3d12_device_release(resource->device); vkd3d_free(resource); @@ -2401,6 +2455,13 @@ HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12 hr = hresult_from_vk_result(vr); goto fail; } + + if (vkd3d_resource_can_be_vrs(device, heap_properties, desc)) + { + /* Make the implicit VRS view here... */ + if (FAILED(hr = vkd3d_resource_make_vrs_view(device, object->res.vk_image, &object->vrs_view))) + goto fail; + } } else { @@ -2502,6 +2563,13 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE object->res.va = object->mem.resource.va; } + if (vkd3d_resource_can_be_vrs(device, &heap->desc.Properties, desc)) + { + /* Make the implicit VRS view here... */ + if (FAILED(hr = vkd3d_resource_make_vrs_view(device, object->res.vk_image, &object->vrs_view))) + goto fail; + } + *resource = object; return S_OK; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 131993e9..8a7027a9 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -820,6 +820,8 @@ struct d3d12_resource const struct vkd3d_format *format; + VkImageView vrs_view; + struct vkd3d_private_store private_store; };