vulkan: Updated vulkan.h for revision 79 -- Bug #13464
Implemented the changes required for adding fine-grained synchronization
to vkBindMemoryObject and related APIs.
diff --git a/layers/mem_tracker.cpp b/layers/mem_tracker.cpp
index c5f83d2..d67887e 100644
--- a/layers/mem_tracker.cpp
+++ b/layers/mem_tracker.cpp
@@ -490,36 +490,50 @@
}
// For given MemObjInfo, report Obj & CB bindings
-static void reportMemReferences(const MT_MEM_OBJ_INFO* pMemObjInfo)
+static void reportMemReferencesAndCleanUp(MT_MEM_OBJ_INFO* pMemObjInfo)
{
- uint32_t refCount = 0; // Count found references
+ uint32_t cmdBufRefCount = pMemObjInfo->pCmdBufferBindings.size();
+ uint32_t objRefCount = pMemObjInfo->pObjBindings.size();
- for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
- refCount++;
+ if ((pMemObjInfo->pCmdBufferBindings.size() + pMemObjInfo->pObjBindings.size()) != 0) {
char str[1024];
- sprintf(str, "Command Buffer %p has reference to mem obj %p", (*it), pMemObjInfo->mem);
- layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
- }
- for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
- char str[1024];
- sprintf(str, "VK Object %p has reference to mem obj %p", (*it), pMemObjInfo->mem);
- layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
- }
- if (refCount != pMemObjInfo->refCount) {
- char str[1024];
- sprintf(str, "Refcount of %u for Mem Obj %p does't match reported refs of %u", pMemObjInfo->refCount, pMemObjInfo->mem, refCount);
+ sprintf(str, "Attempting to free memory object %p which still contains %d references", pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
}
+
+ if (cmdBufRefCount > 0) {
+ for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
+ char str[1024];
+ sprintf(str, "Command Buffer %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
+ layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
+ }
+ // Clear the list of hanging references
+ pMemObjInfo->pCmdBufferBindings.clear();
+ }
+
+ if (objRefCount > 0) {
+ for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
+ char str[1024];
+ sprintf(str, "VK Object %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
+ layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
+ }
+ // Clear the list of hanging references
+ pMemObjInfo->pObjBindings.clear();
+ }
}
static void deleteMemObjInfo(VkGpuMemory mem)
{
- MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
if (memObjMap.find(mem) != memObjMap.end()) {
MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
delete pDelInfo;
memObjMap.erase(mem);
}
+ else {
+ char str[1024];
+ sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
+ layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
+ }
}
// Check if fence for given CB is completed
@@ -582,7 +596,7 @@
char str[1024];
sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
- reportMemReferences(pInfo);
+ reportMemReferencesAndCleanUp(pInfo);
result = VK_FALSE;
}
// Delete mem obj info
@@ -610,12 +624,16 @@
sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
} else {
+ // This obj is bound to a memory object. Remove the reference to this object in that memory object's list, decrement the memObj's refcount
+ // and set the objects memory binding pointer to NULL.
for (list<VkObject>::iterator it = pObjInfo->pMemObjInfo->pObjBindings.begin(); it != pObjInfo->pMemObjInfo->pObjBindings.end(); ++it) {
- pObjInfo->pMemObjInfo->refCount--;
- pObjInfo->pMemObjInfo = NULL;
- it = pObjInfo->pMemObjInfo->pObjBindings.erase(it);
- result = VK_TRUE;
- break;
+ if ((*it) == object) {
+ pObjInfo->pMemObjInfo->refCount--;
+ pObjInfo->pMemObjInfo->pObjBindings.erase(it);
+ pObjInfo->pMemObjInfo = NULL;
+ result = VK_TRUE;
+ break;
+ }
}
if (result == VK_FALSE) {
char str[1024];
@@ -1168,7 +1186,7 @@
}
else {
char str[1024];
- sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding by calling vkBindObjectMemory(%p, 0, VK_NULL_HANDLE, 0)", object, (void*)pDelInfo->pMemObjInfo->mem, object);
+ sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding by calling vkQueueBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)", object, (void*)pDelInfo->pMemObjInfo->mem, object);
layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
// From the spec : If an object has previous memory binding, it is required to unbind memory from an API object before it is destroyed.
clearObjectBinding(object);
@@ -1186,15 +1204,15 @@
VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo(VkBaseObject object, VkObjectInfoType infoType, size_t* pDataSize, void* pData)
{
// TODO : What to track here?
- // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
+ // Could potentially save returned mem requirements and validate values passed into QueueBindObjectMemory for this object
// From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues, command buffers, shaders and memory objects.
VkResult result = nextTable.GetObjectInfo(object, infoType, pDataSize, pData);
return result;
}
-VK_LAYER_EXPORT VkResult VKAPI vkBindObjectMemory(VkObject object, uint32_t allocationIdx, VkGpuMemory mem, VkGpuSize offset)
+VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(VkQueue queue, VkObject object, uint32_t allocationIdx, VkGpuMemory mem, VkGpuSize offset)
{
- VkResult result = nextTable.BindObjectMemory(object, allocationIdx, mem, offset);
+ VkResult result = nextTable.QueueBindObjectMemory(queue, object, allocationIdx, mem, offset);
loader_platform_thread_lock_mutex(&globalLock);
// Track objects tied to memory
if (VK_FALSE == updateObjectBinding(object, mem)) {
@@ -2013,8 +2031,8 @@
return (void*) vkDestroyObject;
if (!strcmp(funcName, "vkGetObjectInfo"))
return (void*) vkGetObjectInfo;
- if (!strcmp(funcName, "vkBindObjectMemory"))
- return (void*) vkBindObjectMemory;
+ if (!strcmp(funcName, "vkQueueBindObjectMemory"))
+ return (void*) vkQueueBindObjectMemory;
if (!strcmp(funcName, "vkCreateFence"))
return (void*) vkCreateFence;
if (!strcmp(funcName, "vkGetFenceStatus"))