Update code to header 1.0.2 and new layer initialisation scheme

This commit is contained in:
baldurk
2016-02-07 18:52:14 +01:00
parent 87cd6a1d4d
commit 90b1058f9d
8 changed files with 182 additions and 84 deletions
@@ -44,11 +44,11 @@ extern "C"
* DebugReport Vulkan Extension API
***************************************************************************************************
*/
#define VK_EXT_debug_report 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
#define VK_EXT_DEBUG_REPORT_REVISION 2
#define VK_EXT_DEBUG_REPORT_EXTENSION_NUMBER 11
#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 1
#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
@@ -85,10 +85,11 @@ typedef enum VkDebugReportObjectTypeEXT {
} VkDebugReportObjectTypeEXT;
typedef enum VkDebugReportErrorEXT {
VK_DEBUG_REPORT_ERROR_NONE = 0,
VK_DEBUG_REPORT_ERROR_CALLBACK_REF = 1,
VK_DEBUG_REPORT_ERROR_NONE_EXT = 0,
VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT = 1,
} VkDebugReportErrorEXT;
typedef enum VkDebugReportFlagBitsEXT {
VK_DEBUG_REPORT_INFO_BIT_EXT = 0x00000001,
VK_DEBUG_REPORT_WARN_BIT_EXT = 0x00000002,
@@ -106,15 +107,15 @@ typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
const void* pUserData);
void* pUserData);
typedef struct VkDebugReportCallbackCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDebugReportFlagsEXT flags;
PFN_vkDebugReportCallbackEXT pfnCallback;
const void* pUserData;
VkStructureType sType;
const void* pNext;
VkDebugReportFlagsEXT flags;
PFN_vkDebugReportCallbackEXT pfnCallback;
void* pUserData;
} VkDebugReportCallbackCreateInfoEXT;
typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);
+67 -10
View File
@@ -15,18 +15,11 @@
# define VK_LAYER_EXPORT
#endif
typedef void * (VKAPI_PTR *PFN_vkGPA)(void* obj, const char * pName);
typedef struct VkBaseLayerObject_
{
PFN_vkGPA pGPA;
void* nextObject;
void* baseObject;
} VkBaseLayerObject;
typedef struct VkLayerDispatchTable_
{
PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
PFN_vkCreateDevice CreateDevice;
PFN_vkDestroyDevice DestroyDevice;
PFN_vkGetDeviceQueue GetDeviceQueue;
PFN_vkQueueSubmit QueueSubmit;
@@ -157,7 +150,6 @@ typedef struct VkLayerDispatchTable_
typedef struct VkLayerInstanceDispatchTable_
{
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
PFN_vkCreateInstance CreateInstance;
PFN_vkDestroyInstance DestroyInstance;
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
@@ -208,7 +200,7 @@ typedef struct VkLayerDbgFunctionNode_
VkDebugReportCallbackEXT msgCallback;
PFN_vkDebugReportCallbackEXT pfnMsgCallback;
VkFlags msgFlags;
const void *pUserData;
void *pUserData;
struct VkLayerDbgFunctionNode_ *pNext;
} VkLayerDbgFunctionNode;
@@ -221,5 +213,70 @@ typedef enum VkLayerDbgAction_
VK_DBG_LAYER_ACTION_DEBUG_OUTPUT = 0x8,
} VkLayerDbgAction;
// ------------------------------------------------------------------------------------------------
// CreateInstance and CreateDevice support structures
typedef enum VkLayerFunction_
{
VK_LAYER_LINK_INFO = 0,
VK_LAYER_DEVICE_INFO = 1,
VK_LAYER_INSTANCE_INFO = 2
} VkLayerFunction;
/*
* When creating the device chain the loader needs to pass
* down information about it's device structure needed at
* the end of the chain. Passing the data via the
* VkLayerInstanceInfo avoids issues with finding the
* exact instance being used.
*/
typedef struct VkLayerInstanceInfo_ {
void *instance_info;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerInstanceInfo;
typedef struct VkLayerInstanceLink_ {
struct VkLayerInstanceLink_* pNext;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerInstanceLink;
/*
* When creating the device chain the loader needs to pass
* down information about it's device structure needed at
* the end of the chain. Passing the data via the
* VkLayerDeviceInfo avoids issues with finding the
* exact instance being used.
*/
typedef struct VkLayerDeviceInfo_ {
void *device_info;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
} VkLayerDeviceInfo;
typedef struct {
VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_INSTANCE_CREATE_INFO
const void* pNext;
VkLayerFunction function;
union {
VkLayerInstanceLink* pLayerInfo;
VkLayerInstanceInfo instanceInfo;
} u;
} VkLayerInstanceCreateInfo;
typedef struct VkLayerDeviceLink_ {
struct VkLayerDeviceLink_* pNext;
PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr;
} VkLayerDeviceLink;
typedef struct {
VkStructureType sType; // VK_STRUCTURE_TYPE_LAYER_DEVICE_CREATE_INFO
const void* pNext;
VkLayerFunction function;
union {
VkLayerDeviceLink* pLayerInfo;
VkLayerDeviceInfo deviceInfo;
} u;
} VkLayerDeviceCreateInfo;
// ------------------------------------------------------------------------------------------------
// API functions
+5 -4
View File
@@ -41,7 +41,7 @@ extern "C" {
((major << 22) | (minor << 12) | patch)
// Vulkan API version supported by this file
#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 1)
#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 2)
#define VK_NULL_HANDLE 0
@@ -144,10 +144,10 @@ typedef enum VkResult {
VK_ERROR_TOO_MANY_OBJECTS = -10,
VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
VK_ERROR_SURFACE_LOST_KHR = -1000000000,
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
VK_SUBOPTIMAL_KHR = 1000001003,
VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000008000,
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
VK_RESULT_BEGIN_RANGE = VK_ERROR_FORMAT_NOT_SUPPORTED,
VK_RESULT_END_RANGE = VK_INCOMPLETE,
@@ -814,6 +814,7 @@ typedef enum VkFormatFeatureFlagBits {
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200,
VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400,
VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800,
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
} VkFormatFeatureFlagBits;
typedef VkFlags VkFormatFeatureFlags;
@@ -3140,7 +3141,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(
#define VK_KHR_surface 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
#define VK_KHR_SURFACE_SPEC_VERSION 24
#define VK_KHR_SURFACE_SPEC_VERSION 25
#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface"
@@ -3615,7 +3616,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
#define VK_KHR_android_surface 1
#include <android/native_window.h>
#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 5
#define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6
#define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface"
typedef VkFlags VkAndroidSurfaceCreateFlagsKHR;
+1 -1
View File
@@ -519,7 +519,7 @@ private:
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
const void* pUserData)
void* pUserData)
{
return ((WrappedVulkan *)pUserData)->DebugCallback(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage);
}
+12 -13
View File
@@ -153,10 +153,10 @@ static void *GetKey(void *obj)
return (void *)*tablePtr;
}
void InitDeviceTable(const VkBaseLayerObject *obj)
void InitDeviceTable(VkDevice dev, PFN_vkGetDeviceProcAddr gpa)
{
void *key = GetKey(obj->baseObject);
void *key = GetKey(dev);
VkLayerDispatchTableExtended *table = NULL;
{
@@ -165,19 +165,18 @@ void InitDeviceTable(const VkBaseLayerObject *obj)
table = &devlookup[key];
}
// init the GetDeviceProcAddr function first
table->GetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)obj->pGPA((VkDevice)obj->nextObject, "vkGetDeviceProcAddr");
table->GetDeviceProcAddr = gpa;
// fetch the rest of the functions
#undef HookInit
#define HookInit(name) if(table->name == NULL) table->name = (CONCAT(PFN_vk, name))obj->pGPA((VkDevice)obj->baseObject, STRINGIZE(CONCAT(vk, name)))
#define HookInit(name) if(table->name == NULL) table->name = (CONCAT(PFN_vk, name))gpa(dev, STRINGIZE(CONCAT(vk, name)))
HookInitVulkanDevice();
}
void InitInstanceTable(const VkBaseLayerObject *obj)
void InitInstanceTable(VkInstance inst, PFN_vkGetInstanceProcAddr gpa)
{
void *key = GetKey(obj->baseObject);
void *key = GetKey(inst);
VkLayerInstanceDispatchTableExtended *table = NULL;
@@ -188,14 +187,14 @@ void InitInstanceTable(const VkBaseLayerObject *obj)
}
// init the GetInstanceProcAddr function first
table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)obj->pGPA((VkInstance)obj->nextObject, "vkGetInstanceProcAddr");
table->GetInstanceProcAddr = gpa;
// fetch the rest of the functions
#undef HookInit
#define HookInit(name) if(table->name == NULL) table->name = (CONCAT(PFN_vk, name))obj->pGPA((VkInstance)obj->baseObject, STRINGIZE(CONCAT(vk, name)))
#define HookInit(name) if(table->name == NULL) table->name = (CONCAT(PFN_vk, name))gpa(inst, STRINGIZE(CONCAT(vk, name)))
HookInitVulkanInstance();
// we also need these functions for layer handling
HookInit(EnumerateDeviceExtensionProperties);
HookInit(EnumerateDeviceLayerProperties);
@@ -405,11 +405,19 @@
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
{
// for consistency & ease, we declare the CreateInstance pointer here
// even though it won't actually ever get used
PFN_vkCreateInstance CreateInstance;
// extensions here
};
struct VkLayerDispatchTableExtended : VkLayerDispatchTable
{
// for consistency & ease, we declare the CreateDevice pointer here
// even though it won't actually ever get used
PFN_vkCreateDevice CreateDevice;
// VK_LUNARG_DEBUG_MARKER
PFN_vkCmdDbgMarkerBegin CmdDbgMarkerBegin;
PFN_vkCmdDbgMarkerEnd CmdDbgMarkerEnd;
+18 -43
View File
@@ -47,9 +47,6 @@
#define VK_LAYER_EXPORT extern "C" __declspec(dllexport)
#endif
void InitDeviceTable(const VkBaseLayerObject *obj);
void InitInstanceTable(const VkBaseLayerObject *obj);
// in vk_<platform>.cpp
bool LayerRegistered();
@@ -170,7 +167,7 @@ VkResult getProps(uint32_t *dstCount, void *dstProps, uint32_t srcCount, void *s
extern "C" {
VK_LAYER_EXPORT VkResult VKAPI_CALL RenderDocEnumerateDeviceLayerProperties(
VK_LAYER_EXPORT VkResult VKAPI_CALL RenderDoc_EnumerateDeviceLayerProperties(
VkPhysicalDevice physicalDevice,
uint32_t* pPropertyCount,
VkLayerProperties* pProperties)
@@ -178,7 +175,7 @@ VK_LAYER_EXPORT VkResult VKAPI_CALL RenderDocEnumerateDeviceLayerProperties(
return getProps(pPropertyCount, pProperties, ARRAY_COUNT(physLayers), (void *)physLayers, sizeof(VkLayerProperties));
}
VK_LAYER_EXPORT VkResult VKAPI_CALL RenderDocEnumerateDeviceExtensionProperties(
VK_LAYER_EXPORT VkResult VKAPI_CALL RenderDoc_EnumerateDeviceExtensionProperties(
VkPhysicalDevice physicalDevice,
const char *pLayerName,
uint32_t *pPropertyCount,
@@ -207,65 +204,43 @@ VK_LAYER_EXPORT VkResult VKAPI_CALL RenderDocEnumerateDeviceExtensionProperties(
VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL RenderDoc_GetDeviceProcAddr(VkDevice device, const char* pName)
{
if (device == NULL)
return NULL;
/* loader uses this to force layer initialization; device object is wrapped */
if (!strcmp("vkGetDeviceProcAddr", pName)) {
InitDeviceTable((const VkBaseLayerObject *) device);
if(!strcmp("vkGetDeviceProcAddr", pName))
return (PFN_vkVoidFunction) &RenderDoc_GetDeviceProcAddr;
}
if (!strcmp("vkCreateDevice", pName))
if(!strcmp("vkCreateDevice", pName))
return (PFN_vkVoidFunction) &hooked_vkCreateDevice;
if (!strcmp("vkDestroyDevice", pName))
if(!strcmp("vkDestroyDevice", pName))
return (PFN_vkVoidFunction) &hooked_vkDestroyDevice;
HookInitVulkanDevice();
if(device == VK_NULL_HANDLE)
return NULL;
InstanceDeviceInfo *instDevInfo = GetRecord(device)->instDevInfo;
HookInitVulkanDeviceExts();
if (GetDeviceDispatchTable(device)->GetDeviceProcAddr == NULL)
if(GetDeviceDispatchTable(device)->GetDeviceProcAddr == NULL)
return NULL;
return GetDeviceDispatchTable(device)->GetDeviceProcAddr(Unwrap(device), pName);
}
VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL RenderDoc_GetInstanceProcAddr(VkInstance instance, const char* pName)
{
if (instance == NULL)
return NULL;
/* loader uses this to force layer initialization; instance object is wrapped */
if (!strcmp("vkGetInstanceProcAddr", pName)) {
InitInstanceTable((const VkBaseLayerObject *) instance);
if(!strcmp("vkGetInstanceProcAddr", pName))
return (PFN_vkVoidFunction) &RenderDoc_GetInstanceProcAddr;
}
if (!strcmp("vkEnumerateDeviceLayerProperties", pName))
return (PFN_vkVoidFunction) &RenderDocEnumerateDeviceLayerProperties;
if (!strcmp("vkEnumerateDeviceExtensionProperties", pName))
return (PFN_vkVoidFunction) &RenderDocEnumerateDeviceExtensionProperties;
if(!strcmp("vkEnumerateDeviceLayerProperties", pName))
return (PFN_vkVoidFunction) &RenderDoc_EnumerateDeviceLayerProperties;
if(!strcmp("vkEnumerateDeviceExtensionProperties", pName))
return (PFN_vkVoidFunction) &RenderDoc_EnumerateDeviceExtensionProperties;
HookInitVulkanInstance();
if(instance == VK_NULL_HANDLE)
return NULL;
InstanceDeviceInfo *instDevInfo = GetRecord(instance)->instDevInfo;
// TEMPORARY HACK until loader is patched
InstanceDeviceInfo dummy;
dummy.VK_KHR_xlib_surface = true;
dummy.VK_KHR_xcb_surface = true;
dummy.VK_KHR_win32_surface = true;
dummy.VK_KHR_surface = true;
dummy.VK_KHR_swapchain = true;
if(!WrappedVkInstance::IsAlloc(instance))
{
RDCLOG("Doing workaround for non-wrapped instance passed to GIPA");
instDevInfo = &dummy;
}
HookInitVulkanInstanceExts();
// GetInstanceProcAddr must also unconditionally return all device functions
@@ -277,7 +252,7 @@ VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL RenderDoc_GetInstanceProcAddr(VkIn
HookInitVulkanDeviceExts();
if (GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL)
if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL)
return NULL;
return GetInstanceDispatchTable(instance)->GetInstanceProcAddr(Unwrap(instance), pName);
}
@@ -25,6 +25,10 @@
#include "../vk_core.h"
#include "../vk_debug.h"
// vk_dispatchtables.cpp
void InitDeviceTable(VkDevice dev, PFN_vkGetDeviceProcAddr gpa);
void InitInstanceTable(VkInstance inst, PFN_vkGetInstanceProcAddr gpa);
// Init/shutdown order:
//
// On capture, WrappedVulkan is new'd and delete'd before vkCreateInstance() and after vkDestroyInstance()
@@ -138,11 +142,34 @@ VkResult WrappedVulkan::vkCreateInstance(
// don't support any extensions for this createinfo
RDCASSERT(pCreateInfo->pApplicationInfo == NULL || pCreateInfo->pApplicationInfo->pNext == NULL);
RDCASSERT(pCreateInfo->pNext == NULL);
VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext;
// step through the chain of pNext until we get to the link info
while(layerCreateInfo &&
(layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO ||
layerCreateInfo->function != VK_LAYER_LINK_INFO)
)
{
// we don't handle any pNext elements other than this create info struct
RDCASSERT(layerCreateInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO);
layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext;
}
RDCASSERT(layerCreateInfo);
// make sure there are no elements after this, that we don't handle
RDCASSERT(layerCreateInfo->pNext == NULL);
PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
// move chain on for next layer
layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance");
VkResult ret = createFunc(pCreateInfo, pAllocator, pInstance);
m_Instance = *pInstance;
VkResult ret = GetInstanceDispatchTable(*pInstance)->CreateInstance(pCreateInfo, pAllocator, &m_Instance);
InitInstanceTable(m_Instance, gpa);
GetResourceManager()->WrapResource(m_Instance, m_Instance);
@@ -726,7 +753,37 @@ VkResult WrappedVulkan::vkCreateDevice(
m_QueueFamilies[family][q] = VK_NULL_HANDLE;
}
VkResult ret = GetDeviceDispatchTable(*pDevice)->CreateDevice(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice);
VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
// step through the chain of pNext until we get to the link info
while(layerCreateInfo &&
(layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
layerCreateInfo->function != VK_LAYER_LINK_INFO)
)
{
// we don't handle any pNext elements other than this create info struct
RDCASSERT(layerCreateInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO);
layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
}
RDCASSERT(layerCreateInfo);
// make sure there are no elements after this, that we don't handle
RDCASSERT(layerCreateInfo->pNext == NULL);
PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
// move chain on for next layer
layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext;
PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice");
VkResult ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice);
// don't serialise out any of the pNext stuff for layer initialisation
// (note that we asserted above that there was nothing else in the chain)
createInfo.pNext = NULL;
InitDeviceTable(*pDevice, gdpa);
if(ret == VK_SUCCESS)
{