summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Natalie <jenatali@microsoft.com>2023-05-03 21:17:12 -0700
committerMarge Bot <emma+marge@anholt.net>2023-05-15 17:14:20 +0000
commitfb613407905de9aea2db685c009f114d902229ab (patch)
tree13454136d16c4aa4e160523e2f8c0fb70e07d389
parent7cc59ad9736ddaaeeeeee7bc5c2f21c0b1df6be1 (diff)
downloadmesa-fb613407905de9aea2db685c009f114d902229ab.tar.gz
dzn: Dedicated resource cleanup
Vulkan's concept of dedicated resources is dangerously close to D3D12's concept of a "committed" resource, where the memory and resource are inextricably tied. This is a minor optimization, but will start to be more important going forward with external memory. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22879>
-rw-r--r--src/microsoft/vulkan/dzn_cmd_buffer.c17
-rw-r--r--src/microsoft/vulkan/dzn_device.c177
-rw-r--r--src/microsoft/vulkan/dzn_image.c113
-rw-r--r--src/microsoft/vulkan/dzn_private.h7
-rw-r--r--src/microsoft/vulkan/dzn_wsi.c4
5 files changed, 163 insertions, 155 deletions
diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c
index 06118dee6ec..9f6bbe77d51 100644
--- a/src/microsoft/vulkan/dzn_cmd_buffer.c
+++ b/src/microsoft/vulkan/dzn_cmd_buffer.c
@@ -1134,23 +1134,6 @@ dzn_CmdPipelineBarrier2(VkCommandBuffer commandBuffer,
const VkImageSubresourceRange *range = &ibarrier->subresourceRange;
VK_FROM_HANDLE(dzn_image, image, ibarrier->image);
- if (image->mem->swapchain_res != image->res) {
- /* We use placed resource's simple model, in which only one resource
- * pointing to a given heap is active at a given time. To make the
- * resource active we need to add an aliasing barrier.
- */
- D3D12_RESOURCE_BARRIER aliasing_barrier = {
- .Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING,
- .Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
- .Aliasing = {
- .pResourceBefore = NULL,
- .pResourceAfter = image->res,
- },
- };
-
- ID3D12GraphicsCommandList1_ResourceBarrier(cmdbuf->cmdlist, 1, &aliasing_barrier);
- }
-
VkImageLayout old_layout = ibarrier->oldLayout;
VkImageLayout new_layout = ibarrier->newLayout;
if ((image->vk.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c
index 2f38603fe19..44d99e903f9 100644
--- a/src/microsoft/vulkan/dzn_device.c
+++ b/src/microsoft/vulkan/dzn_device.c
@@ -2559,8 +2559,8 @@ dzn_device_memory_destroy(struct dzn_device_memory *mem,
if (mem->heap)
ID3D12Heap_Release(mem->heap);
- if (mem->swapchain_res)
- ID3D12Resource_Release(mem->swapchain_res);
+ if (mem->dedicated_res)
+ ID3D12Resource_Release(mem->dedicated_res);
vk_object_base_finish(&mem->base);
vk_free2(&device->vk.alloc, pAllocator, mem);
@@ -2575,19 +2575,6 @@ dzn_device_memory_create(struct dzn_device *device,
struct dzn_physical_device *pdevice =
container_of(device->vk.physical, struct dzn_physical_device, vk);
- struct dzn_device_memory *mem =
- vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!mem)
- return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
-
- vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY);
-
- /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */
- assert(pAllocateInfo->allocationSize > 0);
-
- mem->size = pAllocateInfo->allocationSize;
-
const struct dzn_buffer *buffer = NULL;
const struct dzn_image *image = NULL;
@@ -2636,12 +2623,26 @@ dzn_device_memory_create(struct dzn_device *device,
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
}
- heap_desc.SizeInBytes = ALIGN_POT(heap_desc.SizeInBytes, heap_desc.Alignment);
- heap_desc.Flags =
- dzn_physical_device_get_heap_flags_for_mem_type(pdevice,
- pAllocateInfo->memoryTypeIndex);
+ if (mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
+ image = NULL;
+
+ struct dzn_device_memory *mem =
+ vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!mem)
+ return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY);
+
+ /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */
+ assert(pAllocateInfo->allocationSize > 0);
+
+ mem->size = pAllocateInfo->allocationSize;
- /* TODO: Unsure about this logic??? */
+ heap_desc.SizeInBytes = ALIGN_POT(heap_desc.SizeInBytes, heap_desc.Alignment);
+ if (!image && !buffer)
+ heap_desc.Flags =
+ dzn_physical_device_get_heap_flags_for_mem_type(pdevice, pAllocateInfo->memoryTypeIndex);
heap_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM;
heap_desc.Properties.MemoryPoolPreference =
((mem_type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) &&
@@ -2656,35 +2657,87 @@ dzn_device_memory_create(struct dzn_device *device,
heap_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE;
}
- if (FAILED(ID3D12Device1_CreateHeap(device->dev, &heap_desc,
- &IID_ID3D12Heap,
- (void **)&mem->heap))) {
- dzn_device_memory_destroy(mem, pAllocator);
- return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ if (image) {
+ if (device->dev10 && image->castable_format_count > 0) {
+ D3D12_RESOURCE_DESC1 desc = {
+ .Dimension = image->desc.Dimension,
+ .Alignment = image->desc.Alignment,
+ .Width = image->desc.Width,
+ .Height = image->desc.Height,
+ .DepthOrArraySize = image->desc.DepthOrArraySize,
+ .MipLevels = image->desc.MipLevels,
+ .Format = image->desc.Format,
+ .SampleDesc = image->desc.SampleDesc,
+ .Layout = image->desc.Layout,
+ .Flags = image->desc.Flags,
+ };
+ if (FAILED(ID3D12Device10_CreateCommittedResource3(device->dev10, &heap_desc.Properties,
+ heap_desc.Flags, &desc,
+ D3D12_BARRIER_LAYOUT_COMMON,
+ NULL, NULL,
+ image->castable_format_count,
+ image->castable_formats,
+ &IID_ID3D12Resource,
+ (void **)&mem->dedicated_res))) {
+ dzn_device_memory_destroy(mem, pAllocator);
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ }
+ } else if (FAILED(ID3D12Device1_CreateCommittedResource(device->dev, &heap_desc.Properties,
+ heap_desc.Flags, &image->desc,
+ D3D12_RESOURCE_STATE_COMMON,
+ NULL,
+ &IID_ID3D12Resource,
+ (void **)&mem->dedicated_res))) {
+ dzn_device_memory_destroy(mem, pAllocator);
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ }
+ } else if (buffer) {
+ if (FAILED(ID3D12Device1_CreateCommittedResource(device->dev, &heap_desc.Properties,
+ heap_desc.Flags, &buffer->desc,
+ D3D12_RESOURCE_STATE_COMMON,
+ NULL,
+ &IID_ID3D12Resource,
+ (void **)&mem->dedicated_res))) {
+ dzn_device_memory_destroy(mem, pAllocator);
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ }
+ } else {
+ if (FAILED(ID3D12Device1_CreateHeap(device->dev, &heap_desc,
+ &IID_ID3D12Heap,
+ (void **)&mem->heap))) {
+ dzn_device_memory_destroy(mem, pAllocator);
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ }
}
if ((mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&
!(heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS)){
- D3D12_RESOURCE_DESC res_desc = { 0 };
- res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- res_desc.Format = DXGI_FORMAT_UNKNOWN;
- res_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
- res_desc.Width = heap_desc.SizeInBytes;
- res_desc.Height = 1;
- res_desc.DepthOrArraySize = 1;
- res_desc.MipLevels = 1;
- res_desc.SampleDesc.Count = 1;
- res_desc.SampleDesc.Quality = 0;
- res_desc.Flags = D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
- res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- HRESULT hr = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap, 0, &res_desc,
- D3D12_RESOURCE_STATE_COMMON,
- NULL,
- &IID_ID3D12Resource,
- (void **)&mem->map_res);
- if (FAILED(hr)) {
- dzn_device_memory_destroy(mem, pAllocator);
- return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ assert(!image);
+ if (buffer) {
+ mem->map_res = mem->dedicated_res;
+ ID3D12Resource_AddRef(mem->map_res);
+ } else {
+ D3D12_RESOURCE_DESC res_desc = { 0 };
+ res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
+ res_desc.Format = DXGI_FORMAT_UNKNOWN;
+ res_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
+ res_desc.Width = heap_desc.SizeInBytes;
+ res_desc.Height = 1;
+ res_desc.DepthOrArraySize = 1;
+ res_desc.MipLevels = 1;
+ res_desc.SampleDesc.Count = 1;
+ res_desc.SampleDesc.Quality = 0;
+ res_desc.Flags = D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
+ res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
+ HRESULT hr = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap, 0, &res_desc,
+ D3D12_RESOURCE_STATE_COMMON,
+ NULL,
+ &IID_ID3D12Resource,
+ (void **)&mem->map_res);
+ if (FAILED(hr)) {
+ dzn_device_memory_destroy(mem, pAllocator);
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ }
}
}
@@ -3025,7 +3078,6 @@ dzn_GetBufferMemoryRequirements2(VkDevice dev,
struct dzn_physical_device *pdev =
container_of(device->vk.physical, struct dzn_physical_device, vk);
- /* uh, this is grossly over-estimating things */
uint32_t alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
VkDeviceSize size = buffer->size;
@@ -3044,9 +3096,8 @@ dzn_GetBufferMemoryRequirements2(VkDevice dev,
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *requirements =
(VkMemoryDedicatedRequirements *)ext;
- /* TODO: figure out dedicated allocations */
- requirements->prefersDedicatedAllocation = false;
requirements->requiresDedicatedAllocation = false;
+ requirements->prefersDedicatedAllocation = false;
break;
}
@@ -3055,13 +3106,6 @@ dzn_GetBufferMemoryRequirements2(VkDevice dev,
break;
}
}
-
-#if 0
- D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo(
- UINT visibleMask,
- UINT numResourceDescs,
- const D3D12_RESOURCE_DESC *pResourceDescs);
-#endif
}
VKAPI_ATTR VkResult VKAPI_CALL
@@ -3077,14 +3121,21 @@ dzn_BindBufferMemory2(VkDevice _device,
VK_FROM_HANDLE(dzn_device_memory, mem, pBindInfos[i].memory);
VK_FROM_HANDLE(dzn_buffer, buffer, pBindInfos[i].buffer);
- if (FAILED(ID3D12Device1_CreatePlacedResource(device->dev, mem->heap,
- pBindInfos[i].memoryOffset,
- &buffer->desc,
- D3D12_RESOURCE_STATE_COMMON,
- NULL,
- &IID_ID3D12Resource,
- (void **)&buffer->res)))
- return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+ if (mem->dedicated_res) {
+ assert(pBindInfos[i].memoryOffset == 0 &&
+ buffer->size == mem->size);
+ buffer->res = mem->dedicated_res;
+ ID3D12Resource_AddRef(buffer->res);
+ } else {
+ if (FAILED(ID3D12Device1_CreatePlacedResource(device->dev, mem->heap,
+ pBindInfos[i].memoryOffset,
+ &buffer->desc,
+ D3D12_RESOURCE_STATE_COMMON,
+ NULL,
+ &IID_ID3D12Resource,
+ (void **)&buffer->res)))
+ return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
buffer->gpuva = ID3D12Resource_GetGPUVirtualAddress(buffer->res);
diff --git a/src/microsoft/vulkan/dzn_image.c b/src/microsoft/vulkan/dzn_image.c
index 07ffe4f4078..95793d2476c 100644
--- a/src/microsoft/vulkan/dzn_image.c
+++ b/src/microsoft/vulkan/dzn_image.c
@@ -811,78 +811,53 @@ dzn_BindImageMemory2(VkDevice dev,
const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
VK_FROM_HANDLE(dzn_device_memory, mem, bind_info->memory);
VK_FROM_HANDLE(dzn_image, image, bind_info->image);
- bool did_bind = false;
vk_foreach_struct_const(s, bind_info->pNext) {
- switch (s->sType) {
- case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
- const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
- (const VkBindImageMemorySwapchainInfoKHR *) s;
- ASSERTED struct dzn_image *swapchain_image =
- dzn_swapchain_get_image(device,
- swapchain_info->swapchain,
- swapchain_info->imageIndex);
- assert(swapchain_image);
- assert(image->vk.aspects == swapchain_image->vk.aspects);
- assert(mem == NULL);
-
- /* TODO: something something binding the image memory */
- assert(false);
-
- did_bind = true;
- break;
- }
- default:
- dzn_debug_ignored_stype(s->sType);
- break;
- }
+ dzn_debug_ignored_stype(s->sType);
}
- if (!did_bind) {
- image->mem = mem;
- image->mem_offset = bind_info->memoryOffset;
-
- HRESULT hres = S_OK;
-
- if (mem->swapchain_res) {
- image->res = mem->swapchain_res;
- ID3D12Resource_AddRef(image->res);
- } else if (device->dev10 && image->castable_format_count > 0) {
- D3D12_RESOURCE_DESC1 desc = {
- .Dimension = image->desc.Dimension,
- .Alignment = image->desc.Alignment,
- .Width = image->desc.Width,
- .Height = image->desc.Height,
- .DepthOrArraySize = image->desc.DepthOrArraySize,
- .MipLevels = image->desc.MipLevels,
- .Format = image->desc.Format,
- .SampleDesc = image->desc.SampleDesc,
- .Layout = image->desc.Layout,
- .Flags = image->desc.Flags,
- };
-
- hres = ID3D12Device10_CreatePlacedResource2(device->dev10, mem->heap,
- bind_info->memoryOffset,
- &desc,
- D3D12_BARRIER_LAYOUT_COMMON,
- NULL,
- image->castable_format_count,
- image->castable_formats,
- &IID_ID3D12Resource,
- (void **)&image->res);
- } else {
- hres = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap,
- bind_info->memoryOffset,
- &image->desc,
- D3D12_RESOURCE_STATE_COMMON,
- NULL,
- &IID_ID3D12Resource,
- (void **)&image->res);
- }
- if (FAILED(hres))
- return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
- did_bind = true;
+ image->mem = mem;
+
+ HRESULT hres = S_OK;
+
+ if (mem->dedicated_res) {
+ assert(pBindInfos[i].memoryOffset == 0);
+ image->res = mem->dedicated_res;
+ ID3D12Resource_AddRef(image->res);
+ } else if (device->dev10 && image->castable_format_count > 0) {
+ D3D12_RESOURCE_DESC1 desc = {
+ .Dimension = image->desc.Dimension,
+ .Alignment = image->desc.Alignment,
+ .Width = image->desc.Width,
+ .Height = image->desc.Height,
+ .DepthOrArraySize = image->desc.DepthOrArraySize,
+ .MipLevels = image->desc.MipLevels,
+ .Format = image->desc.Format,
+ .SampleDesc = image->desc.SampleDesc,
+ .Layout = image->desc.Layout,
+ .Flags = image->desc.Flags,
+ };
+
+ hres = ID3D12Device10_CreatePlacedResource2(device->dev10, mem->heap,
+ bind_info->memoryOffset,
+ &desc,
+ D3D12_BARRIER_LAYOUT_COMMON,
+ NULL,
+ image->castable_format_count,
+ image->castable_formats,
+ &IID_ID3D12Resource,
+ (void **)&image->res);
+ } else {
+ hres = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap,
+ bind_info->memoryOffset,
+ &image->desc,
+ D3D12_RESOURCE_STATE_COMMON,
+ NULL,
+ &IID_ID3D12Resource,
+ (void **)&image->res);
}
+ if (FAILED(hres))
+ return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
}
return VK_SUCCESS;
@@ -907,9 +882,9 @@ dzn_GetImageMemoryRequirements2(VkDevice _device,
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *requirements =
(VkMemoryDedicatedRequirements *)ext;
- /* TODO: figure out dedicated allocations */
- requirements->prefersDedicatedAllocation = false;
requirements->requiresDedicatedAllocation = false;
+ requirements->prefersDedicatedAllocation = requirements->requiresDedicatedAllocation ||
+ image->vk.tiling == VK_IMAGE_TILING_OPTIMAL;
break;
}
diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h
index 4dea615c696..a5b312fb544 100644
--- a/src/microsoft/vulkan/dzn_private.h
+++ b/src/microsoft/vulkan/dzn_private.h
@@ -329,10 +329,10 @@ struct dzn_device_memory {
struct list_head link;
- /* Swapchain image resource, NULL if the memory is not backed by
- * a DXGI swapchain.
+ /* Dedicated image/buffer resource. Can be used for import (e.g. from a swapchain)
+ * or just from a dedicated allocation request.
*/
- ID3D12Resource *swapchain_res;
+ ID3D12Resource *dedicated_res;
ID3D12Heap *heap;
VkDeviceSize size;
@@ -1040,7 +1040,6 @@ struct dzn_image {
D3D12_RESOURCE_DESC desc;
ID3D12Resource *res;
struct dzn_device_memory *mem;
- VkDeviceSize mem_offset;
uint32_t castable_format_count;
const DXGI_FORMAT *castable_formats;
diff --git a/src/microsoft/vulkan/dzn_wsi.c b/src/microsoft/vulkan/dzn_wsi.c
index c66e2c74c62..e077532d199 100644
--- a/src/microsoft/vulkan/dzn_wsi.c
+++ b/src/microsoft/vulkan/dzn_wsi.c
@@ -68,8 +68,8 @@ dzn_wsi_create_image_memory(VkDevice dev, void *resource,
return VK_ERROR_OUT_OF_HOST_MEMORY;
vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY);
- mem->swapchain_res = resource;
- ID3D12Resource_AddRef(mem->swapchain_res);
+ mem->dedicated_res = resource;
+ ID3D12Resource_AddRef(mem->dedicated_res);
*out = dzn_device_memory_to_handle(mem);
return VK_SUCCESS;