blob: bce0cb80b13c23f90c2e9b60adedf87628202609 [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 Stroyan82598892015-05-18 16:33:03 -0600216 for (map<uint64_t, MT_FENCE_INFO*>::iterator ii=fenceMap.begin(); !found && ii!=fenceMap.end();) {
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 {
Mike Stroyan82598892015-05-18 16:33:03 -0600224 // Update iterator before deleting item it referred to
225 uint64_t fenceId = (*ii).first;
226 ++ii;
227 deleteFenceInfo(fenceId);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500228 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500229 // Update fence state in fenceCreateInfo structure
230 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
231 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500232 pObjectInfo->create_info.fence_create_info.flags =
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600233 static_cast<VkFenceCreateFlags>(
234 pObjectInfo->create_info.fence_create_info.flags | VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500235 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500236 }
237 }
238}
239
240// Utility function that determines if a fenceId has been retired yet
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600241static bool32_t fenceRetired(
242 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500243{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600244 bool32_t result = VK_FALSE;
Courtney Goeltzenleuchter60edc352015-04-15 14:10:51 -0600245 if (fenceMap.find(fenceId) != fenceMap.end()) {
246 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500247 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
Mark Lobodzinski91a1ec52015-04-02 08:52:53 -0500248 if (fenceId <= pQueueInfo->lastRetiredId)
249 {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600250 result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500251 }
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500252 } else { // If not in list, fence has been retired and deleted
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600253 result = VK_TRUE;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500254 }
255 return result;
256}
257
258// Return the fence associated with a fenceId
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600259static VkFence getFenceFromId(
260 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500261{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600262 VkFence fence = NULL;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500263 if (fenceId != 0) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500264 // Search for an item with this fenceId
265 if (fenceMap.find(fenceId) != fenceMap.end()) {
266 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
267 if (pFenceInfo != NULL) {
268 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
269 if (fenceId > pQueueInfo->lastRetiredId) {
270 fence = pFenceInfo->fence;
271 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500272 }
273 }
274 }
275 return fence;
276}
277
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500278// Helper routine that updates the fence list for a specific queue to all-retired
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600279static void retireQueueFences(
280 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500281{
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600282 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
283 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
284 // Set Queue's lastRetired to lastSubmitted, free items in queue's fence list
285 map<uint64_t, MT_FENCE_INFO*>::iterator it = fenceMap.begin();
286 map<uint64_t, MT_FENCE_INFO*>::iterator temp;
David Pinedof5997ab2015-04-27 16:36:17 -0600287 while (fenceMap.size() > 0 && it != fenceMap.end()) {
Tobin Ehlisbfc55032015-04-15 14:25:02 -0600288 if ((((*it).second) != NULL) && ((*it).second)->queue == queue) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600289 temp = it;
290 ++temp;
291 deleteFenceInfo((*it).first);
292 it = temp;
293 } else {
294 ++it;
295 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500296 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700297}
298
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500299// Helper routine that updates fence list for all queues to all-retired
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600300static void retireDeviceFences(
301 VkDevice device)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500302{
303 // Process each queue for device
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600304 // TODO: Add multiple device support
David Pinedof5997ab2015-04-27 16:36:17 -0600305 if (queueMap.size() <= 0)
306 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600307 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500308 retireQueueFences((*ii).first);
309 }
310}
311
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500312// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700313// Calls to this function should be wrapped in mutex
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600314static MT_MEM_OBJ_INFO* getMemObjInfo(
315 const VkDeviceMemory mem)
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700316{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500317 MT_MEM_OBJ_INFO* pMemObjInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500318
319 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500320 pMemObjInfo = memObjMap[mem];
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600321 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500322 return pMemObjInfo;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700323}
324
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600325static void addMemObjInfo(
326 const VkDeviceMemory mem,
327 const VkMemoryAllocInfo *pAllocInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700328{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500329 MT_MEM_OBJ_INFO* pInfo = new MT_MEM_OBJ_INFO;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600330 pInfo->refCount = 0;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600331 memset(&pInfo->allocInfo, 0, sizeof(VkMemoryAllocInfo));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500332
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800333 if (pAllocInfo) { // MEM alloc created by vkCreateSwapChainWSI() doesn't have alloc info struct
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600334 memcpy(&pInfo->allocInfo, pAllocInfo, sizeof(VkMemoryAllocInfo));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500335 // TODO: Update for real hardware, actually process allocation info structures
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500336 pInfo->allocInfo.pNext = NULL;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700337 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500338 pInfo->mem = mem;
339 memObjMap[mem] = pInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700340}
341
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500342// Find CB Info and add mem binding to list container
343// Find Mem Obj Info and add CB binding to list container
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600344static bool32_t updateCBBinding(
345 const VkCmdBuffer cb,
346 const VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700347{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600348 bool32_t result = VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700349 // First update CB binding in MemObj mini CB list
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500350 MT_MEM_OBJ_INFO* pMemInfo = getMemObjInfo(mem);
351 if (!pMemInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700352 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600353 sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that mem obj.\n "
354 "Was it correctly allocated? Did it already get freed?", mem, cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600355 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
356 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600357 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500358 // Search for cmd buffer object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600359 bool32_t found = VK_FALSE;
David Pinedof5997ab2015-04-27 16:36:17 -0600360 if (pMemInfo->pCmdBufferBindings.size() > 0) {
361 for (list<VkCmdBuffer>::iterator it = pMemInfo->pCmdBufferBindings.begin(); it != pMemInfo->pCmdBufferBindings.end(); ++it) {
362 if ((*it) == cb) {
363 found = VK_TRUE;
364 break;
365 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500366 }
367 }
368 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600369 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500370 pMemInfo->pCmdBufferBindings.push_front(cb);
371 pMemInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500372 }
373
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500374 // Now update CBInfo's Mem binding list
375 MT_CB_INFO* pCBInfo = getCBInfo(cb);
376 if (!pCBInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500377 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500378 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 -0600379 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
380 result = VK_FALSE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500381 } else {
382 // Search for memory object in cmd buffer's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600383 bool32_t found = VK_FALSE;
David Pinedof5997ab2015-04-27 16:36:17 -0600384 if (pCBInfo->pMemObjList.size() > 0) {
385 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
386 if ((*it) == mem) {
387 found = VK_TRUE;
388 break;
389 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500390 }
391 }
392 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600393 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500394 pCBInfo->pMemObjList.push_front(mem);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600395 }
396 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700397 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600398 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700399}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600400
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700401// Clear the CB Binding for mem
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700402// Calls to this function should be wrapped in mutex
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600403static void clearCBBinding(
404 const VkCmdBuffer cb,
405 const VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700406{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500407 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500408 // TODO : Having this check is not ideal, really if memInfo was deleted,
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700409 // its CB bindings should be cleared and then freeCBBindings wouldn't call
410 // us here with stale mem objs
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500411 if (pInfo) {
412 pInfo->pCmdBufferBindings.remove(cb);
413 pInfo->refCount--;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700414 }
415}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600416
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700417// Free bindings related to CB
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600418static bool32_t freeCBBindings(
419 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700420{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600421 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500422 MT_CB_INFO* pCBInfo = getCBInfo(cb);
423 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700424 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500425 sprintf(str, "Unable to find global CB info %p for deletion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600426 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
427 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600428 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500429 if (!fenceRetired(pCBInfo->fenceId)) {
430 deleteFenceInfo(pCBInfo->fenceId);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600431 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500432
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600433 if (pCBInfo->pMemObjList.size() > 0) {
434 list<VkDeviceMemory> mem_obj_list = pCBInfo->pMemObjList;
435 for (list<VkDeviceMemory>::iterator it=mem_obj_list.begin(); it!=mem_obj_list.end(); ++it) {
David Pinedof5997ab2015-04-27 16:36:17 -0600436 clearCBBinding(cb, (*it));
437 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600438 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500439 pCBInfo->pMemObjList.clear();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700440 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600441 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700442}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600443
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500444// Delete CBInfo from list along with all of it's mini MemObjInfo
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500445// and also clear mem references to CB
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700446// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600447static bool32_t deleteCBInfo(
448 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700449{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600450 bool32_t result = VK_TRUE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600451 result = freeCBBindings(cb);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500452 // Delete the CBInfo info
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600453 if (result == VK_TRUE) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500454 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500455 MT_CB_INFO* pDelInfo = cbMap[cb];
456 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500457 cbMap.erase(cb);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600458 }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700459 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600460 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700461}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600462
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700463// Delete the entire CB list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600464static bool32_t deleteCBInfoList(
465 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700466{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600467 bool32_t result = VK_TRUE;
David Pinedof5997ab2015-04-27 16:36:17 -0600468 if (cbMap.size() <= 0)
469 return result;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600470 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500471 freeCBBindings((*ii).first);
472 delete (*ii).second;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700473 }
474 return result;
475}
476
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500477// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600478static void reportMemReferencesAndCleanUp(
479 MT_MEM_OBJ_INFO* pMemObjInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700480{
Tony Barboura938abb2015-04-22 11:36:22 -0600481 size_t cmdBufRefCount = pMemObjInfo->pCmdBufferBindings.size();
482 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500483
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500484 if ((pMemObjInfo->pCmdBufferBindings.size() + pMemObjInfo->pObjBindings.size()) != 0) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700485 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600486 sprintf(str, "Attempting to free memory object %p which still contains %lu references",
487 pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500488 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700489 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500490
David Pinedof5997ab2015-04-27 16:36:17 -0600491 if (cmdBufRefCount > 0 && pMemObjInfo->pCmdBufferBindings.size() > 0) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500492 for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
493 char str[1024];
494 sprintf(str, "Command Buffer %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
495 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
496 }
497 // Clear the list of hanging references
498 pMemObjInfo->pCmdBufferBindings.clear();
499 }
500
David Pinedof5997ab2015-04-27 16:36:17 -0600501 if (objRefCount > 0 && pMemObjInfo->pObjBindings.size() > 0) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500502 for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
503 char str[1024];
504 sprintf(str, "VK Object %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
505 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
506 }
507 // Clear the list of hanging references
508 pMemObjInfo->pObjBindings.clear();
509 }
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500510
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700511}
512
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600513static void deleteMemObjInfo(
514 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700515{
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500516 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500517 MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
518 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500519 memObjMap.erase(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700520 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500521 else {
522 char str[1024];
523 sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
524 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
525 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700526}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500527
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700528// Check if fence for given CB is completed
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600529static bool32_t checkCBCompleted(
530 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700531{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600532 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500533 MT_CB_INFO* pCBInfo = getCBInfo(cb);
534 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700535 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500536 sprintf(str, "Unable to find global CB info %p to check for completion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600537 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
538 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600539 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500540 if (!fenceRetired(pCBInfo->fenceId)) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600541 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600542 sprintf(str, "FenceId %" PRIx64", fence %p for CB %p has not been checked for completion",
543 pCBInfo->fenceId, getFenceFromId(pCBInfo->fenceId), cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600544 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
545 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600546 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700547 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600548 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700549}
550
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600551static bool32_t freeMemObjInfo(
552 VkDeviceMemory mem,
553 bool internal)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700554{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600555 bool32_t result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500556 // Parse global list to find info w/ mem
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500557 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
558 if (!pInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700559 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600560 sprintf(str, "Couldn't find mem info object for %p\n Was %p never allocated or previously freed?",
561 (void*)mem, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600562 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
563 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600564 } else {
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -0600565 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600566 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600567 sprintf(str, "Attempting to free memory associated with a Persistent Image, %p, "
568 "this should not be explicitly freed\n", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600569 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
570 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600571 } else {
572 // Clear any CB bindings for completed CBs
573 // TODO : Is there a better place to do this?
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500574
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600575 list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin();
576 list<VkCmdBuffer>::iterator temp;
David Pinedof5997ab2015-04-27 16:36:17 -0600577 while (pInfo->pCmdBufferBindings.size() > 0 && it != pInfo->pCmdBufferBindings.end()) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600578 if (VK_TRUE == checkCBCompleted(*it)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500579 temp = it;
580 ++temp;
581 freeCBBindings(*it);
582 it = temp;
583 } else {
584 ++it;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600585 }
586 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500587
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600588 // Now verify that no references to this mem obj remain
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500589 if (0 != pInfo->refCount) {
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);
Mark Lobodzinski23182612015-05-29 09:32:35 -0500614 layerCbMsg(VK_DBG_MSG_UNKNOWN, 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 Lobodzinski5f25be42015-05-14 15:08:13 -0500671 return VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600672 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500673 // Search for object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600674 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600675 if (pInfo->pObjBindings.size() > 0) {
676 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
677 if ((*it) == object) {
678 found = VK_TRUE;
679 break;
680 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600681 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600682 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500683 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600684 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500685 pInfo->pObjBindings.push_front(object);
686 pInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500687 }
688
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500689 if (pObjInfo->pMemObjInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500690 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500691 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 -0600692 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500693 }
694 // For image objects, make sure default memory state is correctly set
695 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600696 if (VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pObjInfo->sType) {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600697 if (pObjInfo->create_info.image_create_info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
698 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500699 // TODO:: More memory state transition stuff.
700 }
701 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500702 pObjInfo->pMemObjInfo = pInfo;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700703 }
704 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600705 return VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700706}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600707
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700708// Print details of global Obj tracking list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600709static void printObjList(
710 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700711{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500712 MT_OBJ_INFO* pInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500713 char str[1024];
Mike Stroyan4879df32015-05-18 16:29:39 -0600714 if (g_reportingLevel > VK_DBG_LAYER_LEVEL_INFO) {
715 return;
716 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500717 sprintf(str, "Details of Object list of size %lu elements", objectMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600718 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600719 if (objectMap.size() <= 0)
720 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600721 for (map<VkObject, MT_OBJ_INFO*>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500722 pInfo = (*ii).second;
723 sprintf(str, " ObjInfo %p has object %p, pMemObjInfo %p", pInfo, pInfo->object, pInfo->pMemObjInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600724 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700725 }
726}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600727
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700728// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600729static VkDeviceMemory getMemBindingFromObject(
730 const VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700731{
Tony Barbour8205d902015-04-16 15:59:00 -0600732 VkDeviceMemory mem = NULL;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500733 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
734 if (pObjInfo) {
735 if (pObjInfo->pMemObjInfo) {
736 mem = pObjInfo->pMemObjInfo->mem;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600737 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700738 char str[1024];
739 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600740 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700741 printObjList();
742 }
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600743 } else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700744 char str[1024];
745 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 -0600746 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700747 printObjList();
748 }
749 return mem;
750}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500751
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500752// Print details of MemObjInfo list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600753static void printMemList(
754 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700755{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500756 MT_MEM_OBJ_INFO* pInfo = NULL;
Tobin Ehlis62086412014-11-19 16:19:28 -0700757 // Just printing each msg individually for now, may want to package these into single large print
758 char str[1024];
Mike Stroyan4879df32015-05-18 16:29:39 -0600759 if (g_reportingLevel > VK_DBG_LAYER_LEVEL_INFO) {
760 return;
761 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500762 sprintf(str, "MEM INFO : Details of Memory Object list of size %lu elements", memObjMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600763 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500764
David Pinedof5997ab2015-04-27 16:36:17 -0600765 if (memObjMap.size() <= 0)
766 return;
767
Tony Barbour8205d902015-04-16 15:59:00 -0600768 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500769 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500770
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500771 sprintf(str, " ===MemObjInfo at %p===", (void*)pInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600772 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500773 sprintf(str, " Mem object: %p", (void*)pInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600774 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500775 sprintf(str, " Ref Count: %u", pInfo->refCount);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600776 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500777 if (0 != pInfo->allocInfo.allocationSize) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600778 string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "{MEM}INFO : ");
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500779 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600780 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500781 } else {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800782 sprintf(str, " Mem Alloc info is NULL (alloc done by vkCreateSwapChainWSI())");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600783 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500784 }
785
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600786 sprintf(str, " VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
787 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600788 if (pInfo->pObjBindings.size() > 0) {
789 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
790 sprintf(str, " VK OBJECT %p", (*it));
791 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
792 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500793 }
794
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600795 sprintf(str, " VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
796 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
David Pinedof5997ab2015-04-27 16:36:17 -0600797 if (pInfo->pCmdBufferBindings.size() > 0)
798 {
799 for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
800 sprintf(str, " VK CB %p", (*it));
801 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
802 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700803 }
804 }
805}
806
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600807static void printCBList(
808 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700809{
Tobin Ehlis62086412014-11-19 16:19:28 -0700810 char str[1024] = {0};
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500811 MT_CB_INFO* pCBInfo = NULL;
Mike Stroyan4879df32015-05-18 16:29:39 -0600812 if (g_reportingLevel > VK_DBG_LAYER_LEVEL_INFO) {
813 return;
814 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500815 sprintf(str, "Details of CB list of size %lu elements", cbMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600816 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500817
David Pinedof5997ab2015-04-27 16:36:17 -0600818 if (cbMap.size() <= 0)
819 return;
820
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600821 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500822 pCBInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500823
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500824 sprintf(str, " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %p",
825 (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
826 (void*)getFenceFromId(pCBInfo->fenceId));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600827 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500828
David Pinedof5997ab2015-04-27 16:36:17 -0600829 if (pCBInfo->pMemObjList.size() <= 0)
830 continue;
Tony Barbour8205d902015-04-16 15:59:00 -0600831 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500832 sprintf(str, " Mem obj %p", (*it));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600833 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700834 }
835 }
836}
837
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600838static void initMemTracker(
839 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700840{
Jon Ashburnf57ea372014-12-22 13:24:15 -0700841 const char *strOpt;
842 // initialize MemTracker options
Ian Elliott7d0b5d22015-03-06 13:50:05 -0700843 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
844 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -0700845
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600846 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburnf57ea372014-12-22 13:24:15 -0700847 {
848 strOpt = getLayerOption("MemTrackerLogFilename");
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600849 if (strOpt) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700850 g_logFile = fopen(strOpt, "w");
Jon Ashburnf57ea372014-12-22 13:24:15 -0700851 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600852 if (g_logFile == NULL) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700853 g_logFile = stdout;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600854 }
Jon Ashburnf57ea372014-12-22 13:24:15 -0700855 }
856
857 // initialize Layer dispatch table
858 // TODO handle multiple GPUs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600859 PFN_vkGetProcAddr fpNextGPA;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700860 fpNextGPA = pCurObj->pGPA;
861 assert(fpNextGPA);
862
Tony Barbour8205d902015-04-16 15:59:00 -0600863 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800864
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600865 if (!globalLockInitialized)
866 {
867 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600868 // suggestion is to call this during vkCreateInstance(), and then we
869 // can clean it up during vkDestroyInstance(). However, that requires
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600870 // that the layer have per-instance locks. We need to come back and
871 // address this soon.
872 loader_platform_thread_create_mutex(&globalLock);
873 globalLockInitialized = 1;
874 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700875}
876
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600877VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
878 VkPhysicalDevice gpu,
879 const VkDeviceCreateInfo *pCreateInfo,
880 VkDevice *pDevice)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700881{
Jon Ashburn630e44f2015-04-08 21:33:34 -0600882 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700883 loader_platform_thread_once(&g_initOnce, initMemTracker);
Jon Ashburn630e44f2015-04-08 21:33:34 -0600884 VkResult result = nextTable.CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700885 // Save off device in case we need it to create Fences
886 globalDevice = *pDevice;
887 return result;
888}
889
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600890VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(
891 VkDevice device)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700892{
Tobin Ehlis62086412014-11-19 16:19:28 -0700893 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600894 sprintf(str, "Printing List details prior to vkDestroyDevice()");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600895 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600896 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700897 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500898 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700899 printObjList();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600900 if (VK_FALSE == deleteCBInfoList()) {
901 sprintf(str, "Issue deleting global CB list in vkDestroyDevice()");
902 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -0700903 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700904 // Report any memory leaks
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500905 MT_MEM_OBJ_INFO* pInfo = NULL;
David Pinedof5997ab2015-04-27 16:36:17 -0600906 if (memObjMap.size() > 0) {
907 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
908 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500909
David Pinedof5997ab2015-04-27 16:36:17 -0600910 if (pInfo->allocInfo.allocationSize != 0) {
911 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling "
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600912 "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
David Pinedof5997ab2015-04-27 16:36:17 -0600913 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
914 }
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600915 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700916 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500917
918 // Queues persist until device is destroyed
919 deleteQueueInfoList();
920
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600921 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600922 VkResult result = nextTable.DestroyDevice(device);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700923 return result;
924}
925
Jon Ashburneb2728b2015-04-10 14:33:07 -0600926struct extProps {
927 uint32_t version;
928 const char * const name;
929};
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600930#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2
Jon Ashburneb2728b2015-04-10 14:33:07 -0600931static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
932 // TODO what is the version?
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600933 0x10, "MemTracker",
934 0x10, "Validation"
Jon Ashburneb2728b2015-04-10 14:33:07 -0600935};
936
937VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600938 VkExtensionInfoType infoType,
939 uint32_t extensionIndex,
940 size_t *pDataSize,
941 void *pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600942{
Mark Lobodzinski5f25be42015-05-14 15:08:13 -0500943 // This entrypoint is NOT going to init its own dispatch table since loader calls here early
Jon Ashburneb2728b2015-04-10 14:33:07 -0600944 VkExtensionProperties *ext_props;
945 uint32_t *count;
946
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600947 if (pDataSize == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600948 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600949 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600950
951 switch (infoType) {
952 case VK_EXTENSION_INFO_TYPE_COUNT:
953 *pDataSize = sizeof(uint32_t);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600954 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600955 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600956 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600957 count = (uint32_t *) pData;
958 *count = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE;
959 break;
960 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
961 *pDataSize = sizeof(VkExtensionProperties);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600962 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600963 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600964 }
965 if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600966 return VK_ERROR_INVALID_VALUE;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600967 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600968 ext_props = (VkExtensionProperties *) pData;
969 ext_props->version = mtExts[extensionIndex].version;
970 strncpy(ext_props->extName, mtExts[extensionIndex].name,
971 VK_MAX_EXTENSION_NAME);
972 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
973 break;
974 default:
975 return VK_ERROR_INVALID_VALUE;
976 };
977
978 return VK_SUCCESS;
979}
980
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600981VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(
982 VkPhysicalDevice gpu,
983 size_t maxStringSize,
984 size_t *pLayerCount,
985 char* const *pOutLayers,
986 void *pReserved)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700987{
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600988 if (gpu != NULL)
Jon Ashburn451c16f2014-11-25 11:08:42 -0700989 {
Jon Ashburn630e44f2015-04-08 21:33:34 -0600990 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700991 loader_platform_thread_once(&g_initOnce, initMemTracker);
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -0600992 VkResult result = nextTable.EnumerateLayers(gpu,
993 maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn451c16f2014-11-25 11:08:42 -0700994 return result;
995 } else
996 {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600997 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600998 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600999 }
Jon Ashburn451c16f2014-11-25 11:08:42 -07001000 // This layer compatible with all GPUs
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001001 *pLayerCount = 1;
Chia-I Wua837c522014-12-16 10:47:33 +08001002 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001003 return VK_SUCCESS;
Jon Ashburn451c16f2014-11-25 11:08:42 -07001004 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001005}
1006
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001007VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
1008 VkDevice device,
1009 uint32_t queueNodeIndex,
1010 uint32_t queueIndex,
1011 VkQueue *pQueue)
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001012{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001013 VkResult result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001014 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001015 loader_platform_thread_lock_mutex(&globalLock);
1016 addQueueInfo(*pQueue);
1017 loader_platform_thread_unlock_mutex(&globalLock);
1018 }
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001019 return result;
1020}
1021
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001022VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(
1023 VkQueue queue,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001024 uint32_t cmdBufferCount,
1025 const VkCmdBuffer *pCmdBuffers,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001026 VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001027{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001028 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001029 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001030 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001031 uint64_t fenceId = addFenceInfo(fence, queue);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001032
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001033 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001034 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001035 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001036 pCBInfo = getCBInfo(pCmdBuffers[i]);
1037 pCBInfo->fenceId = fenceId;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001038 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001039
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001040 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyanc6d71832015-05-18 16:31:44 -06001041 VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
Courtney Goeltzenleuchtercfedf362015-04-02 13:39:07 -06001042 return result;
1043}
1044
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001045VK_LAYER_EXPORT VkResult VKAPI vkAllocMemory(
1046 VkDevice device,
1047 const VkMemoryAllocInfo *pAllocInfo,
1048 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001049{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001050 VkResult result = nextTable.AllocMemory(device, pAllocInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001051 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001052 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001053 addMemObjInfo(*pMem, pAllocInfo);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001054 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001055 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001056 return result;
1057}
1058
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001059VK_LAYER_EXPORT VkResult VKAPI vkFreeMemory(
1060 VkDevice device,
1061 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001062{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001063 /* From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed. Before
Tobin Ehlisa747e682014-11-25 14:47:20 -07001064 * freeing a memory object, an application must ensure the memory object is unbound from
1065 * all API objects referencing it and that it is not referenced by any queued command buffers
1066 */
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001067 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001068 bool32_t noerror = freeMemObjInfo(mem, false);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001069 printMemList();
1070 printObjList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001071 printCBList();
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001072 // Output an warning message for proper error/warning handling
1073 if (noerror == VK_FALSE) {
1074 char str[1024];
1075 sprintf(str, "Freeing memory object while it still has references: mem obj %p", (void*)mem);
1076 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
1077 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001078 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001079 VkResult result = nextTable.FreeMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001080 return result;
1081}
1082
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001083VK_LAYER_EXPORT VkResult VKAPI vkSetMemoryPriority(
1084 VkDevice device,
1085 VkDeviceMemory mem,
1086 VkMemoryPriority priority)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001087{
1088 // TODO : Update tracking for this alloc
1089 // Make sure memory is not pinned, which can't have priority set
Mike Stroyan230e6252015-04-17 12:36:38 -06001090 VkResult result = nextTable.SetMemoryPriority(device, mem, priority);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001091 return result;
1092}
1093
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001094VK_LAYER_EXPORT VkResult VKAPI vkMapMemory(
1095 VkDevice device,
1096 VkDeviceMemory mem,
1097 VkDeviceSize offset,
1098 VkDeviceSize size,
1099 VkFlags flags,
1100 void **ppData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001101{
1102 // TODO : Track when memory is mapped
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001103 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001104 MT_MEM_OBJ_INFO *pMemObj = getMemObjInfo(mem);
Tony Barbour8205d902015-04-16 15:59:00 -06001105 if ((pMemObj->allocInfo.memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001106 char str[1024];
Mark Lobodzinski5f25be42015-05-14 15:08:13 -05001107 sprintf(str, "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj %p", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001108 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001109 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001110 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001111 VkResult result = nextTable.MapMemory(device, mem, offset, size, flags, ppData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001112 return result;
1113}
1114
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001115VK_LAYER_EXPORT VkResult VKAPI vkUnmapMemory(
1116 VkDevice device,
1117 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001118{
1119 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
1120 // Make sure that memory was ever mapped to begin with
Mike Stroyan230e6252015-04-17 12:36:38 -06001121 VkResult result = nextTable.UnmapMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001122 return result;
1123}
1124
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001125VK_LAYER_EXPORT VkResult VKAPI vkPinSystemMemory(
1126 VkDevice device,
1127 const void *pSysMem,
1128 size_t memSize,
1129 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001130{
1131 // TODO : Track this
1132 // Verify that memory is actually pinnable
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001133 VkResult result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001134 return result;
1135}
1136
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001137VK_LAYER_EXPORT VkResult VKAPI vkOpenSharedMemory(
1138 VkDevice device,
1139 const VkMemoryOpenInfo *pOpenInfo,
1140 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001141{
1142 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001143 VkResult result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001144 return result;
1145}
1146
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001147VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerMemory(
1148 VkDevice device,
1149 const VkPeerMemoryOpenInfo *pOpenInfo,
1150 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001151{
1152 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001153 VkResult result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001154 return result;
1155}
1156
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001157VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerImage(
1158 VkDevice device,
1159 const VkPeerImageOpenInfo *pOpenInfo,
1160 VkImage *pImage,
1161 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001162{
1163 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001164 VkResult result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001165 return result;
1166}
1167
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001168VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(
1169 VkDevice device,
1170 VkObjectType objType,
1171 VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001172{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001173 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001174
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001175 // First check if this is a CmdBuffer
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001176 if (NULL != getCBInfo((VkCmdBuffer)object)) {
1177 deleteCBInfo((VkCmdBuffer)object);
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001178 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001179
1180 if (objectMap.find(object) != objectMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001181 MT_OBJ_INFO* pDelInfo = objectMap[object];
1182 if (pDelInfo->pMemObjInfo) {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001183 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001184 if (0 == pDelInfo->pMemObjInfo->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
Tony Barbour8205d902015-04-16 15:59:00 -06001185 VkDeviceMemory memToFree = pDelInfo->pMemObjInfo->mem;
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001186 clearObjectBinding(object);
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -06001187 freeMemObjInfo(memToFree, true);
1188 }
1189 else {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001190 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001191 sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding "
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001192 "by calling vkBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)",
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001193 object, (void*)pDelInfo->pMemObjInfo->mem, object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001194 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001195 // From the spec : If an object has previous memory binding, it is required to unbind memory
1196 // from an API object before it is destroyed.
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001197 clearObjectBinding(object);
1198 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001199 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001200 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001201 objectMap.erase(object);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001202 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001203
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001204 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001205 VkResult result = nextTable.DestroyObject(device, objType, object);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001206 return result;
1207}
1208
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001209VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo(
1210 VkDevice device,
1211 VkObjectType objType,
1212 VkObject object,
1213 VkObjectInfoType infoType,
1214 size_t *pDataSize,
1215 void *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001216{
1217 // TODO : What to track here?
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001218 // Could potentially save returned mem requirements and validate values passed into BindObjectMemory for this object
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001219 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues,
1220 // command buffers, shaders and memory objects.
Mike Stroyan230e6252015-04-17 12:36:38 -06001221 VkResult result = nextTable.GetObjectInfo(device, objType, object, infoType, pDataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001222 return result;
1223}
1224
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001225VK_LAYER_EXPORT VkResult VKAPI vkBindObjectMemory(
1226 VkDevice device,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001227 VkObjectType objType,
1228 VkObject object,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001229 VkDeviceMemory mem,
1230 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001231{
Mark Lobodzinski23182612015-05-29 09:32:35 -05001232 VkResult result = nextTable.BindObjectMemory(device, objType, object, mem, offset);
Mike Stroyan230e6252015-04-17 12:36:38 -06001233 loader_platform_thread_lock_mutex(&globalLock);
1234 // Track objects tied to memory
1235 if (VK_FALSE == updateObjectBinding(object, mem)) {
1236 char str[1024];
1237 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1238 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1239 }
1240 printObjList();
1241 printMemList();
1242 loader_platform_thread_unlock_mutex(&globalLock);
1243 return result;
1244}
1245
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001246VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001247 VkQueue queue,
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001248 VkBuffer buffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001249 VkDeviceSize rangeOffset,
1250 VkDeviceSize rangeSize,
1251 VkDeviceMemory mem,
1252 VkDeviceSize memOffset)
Mike Stroyan230e6252015-04-17 12:36:38 -06001253{
Mark Lobodzinski23182612015-05-29 09:32:35 -05001254 VkResult result = nextTable.QueueBindSparseBufferMemory(queue, buffer, rangeOffset, rangeSize, mem, memOffset);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001255 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001256 // Track objects tied to memory
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001257 if (VK_FALSE == updateObjectBinding(buffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001258 char str[1024];
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001259 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)buffer, (void*)mem);
1260 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, buffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001261 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001262 printObjList();
1263 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001264 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001265 return result;
1266}
1267
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001268VK_LAYER_EXPORT VkResult VKAPI vkCreateFence(
1269 VkDevice device,
1270 const VkFenceCreateInfo *pCreateInfo,
1271 VkFence *pFence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001272{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001273 VkResult result = nextTable.CreateFence(device, pCreateInfo, pFence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001274 if (VK_SUCCESS == result) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001275 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001276 addObjectInfo(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(VkFenceCreateInfo), "fence");
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001277 loader_platform_thread_unlock_mutex(&globalLock);
1278 }
1279 return result;
1280}
1281
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001282VK_LAYER_EXPORT VkResult VKAPI vkResetFences(
1283 VkDevice device,
1284 uint32_t fenceCount,
1285 VkFence *pFences)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001286{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001287 VkResult result = nextTable.ResetFences(device, fenceCount, pFences);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001288 if (VK_SUCCESS == result) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001289 loader_platform_thread_lock_mutex(&globalLock);
1290 // Reset fence state in fenceCreateInfo structure
1291 for (uint32_t i = 0; i < fenceCount; i++) {
1292 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1293 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001294 // Validate fences in SIGNALED state
Tobin Ehlisf29da382015-04-15 07:46:12 -06001295 if (!(pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001296 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001297 sprintf(str, "Fence %p submitted to VkResetFences in UNSIGNALED STATE", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001298 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
1299 result = VK_ERROR_INVALID_VALUE;
Mark Lobodzinski56945182015-04-09 13:46:09 -05001300 }
1301 else {
1302 pObjectInfo->create_info.fence_create_info.flags =
Tobin Ehlisf29da382015-04-15 07:46:12 -06001303 static_cast<VkFenceCreateFlags>(pObjectInfo->create_info.fence_create_info.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski56945182015-04-09 13:46:09 -05001304 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001305 }
1306 }
1307 loader_platform_thread_unlock_mutex(&globalLock);
1308 }
1309 return result;
1310}
1311
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001312VK_LAYER_EXPORT VkResult VKAPI vkGetFenceStatus(
1313 VkDevice device,
1314 VkFence fence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001315{
Mike Stroyan230e6252015-04-17 12:36:38 -06001316 VkResult result = nextTable.GetFenceStatus(device, fence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001317 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001318 loader_platform_thread_lock_mutex(&globalLock);
1319 updateFenceTracking(fence);
1320 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001321 }
1322 return result;
1323}
1324
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001325VK_LAYER_EXPORT VkResult VKAPI vkWaitForFences(
1326 VkDevice device,
1327 uint32_t fenceCount,
1328 const VkFence *pFences,
1329 bool32_t waitAll,
1330 uint64_t timeout)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001331{
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001332 // Verify fence status of submitted fences
1333 for(uint32_t i = 0; i < fenceCount; i++) {
1334 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1335 if (pObjectInfo != NULL) {
Tobin Ehlisf29da382015-04-15 07:46:12 -06001336 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001337 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001338 sprintf(str, "VkWaitForFences specified fence %p already in SIGNALED state.", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001339 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 -05001340 }
1341 }
1342 }
1343
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001344 VkResult result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001345 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001346
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001347 if (VK_SUCCESS == result) {
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001348 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001349 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001350 updateFenceTracking(pFences[i]);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001351 }
1352 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001353 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001354 loader_platform_thread_unlock_mutex(&globalLock);
1355 return result;
1356}
1357
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001358VK_LAYER_EXPORT VkResult VKAPI vkQueueWaitIdle(
1359 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001360{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001361 VkResult result = nextTable.QueueWaitIdle(queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001362 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001363 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001364 retireQueueFences(queue);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001365 loader_platform_thread_unlock_mutex(&globalLock);
1366 }
1367 return result;
1368}
1369
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001370VK_LAYER_EXPORT VkResult VKAPI vkDeviceWaitIdle(
1371 VkDevice device)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001372{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001373 VkResult result = nextTable.DeviceWaitIdle(device);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001374 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001375 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001376 retireDeviceFences(device);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001377 loader_platform_thread_unlock_mutex(&globalLock);
1378 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001379 return result;
1380}
1381
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001382VK_LAYER_EXPORT VkResult VKAPI vkCreateEvent(
1383 VkDevice device,
1384 const VkEventCreateInfo *pCreateInfo,
1385 VkEvent *pEvent)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001386{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001387 VkResult result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001388 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001389 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001390 addObjectInfo(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(VkEventCreateInfo), "event");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001391 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001392 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001393 return result;
1394}
1395
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001396VK_LAYER_EXPORT VkResult VKAPI vkCreateQueryPool(
1397 VkDevice device,
1398 const VkQueryPoolCreateInfo *pCreateInfo,
1399 VkQueryPool *pQueryPool)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001400{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001401 VkResult result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001402 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001403 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001404 addObjectInfo(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(VkQueryPoolCreateInfo), "query_pool");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001405 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001406 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001407 return result;
1408}
1409
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001410VK_LAYER_EXPORT VkResult VKAPI vkCreateBuffer(
1411 VkDevice device,
1412 const VkBufferCreateInfo *pCreateInfo,
1413 VkBuffer *pBuffer)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001414{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001415 VkResult result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001416 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001417 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001418 addObjectInfo(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferCreateInfo), "buffer");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001419 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001420 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001421 return result;
1422}
1423
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001424VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(
1425 VkDevice device,
1426 const VkBufferViewCreateInfo *pCreateInfo,
1427 VkBufferView *pView)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001428{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001429 VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001430 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001431 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001432 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferViewCreateInfo), "buffer_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001433 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001434 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001435 return result;
1436}
1437
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001438VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(
1439 VkDevice device,
1440 const VkImageCreateInfo *pCreateInfo,
1441 VkImage *pImage)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001442{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001443 VkResult result = nextTable.CreateImage(device, pCreateInfo, pImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001444 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001445 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001446 addObjectInfo(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(VkImageCreateInfo), "image");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001447 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001448 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001449 return result;
1450}
1451
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001452VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(
1453 VkDevice device,
1454 const VkImageViewCreateInfo *pCreateInfo,
1455 VkImageView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001456{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001457 VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001458 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001459 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001460 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkImageViewCreateInfo), "image_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001461 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001462 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001463 return result;
1464}
1465
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001466VK_LAYER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(
1467 VkDevice device,
1468 const VkColorAttachmentViewCreateInfo *pCreateInfo,
1469 VkColorAttachmentView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001470{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001471 VkResult result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001472 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001473 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001474 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkColorAttachmentViewCreateInfo), "color_attachment_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001475 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001476 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001477 return result;
1478}
1479
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001480VK_LAYER_EXPORT VkResult VKAPI vkCreateDepthStencilView(
1481 VkDevice device,
1482 const VkDepthStencilViewCreateInfo *pCreateInfo,
1483 VkDepthStencilView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001484{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001485 VkResult result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001486 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001487 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001488 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkDepthStencilViewCreateInfo), "ds_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001489 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001490 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001491 return result;
1492}
1493
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001494VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(
1495 VkDevice device,
1496 const VkShaderCreateInfo *pCreateInfo,
1497 VkShader *pShader)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001498{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001499 VkResult result = nextTable.CreateShader(device, pCreateInfo, pShader);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001500 return result;
1501}
1502
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001503VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(
1504 VkDevice device,
1505 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1506 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001507{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001508 VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001509 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001510 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001511 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001512 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001513 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001514 return result;
1515}
1516
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001517VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001518 VkDevice device,
1519 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1520 VkPipeline basePipeline,
1521 VkPipeline *pPipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001522{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001523 VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001524 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001525 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001526 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001527 loader_platform_thread_unlock_mutex(&globalLock);
1528 }
1529 return result;
1530}
1531
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001532VK_LAYER_EXPORT VkResult VKAPI vkCreateComputePipeline(
1533 VkDevice device,
1534 const VkComputePipelineCreateInfo *pCreateInfo,
1535 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001536{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001537 VkResult result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001538 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001539 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001540 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkComputePipelineCreateInfo), "compute_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001541 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001542 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001543 return result;
1544}
1545
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001546VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(
1547 VkDevice device,
1548 const VkSamplerCreateInfo *pCreateInfo,
1549 VkSampler *pSampler)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001550{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001551 VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001552 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001553 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001554 addObjectInfo(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(VkSamplerCreateInfo), "sampler");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001555 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001556 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001557 return result;
1558}
1559
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001560VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(
1561 VkDevice device,
1562 const VkDynamicVpStateCreateInfo *pCreateInfo,
1563 VkDynamicVpState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001564{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001565 VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001566 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001567 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001568 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo), "viewport_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001569 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001570 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001571 return result;
1572}
1573
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001574VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(
1575 VkDevice device,
1576 const VkDynamicRsStateCreateInfo *pCreateInfo,
1577 VkDynamicRsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001578{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001579 VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001580 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001581 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001582 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo), "raster_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001583 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001584 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001585 return result;
1586}
1587
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001588VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(
1589 VkDevice device,
1590 const VkDynamicCbStateCreateInfo *pCreateInfo,
1591 VkDynamicCbState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001592{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001593 VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001594 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001595 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001596 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo), "cb_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001597 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001598 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001599 return result;
1600}
1601
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001602VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(
1603 VkDevice device,
1604 const VkDynamicDsStateCreateInfo *pCreateInfo,
1605 VkDynamicDsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001606{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001607 VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001608 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001609 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001610 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo), "ds_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001611 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001612 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001613 return result;
1614}
1615
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001616VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(
1617 VkDevice device,
1618 const VkCmdBufferCreateInfo *pCreateInfo,
1619 VkCmdBuffer *pCmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001620{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001621 VkResult result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001622 // At time of cmd buffer creation, create global cmd buffer info for the returned cmd buffer
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001623 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001624 if (*pCmdBuffer)
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001625 addCBInfo(*pCmdBuffer);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001626 printCBList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001627 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001628 return result;
1629}
1630
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001631VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(
1632 VkCmdBuffer cmdBuffer,
1633 const VkCmdBufferBeginInfo *pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001634{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001635 // 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 -05001636 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1637 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001638 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001639 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001640 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001641 sprintf(str, "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
1642 "You must check CB flag before this call.", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001643 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 -07001644 }
1645 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001646 VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001647 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001648 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001649 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001650 return result;
1651}
1652
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001653VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(
1654 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001655{
1656 // TODO : Anything to do here?
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001657 VkResult result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001658 return result;
1659}
1660
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001661VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(
1662 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001663{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001664 // Verify that CB is complete (not in-flight)
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001665 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1666 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001667 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001668 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001669 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001670 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before "
1671 "calling vkResetCommandBuffer().", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001672 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 -07001673 }
1674 }
1675 // Clear memory references as this point.
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001676 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001677 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001678 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001679 VkResult result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001680 return result;
1681}
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001682// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001683// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001684VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(
1685 VkCmdBuffer cmdBuffer,
1686 VkPipelineBindPoint pipelineBindPoint,
1687 VkPipeline pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001688{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001689#if 0
1690 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1691 if (getPipeline(pipeline)) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001692 MT_CB_INFO *pCBInfo = getCBInfo(cmdBuffer);
1693 if (pCBInfo) {
1694 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001695 } else {
1696 char str[1024];
1697 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001698 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 -07001699 }
1700 }
1701 else {
1702 char str[1024];
1703 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001704 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 -07001705 }
1706#endif
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001707 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1708}
1709
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001710VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(
1711 VkCmdBuffer cmdBuffer,
1712 VkStateBindPoint stateBindPoint,
1713 VkDynamicStateObject state)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001714{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001715 MT_OBJ_INFO *pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001716 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001717 MT_CB_INFO *pCmdBuf = getCBInfo(cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001718 if (!pCmdBuf) {
1719 char str[1024];
1720 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001721 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001722 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001723 pObjInfo = getObjectInfo(state);
1724 if (!pObjInfo) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001725 char str[1024];
1726 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001727 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001728 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001729 pCmdBuf->pDynamicState[stateBindPoint] = pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001730 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001731 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001732}
1733
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001734VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001735 VkCmdBuffer cmdBuffer,
1736 VkPipelineBindPoint pipelineBindPoint,
1737 uint32_t firstSet,
1738 uint32_t setCount,
1739 const VkDescriptorSet *pDescriptorSets,
1740 uint32_t dynamicOffsetCount,
1741 const uint32_t *pDynamicOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001742{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001743 // 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 -06001744 nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001745}
1746
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001747VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001748 VkCmdBuffer cmdBuffer,
1749 uint32_t startBinding,
1750 uint32_t bindingCount,
1751 const VkBuffer *pBuffers,
1752 const VkDeviceSize *pOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001753{
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001754 nextTable.CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001755}
1756
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001757VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(
1758 VkCmdBuffer cmdBuffer,
1759 VkBuffer buffer,
1760 VkDeviceSize offset,
1761 VkIndexType indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001762{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001763 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001764}
1765
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001766VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(
1767 VkCmdBuffer cmdBuffer,
1768 VkBuffer buffer,
1769 VkDeviceSize offset,
1770 uint32_t count,
1771 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001772{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001773 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001774 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001775 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001776 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001777 sprintf(str, "In vkCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1778 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001779 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001780 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001781 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001782}
1783
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001784VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(
1785 VkCmdBuffer cmdBuffer,
1786 VkBuffer buffer,
1787 VkDeviceSize offset,
1788 uint32_t count,
1789 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001790{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001791 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001792 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001793 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001794 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001795 sprintf(str, "In vkCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1796 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001797 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001798 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001799 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001800}
1801
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001802VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(
1803 VkCmdBuffer cmdBuffer,
1804 VkBuffer buffer,
1805 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001806{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001807 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001808 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001809 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001810 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001811 sprintf(str, "In vkCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1812 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001813 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001814 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001815 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001816}
1817
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001818VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(
1819 VkCmdBuffer cmdBuffer,
1820 VkBuffer srcBuffer,
1821 VkBuffer destBuffer,
1822 uint32_t regionCount,
1823 const VkBufferCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001824{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001825 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001826 VkDeviceMemory mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001827 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001828 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001829 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1830 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001831 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001832 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001833 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001834 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001835 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1836 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001837 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001838 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001839 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001840}
1841
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001842VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
1843 VkCmdBuffer cmdBuffer,
1844 VkImage srcImage,
1845 VkImageLayout srcImageLayout,
1846 VkImage destImage,
1847 VkImageLayout destImageLayout,
1848 uint32_t regionCount,
1849 const VkImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001850{
1851 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001852 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001853}
1854
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001855VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
1856 VkCmdBuffer cmdBuffer,
1857 VkImage srcImage,
1858 VkImageLayout srcImageLayout,
1859 VkImage destImage,
1860 VkImageLayout destImageLayout,
1861 uint32_t regionCount,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05001862 const VkImageBlit *pRegions,
1863 VkTexFilter filter)
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001864{
1865 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski20f68592015-05-22 14:43:25 -05001866 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001867}
1868
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001869VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
1870 VkCmdBuffer cmdBuffer,
1871 VkBuffer srcBuffer,
1872 VkImage destImage,
1873 VkImageLayout destImageLayout,
1874 uint32_t regionCount,
1875 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001876{
1877 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001878 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001879 VkDeviceMemory mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001880 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001881 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001882 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
1883 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001884 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001885
1886 mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001887 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001888 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001889 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1890 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001891 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001892 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001893 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001894}
1895
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001896VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
1897 VkCmdBuffer cmdBuffer,
1898 VkImage srcImage,
1899 VkImageLayout srcImageLayout,
1900 VkBuffer destBuffer,
1901 uint32_t regionCount,
1902 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001903{
1904 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001905 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001906 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001907 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001908 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001909 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
1910 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001911 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001912 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001913 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001914 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001915 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1916 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001917 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001918 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001919 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001920}
1921
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001922VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
1923 VkCmdBuffer cmdBuffer,
1924 VkBuffer destBuffer,
1925 VkDeviceSize destOffset,
1926 VkDeviceSize dataSize,
1927 const uint32_t *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001928{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001929 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001930 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001931 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001932 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001933 sprintf(str, "In vkCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1934 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001935 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001936 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001937 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001938}
1939
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001940VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
1941 VkCmdBuffer cmdBuffer,
1942 VkBuffer destBuffer,
1943 VkDeviceSize destOffset,
1944 VkDeviceSize fillSize,
1945 uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001946{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001947 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001948 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001949 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001950 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001951 sprintf(str, "In vkCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1952 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001953 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001954 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001955 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001956}
1957
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001958VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
1959 VkCmdBuffer cmdBuffer,
1960 VkImage image,
1961 VkImageLayout imageLayout,
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06001962 const VkClearColor *pColor,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001963 uint32_t rangeCount,
1964 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001965{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001966 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001967 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001968 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001969 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001970 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001971 sprintf(str, "In vkCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
1972 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001973 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001974 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06001975 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001976}
1977
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001978VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(
1979 VkCmdBuffer cmdBuffer,
1980 VkImage image,
1981 VkImageLayout imageLayout,
1982 float depth,
1983 uint32_t stencil,
1984 uint32_t rangeCount,
1985 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001986{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001987 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001988 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001989 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001990 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001991 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001992 sprintf(str, "In vkCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
1993 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001994 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001995 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001996 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001997}
1998
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001999VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
2000 VkCmdBuffer cmdBuffer,
2001 VkImage srcImage,
2002 VkImageLayout srcImageLayout,
2003 VkImage destImage,
2004 VkImageLayout destImageLayout,
2005 uint32_t regionCount,
2006 const VkImageResolve *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002007{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002008 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002009 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002010 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002011 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002012 sprintf(str, "In vkCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2013 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002014 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002015 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002016 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002017 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002018 sprintf(str, "In vkCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2019 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002020 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002021 loader_platform_thread_unlock_mutex(&globalLock);
Tony Barbour11f74372015-04-13 15:02:52 -06002022 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002023}
2024
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002025VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(
2026 VkCmdBuffer cmdBuffer,
2027 VkQueryPool queryPool,
2028 uint32_t slot,
2029 VkFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002030{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002031 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002032 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002033 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002034 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002035 sprintf(str, "In vkCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2036 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002037 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002038 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002039 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2040}
2041
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002042VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(
2043 VkCmdBuffer cmdBuffer,
2044 VkQueryPool queryPool,
2045 uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002046{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002047 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002048 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002049 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002050 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002051 sprintf(str, "In vkCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2052 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002053 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002054 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002055 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2056}
2057
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002058VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(
2059 VkCmdBuffer cmdBuffer,
2060 VkQueryPool queryPool,
2061 uint32_t startQuery,
2062 uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002063{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002064 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002065 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002066 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002067 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002068 sprintf(str, "In vkCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2069 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002070 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002071 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002072 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2073}
2074
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002075VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
2076 VkInstance instance,
2077 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
2078 void *pUserData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002079{
Tobin Ehlis62086412014-11-19 16:19:28 -07002080 // This layer intercepts callbacks
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002081 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 -07002082 if (!pNewDbgFuncNode)
Tony Barbour8205d902015-04-16 15:59:00 -06002083 return VK_ERROR_OUT_OF_HOST_MEMORY;
Tobin Ehlis62086412014-11-19 16:19:28 -07002084 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2085 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburnf57ea372014-12-22 13:24:15 -07002086 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2087 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburne4722392015-03-03 15:07:15 -07002088 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002089 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002090 g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002091 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002092 VkResult result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002093 return result;
2094}
2095
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002096VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
2097 VkInstance instance,
2098 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002099{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002100 VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
2101 VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002102 while (pInfo) {
2103 if (pInfo->pfnMsgCallback == pfnMsgCallback) {
2104 pPrev->pNext = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002105 if (g_pDbgFunctionHead == pInfo) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002106 g_pDbgFunctionHead = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002107 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002108 free(pInfo);
Tobin Ehlis62086412014-11-19 16:19:28 -07002109 break;
2110 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002111 pPrev = pInfo;
2112 pInfo = pInfo->pNext;
Tobin Ehlis62086412014-11-19 16:19:28 -07002113 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002114 if (g_pDbgFunctionHead == NULL) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002115 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002116 g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002117 } else {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002118 g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002119 }
Jon Ashburne4722392015-03-03 15:07:15 -07002120 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002121 VkResult result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002122 return result;
2123}
2124
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002125VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
2126 VkDevice device,
2127 const VkSwapChainCreateInfoWSI *pCreateInfo,
2128 VkSwapChainWSI *pSwapChain)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002129{
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002130 VkResult result = nextTable.CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
2131
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002132 if (VK_SUCCESS == result) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002133 loader_platform_thread_lock_mutex(&globalLock);
2134 addSwapChainInfo(*pSwapChain);
2135 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -07002136 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002137
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002138 return result;
2139}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002140
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002141VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
2142 VkSwapChainWSI swapChain)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002143{
2144 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002145
2146 if (swapChainMap.find(swapChain) != swapChainMap.end()) {
2147 MT_SWAP_CHAIN_INFO* pInfo = swapChainMap[swapChain];
2148
David Pinedof5997ab2015-04-27 16:36:17 -06002149 if (pInfo->images.size() > 0) {
2150 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2151 it != pInfo->images.end(); it++) {
2152 clearObjectBinding(it->image);
2153 freeMemObjInfo(it->memory, true);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002154
David Pinedof5997ab2015-04-27 16:36:17 -06002155 MT_OBJ_INFO* pDelInfo = objectMap[it->image];
2156 delete pDelInfo;
2157 objectMap.erase(it->image);
2158 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002159 }
2160
2161 delete pInfo;
2162 swapChainMap.erase(swapChain);
2163 }
2164
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002165 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002166
2167 return nextTable.DestroySwapChainWSI(swapChain);
2168}
2169
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002170VK_LAYER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
2171 VkSwapChainWSI swapChain,
2172 VkSwapChainInfoTypeWSI infoType,
2173 size_t *pDataSize,
2174 void *pData)
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002175{
2176 VkResult result = nextTable.GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
2177
2178 if (infoType == VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI && result == VK_SUCCESS) {
2179 const size_t count = *pDataSize / sizeof(VkSwapChainImageInfoWSI);
2180 MT_SWAP_CHAIN_INFO *pInfo = swapChainMap[swapChain];
2181
2182 if (pInfo->images.empty()) {
2183 pInfo->images.resize(count);
2184 memcpy(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count);
2185
David Pinedof5997ab2015-04-27 16:36:17 -06002186 if (pInfo->images.size() > 0) {
2187 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2188 it != pInfo->images.end(); it++) {
2189 // Add image object, then insert the new Mem Object and then bind it to created image
2190 addObjectInfo(it->image, VK_STRUCTURE_TYPE_MAX_ENUM, &pInfo->createInfo, sizeof(pInfo->createInfo), "persistent_image");
2191 addMemObjInfo(it->memory, NULL);
2192 if (VK_FALSE == updateObjectBinding(it->image, it->memory)) {
2193 char str[1024];
2194 sprintf(str, "In vkGetSwapChainInfoWSI(), unable to set image %p binding to mem obj %p", (void*)it->image, (void*)it->memory);
2195 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
2196 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002197 }
2198 }
2199 } else {
2200 const bool mismatch = (pInfo->images.size() != count ||
2201 memcmp(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count));
2202
2203 if (mismatch) {
2204 char str[1024];
2205 sprintf(str, "vkGetSwapChainInfoWSI(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI) returned mismatching data", swapChain);
Mike Stroyan230e6252015-04-17 12:36:38 -06002206 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 +08002207 }
2208 }
2209 }
2210
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002211 return result;
2212}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002213
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002214VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(
2215 VkPhysicalDevice gpu,
2216 const char *funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002217{
Jon Ashburn301c5f02015-04-06 10:58:22 -06002218 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wu706533e2015-01-05 13:18:57 +08002219
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002220 if (gpu == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002221 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002222 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002223 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07002224 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002225
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002226 if (!strcmp(funcName, "vkGetProcAddr"))
2227 return (void *) vkGetProcAddr;
2228 if (!strcmp(funcName, "vkCreateDevice"))
2229 return (void*) vkCreateDevice;
2230 if (!strcmp(funcName, "vkDestroyDevice"))
2231 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002232 if (!strcmp(funcName, "vkEnumerateLayers"))
2233 return (void*) vkEnumerateLayers;
2234 if (!strcmp(funcName, "vkQueueSubmit"))
2235 return (void*) vkQueueSubmit;
2236 if (!strcmp(funcName, "vkAllocMemory"))
2237 return (void*) vkAllocMemory;
2238 if (!strcmp(funcName, "vkFreeMemory"))
2239 return (void*) vkFreeMemory;
2240 if (!strcmp(funcName, "vkSetMemoryPriority"))
2241 return (void*) vkSetMemoryPriority;
2242 if (!strcmp(funcName, "vkMapMemory"))
2243 return (void*) vkMapMemory;
2244 if (!strcmp(funcName, "vkUnmapMemory"))
2245 return (void*) vkUnmapMemory;
2246 if (!strcmp(funcName, "vkPinSystemMemory"))
2247 return (void*) vkPinSystemMemory;
2248 if (!strcmp(funcName, "vkOpenSharedMemory"))
2249 return (void*) vkOpenSharedMemory;
2250 if (!strcmp(funcName, "vkOpenPeerMemory"))
2251 return (void*) vkOpenPeerMemory;
2252 if (!strcmp(funcName, "vkOpenPeerImage"))
2253 return (void*) vkOpenPeerImage;
2254 if (!strcmp(funcName, "vkDestroyObject"))
2255 return (void*) vkDestroyObject;
2256 if (!strcmp(funcName, "vkGetObjectInfo"))
2257 return (void*) vkGetObjectInfo;
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05002258 if (!strcmp(funcName, "vkBindObjectMemory"))
2259 return (void*) vkBindObjectMemory;
2260 if (!strcmp(funcName, "vkQueueBindSparseBufferMemory"))
2261 return (void*) vkQueueBindSparseBufferMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002262 if (!strcmp(funcName, "vkCreateFence"))
2263 return (void*) vkCreateFence;
2264 if (!strcmp(funcName, "vkGetFenceStatus"))
2265 return (void*) vkGetFenceStatus;
2266 if (!strcmp(funcName, "vkResetFences"))
2267 return (void*) vkResetFences;
2268 if (!strcmp(funcName, "vkWaitForFences"))
2269 return (void*) vkWaitForFences;
2270 if (!strcmp(funcName, "vkQueueWaitIdle"))
2271 return (void*) vkQueueWaitIdle;
2272 if (!strcmp(funcName, "vkDeviceWaitIdle"))
2273 return (void*) vkDeviceWaitIdle;
2274 if (!strcmp(funcName, "vkCreateEvent"))
2275 return (void*) vkCreateEvent;
2276 if (!strcmp(funcName, "vkCreateQueryPool"))
2277 return (void*) vkCreateQueryPool;
2278 if (!strcmp(funcName, "vkCreateBuffer"))
2279 return (void*) vkCreateBuffer;
2280 if (!strcmp(funcName, "vkCreateBufferView"))
2281 return (void*) vkCreateBufferView;
2282 if (!strcmp(funcName, "vkCreateImage"))
2283 return (void*) vkCreateImage;
2284 if (!strcmp(funcName, "vkCreateImageView"))
2285 return (void*) vkCreateImageView;
2286 if (!strcmp(funcName, "vkCreateColorAttachmentView"))
2287 return (void*) vkCreateColorAttachmentView;
2288 if (!strcmp(funcName, "vkCreateDepthStencilView"))
2289 return (void*) vkCreateDepthStencilView;
2290 if (!strcmp(funcName, "vkCreateShader"))
2291 return (void*) vkCreateShader;
2292 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2293 return (void*) vkCreateGraphicsPipeline;
2294 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2295 return (void*) vkCreateGraphicsPipelineDerivative;
2296 if (!strcmp(funcName, "vkCreateComputePipeline"))
2297 return (void*) vkCreateComputePipeline;
2298 if (!strcmp(funcName, "vkCreateSampler"))
2299 return (void*) vkCreateSampler;
2300 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2301 return (void*) vkCreateDynamicViewportState;
2302 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2303 return (void*) vkCreateDynamicRasterState;
2304 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2305 return (void*) vkCreateDynamicColorBlendState;
2306 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2307 return (void*) vkCreateDynamicDepthStencilState;
2308 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2309 return (void*) vkCreateCommandBuffer;
2310 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2311 return (void*) vkBeginCommandBuffer;
2312 if (!strcmp(funcName, "vkEndCommandBuffer"))
2313 return (void*) vkEndCommandBuffer;
2314 if (!strcmp(funcName, "vkResetCommandBuffer"))
2315 return (void*) vkResetCommandBuffer;
2316 if (!strcmp(funcName, "vkCmdBindPipeline"))
2317 return (void*) vkCmdBindPipeline;
2318 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2319 return (void*) vkCmdBindDynamicStateObject;
2320 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2321 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002322 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2323 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002324 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2325 return (void*) vkCmdBindIndexBuffer;
2326 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2327 return (void*) vkCmdDrawIndirect;
2328 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2329 return (void*) vkCmdDrawIndexedIndirect;
2330 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2331 return (void*) vkCmdDispatchIndirect;
2332 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2333 return (void*) vkCmdCopyBuffer;
2334 if (!strcmp(funcName, "vkCmdCopyImage"))
2335 return (void*) vkCmdCopyImage;
2336 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2337 return (void*) vkCmdCopyBufferToImage;
2338 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2339 return (void*) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002340 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2341 return (void*) vkCmdUpdateBuffer;
2342 if (!strcmp(funcName, "vkCmdFillBuffer"))
2343 return (void*) vkCmdFillBuffer;
2344 if (!strcmp(funcName, "vkCmdClearColorImage"))
2345 return (void*) vkCmdClearColorImage;
2346 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2347 return (void*) vkCmdClearDepthStencil;
2348 if (!strcmp(funcName, "vkCmdResolveImage"))
2349 return (void*) vkCmdResolveImage;
2350 if (!strcmp(funcName, "vkCmdBeginQuery"))
2351 return (void*) vkCmdBeginQuery;
2352 if (!strcmp(funcName, "vkCmdEndQuery"))
2353 return (void*) vkCmdEndQuery;
2354 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2355 return (void*) vkCmdResetQueryPool;
2356 if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
2357 return (void*) vkDbgRegisterMsgCallback;
2358 if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
2359 return (void*) vkDbgUnregisterMsgCallback;
2360 if (!strcmp(funcName, "vkGetDeviceQueue"))
2361 return (void*) vkGetDeviceQueue;
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002362 if (!strcmp(funcName, "vkCreateSwapChainWSI"))
2363 return (void*) vkCreateSwapChainWSI;
2364 if (!strcmp(funcName, "vkDestroySwapChainWSI"))
2365 return (void*) vkDestroySwapChainWSI;
2366 if (!strcmp(funcName, "vkGetSwapChainInfoWSI"))
2367 return (void*) vkGetSwapChainInfoWSI;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002368 else {
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002369 if (gpuw->pGPA == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002370 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002371 }
Tony Barbour8205d902015-04-16 15:59:00 -06002372 return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002373 }
2374}