blob: dc3dda4c675ce9a924ec6bc86934a2bf746727c6 [file] [log] [blame]
Tobin Ehlis6663f492014-11-10 12:29:12 -07001/*
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05002 * Vulkan
Tobin Ehlis6663f492014-11-10 12:29:12 -07003 *
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05004 * Copyright (C) 2015 LunarG, Inc.
Tobin Ehlis6663f492014-11-10 12:29:12 -07005 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050017* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Tobin Ehlis6663f492014-11-10 12:29:12 -070018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050025#include <inttypes.h>
Tobin Ehlis6663f492014-11-10 12:29:12 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <assert.h>
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050030#include <list>
31#include <map>
Chia-I Wuf8693382015-04-16 22:02:10 +080032#include <vector>
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050033using namespace std;
34
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070035#include "loader_platform.h"
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060036#include "vk_dispatch_table_helper.h"
37#include "vk_struct_string_helper_cpp.h"
Tobin Ehliscd9223b2014-11-19 16:19:28 -070038#include "mem_tracker.h"
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070039#include "layers_config.h"
Ian Elliott655cad72015-02-12 17:08:34 -070040// The following is #included again to catch certain OS-specific functions
41// being used:
42#include "loader_platform.h"
Jon Ashburn2e672892015-02-16 08:46:53 -070043#include "layers_msg.h"
Tobin Ehlis6663f492014-11-10 12:29:12 -070044
Jon Ashburnbacb0f52015-04-06 10:58:22 -060045static VkLayerDispatchTable nextTable;
46static VkBaseLayerObject *pCurObj;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -070047static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -060048// TODO : This can be much smarter, using separate locks for separate global data
49static int globalLockInitialized = 0;
50static loader_platform_thread_mutex globalLock;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -070051
Tobin Ehlisc145be82015-01-08 15:22:32 -070052#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlisc145be82015-01-08 15:22:32 -070053
Mark Lobodzinskib1567a02015-04-21 15:33:04 -060054map<VkCmdBuffer, MT_CB_INFO*> cbMap;
55map<VkDeviceMemory, MT_MEM_OBJ_INFO*> memObjMap;
56map<VkObject, MT_OBJ_INFO*> objectMap;
57map<uint64_t, MT_FENCE_INFO*> fenceMap; // Map fenceId to fence info
58map<VkQueue, MT_QUEUE_INFO*> queueMap;
59map<VkSwapChainWSI, MT_SWAP_CHAIN_INFO*> swapChainMap;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050060
Mark Lobodzinski50932972015-04-02 20:49:09 -050061// TODO : Add per-device fence completion
Mark Lobodzinskib1567a02015-04-21 15:33:04 -060062static uint64_t g_currentFenceId = 1;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -060063static VkDevice globalDevice = NULL;
Mark Lobodzinskic52b7752015-02-18 16:38:17 -060064
Mark Lobodzinski223ca202015-04-02 08:52:53 -050065// Add new queue for this device to map container
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -060066static void addQueueInfo(const VkQueue queue)
Mark Lobodzinski223ca202015-04-02 08:52:53 -050067{
Mark Lobodzinski50932972015-04-02 20:49:09 -050068 MT_QUEUE_INFO* pInfo = new MT_QUEUE_INFO;
69 pInfo->lastRetiredId = 0;
70 pInfo->lastSubmittedId = 0;
71 queueMap[queue] = pInfo;
Mark Lobodzinski223ca202015-04-02 08:52:53 -050072}
73
Mark Lobodzinskib1567a02015-04-21 15:33:04 -060074static void deleteQueueInfoList(
75 void)
Mark Lobodzinski223ca202015-04-02 08:52:53 -050076{
77 // Process queue list, cleaning up each entry before deleting
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -060078 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -050079 (*ii).second->pQueueCmdBuffers.clear();
80 }
81 queueMap.clear();
82}
83
Mark Lobodzinskib1567a02015-04-21 15:33:04 -060084static void addSwapChainInfo(
85 const VkSwapChainWSI swapChain)
Chia-I Wuf8693382015-04-16 22:02:10 +080086{
87 MT_SWAP_CHAIN_INFO* pInfo = new MT_SWAP_CHAIN_INFO;
88 swapChainMap[swapChain] = pInfo;
89}
90
Mark Lobodzinski223ca202015-04-02 08:52:53 -050091// Add new CBInfo for this cb to map container
Mark Lobodzinskib1567a02015-04-21 15:33:04 -060092static void addCBInfo(
93 const VkCmdBuffer cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -070094{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -050095 MT_CB_INFO* pInfo = new MT_CB_INFO;
Tony Barbourd1c35722015-04-16 15:59:00 -060096 memset(pInfo, 0, (sizeof(MT_CB_INFO) - sizeof(list<VkDeviceMemory>)));
Mark Lobodzinski6434eff2015-03-31 16:05:35 -050097 pInfo->cmdBuffer = cb;
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -060098 cbMap[cb] = pInfo;
Tobin Ehlis6663f492014-11-10 12:29:12 -070099}
100
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500101// Return ptr to Info in CB map, or NULL if not found
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600102static MT_CB_INFO* getCBInfo(
103 const VkCmdBuffer cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700104{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500105 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500106 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500107 pCBInfo = cbMap[cb];
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600108 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500109 return pCBInfo;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700110}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600111
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500112// Return object info for 'object' or return NULL if no info exists
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600113static MT_OBJ_INFO* getObjectInfo(
114 const VkObject object)
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500115{
116 MT_OBJ_INFO* pObjInfo = NULL;
117
118 if (objectMap.find(object) != objectMap.end()) {
119 pObjInfo = objectMap[object];
120 }
121 return pObjInfo;
122}
123
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600124static MT_OBJ_INFO* addObjectInfo(
125 VkObject object,
126 VkStructureType sType,
127 const void *pCreateInfo,
128 const int struct_size,
129 const char *name_prefix)
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500130{
131 MT_OBJ_INFO* pInfo = new MT_OBJ_INFO;
132 memset(pInfo, 0, sizeof(MT_OBJ_INFO));
133 memcpy(&pInfo->create_info, pCreateInfo, struct_size);
134 sprintf(pInfo->object_name, "%s_%p", name_prefix, object);
135
136 pInfo->object = object;
137 pInfo->ref_count = 1;
138 pInfo->sType = sType;
139 objectMap[object] = pInfo;
140
141 return pInfo;
142}
143
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500144// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600145static uint64_t addFenceInfo(
146 VkFence fence,
147 VkQueue queue)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500148{
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500149 // Create fence object
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500150 MT_FENCE_INFO* pFenceInfo = new MT_FENCE_INFO;
Mark Lobodzinski50932972015-04-02 20:49:09 -0500151 MT_QUEUE_INFO* pQueueInfo = queueMap[queue];
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500152 uint64_t fenceId = g_currentFenceId++;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500153 memset(pFenceInfo, 0, sizeof(MT_FENCE_INFO));
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500154 // If no fence, create an internal fence to track the submissions
155 if (fence == NULL) {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600156 VkFenceCreateInfo fci;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600157 fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500158 fci.pNext = NULL;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600159 fci.flags = static_cast<VkFenceCreateFlags>(0);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500160 nextTable.CreateFence(globalDevice, &fci, &pFenceInfo->fence);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600161 addObjectInfo(pFenceInfo->fence, fci.sType, &fci, sizeof(VkFenceCreateInfo), "internalFence");
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600162 pFenceInfo->localFence = VK_TRUE;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500163 } else {
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -0500164 // Validate that fence is in UNSIGNALED state
165 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
166 if (pObjectInfo != NULL) {
Tobin Ehlisb870cbb2015-04-15 07:46:12 -0600167 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -0500168 char str[1024];
169 sprintf(str, "Fence %p submitted in SIGNALED state. Fences must be reset before being submitted", fence);
Tobin Ehlisb870cbb2015-04-15 07:46:12 -0600170 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -0500171 }
172 }
Tobin Ehlisb870cbb2015-04-15 07:46:12 -0600173 pFenceInfo->localFence = VK_FALSE;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500174 pFenceInfo->fence = fence;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700175 }
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500176 pFenceInfo->queue = queue;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500177 fenceMap[fenceId] = pFenceInfo;
Mark Lobodzinski50932972015-04-02 20:49:09 -0500178 // Update most recently submitted fenceId for Queue
179 pQueueInfo->lastSubmittedId = fenceId;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500180 return fenceId;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500181}
182
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500183// Remove a fenceInfo from our list of fences/fenceIds
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600184static void deleteFenceInfo(
185 uint64_t fenceId)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500186{
187 if (fenceId != 0) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500188 if (fenceMap.find(fenceId) != fenceMap.end()) {
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600189 map<uint64_t, MT_FENCE_INFO*>::iterator item;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500190 MT_FENCE_INFO* pDelInfo = fenceMap[fenceId];
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500191 if (pDelInfo != NULL) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600192 if (pDelInfo->localFence == VK_TRUE) {
Mike Stroyanb050c682015-04-17 12:36:38 -0600193 nextTable.DestroyObject(globalDevice, VK_OBJECT_TYPE_FENCE, pDelInfo->fence);
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500194 }
195 delete pDelInfo;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500196 }
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600197 item = fenceMap.find(fenceId);
198 fenceMap.erase(item);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500199 }
200 }
201}
202
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500203// Search through list for this fence, deleting all items before it (with lower IDs) and updating lastRetiredId
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600204static void updateFenceTracking(
205 VkFence fence)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500206{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500207 MT_FENCE_INFO *pCurFenceInfo = NULL;
208 uint64_t fenceId = 0;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600209 VkQueue queue = NULL;
210 bool found = false;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500211
Mike Stroyan8fbeea92015-04-15 15:37:47 -0600212 for (map<uint64_t, MT_FENCE_INFO*>::iterator ii=fenceMap.begin(); !found && ii!=fenceMap.end(); ++ii) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500213 if ((*ii).second != NULL) {
214 if (fence == ((*ii).second)->fence) {
215 queue = ((*ii).second)->queue;
216 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
217 pQueueInfo->lastRetiredId = (*ii).first;
Mike Stroyan8fbeea92015-04-15 15:37:47 -0600218 found = true;
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500219 } else {
220 deleteFenceInfo((*ii).first);
221 }
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500222 // Update fence state in fenceCreateInfo structure
223 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
224 if (pObjectInfo != NULL) {
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -0500225 pObjectInfo->create_info.fence_create_info.flags =
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600226 static_cast<VkFenceCreateFlags>(
227 pObjectInfo->create_info.fence_create_info.flags | VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500228 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500229 }
230 }
231}
232
233// Utility function that determines if a fenceId has been retired yet
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600234static bool32_t fenceRetired(
235 uint64_t fenceId)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500236{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600237 bool32_t result = VK_FALSE;
Courtney Goeltzenleuchter0c55f3a2015-04-15 14:10:51 -0600238 if (fenceMap.find(fenceId) != fenceMap.end()) {
239 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500240 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
Mark Lobodzinski3bc3f6e2015-04-02 08:52:53 -0500241 if (fenceId <= pQueueInfo->lastRetiredId)
242 {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600243 result = VK_TRUE;
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500244 }
Mark Lobodzinski50932972015-04-02 20:49:09 -0500245 } else { // If not in list, fence has been retired and deleted
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600246 result = VK_TRUE;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500247 }
248 return result;
249}
250
251// Return the fence associated with a fenceId
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600252static VkFence getFenceFromId(
253 uint64_t fenceId)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500254{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600255 VkFence fence = NULL;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500256 if (fenceId != 0) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500257 // Search for an item with this fenceId
258 if (fenceMap.find(fenceId) != fenceMap.end()) {
259 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
260 if (pFenceInfo != NULL) {
261 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
262 if (fenceId > pQueueInfo->lastRetiredId) {
263 fence = pFenceInfo->fence;
264 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500265 }
266 }
267 }
268 return fence;
269}
270
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500271// Helper routine that updates the fence list for a specific queue to all-retired
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600272static void retireQueueFences(
273 VkQueue queue)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500274{
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600275 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
276 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
277 // Set Queue's lastRetired to lastSubmitted, free items in queue's fence list
278 map<uint64_t, MT_FENCE_INFO*>::iterator it = fenceMap.begin();
279 map<uint64_t, MT_FENCE_INFO*>::iterator temp;
280 while (it != fenceMap.end()) {
Tobin Ehlis5d37f702015-04-15 14:25:02 -0600281 if ((((*it).second) != NULL) && ((*it).second)->queue == queue) {
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600282 temp = it;
283 ++temp;
284 deleteFenceInfo((*it).first);
285 it = temp;
286 } else {
287 ++it;
288 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500289 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700290}
291
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500292// Helper routine that updates fence list for all queues to all-retired
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600293static void retireDeviceFences(
294 VkDevice device)
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500295{
296 // Process each queue for device
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600297 // TODO: Add multiple device support
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600298 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500299 retireQueueFences((*ii).first);
300 }
301}
302
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500303// Returns True if a memory reference is present in a Queue's memory reference list
304// Queue is validated by caller
305static bool32_t checkMemRef(
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600306 VkQueue queue,
Tony Barbourd1c35722015-04-16 15:59:00 -0600307 VkDeviceMemory mem)
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500308{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600309 bool32_t result = VK_FALSE;
Tony Barbourd1c35722015-04-16 15:59:00 -0600310 list<VkDeviceMemory>::iterator it;
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500311 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
312 for (it = pQueueInfo->pMemRefList.begin(); it != pQueueInfo->pMemRefList.end(); ++it) {
313 if ((*it) == mem) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600314 result = VK_TRUE;
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500315 break;
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500316 }
317 }
318 return result;
319}
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500320
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500321static bool32_t validateQueueMemRefs(
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600322 VkQueue queue,
323 uint32_t cmdBufferCount,
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600324 const VkCmdBuffer *pCmdBuffers)
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500325{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600326 bool32_t result = VK_TRUE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500327
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500328 // Verify Queue
329 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
330 if (pQueueInfo == NULL) {
331 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600332 sprintf(str, "Unknown Queue %p specified in vkQueueSubmit", queue);
333 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500334 }
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500335 else {
336 // Iterate through all CBs in pCmdBuffers
337 for (uint32_t i = 0; i < cmdBufferCount; i++) {
338 MT_CB_INFO* pCBInfo = getCBInfo(pCmdBuffers[i]);
339 if (!pCBInfo) {
340 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600341 sprintf(str, "Unable to find info for CB %p in order to check memory references in "
342 "vkQueueSubmit for queue %p",
343 (void*)pCmdBuffers[i], queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600344 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_INVALID_CB, "MEM", str);
345 result = VK_FALSE;
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500346 } else {
347 // Validate that all actual references are accounted for in pMemRefs
Tony Barbourd1c35722015-04-16 15:59:00 -0600348 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500349 // Search for each memref in queues memreflist.
350 if (checkMemRef(queue, *it)) {
351 char str[1024];
352 sprintf(str, "Found Mem Obj %p binding to CB %p for queue %p", (*it), pCmdBuffers[i], queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600353 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500354 }
355 else {
356 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600357 sprintf(str, "Queue %p Memory reference list for Command Buffer %p is missing ref to mem obj %p",
358 queue, pCmdBuffers[i], (*it));
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600359 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_INVALID_MEM_REF, "MEM", str);
360 result = VK_FALSE;
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500361 }
362 }
363 }
364 }
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600365 if (result == VK_TRUE) {
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500366 char str[1024];
367 sprintf(str, "Verified all memory dependencies for Queue %p are included in pMemRefs list", queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600368 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500369 // TODO : Could report mem refs in pMemRefs that AREN'T in mem list, that would be primarily informational
370 // Currently just noting that there is a difference
371 }
372 }
373
374 return result;
375}
Courtney Goeltzenleuchter97b75232015-04-07 17:13:38 -0600376
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500377// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700378// Calls to this function should be wrapped in mutex
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600379static MT_MEM_OBJ_INFO* getMemObjInfo(
380 const VkDeviceMemory mem)
Tobin Ehlisc145be82015-01-08 15:22:32 -0700381{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500382 MT_MEM_OBJ_INFO* pMemObjInfo = NULL;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500383
384 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500385 pMemObjInfo = memObjMap[mem];
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600386 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500387 return pMemObjInfo;
Tobin Ehlisc145be82015-01-08 15:22:32 -0700388}
389
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600390static void addMemObjInfo(
391 const VkDeviceMemory mem,
392 const VkMemoryAllocInfo *pAllocInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700393{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500394 MT_MEM_OBJ_INFO* pInfo = new MT_MEM_OBJ_INFO;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600395 pInfo->refCount = 0;
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600396 memset(&pInfo->allocInfo, 0, sizeof(VkMemoryAllocInfo));
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500397
Chia-I Wuf8693382015-04-16 22:02:10 +0800398 if (pAllocInfo) { // MEM alloc created by vkCreateSwapChainWSI() doesn't have alloc info struct
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600399 memcpy(&pInfo->allocInfo, pAllocInfo, sizeof(VkMemoryAllocInfo));
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500400 // TODO: Update for real hardware, actually process allocation info structures
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500401 pInfo->allocInfo.pNext = NULL;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700402 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500403 pInfo->mem = mem;
404 memObjMap[mem] = pInfo;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700405}
406
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500407// Find CB Info and add mem binding to list container
408// Find Mem Obj Info and add CB binding to list container
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600409static bool32_t updateCBBinding(
410 const VkCmdBuffer cb,
411 const VkDeviceMemory mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700412{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600413 bool32_t result = VK_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700414 // First update CB binding in MemObj mini CB list
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500415 MT_MEM_OBJ_INFO* pMemInfo = getMemObjInfo(mem);
416 if (!pMemInfo) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700417 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600418 sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that mem obj.\n "
419 "Was it correctly allocated? Did it already get freed?", mem, cb);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600420 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
421 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600422 } else {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500423 // Search for cmd buffer object in memory object's binding list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600424 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600425 for (list<VkCmdBuffer>::iterator it = pMemInfo->pCmdBufferBindings.begin(); it != pMemInfo->pCmdBufferBindings.end(); ++it) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500426 if ((*it) == cb) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600427 found = VK_TRUE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500428 break;
429 }
430 }
431 // If not present, add to list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600432 if (found == VK_FALSE) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500433 pMemInfo->pCmdBufferBindings.push_front(cb);
434 pMemInfo->refCount++;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500435 }
436
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500437 // Now update CBInfo's Mem binding list
438 MT_CB_INFO* pCBInfo = getCBInfo(cb);
439 if (!pCBInfo) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500440 char str[1024];
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500441 sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that CB. Was it CB incorrectly destroyed?", mem, cb);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600442 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
443 result = VK_FALSE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500444 } else {
445 // Search for memory object in cmd buffer's binding list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600446 bool32_t found = VK_FALSE;
Tony Barbourd1c35722015-04-16 15:59:00 -0600447 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500448 if ((*it) == mem) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600449 found = VK_TRUE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500450 break;
451 }
452 }
453 // If not present, add to list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600454 if (found == VK_FALSE) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500455 pCBInfo->pMemObjList.push_front(mem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600456 }
457 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700458 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600459 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700460}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600461
Tobin Ehlis6663f492014-11-10 12:29:12 -0700462// Clear the CB Binding for mem
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700463// Calls to this function should be wrapped in mutex
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600464static void clearCBBinding(
465 const VkCmdBuffer cb,
466 const VkDeviceMemory mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700467{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500468 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500469 // TODO : Having this check is not ideal, really if memInfo was deleted,
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700470 // its CB bindings should be cleared and then freeCBBindings wouldn't call
471 // us here with stale mem objs
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500472 if (pInfo) {
473 pInfo->pCmdBufferBindings.remove(cb);
474 pInfo->refCount--;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700475 }
476}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600477
Tobin Ehlis6663f492014-11-10 12:29:12 -0700478// Free bindings related to CB
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600479static bool32_t freeCBBindings(
480 const VkCmdBuffer cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700481{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600482 bool32_t result = VK_TRUE;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500483 MT_CB_INFO* pCBInfo = getCBInfo(cb);
484 if (!pCBInfo) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700485 char str[1024];
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500486 sprintf(str, "Unable to find global CB info %p for deletion", cb);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600487 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
488 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600489 } else {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500490 if (!fenceRetired(pCBInfo->fenceId)) {
491 deleteFenceInfo(pCBInfo->fenceId);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600492 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500493
Tony Barbourd1c35722015-04-16 15:59:00 -0600494 for (list<VkDeviceMemory>::iterator it=pCBInfo->pMemObjList.begin(); it!=pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500495 clearCBBinding(cb, (*it));
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600496 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500497 pCBInfo->pMemObjList.clear();
Tobin Ehlis6663f492014-11-10 12:29:12 -0700498 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600499 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700500}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600501
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500502// Delete CBInfo from list along with all of it's mini MemObjInfo
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500503// and also clear mem references to CB
Tobin Ehlis6663f492014-11-10 12:29:12 -0700504// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600505static bool32_t deleteCBInfo(
506 const VkCmdBuffer cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700507{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600508 bool32_t result = VK_TRUE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600509 result = freeCBBindings(cb);
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500510 // Delete the CBInfo info
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600511 if (result == VK_TRUE) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500512 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500513 MT_CB_INFO* pDelInfo = cbMap[cb];
514 delete pDelInfo;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500515 cbMap.erase(cb);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600516 }
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700517 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600518 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700519}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600520
Tobin Ehlis6663f492014-11-10 12:29:12 -0700521// Delete the entire CB list
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600522static bool32_t deleteCBInfoList(
523 void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700524{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600525 bool32_t result = VK_TRUE;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600526 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500527 freeCBBindings((*ii).first);
528 delete (*ii).second;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700529 }
530 return result;
531}
532
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500533// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600534static void reportMemReferencesAndCleanUp(
535 MT_MEM_OBJ_INFO* pMemObjInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700536{
Tony Barbour18f71552015-04-22 11:36:22 -0600537 size_t cmdBufRefCount = pMemObjInfo->pCmdBufferBindings.size();
538 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500539
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500540 if ((pMemObjInfo->pCmdBufferBindings.size() + pMemObjInfo->pObjBindings.size()) != 0) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700541 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600542 sprintf(str, "Attempting to free memory object %p which still contains %lu references",
543 pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600544 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700545 }
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500546
547 if (cmdBufRefCount > 0) {
548 for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
549 char str[1024];
550 sprintf(str, "Command Buffer %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
551 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
552 }
553 // Clear the list of hanging references
554 pMemObjInfo->pCmdBufferBindings.clear();
555 }
556
557 if (objRefCount > 0) {
558 for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
559 char str[1024];
560 sprintf(str, "VK Object %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
561 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
562 }
563 // Clear the list of hanging references
564 pMemObjInfo->pObjBindings.clear();
565 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700566}
567
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600568static void deleteMemObjInfo(
569 VkDeviceMemory mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700570{
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500571 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500572 MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
573 delete pDelInfo;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500574 memObjMap.erase(mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700575 }
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500576 else {
577 char str[1024];
578 sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
579 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
580 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700581}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500582
Tobin Ehlis6663f492014-11-10 12:29:12 -0700583// Check if fence for given CB is completed
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600584static bool32_t checkCBCompleted(
585 const VkCmdBuffer cb)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700586{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600587 bool32_t result = VK_TRUE;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500588 MT_CB_INFO* pCBInfo = getCBInfo(cb);
589 if (!pCBInfo) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700590 char str[1024];
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500591 sprintf(str, "Unable to find global CB info %p to check for completion", cb);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600592 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
593 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600594 } else {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500595 if (!fenceRetired(pCBInfo->fenceId)) {
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600596 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600597 sprintf(str, "FenceId %" PRIx64", fence %p for CB %p has not been checked for completion",
598 pCBInfo->fenceId, getFenceFromId(pCBInfo->fenceId), cb);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600599 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
600 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600601 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700602 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600603 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700604}
605
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600606static bool32_t freeMemObjInfo(
607 VkDeviceMemory mem,
608 bool internal)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700609{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600610 bool32_t result = VK_TRUE;
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500611 // Parse global list to find info w/ mem
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500612 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
613 if (!pInfo) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700614 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600615 sprintf(str, "Couldn't find mem info object for %p\n Was %p never allocated or previously freed?",
616 (void*)mem, (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600617 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
618 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600619 } else {
Courtney Goeltzenleuchter1c943a72015-03-26 16:15:39 -0600620 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600621 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600622 sprintf(str, "Attempting to free memory associated with a Persistent Image, %p, "
623 "this should not be explicitly freed\n", (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600624 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
625 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600626 } else {
627 // Clear any CB bindings for completed CBs
628 // TODO : Is there a better place to do this?
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500629
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600630 list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin();
631 list<VkCmdBuffer>::iterator temp;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500632 while (it != pInfo->pCmdBufferBindings.end()) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600633 if (VK_TRUE == checkCBCompleted(*it)) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500634 temp = it;
635 ++temp;
636 freeCBBindings(*it);
637 it = temp;
638 } else {
639 ++it;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600640 }
641 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500642
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600643 // Now verify that no references to this mem obj remain
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500644 if (0 != pInfo->refCount) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500645 // If references remain, report the error and can search CB list to find references
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600646 char str[1024];
647 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600648 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500649 reportMemReferencesAndCleanUp(pInfo);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600650 result = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600651 }
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600652 // Delete mem obj info
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500653 deleteMemObjInfo(mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700654 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700655 }
656 return result;
657}
658
Tobin Ehlis6663f492014-11-10 12:29:12 -0700659// Remove object binding performs 3 tasks:
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500660// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
661// 2. Decrement refCount for MemObjInfo
662// 3. Clear MemObjInfo ptr from ObjectInfo
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600663static bool32_t clearObjectBinding(
664 VkObject object)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700665{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600666 bool32_t result = VK_FALSE;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500667 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
668 if (!pObjInfo) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700669 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600670 sprintf(str, "Attempting to clear mem binding for object %p: devices, queues, command buffers, "
671 "shaders and memory objects do not have external memory requirements and it is "
672 "unneccessary to call bind/unbindObjectMemory on them.", object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600673 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600674 } else {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500675 if (!pObjInfo->pMemObjInfo) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600676 char str[1024];
677 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600678 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600679 } else {
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500680 // 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
681 // and set the objects memory binding pointer to NULL.
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600682 for (list<VkObject>::iterator it = pObjInfo->pMemObjInfo->pObjBindings.begin(); it != pObjInfo->pMemObjInfo->pObjBindings.end(); ++it) {
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500683 if ((*it) == object) {
684 pObjInfo->pMemObjInfo->refCount--;
685 pObjInfo->pMemObjInfo->pObjBindings.erase(it);
686 pObjInfo->pMemObjInfo = NULL;
687 result = VK_TRUE;
688 break;
689 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600690 }
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600691 if (result == VK_FALSE) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600692 char str[1024];
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500693 sprintf(str, "While trying to clear mem binding for object %p, unable to find that object referenced by mem obj %p",
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500694 object, pObjInfo->pMemObjInfo->mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600695 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600696 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700697 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700698 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600699 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700700}
701
702// For NULL mem case, clear any previous binding Else...
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500703// Make sure given object is in global object map
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700704// IF a previous binding existed, clear it
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500705// Add reference from objectInfo to memoryInfo
706// Add reference off of objInfo
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600707// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600708static bool32_t updateObjectBinding(
709 VkObject object,
710 VkDeviceMemory mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700711{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600712 bool32_t result = VK_FALSE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700713 // Handle NULL case separately, just clear previous binding & decrement reference
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600714 if (mem == VK_NULL_HANDLE) {
Tobin Ehlis6663f492014-11-10 12:29:12 -0700715 clearObjectBinding(object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600716 result = VK_TRUE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600717 } else {
718 char str[1024];
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500719 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
720 if (!pObjInfo) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600721 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600722 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
723 return VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600724 }
725 // non-null case so should have real mem obj
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500726 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
727 if (!pInfo) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500728 sprintf(str, "While trying to bind mem for obj %p, couldn't find info for mem obj %p", (void*)object, (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600729 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600730 } else {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500731 // Search for object in memory object's binding list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600732 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600733 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500734 if ((*it) == object) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600735 found = VK_TRUE;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500736 break;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600737 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600738 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500739 // If not present, add to list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600740 if (found == VK_FALSE) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500741 pInfo->pObjBindings.push_front(object);
742 pInfo->refCount++;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500743 }
744
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500745 if (pObjInfo->pMemObjInfo) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500746 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500747 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pObjInfo->pMemObjInfo->mem, mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600748 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500749 }
750 // For image objects, make sure default memory state is correctly set
751 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600752 if (VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pObjInfo->sType) {
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600753 if (pObjInfo->create_info.image_create_info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
754 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500755 // TODO:: More memory state transition stuff.
756 }
757 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500758 pObjInfo->pMemObjInfo = pInfo;
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700759 }
760 }
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600761 return VK_TRUE;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700762}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600763
Tobin Ehlis6663f492014-11-10 12:29:12 -0700764// Print details of global Obj tracking list
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600765static void printObjList(
766 void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700767{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500768 MT_OBJ_INFO* pInfo = NULL;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500769 char str[1024];
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500770 sprintf(str, "Details of Object list of size %lu elements", objectMap.size());
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600771 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600772 for (map<VkObject, MT_OBJ_INFO*>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500773 pInfo = (*ii).second;
774 sprintf(str, " ObjInfo %p has object %p, pMemObjInfo %p", pInfo, pInfo->object, pInfo->pMemObjInfo);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600775 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700776 }
777}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600778
Tobin Ehlis6663f492014-11-10 12:29:12 -0700779// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600780static VkDeviceMemory getMemBindingFromObject(
781 const VkObject object)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700782{
Tony Barbourd1c35722015-04-16 15:59:00 -0600783 VkDeviceMemory mem = NULL;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500784 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
785 if (pObjInfo) {
786 if (pObjInfo->pMemObjInfo) {
787 mem = pObjInfo->pMemObjInfo->mem;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700788 }
789 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700790 char str[1024];
791 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600792 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700793 printObjList();
794 }
795 }
796 else {
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700797 char str[1024];
798 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600799 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700800 printObjList();
801 }
802 return mem;
803}
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500804
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500805// Print details of MemObjInfo list
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600806static void printMemList(
807 void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700808{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500809 MT_MEM_OBJ_INFO* pInfo = NULL;
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700810 // Just printing each msg individually for now, may want to package these into single large print
811 char str[1024];
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500812 sprintf(str, "MEM INFO : Details of Memory Object list of size %lu elements", memObjMap.size());
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600813 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500814
Tony Barbourd1c35722015-04-16 15:59:00 -0600815 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500816 pInfo = (*ii).second;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500817
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500818 sprintf(str, " ===MemObjInfo at %p===", (void*)pInfo);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600819 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500820 sprintf(str, " Mem object: %p", (void*)pInfo->mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600821 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500822 sprintf(str, " Ref Count: %u", pInfo->refCount);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600823 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500824 if (0 != pInfo->allocInfo.allocationSize) {
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600825 string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "{MEM}INFO : ");
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500826 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600827 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500828 } else {
Chia-I Wuf8693382015-04-16 22:02:10 +0800829 sprintf(str, " Mem Alloc info is NULL (alloc done by vkCreateSwapChainWSI())");
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600830 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500831 }
832
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600833 sprintf(str, " VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
834 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600835 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600836 sprintf(str, " VK OBJECT %p", (*it));
837 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500838 }
839
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600840 sprintf(str, " VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
841 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600842 for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600843 sprintf(str, " VK CB %p", (*it));
844 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700845 }
846 }
847}
848
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600849static void printCBList(
850 void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700851{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700852 char str[1024] = {0};
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500853 MT_CB_INFO* pCBInfo = NULL;
854 sprintf(str, "Details of CB list of size %lu elements", cbMap.size());
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600855 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500856
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600857 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500858 pCBInfo = (*ii).second;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500859
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500860 sprintf(str, " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %p",
861 (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
862 (void*)getFenceFromId(pCBInfo->fenceId));
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600863 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500864
Tony Barbourd1c35722015-04-16 15:59:00 -0600865 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500866 sprintf(str, " Mem obj %p", (*it));
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600867 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700868 }
869 }
870}
871
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600872static void initMemTracker(
873 void)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700874{
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700875 const char *strOpt;
876 // initialize MemTracker options
Ian Elliotte7826712015-03-06 13:50:05 -0700877 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
878 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlisee702232015-01-08 14:26:53 -0700879
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600880 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700881 {
882 strOpt = getLayerOption("MemTrackerLogFilename");
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600883 if (strOpt) {
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700884 g_logFile = fopen(strOpt, "w");
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700885 }
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600886 if (g_logFile == NULL) {
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700887 g_logFile = stdout;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600888 }
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700889 }
890
891 // initialize Layer dispatch table
892 // TODO handle multiple GPUs
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600893 PFN_vkGetProcAddr fpNextGPA;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700894 fpNextGPA = pCurObj->pGPA;
895 assert(fpNextGPA);
896
Tony Barbourd1c35722015-04-16 15:59:00 -0600897 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
Chia-I Wuaa4121f2015-01-04 23:11:43 +0800898
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600899 if (!globalLockInitialized)
900 {
901 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600902 // suggestion is to call this during vkCreateInstance(), and then we
903 // can clean it up during vkDestroyInstance(). However, that requires
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600904 // that the layer have per-instance locks. We need to come back and
905 // address this soon.
906 loader_platform_thread_create_mutex(&globalLock);
907 globalLockInitialized = 1;
908 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700909}
910
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600911VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
912 VkPhysicalDevice gpu,
913 const VkDeviceCreateInfo *pCreateInfo,
914 VkDevice *pDevice)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700915{
Jon Ashburn4d9f4652015-04-08 21:33:34 -0600916 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -0700917 loader_platform_thread_once(&g_initOnce, initMemTracker);
Jon Ashburn4d9f4652015-04-08 21:33:34 -0600918 VkResult result = nextTable.CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700919 // Save off device in case we need it to create Fences
920 globalDevice = *pDevice;
921 return result;
922}
923
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600924VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(
925 VkDevice device)
Tobin Ehlis6663f492014-11-10 12:29:12 -0700926{
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700927 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600928 sprintf(str, "Printing List details prior to vkDestroyDevice()");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600929 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600930 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700931 printMemList();
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500932 printCBList();
Tobin Ehlis6663f492014-11-10 12:29:12 -0700933 printObjList();
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600934 if (VK_FALSE == deleteCBInfoList()) {
935 sprintf(str, "Issue deleting global CB list in vkDestroyDevice()");
936 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -0700937 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700938 // Report any memory leaks
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500939 MT_MEM_OBJ_INFO* pInfo = NULL;
Tony Barbourd1c35722015-04-16 15:59:00 -0600940 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinskied450b02015-04-07 13:38:21 -0500941 pInfo = (*ii).second;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500942
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500943 if (pInfo->allocInfo.allocationSize != 0) {
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600944 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling "
945 "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600946 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -0600947 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -0700948 }
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500949
950 // Queues persist until device is destroyed
951 deleteQueueInfoList();
952
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600953 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600954 VkResult result = nextTable.DestroyDevice(device);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700955 return result;
956}
957
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600958struct extProps {
959 uint32_t version;
960 const char * const name;
961};
Jon Ashburn120cfbe2015-04-14 14:12:59 -0600962#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600963static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
964 // TODO what is the version?
Jon Ashburn120cfbe2015-04-14 14:12:59 -0600965 0x10, "MemTracker",
966 0x10, "Validation"
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600967};
968
969VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600970 VkExtensionInfoType infoType,
971 uint32_t extensionIndex,
972 size_t *pDataSize,
973 void *pData)
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600974{
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600975 // This entrypoint is NOT going to init its own dispatch table since loader calls here early
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600976 VkExtensionProperties *ext_props;
977 uint32_t *count;
978
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600979 if (pDataSize == NULL) {
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600980 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600981 }
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600982
983 switch (infoType) {
984 case VK_EXTENSION_INFO_TYPE_COUNT:
985 *pDataSize = sizeof(uint32_t);
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600986 if (pData == NULL) {
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600987 return VK_SUCCESS;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600988 }
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600989 count = (uint32_t *) pData;
990 *count = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE;
991 break;
992 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
993 *pDataSize = sizeof(VkExtensionProperties);
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600994 if (pData == NULL) {
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600995 return VK_SUCCESS;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600996 }
997 if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) {
Jon Ashburn9fd4cc42015-04-10 14:33:07 -0600998 return VK_ERROR_INVALID_VALUE;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -0600999 }
Jon Ashburn9fd4cc42015-04-10 14:33:07 -06001000 ext_props = (VkExtensionProperties *) pData;
1001 ext_props->version = mtExts[extensionIndex].version;
1002 strncpy(ext_props->extName, mtExts[extensionIndex].name,
1003 VK_MAX_EXTENSION_NAME);
1004 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
1005 break;
1006 default:
1007 return VK_ERROR_INVALID_VALUE;
1008 };
1009
1010 return VK_SUCCESS;
1011}
1012
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001013VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(
1014 VkPhysicalDevice gpu,
1015 size_t maxStringSize,
1016 size_t *pLayerCount,
1017 char* const *pOutLayers,
1018 void *pReserved)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001019{
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001020 if (gpu != NULL)
Jon Ashburnf7a08742014-11-25 11:08:42 -07001021 {
Jon Ashburn4d9f4652015-04-08 21:33:34 -06001022 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07001023 loader_platform_thread_once(&g_initOnce, initMemTracker);
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -06001024 VkResult result = nextTable.EnumerateLayers(gpu,
1025 maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburnf7a08742014-11-25 11:08:42 -07001026 return result;
1027 } else
1028 {
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001029 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001030 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001031 }
Jon Ashburnf7a08742014-11-25 11:08:42 -07001032 // This layer compatible with all GPUs
Courtney Goeltzenleuchterd9dc0c72015-04-20 11:04:54 -06001033 *pLayerCount = 1;
Chia-I Wu1da4b9f2014-12-16 10:47:33 +08001034 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001035 return VK_SUCCESS;
Jon Ashburnf7a08742014-11-25 11:08:42 -07001036 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001037}
1038
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001039VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
1040 VkDevice device,
1041 uint32_t queueNodeIndex,
1042 uint32_t queueIndex,
1043 VkQueue *pQueue)
Mark Lobodzinski748eddf2015-03-31 16:05:35 -05001044{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001045 VkResult result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001046 if (result == VK_SUCCESS) {
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001047 loader_platform_thread_lock_mutex(&globalLock);
1048 addQueueInfo(*pQueue);
1049 loader_platform_thread_unlock_mutex(&globalLock);
1050 }
Mark Lobodzinski748eddf2015-03-31 16:05:35 -05001051 return result;
1052}
1053
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001054VK_LAYER_EXPORT VkResult VKAPI vkQueueAddMemReferences(
1055 VkQueue queue,
1056 uint32_t count,
1057 const VkDeviceMemory *pMems)
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001058{
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001059 VkResult result = nextTable.QueueAddMemReferences(queue, count, pMems);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001060 if (result == VK_SUCCESS) {
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001061 loader_platform_thread_lock_mutex(&globalLock);
1062
1063 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
1064 if (pQueueInfo == NULL) {
1065 char str[1024];
1066 sprintf(str, "Unknown Queue %p", queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001067 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001068 } else {
Tony Barbour18f71552015-04-22 11:36:22 -06001069 for (uint32_t i = 0; i < count; i++) {
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001070 if (checkMemRef(queue, pMems[i]) == VK_TRUE) {
1071 // Alread in list, just warn
1072 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001073 sprintf(str, "Request to add a memory reference (%p) to Queue %p -- ref is already "
1074 "present in the queue's reference list", pMems[i], queue);
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001075 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pMems[i], 0, MEMTRACK_INVALID_MEM_REF, "MEM", str);
1076 } else {
1077 // Add to queue's memory reference list
1078 pQueueInfo->pMemRefList.push_front(pMems[i]);
1079 }
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001080 }
1081 }
1082 loader_platform_thread_unlock_mutex(&globalLock);
1083 }
1084 return result;
1085}
1086
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001087VK_LAYER_EXPORT VkResult VKAPI vkQueueRemoveMemReferences(
1088 VkQueue queue,
1089 uint32_t count,
1090 const VkDeviceMemory *pMems)
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001091{
1092 // TODO : Decrement ref count for this memory reference on this queue. Remove if ref count is zero.
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001093 VkResult result = nextTable.QueueRemoveMemReferences(queue, count, pMems);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001094 if (result == VK_SUCCESS) {
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001095 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001096
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001097 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
1098 if (pQueueInfo == NULL) {
1099 char str[1024];
1100 sprintf(str, "Unknown Queue %p", queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001101 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001102 } else {
Tony Barbour18f71552015-04-22 11:36:22 -06001103 for (uint32_t i = 0; i < count; i++) {
Tony Barbourd1c35722015-04-16 15:59:00 -06001104 for (list<VkDeviceMemory>::iterator it = pQueueInfo->pMemRefList.begin(); it != pQueueInfo->pMemRefList.end(); ++it) {
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001105 if ((*it) == pMems[i]) {
1106 it = pQueueInfo->pMemRefList.erase(it);
1107 }
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001108 }
1109 }
1110 }
1111 loader_platform_thread_unlock_mutex(&globalLock);
1112 }
1113 return result;
1114}
1115
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001116VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(
1117 VkQueue queue,
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001118 uint32_t cmdBufferCount,
1119 const VkCmdBuffer *pCmdBuffers,
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001120 VkFence fence)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001121{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001122 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001123 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001124 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski223ca202015-04-02 08:52:53 -05001125 uint64_t fenceId = addFenceInfo(fence, queue);
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001126
Tobin Ehlis6663f492014-11-10 12:29:12 -07001127 printMemList();
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001128 printCBList();
Tobin Ehlis6663f492014-11-10 12:29:12 -07001129 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001130 pCBInfo = getCBInfo(pCmdBuffers[i]);
1131 pCBInfo->fenceId = fenceId;
Tobin Ehlis6663f492014-11-10 12:29:12 -07001132 }
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001133
Mark Lobodzinskie01252d2015-04-17 11:44:25 -05001134 validateQueueMemRefs(queue, cmdBufferCount, pCmdBuffers);
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001135
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001136 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001137 VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, getFenceFromId(fenceId));
Courtney Goeltzenleuchterd3fb9552015-04-02 13:39:07 -06001138 return result;
1139}
1140
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001141VK_LAYER_EXPORT VkResult VKAPI vkAllocMemory(
1142 VkDevice device,
1143 const VkMemoryAllocInfo *pAllocInfo,
1144 VkDeviceMemory *pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001145{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001146 VkResult result = nextTable.AllocMemory(device, pAllocInfo, pMem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001147 // TODO : Track allocations and overall size here
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001148 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski223ca202015-04-02 08:52:53 -05001149 addMemObjInfo(*pMem, pAllocInfo);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001150 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001151 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001152 return result;
1153}
1154
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001155VK_LAYER_EXPORT VkResult VKAPI vkFreeMemory(
1156 VkDevice device,
1157 VkDeviceMemory mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001158{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001159 /* From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed. Before
Tobin Ehlisc0418f92014-11-25 14:47:20 -07001160 * freeing a memory object, an application must ensure the memory object is unbound from
1161 * all API objects referencing it and that it is not referenced by any queued command buffers
1162 */
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001163 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001164 if (VK_FALSE == freeMemObjInfo(mem, false)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001165 char str[1024];
1166 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001167 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001168 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001169 printMemList();
1170 printObjList();
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001171 printCBList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001172 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanb050c682015-04-17 12:36:38 -06001173 VkResult result = nextTable.FreeMemory(device, mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001174 return result;
1175}
1176
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001177VK_LAYER_EXPORT VkResult VKAPI vkSetMemoryPriority(
1178 VkDevice device,
1179 VkDeviceMemory mem,
1180 VkMemoryPriority priority)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001181{
1182 // TODO : Update tracking for this alloc
1183 // Make sure memory is not pinned, which can't have priority set
Mike Stroyanb050c682015-04-17 12:36:38 -06001184 VkResult result = nextTable.SetMemoryPriority(device, mem, priority);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001185 return result;
1186}
1187
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001188VK_LAYER_EXPORT VkResult VKAPI vkMapMemory(
1189 VkDevice device,
1190 VkDeviceMemory mem,
1191 VkDeviceSize offset,
1192 VkDeviceSize size,
1193 VkFlags flags,
1194 void **ppData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001195{
1196 // TODO : Track when memory is mapped
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001197 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001198 MT_MEM_OBJ_INFO *pMemObj = getMemObjInfo(mem);
Tony Barbourd1c35722015-04-16 15:59:00 -06001199 if ((pMemObj->allocInfo.memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
Mark Lobodzinski95152dc2015-02-25 12:16:04 -06001200 char str[1024];
Tony Barbourd1c35722015-04-16 15:59:00 -06001201 sprintf(str, "Mapping Memory (%p) without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set", (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001202 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
Mark Lobodzinski95152dc2015-02-25 12:16:04 -06001203 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001204 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanb050c682015-04-17 12:36:38 -06001205 VkResult result = nextTable.MapMemory(device, mem, offset, size, flags, ppData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001206 return result;
1207}
1208
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001209VK_LAYER_EXPORT VkResult VKAPI vkUnmapMemory(
1210 VkDevice device,
1211 VkDeviceMemory mem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001212{
1213 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
1214 // Make sure that memory was ever mapped to begin with
Mike Stroyanb050c682015-04-17 12:36:38 -06001215 VkResult result = nextTable.UnmapMemory(device, mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001216 return result;
1217}
1218
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001219VK_LAYER_EXPORT VkResult VKAPI vkPinSystemMemory(
1220 VkDevice device,
1221 const void *pSysMem,
1222 size_t memSize,
1223 VkDeviceMemory *pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001224{
1225 // TODO : Track this
1226 // Verify that memory is actually pinnable
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001227 VkResult result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001228 return result;
1229}
1230
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001231VK_LAYER_EXPORT VkResult VKAPI vkOpenSharedMemory(
1232 VkDevice device,
1233 const VkMemoryOpenInfo *pOpenInfo,
1234 VkDeviceMemory *pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001235{
1236 // TODO : Track this
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001237 VkResult result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001238 return result;
1239}
1240
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001241VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerMemory(
1242 VkDevice device,
1243 const VkPeerMemoryOpenInfo *pOpenInfo,
1244 VkDeviceMemory *pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001245{
1246 // TODO : Track this
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001247 VkResult result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001248 return result;
1249}
1250
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001251VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerImage(
1252 VkDevice device,
1253 const VkPeerImageOpenInfo *pOpenInfo,
1254 VkImage *pImage,
1255 VkDeviceMemory *pMem)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001256{
1257 // TODO : Track this
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001258 VkResult result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001259 return result;
1260}
1261
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001262VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(
1263 VkDevice device,
1264 VkObjectType objType,
1265 VkObject object)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001266{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001267 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001268
Tobin Ehlisa98df732014-11-27 07:52:04 -07001269 // First check if this is a CmdBuffer
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001270 if (NULL != getCBInfo((VkCmdBuffer)object)) {
1271 deleteCBInfo((VkCmdBuffer)object);
Tobin Ehlisa98df732014-11-27 07:52:04 -07001272 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001273
1274 if (objectMap.find(object) != objectMap.end()) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001275 MT_OBJ_INFO* pDelInfo = objectMap[object];
1276 if (pDelInfo->pMemObjInfo) {
Tobin Ehlisa98df732014-11-27 07:52:04 -07001277 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001278 if (0 == pDelInfo->pMemObjInfo->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
Tony Barbourd1c35722015-04-16 15:59:00 -06001279 VkDeviceMemory memToFree = pDelInfo->pMemObjInfo->mem;
Tobin Ehlisa98df732014-11-27 07:52:04 -07001280 clearObjectBinding(object);
Courtney Goeltzenleuchter1c943a72015-03-26 16:15:39 -06001281 freeMemObjInfo(memToFree, true);
1282 }
1283 else {
Tobin Ehlisa98df732014-11-27 07:52:04 -07001284 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001285 sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding "
1286 "by calling vkQueueBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)",
1287 object, (void*)pDelInfo->pMemObjInfo->mem, object);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001288 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001289 // From the spec : If an object has previous memory binding, it is required to unbind memory
1290 // from an API object before it is destroyed.
Tobin Ehlisa98df732014-11-27 07:52:04 -07001291 clearObjectBinding(object);
1292 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001293 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001294 delete pDelInfo;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001295 objectMap.erase(object);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001296 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05001297
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001298 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanb050c682015-04-17 12:36:38 -06001299 VkResult result = nextTable.DestroyObject(device, objType, object);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001300 return result;
1301}
1302
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001303VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo(
1304 VkDevice device,
1305 VkObjectType objType,
1306 VkObject object,
1307 VkObjectInfoType infoType,
1308 size_t *pDataSize,
1309 void *pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001310{
1311 // TODO : What to track here?
Mark Lobodzinski40f7f402015-04-16 11:44:05 -05001312 // Could potentially save returned mem requirements and validate values passed into QueueBindObjectMemory for this object
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001313 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues,
1314 // command buffers, shaders and memory objects.
Mike Stroyanb050c682015-04-17 12:36:38 -06001315 VkResult result = nextTable.GetObjectInfo(device, objType, object, infoType, pDataSize, pData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001316 return result;
1317}
1318
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001319VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(
1320 VkQueue queue,
1321 VkObjectType objType,
1322 VkObject object,
1323 uint32_t allocationIdx,
1324 VkDeviceMemory mem,
1325 VkDeviceSize offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001326{
Mike Stroyanb050c682015-04-17 12:36:38 -06001327 VkResult result = nextTable.QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset);
1328 loader_platform_thread_lock_mutex(&globalLock);
1329 // Track objects tied to memory
1330 if (VK_FALSE == updateObjectBinding(object, mem)) {
1331 char str[1024];
1332 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1333 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1334 }
1335 printObjList();
1336 printMemList();
1337 loader_platform_thread_unlock_mutex(&globalLock);
1338 return result;
1339}
1340
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001341VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange(
1342 VkQueue queue,
1343 VkObjectType objType,
1344 VkObject object,
1345 uint32_t allocationIdx,
1346 VkDeviceSize rangeOffset,
1347 VkDeviceSize rangeSize,
1348 VkDeviceMemory mem,
1349 VkDeviceSize memOffset)
Mike Stroyanb050c682015-04-17 12:36:38 -06001350{
1351 VkResult result = nextTable.QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001352 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001353 // Track objects tied to memory
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001354 if (VK_FALSE == updateObjectBinding(object, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001355 char str[1024];
1356 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001357 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001358 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001359 printObjList();
1360 printMemList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001361 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001362 return result;
1363}
1364
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001365VK_LAYER_EXPORT VkResult VKAPI vkCreateFence(
1366 VkDevice device,
1367 const VkFenceCreateInfo *pCreateInfo,
1368 VkFence *pFence)
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001369{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001370 VkResult result = nextTable.CreateFence(device, pCreateInfo, pFence);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001371 if (VK_SUCCESS == result) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001372 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001373 addObjectInfo(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(VkFenceCreateInfo), "fence");
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001374 loader_platform_thread_unlock_mutex(&globalLock);
1375 }
1376 return result;
1377}
1378
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001379VK_LAYER_EXPORT VkResult VKAPI vkResetFences(
1380 VkDevice device,
1381 uint32_t fenceCount,
1382 VkFence *pFences)
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001383{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001384 VkResult result = nextTable.ResetFences(device, fenceCount, pFences);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001385 if (VK_SUCCESS == result) {
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001386 loader_platform_thread_lock_mutex(&globalLock);
1387 // Reset fence state in fenceCreateInfo structure
1388 for (uint32_t i = 0; i < fenceCount; i++) {
1389 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1390 if (pObjectInfo != NULL) {
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -05001391 // Validate fences in SIGNALED state
Tobin Ehlisb870cbb2015-04-15 07:46:12 -06001392 if (!(pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -05001393 char str[1024];
Mark Lobodzinskib2689212015-04-14 14:09:32 -05001394 sprintf(str, "Fence %p submitted to VkResetFences in UNSIGNALED STATE", pFences[i]);
Tobin Ehlisb870cbb2015-04-15 07:46:12 -06001395 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
1396 result = VK_ERROR_INVALID_VALUE;
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -05001397 }
1398 else {
1399 pObjectInfo->create_info.fence_create_info.flags =
Tobin Ehlisb870cbb2015-04-15 07:46:12 -06001400 static_cast<VkFenceCreateFlags>(pObjectInfo->create_info.fence_create_info.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -05001401 }
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001402 }
1403 }
1404 loader_platform_thread_unlock_mutex(&globalLock);
1405 }
1406 return result;
1407}
1408
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001409VK_LAYER_EXPORT VkResult VKAPI vkGetFenceStatus(
1410 VkDevice device,
1411 VkFence fence)
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001412{
Mike Stroyanb050c682015-04-17 12:36:38 -06001413 VkResult result = nextTable.GetFenceStatus(device, fence);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001414 if (VK_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001415 loader_platform_thread_lock_mutex(&globalLock);
1416 updateFenceTracking(fence);
1417 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001418 }
1419 return result;
1420}
1421
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001422VK_LAYER_EXPORT VkResult VKAPI vkWaitForFences(
1423 VkDevice device,
1424 uint32_t fenceCount,
1425 const VkFence *pFences,
1426 bool32_t waitAll,
1427 uint64_t timeout)
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001428{
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001429 // Verify fence status of submitted fences
1430 for(uint32_t i = 0; i < fenceCount; i++) {
1431 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1432 if (pObjectInfo != NULL) {
Tobin Ehlisb870cbb2015-04-15 07:46:12 -06001433 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001434 char str[1024];
Mark Lobodzinskib2689212015-04-14 14:09:32 -05001435 sprintf(str, "VkWaitForFences specified fence %p already in SIGNALED state.", pFences[i]);
Tobin Ehlisb870cbb2015-04-15 07:46:12 -06001436 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
Mark Lobodzinski148e1582015-04-07 16:07:57 -05001437 }
1438 }
1439 }
1440
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001441 VkResult result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001442 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski50932972015-04-02 20:49:09 -05001443
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001444 if (VK_SUCCESS == result) {
Mark Lobodzinski50932972015-04-02 20:49:09 -05001445 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001446 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001447 updateFenceTracking(pFences[i]);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001448 }
1449 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001450 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001451 loader_platform_thread_unlock_mutex(&globalLock);
1452 return result;
1453}
1454
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001455VK_LAYER_EXPORT VkResult VKAPI vkQueueWaitIdle(
1456 VkQueue queue)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001457{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001458 VkResult result = nextTable.QueueWaitIdle(queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001459 if (VK_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001460 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski223ca202015-04-02 08:52:53 -05001461 retireQueueFences(queue);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001462 loader_platform_thread_unlock_mutex(&globalLock);
1463 }
1464 return result;
1465}
1466
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001467VK_LAYER_EXPORT VkResult VKAPI vkDeviceWaitIdle(
1468 VkDevice device)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001469{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001470 VkResult result = nextTable.DeviceWaitIdle(device);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001471 if (VK_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001472 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski50932972015-04-02 20:49:09 -05001473 retireDeviceFences(device);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05001474 loader_platform_thread_unlock_mutex(&globalLock);
1475 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001476 return result;
1477}
1478
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001479VK_LAYER_EXPORT VkResult VKAPI vkCreateEvent(
1480 VkDevice device,
1481 const VkEventCreateInfo *pCreateInfo,
1482 VkEvent *pEvent)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001483{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001484 VkResult result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001485 if (VK_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001486 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001487 addObjectInfo(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(VkEventCreateInfo), "event");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001488 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001489 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001490 return result;
1491}
1492
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001493VK_LAYER_EXPORT VkResult VKAPI vkCreateQueryPool(
1494 VkDevice device,
1495 const VkQueryPoolCreateInfo *pCreateInfo,
1496 VkQueryPool *pQueryPool)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001497{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001498 VkResult result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001499 if (VK_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001500 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001501 addObjectInfo(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(VkQueryPoolCreateInfo), "query_pool");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001502 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001503 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001504 return result;
1505}
1506
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001507VK_LAYER_EXPORT VkResult VKAPI vkCreateBuffer(
1508 VkDevice device,
1509 const VkBufferCreateInfo *pCreateInfo,
1510 VkBuffer *pBuffer)
Tobin Ehlis7265e832015-01-19 08:42:29 -07001511{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001512 VkResult result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001513 if (VK_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001514 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -06001515 addObjectInfo(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferCreateInfo), "buffer");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001516 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001517 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001518 return result;
1519}
1520
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001521VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(
1522 VkDevice device,
1523 const VkBufferViewCreateInfo *pCreateInfo,
1524 VkBufferView *pView)
Tobin Ehlis7265e832015-01-19 08:42:29 -07001525{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001526 VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001527 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001528 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -06001529 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferViewCreateInfo), "buffer_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001530 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001531 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07001532 return result;
1533}
1534
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001535VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(
1536 VkDevice device,
1537 const VkImageCreateInfo *pCreateInfo,
1538 VkImage *pImage)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001539{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001540 VkResult result = nextTable.CreateImage(device, pCreateInfo, pImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001541 if (VK_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001542 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001543 addObjectInfo(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(VkImageCreateInfo), "image");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001544 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001545 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001546 return result;
1547}
1548
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001549VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(
1550 VkDevice device,
1551 const VkImageViewCreateInfo *pCreateInfo,
1552 VkImageView *pView)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001553{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001554 VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001555 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001556 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001557 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkImageViewCreateInfo), "image_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001558 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001559 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001560 return result;
1561}
1562
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001563VK_LAYER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(
1564 VkDevice device,
1565 const VkColorAttachmentViewCreateInfo *pCreateInfo,
1566 VkColorAttachmentView *pView)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001567{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001568 VkResult result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001569 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001570 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001571 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkColorAttachmentViewCreateInfo), "color_attachment_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001572 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001573 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001574 return result;
1575}
1576
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001577VK_LAYER_EXPORT VkResult VKAPI vkCreateDepthStencilView(
1578 VkDevice device,
1579 const VkDepthStencilViewCreateInfo *pCreateInfo,
1580 VkDepthStencilView *pView)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001581{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001582 VkResult result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001583 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001584 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001585 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkDepthStencilViewCreateInfo), "ds_view");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001586 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001587 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001588 return result;
1589}
1590
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001591VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(
1592 VkDevice device,
1593 const VkShaderCreateInfo *pCreateInfo,
1594 VkShader *pShader)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001595{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001596 VkResult result = nextTable.CreateShader(device, pCreateInfo, pShader);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001597 return result;
1598}
1599
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001600VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(
1601 VkDevice device,
1602 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1603 VkPipeline *pPipeline)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001604{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001605 VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001606 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001607 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001608 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001609 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001610 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001611 return result;
1612}
1613
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001614VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001615 VkDevice device,
1616 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1617 VkPipeline basePipeline,
1618 VkPipeline *pPipeline)
Courtney Goeltzenleuchter0d40f152015-03-25 15:37:49 -06001619{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001620 VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001621 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter0d40f152015-03-25 15:37:49 -06001622 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001623 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Courtney Goeltzenleuchter0d40f152015-03-25 15:37:49 -06001624 loader_platform_thread_unlock_mutex(&globalLock);
1625 }
1626 return result;
1627}
1628
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001629VK_LAYER_EXPORT VkResult VKAPI vkCreateComputePipeline(
1630 VkDevice device,
1631 const VkComputePipelineCreateInfo *pCreateInfo,
1632 VkPipeline *pPipeline)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001633{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001634 VkResult result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001635 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001636 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001637 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkComputePipelineCreateInfo), "compute_pipeline");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001638 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001639 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001640 return result;
1641}
1642
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001643VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(
1644 VkDevice device,
1645 const VkSamplerCreateInfo *pCreateInfo,
1646 VkSampler *pSampler)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001647{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001648 VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001649 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001650 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001651 addObjectInfo(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(VkSamplerCreateInfo), "sampler");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001652 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001653 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001654 return result;
1655}
1656
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001657VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(
1658 VkDevice device,
1659 const VkDynamicVpStateCreateInfo *pCreateInfo,
1660 VkDynamicVpState *pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001661{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001662 VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001663 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001664 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001665 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo), "viewport_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001666 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001667 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001668 return result;
1669}
1670
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001671VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(
1672 VkDevice device,
1673 const VkDynamicRsStateCreateInfo *pCreateInfo,
1674 VkDynamicRsState *pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001675{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001676 VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001677 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001678 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001679 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo), "raster_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001680 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001681 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001682 return result;
1683}
1684
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001685VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(
1686 VkDevice device,
1687 const VkDynamicCbStateCreateInfo *pCreateInfo,
1688 VkDynamicCbState *pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001689{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001690 VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001691 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001692 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001693 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo), "cb_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001694 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001695 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001696 return result;
1697}
1698
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001699VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(
1700 VkDevice device,
1701 const VkDynamicDsStateCreateInfo *pCreateInfo,
1702 VkDynamicDsState *pState)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001703{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001704 VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001705 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001706 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001707 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo), "ds_state");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001708 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07001709 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001710 return result;
1711}
1712
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001713VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(
1714 VkDevice device,
1715 const VkCmdBufferCreateInfo *pCreateInfo,
1716 VkCmdBuffer *pCmdBuffer)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001717{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001718 VkResult result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Mark Lobodzinski223ca202015-04-02 08:52:53 -05001719 // At time of cmd buffer creation, create global cmd buffer info for the returned cmd buffer
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001720 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001721 if (*pCmdBuffer)
Mark Lobodzinski223ca202015-04-02 08:52:53 -05001722 addCBInfo(*pCmdBuffer);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001723 printCBList();
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001724 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001725 return result;
1726}
1727
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001728VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(
1729 VkCmdBuffer cmdBuffer,
1730 const VkCmdBufferBeginInfo *pBeginInfo)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001731{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001732 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001733 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1734 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001735 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001736 if (VK_FALSE == cbDone) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001737 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001738 sprintf(str, "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
1739 "You must check CB flag before this call.", cmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001740 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001741 }
1742 }
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001743 VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001744 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001745 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001746 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001747 return result;
1748}
1749
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001750VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(
1751 VkCmdBuffer cmdBuffer)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001752{
1753 // TODO : Anything to do here?
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001754 VkResult result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001755 return result;
1756}
1757
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001758VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(
1759 VkCmdBuffer cmdBuffer)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001760{
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001761 // Verify that CB is complete (not in-flight)
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001762 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1763 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001764 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001765 if (VK_FALSE == cbDone) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001766 char str[1024];
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001767 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before "
1768 "calling vkResetCommandBuffer().", cmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001769 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07001770 }
1771 }
1772 // Clear memory references as this point.
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001773 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001774 freeCBBindings(cmdBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001775 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06001776 VkResult result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001777 return result;
1778}
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001779// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Tobin Ehlis6663f492014-11-10 12:29:12 -07001780// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001781VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(
1782 VkCmdBuffer cmdBuffer,
1783 VkPipelineBindPoint pipelineBindPoint,
1784 VkPipeline pipeline)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001785{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001786#if 0
1787 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1788 if (getPipeline(pipeline)) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001789 MT_CB_INFO *pCBInfo = getCBInfo(cmdBuffer);
1790 if (pCBInfo) {
1791 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlisc145be82015-01-08 15:22:32 -07001792 } else {
1793 char str[1024];
1794 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001795 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001796 }
1797 }
1798 else {
1799 char str[1024];
1800 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001801 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001802 }
1803#endif
Tobin Ehlis6663f492014-11-10 12:29:12 -07001804 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1805}
1806
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001807VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(
1808 VkCmdBuffer cmdBuffer,
1809 VkStateBindPoint stateBindPoint,
1810 VkDynamicStateObject state)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001811{
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001812 MT_OBJ_INFO *pObjInfo;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001813 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001814 MT_CB_INFO *pCmdBuf = getCBInfo(cmdBuffer);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001815 if (!pCmdBuf) {
1816 char str[1024];
1817 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001818 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001819 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001820 pObjInfo = getObjectInfo(state);
1821 if (!pObjInfo) {
Tobin Ehlisc145be82015-01-08 15:22:32 -07001822 char str[1024];
1823 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001824 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07001825 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05001826 pCmdBuf->pDynamicState[stateBindPoint] = pObjInfo;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001827 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001828 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001829}
1830
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001831VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001832 VkCmdBuffer cmdBuffer,
1833 VkPipelineBindPoint pipelineBindPoint,
1834 uint32_t firstSet,
1835 uint32_t setCount,
1836 const VkDescriptorSet *pDescriptorSets,
1837 uint32_t dynamicOffsetCount,
1838 const uint32_t *pDynamicOffsets)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001839{
Tobin Ehlisc145be82015-01-08 15:22:32 -07001840 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Cody Northropd4c1a502015-04-16 13:41:56 -06001841 nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001842}
1843
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001844VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001845 VkCmdBuffer cmdBuffer,
1846 uint32_t startBinding,
1847 uint32_t bindingCount,
1848 const VkBuffer *pBuffers,
1849 const VkDeviceSize *pOffsets)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001850{
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06001851 nextTable.CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wu19156822015-01-05 13:42:56 +08001852}
1853
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001854VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(
1855 VkCmdBuffer cmdBuffer,
1856 VkBuffer buffer,
1857 VkDeviceSize offset,
1858 VkIndexType indexType)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001859{
Tobin Ehlis7265e832015-01-19 08:42:29 -07001860 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001861}
1862
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001863VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(
1864 VkCmdBuffer cmdBuffer,
1865 VkBuffer buffer,
1866 VkDeviceSize offset,
1867 uint32_t count,
1868 uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001869{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001870 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06001871 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001872 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001873 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001874 sprintf(str, "In vkCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1875 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001876 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001877 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001878 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001879}
1880
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001881VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(
1882 VkCmdBuffer cmdBuffer,
1883 VkBuffer buffer,
1884 VkDeviceSize offset,
1885 uint32_t count,
1886 uint32_t stride)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001887{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001888 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06001889 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001890 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001891 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001892 sprintf(str, "In vkCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1893 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001894 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001895 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07001896 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001897}
1898
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001899VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(
1900 VkCmdBuffer cmdBuffer,
1901 VkBuffer buffer,
1902 VkDeviceSize offset)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001903{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001904 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06001905 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001906 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001907 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001908 sprintf(str, "In vkCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1909 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001910 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001911 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001912 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001913}
1914
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001915VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(
1916 VkCmdBuffer cmdBuffer,
1917 VkBuffer srcBuffer,
1918 VkBuffer destBuffer,
1919 uint32_t regionCount,
1920 const VkBufferCopy *pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001921{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001922 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06001923 VkDeviceMemory mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001924 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001925 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001926 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1927 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001928 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001929 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001930 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001931 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001932 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1933 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001934 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001935 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001936 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001937}
1938
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001939VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
1940 VkCmdBuffer cmdBuffer,
1941 VkImage srcImage,
1942 VkImageLayout srcImageLayout,
1943 VkImage destImage,
1944 VkImageLayout destImageLayout,
1945 uint32_t regionCount,
1946 const VkImageCopy *pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001947{
1948 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06001949 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001950}
1951
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001952VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
1953 VkCmdBuffer cmdBuffer,
1954 VkImage srcImage,
1955 VkImageLayout srcImageLayout,
1956 VkImage destImage,
1957 VkImageLayout destImageLayout,
1958 uint32_t regionCount,
1959 const VkImageBlit *pRegions)
Courtney Goeltzenleuchter89299fa2015-03-08 17:02:18 -06001960{
1961 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06001962 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Courtney Goeltzenleuchter89299fa2015-03-08 17:02:18 -06001963}
1964
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001965VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
1966 VkCmdBuffer cmdBuffer,
1967 VkBuffer srcBuffer,
1968 VkImage destImage,
1969 VkImageLayout destImageLayout,
1970 uint32_t regionCount,
1971 const VkBufferImageCopy *pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001972{
1973 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001974 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06001975 VkDeviceMemory mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001976 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001977 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001978 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
1979 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001980 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06001981
1982 mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001983 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001984 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001985 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1986 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07001987 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001988 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06001989 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001990}
1991
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06001992VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
1993 VkCmdBuffer cmdBuffer,
1994 VkImage srcImage,
1995 VkImageLayout srcImageLayout,
1996 VkBuffer destBuffer,
1997 uint32_t regionCount,
1998 const VkBufferImageCopy *pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07001999{
2000 // TODO : Track this
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002001 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002002 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002003 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002004 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002005 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2006 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002007 }
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06002008 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002009 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002010 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002011 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
2012 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002013 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002014 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002015 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002016}
2017
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002018VK_LAYER_EXPORT void VKAPI vkCmdCloneImageData(
2019 VkCmdBuffer cmdBuffer,
2020 VkImage srcImage,
2021 VkImageLayout srcImageLayout,
2022 VkImage destImage,
2023 VkImageLayout destImageLayout)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002024{
2025 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002026 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002027 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002028 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002029 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002030 sprintf(str, "In vkCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2031 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002032 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002033 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002034 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002035 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002036 sprintf(str, "In vkCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2037 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002038 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002039 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanfb80d5f2014-12-04 11:08:39 +00002040 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002041}
2042
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002043VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
2044 VkCmdBuffer cmdBuffer,
2045 VkBuffer destBuffer,
2046 VkDeviceSize destOffset,
2047 VkDeviceSize dataSize,
2048 const uint32_t *pData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002049{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002050 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002051 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002052 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002053 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002054 sprintf(str, "In vkCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
2055 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002056 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002057 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07002058 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002059}
2060
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002061VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
2062 VkCmdBuffer cmdBuffer,
2063 VkBuffer destBuffer,
2064 VkDeviceSize destOffset,
2065 VkDeviceSize fillSize,
2066 uint32_t data)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002067{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002068 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002069 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002070 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002071 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002072 sprintf(str, "In vkCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
2073 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002074 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002075 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis7265e832015-01-19 08:42:29 -07002076 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002077}
2078
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002079VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2080 VkCmdBuffer cmdBuffer,
2081 VkImage image,
2082 VkImageLayout imageLayout,
2083 VkClearColor color,
2084 uint32_t rangeCount,
2085 const VkImageSubresourceRange *pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002086{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002087 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002088 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002089 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002090 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002091 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002092 sprintf(str, "In vkCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
2093 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002094 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002095 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002096 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, color, rangeCount, pRanges);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002097}
2098
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002099VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(
2100 VkCmdBuffer cmdBuffer,
2101 VkImage image,
2102 VkImageLayout imageLayout,
2103 float depth,
2104 uint32_t stencil,
2105 uint32_t rangeCount,
2106 const VkImageSubresourceRange *pRanges)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002107{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002108 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002109 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002110 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002111 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002112 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002113 sprintf(str, "In vkCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
2114 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002115 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002116 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -06002117 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002118}
2119
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002120VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
2121 VkCmdBuffer cmdBuffer,
2122 VkImage srcImage,
2123 VkImageLayout srcImageLayout,
2124 VkImage destImage,
2125 VkImageLayout destImageLayout,
2126 uint32_t regionCount,
2127 const VkImageResolve *pRegions)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002128{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002129 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002130 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002131 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002132 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002133 sprintf(str, "In vkCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2134 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002135 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002136 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002137 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002138 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002139 sprintf(str, "In vkCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2140 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002141 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002142 loader_platform_thread_unlock_mutex(&globalLock);
Tony Barbour6865d4a2015-04-13 15:02:52 -06002143 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002144}
2145
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002146VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(
2147 VkCmdBuffer cmdBuffer,
2148 VkQueryPool queryPool,
2149 uint32_t slot,
2150 VkFlags flags)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002151{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002152 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002153 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002154 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002155 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002156 sprintf(str, "In vkCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2157 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002158 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002159 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002160 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2161}
2162
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002163VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(
2164 VkCmdBuffer cmdBuffer,
2165 VkQueryPool queryPool,
2166 uint32_t slot)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002167{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002168 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002169 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002170 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002171 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002172 sprintf(str, "In vkCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2173 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002174 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002175 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002176 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2177}
2178
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002179VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(
2180 VkCmdBuffer cmdBuffer,
2181 VkQueryPool queryPool,
2182 uint32_t startQuery,
2183 uint32_t queryCount)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002184{
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002185 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbourd1c35722015-04-16 15:59:00 -06002186 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002187 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002188 char str[1024];
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002189 sprintf(str, "In vkCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2190 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002191 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002192 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002193 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2194}
2195
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002196VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
2197 VkInstance instance,
2198 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
2199 void *pUserData)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002200{
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002201 // This layer intercepts callbacks
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002202 VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (VK_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(VK_LAYER_DBG_FUNCTION_NODE));
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002203 if (!pNewDbgFuncNode)
Tony Barbourd1c35722015-04-16 15:59:00 -06002204 return VK_ERROR_OUT_OF_HOST_MEMORY;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002205 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2206 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07002207 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2208 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburna8aa8372015-03-03 15:07:15 -07002209 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07002210 if (g_actionIsDefault) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002211 g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter90d93202015-03-04 15:47:34 -07002212 }
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06002213 VkResult result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002214 return result;
2215}
2216
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002217VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
2218 VkInstance instance,
2219 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002220{
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002221 VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
2222 VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05002223 while (pInfo) {
2224 if (pInfo->pfnMsgCallback == pfnMsgCallback) {
2225 pPrev->pNext = pInfo->pNext;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002226 if (g_pDbgFunctionHead == pInfo) {
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05002227 g_pDbgFunctionHead = pInfo->pNext;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002228 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05002229 free(pInfo);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002230 break;
2231 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05002232 pPrev = pInfo;
2233 pInfo = pInfo->pNext;
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002234 }
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002235 if (g_pDbgFunctionHead == NULL) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05002236 if (g_actionIsDefault) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002237 g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05002238 } else {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002239 g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -05002240 }
Jon Ashburna8aa8372015-03-03 15:07:15 -07002241 }
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -06002242 VkResult result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002243 return result;
2244}
2245
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002246VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
2247 VkDevice device,
2248 const VkSwapChainCreateInfoWSI *pCreateInfo,
2249 VkSwapChainWSI *pSwapChain)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002250{
Chia-I Wuf8693382015-04-16 22:02:10 +08002251 VkResult result = nextTable.CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
2252
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002253 if (VK_SUCCESS == result) {
Chia-I Wuf8693382015-04-16 22:02:10 +08002254 loader_platform_thread_lock_mutex(&globalLock);
2255 addSwapChainInfo(*pSwapChain);
2256 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07002257 }
Chia-I Wuf8693382015-04-16 22:02:10 +08002258
Tobin Ehlis6663f492014-11-10 12:29:12 -07002259 return result;
2260}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002261
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002262VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
2263 VkSwapChainWSI swapChain)
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002264{
2265 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wuf8693382015-04-16 22:02:10 +08002266
2267 if (swapChainMap.find(swapChain) != swapChainMap.end()) {
2268 MT_SWAP_CHAIN_INFO* pInfo = swapChainMap[swapChain];
2269
2270 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2271 it != pInfo->images.end(); it++) {
2272 clearObjectBinding(it->image);
2273 freeMemObjInfo(it->memory, true);
2274
2275 MT_OBJ_INFO* pDelInfo = objectMap[it->image];
2276 delete pDelInfo;
2277 objectMap.erase(it->image);
2278 }
2279
2280 delete pInfo;
2281 swapChainMap.erase(swapChain);
2282 }
2283
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002284 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wuf8693382015-04-16 22:02:10 +08002285
2286 return nextTable.DestroySwapChainWSI(swapChain);
2287}
2288
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002289VK_LAYER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
2290 VkSwapChainWSI swapChain,
2291 VkSwapChainInfoTypeWSI infoType,
2292 size_t *pDataSize,
2293 void *pData)
Chia-I Wuf8693382015-04-16 22:02:10 +08002294{
2295 VkResult result = nextTable.GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
2296
2297 if (infoType == VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI && result == VK_SUCCESS) {
2298 const size_t count = *pDataSize / sizeof(VkSwapChainImageInfoWSI);
2299 MT_SWAP_CHAIN_INFO *pInfo = swapChainMap[swapChain];
2300
2301 if (pInfo->images.empty()) {
2302 pInfo->images.resize(count);
2303 memcpy(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count);
2304
2305 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2306 it != pInfo->images.end(); it++) {
2307 // Add image object, then insert the new Mem Object and then bind it to created image
2308 addObjectInfo(it->image, VK_STRUCTURE_TYPE_MAX_ENUM, &pInfo->createInfo, sizeof(pInfo->createInfo), "persistent_image");
2309 addMemObjInfo(it->memory, NULL);
2310 if (VK_FALSE == updateObjectBinding(it->image, it->memory)) {
2311 char str[1024];
2312 sprintf(str, "In vkGetSwapChainInfoWSI(), unable to set image %p binding to mem obj %p", (void*)it->image, (void*)it->memory);
2313 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
2314 }
2315 }
2316 } else {
2317 const bool mismatch = (pInfo->images.size() != count ||
2318 memcmp(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count));
2319
2320 if (mismatch) {
2321 char str[1024];
2322 sprintf(str, "vkGetSwapChainInfoWSI(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI) returned mismatching data", swapChain);
Mike Stroyanb050c682015-04-17 12:36:38 -06002323 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, (VkObject) swapChain, 0, MEMTRACK_NONE, "SWAP_CHAIN", str);
Chia-I Wuf8693382015-04-16 22:02:10 +08002324 }
2325 }
2326 }
2327
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002328 return result;
2329}
Tobin Ehlis6663f492014-11-10 12:29:12 -07002330
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002331VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(
2332 VkPhysicalDevice gpu,
2333 const char *funcName)
Tobin Ehlis6663f492014-11-10 12:29:12 -07002334{
Jon Ashburnbacb0f52015-04-06 10:58:22 -06002335 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wu4d11dcc2015-01-05 13:18:57 +08002336
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002337 if (gpu == NULL) {
Tobin Ehlis6663f492014-11-10 12:29:12 -07002338 return NULL;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002339 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002340 pCurObj = gpuw;
Ian Elliott2d4ab1e2015-01-13 17:52:38 -07002341 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002342
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002343 if (!strcmp(funcName, "vkGetProcAddr"))
2344 return (void *) vkGetProcAddr;
2345 if (!strcmp(funcName, "vkCreateDevice"))
2346 return (void*) vkCreateDevice;
2347 if (!strcmp(funcName, "vkDestroyDevice"))
2348 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002349 if (!strcmp(funcName, "vkEnumerateLayers"))
2350 return (void*) vkEnumerateLayers;
2351 if (!strcmp(funcName, "vkQueueSubmit"))
2352 return (void*) vkQueueSubmit;
2353 if (!strcmp(funcName, "vkAllocMemory"))
2354 return (void*) vkAllocMemory;
2355 if (!strcmp(funcName, "vkFreeMemory"))
2356 return (void*) vkFreeMemory;
2357 if (!strcmp(funcName, "vkSetMemoryPriority"))
2358 return (void*) vkSetMemoryPriority;
2359 if (!strcmp(funcName, "vkMapMemory"))
2360 return (void*) vkMapMemory;
2361 if (!strcmp(funcName, "vkUnmapMemory"))
2362 return (void*) vkUnmapMemory;
2363 if (!strcmp(funcName, "vkPinSystemMemory"))
2364 return (void*) vkPinSystemMemory;
2365 if (!strcmp(funcName, "vkOpenSharedMemory"))
2366 return (void*) vkOpenSharedMemory;
2367 if (!strcmp(funcName, "vkOpenPeerMemory"))
2368 return (void*) vkOpenPeerMemory;
2369 if (!strcmp(funcName, "vkOpenPeerImage"))
2370 return (void*) vkOpenPeerImage;
2371 if (!strcmp(funcName, "vkDestroyObject"))
2372 return (void*) vkDestroyObject;
2373 if (!strcmp(funcName, "vkGetObjectInfo"))
2374 return (void*) vkGetObjectInfo;
Mark Lobodzinski40f7f402015-04-16 11:44:05 -05002375 if (!strcmp(funcName, "vkQueueBindObjectMemory"))
2376 return (void*) vkQueueBindObjectMemory;
Mike Stroyanb050c682015-04-17 12:36:38 -06002377 if (!strcmp(funcName, "vkQueueBindObjectMemoryRange"))
2378 return (void*) vkQueueBindObjectMemoryRange;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002379 if (!strcmp(funcName, "vkCreateFence"))
2380 return (void*) vkCreateFence;
2381 if (!strcmp(funcName, "vkGetFenceStatus"))
2382 return (void*) vkGetFenceStatus;
2383 if (!strcmp(funcName, "vkResetFences"))
2384 return (void*) vkResetFences;
2385 if (!strcmp(funcName, "vkWaitForFences"))
2386 return (void*) vkWaitForFences;
2387 if (!strcmp(funcName, "vkQueueWaitIdle"))
2388 return (void*) vkQueueWaitIdle;
2389 if (!strcmp(funcName, "vkDeviceWaitIdle"))
2390 return (void*) vkDeviceWaitIdle;
2391 if (!strcmp(funcName, "vkCreateEvent"))
2392 return (void*) vkCreateEvent;
2393 if (!strcmp(funcName, "vkCreateQueryPool"))
2394 return (void*) vkCreateQueryPool;
2395 if (!strcmp(funcName, "vkCreateBuffer"))
2396 return (void*) vkCreateBuffer;
2397 if (!strcmp(funcName, "vkCreateBufferView"))
2398 return (void*) vkCreateBufferView;
2399 if (!strcmp(funcName, "vkCreateImage"))
2400 return (void*) vkCreateImage;
2401 if (!strcmp(funcName, "vkCreateImageView"))
2402 return (void*) vkCreateImageView;
2403 if (!strcmp(funcName, "vkCreateColorAttachmentView"))
2404 return (void*) vkCreateColorAttachmentView;
2405 if (!strcmp(funcName, "vkCreateDepthStencilView"))
2406 return (void*) vkCreateDepthStencilView;
2407 if (!strcmp(funcName, "vkCreateShader"))
2408 return (void*) vkCreateShader;
2409 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2410 return (void*) vkCreateGraphicsPipeline;
2411 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2412 return (void*) vkCreateGraphicsPipelineDerivative;
2413 if (!strcmp(funcName, "vkCreateComputePipeline"))
2414 return (void*) vkCreateComputePipeline;
2415 if (!strcmp(funcName, "vkCreateSampler"))
2416 return (void*) vkCreateSampler;
2417 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2418 return (void*) vkCreateDynamicViewportState;
2419 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2420 return (void*) vkCreateDynamicRasterState;
2421 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2422 return (void*) vkCreateDynamicColorBlendState;
2423 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2424 return (void*) vkCreateDynamicDepthStencilState;
2425 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2426 return (void*) vkCreateCommandBuffer;
2427 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2428 return (void*) vkBeginCommandBuffer;
2429 if (!strcmp(funcName, "vkEndCommandBuffer"))
2430 return (void*) vkEndCommandBuffer;
2431 if (!strcmp(funcName, "vkResetCommandBuffer"))
2432 return (void*) vkResetCommandBuffer;
2433 if (!strcmp(funcName, "vkCmdBindPipeline"))
2434 return (void*) vkCmdBindPipeline;
2435 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2436 return (void*) vkCmdBindDynamicStateObject;
2437 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2438 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06002439 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2440 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002441 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2442 return (void*) vkCmdBindIndexBuffer;
2443 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2444 return (void*) vkCmdDrawIndirect;
2445 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2446 return (void*) vkCmdDrawIndexedIndirect;
2447 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2448 return (void*) vkCmdDispatchIndirect;
2449 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2450 return (void*) vkCmdCopyBuffer;
2451 if (!strcmp(funcName, "vkCmdCopyImage"))
2452 return (void*) vkCmdCopyImage;
2453 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2454 return (void*) vkCmdCopyBufferToImage;
2455 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2456 return (void*) vkCmdCopyImageToBuffer;
2457 if (!strcmp(funcName, "vkCmdCloneImageData"))
2458 return (void*) vkCmdCloneImageData;
2459 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2460 return (void*) vkCmdUpdateBuffer;
2461 if (!strcmp(funcName, "vkCmdFillBuffer"))
2462 return (void*) vkCmdFillBuffer;
2463 if (!strcmp(funcName, "vkCmdClearColorImage"))
2464 return (void*) vkCmdClearColorImage;
2465 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2466 return (void*) vkCmdClearDepthStencil;
2467 if (!strcmp(funcName, "vkCmdResolveImage"))
2468 return (void*) vkCmdResolveImage;
2469 if (!strcmp(funcName, "vkCmdBeginQuery"))
2470 return (void*) vkCmdBeginQuery;
2471 if (!strcmp(funcName, "vkCmdEndQuery"))
2472 return (void*) vkCmdEndQuery;
2473 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2474 return (void*) vkCmdResetQueryPool;
2475 if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
2476 return (void*) vkDbgRegisterMsgCallback;
2477 if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
2478 return (void*) vkDbgUnregisterMsgCallback;
2479 if (!strcmp(funcName, "vkGetDeviceQueue"))
2480 return (void*) vkGetDeviceQueue;
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06002481 if (!strcmp(funcName, "vkQueueAddMemReferences"))
2482 return (void*) vkQueueAddMemReferences;
2483 if (!strcmp(funcName, "vkQueueRemoveMemReferences"))
2484 return (void*) vkQueueRemoveMemReferences;
Chia-I Wuf8693382015-04-16 22:02:10 +08002485 if (!strcmp(funcName, "vkCreateSwapChainWSI"))
2486 return (void*) vkCreateSwapChainWSI;
2487 if (!strcmp(funcName, "vkDestroySwapChainWSI"))
2488 return (void*) vkDestroySwapChainWSI;
2489 if (!strcmp(funcName, "vkGetSwapChainInfoWSI"))
2490 return (void*) vkGetSwapChainInfoWSI;
Tobin Ehlis6663f492014-11-10 12:29:12 -07002491 else {
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002492 if (gpuw->pGPA == NULL) {
Tobin Ehlis6663f492014-11-10 12:29:12 -07002493 return NULL;
Mark Lobodzinskib1567a02015-04-21 15:33:04 -06002494 }
Tony Barbourd1c35722015-04-16 15:59:00 -06002495 return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002496 }
2497}