diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2015-04-09 12:09:45 -0500 |
|---|---|---|
| committer | Chia-I Wu <olv@lunarg.com> | 2015-04-16 17:48:19 +0800 |
| commit | 3d99c6e091024c2ed63cb46880c37d0a7279d650 (patch) | |
| tree | ac8eb985b67dcf1f8881f0bca5d6b71f4a6a6fa5 | |
| parent | 1e8ab91c6cd469a0af62b4d3d94e209925b435b7 (diff) | |
| download | usermoji-3d99c6e091024c2ed63cb46880c37d0a7279d650.tar.xz | |
layers: ObjTracker -- free each queue's memRefs
Cleanup and free memRef-related resources for each queue upon device
destruction.
TODO: Verify vk-layer-generation.py
TODO: APIDump layer needs some help
| -rwxr-xr-x | vk-layer-generate.py | 210 |
1 files changed, 198 insertions, 12 deletions
diff --git a/vk-layer-generate.py b/vk-layer-generate.py index c924cfd9..266319c5 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -832,11 +832,162 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' struct _objNode *pNextObj;') header_txt.append(' struct _objNode *pNextGlobal;') header_txt.append('} objNode;') - header_txt.append('static objNode *pObjectHead[VK_NUM_OBJECT_TYPE] = {0};') + header_txt.append('') + header_txt.append('static objNode *pObjectHead[VkNumObjectType] = {0};') header_txt.append('static objNode *pGlobalHead = NULL;') - header_txt.append('static uint64_t numObjs[VK_NUM_OBJECT_TYPE] = {0};') + header_txt.append('static uint64_t numObjs[VkNumObjectType] = {0};') header_txt.append('static uint64_t numTotalObjs = 0;') header_txt.append('static uint32_t maxMemReferences = 0;') + header_txt.append('') + header_txt.append('// For each Queue\'s doubly linked-list of mem refs') + header_txt.append('typedef struct _OT_MEM_INFO {') + header_txt.append(' VkGpuMemory mem;') + header_txt.append(' struct _OT_MEM_INFO *pNextMI;') + header_txt.append(' struct _OT_MEM_INFO *pPrevMI;') + header_txt.append('') + header_txt.append('} OT_MEM_INFO;') + header_txt.append('') + header_txt.append('// Track Queue information') + header_txt.append('typedef struct _OT_QUEUE_INFO {') + header_txt.append(' OT_MEM_INFO *pMemRefList;') + header_txt.append(' struct _OT_QUEUE_INFO *pNextQI;') + header_txt.append(' VkQueue queue;') + header_txt.append(' uint32_t refCount;') + header_txt.append('} OT_QUEUE_INFO;') + header_txt.append('') + header_txt.append('// Global list of QueueInfo structures, one per queue') + header_txt.append('static OT_QUEUE_INFO *g_pQueueInfo;') + header_txt.append('') + header_txt.append('// Add new queue to head of global queue list') + header_txt.append('static void addQueueInfo(VkQueue queue)') + header_txt.append('{') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = malloc(sizeof(OT_QUEUE_INFO));') + header_txt.append(' memset(pQueueInfo, 0, sizeof(OT_QUEUE_INFO));') + header_txt.append(' pQueueInfo->queue = queue;') + header_txt.append('') + header_txt.append(' if (pQueueInfo != NULL) {') + header_txt.append(' pQueueInfo->pNextQI = g_pQueueInfo;') + header_txt.append(' g_pQueueInfo = pQueueInfo;') + header_txt.append(' }') + header_txt.append(' else {') + header_txt.append(' char str[1024];') + header_txt.append(' sprintf(str, "ERROR: VK_ERROR_OUT_OF_MEMORY -- could not allocate memory for Queue Information");') + header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);') + header_txt.append(' }') + header_txt.append('}') + header_txt.append('') + header_txt.append('// Returns pointer to this queue\'s mem ref data') + header_txt.append('static OT_QUEUE_INFO* getQueueInfo(VkQueue queue)') + header_txt.append('{') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;') + header_txt.append(' OT_QUEUE_INFO *pFound = NULL;') + header_txt.append(' while (pQueueInfo != NULL) {') + header_txt.append(' if (pQueueInfo->queue != queue) {') + header_txt.append(' pQueueInfo = pQueueInfo->pNextQI;') + header_txt.append(' }') + header_txt.append(' else {') + header_txt.append(' pFound = pQueueInfo;') + header_txt.append(' break;') + header_txt.append(' }') + header_txt.append(' }') + header_txt.append(' return pFound;') + header_txt.append('}') + header_txt.append('') + header_txt.append('// Returns pointer to a specific memory reference in a queue\'s mem ref list') + header_txt.append('static OT_MEM_INFO* findMemRefInQueueList(VkQueue queue, VkGpuMemory mem)') + header_txt.append('{') + header_txt.append(' // Get pointer to queue\'s list') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = getQueueInfo(queue);') + header_txt.append(' OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;') + header_txt.append(' OT_MEM_INFO *pFound = NULL;') + header_txt.append('') + header_txt.append(' while (pMemInfo != NULL) {') + header_txt.append(' if (pMemInfo->mem != mem) {') + header_txt.append(' pMemInfo = pMemInfo->pNextMI;') + header_txt.append(' }') + header_txt.append(' else {') + header_txt.append(' pFound = pMemInfo;') + header_txt.append(' break;') + header_txt.append(' }') + header_txt.append(' }') + header_txt.append(' return pFound;') + header_txt.append('}') + header_txt.append('') + header_txt.append('// Add memory reference to queue\'s mem ref list') + header_txt.append('static void addMemRef(VkQueue queue, VkGpuMemory mem)') + header_txt.append('{') + header_txt.append(' // if ref not already in queue\'s list, add to front.') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = getQueueInfo(queue);') + header_txt.append(' OT_MEM_INFO *pMemInfo = findMemRefInQueueList(queue, mem);') + header_txt.append(' if (pMemInfo == NULL) {') + header_txt.append(' // Not in list, add to front') + header_txt.append(' pMemInfo = malloc(sizeof(OT_MEM_INFO));') + header_txt.append(' memset(pMemInfo, 0, sizeof(OT_MEM_INFO));') + header_txt.append('') + header_txt.append(' if (pMemInfo != NULL) {') + header_txt.append(' pMemInfo->mem = mem;') + header_txt.append(' pMemInfo->pNextMI = pQueueInfo->pMemRefList;') + header_txt.append(' pMemInfo->pPrevMI = NULL;') + header_txt.append(' if (pQueueInfo->pMemRefList != NULL) {') + header_txt.append(' pQueueInfo->pMemRefList->pPrevMI = pMemInfo;') + header_txt.append(' }') + header_txt.append(' pQueueInfo->pMemRefList = pMemInfo;') + header_txt.append(' pQueueInfo->refCount++;') + header_txt.append(' }') + header_txt.append(' else {') + header_txt.append(' char str[1024];') + header_txt.append(' sprintf(str, "ERROR: VK_ERROR_OUT_OF_MEMORY -- could not allocate memory for memory reference Information");') + header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_INTERNAL_ERROR, "OBJTRACK", str);') + header_txt.append(' }') + header_txt.append(' }') + header_txt.append('}') + header_txt.append('') + header_txt.append('static void deleteMemRef(VkQueue queue, VkGpuMemory mem)') + header_txt.append('{') + header_txt.append(' // Search queue\'s list for mem, remove from list') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = getQueueInfo(queue);') + header_txt.append(' OT_MEM_INFO *pMemInfo = findMemRefInQueueList(queue, mem);') + header_txt.append('') + header_txt.append(' if (pMemInfo != NULL) {') + header_txt.append(' // Remove pMemInfo from doubly-linked list') + header_txt.append(' if (pQueueInfo->pMemRefList == pMemInfo) {') + header_txt.append(' // update head of list, which is being removed') + header_txt.append(' pQueueInfo->pMemRefList = pMemInfo->pNextMI;') + header_txt.append(' }') + header_txt.append(' if (pMemInfo->pNextMI != NULL) {') + header_txt.append(' pMemInfo->pNextMI->pPrevMI = pMemInfo->pPrevMI;') + header_txt.append(' }') + header_txt.append(' if (pMemInfo->pPrevMI != NULL) {') + header_txt.append(' pMemInfo->pPrevMI->pNextMI = pMemInfo->pNextMI;') + header_txt.append(' }') + header_txt.append(' free(pMemInfo);') + header_txt.append(' pQueueInfo->refCount--;') + header_txt.append(' }') + header_txt.append(' else {') + header_txt.append(' char str[1024];') + header_txt.append(' sprintf(str, "vkQueueRemoveReference called to remove a memory reference %p from queue %p that was not added", mem, queue);') + header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, OBJTRACK_MISSING_OBJECT, "OBJTRACK", str);') + header_txt.append(' }') + header_txt.append('}') + header_txt.append('') + header_txt.append('// Destroy memRef lists and free all memory') + header_txt.append('static void destroyQueueMemRefLists()') + header_txt.append('{') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = g_pQueueInfo;') + header_txt.append(' OT_QUEUE_INFO *pDelQueueInfo = NULL;') + header_txt.append(' while (pQueueInfo != NULL) {') + header_txt.append(' OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;') + header_txt.append(' while (pMemInfo != NULL) {') + header_txt.append(' OT_MEM_INFO *pDelMemInfo = pMemInfo;') + header_txt.append(' pMemInfo = pMemInfo->pNextMI;') + header_txt.append(' free(pDelMemInfo);') + header_txt.append(' }') + header_txt.append(' pDelQueueInfo = pQueueInfo;') + header_txt.append(' pQueueInfo = pQueueInfo->pNextQI;') + header_txt.append(' free(pDelQueueInfo);') + header_txt.append(' }') + header_txt.append('}') + header_txt.append('') header_txt.append('// Debug function to print global list and each individual object list') header_txt.append('static void ll_print_lists()') header_txt.append('{') @@ -846,7 +997,7 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' printf(" ObjNode (%p) w/ %s obj %p has pNextGlobal %p\\n", (void*)pTrav, string_VK_OBJECT_TYPE(pTrav->obj.objType), pTrav->obj.pObj, (void*)pTrav->pNextGlobal);') header_txt.append(' pTrav = pTrav->pNextGlobal;') header_txt.append(' }') - header_txt.append(' for (uint32_t i = 0; i < VK_NUM_OBJECT_TYPE; i++) {') + header_txt.append(' for (uint32_t i = 0; i < VkNumObjectType; i++) {') header_txt.append(' pTrav = pObjectHead[i];') header_txt.append(' if (pTrav) {') header_txt.append(' printf("=====%s OBJECT LIST (%lu objs):\\n", string_VK_OBJECT_TYPE(pTrav->obj.objType), numObjs[i]);') @@ -889,7 +1040,7 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' char str[1024];') header_txt.append(' sprintf(str, "Attempting look-up on obj %p but it is NOT in the global list!", (void*)object);') header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, OBJTRACK_MISSING_OBJECT, "OBJTRACK", str);') - header_txt.append(' return VK_OBJECT_TYPE_UNKNOWN;') + header_txt.append(' return VkObjectTypeUnknown;') header_txt.append('}') header_txt.append('#if 0') header_txt.append('static uint64_t ll_get_obj_uses(void* pObj, VK_OBJECT_TYPE objType) {') @@ -995,8 +1146,8 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append('}') header_txt.append('') header_txt.append('// Track selected state for an object node') - header_txt.append('static void track_object_status(void* pObj, VK_STATE_BIND_POINT stateBindPoint) {') - header_txt.append(' objNode *pTrav = pObjectHead[VK_OBJECT_TYPE_CMD_BUFFER];') + header_txt.append('static void track_object_status(void* pObj, VkStateBindPoint stateBindPoint) {') + header_txt.append(' objNode *pTrav = pObjectHead[VkObjectTypeCmdBuffer];') header_txt.append('') header_txt.append(' while (pTrav) {') header_txt.append(' if (pTrav->obj.pObj == pObj) {') @@ -1050,7 +1201,7 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append(' }') header_txt.append(' pTrav = pTrav->pNextObj;') header_txt.append(' }') - header_txt.append(' if (objType != VK_OBJECT_TYPE_PRESENTABLE_IMAGE_MEMORY) {') + header_txt.append(' if (objType != VkObjectTypePresentableImageMemory) {') header_txt.append(' // If we do not find it print an error') header_txt.append(' char str[1024];') header_txt.append(' sprintf(str, "Unable to obtain status for non-existent object %p of %s type", pObj, string_VK_OBJECT_TYPE(objType));') @@ -1060,14 +1211,45 @@ class ObjectTrackerSubcommand(Subcommand): header_txt.append('}') header_txt.append('') header_txt.append('static void validate_draw_state_flags(void* pObj) {') - header_txt.append(' validate_status((void*)pObj, VK_OBJECT_TYPE_CMD_BUFFER, OBJSTATUS_VIEWPORT_BOUND, OBJSTATUS_VIEWPORT_BOUND, VK_DBG_MSG_ERROR, OBJTRACK_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");') - header_txt.append(' validate_status((void*)pObj, VK_OBJECT_TYPE_CMD_BUFFER, OBJSTATUS_RASTER_BOUND, OBJSTATUS_RASTER_BOUND, VK_DBG_MSG_ERROR, OBJTRACK_RASTER_NOT_BOUND, "Raster object not bound to this command buffer");') - header_txt.append(' validate_status((void*)pObj, VK_OBJECT_TYPE_CMD_BUFFER, OBJSTATUS_COLOR_BLEND_BOUND, OBJSTATUS_COLOR_BLEND_BOUND, VK_DBG_MSG_UNKNOWN, OBJTRACK_COLOR_BLEND_NOT_BOUND, "Color-blend object not bound to this command buffer");') - header_txt.append(' validate_status((void*)pObj, VK_OBJECT_TYPE_CMD_BUFFER, OBJSTATUS_DEPTH_STENCIL_BOUND, OBJSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_MSG_UNKNOWN, OBJTRACK_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");') + header_txt.append(' validate_status((void*)pObj, VkObjectTypeCmdBuffer, OBJSTATUS_VIEWPORT_BOUND, OBJSTATUS_VIEWPORT_BOUND, VK_DBG_MSG_ERROR, OBJTRACK_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");') + header_txt.append(' validate_status((void*)pObj, VkObjectTypeCmdBuffer, OBJSTATUS_RASTER_BOUND, OBJSTATUS_RASTER_BOUND, VK_DBG_MSG_ERROR, OBJTRACK_RASTER_NOT_BOUND, "Raster object not bound to this command buffer");') + header_txt.append(' validate_status((void*)pObj, VkObjectTypeCmdBuffer, OBJSTATUS_COLOR_BLEND_BOUND, OBJSTATUS_COLOR_BLEND_BOUND, VK_DBG_MSG_UNKNOWN, OBJTRACK_COLOR_BLEND_NOT_BOUND, "Color-blend object not bound to this command buffer");') + header_txt.append(' validate_status((void*)pObj, VkObjectTypeCmdBuffer, OBJSTATUS_DEPTH_STENCIL_BOUND, OBJSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_MSG_UNKNOWN, OBJTRACK_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");') + header_txt.append('}') + header_txt.append('') + header_txt.append('static void validate_memory_mapping_status(VkQueue queue)') + header_txt.append('{') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = getQueueInfo(queue);') + header_txt.append(' OT_MEM_INFO *pMemInfo = pQueueInfo->pMemRefList;') + header_txt.append('') + header_txt.append(' while (pMemInfo != NULL) {') + header_txt.append(' // If mem reference is in a presentable image memory list, skip the check of the GPU_MEMORY list') + header_txt.append(' if (!validate_status((void *)pMemInfo->mem, VkObjectTypePresentableImageMemory, OBJSTATUS_NONE,') + header_txt.append(' OBJSTATUS_NONE, VK_DBG_MSG_UNKNOWN, OBJTRACK_NONE, NULL) == VK_TRUE) {') + header_txt.append(' validate_status((void *)pMemInfo->mem, VkObjectTypeGpuMemory, OBJSTATUS_GPU_MEM_MAPPED, OBJSTATUS_NONE,') + header_txt.append(' VK_DBG_MSG_ERROR, OBJTRACK_GPU_MEM_MAPPED, "A Mapped Memory Object was referenced in a command buffer");') + header_txt.append(' }') + header_txt.append(' pMemInfo = pMemInfo->pNextMI;') + header_txt.append(' }') + header_txt.append('}') + header_txt.append('') + header_txt.append('static void validate_mem_ref_count(VkQueue queue) {') + header_txt.append(' if (maxMemReferences == 0) {') + header_txt.append(' char str[1024];') + header_txt.append(' sprintf(str, "vkQueueSubmit called before calling vkGetGpuInfo");') + header_txt.append(' layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, NULL, 0, OBJTRACK_GETGPUINFO_NOT_CALLED, "OBJTRACK", str);') + header_txt.append(' } else {') + header_txt.append(' OT_QUEUE_INFO *pQueueInfo = getQueueInfo(queue);') + header_txt.append(' if (pQueueInfo->refCount > maxMemReferences) {') + header_txt.append(' char str[1024];') + header_txt.append(' sprintf(str, "vkQueueSubmit Memory reference count (%d) exceeds allowable GPU limit (%d)", pQueueInfo->refCount, maxMemReferences);') + header_txt.append(' layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, OBJTRACK_MEMREFCOUNT_MAX_EXCEEDED, "OBJTRACK", str);') + header_txt.append(' }') + header_txt.append(' }') header_txt.append('}') header_txt.append('') header_txt.append('static void setGpuQueueInfoState(void *pData) {') - header_txt.append(' maxMemReferences = ((VkPhysicalGpu_QUEUE_PROPERTIES *)pData)->maxMemReferences;') + header_txt.append(' maxMemReferences = ((VkPhysicalGpuQueueProperties *)pData)->maxMemReferences;') header_txt.append('}') return "\n".join(header_txt) @@ -1154,6 +1336,10 @@ class ObjectTrackerSubcommand(Subcommand): destroy_line += ' pTrav = pTrav->pNextGlobal;\n' destroy_line += ' }\n' destroy_line += ' }\n' + destroy_line += ' // Clean up Queue\'s MemRef Linked Lists\n' + destroy_line += ' destroyQueueMemRefLists();\n' + if 'GetDeviceQueue' in proto.name: + destroy_line = ' addQueueInfo(*pQueue);\n' ret_val = '' stmt = '' if proto.ret != "void": |
