blob: bbdb4f5da6f292497d40df0f463066fdad86cc02 [file] [log] [blame]
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001/*
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002 * Vulkan
Tobin Ehlis791a49c2014-11-10 12:29:12 -07003 *
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05004 * Copyright (C) 2015 LunarG, Inc.
Tobin Ehlis791a49c2014-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 Lobodzinski283a4c22015-03-24 16:29:24 -050017* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Tobin Ehlis791a49c2014-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 Lobodzinski4aad3642015-03-17 10:53:12 -050025#include <inttypes.h>
Tobin Ehlis791a49c2014-11-10 12:29:12 -070026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <assert.h>
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050030#include <list>
31#include <map>
Chia-I Wu5b66aa52015-04-16 22:02:10 +080032#include <vector>
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050033using namespace std;
34
Ian Elliott81ac44c2015-01-13 17:52:38 -070035#include "loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060036#include "vk_dispatch_table_helper.h"
37#include "vk_struct_string_helper_cpp.h"
Tobin Ehlis62086412014-11-19 16:19:28 -070038#include "mem_tracker.h"
Jon Ashburnf57ea372014-12-22 13:24:15 -070039#include "layers_config.h"
Ian Elliott20f06872015-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 Ashburn5a7be202015-02-16 08:46:53 -070043#include "layers_msg.h"
Tobin Ehlis791a49c2014-11-10 12:29:12 -070044
Jon Ashburn301c5f02015-04-06 10:58:22 -060045static VkLayerDispatchTable nextTable;
46static VkBaseLayerObject *pCurObj;
Ian Elliott81ac44c2015-01-13 17:52:38 -070047static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski0c0d6a02015-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 Ashburnf57ea372014-12-22 13:24:15 -070051
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070052#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070053
Mark Lobodzinskia908b162015-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 Lobodzinski283a4c22015-03-24 16:29:24 -050060
Mark Lobodzinski8ee96342015-04-02 20:49:09 -050061// TODO : Add per-device fence completion
Mark Lobodzinskia908b162015-04-21 15:33:04 -060062static uint64_t g_currentFenceId = 1;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060063static VkDevice globalDevice = NULL;
Mark Lobodzinski15427102015-02-18 16:38:17 -060064
Mark Lobodzinski85a83982015-04-02 08:52:53 -050065// Add new queue for this device to map container
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060066static void addQueueInfo(const VkQueue queue)
Mark Lobodzinski85a83982015-04-02 08:52:53 -050067{
Mark Lobodzinski8ee96342015-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 Lobodzinski85a83982015-04-02 08:52:53 -050072}
73
Mark Lobodzinskia908b162015-04-21 15:33:04 -060074static void deleteQueueInfoList(
75 void)
Mark Lobodzinski85a83982015-04-02 08:52:53 -050076{
77 // Process queue list, cleaning up each entry before deleting
David Pinedof5997ab2015-04-27 16:36:17 -060078 if (queueMap.size() <= 0)
79 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060080 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -050081 (*ii).second->pQueueCmdBuffers.clear();
82 }
83 queueMap.clear();
84}
85
Mark Lobodzinskia908b162015-04-21 15:33:04 -060086static void addSwapChainInfo(
87 const VkSwapChainWSI swapChain)
Chia-I Wu5b66aa52015-04-16 22:02:10 +080088{
89 MT_SWAP_CHAIN_INFO* pInfo = new MT_SWAP_CHAIN_INFO;
90 swapChainMap[swapChain] = pInfo;
91}
92
Mark Lobodzinski85a83982015-04-02 08:52:53 -050093// Add new CBInfo for this cb to map container
Mark Lobodzinskia908b162015-04-21 15:33:04 -060094static void addCBInfo(
95 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -070096{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -050097 MT_CB_INFO* pInfo = new MT_CB_INFO;
Tony Barbour8205d902015-04-16 15:59:00 -060098 memset(pInfo, 0, (sizeof(MT_CB_INFO) - sizeof(list<VkDeviceMemory>)));
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -050099 pInfo->cmdBuffer = cb;
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600100 cbMap[cb] = pInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700101}
102
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500103// Return ptr to Info in CB map, or NULL if not found
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600104static MT_CB_INFO* getCBInfo(
105 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700106{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500107 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500108 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500109 pCBInfo = cbMap[cb];
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600110 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500111 return pCBInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700112}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600113
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500114// Return object info for 'object' or return NULL if no info exists
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600115static MT_OBJ_INFO* getObjectInfo(
116 const VkObject object)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500117{
118 MT_OBJ_INFO* pObjInfo = NULL;
119
120 if (objectMap.find(object) != objectMap.end()) {
121 pObjInfo = objectMap[object];
122 }
123 return pObjInfo;
124}
125
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600126static MT_OBJ_INFO* addObjectInfo(
127 VkObject object,
128 VkStructureType sType,
129 const void *pCreateInfo,
130 const int struct_size,
131 const char *name_prefix)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500132{
133 MT_OBJ_INFO* pInfo = new MT_OBJ_INFO;
134 memset(pInfo, 0, sizeof(MT_OBJ_INFO));
135 memcpy(&pInfo->create_info, pCreateInfo, struct_size);
136 sprintf(pInfo->object_name, "%s_%p", name_prefix, object);
137
138 pInfo->object = object;
139 pInfo->ref_count = 1;
140 pInfo->sType = sType;
141 objectMap[object] = pInfo;
142
143 return pInfo;
144}
145
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500146// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600147static uint64_t addFenceInfo(
148 VkFence fence,
149 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500150{
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500151 // Create fence object
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500152 MT_FENCE_INFO* pFenceInfo = new MT_FENCE_INFO;
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500153 MT_QUEUE_INFO* pQueueInfo = queueMap[queue];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500154 uint64_t fenceId = g_currentFenceId++;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500155 memset(pFenceInfo, 0, sizeof(MT_FENCE_INFO));
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500156 // If no fence, create an internal fence to track the submissions
157 if (fence == NULL) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600158 VkFenceCreateInfo fci;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600159 fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500160 fci.pNext = NULL;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600161 fci.flags = static_cast<VkFenceCreateFlags>(0);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500162 nextTable.CreateFence(globalDevice, &fci, &pFenceInfo->fence);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600163 addObjectInfo(pFenceInfo->fence, fci.sType, &fci, sizeof(VkFenceCreateInfo), "internalFence");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600164 pFenceInfo->localFence = VK_TRUE;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500165 } else {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500166 // Validate that fence is in UNSIGNALED state
167 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
168 if (pObjectInfo != NULL) {
Tobin Ehlisf29da382015-04-15 07:46:12 -0600169 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500170 char str[1024];
171 sprintf(str, "Fence %p submitted in SIGNALED state. Fences must be reset before being submitted", fence);
Tobin Ehlisf29da382015-04-15 07:46:12 -0600172 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
Mark Lobodzinski56945182015-04-09 13:46:09 -0500173 }
174 }
Tobin Ehlisf29da382015-04-15 07:46:12 -0600175 pFenceInfo->localFence = VK_FALSE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500176 pFenceInfo->fence = fence;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700177 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500178 pFenceInfo->queue = queue;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500179 fenceMap[fenceId] = pFenceInfo;
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500180 // Update most recently submitted fenceId for Queue
181 pQueueInfo->lastSubmittedId = fenceId;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500182 return fenceId;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500183}
184
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500185// Remove a fenceInfo from our list of fences/fenceIds
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600186static void deleteFenceInfo(
187 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500188{
189 if (fenceId != 0) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500190 if (fenceMap.find(fenceId) != fenceMap.end()) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600191 map<uint64_t, MT_FENCE_INFO*>::iterator item;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500192 MT_FENCE_INFO* pDelInfo = fenceMap[fenceId];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500193 if (pDelInfo != NULL) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600194 if (pDelInfo->localFence == VK_TRUE) {
Mike Stroyan230e6252015-04-17 12:36:38 -0600195 nextTable.DestroyObject(globalDevice, VK_OBJECT_TYPE_FENCE, pDelInfo->fence);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500196 }
197 delete pDelInfo;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500198 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600199 item = fenceMap.find(fenceId);
200 fenceMap.erase(item);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500201 }
202 }
203}
204
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500205// Search through list for this fence, deleting all items before it (with lower IDs) and updating lastRetiredId
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600206static void updateFenceTracking(
207 VkFence fence)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500208{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500209 MT_FENCE_INFO *pCurFenceInfo = NULL;
210 uint64_t fenceId = 0;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600211 VkQueue queue = NULL;
212 bool found = false;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500213
David Pinedof5997ab2015-04-27 16:36:17 -0600214 if (fenceMap.size() <= 0)
215 return;
Mike Stroyan62d0bbf2015-04-15 15:37:47 -0600216 for (map<uint64_t, MT_FENCE_INFO*>::iterator ii=fenceMap.begin(); !found && ii!=fenceMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500217 if ((*ii).second != NULL) {
218 if (fence == ((*ii).second)->fence) {
219 queue = ((*ii).second)->queue;
220 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
221 pQueueInfo->lastRetiredId = (*ii).first;
Mike Stroyan62d0bbf2015-04-15 15:37:47 -0600222 found = true;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500223 } else {
224 deleteFenceInfo((*ii).first);
225 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500226 // Update fence state in fenceCreateInfo structure
227 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
228 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500229 pObjectInfo->create_info.fence_create_info.flags =
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600230 static_cast<VkFenceCreateFlags>(
231 pObjectInfo->create_info.fence_create_info.flags | VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500232 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500233 }
234 }
235}
236
237// Utility function that determines if a fenceId has been retired yet
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600238static bool32_t fenceRetired(
239 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500240{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600241 bool32_t result = VK_FALSE;
Courtney Goeltzenleuchter60edc352015-04-15 14:10:51 -0600242 if (fenceMap.find(fenceId) != fenceMap.end()) {
243 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500244 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
Mark Lobodzinski91a1ec52015-04-02 08:52:53 -0500245 if (fenceId <= pQueueInfo->lastRetiredId)
246 {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600247 result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500248 }
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500249 } else { // If not in list, fence has been retired and deleted
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600250 result = VK_TRUE;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500251 }
252 return result;
253}
254
255// Return the fence associated with a fenceId
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600256static VkFence getFenceFromId(
257 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500258{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600259 VkFence fence = NULL;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500260 if (fenceId != 0) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500261 // Search for an item with this fenceId
262 if (fenceMap.find(fenceId) != fenceMap.end()) {
263 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
264 if (pFenceInfo != NULL) {
265 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
266 if (fenceId > pQueueInfo->lastRetiredId) {
267 fence = pFenceInfo->fence;
268 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500269 }
270 }
271 }
272 return fence;
273}
274
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500275// Helper routine that updates the fence list for a specific queue to all-retired
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600276static void retireQueueFences(
277 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500278{
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600279 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
280 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
281 // Set Queue's lastRetired to lastSubmitted, free items in queue's fence list
282 map<uint64_t, MT_FENCE_INFO*>::iterator it = fenceMap.begin();
283 map<uint64_t, MT_FENCE_INFO*>::iterator temp;
David Pinedof5997ab2015-04-27 16:36:17 -0600284 while (fenceMap.size() > 0 && it != fenceMap.end()) {
Tobin Ehlisbfc55032015-04-15 14:25:02 -0600285 if ((((*it).second) != NULL) && ((*it).second)->queue == queue) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600286 temp = it;
287 ++temp;
288 deleteFenceInfo((*it).first);
289 it = temp;
290 } else {
291 ++it;
292 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500293 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700294}
295
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500296// Helper routine that updates fence list for all queues to all-retired
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600297static void retireDeviceFences(
298 VkDevice device)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500299{
300 // Process each queue for device
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600301 // TODO: Add multiple device support
David Pinedof5997ab2015-04-27 16:36:17 -0600302 if (queueMap.size() <= 0)
303 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600304 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500305 retireQueueFences((*ii).first);
306 }
307}
308
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500309// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700310// Calls to this function should be wrapped in mutex
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600311static MT_MEM_OBJ_INFO* getMemObjInfo(
312 const VkDeviceMemory mem)
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700313{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500314 MT_MEM_OBJ_INFO* pMemObjInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500315
316 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500317 pMemObjInfo = memObjMap[mem];
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600318 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500319 return pMemObjInfo;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700320}
321
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600322static void addMemObjInfo(
323 const VkDeviceMemory mem,
324 const VkMemoryAllocInfo *pAllocInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700325{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500326 MT_MEM_OBJ_INFO* pInfo = new MT_MEM_OBJ_INFO;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600327 pInfo->refCount = 0;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600328 memset(&pInfo->allocInfo, 0, sizeof(VkMemoryAllocInfo));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500329
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800330 if (pAllocInfo) { // MEM alloc created by vkCreateSwapChainWSI() doesn't have alloc info struct
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600331 memcpy(&pInfo->allocInfo, pAllocInfo, sizeof(VkMemoryAllocInfo));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500332 // TODO: Update for real hardware, actually process allocation info structures
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500333 pInfo->allocInfo.pNext = NULL;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700334 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500335 pInfo->mem = mem;
336 memObjMap[mem] = pInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700337}
338
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500339// Find CB Info and add mem binding to list container
340// Find Mem Obj Info and add CB binding to list container
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600341static bool32_t updateCBBinding(
342 const VkCmdBuffer cb,
343 const VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700344{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600345 bool32_t result = VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700346 // First update CB binding in MemObj mini CB list
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500347 MT_MEM_OBJ_INFO* pMemInfo = getMemObjInfo(mem);
348 if (!pMemInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700349 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600350 sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that mem obj.\n "
351 "Was it correctly allocated? Did it already get freed?", mem, cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600352 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
353 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600354 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500355 // Search for cmd buffer object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600356 bool32_t found = VK_FALSE;
David Pinedof5997ab2015-04-27 16:36:17 -0600357 if (pMemInfo->pCmdBufferBindings.size() > 0) {
358 for (list<VkCmdBuffer>::iterator it = pMemInfo->pCmdBufferBindings.begin(); it != pMemInfo->pCmdBufferBindings.end(); ++it) {
359 if ((*it) == cb) {
360 found = VK_TRUE;
361 break;
362 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500363 }
364 }
365 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600366 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500367 pMemInfo->pCmdBufferBindings.push_front(cb);
368 pMemInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500369 }
370
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500371 // Now update CBInfo's Mem binding list
372 MT_CB_INFO* pCBInfo = getCBInfo(cb);
373 if (!pCBInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500374 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500375 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 Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600376 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
377 result = VK_FALSE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500378 } else {
379 // Search for memory object in cmd buffer's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600380 bool32_t found = VK_FALSE;
David Pinedof5997ab2015-04-27 16:36:17 -0600381 if (pCBInfo->pMemObjList.size() > 0) {
382 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
383 if ((*it) == mem) {
384 found = VK_TRUE;
385 break;
386 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500387 }
388 }
389 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600390 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500391 pCBInfo->pMemObjList.push_front(mem);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600392 }
393 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700394 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600395 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700396}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600397
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700398// Clear the CB Binding for mem
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700399// Calls to this function should be wrapped in mutex
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600400static void clearCBBinding(
401 const VkCmdBuffer cb,
402 const VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700403{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500404 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500405 // TODO : Having this check is not ideal, really if memInfo was deleted,
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700406 // its CB bindings should be cleared and then freeCBBindings wouldn't call
407 // us here with stale mem objs
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500408 if (pInfo) {
409 pInfo->pCmdBufferBindings.remove(cb);
410 pInfo->refCount--;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700411 }
412}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600413
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700414// Free bindings related to CB
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600415static bool32_t freeCBBindings(
416 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700417{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600418 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500419 MT_CB_INFO* pCBInfo = getCBInfo(cb);
420 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700421 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500422 sprintf(str, "Unable to find global CB info %p for deletion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600423 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
424 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600425 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500426 if (!fenceRetired(pCBInfo->fenceId)) {
427 deleteFenceInfo(pCBInfo->fenceId);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600428 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500429
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600430 if (pCBInfo->pMemObjList.size() > 0) {
431 list<VkDeviceMemory> mem_obj_list = pCBInfo->pMemObjList;
432 for (list<VkDeviceMemory>::iterator it=mem_obj_list.begin(); it!=mem_obj_list.end(); ++it) {
David Pinedof5997ab2015-04-27 16:36:17 -0600433 clearCBBinding(cb, (*it));
434 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600435 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500436 pCBInfo->pMemObjList.clear();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700437 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600438 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700439}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600440
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500441// Delete CBInfo from list along with all of it's mini MemObjInfo
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500442// and also clear mem references to CB
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700443// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600444static bool32_t deleteCBInfo(
445 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700446{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600447 bool32_t result = VK_TRUE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600448 result = freeCBBindings(cb);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500449 // Delete the CBInfo info
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600450 if (result == VK_TRUE) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500451 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500452 MT_CB_INFO* pDelInfo = cbMap[cb];
453 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500454 cbMap.erase(cb);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600455 }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700456 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600457 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700458}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600459
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700460// Delete the entire CB list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600461static bool32_t deleteCBInfoList(
462 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700463{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600464 bool32_t result = VK_TRUE;
David Pinedof5997ab2015-04-27 16:36:17 -0600465 if (cbMap.size() <= 0)
466 return result;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600467 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500468 freeCBBindings((*ii).first);
469 delete (*ii).second;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700470 }
471 return result;
472}
473
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500474// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600475static void reportMemReferencesAndCleanUp(
476 MT_MEM_OBJ_INFO* pMemObjInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700477{
Tony Barboura938abb2015-04-22 11:36:22 -0600478 size_t cmdBufRefCount = pMemObjInfo->pCmdBufferBindings.size();
479 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500480
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500481 if ((pMemObjInfo->pCmdBufferBindings.size() + pMemObjInfo->pObjBindings.size()) != 0) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700482 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600483 sprintf(str, "Attempting to free memory object %p which still contains %lu references",
484 pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500485 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700486 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500487
David Pinedof5997ab2015-04-27 16:36:17 -0600488 if (cmdBufRefCount > 0 && pMemObjInfo->pCmdBufferBindings.size() > 0) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500489 for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
490 char str[1024];
491 sprintf(str, "Command Buffer %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
492 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
493 }
494 // Clear the list of hanging references
495 pMemObjInfo->pCmdBufferBindings.clear();
496 }
497
David Pinedof5997ab2015-04-27 16:36:17 -0600498 if (objRefCount > 0 && pMemObjInfo->pObjBindings.size() > 0) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500499 for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
500 char str[1024];
501 sprintf(str, "VK Object %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
502 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
503 }
504 // Clear the list of hanging references
505 pMemObjInfo->pObjBindings.clear();
506 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500507
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700508}
509
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600510static void deleteMemObjInfo(
511 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700512{
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500513 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500514 MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
515 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500516 memObjMap.erase(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700517 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500518 else {
519 char str[1024];
520 sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
521 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
522 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700523}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500524
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700525// Check if fence for given CB is completed
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600526static bool32_t checkCBCompleted(
527 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700528{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600529 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500530 MT_CB_INFO* pCBInfo = getCBInfo(cb);
531 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700532 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500533 sprintf(str, "Unable to find global CB info %p to check for completion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600534 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
535 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600536 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500537 if (!fenceRetired(pCBInfo->fenceId)) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600538 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600539 sprintf(str, "FenceId %" PRIx64", fence %p for CB %p has not been checked for completion",
540 pCBInfo->fenceId, getFenceFromId(pCBInfo->fenceId), cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600541 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
542 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600543 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700544 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600545 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700546}
547
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600548static bool32_t freeMemObjInfo(
549 VkDeviceMemory mem,
550 bool internal)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700551{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600552 bool32_t result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500553 // Parse global list to find info w/ mem
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500554 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
555 if (!pInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700556 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600557 sprintf(str, "Couldn't find mem info object for %p\n Was %p never allocated or previously freed?",
558 (void*)mem, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600559 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
560 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600561 } else {
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -0600562 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600563 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600564 sprintf(str, "Attempting to free memory associated with a Persistent Image, %p, "
565 "this should not be explicitly freed\n", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600566 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
567 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600568 } else {
569 // Clear any CB bindings for completed CBs
570 // TODO : Is there a better place to do this?
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500571
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600572 list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin();
573 list<VkCmdBuffer>::iterator temp;
David Pinedof5997ab2015-04-27 16:36:17 -0600574 while (pInfo->pCmdBufferBindings.size() > 0 && it != pInfo->pCmdBufferBindings.end()) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600575 if (VK_TRUE == checkCBCompleted(*it)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500576 temp = it;
577 ++temp;
578 freeCBBindings(*it);
579 it = temp;
580 } else {
581 ++it;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600582 }
583 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500584
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600585 // Now verify that no references to this mem obj remain
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500586 if (0 != pInfo->refCount) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500587 reportMemReferencesAndCleanUp(pInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600588 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600589 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600590 // Delete mem obj info
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500591 deleteMemObjInfo(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700592 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700593 }
594 return result;
595}
596
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700597// Remove object binding performs 3 tasks:
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500598// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
599// 2. Decrement refCount for MemObjInfo
600// 3. Clear MemObjInfo ptr from ObjectInfo
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600601static bool32_t clearObjectBinding(
602 VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700603{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600604 bool32_t result = VK_FALSE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500605 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
606 if (!pObjInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700607 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600608 sprintf(str, "Attempting to clear mem binding for object %p: devices, queues, command buffers, "
609 "shaders and memory objects do not have external memory requirements and it is "
610 "unneccessary to call bind/unbindObjectMemory on them.", object);
Mark Lobodzinski23182612015-05-29 09:32:35 -0500611 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600612 } else {
David Pinedof5997ab2015-04-27 16:36:17 -0600613 if (!pObjInfo->pMemObjInfo || pObjInfo->pMemObjInfo->pObjBindings.size() <= 0) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600614 char str[1024];
615 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600616 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600617 } else {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500618 // 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
619 // and set the objects memory binding pointer to NULL.
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600620 for (list<VkObject>::iterator it = pObjInfo->pMemObjInfo->pObjBindings.begin(); it != pObjInfo->pMemObjInfo->pObjBindings.end(); ++it) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500621 if ((*it) == object) {
622 pObjInfo->pMemObjInfo->refCount--;
623 pObjInfo->pMemObjInfo->pObjBindings.erase(it);
624 pObjInfo->pMemObjInfo = NULL;
625 result = VK_TRUE;
626 break;
627 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600628 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600629 if (result == VK_FALSE) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600630 char str[1024];
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500631 sprintf(str, "While trying to clear mem binding for object %p, unable to find that object referenced by mem obj %p",
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500632 object, pObjInfo->pMemObjInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600633 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600634 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700635 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700636 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600637 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700638}
639
640// For NULL mem case, clear any previous binding Else...
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500641// Make sure given object is in global object map
Tobin Ehlis62086412014-11-19 16:19:28 -0700642// IF a previous binding existed, clear it
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500643// Add reference from objectInfo to memoryInfo
644// Add reference off of objInfo
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600645// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600646static bool32_t updateObjectBinding(
647 VkObject object,
648 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700649{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600650 bool32_t result = VK_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700651 // Handle NULL case separately, just clear previous binding & decrement reference
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600652 if (mem == VK_NULL_HANDLE) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700653 clearObjectBinding(object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600654 result = VK_TRUE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600655 } else {
656 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500657 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
658 if (!pObjInfo) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600659 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600660 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
661 return VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600662 }
663 // non-null case so should have real mem obj
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500664 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600665 if (!pInfo) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500666 sprintf(str, "While trying to bind mem for obj %p, couldn't find info for mem obj %p", (void*)object, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600667 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500668 return VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600669 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500670 // Search for object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600671 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600672 if (pInfo->pObjBindings.size() > 0) {
673 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
674 if ((*it) == object) {
675 found = VK_TRUE;
676 break;
677 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600678 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600679 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500680 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600681 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500682 pInfo->pObjBindings.push_front(object);
683 pInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500684 }
685
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500686 if (pObjInfo->pMemObjInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500687 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500688 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pObjInfo->pMemObjInfo->mem, mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600689 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500690 }
691 // For image objects, make sure default memory state is correctly set
692 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600693 if (VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pObjInfo->sType) {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600694 if (pObjInfo->create_info.image_create_info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
695 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500696 // TODO:: More memory state transition stuff.
697 }
698 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500699 pObjInfo->pMemObjInfo = pInfo;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700700 }
701 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600702 return VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700703}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600704
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700705// Print details of global Obj tracking list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600706static void printObjList(
707 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700708{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500709 MT_OBJ_INFO* pInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500710 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500711 sprintf(str, "Details of Object list of size %lu elements", objectMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600712 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600713 if (objectMap.size() <= 0)
714 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600715 for (map<VkObject, MT_OBJ_INFO*>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500716 pInfo = (*ii).second;
717 sprintf(str, " ObjInfo %p has object %p, pMemObjInfo %p", pInfo, pInfo->object, pInfo->pMemObjInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600718 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700719 }
720}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600721
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700722// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600723static VkDeviceMemory getMemBindingFromObject(
724 const VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700725{
Tony Barbour8205d902015-04-16 15:59:00 -0600726 VkDeviceMemory mem = NULL;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500727 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
728 if (pObjInfo) {
729 if (pObjInfo->pMemObjInfo) {
730 mem = pObjInfo->pMemObjInfo->mem;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600731 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700732 char str[1024];
733 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600734 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700735 printObjList();
736 }
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600737 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700738 char str[1024];
739 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600740 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700741 printObjList();
742 }
743 return mem;
744}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500745
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500746// Print details of MemObjInfo list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600747static void printMemList(
748 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700749{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500750 MT_MEM_OBJ_INFO* pInfo = NULL;
Tobin Ehlis62086412014-11-19 16:19:28 -0700751 // Just printing each msg individually for now, may want to package these into single large print
752 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500753 sprintf(str, "MEM INFO : Details of Memory Object list of size %lu elements", memObjMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600754 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500755
David Pinedof5997ab2015-04-27 16:36:17 -0600756 if (memObjMap.size() <= 0)
757 return;
758
Tony Barbour8205d902015-04-16 15:59:00 -0600759 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500760 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500761
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500762 sprintf(str, " ===MemObjInfo at %p===", (void*)pInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600763 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500764 sprintf(str, " Mem object: %p", (void*)pInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600765 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500766 sprintf(str, " Ref Count: %u", pInfo->refCount);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600767 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500768 if (0 != pInfo->allocInfo.allocationSize) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600769 string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "{MEM}INFO : ");
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500770 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600771 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500772 } else {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800773 sprintf(str, " Mem Alloc info is NULL (alloc done by vkCreateSwapChainWSI())");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600774 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500775 }
776
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600777 sprintf(str, " VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
778 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600779 if (pInfo->pObjBindings.size() > 0) {
780 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
781 sprintf(str, " VK OBJECT %p", (*it));
782 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
783 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500784 }
785
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600786 sprintf(str, " VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
787 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600788 if (pInfo->pCmdBufferBindings.size() > 0)
789 {
790 for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
791 sprintf(str, " VK CB %p", (*it));
792 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
793 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700794 }
795 }
796}
797
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600798static void printCBList(
799 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700800{
Tobin Ehlis62086412014-11-19 16:19:28 -0700801 char str[1024] = {0};
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500802 MT_CB_INFO* pCBInfo = NULL;
803 sprintf(str, "Details of CB list of size %lu elements", cbMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600804 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500805
David Pinedof5997ab2015-04-27 16:36:17 -0600806 if (cbMap.size() <= 0)
807 return;
808
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600809 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500810 pCBInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500811
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500812 sprintf(str, " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %p",
813 (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
814 (void*)getFenceFromId(pCBInfo->fenceId));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600815 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500816
David Pinedof5997ab2015-04-27 16:36:17 -0600817 if (pCBInfo->pMemObjList.size() <= 0)
818 continue;
Tony Barbour8205d902015-04-16 15:59:00 -0600819 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500820 sprintf(str, " Mem obj %p", (*it));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600821 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700822 }
823 }
824}
825
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600826static void initMemTracker(
827 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700828{
Jon Ashburnf57ea372014-12-22 13:24:15 -0700829 const char *strOpt;
830 // initialize MemTracker options
Ian Elliott7d0b5d22015-03-06 13:50:05 -0700831 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
832 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -0700833
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600834 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburnf57ea372014-12-22 13:24:15 -0700835 {
836 strOpt = getLayerOption("MemTrackerLogFilename");
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600837 if (strOpt) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700838 g_logFile = fopen(strOpt, "w");
Jon Ashburnf57ea372014-12-22 13:24:15 -0700839 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600840 if (g_logFile == NULL) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700841 g_logFile = stdout;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600842 }
Jon Ashburnf57ea372014-12-22 13:24:15 -0700843 }
844
845 // initialize Layer dispatch table
846 // TODO handle multiple GPUs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600847 PFN_vkGetProcAddr fpNextGPA;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700848 fpNextGPA = pCurObj->pGPA;
849 assert(fpNextGPA);
850
Tony Barbour8205d902015-04-16 15:59:00 -0600851 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800852
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600853 if (!globalLockInitialized)
854 {
855 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600856 // suggestion is to call this during vkCreateInstance(), and then we
857 // can clean it up during vkDestroyInstance(). However, that requires
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600858 // that the layer have per-instance locks. We need to come back and
859 // address this soon.
860 loader_platform_thread_create_mutex(&globalLock);
861 globalLockInitialized = 1;
862 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700863}
864
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600865VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
866 VkPhysicalDevice gpu,
867 const VkDeviceCreateInfo *pCreateInfo,
868 VkDevice *pDevice)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700869{
Jon Ashburn630e44f2015-04-08 21:33:34 -0600870 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700871 loader_platform_thread_once(&g_initOnce, initMemTracker);
Jon Ashburn630e44f2015-04-08 21:33:34 -0600872 VkResult result = nextTable.CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700873 // Save off device in case we need it to create Fences
874 globalDevice = *pDevice;
875 return result;
876}
877
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600878VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(
879 VkDevice device)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700880{
Tobin Ehlis62086412014-11-19 16:19:28 -0700881 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600882 sprintf(str, "Printing List details prior to vkDestroyDevice()");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600883 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600884 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700885 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500886 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700887 printObjList();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600888 if (VK_FALSE == deleteCBInfoList()) {
889 sprintf(str, "Issue deleting global CB list in vkDestroyDevice()");
890 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -0700891 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700892 // Report any memory leaks
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500893 MT_MEM_OBJ_INFO* pInfo = NULL;
David Pinedof5997ab2015-04-27 16:36:17 -0600894 if (memObjMap.size() > 0) {
895 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
896 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500897
David Pinedof5997ab2015-04-27 16:36:17 -0600898 if (pInfo->allocInfo.allocationSize != 0) {
899 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling "
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600900 "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
David Pinedof5997ab2015-04-27 16:36:17 -0600901 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
902 }
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600903 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700904 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500905
906 // Queues persist until device is destroyed
907 deleteQueueInfoList();
908
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600909 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600910 VkResult result = nextTable.DestroyDevice(device);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700911 return result;
912}
913
Jon Ashburneb2728b2015-04-10 14:33:07 -0600914struct extProps {
915 uint32_t version;
916 const char * const name;
917};
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600918#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2
Jon Ashburneb2728b2015-04-10 14:33:07 -0600919static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
920 // TODO what is the version?
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600921 0x10, "MemTracker",
922 0x10, "Validation"
Jon Ashburneb2728b2015-04-10 14:33:07 -0600923};
924
925VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600926 VkExtensionInfoType infoType,
927 uint32_t extensionIndex,
928 size_t *pDataSize,
929 void *pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600930{
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500931 // This entrypoint is NOT going to init its own dispatch table since loader calls here early
Jon Ashburneb2728b2015-04-10 14:33:07 -0600932 VkExtensionProperties *ext_props;
933 uint32_t *count;
934
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600935 if (pDataSize == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600936 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600937 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600938
939 switch (infoType) {
940 case VK_EXTENSION_INFO_TYPE_COUNT:
941 *pDataSize = sizeof(uint32_t);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600942 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600943 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600944 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600945 count = (uint32_t *) pData;
946 *count = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE;
947 break;
948 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
949 *pDataSize = sizeof(VkExtensionProperties);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600950 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600951 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600952 }
953 if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600954 return VK_ERROR_INVALID_VALUE;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600955 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600956 ext_props = (VkExtensionProperties *) pData;
957 ext_props->version = mtExts[extensionIndex].version;
958 strncpy(ext_props->extName, mtExts[extensionIndex].name,
959 VK_MAX_EXTENSION_NAME);
960 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
961 break;
962 default:
963 return VK_ERROR_INVALID_VALUE;
964 };
965
966 return VK_SUCCESS;
967}
968
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600969VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(
970 VkPhysicalDevice gpu,
971 size_t maxStringSize,
972 size_t *pLayerCount,
973 char* const *pOutLayers,
974 void *pReserved)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700975{
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600976 if (gpu != NULL)
Jon Ashburn451c16f2014-11-25 11:08:42 -0700977 {
Jon Ashburn630e44f2015-04-08 21:33:34 -0600978 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700979 loader_platform_thread_once(&g_initOnce, initMemTracker);
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600980 VkResult result = nextTable.EnumerateLayers(gpu,
981 maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn451c16f2014-11-25 11:08:42 -0700982 return result;
983 } else
984 {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600985 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600986 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600987 }
Jon Ashburn451c16f2014-11-25 11:08:42 -0700988 // This layer compatible with all GPUs
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600989 *pLayerCount = 1;
Chia-I Wua837c522014-12-16 10:47:33 +0800990 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600991 return VK_SUCCESS;
Jon Ashburn451c16f2014-11-25 11:08:42 -0700992 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700993}
994
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600995VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
996 VkDevice device,
997 uint32_t queueNodeIndex,
998 uint32_t queueIndex,
999 VkQueue *pQueue)
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001000{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001001 VkResult result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001002 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001003 loader_platform_thread_lock_mutex(&globalLock);
1004 addQueueInfo(*pQueue);
1005 loader_platform_thread_unlock_mutex(&globalLock);
1006 }
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001007 return result;
1008}
1009
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001010VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(
1011 VkQueue queue,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001012 uint32_t cmdBufferCount,
1013 const VkCmdBuffer *pCmdBuffers,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001014 VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001015{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001016 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001017 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001018 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001019 uint64_t fenceId = addFenceInfo(fence, queue);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001020
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001021 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001022 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001023 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001024 pCBInfo = getCBInfo(pCmdBuffers[i]);
1025 pCBInfo->fenceId = fenceId;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001026 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001027
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001028 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001029 VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, getFenceFromId(fenceId));
Courtney Goeltzenleuchtercfedf362015-04-02 13:39:07 -06001030 return result;
1031}
1032
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001033VK_LAYER_EXPORT VkResult VKAPI vkAllocMemory(
1034 VkDevice device,
1035 const VkMemoryAllocInfo *pAllocInfo,
1036 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001037{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001038 VkResult result = nextTable.AllocMemory(device, pAllocInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001039 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001040 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001041 addMemObjInfo(*pMem, pAllocInfo);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001042 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001043 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001044 return result;
1045}
1046
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001047VK_LAYER_EXPORT VkResult VKAPI vkFreeMemory(
1048 VkDevice device,
1049 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001050{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001051 /* From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed. Before
Tobin Ehlisa747e682014-11-25 14:47:20 -07001052 * freeing a memory object, an application must ensure the memory object is unbound from
1053 * all API objects referencing it and that it is not referenced by any queued command buffers
1054 */
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001055 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001056 bool32_t noerror = freeMemObjInfo(mem, false);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001057 printMemList();
1058 printObjList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001059 printCBList();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001060 // Output an warning message for proper error/warning handling
1061 if (noerror == VK_FALSE) {
1062 char str[1024];
1063 sprintf(str, "Freeing memory object while it still has references: mem obj %p", (void*)mem);
1064 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
1065 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001066 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001067 VkResult result = nextTable.FreeMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001068 return result;
1069}
1070
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001071VK_LAYER_EXPORT VkResult VKAPI vkSetMemoryPriority(
1072 VkDevice device,
1073 VkDeviceMemory mem,
1074 VkMemoryPriority priority)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001075{
1076 // TODO : Update tracking for this alloc
1077 // Make sure memory is not pinned, which can't have priority set
Mike Stroyan230e6252015-04-17 12:36:38 -06001078 VkResult result = nextTable.SetMemoryPriority(device, mem, priority);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001079 return result;
1080}
1081
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001082VK_LAYER_EXPORT VkResult VKAPI vkMapMemory(
1083 VkDevice device,
1084 VkDeviceMemory mem,
1085 VkDeviceSize offset,
1086 VkDeviceSize size,
1087 VkFlags flags,
1088 void **ppData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001089{
1090 // TODO : Track when memory is mapped
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001091 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001092 MT_MEM_OBJ_INFO *pMemObj = getMemObjInfo(mem);
Tony Barbour8205d902015-04-16 15:59:00 -06001093 if ((pMemObj->allocInfo.memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001094 char str[1024];
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001095 sprintf(str, "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj %p", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001096 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001097 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001098 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001099 VkResult result = nextTable.MapMemory(device, mem, offset, size, flags, ppData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001100 return result;
1101}
1102
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001103VK_LAYER_EXPORT VkResult VKAPI vkUnmapMemory(
1104 VkDevice device,
1105 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001106{
1107 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
1108 // Make sure that memory was ever mapped to begin with
Mike Stroyan230e6252015-04-17 12:36:38 -06001109 VkResult result = nextTable.UnmapMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001110 return result;
1111}
1112
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001113VK_LAYER_EXPORT VkResult VKAPI vkPinSystemMemory(
1114 VkDevice device,
1115 const void *pSysMem,
1116 size_t memSize,
1117 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001118{
1119 // TODO : Track this
1120 // Verify that memory is actually pinnable
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001121 VkResult result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001122 return result;
1123}
1124
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001125VK_LAYER_EXPORT VkResult VKAPI vkOpenSharedMemory(
1126 VkDevice device,
1127 const VkMemoryOpenInfo *pOpenInfo,
1128 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001129{
1130 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001131 VkResult result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001132 return result;
1133}
1134
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001135VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerMemory(
1136 VkDevice device,
1137 const VkPeerMemoryOpenInfo *pOpenInfo,
1138 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001139{
1140 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001141 VkResult result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001142 return result;
1143}
1144
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001145VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerImage(
1146 VkDevice device,
1147 const VkPeerImageOpenInfo *pOpenInfo,
1148 VkImage *pImage,
1149 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001150{
1151 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001152 VkResult result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001153 return result;
1154}
1155
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001156VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(
1157 VkDevice device,
1158 VkObjectType objType,
1159 VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001160{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001161 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001162
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001163 // First check if this is a CmdBuffer
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001164 if (NULL != getCBInfo((VkCmdBuffer)object)) {
1165 deleteCBInfo((VkCmdBuffer)object);
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001166 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001167
1168 if (objectMap.find(object) != objectMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001169 MT_OBJ_INFO* pDelInfo = objectMap[object];
1170 if (pDelInfo->pMemObjInfo) {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001171 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001172 if (0 == pDelInfo->pMemObjInfo->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
Tony Barbour8205d902015-04-16 15:59:00 -06001173 VkDeviceMemory memToFree = pDelInfo->pMemObjInfo->mem;
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001174 clearObjectBinding(object);
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -06001175 freeMemObjInfo(memToFree, true);
1176 }
1177 else {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001178 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001179 sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding "
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001180 "by calling vkBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)",
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001181 object, (void*)pDelInfo->pMemObjInfo->mem, object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001182 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001183 // From the spec : If an object has previous memory binding, it is required to unbind memory
1184 // from an API object before it is destroyed.
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001185 clearObjectBinding(object);
1186 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001187 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001188 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001189 objectMap.erase(object);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001190 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001191
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001192 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001193 VkResult result = nextTable.DestroyObject(device, objType, object);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001194 return result;
1195}
1196
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001197VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo(
1198 VkDevice device,
1199 VkObjectType objType,
1200 VkObject object,
1201 VkObjectInfoType infoType,
1202 size_t *pDataSize,
1203 void *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001204{
1205 // TODO : What to track here?
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001206 // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001207 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues,
1208 // command buffers, shaders and memory objects.
Mike Stroyan230e6252015-04-17 12:36:38 -06001209 VkResult result = nextTable.GetObjectInfo(device, objType, object, infoType, pDataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001210 return result;
1211}
1212
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001213VK_LAYER_EXPORT VkResult VKAPI vkBindObjectMemory(
1214 VkDevice device,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001215 VkObjectType objType,
1216 VkObject object,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001217 VkDeviceMemory mem,
1218 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001219{
Mark Lobodzinski23182612015-05-29 09:32:35 -05001220 VkResult result = nextTable.BindObjectMemory(device, objType, object, mem, offset);
Mike Stroyan230e6252015-04-17 12:36:38 -06001221 loader_platform_thread_lock_mutex(&globalLock);
1222 // Track objects tied to memory
1223 if (VK_FALSE == updateObjectBinding(object, mem)) {
1224 char str[1024];
1225 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1226 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1227 }
1228 printObjList();
1229 printMemList();
1230 loader_platform_thread_unlock_mutex(&globalLock);
1231 return result;
1232}
1233
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001234VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001235 VkQueue queue,
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001236 VkBuffer buffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001237 VkDeviceSize rangeOffset,
1238 VkDeviceSize rangeSize,
1239 VkDeviceMemory mem,
1240 VkDeviceSize memOffset)
Mike Stroyan230e6252015-04-17 12:36:38 -06001241{
Mark Lobodzinski23182612015-05-29 09:32:35 -05001242 VkResult result = nextTable.QueueBindSparseBufferMemory(queue, buffer, rangeOffset, rangeSize, mem, memOffset);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001243 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001244 // Track objects tied to memory
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001245 if (VK_FALSE == updateObjectBinding(buffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001246 char str[1024];
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001247 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)buffer, (void*)mem);
1248 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, buffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001249 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001250 printObjList();
1251 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001252 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001253 return result;
1254}
1255
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001256VK_LAYER_EXPORT VkResult VKAPI vkCreateFence(
1257 VkDevice device,
1258 const VkFenceCreateInfo *pCreateInfo,
1259 VkFence *pFence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001260{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001261 VkResult result = nextTable.CreateFence(device, pCreateInfo, pFence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001262 if (VK_SUCCESS == result) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001263 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001264 addObjectInfo(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(VkFenceCreateInfo), "fence");
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001265 loader_platform_thread_unlock_mutex(&globalLock);
1266 }
1267 return result;
1268}
1269
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001270VK_LAYER_EXPORT VkResult VKAPI vkResetFences(
1271 VkDevice device,
1272 uint32_t fenceCount,
1273 VkFence *pFences)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001274{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001275 VkResult result = nextTable.ResetFences(device, fenceCount, pFences);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001276 if (VK_SUCCESS == result) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001277 loader_platform_thread_lock_mutex(&globalLock);
1278 // Reset fence state in fenceCreateInfo structure
1279 for (uint32_t i = 0; i < fenceCount; i++) {
1280 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1281 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001282 // Validate fences in SIGNALED state
Tobin Ehlisf29da382015-04-15 07:46:12 -06001283 if (!(pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001284 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001285 sprintf(str, "Fence %p submitted to VkResetFences in UNSIGNALED STATE", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001286 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
1287 result = VK_ERROR_INVALID_VALUE;
Mark Lobodzinski56945182015-04-09 13:46:09 -05001288 }
1289 else {
1290 pObjectInfo->create_info.fence_create_info.flags =
Tobin Ehlisf29da382015-04-15 07:46:12 -06001291 static_cast<VkFenceCreateFlags>(pObjectInfo->create_info.fence_create_info.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski56945182015-04-09 13:46:09 -05001292 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001293 }
1294 }
1295 loader_platform_thread_unlock_mutex(&globalLock);
1296 }
1297 return result;
1298}
1299
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001300VK_LAYER_EXPORT VkResult VKAPI vkGetFenceStatus(
1301 VkDevice device,
1302 VkFence fence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001303{
Mike Stroyan230e6252015-04-17 12:36:38 -06001304 VkResult result = nextTable.GetFenceStatus(device, fence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001305 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001306 loader_platform_thread_lock_mutex(&globalLock);
1307 updateFenceTracking(fence);
1308 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001309 }
1310 return result;
1311}
1312
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001313VK_LAYER_EXPORT VkResult VKAPI vkWaitForFences(
1314 VkDevice device,
1315 uint32_t fenceCount,
1316 const VkFence *pFences,
1317 bool32_t waitAll,
1318 uint64_t timeout)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001319{
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001320 // Verify fence status of submitted fences
1321 for(uint32_t i = 0; i < fenceCount; i++) {
1322 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1323 if (pObjectInfo != NULL) {
Tobin Ehlisf29da382015-04-15 07:46:12 -06001324 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001325 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001326 sprintf(str, "VkWaitForFences specified fence %p already in SIGNALED state.", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001327 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001328 }
1329 }
1330 }
1331
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001332 VkResult result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001333 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001334
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001335 if (VK_SUCCESS == result) {
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001336 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001337 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001338 updateFenceTracking(pFences[i]);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001339 }
1340 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001341 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001342 loader_platform_thread_unlock_mutex(&globalLock);
1343 return result;
1344}
1345
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001346VK_LAYER_EXPORT VkResult VKAPI vkQueueWaitIdle(
1347 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001348{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001349 VkResult result = nextTable.QueueWaitIdle(queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001350 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001351 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001352 retireQueueFences(queue);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001353 loader_platform_thread_unlock_mutex(&globalLock);
1354 }
1355 return result;
1356}
1357
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001358VK_LAYER_EXPORT VkResult VKAPI vkDeviceWaitIdle(
1359 VkDevice device)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001360{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001361 VkResult result = nextTable.DeviceWaitIdle(device);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001362 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001363 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001364 retireDeviceFences(device);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001365 loader_platform_thread_unlock_mutex(&globalLock);
1366 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001367 return result;
1368}
1369
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001370VK_LAYER_EXPORT VkResult VKAPI vkCreateEvent(
1371 VkDevice device,
1372 const VkEventCreateInfo *pCreateInfo,
1373 VkEvent *pEvent)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001374{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001375 VkResult result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001376 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001377 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001378 addObjectInfo(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(VkEventCreateInfo), "event");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001379 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001380 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001381 return result;
1382}
1383
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001384VK_LAYER_EXPORT VkResult VKAPI vkCreateQueryPool(
1385 VkDevice device,
1386 const VkQueryPoolCreateInfo *pCreateInfo,
1387 VkQueryPool *pQueryPool)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001388{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001389 VkResult result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001390 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001391 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001392 addObjectInfo(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(VkQueryPoolCreateInfo), "query_pool");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001393 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001394 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001395 return result;
1396}
1397
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001398VK_LAYER_EXPORT VkResult VKAPI vkCreateBuffer(
1399 VkDevice device,
1400 const VkBufferCreateInfo *pCreateInfo,
1401 VkBuffer *pBuffer)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001402{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001403 VkResult result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001404 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001405 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001406 addObjectInfo(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferCreateInfo), "buffer");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001407 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001408 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001409 return result;
1410}
1411
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001412VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(
1413 VkDevice device,
1414 const VkBufferViewCreateInfo *pCreateInfo,
1415 VkBufferView *pView)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001416{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001417 VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001418 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001419 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001420 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferViewCreateInfo), "buffer_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001421 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001422 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001423 return result;
1424}
1425
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001426VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(
1427 VkDevice device,
1428 const VkImageCreateInfo *pCreateInfo,
1429 VkImage *pImage)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001430{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001431 VkResult result = nextTable.CreateImage(device, pCreateInfo, pImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001432 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001433 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001434 addObjectInfo(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(VkImageCreateInfo), "image");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001435 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001436 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001437 return result;
1438}
1439
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001440VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(
1441 VkDevice device,
1442 const VkImageViewCreateInfo *pCreateInfo,
1443 VkImageView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001444{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001445 VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001446 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001447 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001448 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkImageViewCreateInfo), "image_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001449 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001450 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001451 return result;
1452}
1453
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001454VK_LAYER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(
1455 VkDevice device,
1456 const VkColorAttachmentViewCreateInfo *pCreateInfo,
1457 VkColorAttachmentView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001458{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001459 VkResult result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001460 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001461 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001462 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkColorAttachmentViewCreateInfo), "color_attachment_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001463 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001464 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001465 return result;
1466}
1467
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001468VK_LAYER_EXPORT VkResult VKAPI vkCreateDepthStencilView(
1469 VkDevice device,
1470 const VkDepthStencilViewCreateInfo *pCreateInfo,
1471 VkDepthStencilView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001472{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001473 VkResult result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001474 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001475 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001476 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkDepthStencilViewCreateInfo), "ds_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001477 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001478 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001479 return result;
1480}
1481
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001482VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(
1483 VkDevice device,
1484 const VkShaderCreateInfo *pCreateInfo,
1485 VkShader *pShader)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001486{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001487 VkResult result = nextTable.CreateShader(device, pCreateInfo, pShader);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001488 return result;
1489}
1490
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001491VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(
1492 VkDevice device,
1493 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1494 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001495{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001496 VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001497 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001498 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001499 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001500 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001501 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001502 return result;
1503}
1504
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001505VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001506 VkDevice device,
1507 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1508 VkPipeline basePipeline,
1509 VkPipeline *pPipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001510{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001511 VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001512 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001513 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001514 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001515 loader_platform_thread_unlock_mutex(&globalLock);
1516 }
1517 return result;
1518}
1519
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001520VK_LAYER_EXPORT VkResult VKAPI vkCreateComputePipeline(
1521 VkDevice device,
1522 const VkComputePipelineCreateInfo *pCreateInfo,
1523 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001524{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001525 VkResult result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001526 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001527 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001528 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkComputePipelineCreateInfo), "compute_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001529 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001530 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001531 return result;
1532}
1533
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001534VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(
1535 VkDevice device,
1536 const VkSamplerCreateInfo *pCreateInfo,
1537 VkSampler *pSampler)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001538{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001539 VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001540 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001541 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001542 addObjectInfo(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(VkSamplerCreateInfo), "sampler");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001543 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001544 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001545 return result;
1546}
1547
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001548VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(
1549 VkDevice device,
1550 const VkDynamicVpStateCreateInfo *pCreateInfo,
1551 VkDynamicVpState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001552{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001553 VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001554 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001555 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001556 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo), "viewport_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001557 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001558 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001559 return result;
1560}
1561
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001562VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(
1563 VkDevice device,
1564 const VkDynamicRsStateCreateInfo *pCreateInfo,
1565 VkDynamicRsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001566{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001567 VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001568 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001569 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001570 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo), "raster_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001571 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001572 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001573 return result;
1574}
1575
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001576VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(
1577 VkDevice device,
1578 const VkDynamicCbStateCreateInfo *pCreateInfo,
1579 VkDynamicCbState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001580{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001581 VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001582 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001583 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001584 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo), "cb_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001585 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001586 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001587 return result;
1588}
1589
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001590VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(
1591 VkDevice device,
1592 const VkDynamicDsStateCreateInfo *pCreateInfo,
1593 VkDynamicDsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001594{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001595 VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001596 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001597 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001598 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo), "ds_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001599 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001600 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001601 return result;
1602}
1603
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001604VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(
1605 VkDevice device,
1606 const VkCmdBufferCreateInfo *pCreateInfo,
1607 VkCmdBuffer *pCmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001608{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001609 VkResult result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001610 // At time of cmd buffer creation, create global cmd buffer info for the returned cmd buffer
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001611 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001612 if (*pCmdBuffer)
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001613 addCBInfo(*pCmdBuffer);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001614 printCBList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001615 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001616 return result;
1617}
1618
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001619VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(
1620 VkCmdBuffer cmdBuffer,
1621 const VkCmdBufferBeginInfo *pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001622{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001623 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001624 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1625 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001626 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001627 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001628 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001629 sprintf(str, "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
1630 "You must check CB flag before this call.", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001631 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001632 }
1633 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001634 VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001635 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001636 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001637 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001638 return result;
1639}
1640
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001641VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(
1642 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001643{
1644 // TODO : Anything to do here?
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001645 VkResult result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001646 return result;
1647}
1648
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001649VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(
1650 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001651{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001652 // Verify that CB is complete (not in-flight)
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001653 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1654 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001655 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001656 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001657 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001658 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before "
1659 "calling vkResetCommandBuffer().", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001660 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", str);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001661 }
1662 }
1663 // Clear memory references as this point.
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001664 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001665 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001666 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001667 VkResult result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001668 return result;
1669}
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001670// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001671// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001672VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(
1673 VkCmdBuffer cmdBuffer,
1674 VkPipelineBindPoint pipelineBindPoint,
1675 VkPipeline pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001676{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001677#if 0
1678 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1679 if (getPipeline(pipeline)) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001680 MT_CB_INFO *pCBInfo = getCBInfo(cmdBuffer);
1681 if (pCBInfo) {
1682 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001683 } else {
1684 char str[1024];
1685 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001686 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001687 }
1688 }
1689 else {
1690 char str[1024];
1691 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001692 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001693 }
1694#endif
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001695 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1696}
1697
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001698VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(
1699 VkCmdBuffer cmdBuffer,
1700 VkStateBindPoint stateBindPoint,
1701 VkDynamicStateObject state)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001702{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001703 MT_OBJ_INFO *pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001704 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001705 MT_CB_INFO *pCmdBuf = getCBInfo(cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001706 if (!pCmdBuf) {
1707 char str[1024];
1708 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001709 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001710 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001711 pObjInfo = getObjectInfo(state);
1712 if (!pObjInfo) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001713 char str[1024];
1714 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001715 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001716 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001717 pCmdBuf->pDynamicState[stateBindPoint] = pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001718 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001719 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001720}
1721
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001722VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001723 VkCmdBuffer cmdBuffer,
1724 VkPipelineBindPoint pipelineBindPoint,
1725 uint32_t firstSet,
1726 uint32_t setCount,
1727 const VkDescriptorSet *pDescriptorSets,
1728 uint32_t dynamicOffsetCount,
1729 const uint32_t *pDynamicOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001730{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001731 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Cody Northrop1a01b1d2015-04-16 13:41:56 -06001732 nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001733}
1734
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001735VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001736 VkCmdBuffer cmdBuffer,
1737 uint32_t startBinding,
1738 uint32_t bindingCount,
1739 const VkBuffer *pBuffers,
1740 const VkDeviceSize *pOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001741{
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001742 nextTable.CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001743}
1744
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001745VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(
1746 VkCmdBuffer cmdBuffer,
1747 VkBuffer buffer,
1748 VkDeviceSize offset,
1749 VkIndexType indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001750{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001751 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001752}
1753
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001754VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(
1755 VkCmdBuffer cmdBuffer,
1756 VkBuffer buffer,
1757 VkDeviceSize offset,
1758 uint32_t count,
1759 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001760{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001761 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001762 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001763 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001764 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001765 sprintf(str, "In vkCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1766 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001767 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001768 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001769 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001770}
1771
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001772VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(
1773 VkCmdBuffer cmdBuffer,
1774 VkBuffer buffer,
1775 VkDeviceSize offset,
1776 uint32_t count,
1777 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001778{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001779 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001780 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001781 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001782 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001783 sprintf(str, "In vkCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1784 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001785 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001786 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001787 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001788}
1789
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001790VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(
1791 VkCmdBuffer cmdBuffer,
1792 VkBuffer buffer,
1793 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001794{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001795 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001796 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001797 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001798 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001799 sprintf(str, "In vkCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1800 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001801 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001802 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001803 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001804}
1805
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001806VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(
1807 VkCmdBuffer cmdBuffer,
1808 VkBuffer srcBuffer,
1809 VkBuffer destBuffer,
1810 uint32_t regionCount,
1811 const VkBufferCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001812{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001813 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001814 VkDeviceMemory mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001815 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001816 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001817 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1818 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001819 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001820 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001821 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001822 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001823 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1824 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001825 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001826 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001827 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001828}
1829
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001830VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
1831 VkCmdBuffer cmdBuffer,
1832 VkImage srcImage,
1833 VkImageLayout srcImageLayout,
1834 VkImage destImage,
1835 VkImageLayout destImageLayout,
1836 uint32_t regionCount,
1837 const VkImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001838{
1839 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001840 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001841}
1842
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001843VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
1844 VkCmdBuffer cmdBuffer,
1845 VkImage srcImage,
1846 VkImageLayout srcImageLayout,
1847 VkImage destImage,
1848 VkImageLayout destImageLayout,
1849 uint32_t regionCount,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05001850 const VkImageBlit *pRegions,
1851 VkTexFilter filter)
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001852{
1853 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski20f68592015-05-22 14:43:25 -05001854 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001855}
1856
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001857VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
1858 VkCmdBuffer cmdBuffer,
1859 VkBuffer srcBuffer,
1860 VkImage destImage,
1861 VkImageLayout destImageLayout,
1862 uint32_t regionCount,
1863 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001864{
1865 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001866 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001867 VkDeviceMemory mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001868 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001869 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001870 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
1871 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001872 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001873
1874 mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001875 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001876 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001877 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1878 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001879 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001880 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001881 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001882}
1883
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001884VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
1885 VkCmdBuffer cmdBuffer,
1886 VkImage srcImage,
1887 VkImageLayout srcImageLayout,
1888 VkBuffer destBuffer,
1889 uint32_t regionCount,
1890 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001891{
1892 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001893 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001894 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001895 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001896 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001897 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
1898 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001899 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001900 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001901 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001902 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001903 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1904 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001905 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001906 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001907 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001908}
1909
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001910VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
1911 VkCmdBuffer cmdBuffer,
1912 VkBuffer destBuffer,
1913 VkDeviceSize destOffset,
1914 VkDeviceSize dataSize,
1915 const uint32_t *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001916{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001917 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001918 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001919 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001920 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001921 sprintf(str, "In vkCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1922 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001923 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001924 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001925 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001926}
1927
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001928VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
1929 VkCmdBuffer cmdBuffer,
1930 VkBuffer destBuffer,
1931 VkDeviceSize destOffset,
1932 VkDeviceSize fillSize,
1933 uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001934{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001935 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001936 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001937 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001938 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001939 sprintf(str, "In vkCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1940 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001941 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001942 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001943 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001944}
1945
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001946VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
1947 VkCmdBuffer cmdBuffer,
1948 VkImage image,
1949 VkImageLayout imageLayout,
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06001950 const VkClearColor *pColor,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001951 uint32_t rangeCount,
1952 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001953{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001954 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001955 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001956 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001957 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001958 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001959 sprintf(str, "In vkCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
1960 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001961 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001962 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06001963 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001964}
1965
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001966VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(
1967 VkCmdBuffer cmdBuffer,
1968 VkImage image,
1969 VkImageLayout imageLayout,
1970 float depth,
1971 uint32_t stencil,
1972 uint32_t rangeCount,
1973 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001974{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001975 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001976 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001977 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001978 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001979 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001980 sprintf(str, "In vkCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
1981 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001982 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001983 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001984 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001985}
1986
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001987VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
1988 VkCmdBuffer cmdBuffer,
1989 VkImage srcImage,
1990 VkImageLayout srcImageLayout,
1991 VkImage destImage,
1992 VkImageLayout destImageLayout,
1993 uint32_t regionCount,
1994 const VkImageResolve *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001995{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001996 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001997 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001998 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001999 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002000 sprintf(str, "In vkCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2001 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002002 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002003 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002004 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002005 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002006 sprintf(str, "In vkCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2007 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002008 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002009 loader_platform_thread_unlock_mutex(&globalLock);
Tony Barbour11f74372015-04-13 15:02:52 -06002010 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002011}
2012
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002013VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(
2014 VkCmdBuffer cmdBuffer,
2015 VkQueryPool queryPool,
2016 uint32_t slot,
2017 VkFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002018{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002019 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002020 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002021 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002022 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002023 sprintf(str, "In vkCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2024 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002025 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002026 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002027 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2028}
2029
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002030VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(
2031 VkCmdBuffer cmdBuffer,
2032 VkQueryPool queryPool,
2033 uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002034{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002035 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002036 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002037 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002038 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002039 sprintf(str, "In vkCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2040 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002041 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002042 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002043 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2044}
2045
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002046VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(
2047 VkCmdBuffer cmdBuffer,
2048 VkQueryPool queryPool,
2049 uint32_t startQuery,
2050 uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002051{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002052 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002053 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002054 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002055 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002056 sprintf(str, "In vkCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2057 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002058 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002059 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002060 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2061}
2062
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002063VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
2064 VkInstance instance,
2065 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
2066 void *pUserData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002067{
Tobin Ehlis62086412014-11-19 16:19:28 -07002068 // This layer intercepts callbacks
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002069 VK_LAYER_DBG_FUNCTION_NODE *pNewDbgFuncNode = (VK_LAYER_DBG_FUNCTION_NODE*)malloc(sizeof(VK_LAYER_DBG_FUNCTION_NODE));
Tobin Ehlis62086412014-11-19 16:19:28 -07002070 if (!pNewDbgFuncNode)
Tony Barbour8205d902015-04-16 15:59:00 -06002071 return VK_ERROR_OUT_OF_HOST_MEMORY;
Tobin Ehlis62086412014-11-19 16:19:28 -07002072 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2073 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburnf57ea372014-12-22 13:24:15 -07002074 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2075 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburne4722392015-03-03 15:07:15 -07002076 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002077 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002078 g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002079 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002080 VkResult result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002081 return result;
2082}
2083
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002084VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
2085 VkInstance instance,
2086 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002087{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002088 VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
2089 VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002090 while (pInfo) {
2091 if (pInfo->pfnMsgCallback == pfnMsgCallback) {
2092 pPrev->pNext = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002093 if (g_pDbgFunctionHead == pInfo) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002094 g_pDbgFunctionHead = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002095 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002096 free(pInfo);
Tobin Ehlis62086412014-11-19 16:19:28 -07002097 break;
2098 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002099 pPrev = pInfo;
2100 pInfo = pInfo->pNext;
Tobin Ehlis62086412014-11-19 16:19:28 -07002101 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002102 if (g_pDbgFunctionHead == NULL) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002103 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002104 g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002105 } else {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002106 g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002107 }
Jon Ashburne4722392015-03-03 15:07:15 -07002108 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002109 VkResult result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002110 return result;
2111}
2112
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002113VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
2114 VkDevice device,
2115 const VkSwapChainCreateInfoWSI *pCreateInfo,
2116 VkSwapChainWSI *pSwapChain)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002117{
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002118 VkResult result = nextTable.CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
2119
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002120 if (VK_SUCCESS == result) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002121 loader_platform_thread_lock_mutex(&globalLock);
2122 addSwapChainInfo(*pSwapChain);
2123 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -07002124 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002125
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002126 return result;
2127}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002128
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002129VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
2130 VkSwapChainWSI swapChain)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002131{
2132 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002133
2134 if (swapChainMap.find(swapChain) != swapChainMap.end()) {
2135 MT_SWAP_CHAIN_INFO* pInfo = swapChainMap[swapChain];
2136
David Pinedof5997ab2015-04-27 16:36:17 -06002137 if (pInfo->images.size() > 0) {
2138 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2139 it != pInfo->images.end(); it++) {
2140 clearObjectBinding(it->image);
2141 freeMemObjInfo(it->memory, true);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002142
David Pinedof5997ab2015-04-27 16:36:17 -06002143 MT_OBJ_INFO* pDelInfo = objectMap[it->image];
2144 delete pDelInfo;
2145 objectMap.erase(it->image);
2146 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002147 }
2148
2149 delete pInfo;
2150 swapChainMap.erase(swapChain);
2151 }
2152
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002153 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002154
2155 return nextTable.DestroySwapChainWSI(swapChain);
2156}
2157
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002158VK_LAYER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
2159 VkSwapChainWSI swapChain,
2160 VkSwapChainInfoTypeWSI infoType,
2161 size_t *pDataSize,
2162 void *pData)
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002163{
2164 VkResult result = nextTable.GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
2165
2166 if (infoType == VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI && result == VK_SUCCESS) {
2167 const size_t count = *pDataSize / sizeof(VkSwapChainImageInfoWSI);
2168 MT_SWAP_CHAIN_INFO *pInfo = swapChainMap[swapChain];
2169
2170 if (pInfo->images.empty()) {
2171 pInfo->images.resize(count);
2172 memcpy(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count);
2173
David Pinedof5997ab2015-04-27 16:36:17 -06002174 if (pInfo->images.size() > 0) {
2175 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2176 it != pInfo->images.end(); it++) {
2177 // Add image object, then insert the new Mem Object and then bind it to created image
2178 addObjectInfo(it->image, VK_STRUCTURE_TYPE_MAX_ENUM, &pInfo->createInfo, sizeof(pInfo->createInfo), "persistent_image");
2179 addMemObjInfo(it->memory, NULL);
2180 if (VK_FALSE == updateObjectBinding(it->image, it->memory)) {
2181 char str[1024];
2182 sprintf(str, "In vkGetSwapChainInfoWSI(), unable to set image %p binding to mem obj %p", (void*)it->image, (void*)it->memory);
2183 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
2184 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002185 }
2186 }
2187 } else {
2188 const bool mismatch = (pInfo->images.size() != count ||
2189 memcmp(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count));
2190
2191 if (mismatch) {
2192 char str[1024];
2193 sprintf(str, "vkGetSwapChainInfoWSI(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI) returned mismatching data", swapChain);
Mike Stroyan230e6252015-04-17 12:36:38 -06002194 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, (VkObject) swapChain, 0, MEMTRACK_NONE, "SWAP_CHAIN", str);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002195 }
2196 }
2197 }
2198
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002199 return result;
2200}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002201
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002202VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(
2203 VkPhysicalDevice gpu,
2204 const char *funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002205{
Jon Ashburn301c5f02015-04-06 10:58:22 -06002206 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wu706533e2015-01-05 13:18:57 +08002207
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002208 if (gpu == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002209 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002210 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002211 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07002212 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002213
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002214 if (!strcmp(funcName, "vkGetProcAddr"))
2215 return (void *) vkGetProcAddr;
2216 if (!strcmp(funcName, "vkCreateDevice"))
2217 return (void*) vkCreateDevice;
2218 if (!strcmp(funcName, "vkDestroyDevice"))
2219 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002220 if (!strcmp(funcName, "vkEnumerateLayers"))
2221 return (void*) vkEnumerateLayers;
2222 if (!strcmp(funcName, "vkQueueSubmit"))
2223 return (void*) vkQueueSubmit;
2224 if (!strcmp(funcName, "vkAllocMemory"))
2225 return (void*) vkAllocMemory;
2226 if (!strcmp(funcName, "vkFreeMemory"))
2227 return (void*) vkFreeMemory;
2228 if (!strcmp(funcName, "vkSetMemoryPriority"))
2229 return (void*) vkSetMemoryPriority;
2230 if (!strcmp(funcName, "vkMapMemory"))
2231 return (void*) vkMapMemory;
2232 if (!strcmp(funcName, "vkUnmapMemory"))
2233 return (void*) vkUnmapMemory;
2234 if (!strcmp(funcName, "vkPinSystemMemory"))
2235 return (void*) vkPinSystemMemory;
2236 if (!strcmp(funcName, "vkOpenSharedMemory"))
2237 return (void*) vkOpenSharedMemory;
2238 if (!strcmp(funcName, "vkOpenPeerMemory"))
2239 return (void*) vkOpenPeerMemory;
2240 if (!strcmp(funcName, "vkOpenPeerImage"))
2241 return (void*) vkOpenPeerImage;
2242 if (!strcmp(funcName, "vkDestroyObject"))
2243 return (void*) vkDestroyObject;
2244 if (!strcmp(funcName, "vkGetObjectInfo"))
2245 return (void*) vkGetObjectInfo;
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05002246 if (!strcmp(funcName, "vkBindObjectMemory"))
2247 return (void*) vkBindObjectMemory;
2248 if (!strcmp(funcName, "vkQueueBindSparseBufferMemory"))
2249 return (void*) vkQueueBindSparseBufferMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002250 if (!strcmp(funcName, "vkCreateFence"))
2251 return (void*) vkCreateFence;
2252 if (!strcmp(funcName, "vkGetFenceStatus"))
2253 return (void*) vkGetFenceStatus;
2254 if (!strcmp(funcName, "vkResetFences"))
2255 return (void*) vkResetFences;
2256 if (!strcmp(funcName, "vkWaitForFences"))
2257 return (void*) vkWaitForFences;
2258 if (!strcmp(funcName, "vkQueueWaitIdle"))
2259 return (void*) vkQueueWaitIdle;
2260 if (!strcmp(funcName, "vkDeviceWaitIdle"))
2261 return (void*) vkDeviceWaitIdle;
2262 if (!strcmp(funcName, "vkCreateEvent"))
2263 return (void*) vkCreateEvent;
2264 if (!strcmp(funcName, "vkCreateQueryPool"))
2265 return (void*) vkCreateQueryPool;
2266 if (!strcmp(funcName, "vkCreateBuffer"))
2267 return (void*) vkCreateBuffer;
2268 if (!strcmp(funcName, "vkCreateBufferView"))
2269 return (void*) vkCreateBufferView;
2270 if (!strcmp(funcName, "vkCreateImage"))
2271 return (void*) vkCreateImage;
2272 if (!strcmp(funcName, "vkCreateImageView"))
2273 return (void*) vkCreateImageView;
2274 if (!strcmp(funcName, "vkCreateColorAttachmentView"))
2275 return (void*) vkCreateColorAttachmentView;
2276 if (!strcmp(funcName, "vkCreateDepthStencilView"))
2277 return (void*) vkCreateDepthStencilView;
2278 if (!strcmp(funcName, "vkCreateShader"))
2279 return (void*) vkCreateShader;
2280 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2281 return (void*) vkCreateGraphicsPipeline;
2282 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2283 return (void*) vkCreateGraphicsPipelineDerivative;
2284 if (!strcmp(funcName, "vkCreateComputePipeline"))
2285 return (void*) vkCreateComputePipeline;
2286 if (!strcmp(funcName, "vkCreateSampler"))
2287 return (void*) vkCreateSampler;
2288 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2289 return (void*) vkCreateDynamicViewportState;
2290 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2291 return (void*) vkCreateDynamicRasterState;
2292 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2293 return (void*) vkCreateDynamicColorBlendState;
2294 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2295 return (void*) vkCreateDynamicDepthStencilState;
2296 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2297 return (void*) vkCreateCommandBuffer;
2298 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2299 return (void*) vkBeginCommandBuffer;
2300 if (!strcmp(funcName, "vkEndCommandBuffer"))
2301 return (void*) vkEndCommandBuffer;
2302 if (!strcmp(funcName, "vkResetCommandBuffer"))
2303 return (void*) vkResetCommandBuffer;
2304 if (!strcmp(funcName, "vkCmdBindPipeline"))
2305 return (void*) vkCmdBindPipeline;
2306 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2307 return (void*) vkCmdBindDynamicStateObject;
2308 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2309 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002310 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2311 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002312 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2313 return (void*) vkCmdBindIndexBuffer;
2314 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2315 return (void*) vkCmdDrawIndirect;
2316 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2317 return (void*) vkCmdDrawIndexedIndirect;
2318 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2319 return (void*) vkCmdDispatchIndirect;
2320 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2321 return (void*) vkCmdCopyBuffer;
2322 if (!strcmp(funcName, "vkCmdCopyImage"))
2323 return (void*) vkCmdCopyImage;
2324 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2325 return (void*) vkCmdCopyBufferToImage;
2326 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2327 return (void*) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002328 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2329 return (void*) vkCmdUpdateBuffer;
2330 if (!strcmp(funcName, "vkCmdFillBuffer"))
2331 return (void*) vkCmdFillBuffer;
2332 if (!strcmp(funcName, "vkCmdClearColorImage"))
2333 return (void*) vkCmdClearColorImage;
2334 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2335 return (void*) vkCmdClearDepthStencil;
2336 if (!strcmp(funcName, "vkCmdResolveImage"))
2337 return (void*) vkCmdResolveImage;
2338 if (!strcmp(funcName, "vkCmdBeginQuery"))
2339 return (void*) vkCmdBeginQuery;
2340 if (!strcmp(funcName, "vkCmdEndQuery"))
2341 return (void*) vkCmdEndQuery;
2342 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2343 return (void*) vkCmdResetQueryPool;
2344 if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
2345 return (void*) vkDbgRegisterMsgCallback;
2346 if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
2347 return (void*) vkDbgUnregisterMsgCallback;
2348 if (!strcmp(funcName, "vkGetDeviceQueue"))
2349 return (void*) vkGetDeviceQueue;
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002350 if (!strcmp(funcName, "vkCreateSwapChainWSI"))
2351 return (void*) vkCreateSwapChainWSI;
2352 if (!strcmp(funcName, "vkDestroySwapChainWSI"))
2353 return (void*) vkDestroySwapChainWSI;
2354 if (!strcmp(funcName, "vkGetSwapChainInfoWSI"))
2355 return (void*) vkGetSwapChainInfoWSI;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002356 else {
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002357 if (gpuw->pGPA == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002358 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002359 }
Tony Barbour8205d902015-04-16 15:59:00 -06002360 return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002361 }
2362}