When available, use loader-provided function to set dispatch table

* Also remove SetMagicNumberOverDispatchTable, as the same effect (but
  more portable) can be achieved just by setting dispatch table on the
  wrapped object *after* wrapping, so magic number etc is copied through
  to wrapper to meet loader expectations up the chain
This commit is contained in:
baldurk
2016-05-07 14:11:46 +02:00
parent 27ae3b6fbf
commit 2553abc944
6 changed files with 43 additions and 23 deletions
+6 -1
View File
@@ -292,6 +292,8 @@ WrappedVulkan::WrappedVulkan(const char *logFilename)
m_DrawcallStack.push_back(&m_ParentDrawcall);
m_SetDeviceLoaderData = NULL;
m_ResourceManager = new VulkanResourceManager(m_State, m_pSerialiser, this);
m_pSerialiser->SetUserData(m_ResourceManager);
@@ -368,7 +370,10 @@ VkCommandBuffer WrappedVulkan::GetNextCmd()
VkCommandBufferAllocateInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, NULL, Unwrap(m_InternalCmds.cmdpool), VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 };
VkResult vkr = ObjDisp(m_Device)->AllocateCommandBuffers(Unwrap(m_Device), &cmdInfo, &ret);
SetDispatchTableOverMagicNumber(m_Device, ret);
if(m_SetDeviceLoaderData)
m_SetDeviceLoaderData(m_Device, ret);
else
SetDispatchTableOverMagicNumber(m_Device, ret);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
+2
View File
@@ -256,6 +256,8 @@ private:
VkPhysicalDeviceMemoryProperties memProps;
VkFormatProperties fmtprops[VK_FORMAT_RANGE_SIZE];
};
PFN_vkSetDeviceLoaderData m_SetDeviceLoaderData;
VkInstance m_Instance; // the instance corresponding to this WrappedVulkan
VkDebugReportCallbackEXT m_DbgMsgCallback; // the instance's dbg msg callback handle
-7
View File
@@ -507,13 +507,6 @@ void SetDispatchTableOverMagicNumber(VkDevice parent, RealType obj)
wrapped->loaderTable = GetWrapped(parent)->loaderTable;
}
template<typename RealType>
void SetMagicNumberOverDispatchTable(RealType obj)
{
typename UnwrapHelper<RealType>::Outer *wrapped = GetWrapped(obj);
wrapped->loaderTable = 0x01CDC0DE;
}
template<typename RealType>
WrappedVulkan *CoreDisp(RealType obj)
{
@@ -231,12 +231,17 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(
{
for(uint32_t i=0; i < unwrappedInfo.commandBufferCount; i++)
{
SetDispatchTableOverMagicNumber(device, pCommandBuffers[i]);
VkCommandBuffer unwrappedReal = pCommandBuffers[i];
ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pCommandBuffers[i]);
// loader expects command buffers to have the magic number in them
SetMagicNumberOverDispatchTable(pCommandBuffers[i]);
// we set this *after* wrapping, so that the wrapped resource copies the 'uninitialised'
// loader table, since the loader expects to set the dispatch table onto an existing magic
// number in the trampoline function at the start of the chain.
if(m_SetDeviceLoaderData)
m_SetDeviceLoaderData(device, unwrappedReal);
else
SetDispatchTableOverMagicNumber(device, unwrappedReal);
if(m_State >= WRITING)
{
@@ -174,13 +174,9 @@ VkResult WrappedVulkan::vkCreateInstance(
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
@@ -850,15 +846,10 @@ VkResult WrappedVulkan::vkCreateDevice(
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
@@ -866,6 +857,27 @@ VkResult WrappedVulkan::vkCreateDevice(
PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice");
// now search again through for the loader data callback (if it exists)
layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext;
// step through the chain of pNext
while(layerCreateInfo &&
(layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO ||
layerCreateInfo->function != VK_LOADER_DATA_CALLBACK)
)
{
layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext;
}
// if we found one (we might not - on old loaders), then store the func ptr for
// use instead of SetDispatchTableOverMagicNumber
if(layerCreateInfo)
{
RDCASSERT(m_SetDeviceLoaderData == layerCreateInfo->u.pfnSetDeviceLoaderData || m_SetDeviceLoaderData == NULL,
m_SetDeviceLoaderData, layerCreateInfo->u.pfnSetDeviceLoaderData);
m_SetDeviceLoaderData = layerCreateInfo->u.pfnSetDeviceLoaderData;
}
VkResult ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice);
// don't serialise out any of the pNext stuff for layer initialisation
@@ -66,8 +66,11 @@ void WrappedVulkan::vkGetDeviceQueue(
VkQueue* pQueue)
{
ObjDisp(device)->GetDeviceQueue(Unwrap(device), queueFamilyIndex, queueIndex, pQueue);
SetDispatchTableOverMagicNumber(device, *pQueue);
if(m_SetDeviceLoaderData)
m_SetDeviceLoaderData(m_Device, *pQueue);
else
SetDispatchTableOverMagicNumber(device, *pQueue);
RDCASSERT(m_State >= WRITING);