Add support for KHX experimental external sharing extensions

* VK_KHX_external_memory
* VK_KHX_external_memory_capabilities
* VK_KHX_external_memory_fd
* VK_KHX_external_memory_win32
* VK_KHX_external_semaphore
* VK_KHX_external_semaphore_capabilities
* VK_KHX_external_semaphore_fd
* VK_KHX_external_semaphore_win32
* VK_KHX_win32_keyed_mutex
This commit is contained in:
baldurk
2017-03-09 19:13:25 +00:00
parent e0d1ce1c04
commit 9512a0fc68
8 changed files with 263 additions and 24 deletions
+20 -1
View File
@@ -57,6 +57,16 @@ void ReplacePresentableImageLayout(VkImageLayout &layout)
layout = VK_IMAGE_LAYOUT_GENERAL;
}
void ReplaceExternalQueueFamily(uint32_t &srcQueueFamily, uint32_t &dstQueueFamily)
{
if(srcQueueFamily == VK_QUEUE_FAMILY_EXTERNAL_KHX || dstQueueFamily == VK_QUEUE_FAMILY_EXTERNAL_KHX)
{
// we should ignore this family transition since we're not synchronising with an
// external access.
srcQueueFamily = dstQueueFamily = VK_QUEUE_FAMILY_IGNORED;
}
}
int SampleCount(VkSampleCountFlagBits countFlag)
{
switch(countFlag)
@@ -2850,7 +2860,16 @@ static void SerialiseNext(Serialiser *ser, VkStructureType &sType, const void *&
next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV)
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHX ||
next->sType == VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHX)
{
// do nothing
}
+5
View File
@@ -36,6 +36,10 @@
#define VK_NO_PROTOTYPES
#if defined(VK_USE_PLATFORM_WIN32_KHR)
#define VK_USE_PLATFORM_WIN32_KHX 1
#endif
#if ENABLED(RDOC_X64)
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
@@ -85,6 +89,7 @@ VkPrimitiveTopology MakeVkPrimitiveTopology(PrimitiveTopology Topo);
VkAccessFlags MakeAccessMask(VkImageLayout layout);
void ReplacePresentableImageLayout(VkImageLayout &layout);
void ReplaceExternalQueueFamily(uint32_t &srcQueueFamily, uint32_t &dstQueueFamily);
void DoPipelineBarrier(VkCommandBuffer cmd, uint32_t count, VkImageMemoryBarrier *barriers);
void DoPipelineBarrier(VkCommandBuffer cmd, uint32_t count, VkBufferMemoryBarrier *barriers);
+57
View File
@@ -788,6 +788,41 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION,
},
#endif
{
VK_KHX_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHX_EXTERNAL_MEMORY_SPEC_VERSION,
},
{
VK_KHX_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
VK_KHX_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION,
},
{
VK_KHX_EXTERNAL_MEMORY_FD_EXTENSION_NAME, VK_KHX_EXTERNAL_MEMORY_FD_SPEC_VERSION,
},
#ifdef VK_KHX_external_memory_win32
{
VK_KHX_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, VK_KHX_EXTERNAL_MEMORY_WIN32_SPEC_VERSION,
},
#endif
{
VK_KHX_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_KHX_EXTERNAL_SEMAPHORE_SPEC_VERSION,
},
{
VK_KHX_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
VK_KHX_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION,
},
{
VK_KHX_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHX_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION,
},
#ifdef VK_KHX_external_semaphore_win32
{
VK_KHX_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, VK_KHX_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION,
},
#endif
#ifdef VK_KHX_win32_keyed_mutex
{
VK_KHX_WIN32_KEYED_MUTEX_EXTENSION_NAME, VK_KHX_WIN32_KEYED_MUTEX_SPEC_VERSION,
},
#endif
{
VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION,
@@ -811,6 +846,24 @@ static const VkExtensionProperties supportedExtensions[] = {
#endif
};
static void ValidateSupportedExtensionList()
{
// this should be a unit test
#if DISABLED(RDOC_RELEASE)
std::vector<VkExtensionProperties> unsorted;
unsorted.insert(unsorted.begin(), &supportedExtensions[0],
&supportedExtensions[ARRAY_COUNT(supportedExtensions)]);
std::vector<VkExtensionProperties> sorted = unsorted;
std::sort(sorted.begin(), sorted.end());
for(size_t i = 0; i < unsorted.size(); i++)
if(strcmp(unsorted[i].extensionName, sorted[i].extensionName))
RDCFATAL("supportedExtensions list is not sorted");
#endif
}
// this is the list of extensions we provide - regardless of whether the ICD supports them
static const VkExtensionProperties renderdocProvidedExtensions[] = {
{VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION},
@@ -853,6 +906,8 @@ VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev
std::vector<VkExtensionProperties> filtered;
filtered.reserve(exts.size());
ValidateSupportedExtensionList();
// now we can step through both lists with two pointers,
// instead of doing an O(N*M) lookup searching through each
// supported extension for each reported extension.
@@ -1545,6 +1600,8 @@ void WrappedVulkan::ReadLogInitialisation()
uint64_t lastFrame = 0;
uint64_t firstFrame = 0;
ValidateSupportedExtensionList();
m_pSerialiser->SetDebugText(true);
m_pSerialiser->Rewind();
+40
View File
@@ -1348,6 +1348,21 @@ public:
// VK_NV_external_memory_win32
VkResult vkGetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE *pHandle);
// VK_KHX_external_memory_win32
VkResult vkGetMemoryWin32HandleKHX(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagBitsKHX handleType,
HANDLE *pHandle);
VkResult vkGetMemoryWin32HandlePropertiesKHX(
VkDevice device, VkExternalMemoryHandleTypeFlagBitsKHX handleType, HANDLE handle,
VkMemoryWin32HandlePropertiesKHX *pMemoryWin32HandleProperties);
// VK_KHX_external_semaphore_win32
VkResult vkImportSemaphoreWin32HandleKHX(
VkDevice device, const VkImportSemaphoreWin32HandleInfoKHX *pImportSemaphoreWin32HandleInfo);
VkResult vkGetSemaphoreWin32HandleKHX(VkDevice device, VkSemaphore semaphore,
VkExternalSemaphoreHandleTypeFlagBitsKHX handleType,
HANDLE *pHandle);
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
@@ -1468,4 +1483,29 @@ public:
// VK_EXT_direct_mode_display
VkResult vkReleaseDisplayEXT(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
// VK_KHX_external_memory_capabilities
void vkGetPhysicalDeviceExternalBufferPropertiesKHX(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfoKHX *pExternalBufferInfo,
VkExternalBufferPropertiesKHX *pExternalBufferProperties);
// VK_KHX_external_memory_fd
VkResult vkGetMemoryFdKHX(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagBitsKHX handleType, int *pFd);
VkResult vkGetMemoryFdPropertiesKHX(VkDevice device,
VkExternalMemoryHandleTypeFlagBitsKHX handleType, int fd,
VkMemoryFdPropertiesKHX *pMemoryFdProperties);
// VK_KHX_external_semaphore_capabilities
void vkGetPhysicalDeviceExternalSemaphorePropertiesKHX(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalSemaphoreInfoKHX *pExternalSemaphoreInfo,
VkExternalSemaphorePropertiesKHX *pExternalSemaphoreProperties);
// VK_KHX_external_semaphore_fd
VkResult vkImportSemaphoreFdKHX(VkDevice device,
const VkImportSemaphoreFdInfoKHX *pImportSemaphoreFdInfo);
VkResult vkGetSemaphoreFdKHX(VkDevice device, VkSemaphore semaphore,
VkExternalSemaphoreHandleTypeFlagBitsKHX handleType, int *pFd);
};
@@ -1865,6 +1865,9 @@ bool WrappedVulkan::Serialise_vkCmdPipelineBarrier(
imgBarriers.push_back(imgMemBarriers[i]);
ReplacePresentableImageLayout(imgBarriers.back().oldLayout);
ReplacePresentableImageLayout(imgBarriers.back().newLayout);
ReplaceExternalQueueFamily(imgBarriers.back().srcQueueFamilyIndex,
imgBarriers.back().dstQueueFamilyIndex);
}
}
}
@@ -253,8 +253,58 @@ VkResult WrappedVulkan::vkGetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory
{
return ObjDisp(device)->GetMemoryWin32HandleNV(Unwrap(device), Unwrap(memory), handleType, pHandle);
}
VkResult WrappedVulkan::vkGetMemoryWin32HandleKHX(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagBitsKHX handleType,
HANDLE *pHandle)
{
return ObjDisp(device)->GetMemoryWin32HandleKHX(Unwrap(device), Unwrap(memory), handleType,
pHandle);
}
VkResult WrappedVulkan::vkGetMemoryWin32HandlePropertiesKHX(
VkDevice device, VkExternalMemoryHandleTypeFlagBitsKHX handleType, HANDLE handle,
VkMemoryWin32HandlePropertiesKHX *pMemoryWin32HandleProperties)
{
return ObjDisp(device)->GetMemoryWin32HandlePropertiesKHX(Unwrap(device), handleType, handle,
pMemoryWin32HandleProperties);
}
#endif
VkResult WrappedVulkan::vkGetMemoryFdKHX(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagBitsKHX handleType, int *pFd)
{
return ObjDisp(device)->GetMemoryFdKHX(Unwrap(device), Unwrap(memory), handleType, pFd);
}
VkResult WrappedVulkan::vkGetMemoryFdPropertiesKHX(VkDevice device,
VkExternalMemoryHandleTypeFlagBitsKHX handleType,
int fd,
VkMemoryFdPropertiesKHX *pMemoryFdProperties)
{
return ObjDisp(device)->GetMemoryFdPropertiesKHX(Unwrap(device), handleType, fd,
pMemoryFdProperties);
}
void WrappedVulkan::vkGetPhysicalDeviceExternalBufferPropertiesKHX(
VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHX *pExternalBufferInfo,
VkExternalBufferPropertiesKHX *pExternalBufferProperties)
{
return ObjDisp(physicalDevice)
->GetPhysicalDeviceExternalBufferPropertiesKHX(Unwrap(physicalDevice), pExternalBufferInfo,
pExternalBufferProperties);
}
void WrappedVulkan::vkGetPhysicalDeviceExternalSemaphorePropertiesKHX(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalSemaphoreInfoKHX *pExternalSemaphoreInfo,
VkExternalSemaphorePropertiesKHX *pExternalSemaphoreProperties)
{
return ObjDisp(physicalDevice)
->GetPhysicalDeviceExternalSemaphorePropertiesKHX(
Unwrap(physicalDevice), pExternalSemaphoreInfo, pExternalSemaphoreProperties);
}
void WrappedVulkan::vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2KHR *pFeatures)
{
@@ -470,18 +470,42 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
{
RDCERR("Invalid extension structure");
}
else if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV)
else if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHX)
{
#ifdef VK_NV_win32_keyed_mutex
tempmemSize += sizeof(VkWin32KeyedMutexAcquireReleaseInfoNV);
#ifdef VK_USE_PLATFORM_WIN32_KHR
// make sure the structures are still identical
RDCCOMPILE_ASSERT(sizeof(VkWin32KeyedMutexAcquireReleaseInfoNV) ==
sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHX),
"Structs are different!");
VkWin32KeyedMutexAcquireReleaseInfoNV *info = (VkWin32KeyedMutexAcquireReleaseInfoNV *)next;
#define NV_DUMMY ((VkWin32KeyedMutexAcquireReleaseInfoNV *)NULL)
#define KHX_DUMMY ((VkWin32KeyedMutexAcquireReleaseInfoKHX *)NULL)
RDCCOMPILE_ASSERT(&NV_DUMMY->acquireCount == &KHX_DUMMY->acquireCount,
"Structs are different!");
RDCCOMPILE_ASSERT(&NV_DUMMY->releaseCount == &KHX_DUMMY->releaseCount,
"Structs are different!");
RDCCOMPILE_ASSERT(&NV_DUMMY->pAcquireSyncs == &KHX_DUMMY->pAcquireSyncs,
"Structs are different!");
RDCCOMPILE_ASSERT(&NV_DUMMY->pReleaseSyncs == &KHX_DUMMY->pReleaseSyncs,
"Structs are different!");
#undef NV_DUMMY
#undef KHX_DUMMY
tempmemSize += sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHX);
VkWin32KeyedMutexAcquireReleaseInfoKHX *info = (VkWin32KeyedMutexAcquireReleaseInfoKHX *)next;
tempmemSize += info->acquireCount * sizeof(VkDeviceMemory);
tempmemSize += info->releaseCount * sizeof(VkDeviceMemory);
#else
RDCERR("Support for VK_NV_win32_keyed_mutex not compiled in");
RDCERR("Unexpected use of Win32 Keyed Mutex extension without support compiled in");
#endif
}
else if(next->sType == VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHX)
{
// nothing to do - this is plain old data with nothing to unwrap so we can keep it in the
// pNext chain as-is
}
else
{
RDCERR("Unexpected extension structure %d", next->sType);
@@ -531,40 +555,41 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
{
VkGenericStruct *next = *nextptr;
#ifdef VK_NV_win32_keyed_mutex
if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV)
if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV ||
next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHX)
{
#ifdef VK_USE_PLATFORM_WIN32_KHR
// allocate local unwrapped struct
VkWin32KeyedMutexAcquireReleaseInfoNV *unwrappedMutexInfoNV =
(VkWin32KeyedMutexAcquireReleaseInfoNV *)memory;
memory += sizeof(VkWin32KeyedMutexAcquireReleaseInfoNV);
VkWin32KeyedMutexAcquireReleaseInfoKHX *unwrappedMutexInfoKHX =
(VkWin32KeyedMutexAcquireReleaseInfoKHX *)memory;
memory += sizeof(VkWin32KeyedMutexAcquireReleaseInfoKHX);
// copy over info from original struct
VkWin32KeyedMutexAcquireReleaseInfoNV *wrappedMutexInfoNV =
(VkWin32KeyedMutexAcquireReleaseInfoNV *)next;
*unwrappedMutexInfoNV = *wrappedMutexInfoNV;
VkWin32KeyedMutexAcquireReleaseInfoKHX *wrappedMutexInfoKHX =
(VkWin32KeyedMutexAcquireReleaseInfoKHX *)next;
*unwrappedMutexInfoKHX = *wrappedMutexInfoKHX;
// allocate unwrapped arrays
VkDeviceMemory *unwrappedAcquires = (VkDeviceMemory *)memory;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoNV->acquireCount;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoKHX->acquireCount;
VkDeviceMemory *unwrappedReleases = (VkDeviceMemory *)memory;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoNV->releaseCount;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoKHX->releaseCount;
// unwrap the arrays
for(uint32_t mem = 0; mem < unwrappedMutexInfoNV->acquireCount; mem++)
unwrappedAcquires[mem] = Unwrap(wrappedMutexInfoNV->pAcquireSyncs[mem]);
for(uint32_t mem = 0; mem < unwrappedMutexInfoNV->releaseCount; mem++)
unwrappedReleases[mem] = Unwrap(wrappedMutexInfoNV->pReleaseSyncs[mem]);
for(uint32_t mem = 0; mem < unwrappedMutexInfoKHX->acquireCount; mem++)
unwrappedAcquires[mem] = Unwrap(wrappedMutexInfoKHX->pAcquireSyncs[mem]);
for(uint32_t mem = 0; mem < unwrappedMutexInfoKHX->releaseCount; mem++)
unwrappedReleases[mem] = Unwrap(wrappedMutexInfoKHX->pReleaseSyncs[mem]);
unwrappedMutexInfoNV->pAcquireSyncs = unwrappedAcquires;
unwrappedMutexInfoNV->pReleaseSyncs = unwrappedReleases;
unwrappedMutexInfoKHX->pAcquireSyncs = unwrappedAcquires;
unwrappedMutexInfoKHX->pReleaseSyncs = unwrappedReleases;
// insert this struct into the chain.
// nextptr is pointing to the address of the pNext, so we can overwrite it to point to our
// locally-allocated unwrapped struct
*nextptr = (VkGenericStruct *)unwrappedMutexInfoNV;
}
*nextptr = (VkGenericStruct *)unwrappedMutexInfoKHX;
#endif
}
nextptr = (VkGenericStruct **)&next->pNext;
}
@@ -700,6 +700,9 @@ bool WrappedVulkan::Serialise_vkCmdWaitEvents(
imgBarriers.push_back(imgMemBarriers[i]);
ReplacePresentableImageLayout(imgBarriers.back().oldLayout);
ReplacePresentableImageLayout(imgBarriers.back().newLayout);
ReplaceExternalQueueFamily(imgBarriers.back().srcQueueFamilyIndex,
imgBarriers.back().dstQueueFamilyIndex);
}
}
}
@@ -834,3 +837,40 @@ void WrappedVulkan::vkCmdWaitEvents(VkCommandBuffer cmdBuffer, uint32_t eventCou
record->MarkResourceFrameReferenced(GetResID(pEvents[i]), eFrameRef_Read);
}
}
VkResult WrappedVulkan::vkImportSemaphoreFdKHX(VkDevice device,
const VkImportSemaphoreFdInfoKHX *pImportSemaphoreFdInfo)
{
VkImportSemaphoreFdInfoKHX unwrappedInfo = *pImportSemaphoreFdInfo;
unwrappedInfo.semaphore = Unwrap(unwrappedInfo.semaphore);
return ObjDisp(device)->ImportSemaphoreFdKHX(Unwrap(device), &unwrappedInfo);
}
VkResult WrappedVulkan::vkGetSemaphoreFdKHX(VkDevice device, VkSemaphore semaphore,
VkExternalSemaphoreHandleTypeFlagBitsKHX handleType,
int *pFd)
{
return ObjDisp(device)->GetSemaphoreFdKHX(Unwrap(device), Unwrap(semaphore), handleType, pFd);
}
#if defined(VK_USE_PLATFORM_WIN32_KHR)
VkResult WrappedVulkan::vkImportSemaphoreWin32HandleKHX(
VkDevice device, const VkImportSemaphoreWin32HandleInfoKHX *pImportSemaphoreWin32HandleInfo)
{
VkImportSemaphoreWin32HandleInfoKHX unwrappedInfo = *pImportSemaphoreWin32HandleInfo;
unwrappedInfo.semaphore = Unwrap(unwrappedInfo.semaphore);
return ObjDisp(device)->ImportSemaphoreWin32HandleKHX(Unwrap(device), &unwrappedInfo);
}
VkResult WrappedVulkan::vkGetSemaphoreWin32HandleKHX(VkDevice device, VkSemaphore semaphore,
VkExternalSemaphoreHandleTypeFlagBitsKHX handleType,
HANDLE *pHandle)
{
return ObjDisp(device)->GetSemaphoreWin32HandleKHX(Unwrap(device), Unwrap(semaphore), handleType,
pHandle);
}
#endif