mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
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>
This commit is contained in:
parent
7cc59ad973
commit
fb61340790
5 changed files with 160 additions and 152 deletions
|
|
@ -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) &&
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/* TODO: Unsure about this logic??? */
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
image->mem = mem;
|
||||
|
||||
HRESULT hres = S_OK;
|
||||
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,
|
||||
};
|
||||
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);
|
||||
did_bind = true;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue