Add simple support for NV_external_memory family of extensions

* This might not precisely reflect the contents of memory from external
  APIs, but it will at least run without crashing and allow programs
  that rely on the extension to function and capture for inspecting
  internal vulkan work.
This commit is contained in:
baldurk
2016-12-08 19:05:03 +00:00
parent a076db493e
commit 437bf0a199
10 changed files with 318 additions and 89 deletions
+28 -8
View File
@@ -2762,11 +2762,37 @@ static void SerialiseNext(Serialiser *ser, VkStructureType &sType, const void *&
{
ser->Serialise("sType", sType);
// we don't support any extensions, so pNext must always be NULL
if(ser->IsReading())
{
pNext = NULL;
}
else
RDCASSERT(pNext == NULL);
{
if(pNext == NULL)
return;
VkGenericStruct *next = (VkGenericStruct *)pNext;
while(next)
{
// we can ignore this entirely, we don't need to serialise or replay it as we won't
// actually use external memory. Unwrapping, if necessary, happens elsewhere
if(next->sType == VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV ||
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)
{
// do nothing
}
else
{
RDCERR("Unrecognised extension structure type %d", next->sType);
}
next = (VkGenericStruct *)next->pNext;
}
}
}
template <typename T>
@@ -2788,12 +2814,6 @@ void SerialiseOptionalObject(Serialiser *ser, const char *name, T *&el)
}
}
template <>
void Serialiser::Serialise(const char *name, VkGenericStruct &el)
{
ScopedContext scope(this, name, "NextStructure", 0, true);
}
template <>
void Serialiser::Serialise(const char *name, VkDeviceQueueCreateInfo &el)
{
+91 -32
View File
@@ -682,11 +682,101 @@ bool operator<(const VkExtensionProperties &a, const VkExtensionProperties &b)
return strcmp(a.extensionName, b.extensionName) < 0;
}
// This list must be kept sorted according to the above sort operator!
static const VkExtensionProperties supportedExtensions[] = {
// this extension is 'free' - it just marks SPIR-V extension availability
{
VK_AMD_GCN_SHADER_EXTENSION_NAME, VK_AMD_GCN_SHADER_SPEC_VERSION,
},
// this extension is 'free' - it just marks SPIR-V extension availability
{
VK_AMD_SHADER_BALLOT_EXTENSION_NAME, VK_AMD_SHADER_BALLOT_SPEC_VERSION,
},
// this extension is 'free' - it just marks SPIR-V extension availability
{
VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME,
VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION,
},
// this extension is 'free' - it just marks SPIR-V extension availability
{
VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME, VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION,
},
{
VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
},
#ifdef VK_KHR_android_surface
{
VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_SPEC_VERSION,
},
#endif
#ifdef VK_KHR_display
{
VK_KHR_DISPLAY_EXTENSION_NAME, VK_KHR_DISPLAY_SPEC_VERSION,
},
#endif
#ifdef VK_KHR_display_swapchain
{
VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME, VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION,
},
#endif
{
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION,
},
{
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION,
},
{
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION,
},
#ifdef VK_KHR_win32_surface
{
VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION,
},
#endif
#ifdef VK_KHR_xcb_surface
{
VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_SPEC_VERSION,
},
#endif
#ifdef VK_KHR_xlib_surface
{
VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION,
},
#endif
{
VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME, VK_NV_EXTERNAL_MEMORY_SPEC_VERSION,
},
{
VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION,
},
#ifdef VK_NV_external_memory_win32
{
VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION,
},
#endif
#ifdef VK_NV_win32_keyed_mutex
{
VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME, VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION,
},
#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},
};
bool WrappedVulkan::IsSupportedExtension(const char *extName)
{
for(size_t i = 0; i < ARRAY_COUNT(supportedExtensions); i++)
if(!strcmp(supportedExtensions[i].extensionName, extName))
return true;
return false;
}
VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev,
uint32_t *pPropertyCount,
VkExtensionProperties *pProperties)
@@ -707,38 +797,7 @@ VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev
if(vkr != VK_SUCCESS)
return vkr;
// filter the list of extensions to only the ones we support. Note it's important that
// this list is kept sorted according to the above sort operator!
const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
},
{
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION,
},
{
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION,
},
{
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION,
},
#ifdef VK_KHR_win32_surface
{
VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION,
},
#endif
#ifdef VK_KHR_xcb_surface
{
VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_SPEC_VERSION,
},
#endif
#ifdef VK_KHR_xlib_surface
{
VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION,
},
#endif
};
// filter the list of extensions to only the ones we support.
// sort the reported extensions
std::sort(exts.begin(), exts.end());
+12
View File
@@ -714,6 +714,7 @@ public:
VulkanRenderState &GetRenderState() { return m_RenderState; }
void SetDrawcallCB(VulkanDrawcallCallback *cb) { m_DrawcallCallback = cb; }
bool IsSupportedExtension(const char *extName);
VkResult FilterDeviceExtensionProperties(VkPhysicalDevice physDev, uint32_t *pPropertyCount,
VkExtensionProperties *pProperties);
static VkResult GetProvidedExtensionProperties(uint32_t *pPropertyCount,
@@ -1322,6 +1323,10 @@ public:
VkBool32 vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex);
// VK_NV_external_memory_win32
VkResult vkGetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE *pHandle);
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
@@ -1384,4 +1389,11 @@ public:
const VkSwapchainCreateInfoKHR *pCreateInfos,
const VkAllocationCallbacks *pAllocator,
VkSwapchainKHR *pSwapchains);
// VK_NV_external_memory_capabilities
VkResult vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkExternalMemoryHandleTypeFlagsNV externalHandleType,
VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties);
};
@@ -115,7 +115,7 @@ void InitInstanceExtensionTables(VkInstance instance)
#undef HookInitExtension
#define HookInitExtension(ext, func) \
if(info->ext) \
if(info->ext_##ext) \
{ \
InstanceGPA(func); \
}
@@ -150,7 +150,7 @@ void InitDeviceExtensionTables(VkDevice device)
#undef HookInitExtension
#define HookInitExtension(ext, func) \
if(info->ext) \
if(info->ext_##ext) \
{ \
DeviceGPA(func); \
}
+55 -33
View File
@@ -24,37 +24,31 @@
#pragma once
// since we don't use these macros, we undefine them so they don't interfere
// with bool names etc
#undef VK_KHR_xlib_surface
#undef VK_KHR_xcb_surface
#undef VK_KHR_win32_surface
#undef VK_KHR_android_surface
#undef VK_KHR_surface
#undef VK_KHR_swapchain
#undef VK_KHR_display
#undef VK_KHR_display_swapchain
#undef VK_EXT_debug_report
#undef VK_EXT_debug_marker
#if defined(VK_USE_PLATFORM_WIN32_KHR)
#define HookInitInstance_PlatformSpecific() \
HookInitExtension(VK_KHR_win32_surface, CreateWin32SurfaceKHR); \
HookInitExtension(VK_KHR_win32_surface, GetPhysicalDeviceWin32PresentationSupportKHR);
#define HookInitDevice_PlatformSpecific() \
HookInitExtension(VK_NV_win32_keyed_mutex, GetMemoryWin32HandleNV);
#define HookDefine_PlatformSpecific() \
HookDefine4(VkResult, vkCreateWin32SurfaceKHR, VkInstance, instance, \
const VkWin32SurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \
pAllocator, VkSurfaceKHR *, pSurface); \
HookDefine2(VkBool32, vkGetPhysicalDeviceWin32PresentationSupportKHR, VkPhysicalDevice, \
physicalDevice, uint32_t, queueFamilyIndex);
physicalDevice, uint32_t, queueFamilyIndex); \
HookDefine4(VkResult, vkGetMemoryWin32HandleNV, VkDevice, device, VkDeviceMemory, memory, \
VkExternalMemoryHandleTypeFlagsNV, handleType, HANDLE *, pHandle);
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
#define HookInitInstance_PlatformSpecific() \
HookInitExtension(VK_KHR_android_surface, CreateAndroidSurfaceKHR);
#define HookInitDevice_PlatformSpecific()
#define HookDefine_PlatformSpecific() \
HookDefine4(VkResult, vkCreateAndroidSurfaceKHR, VkInstance, instance, \
const VkAndroidSurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \
@@ -105,6 +99,7 @@
#define HookInitInstance_PlatformSpecific() \
HookInitInstance_PlatformSpecific_Xcb() HookInitInstance_PlatformSpecific_Xlib()
#define HookInitDevice_PlatformSpecific()
#define HookDefine_PlatformSpecific() \
HookDefine_PlatformSpecific_Xcb() HookDefine_PlatformSpecific_Xlib()
@@ -252,13 +247,23 @@
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
#define CheckInstanceExts() \
CheckExt(VK_KHR_xlib_surface) CheckExt(VK_KHR_xcb_surface) CheckExt(VK_KHR_win32_surface) \
CheckExt(VK_KHR_android_surface) CheckExt(VK_KHR_surface) CheckExt(VK_EXT_debug_report) \
CheckExt(VK_KHR_display)
#define CheckInstanceExts() \
CheckExt(VK_KHR_xlib_surface); \
CheckExt(VK_KHR_xcb_surface); \
CheckExt(VK_KHR_win32_surface); \
CheckExt(VK_KHR_android_surface); \
CheckExt(VK_KHR_surface); \
CheckExt(VK_EXT_debug_report); \
CheckExt(VK_KHR_display); \
CheckExt(VK_NV_external_memory_capabilities);
#define CheckDeviceExts() \
CheckExt(VK_EXT_debug_marker) CheckExt(VK_KHR_swapchain) CheckExt(VK_KHR_display_swapchain)
#define CheckDeviceExts() \
CheckExt(VK_EXT_debug_marker); \
CheckExt(VK_KHR_swapchain); \
CheckExt(VK_KHR_display_swapchain); \
CheckExt(VK_NV_external_memory); \
CheckExt(VK_NV_external_memory_win32); \
CheckExt(VK_NV_win32_keyed_mutex);
#define HookInitVulkanInstanceExts() \
HookInitExtension(VK_KHR_surface, DestroySurfaceKHR); \
@@ -276,20 +281,23 @@
HookInitExtension(VK_KHR_display, CreateDisplayModeKHR); \
HookInitExtension(VK_KHR_display, GetDisplayPlaneCapabilitiesKHR); \
HookInitExtension(VK_KHR_display, CreateDisplayPlaneSurfaceKHR); \
HookInitExtension(VK_NV_external_memory_capabilities, \
GetPhysicalDeviceExternalImageFormatPropertiesNV); \
HookInitInstance_PlatformSpecific()
#define HookInitVulkanDeviceExts() \
HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectTagEXT); \
HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectNameEXT); \
HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerBeginEXT); \
HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerEndEXT); \
HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerInsertEXT); \
HookInitExtension(VK_KHR_swapchain, CreateSwapchainKHR); \
HookInitExtension(VK_KHR_swapchain, DestroySwapchainKHR); \
HookInitExtension(VK_KHR_swapchain, GetSwapchainImagesKHR); \
HookInitExtension(VK_KHR_swapchain, AcquireNextImageKHR); \
HookInitExtension(VK_KHR_swapchain, QueuePresentKHR); \
HookInitExtension(VK_KHR_display_swapchain, CreateSharedSwapchainsKHR);
#define HookInitVulkanDeviceExts() \
HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectTagEXT); \
HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectNameEXT); \
HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerBeginEXT); \
HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerEndEXT); \
HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerInsertEXT); \
HookInitExtension(VK_KHR_swapchain, CreateSwapchainKHR); \
HookInitExtension(VK_KHR_swapchain, DestroySwapchainKHR); \
HookInitExtension(VK_KHR_swapchain, GetSwapchainImagesKHR); \
HookInitExtension(VK_KHR_swapchain, AcquireNextImageKHR); \
HookInitExtension(VK_KHR_swapchain, QueuePresentKHR); \
HookInitExtension(VK_KHR_display_swapchain, CreateSharedSwapchainsKHR); \
HookInitDevice_PlatformSpecific()
#define DefineHooks() \
HookDefine3(VkResult, vkEnumeratePhysicalDevices, VkInstance, instance, uint32_t *, \
@@ -636,8 +644,18 @@
HookDefine5(VkResult, vkCreateSharedSwapchainsKHR, VkDevice, device, uint32_t, swapchainCount, \
const VkSwapchainCreateInfoKHR *, pCreateInfos, const VkAllocationCallbacks *, \
pAllocator, VkSwapchainKHR *, pSwapchains); \
HookDefine8(VkResult, vkGetPhysicalDeviceExternalImageFormatPropertiesNV, VkPhysicalDevice, \
physicalDevice, VkFormat, format, VkImageType, type, VkImageTiling, tiling, \
VkImageUsageFlags, usage, VkImageCreateFlags, flags, \
VkExternalMemoryHandleTypeFlagsNV, externalHandleType, \
VkExternalImageFormatPropertiesNV *, pExternalImageFormatProperties); \
HookDefine_PlatformSpecific()
// define function pointers for other platforms to make things easier
#ifndef VK_NV_external_memory_win32
#define PFN_vkGetMemoryWin32HandleNV PFN_vkVoidFunction
#endif
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
{
// for consistency & ease, we declare the CreateInstance pointer here
@@ -648,7 +666,8 @@ struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkEnumerateInstanceLayerProperties EnumerateInstanceLayerProperties;
// extensions here
// VK_NV_external_memory_capabilities
PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV GetPhysicalDeviceExternalImageFormatPropertiesNV;
};
struct VkLayerDispatchTableExtended : VkLayerDispatchTable
@@ -663,4 +682,7 @@ struct VkLayerDispatchTableExtended : VkLayerDispatchTable
PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT;
PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT;
PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT;
// VK_NV_external_memory_win32
PFN_vkGetMemoryWin32HandleNV GetMemoryWin32HandleNV;
};
+2 -2
View File
@@ -827,7 +827,7 @@ struct SwapchainInfo
struct InstanceDeviceInfo
{
#undef CheckExt
#define CheckExt(name) name = false;
#define CheckExt(name) ext_##name = false;
InstanceDeviceInfo()
{
CheckDeviceExts();
@@ -835,7 +835,7 @@ struct InstanceDeviceInfo
}
#undef CheckExt
#define CheckExt(name) bool name;
#define CheckExt(name) bool ext_##name;
CheckDeviceExts();
CheckInstanceExts();
+5 -8
View File
@@ -248,14 +248,11 @@ VK_LAYER_EXPORT VkResult VKAPI_CALL VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExt
return (PFN_vkVoidFunction)&CONCAT(hooked_vk, function);
#undef HookInitExtension
#define HookInitExtension(ext, function) \
if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \
{ \
if(instDevInfo->ext) \
return (PFN_vkVoidFunction)&CONCAT(hooked_vk, function); \
else \
RDCWARN("Requested function %s but extension %s is not enabled!", STRINGIZE(function), \
STRINGIZE(ext)); \
#define HookInitExtension(ext, function) \
if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \
{ \
if(instDevInfo->ext_##ext) \
return (PFN_vkVoidFunction)&CONCAT(hooked_vk, function); \
}
// proc addr routines
@@ -279,6 +279,33 @@ VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo
VkInstanceCreateInfo modifiedCreateInfo;
modifiedCreateInfo = *pCreateInfo;
for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++)
{
if(!IsSupportedExtension(modifiedCreateInfo.ppEnabledExtensionNames[i]))
{
RDCERR("RenderDoc does not support instance extension '%s'.",
modifiedCreateInfo.ppEnabledExtensionNames[i]);
RDCERR("File an issue on github to request support: https://github.com/baldurk/renderdoc");
// see if any debug report callbacks were passed in the pNext chain
VkDebugReportCallbackCreateInfoEXT *report =
(VkDebugReportCallbackCreateInfoEXT *)pCreateInfo->pNext;
while(report)
{
if(report && report->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT)
report->pfnCallback(VK_DEBUG_REPORT_ERROR_BIT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, 1, 1, "RDOC",
"RenderDoc does not support a requested instance extension.",
report->pUserData);
report = (VkDebugReportCallbackCreateInfoEXT *)report->pNext;
}
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
const char **addedExts = new const char *[modifiedCreateInfo.enabledExtensionCount + 1];
for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++)
@@ -311,7 +338,7 @@ VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo
#define CheckExt(name) \
if(!strcmp(modifiedCreateInfo.ppEnabledExtensionNames[i], STRINGIZE(name))) \
{ \
record->instDevInfo->name = true; \
record->instDevInfo->ext_##name = true; \
}
for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++)
@@ -1233,7 +1260,8 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
record->instDevInfo = new InstanceDeviceInfo();
#undef CheckExt
#define CheckExt(name) record->instDevInfo->name = GetRecord(m_Instance)->instDevInfo->name;
#define CheckExt(name) \
record->instDevInfo->ext_##name = GetRecord(m_Instance)->instDevInfo->ext_##name;
// inherit extension enablement from instance, that way GetDeviceProcAddress can check
// for enabled extensions for instance functions
@@ -1243,7 +1271,7 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice,
#define CheckExt(name) \
if(!strcmp(createInfo.ppEnabledExtensionNames[i], STRINGIZE(name))) \
{ \
record->instDevInfo->name = true; \
record->instDevInfo->ext_##name = true; \
}
for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++)
@@ -233,3 +233,24 @@ VkResult WrappedVulkan::vkMergePipelineCaches(VkDevice device, VkPipelineCache d
// do nothing, our pipeline caches are always dummies
return VK_SUCCESS;
}
VkResult WrappedVulkan::vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkExternalMemoryHandleTypeFlagsNV externalHandleType,
VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties)
{
return ObjDisp(physicalDevice)
->GetPhysicalDeviceExternalImageFormatPropertiesNV(Unwrap(physicalDevice), format, type,
tiling, usage, flags, externalHandleType,
pExternalImageFormatProperties);
}
#if defined(VK_USE_PLATFORM_WIN32_KHR)
VkResult WrappedVulkan::vkGetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagsNV handleType,
HANDLE *pHandle)
{
return ObjDisp(device)->GetMemoryWin32HandleNV(Unwrap(device), Unwrap(memory), handleType, pHandle);
}
#endif
@@ -462,6 +462,33 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
tempmemSize += pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer);
tempmemSize += pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore);
tempmemSize += pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore);
VkGenericStruct *next = (VkGenericStruct *)pSubmits[i].pNext;
while(next)
{
if(next->sType == VK_STRUCTURE_TYPE_MAX_ENUM)
{
RDCERR("Invalid extension structure");
}
else if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV)
{
#ifdef VK_NV_win32_keyed_mutex
tempmemSize += sizeof(VkWin32KeyedMutexAcquireReleaseInfoNV);
VkWin32KeyedMutexAcquireReleaseInfoNV *info = (VkWin32KeyedMutexAcquireReleaseInfoNV *)next;
tempmemSize += info->acquireCount * sizeof(VkDeviceMemory);
tempmemSize += info->releaseCount * sizeof(VkDeviceMemory);
#else
RDCERR("Support for VK_NV_win32_keyed_mutex not compiled in");
#endif
}
else
{
RDCERR("Unexpected extension structure %d", next->sType);
}
next = (VkGenericStruct *)next->pNext;
}
}
byte *memory = GetTempMemory(tempmemSize);
@@ -471,7 +498,7 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
for(uint32_t i = 0; i < submitCount; i++)
{
RDCASSERT(pSubmits[i].sType == VK_STRUCTURE_TYPE_SUBMIT_INFO && pSubmits[i].pNext == NULL);
RDCASSERT(pSubmits[i].sType == VK_STRUCTURE_TYPE_SUBMIT_INFO);
unwrappedSubmits[i] = pSubmits[i];
VkSemaphore *unwrappedWaitSems = (VkSemaphore *)memory;
@@ -498,6 +525,49 @@ VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount,
unwrappedSubmits[i].signalSemaphoreCount ? unwrappedSignalSems : NULL;
for(uint32_t o = 0; o < unwrappedSubmits[i].signalSemaphoreCount; o++)
unwrappedSignalSems[o] = Unwrap(pSubmits[i].pSignalSemaphores[o]);
VkGenericStruct **nextptr = (VkGenericStruct **)&unwrappedSubmits[i].pNext;
while(*nextptr)
{
VkGenericStruct *next = *nextptr;
#ifdef VK_NV_win32_keyed_mutex
if(next->sType == VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV)
{
// allocate local unwrapped struct
VkWin32KeyedMutexAcquireReleaseInfoNV *unwrappedMutexInfoNV =
(VkWin32KeyedMutexAcquireReleaseInfoNV *)memory;
memory += sizeof(VkWin32KeyedMutexAcquireReleaseInfoNV);
// copy over info from original struct
VkWin32KeyedMutexAcquireReleaseInfoNV *wrappedMutexInfoNV =
(VkWin32KeyedMutexAcquireReleaseInfoNV *)next;
*unwrappedMutexInfoNV = *wrappedMutexInfoNV;
// allocate unwrapped arrays
VkDeviceMemory *unwrappedAcquires = (VkDeviceMemory *)memory;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoNV->acquireCount;
VkDeviceMemory *unwrappedReleases = (VkDeviceMemory *)memory;
memory += sizeof(VkDeviceMemory) * unwrappedMutexInfoNV->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]);
unwrappedMutexInfoNV->pAcquireSyncs = unwrappedAcquires;
unwrappedMutexInfoNV->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;
}
#endif
nextptr = (VkGenericStruct **)&next->pNext;
}
}
VkResult ret =