mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-20 16:30:50 +02:00
dzn: VK_EXT_external_memory_host
When ID3D12Device13 is available, we can support importing host memory. Imported host memory can be used to back buffers and linear textures. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23886>
This commit is contained in:
parent
a831ee51ae
commit
f0569cdba0
3 changed files with 151 additions and 8 deletions
|
|
@ -147,6 +147,9 @@ dzn_physical_device_get_extensions(struct dzn_physical_device *pdev)
|
|||
.KHR_timeline_semaphore = true,
|
||||
.KHR_uniform_buffer_standard_layout = true,
|
||||
.EXT_descriptor_indexing = pdev->shader_model >= D3D_SHADER_MODEL_6_6,
|
||||
#if defined(_WIN32) && D3D12_SDK_VERSION >= 611
|
||||
.EXT_external_memory_host = pdev->dev13,
|
||||
#endif
|
||||
.EXT_scalar_block_layout = true,
|
||||
.EXT_separate_stencil_usage = true,
|
||||
.EXT_shader_subgroup_ballot = true,
|
||||
|
|
@ -203,6 +206,11 @@ dzn_physical_device_destroy(struct vk_physical_device *physical)
|
|||
if (pdev->dev12)
|
||||
ID3D12Device1_Release(pdev->dev12);
|
||||
|
||||
#if D3D12_SDK_VERSION >= 611
|
||||
if (pdev->dev13)
|
||||
ID3D12Device1_Release(pdev->dev13);
|
||||
#endif
|
||||
|
||||
if (pdev->adapter)
|
||||
IUnknown_Release(pdev->adapter);
|
||||
|
||||
|
|
@ -826,6 +834,10 @@ dzn_physical_device_create(struct vk_instance *instance,
|
|||
pdev->dev11 = NULL;
|
||||
if (FAILED(ID3D12Device1_QueryInterface(pdev->dev, &IID_ID3D12Device12, (void **)&pdev->dev12)))
|
||||
pdev->dev12 = NULL;
|
||||
#if D3D12_SDK_VERSION >= 611
|
||||
if (FAILED(ID3D12Device1_QueryInterface(pdev->dev, &IID_ID3D12Device13, (void **)&pdev->dev13)))
|
||||
pdev->dev13 = NULL;
|
||||
#endif
|
||||
dzn_physical_device_cache_caps(pdev);
|
||||
dzn_physical_device_init_memory(pdev);
|
||||
dzn_physical_device_init_uuids(pdev);
|
||||
|
|
@ -1129,12 +1141,24 @@ dzn_physical_device_get_image_format_properties(struct dzn_physical_device *pdev
|
|||
external_props->externalMemoryProperties.exportFromImportedHandleTypes = d3d11_texture_handle_types;
|
||||
external_props->externalMemoryProperties.externalMemoryFeatures = import_export_feature_flags;
|
||||
break;
|
||||
#if defined(_WIN32) && D3D12_SDK_VERSION >= 611
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
|
||||
if (pdev->dev13) {
|
||||
external_props->externalMemoryProperties.compatibleHandleTypes =
|
||||
external_props->externalMemoryProperties.exportFromImportedHandleTypes =
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT | opaque_external_flag;
|
||||
external_props->externalMemoryProperties.externalMemoryFeatures = import_export_feature_flags;
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
#endif
|
||||
default:
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Linear textures not supported, but there's nothing else we can deduce from just a handle type */
|
||||
if (info->tiling != VK_IMAGE_TILING_OPTIMAL)
|
||||
if (info->tiling != VK_IMAGE_TILING_OPTIMAL &&
|
||||
external_info->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT)
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
|
@ -1340,6 +1364,10 @@ dzn_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,
|
|||
const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
|
||||
VkExternalBufferProperties *pExternalBufferProperties)
|
||||
{
|
||||
#if defined(_WIN32) && D3D12_SDK_VERSION >= 611
|
||||
VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice);
|
||||
#endif
|
||||
|
||||
const VkExternalMemoryHandleTypeFlags d3d12_resource_handle_types =
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT | opaque_external_flag;
|
||||
const VkExternalMemoryFeatureFlags import_export_feature_flags =
|
||||
|
|
@ -1368,6 +1396,17 @@ dzn_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,
|
|||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT | d3d12_resource_handle_types;
|
||||
pExternalBufferProperties->externalMemoryProperties.externalMemoryFeatures = import_export_feature_flags;
|
||||
break;
|
||||
#if defined(_WIN32) && D3D12_SDK_VERSION >= 611
|
||||
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
|
||||
if (pdev->dev13) {
|
||||
pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes =
|
||||
pExternalBufferProperties->externalMemoryProperties.exportFromImportedHandleTypes =
|
||||
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT | opaque_external_flag;
|
||||
pExternalBufferProperties->externalMemoryProperties.externalMemoryFeatures = import_export_feature_flags;
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
#endif
|
||||
default:
|
||||
pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties){ 0 };
|
||||
break;
|
||||
|
|
@ -1912,6 +1951,14 @@ dzn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
|
|||
attr_div->maxVertexAttribDivisor = UINT32_MAX;
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {
|
||||
VkPhysicalDeviceExternalMemoryHostPropertiesEXT *host_props =
|
||||
(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *)ext;
|
||||
host_props->minImportedHostPointerAlignment = 65536;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
dzn_debug_ignored_stype(ext->sType);
|
||||
break;
|
||||
|
|
@ -2231,6 +2278,11 @@ dzn_device_destroy(struct dzn_device *device, const VkAllocationCallbacks *pAllo
|
|||
if (device->dev12)
|
||||
ID3D12Device1_Release(device->dev12);
|
||||
|
||||
#if D3D12_SDK_VERSION >= 611
|
||||
if (device->dev13)
|
||||
ID3D12Device1_Release(device->dev13);
|
||||
#endif
|
||||
|
||||
vk_device_finish(&device->vk);
|
||||
vk_free2(&instance->vk.alloc, pAllocator, device);
|
||||
}
|
||||
|
|
@ -2332,6 +2384,13 @@ dzn_device_create(struct dzn_physical_device *pdev,
|
|||
ID3D12Device1_AddRef(device->dev12);
|
||||
}
|
||||
|
||||
#if D3D12_SDK_VERSION >= 611
|
||||
if (pdev->dev13) {
|
||||
device->dev13 = pdev->dev13;
|
||||
ID3D12Device1_AddRef(device->dev13);
|
||||
}
|
||||
#endif
|
||||
|
||||
ID3D12InfoQueue *info_queue;
|
||||
if (SUCCEEDED(ID3D12Device1_QueryInterface(device->dev,
|
||||
&IID_ID3D12InfoQueue,
|
||||
|
|
@ -2534,7 +2593,7 @@ dzn_device_memory_destroy(struct dzn_device_memory *mem,
|
|||
|
||||
struct dzn_device *device = container_of(mem->base.device, struct dzn_device, vk);
|
||||
|
||||
if (mem->map)
|
||||
if (mem->map && mem->map_res)
|
||||
ID3D12Resource_Unmap(mem->map_res, 0, NULL);
|
||||
|
||||
if (mem->map_res)
|
||||
|
|
@ -2593,6 +2652,7 @@ dzn_device_memory_create(struct dzn_device *device,
|
|||
VkExternalMemoryHandleTypeFlags export_flags = 0;
|
||||
HANDLE import_handle = NULL;
|
||||
bool imported_from_d3d11 = false;
|
||||
void *host_pointer = NULL;
|
||||
#ifdef _WIN32
|
||||
const wchar_t *import_name = NULL;
|
||||
const VkExportMemoryWin32HandleInfoKHR *win32_export = NULL;
|
||||
|
|
@ -2628,6 +2688,12 @@ dzn_device_memory_create(struct dzn_device *device,
|
|||
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR:
|
||||
win32_export = (const VkExportMemoryWin32HandleInfoKHR *)ext;
|
||||
break;
|
||||
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT: {
|
||||
const VkImportMemoryHostPointerInfoEXT *imp =
|
||||
(const VkImportMemoryHostPointerInfoEXT *)ext;
|
||||
host_pointer = imp->pHostPointer;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR: {
|
||||
const VkImportMemoryFdInfoKHR *imp =
|
||||
|
|
@ -2716,7 +2782,7 @@ dzn_device_memory_create(struct dzn_device *device,
|
|||
heap_desc.Properties = deduce_heap_properties_from_memory(pdevice, mem_type);
|
||||
if (export_flags) {
|
||||
heap_desc.Flags |= D3D12_HEAP_FLAG_SHARED;
|
||||
assert(heap_desc.Properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE);
|
||||
assert(host_pointer || heap_desc.Properties.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
VkResult error = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
|
@ -2732,7 +2798,31 @@ dzn_device_memory_create(struct dzn_device *device,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (import_handle) {
|
||||
if (host_pointer) {
|
||||
error = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
|
||||
#if defined(_WIN32) && D3D12_SDK_VERSION >= 611
|
||||
if (!device->dev13)
|
||||
goto cleanup;
|
||||
|
||||
if (FAILED(ID3D12Device13_OpenExistingHeapFromAddress1(device->dev13, host_pointer, heap_desc.SizeInBytes, &IID_ID3D12Heap, &mem->heap)))
|
||||
goto cleanup;
|
||||
|
||||
D3D12_HEAP_DESC desc = dzn_ID3D12Heap_GetDesc(mem->heap);
|
||||
if (desc.Properties.Type != D3D12_HEAP_TYPE_CUSTOM)
|
||||
desc.Properties = dzn_ID3D12Device4_GetCustomHeapProperties(device->dev, 0, desc.Properties.Type);
|
||||
|
||||
if ((heap_desc.Flags & ~desc.Flags) ||
|
||||
desc.Properties.CPUPageProperty != heap_desc.Properties.CPUPageProperty ||
|
||||
desc.Properties.MemoryPoolPreference != heap_desc.Properties.MemoryPoolPreference)
|
||||
goto cleanup;
|
||||
|
||||
mem->map = host_pointer;
|
||||
mem->res_flags = D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER;
|
||||
#else
|
||||
goto cleanup;
|
||||
#endif
|
||||
} else if (import_handle) {
|
||||
error = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
if (image || buffer) {
|
||||
if (FAILED(ID3D12Device_OpenSharedHandle(device->dev, import_handle, &IID_ID3D12Resource, (void **)&mem->dedicated_res)))
|
||||
|
|
@ -2830,7 +2920,8 @@ dzn_device_memory_create(struct dzn_device *device,
|
|||
}
|
||||
|
||||
if ((mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&
|
||||
!(heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS)){
|
||||
!(heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS) &&
|
||||
!mem->map){
|
||||
assert(!image);
|
||||
if (buffer) {
|
||||
mem->map_res = mem->dedicated_res;
|
||||
|
|
@ -2920,6 +3011,11 @@ dzn_MapMemory(VkDevice _device,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (mem->map && !mem->map_res) {
|
||||
*ppData = ((uint8_t *)mem->map) + offset;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (size == VK_WHOLE_SIZE)
|
||||
size = mem->size - offset;
|
||||
|
||||
|
|
@ -2958,7 +3054,9 @@ dzn_UnmapMemory(VkDevice _device,
|
|||
if (mem == NULL)
|
||||
return;
|
||||
|
||||
assert(mem->map_res);
|
||||
if (!mem->map_res)
|
||||
return;
|
||||
|
||||
ID3D12Resource_Unmap(mem->map_res, 0, NULL);
|
||||
|
||||
mem->map = NULL;
|
||||
|
|
@ -3273,6 +3371,8 @@ dzn_BindBufferMemory2(VkDevice _device,
|
|||
buffer->res = mem->dedicated_res;
|
||||
ID3D12Resource_AddRef(buffer->res);
|
||||
} else {
|
||||
D3D12_RESOURCE_DESC desc = buffer->desc;
|
||||
desc.Flags |= mem->res_flags;
|
||||
if (FAILED(ID3D12Device1_CreatePlacedResource(device->dev, mem->heap,
|
||||
pBindInfos[i].memoryOffset,
|
||||
&buffer->desc,
|
||||
|
|
@ -3805,3 +3905,35 @@ cleanup:
|
|||
ID3D12Heap_Release(heap);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && D3D12_SDK_VERSION >= 611
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_GetMemoryHostPointerPropertiesEXT(VkDevice _device,
|
||||
VkExternalMemoryHandleTypeFlagBits handleType,
|
||||
const void *pHostPointer,
|
||||
VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, _device);
|
||||
|
||||
if (!device->dev13)
|
||||
return VK_ERROR_FEATURE_NOT_PRESENT;
|
||||
|
||||
ID3D12Heap *heap;
|
||||
if (FAILED(ID3D12Device13_OpenExistingHeapFromAddress1(device->dev13, pHostPointer, 1, &IID_ID3D12Heap, &heap)))
|
||||
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
||||
|
||||
struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk);
|
||||
D3D12_HEAP_DESC heap_desc = dzn_ID3D12Heap_GetDesc(heap);
|
||||
for (uint32_t i = 0; i < pdev->memory.memoryTypeCount; ++i) {
|
||||
const VkMemoryType *mem_type = &pdev->memory.memoryTypes[i];
|
||||
D3D12_HEAP_PROPERTIES required_props = deduce_heap_properties_from_memory(pdev, mem_type);
|
||||
if (heap_desc.Properties.CPUPageProperty != required_props.CPUPageProperty ||
|
||||
heap_desc.Properties.MemoryPoolPreference != required_props.MemoryPoolPreference)
|
||||
continue;
|
||||
|
||||
pMemoryHostPointerProperties->memoryTypeBits |= (1 << i);
|
||||
}
|
||||
ID3D12Heap_Release(heap);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -843,7 +843,7 @@ dzn_BindImageMemory2(VkDevice dev,
|
|||
.Format = image->desc.Format,
|
||||
.SampleDesc = image->desc.SampleDesc,
|
||||
.Layout = image->desc.Layout,
|
||||
.Flags = image->desc.Flags,
|
||||
.Flags = image->desc.Flags | mem->res_flags,
|
||||
};
|
||||
|
||||
hres = ID3D12Device10_CreatePlacedResource2(device->dev10, mem->heap,
|
||||
|
|
@ -856,9 +856,11 @@ dzn_BindImageMemory2(VkDevice dev,
|
|||
&IID_ID3D12Resource,
|
||||
(void **)&image->res);
|
||||
} else {
|
||||
D3D12_RESOURCE_DESC desc = image->desc;
|
||||
desc.Flags |= mem->res_flags;
|
||||
hres = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap,
|
||||
bind_info->memoryOffset,
|
||||
&image->desc,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
NULL,
|
||||
&IID_ID3D12Resource,
|
||||
|
|
|
|||
|
|
@ -202,6 +202,9 @@ struct dzn_physical_device {
|
|||
ID3D12Device10 *dev10;
|
||||
ID3D12Device11 *dev11;
|
||||
ID3D12Device12 *dev12;
|
||||
#if D3D12_SDK_VERSION >= 611
|
||||
ID3D12Device13 *dev13;
|
||||
#endif
|
||||
D3D_FEATURE_LEVEL feature_level;
|
||||
D3D_SHADER_MODEL shader_model;
|
||||
D3D_ROOT_SIGNATURE_VERSION root_sig_version;
|
||||
|
|
@ -287,6 +290,9 @@ struct dzn_device {
|
|||
ID3D12Device10 *dev10;
|
||||
ID3D12Device11 *dev11;
|
||||
ID3D12Device12 *dev12;
|
||||
#if D3D12_SDK_VERSION >= 611
|
||||
ID3D12Device13 *dev13;
|
||||
#endif
|
||||
ID3D12DeviceConfiguration *dev_config;
|
||||
|
||||
struct dzn_meta_indirect_draw indirect_draws[DZN_NUM_INDIRECT_DRAW_TYPES];
|
||||
|
|
@ -345,6 +351,9 @@ struct dzn_device_memory {
|
|||
|
||||
/* If the resource is exportable, this is the pre-created handle for that */
|
||||
HANDLE export_handle;
|
||||
|
||||
/* These flags need to be added into all resources created on this heap */
|
||||
D3D12_RESOURCE_FLAGS res_flags;
|
||||
};
|
||||
|
||||
enum dzn_cmd_bindpoint_dirty {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue