diff options
author | Jesse Natalie <jenatali@microsoft.com> | 2023-05-03 21:17:12 -0700 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-05-15 17:14:20 +0000 |
commit | fb613407905de9aea2db685c009f114d902229ab (patch) | |
tree | 13454136d16c4aa4e160523e2f8c0fb70e07d389 | |
parent | 7cc59ad9736ddaaeeeeee7bc5c2f21c0b1df6be1 (diff) | |
download | mesa-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.c | 17 | ||||
-rw-r--r-- | src/microsoft/vulkan/dzn_device.c | 177 | ||||
-rw-r--r-- | src/microsoft/vulkan/dzn_image.c | 113 | ||||
-rw-r--r-- | src/microsoft/vulkan/dzn_private.h | 7 | ||||
-rw-r--r-- | src/microsoft/vulkan/dzn_wsi.c | 4 |
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; |