blob: 98b2df547605ecc833e47dcca7857f3a6466de61 [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));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600485 layerCbMsg(VK_DBG_MSG_ERROR, 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 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700507}
508
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600509static void deleteMemObjInfo(
510 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700511{
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500512 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500513 MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
514 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500515 memObjMap.erase(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700516 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500517 else {
518 char str[1024];
519 sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
520 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
521 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700522}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500523
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700524// Check if fence for given CB is completed
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600525static bool32_t checkCBCompleted(
526 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700527{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600528 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500529 MT_CB_INFO* pCBInfo = getCBInfo(cb);
530 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700531 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500532 sprintf(str, "Unable to find global CB info %p to check for completion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600533 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
534 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600535 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500536 if (!fenceRetired(pCBInfo->fenceId)) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600537 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600538 sprintf(str, "FenceId %" PRIx64", fence %p for CB %p has not been checked for completion",
539 pCBInfo->fenceId, getFenceFromId(pCBInfo->fenceId), cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600540 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
541 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600542 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700543 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600544 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700545}
546
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600547static bool32_t freeMemObjInfo(
548 VkDeviceMemory mem,
549 bool internal)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700550{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600551 bool32_t result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500552 // Parse global list to find info w/ mem
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500553 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
554 if (!pInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700555 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600556 sprintf(str, "Couldn't find mem info object for %p\n Was %p never allocated or previously freed?",
557 (void*)mem, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600558 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
559 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600560 } else {
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -0600561 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600562 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600563 sprintf(str, "Attempting to free memory associated with a Persistent Image, %p, "
564 "this should not be explicitly freed\n", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600565 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
566 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600567 } else {
568 // Clear any CB bindings for completed CBs
569 // TODO : Is there a better place to do this?
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500570
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600571 list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin();
572 list<VkCmdBuffer>::iterator temp;
David Pinedof5997ab2015-04-27 16:36:17 -0600573 while (pInfo->pCmdBufferBindings.size() > 0 && it != pInfo->pCmdBufferBindings.end()) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600574 if (VK_TRUE == checkCBCompleted(*it)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500575 temp = it;
576 ++temp;
577 freeCBBindings(*it);
578 it = temp;
579 } else {
580 ++it;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600581 }
582 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500583
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600584 // Now verify that no references to this mem obj remain
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500585 if (0 != pInfo->refCount) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500586 // If references remain, report the error and can search CB list to find references
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600587 char str[1024];
588 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600589 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500590 reportMemReferencesAndCleanUp(pInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600591 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600592 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600593 // Delete mem obj info
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500594 deleteMemObjInfo(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700595 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700596 }
597 return result;
598}
599
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700600// Remove object binding performs 3 tasks:
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500601// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
602// 2. Decrement refCount for MemObjInfo
603// 3. Clear MemObjInfo ptr from ObjectInfo
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600604static bool32_t clearObjectBinding(
605 VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700606{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600607 bool32_t result = VK_FALSE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500608 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
609 if (!pObjInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700610 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600611 sprintf(str, "Attempting to clear mem binding for object %p: devices, queues, command buffers, "
612 "shaders and memory objects do not have external memory requirements and it is "
613 "unneccessary to call bind/unbindObjectMemory on them.", object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600614 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600615 } else {
David Pinedof5997ab2015-04-27 16:36:17 -0600616 if (!pObjInfo->pMemObjInfo || pObjInfo->pMemObjInfo->pObjBindings.size() <= 0) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600617 char str[1024];
618 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600619 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 -0600620 } else {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500621 // 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
622 // and set the objects memory binding pointer to NULL.
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600623 for (list<VkObject>::iterator it = pObjInfo->pMemObjInfo->pObjBindings.begin(); it != pObjInfo->pMemObjInfo->pObjBindings.end(); ++it) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500624 if ((*it) == object) {
625 pObjInfo->pMemObjInfo->refCount--;
626 pObjInfo->pMemObjInfo->pObjBindings.erase(it);
627 pObjInfo->pMemObjInfo = NULL;
628 result = VK_TRUE;
629 break;
630 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600631 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600632 if (result == VK_FALSE) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600633 char str[1024];
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500634 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 -0500635 object, pObjInfo->pMemObjInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600636 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600637 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700638 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700639 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600640 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700641}
642
643// For NULL mem case, clear any previous binding Else...
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500644// Make sure given object is in global object map
Tobin Ehlis62086412014-11-19 16:19:28 -0700645// IF a previous binding existed, clear it
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500646// Add reference from objectInfo to memoryInfo
647// Add reference off of objInfo
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600648// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600649static bool32_t updateObjectBinding(
650 VkObject object,
651 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700652{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600653 bool32_t result = VK_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700654 // Handle NULL case separately, just clear previous binding & decrement reference
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600655 if (mem == VK_NULL_HANDLE) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700656 clearObjectBinding(object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600657 result = VK_TRUE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600658 } else {
659 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500660 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
661 if (!pObjInfo) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600662 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600663 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
664 return VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600665 }
666 // non-null case so should have real mem obj
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500667 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600668 if (!pInfo) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500669 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 -0600670 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600671 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500672 // Search for object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600673 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600674 if (pInfo->pObjBindings.size() > 0) {
675 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
676 if ((*it) == object) {
677 found = VK_TRUE;
678 break;
679 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600680 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600681 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500682 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600683 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500684 pInfo->pObjBindings.push_front(object);
685 pInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500686 }
687
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500688 if (pObjInfo->pMemObjInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500689 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500690 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 -0600691 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500692 }
693 // For image objects, make sure default memory state is correctly set
694 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600695 if (VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pObjInfo->sType) {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600696 if (pObjInfo->create_info.image_create_info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
697 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500698 // TODO:: More memory state transition stuff.
699 }
700 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500701 pObjInfo->pMemObjInfo = pInfo;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700702 }
703 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600704 return VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700705}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600706
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700707// Print details of global Obj tracking list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600708static void printObjList(
709 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700710{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500711 MT_OBJ_INFO* pInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500712 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500713 sprintf(str, "Details of Object list of size %lu elements", objectMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600714 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600715 if (objectMap.size() <= 0)
716 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600717 for (map<VkObject, MT_OBJ_INFO*>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500718 pInfo = (*ii).second;
719 sprintf(str, " ObjInfo %p has object %p, pMemObjInfo %p", pInfo, pInfo->object, pInfo->pMemObjInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600720 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700721 }
722}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600723
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700724// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600725static VkDeviceMemory getMemBindingFromObject(
726 const VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700727{
Tony Barbour8205d902015-04-16 15:59:00 -0600728 VkDeviceMemory mem = NULL;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500729 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
730 if (pObjInfo) {
731 if (pObjInfo->pMemObjInfo) {
732 mem = pObjInfo->pMemObjInfo->mem;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600733 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700734 char str[1024];
735 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 -0600736 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700737 printObjList();
738 }
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600739 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700740 char str[1024];
741 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 -0600742 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700743 printObjList();
744 }
745 return mem;
746}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500747
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500748// Print details of MemObjInfo list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600749static void printMemList(
750 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700751{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500752 MT_MEM_OBJ_INFO* pInfo = NULL;
Tobin Ehlis62086412014-11-19 16:19:28 -0700753 // Just printing each msg individually for now, may want to package these into single large print
754 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500755 sprintf(str, "MEM INFO : Details of Memory Object list of size %lu elements", memObjMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600756 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500757
David Pinedof5997ab2015-04-27 16:36:17 -0600758 if (memObjMap.size() <= 0)
759 return;
760
Tony Barbour8205d902015-04-16 15:59:00 -0600761 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500762 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500763
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500764 sprintf(str, " ===MemObjInfo at %p===", (void*)pInfo);
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, " Mem object: %p", (void*)pInfo->mem);
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 sprintf(str, " Ref Count: %u", pInfo->refCount);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600769 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500770 if (0 != pInfo->allocInfo.allocationSize) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600771 string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "{MEM}INFO : ");
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500772 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600773 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500774 } else {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800775 sprintf(str, " Mem Alloc info is NULL (alloc done by vkCreateSwapChainWSI())");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600776 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500777 }
778
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600779 sprintf(str, " VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
780 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600781 if (pInfo->pObjBindings.size() > 0) {
782 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
783 sprintf(str, " VK OBJECT %p", (*it));
784 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
785 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500786 }
787
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600788 sprintf(str, " VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
789 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600790 if (pInfo->pCmdBufferBindings.size() > 0)
791 {
792 for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
793 sprintf(str, " VK CB %p", (*it));
794 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
795 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700796 }
797 }
798}
799
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600800static void printCBList(
801 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700802{
Tobin Ehlis62086412014-11-19 16:19:28 -0700803 char str[1024] = {0};
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500804 MT_CB_INFO* pCBInfo = NULL;
805 sprintf(str, "Details of CB list of size %lu elements", cbMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600806 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500807
David Pinedof5997ab2015-04-27 16:36:17 -0600808 if (cbMap.size() <= 0)
809 return;
810
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600811 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500812 pCBInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500813
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500814 sprintf(str, " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %p",
815 (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
816 (void*)getFenceFromId(pCBInfo->fenceId));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600817 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500818
David Pinedof5997ab2015-04-27 16:36:17 -0600819 if (pCBInfo->pMemObjList.size() <= 0)
820 continue;
Tony Barbour8205d902015-04-16 15:59:00 -0600821 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500822 sprintf(str, " Mem obj %p", (*it));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600823 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700824 }
825 }
826}
827
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600828static void initMemTracker(
829 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700830{
Jon Ashburnf57ea372014-12-22 13:24:15 -0700831 const char *strOpt;
832 // initialize MemTracker options
Ian Elliott7d0b5d22015-03-06 13:50:05 -0700833 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
834 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -0700835
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600836 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburnf57ea372014-12-22 13:24:15 -0700837 {
838 strOpt = getLayerOption("MemTrackerLogFilename");
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600839 if (strOpt) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700840 g_logFile = fopen(strOpt, "w");
Jon Ashburnf57ea372014-12-22 13:24:15 -0700841 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600842 if (g_logFile == NULL) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700843 g_logFile = stdout;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600844 }
Jon Ashburnf57ea372014-12-22 13:24:15 -0700845 }
846
847 // initialize Layer dispatch table
848 // TODO handle multiple GPUs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600849 PFN_vkGetProcAddr fpNextGPA;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700850 fpNextGPA = pCurObj->pGPA;
851 assert(fpNextGPA);
852
Tony Barbour8205d902015-04-16 15:59:00 -0600853 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800854
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600855 if (!globalLockInitialized)
856 {
857 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600858 // suggestion is to call this during vkCreateInstance(), and then we
859 // can clean it up during vkDestroyInstance(). However, that requires
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600860 // that the layer have per-instance locks. We need to come back and
861 // address this soon.
862 loader_platform_thread_create_mutex(&globalLock);
863 globalLockInitialized = 1;
864 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700865}
866
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600867VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
868 VkPhysicalDevice gpu,
869 const VkDeviceCreateInfo *pCreateInfo,
870 VkDevice *pDevice)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700871{
Jon Ashburn630e44f2015-04-08 21:33:34 -0600872 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700873 loader_platform_thread_once(&g_initOnce, initMemTracker);
Jon Ashburn630e44f2015-04-08 21:33:34 -0600874 VkResult result = nextTable.CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700875 // Save off device in case we need it to create Fences
876 globalDevice = *pDevice;
877 return result;
878}
879
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600880VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(
881 VkDevice device)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700882{
Tobin Ehlis62086412014-11-19 16:19:28 -0700883 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600884 sprintf(str, "Printing List details prior to vkDestroyDevice()");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600885 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600886 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700887 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500888 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700889 printObjList();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600890 if (VK_FALSE == deleteCBInfoList()) {
891 sprintf(str, "Issue deleting global CB list in vkDestroyDevice()");
892 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -0700893 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700894 // Report any memory leaks
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500895 MT_MEM_OBJ_INFO* pInfo = NULL;
David Pinedof5997ab2015-04-27 16:36:17 -0600896 if (memObjMap.size() > 0) {
897 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
898 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500899
David Pinedof5997ab2015-04-27 16:36:17 -0600900 if (pInfo->allocInfo.allocationSize != 0) {
901 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling "
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600902 "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
David Pinedof5997ab2015-04-27 16:36:17 -0600903 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
904 }
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600905 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700906 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500907
908 // Queues persist until device is destroyed
909 deleteQueueInfoList();
910
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600911 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600912 VkResult result = nextTable.DestroyDevice(device);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700913 return result;
914}
915
Jon Ashburneb2728b2015-04-10 14:33:07 -0600916struct extProps {
917 uint32_t version;
918 const char * const name;
919};
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600920#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2
Jon Ashburneb2728b2015-04-10 14:33:07 -0600921static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
922 // TODO what is the version?
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600923 0x10, "MemTracker",
924 0x10, "Validation"
Jon Ashburneb2728b2015-04-10 14:33:07 -0600925};
926
927VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600928 VkExtensionInfoType infoType,
929 uint32_t extensionIndex,
930 size_t *pDataSize,
931 void *pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600932{
Ian Elliottede4a2e2015-04-28 16:11:24 -0600933 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
Jon Ashburneb2728b2015-04-10 14:33:07 -0600934 VkExtensionProperties *ext_props;
935 uint32_t *count;
936
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600937 if (pDataSize == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600938 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600939 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600940
941 switch (infoType) {
942 case VK_EXTENSION_INFO_TYPE_COUNT:
943 *pDataSize = sizeof(uint32_t);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600944 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600945 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600946 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600947 count = (uint32_t *) pData;
948 *count = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE;
949 break;
950 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
951 *pDataSize = sizeof(VkExtensionProperties);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600952 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600953 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600954 }
955 if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600956 return VK_ERROR_INVALID_VALUE;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600957 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600958 ext_props = (VkExtensionProperties *) pData;
959 ext_props->version = mtExts[extensionIndex].version;
960 strncpy(ext_props->extName, mtExts[extensionIndex].name,
961 VK_MAX_EXTENSION_NAME);
962 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
963 break;
964 default:
965 return VK_ERROR_INVALID_VALUE;
966 };
967
968 return VK_SUCCESS;
969}
970
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600971VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(
972 VkPhysicalDevice gpu,
973 size_t maxStringSize,
974 size_t *pLayerCount,
975 char* const *pOutLayers,
976 void *pReserved)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700977{
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600978 if (gpu != NULL)
Jon Ashburn451c16f2014-11-25 11:08:42 -0700979 {
Jon Ashburn630e44f2015-04-08 21:33:34 -0600980 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700981 loader_platform_thread_once(&g_initOnce, initMemTracker);
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600982 VkResult result = nextTable.EnumerateLayers(gpu,
983 maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn451c16f2014-11-25 11:08:42 -0700984 return result;
985 } else
986 {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600987 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600988 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600989 }
Jon Ashburn451c16f2014-11-25 11:08:42 -0700990 // This layer compatible with all GPUs
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600991 *pLayerCount = 1;
Chia-I Wua837c522014-12-16 10:47:33 +0800992 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600993 return VK_SUCCESS;
Jon Ashburn451c16f2014-11-25 11:08:42 -0700994 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700995}
996
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600997VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
998 VkDevice device,
999 uint32_t queueNodeIndex,
1000 uint32_t queueIndex,
1001 VkQueue *pQueue)
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001002{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001003 VkResult result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001004 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001005 loader_platform_thread_lock_mutex(&globalLock);
1006 addQueueInfo(*pQueue);
1007 loader_platform_thread_unlock_mutex(&globalLock);
1008 }
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001009 return result;
1010}
1011
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001012VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(
1013 VkQueue queue,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001014 uint32_t cmdBufferCount,
1015 const VkCmdBuffer *pCmdBuffers,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001016 VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001017{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001018 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001019 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001020 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001021 uint64_t fenceId = addFenceInfo(fence, queue);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001022
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001023 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001024 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001025 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001026 pCBInfo = getCBInfo(pCmdBuffers[i]);
1027 pCBInfo->fenceId = fenceId;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001028 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001029
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001030 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001031 VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, getFenceFromId(fenceId));
Courtney Goeltzenleuchtercfedf362015-04-02 13:39:07 -06001032 return result;
1033}
1034
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001035VK_LAYER_EXPORT VkResult VKAPI vkAllocMemory(
1036 VkDevice device,
1037 const VkMemoryAllocInfo *pAllocInfo,
1038 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001039{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001040 VkResult result = nextTable.AllocMemory(device, pAllocInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001041 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001042 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001043 addMemObjInfo(*pMem, pAllocInfo);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001044 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001045 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001046 return result;
1047}
1048
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001049VK_LAYER_EXPORT VkResult VKAPI vkFreeMemory(
1050 VkDevice device,
1051 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001052{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001053 /* From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed. Before
Tobin Ehlisa747e682014-11-25 14:47:20 -07001054 * freeing a memory object, an application must ensure the memory object is unbound from
1055 * all API objects referencing it and that it is not referenced by any queued command buffers
1056 */
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001057 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001058 if (VK_FALSE == freeMemObjInfo(mem, false)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001059 char str[1024];
1060 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001061 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001062 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001063 printMemList();
1064 printObjList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001065 printCBList();
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];
Tony Barbour8205d902015-04-16 15:59:00 -06001095 sprintf(str, "Mapping Memory (%p) without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set", (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 "
1180 "by calling vkQueueBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)",
1181 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 Lobodzinskicf26e072015-04-16 11:44:05 -05001206 // Could potentially save returned mem requirements and validate values passed into QueueBindObjectMemory 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 Lobodzinskia908b162015-04-21 15:33:04 -06001213VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(
1214 VkQueue queue,
1215 VkObjectType objType,
1216 VkObject object,
1217 uint32_t allocationIdx,
1218 VkDeviceMemory mem,
1219 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001220{
Mike Stroyan230e6252015-04-17 12:36:38 -06001221 VkResult result = nextTable.QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset);
1222 loader_platform_thread_lock_mutex(&globalLock);
1223 // Track objects tied to memory
1224 if (VK_FALSE == updateObjectBinding(object, mem)) {
1225 char str[1024];
1226 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1227 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1228 }
1229 printObjList();
1230 printMemList();
1231 loader_platform_thread_unlock_mutex(&globalLock);
1232 return result;
1233}
1234
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001235VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange(
1236 VkQueue queue,
1237 VkObjectType objType,
1238 VkObject object,
1239 uint32_t allocationIdx,
1240 VkDeviceSize rangeOffset,
1241 VkDeviceSize rangeSize,
1242 VkDeviceMemory mem,
1243 VkDeviceSize memOffset)
Mike Stroyan230e6252015-04-17 12:36:38 -06001244{
1245 VkResult result = nextTable.QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001246 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001247 // Track objects tied to memory
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001248 if (VK_FALSE == updateObjectBinding(object, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001249 char str[1024];
1250 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001251 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001252 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001253 printObjList();
1254 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001255 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001256 return result;
1257}
1258
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001259VK_LAYER_EXPORT VkResult VKAPI vkCreateFence(
1260 VkDevice device,
1261 const VkFenceCreateInfo *pCreateInfo,
1262 VkFence *pFence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001263{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001264 VkResult result = nextTable.CreateFence(device, pCreateInfo, pFence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001265 if (VK_SUCCESS == result) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001266 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001267 addObjectInfo(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(VkFenceCreateInfo), "fence");
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001268 loader_platform_thread_unlock_mutex(&globalLock);
1269 }
1270 return result;
1271}
1272
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001273VK_LAYER_EXPORT VkResult VKAPI vkResetFences(
1274 VkDevice device,
1275 uint32_t fenceCount,
1276 VkFence *pFences)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001277{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001278 VkResult result = nextTable.ResetFences(device, fenceCount, pFences);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001279 if (VK_SUCCESS == result) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001280 loader_platform_thread_lock_mutex(&globalLock);
1281 // Reset fence state in fenceCreateInfo structure
1282 for (uint32_t i = 0; i < fenceCount; i++) {
1283 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1284 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001285 // Validate fences in SIGNALED state
Tobin Ehlisf29da382015-04-15 07:46:12 -06001286 if (!(pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001287 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001288 sprintf(str, "Fence %p submitted to VkResetFences in UNSIGNALED STATE", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001289 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
1290 result = VK_ERROR_INVALID_VALUE;
Mark Lobodzinski56945182015-04-09 13:46:09 -05001291 }
1292 else {
1293 pObjectInfo->create_info.fence_create_info.flags =
Tobin Ehlisf29da382015-04-15 07:46:12 -06001294 static_cast<VkFenceCreateFlags>(pObjectInfo->create_info.fence_create_info.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski56945182015-04-09 13:46:09 -05001295 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001296 }
1297 }
1298 loader_platform_thread_unlock_mutex(&globalLock);
1299 }
1300 return result;
1301}
1302
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001303VK_LAYER_EXPORT VkResult VKAPI vkGetFenceStatus(
1304 VkDevice device,
1305 VkFence fence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001306{
Mike Stroyan230e6252015-04-17 12:36:38 -06001307 VkResult result = nextTable.GetFenceStatus(device, fence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001308 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001309 loader_platform_thread_lock_mutex(&globalLock);
1310 updateFenceTracking(fence);
1311 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001312 }
1313 return result;
1314}
1315
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001316VK_LAYER_EXPORT VkResult VKAPI vkWaitForFences(
1317 VkDevice device,
1318 uint32_t fenceCount,
1319 const VkFence *pFences,
1320 bool32_t waitAll,
1321 uint64_t timeout)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001322{
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001323 // Verify fence status of submitted fences
1324 for(uint32_t i = 0; i < fenceCount; i++) {
1325 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1326 if (pObjectInfo != NULL) {
Tobin Ehlisf29da382015-04-15 07:46:12 -06001327 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001328 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001329 sprintf(str, "VkWaitForFences specified fence %p already in SIGNALED state.", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001330 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 -05001331 }
1332 }
1333 }
1334
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001335 VkResult result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001336 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001337
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001338 if (VK_SUCCESS == result) {
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001339 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001340 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001341 updateFenceTracking(pFences[i]);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001342 }
1343 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001344 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001345 loader_platform_thread_unlock_mutex(&globalLock);
1346 return result;
1347}
1348
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001349VK_LAYER_EXPORT VkResult VKAPI vkQueueWaitIdle(
1350 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001351{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001352 VkResult result = nextTable.QueueWaitIdle(queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001353 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001354 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001355 retireQueueFences(queue);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001356 loader_platform_thread_unlock_mutex(&globalLock);
1357 }
1358 return result;
1359}
1360
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001361VK_LAYER_EXPORT VkResult VKAPI vkDeviceWaitIdle(
1362 VkDevice device)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001363{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001364 VkResult result = nextTable.DeviceWaitIdle(device);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001365 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001366 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001367 retireDeviceFences(device);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001368 loader_platform_thread_unlock_mutex(&globalLock);
1369 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001370 return result;
1371}
1372
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001373VK_LAYER_EXPORT VkResult VKAPI vkCreateEvent(
1374 VkDevice device,
1375 const VkEventCreateInfo *pCreateInfo,
1376 VkEvent *pEvent)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001377{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001378 VkResult result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001379 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001380 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001381 addObjectInfo(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(VkEventCreateInfo), "event");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001382 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001383 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001384 return result;
1385}
1386
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001387VK_LAYER_EXPORT VkResult VKAPI vkCreateQueryPool(
1388 VkDevice device,
1389 const VkQueryPoolCreateInfo *pCreateInfo,
1390 VkQueryPool *pQueryPool)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001391{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001392 VkResult result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001393 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001394 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001395 addObjectInfo(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(VkQueryPoolCreateInfo), "query_pool");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001396 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001397 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001398 return result;
1399}
1400
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001401VK_LAYER_EXPORT VkResult VKAPI vkCreateBuffer(
1402 VkDevice device,
1403 const VkBufferCreateInfo *pCreateInfo,
1404 VkBuffer *pBuffer)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001405{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001406 VkResult result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001407 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001408 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001409 addObjectInfo(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferCreateInfo), "buffer");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001410 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001411 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001412 return result;
1413}
1414
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001415VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(
1416 VkDevice device,
1417 const VkBufferViewCreateInfo *pCreateInfo,
1418 VkBufferView *pView)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001419{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001420 VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001421 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001422 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001423 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferViewCreateInfo), "buffer_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001424 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001425 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001426 return result;
1427}
1428
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001429VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(
1430 VkDevice device,
1431 const VkImageCreateInfo *pCreateInfo,
1432 VkImage *pImage)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001433{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001434 VkResult result = nextTable.CreateImage(device, pCreateInfo, pImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001435 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001436 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001437 addObjectInfo(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(VkImageCreateInfo), "image");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001438 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001439 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001440 return result;
1441}
1442
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001443VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(
1444 VkDevice device,
1445 const VkImageViewCreateInfo *pCreateInfo,
1446 VkImageView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001447{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001448 VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001449 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001450 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001451 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkImageViewCreateInfo), "image_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001452 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001453 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001454 return result;
1455}
1456
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001457VK_LAYER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(
1458 VkDevice device,
1459 const VkColorAttachmentViewCreateInfo *pCreateInfo,
1460 VkColorAttachmentView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001461{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001462 VkResult result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001463 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001464 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001465 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkColorAttachmentViewCreateInfo), "color_attachment_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001466 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001467 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001468 return result;
1469}
1470
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001471VK_LAYER_EXPORT VkResult VKAPI vkCreateDepthStencilView(
1472 VkDevice device,
1473 const VkDepthStencilViewCreateInfo *pCreateInfo,
1474 VkDepthStencilView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001475{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001476 VkResult result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001477 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001478 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001479 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkDepthStencilViewCreateInfo), "ds_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001480 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001481 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001482 return result;
1483}
1484
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001485VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(
1486 VkDevice device,
1487 const VkShaderCreateInfo *pCreateInfo,
1488 VkShader *pShader)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001489{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001490 VkResult result = nextTable.CreateShader(device, pCreateInfo, pShader);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001491 return result;
1492}
1493
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001494VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(
1495 VkDevice device,
1496 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1497 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001498{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001499 VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001500 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001501 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001502 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001503 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001504 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001505 return result;
1506}
1507
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001508VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001509 VkDevice device,
1510 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1511 VkPipeline basePipeline,
1512 VkPipeline *pPipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001513{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001514 VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001515 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001516 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001517 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001518 loader_platform_thread_unlock_mutex(&globalLock);
1519 }
1520 return result;
1521}
1522
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001523VK_LAYER_EXPORT VkResult VKAPI vkCreateComputePipeline(
1524 VkDevice device,
1525 const VkComputePipelineCreateInfo *pCreateInfo,
1526 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001527{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001528 VkResult result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001529 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001530 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001531 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkComputePipelineCreateInfo), "compute_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001532 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001533 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001534 return result;
1535}
1536
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001537VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(
1538 VkDevice device,
1539 const VkSamplerCreateInfo *pCreateInfo,
1540 VkSampler *pSampler)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001541{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001542 VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001543 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001544 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001545 addObjectInfo(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(VkSamplerCreateInfo), "sampler");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001546 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001547 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001548 return result;
1549}
1550
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001551VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(
1552 VkDevice device,
1553 const VkDynamicVpStateCreateInfo *pCreateInfo,
1554 VkDynamicVpState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001555{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001556 VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001557 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001558 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001559 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo), "viewport_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001560 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001561 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001562 return result;
1563}
1564
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001565VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(
1566 VkDevice device,
1567 const VkDynamicRsStateCreateInfo *pCreateInfo,
1568 VkDynamicRsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001569{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001570 VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001571 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001572 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001573 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo), "raster_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001574 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001575 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001576 return result;
1577}
1578
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001579VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(
1580 VkDevice device,
1581 const VkDynamicCbStateCreateInfo *pCreateInfo,
1582 VkDynamicCbState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001583{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001584 VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001585 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001586 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001587 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo), "cb_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001588 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001589 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001590 return result;
1591}
1592
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001593VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(
1594 VkDevice device,
1595 const VkDynamicDsStateCreateInfo *pCreateInfo,
1596 VkDynamicDsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001597{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001598 VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001599 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001600 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001601 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo), "ds_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001602 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001603 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001604 return result;
1605}
1606
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001607VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(
1608 VkDevice device,
1609 const VkCmdBufferCreateInfo *pCreateInfo,
1610 VkCmdBuffer *pCmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001611{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001612 VkResult result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001613 // At time of cmd buffer creation, create global cmd buffer info for the returned cmd buffer
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001614 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001615 if (*pCmdBuffer)
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001616 addCBInfo(*pCmdBuffer);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001617 printCBList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001618 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001619 return result;
1620}
1621
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001622VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(
1623 VkCmdBuffer cmdBuffer,
1624 const VkCmdBufferBeginInfo *pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001625{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001626 // 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 -05001627 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1628 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001629 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001630 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001631 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001632 sprintf(str, "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
1633 "You must check CB flag before this call.", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001634 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 -07001635 }
1636 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001637 VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001638 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001639 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001640 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001641 return result;
1642}
1643
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001644VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(
1645 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001646{
1647 // TODO : Anything to do here?
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001648 VkResult result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001649 return result;
1650}
1651
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001652VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(
1653 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001654{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001655 // Verify that CB is complete (not in-flight)
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001656 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1657 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001658 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001659 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001660 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001661 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before "
1662 "calling vkResetCommandBuffer().", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001663 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 -07001664 }
1665 }
1666 // Clear memory references as this point.
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001667 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001668 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001669 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001670 VkResult result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001671 return result;
1672}
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001673// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001674// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001675VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(
1676 VkCmdBuffer cmdBuffer,
1677 VkPipelineBindPoint pipelineBindPoint,
1678 VkPipeline pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001679{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001680#if 0
1681 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1682 if (getPipeline(pipeline)) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001683 MT_CB_INFO *pCBInfo = getCBInfo(cmdBuffer);
1684 if (pCBInfo) {
1685 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001686 } else {
1687 char str[1024];
1688 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001689 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 -07001690 }
1691 }
1692 else {
1693 char str[1024];
1694 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001695 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 -07001696 }
1697#endif
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001698 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1699}
1700
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001701VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(
1702 VkCmdBuffer cmdBuffer,
1703 VkStateBindPoint stateBindPoint,
1704 VkDynamicStateObject state)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001705{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001706 MT_OBJ_INFO *pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001707 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001708 MT_CB_INFO *pCmdBuf = getCBInfo(cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001709 if (!pCmdBuf) {
1710 char str[1024];
1711 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001712 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001713 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001714 pObjInfo = getObjectInfo(state);
1715 if (!pObjInfo) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001716 char str[1024];
1717 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001718 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001719 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001720 pCmdBuf->pDynamicState[stateBindPoint] = pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001721 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001722 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001723}
1724
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001725VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001726 VkCmdBuffer cmdBuffer,
1727 VkPipelineBindPoint pipelineBindPoint,
1728 uint32_t firstSet,
1729 uint32_t setCount,
1730 const VkDescriptorSet *pDescriptorSets,
1731 uint32_t dynamicOffsetCount,
1732 const uint32_t *pDynamicOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001733{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001734 // 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 -06001735 nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001736}
1737
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001738VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001739 VkCmdBuffer cmdBuffer,
1740 uint32_t startBinding,
1741 uint32_t bindingCount,
1742 const VkBuffer *pBuffers,
1743 const VkDeviceSize *pOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001744{
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001745 nextTable.CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001746}
1747
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001748VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(
1749 VkCmdBuffer cmdBuffer,
1750 VkBuffer buffer,
1751 VkDeviceSize offset,
1752 VkIndexType indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001753{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001754 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001755}
1756
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001757VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(
1758 VkCmdBuffer cmdBuffer,
1759 VkBuffer buffer,
1760 VkDeviceSize offset,
1761 uint32_t count,
1762 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001763{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001764 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001765 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001766 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001767 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001768 sprintf(str, "In vkCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1769 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001770 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001771 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001772 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001773}
1774
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001775VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(
1776 VkCmdBuffer cmdBuffer,
1777 VkBuffer buffer,
1778 VkDeviceSize offset,
1779 uint32_t count,
1780 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001781{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001782 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001783 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001784 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001785 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001786 sprintf(str, "In vkCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1787 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001788 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001789 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001790 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001791}
1792
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001793VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(
1794 VkCmdBuffer cmdBuffer,
1795 VkBuffer buffer,
1796 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001797{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001798 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001799 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001800 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001801 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001802 sprintf(str, "In vkCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1803 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001804 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001805 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001806 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001807}
1808
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001809VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(
1810 VkCmdBuffer cmdBuffer,
1811 VkBuffer srcBuffer,
1812 VkBuffer destBuffer,
1813 uint32_t regionCount,
1814 const VkBufferCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001815{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001816 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001817 VkDeviceMemory mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001818 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001819 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001820 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1821 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001822 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001823 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001824 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001825 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001826 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1827 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001828 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001829 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001830 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001831}
1832
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001833VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
1834 VkCmdBuffer cmdBuffer,
1835 VkImage srcImage,
1836 VkImageLayout srcImageLayout,
1837 VkImage destImage,
1838 VkImageLayout destImageLayout,
1839 uint32_t regionCount,
1840 const VkImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001841{
1842 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001843 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001844}
1845
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001846VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
1847 VkCmdBuffer cmdBuffer,
1848 VkImage srcImage,
1849 VkImageLayout srcImageLayout,
1850 VkImage destImage,
1851 VkImageLayout destImageLayout,
1852 uint32_t regionCount,
1853 const VkImageBlit *pRegions)
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001854{
1855 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001856 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001857}
1858
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001859VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
1860 VkCmdBuffer cmdBuffer,
1861 VkBuffer srcBuffer,
1862 VkImage destImage,
1863 VkImageLayout destImageLayout,
1864 uint32_t regionCount,
1865 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001866{
1867 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001868 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001869 VkDeviceMemory mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001870 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001871 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001872 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
1873 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001874 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001875
1876 mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001877 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001878 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001879 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1880 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001881 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001882 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001883 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001884}
1885
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001886VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
1887 VkCmdBuffer cmdBuffer,
1888 VkImage srcImage,
1889 VkImageLayout srcImageLayout,
1890 VkBuffer destBuffer,
1891 uint32_t regionCount,
1892 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001893{
1894 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001895 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001896 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001897 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001898 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001899 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
1900 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001901 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001902 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001903 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001904 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001905 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1906 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001907 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001908 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001909 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001910}
1911
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001912VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
1913 VkCmdBuffer cmdBuffer,
1914 VkBuffer destBuffer,
1915 VkDeviceSize destOffset,
1916 VkDeviceSize dataSize,
1917 const uint32_t *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001918{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001919 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001920 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001921 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001922 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001923 sprintf(str, "In vkCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1924 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001925 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001926 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001927 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001928}
1929
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001930VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
1931 VkCmdBuffer cmdBuffer,
1932 VkBuffer destBuffer,
1933 VkDeviceSize destOffset,
1934 VkDeviceSize fillSize,
1935 uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001936{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001937 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001938 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001939 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001940 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001941 sprintf(str, "In vkCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1942 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001943 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001944 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001945 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001946}
1947
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001948VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
1949 VkCmdBuffer cmdBuffer,
1950 VkImage image,
1951 VkImageLayout imageLayout,
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06001952 const VkClearColor *pColor,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001953 uint32_t rangeCount,
1954 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001955{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001956 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001957 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001958 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001959 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001960 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001961 sprintf(str, "In vkCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
1962 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001963 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001964 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06001965 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001966}
1967
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001968VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(
1969 VkCmdBuffer cmdBuffer,
1970 VkImage image,
1971 VkImageLayout imageLayout,
1972 float depth,
1973 uint32_t stencil,
1974 uint32_t rangeCount,
1975 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001976{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001977 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001978 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001979 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001980 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001981 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001982 sprintf(str, "In vkCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
1983 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001984 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001985 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001986 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001987}
1988
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001989VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
1990 VkCmdBuffer cmdBuffer,
1991 VkImage srcImage,
1992 VkImageLayout srcImageLayout,
1993 VkImage destImage,
1994 VkImageLayout destImageLayout,
1995 uint32_t regionCount,
1996 const VkImageResolve *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001997{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001998 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001999 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002000 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002001 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002002 sprintf(str, "In vkCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2003 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002004 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002005 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002006 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002007 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002008 sprintf(str, "In vkCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2009 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002010 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002011 loader_platform_thread_unlock_mutex(&globalLock);
Tony Barbour11f74372015-04-13 15:02:52 -06002012 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002013}
2014
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002015VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(
2016 VkCmdBuffer cmdBuffer,
2017 VkQueryPool queryPool,
2018 uint32_t slot,
2019 VkFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002020{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002021 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002022 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002023 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002024 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002025 sprintf(str, "In vkCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2026 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002027 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002028 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002029 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2030}
2031
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002032VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(
2033 VkCmdBuffer cmdBuffer,
2034 VkQueryPool queryPool,
2035 uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002036{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002037 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002038 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002039 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002040 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002041 sprintf(str, "In vkCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2042 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002043 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002044 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002045 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2046}
2047
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002048VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(
2049 VkCmdBuffer cmdBuffer,
2050 VkQueryPool queryPool,
2051 uint32_t startQuery,
2052 uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002053{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002054 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002055 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002056 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002057 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002058 sprintf(str, "In vkCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2059 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002060 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002061 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002062 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2063}
2064
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002065VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
2066 VkInstance instance,
2067 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
2068 void *pUserData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002069{
Tobin Ehlis62086412014-11-19 16:19:28 -07002070 // This layer intercepts callbacks
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002071 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 -07002072 if (!pNewDbgFuncNode)
Tony Barbour8205d902015-04-16 15:59:00 -06002073 return VK_ERROR_OUT_OF_HOST_MEMORY;
Tobin Ehlis62086412014-11-19 16:19:28 -07002074 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2075 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburnf57ea372014-12-22 13:24:15 -07002076 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2077 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburne4722392015-03-03 15:07:15 -07002078 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002079 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002080 g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002081 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002082 VkResult result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002083 return result;
2084}
2085
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002086VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
2087 VkInstance instance,
2088 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002089{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002090 VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
2091 VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002092 while (pInfo) {
2093 if (pInfo->pfnMsgCallback == pfnMsgCallback) {
2094 pPrev->pNext = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002095 if (g_pDbgFunctionHead == pInfo) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002096 g_pDbgFunctionHead = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002097 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002098 free(pInfo);
Tobin Ehlis62086412014-11-19 16:19:28 -07002099 break;
2100 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002101 pPrev = pInfo;
2102 pInfo = pInfo->pNext;
Tobin Ehlis62086412014-11-19 16:19:28 -07002103 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002104 if (g_pDbgFunctionHead == NULL) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002105 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002106 g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002107 } else {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002108 g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002109 }
Jon Ashburne4722392015-03-03 15:07:15 -07002110 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002111 VkResult result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002112 return result;
2113}
2114
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002115VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
2116 VkDevice device,
2117 const VkSwapChainCreateInfoWSI *pCreateInfo,
2118 VkSwapChainWSI *pSwapChain)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002119{
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002120 VkResult result = nextTable.CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
2121
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002122 if (VK_SUCCESS == result) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002123 loader_platform_thread_lock_mutex(&globalLock);
2124 addSwapChainInfo(*pSwapChain);
2125 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -07002126 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002127
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002128 return result;
2129}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002130
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002131VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
2132 VkSwapChainWSI swapChain)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002133{
2134 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002135
2136 if (swapChainMap.find(swapChain) != swapChainMap.end()) {
2137 MT_SWAP_CHAIN_INFO* pInfo = swapChainMap[swapChain];
2138
David Pinedof5997ab2015-04-27 16:36:17 -06002139 if (pInfo->images.size() > 0) {
2140 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2141 it != pInfo->images.end(); it++) {
2142 clearObjectBinding(it->image);
2143 freeMemObjInfo(it->memory, true);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002144
David Pinedof5997ab2015-04-27 16:36:17 -06002145 MT_OBJ_INFO* pDelInfo = objectMap[it->image];
2146 delete pDelInfo;
2147 objectMap.erase(it->image);
2148 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002149 }
2150
2151 delete pInfo;
2152 swapChainMap.erase(swapChain);
2153 }
2154
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002155 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002156
2157 return nextTable.DestroySwapChainWSI(swapChain);
2158}
2159
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002160VK_LAYER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
2161 VkSwapChainWSI swapChain,
2162 VkSwapChainInfoTypeWSI infoType,
2163 size_t *pDataSize,
2164 void *pData)
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002165{
2166 VkResult result = nextTable.GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
2167
2168 if (infoType == VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI && result == VK_SUCCESS) {
2169 const size_t count = *pDataSize / sizeof(VkSwapChainImageInfoWSI);
2170 MT_SWAP_CHAIN_INFO *pInfo = swapChainMap[swapChain];
2171
2172 if (pInfo->images.empty()) {
2173 pInfo->images.resize(count);
2174 memcpy(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count);
2175
David Pinedof5997ab2015-04-27 16:36:17 -06002176 if (pInfo->images.size() > 0) {
2177 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2178 it != pInfo->images.end(); it++) {
2179 // Add image object, then insert the new Mem Object and then bind it to created image
2180 addObjectInfo(it->image, VK_STRUCTURE_TYPE_MAX_ENUM, &pInfo->createInfo, sizeof(pInfo->createInfo), "persistent_image");
2181 addMemObjInfo(it->memory, NULL);
2182 if (VK_FALSE == updateObjectBinding(it->image, it->memory)) {
2183 char str[1024];
2184 sprintf(str, "In vkGetSwapChainInfoWSI(), unable to set image %p binding to mem obj %p", (void*)it->image, (void*)it->memory);
2185 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
2186 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002187 }
2188 }
2189 } else {
2190 const bool mismatch = (pInfo->images.size() != count ||
2191 memcmp(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count));
2192
2193 if (mismatch) {
2194 char str[1024];
2195 sprintf(str, "vkGetSwapChainInfoWSI(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI) returned mismatching data", swapChain);
Mike Stroyan230e6252015-04-17 12:36:38 -06002196 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 +08002197 }
2198 }
2199 }
2200
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002201 return result;
2202}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002203
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002204VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(
2205 VkPhysicalDevice gpu,
2206 const char *funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002207{
Jon Ashburn301c5f02015-04-06 10:58:22 -06002208 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wu706533e2015-01-05 13:18:57 +08002209
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002210 if (gpu == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002211 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002212 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002213 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07002214 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002215
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002216 if (!strcmp(funcName, "vkGetProcAddr"))
2217 return (void *) vkGetProcAddr;
2218 if (!strcmp(funcName, "vkCreateDevice"))
2219 return (void*) vkCreateDevice;
2220 if (!strcmp(funcName, "vkDestroyDevice"))
2221 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002222 if (!strcmp(funcName, "vkEnumerateLayers"))
2223 return (void*) vkEnumerateLayers;
2224 if (!strcmp(funcName, "vkQueueSubmit"))
2225 return (void*) vkQueueSubmit;
2226 if (!strcmp(funcName, "vkAllocMemory"))
2227 return (void*) vkAllocMemory;
2228 if (!strcmp(funcName, "vkFreeMemory"))
2229 return (void*) vkFreeMemory;
2230 if (!strcmp(funcName, "vkSetMemoryPriority"))
2231 return (void*) vkSetMemoryPriority;
2232 if (!strcmp(funcName, "vkMapMemory"))
2233 return (void*) vkMapMemory;
2234 if (!strcmp(funcName, "vkUnmapMemory"))
2235 return (void*) vkUnmapMemory;
2236 if (!strcmp(funcName, "vkPinSystemMemory"))
2237 return (void*) vkPinSystemMemory;
2238 if (!strcmp(funcName, "vkOpenSharedMemory"))
2239 return (void*) vkOpenSharedMemory;
2240 if (!strcmp(funcName, "vkOpenPeerMemory"))
2241 return (void*) vkOpenPeerMemory;
2242 if (!strcmp(funcName, "vkOpenPeerImage"))
2243 return (void*) vkOpenPeerImage;
2244 if (!strcmp(funcName, "vkDestroyObject"))
2245 return (void*) vkDestroyObject;
2246 if (!strcmp(funcName, "vkGetObjectInfo"))
2247 return (void*) vkGetObjectInfo;
Mark Lobodzinskicf26e072015-04-16 11:44:05 -05002248 if (!strcmp(funcName, "vkQueueBindObjectMemory"))
2249 return (void*) vkQueueBindObjectMemory;
Mike Stroyan230e6252015-04-17 12:36:38 -06002250 if (!strcmp(funcName, "vkQueueBindObjectMemoryRange"))
2251 return (void*) vkQueueBindObjectMemoryRange;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002252 if (!strcmp(funcName, "vkCreateFence"))
2253 return (void*) vkCreateFence;
2254 if (!strcmp(funcName, "vkGetFenceStatus"))
2255 return (void*) vkGetFenceStatus;
2256 if (!strcmp(funcName, "vkResetFences"))
2257 return (void*) vkResetFences;
2258 if (!strcmp(funcName, "vkWaitForFences"))
2259 return (void*) vkWaitForFences;
2260 if (!strcmp(funcName, "vkQueueWaitIdle"))
2261 return (void*) vkQueueWaitIdle;
2262 if (!strcmp(funcName, "vkDeviceWaitIdle"))
2263 return (void*) vkDeviceWaitIdle;
2264 if (!strcmp(funcName, "vkCreateEvent"))
2265 return (void*) vkCreateEvent;
2266 if (!strcmp(funcName, "vkCreateQueryPool"))
2267 return (void*) vkCreateQueryPool;
2268 if (!strcmp(funcName, "vkCreateBuffer"))
2269 return (void*) vkCreateBuffer;
2270 if (!strcmp(funcName, "vkCreateBufferView"))
2271 return (void*) vkCreateBufferView;
2272 if (!strcmp(funcName, "vkCreateImage"))
2273 return (void*) vkCreateImage;
2274 if (!strcmp(funcName, "vkCreateImageView"))
2275 return (void*) vkCreateImageView;
2276 if (!strcmp(funcName, "vkCreateColorAttachmentView"))
2277 return (void*) vkCreateColorAttachmentView;
2278 if (!strcmp(funcName, "vkCreateDepthStencilView"))
2279 return (void*) vkCreateDepthStencilView;
2280 if (!strcmp(funcName, "vkCreateShader"))
2281 return (void*) vkCreateShader;
2282 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2283 return (void*) vkCreateGraphicsPipeline;
2284 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2285 return (void*) vkCreateGraphicsPipelineDerivative;
2286 if (!strcmp(funcName, "vkCreateComputePipeline"))
2287 return (void*) vkCreateComputePipeline;
2288 if (!strcmp(funcName, "vkCreateSampler"))
2289 return (void*) vkCreateSampler;
2290 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2291 return (void*) vkCreateDynamicViewportState;
2292 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2293 return (void*) vkCreateDynamicRasterState;
2294 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2295 return (void*) vkCreateDynamicColorBlendState;
2296 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2297 return (void*) vkCreateDynamicDepthStencilState;
2298 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2299 return (void*) vkCreateCommandBuffer;
2300 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2301 return (void*) vkBeginCommandBuffer;
2302 if (!strcmp(funcName, "vkEndCommandBuffer"))
2303 return (void*) vkEndCommandBuffer;
2304 if (!strcmp(funcName, "vkResetCommandBuffer"))
2305 return (void*) vkResetCommandBuffer;
2306 if (!strcmp(funcName, "vkCmdBindPipeline"))
2307 return (void*) vkCmdBindPipeline;
2308 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2309 return (void*) vkCmdBindDynamicStateObject;
2310 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2311 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002312 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2313 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002314 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2315 return (void*) vkCmdBindIndexBuffer;
2316 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2317 return (void*) vkCmdDrawIndirect;
2318 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2319 return (void*) vkCmdDrawIndexedIndirect;
2320 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2321 return (void*) vkCmdDispatchIndirect;
2322 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2323 return (void*) vkCmdCopyBuffer;
2324 if (!strcmp(funcName, "vkCmdCopyImage"))
2325 return (void*) vkCmdCopyImage;
2326 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2327 return (void*) vkCmdCopyBufferToImage;
2328 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2329 return (void*) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002330 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2331 return (void*) vkCmdUpdateBuffer;
2332 if (!strcmp(funcName, "vkCmdFillBuffer"))
2333 return (void*) vkCmdFillBuffer;
2334 if (!strcmp(funcName, "vkCmdClearColorImage"))
2335 return (void*) vkCmdClearColorImage;
2336 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2337 return (void*) vkCmdClearDepthStencil;
2338 if (!strcmp(funcName, "vkCmdResolveImage"))
2339 return (void*) vkCmdResolveImage;
2340 if (!strcmp(funcName, "vkCmdBeginQuery"))
2341 return (void*) vkCmdBeginQuery;
2342 if (!strcmp(funcName, "vkCmdEndQuery"))
2343 return (void*) vkCmdEndQuery;
2344 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2345 return (void*) vkCmdResetQueryPool;
2346 if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
2347 return (void*) vkDbgRegisterMsgCallback;
2348 if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
2349 return (void*) vkDbgUnregisterMsgCallback;
2350 if (!strcmp(funcName, "vkGetDeviceQueue"))
2351 return (void*) vkGetDeviceQueue;
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002352 if (!strcmp(funcName, "vkCreateSwapChainWSI"))
2353 return (void*) vkCreateSwapChainWSI;
2354 if (!strcmp(funcName, "vkDestroySwapChainWSI"))
2355 return (void*) vkDestroySwapChainWSI;
2356 if (!strcmp(funcName, "vkGetSwapChainInfoWSI"))
2357 return (void*) vkGetSwapChainInfoWSI;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002358 else {
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002359 if (gpuw->pGPA == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002360 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002361 }
Tony Barbour8205d902015-04-16 15:59:00 -06002362 return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002363 }
2364}