blob: 771feb8bbc8633bf49602a18d43bbac8612706f2 [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
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060078 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -050079 (*ii).second->pQueueCmdBuffers.clear();
80 }
81 queueMap.clear();
82}
83
Mark Lobodzinskia908b162015-04-21 15:33:04 -060084static void addSwapChainInfo(
85 const VkSwapChainWSI swapChain)
Chia-I Wu5b66aa52015-04-16 22:02:10 +080086{
87 MT_SWAP_CHAIN_INFO* pInfo = new MT_SWAP_CHAIN_INFO;
88 swapChainMap[swapChain] = pInfo;
89}
90
Mark Lobodzinski85a83982015-04-02 08:52:53 -050091// Add new CBInfo for this cb to map container
Mark Lobodzinskia908b162015-04-21 15:33:04 -060092static void addCBInfo(
93 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -070094{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -050095 MT_CB_INFO* pInfo = new MT_CB_INFO;
Tony Barbour8205d902015-04-16 15:59:00 -060096 memset(pInfo, 0, (sizeof(MT_CB_INFO) - sizeof(list<VkDeviceMemory>)));
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -050097 pInfo->cmdBuffer = cb;
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -060098 cbMap[cb] = pInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -070099}
100
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500101// Return ptr to Info in CB map, or NULL if not found
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600102static MT_CB_INFO* getCBInfo(
103 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700104{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500105 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500106 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500107 pCBInfo = cbMap[cb];
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600108 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500109 return pCBInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700110}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600111
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500112// Return object info for 'object' or return NULL if no info exists
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600113static MT_OBJ_INFO* getObjectInfo(
114 const VkObject object)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500115{
116 MT_OBJ_INFO* pObjInfo = NULL;
117
118 if (objectMap.find(object) != objectMap.end()) {
119 pObjInfo = objectMap[object];
120 }
121 return pObjInfo;
122}
123
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600124static MT_OBJ_INFO* addObjectInfo(
125 VkObject object,
126 VkStructureType sType,
127 const void *pCreateInfo,
128 const int struct_size,
129 const char *name_prefix)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500130{
131 MT_OBJ_INFO* pInfo = new MT_OBJ_INFO;
132 memset(pInfo, 0, sizeof(MT_OBJ_INFO));
133 memcpy(&pInfo->create_info, pCreateInfo, struct_size);
134 sprintf(pInfo->object_name, "%s_%p", name_prefix, object);
135
136 pInfo->object = object;
137 pInfo->ref_count = 1;
138 pInfo->sType = sType;
139 objectMap[object] = pInfo;
140
141 return pInfo;
142}
143
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500144// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600145static uint64_t addFenceInfo(
146 VkFence fence,
147 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500148{
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500149 // Create fence object
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500150 MT_FENCE_INFO* pFenceInfo = new MT_FENCE_INFO;
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500151 MT_QUEUE_INFO* pQueueInfo = queueMap[queue];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500152 uint64_t fenceId = g_currentFenceId++;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500153 memset(pFenceInfo, 0, sizeof(MT_FENCE_INFO));
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500154 // If no fence, create an internal fence to track the submissions
155 if (fence == NULL) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600156 VkFenceCreateInfo fci;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600157 fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500158 fci.pNext = NULL;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600159 fci.flags = static_cast<VkFenceCreateFlags>(0);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500160 nextTable.CreateFence(globalDevice, &fci, &pFenceInfo->fence);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600161 addObjectInfo(pFenceInfo->fence, fci.sType, &fci, sizeof(VkFenceCreateInfo), "internalFence");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600162 pFenceInfo->localFence = VK_TRUE;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500163 } else {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500164 // Validate that fence is in UNSIGNALED state
165 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
166 if (pObjectInfo != NULL) {
Tobin Ehlisf29da382015-04-15 07:46:12 -0600167 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500168 char str[1024];
169 sprintf(str, "Fence %p submitted in SIGNALED state. Fences must be reset before being submitted", fence);
Tobin Ehlisf29da382015-04-15 07:46:12 -0600170 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
Mark Lobodzinski56945182015-04-09 13:46:09 -0500171 }
172 }
Tobin Ehlisf29da382015-04-15 07:46:12 -0600173 pFenceInfo->localFence = VK_FALSE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500174 pFenceInfo->fence = fence;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700175 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500176 pFenceInfo->queue = queue;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500177 fenceMap[fenceId] = pFenceInfo;
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500178 // Update most recently submitted fenceId for Queue
179 pQueueInfo->lastSubmittedId = fenceId;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500180 return fenceId;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500181}
182
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500183// Remove a fenceInfo from our list of fences/fenceIds
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600184static void deleteFenceInfo(
185 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500186{
187 if (fenceId != 0) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500188 if (fenceMap.find(fenceId) != fenceMap.end()) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600189 map<uint64_t, MT_FENCE_INFO*>::iterator item;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500190 MT_FENCE_INFO* pDelInfo = fenceMap[fenceId];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500191 if (pDelInfo != NULL) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600192 if (pDelInfo->localFence == VK_TRUE) {
Mike Stroyan230e6252015-04-17 12:36:38 -0600193 nextTable.DestroyObject(globalDevice, VK_OBJECT_TYPE_FENCE, pDelInfo->fence);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500194 }
195 delete pDelInfo;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500196 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600197 item = fenceMap.find(fenceId);
198 fenceMap.erase(item);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500199 }
200 }
201}
202
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500203// Search through list for this fence, deleting all items before it (with lower IDs) and updating lastRetiredId
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600204static void updateFenceTracking(
205 VkFence fence)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500206{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500207 MT_FENCE_INFO *pCurFenceInfo = NULL;
208 uint64_t fenceId = 0;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600209 VkQueue queue = NULL;
210 bool found = false;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500211
Mike Stroyan62d0bbf2015-04-15 15:37:47 -0600212 for (map<uint64_t, MT_FENCE_INFO*>::iterator ii=fenceMap.begin(); !found && ii!=fenceMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500213 if ((*ii).second != NULL) {
214 if (fence == ((*ii).second)->fence) {
215 queue = ((*ii).second)->queue;
216 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
217 pQueueInfo->lastRetiredId = (*ii).first;
Mike Stroyan62d0bbf2015-04-15 15:37:47 -0600218 found = true;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500219 } else {
220 deleteFenceInfo((*ii).first);
221 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500222 // Update fence state in fenceCreateInfo structure
223 MT_OBJ_INFO* pObjectInfo = getObjectInfo(fence);
224 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -0500225 pObjectInfo->create_info.fence_create_info.flags =
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600226 static_cast<VkFenceCreateFlags>(
227 pObjectInfo->create_info.fence_create_info.flags | VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500228 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500229 }
230 }
231}
232
233// Utility function that determines if a fenceId has been retired yet
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600234static bool32_t fenceRetired(
235 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500236{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600237 bool32_t result = VK_FALSE;
Courtney Goeltzenleuchter60edc352015-04-15 14:10:51 -0600238 if (fenceMap.find(fenceId) != fenceMap.end()) {
239 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500240 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
Mark Lobodzinski91a1ec52015-04-02 08:52:53 -0500241 if (fenceId <= pQueueInfo->lastRetiredId)
242 {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600243 result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500244 }
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500245 } else { // If not in list, fence has been retired and deleted
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600246 result = VK_TRUE;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500247 }
248 return result;
249}
250
251// Return the fence associated with a fenceId
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600252static VkFence getFenceFromId(
253 uint64_t fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500254{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600255 VkFence fence = NULL;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500256 if (fenceId != 0) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500257 // Search for an item with this fenceId
258 if (fenceMap.find(fenceId) != fenceMap.end()) {
259 MT_FENCE_INFO* pFenceInfo = fenceMap[fenceId];
260 if (pFenceInfo != NULL) {
261 MT_QUEUE_INFO* pQueueInfo = queueMap[pFenceInfo->queue];
262 if (fenceId > pQueueInfo->lastRetiredId) {
263 fence = pFenceInfo->fence;
264 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500265 }
266 }
267 }
268 return fence;
269}
270
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500271// Helper routine that updates the fence list for a specific queue to all-retired
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600272static void retireQueueFences(
273 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500274{
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600275 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
276 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
277 // Set Queue's lastRetired to lastSubmitted, free items in queue's fence list
278 map<uint64_t, MT_FENCE_INFO*>::iterator it = fenceMap.begin();
279 map<uint64_t, MT_FENCE_INFO*>::iterator temp;
280 while (it != fenceMap.end()) {
Tobin Ehlisbfc55032015-04-15 14:25:02 -0600281 if ((((*it).second) != NULL) && ((*it).second)->queue == queue) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600282 temp = it;
283 ++temp;
284 deleteFenceInfo((*it).first);
285 it = temp;
286 } else {
287 ++it;
288 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500289 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700290}
291
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500292// Helper routine that updates fence list for all queues to all-retired
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600293static void retireDeviceFences(
294 VkDevice device)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500295{
296 // Process each queue for device
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600297 // TODO: Add multiple device support
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600298 for (map<VkQueue, MT_QUEUE_INFO*>::iterator ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500299 retireQueueFences((*ii).first);
300 }
301}
302
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500303// Returns True if a memory reference is present in a Queue's memory reference list
304// Queue is validated by caller
305static bool32_t checkMemRef(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600306 VkQueue queue,
Tony Barbour8205d902015-04-16 15:59:00 -0600307 VkDeviceMemory mem)
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500308{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600309 bool32_t result = VK_FALSE;
Tony Barbour8205d902015-04-16 15:59:00 -0600310 list<VkDeviceMemory>::iterator it;
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500311 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
312 for (it = pQueueInfo->pMemRefList.begin(); it != pQueueInfo->pMemRefList.end(); ++it) {
313 if ((*it) == mem) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600314 result = VK_TRUE;
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500315 break;
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500316 }
317 }
318 return result;
319}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500320
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500321static bool32_t validateQueueMemRefs(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600322 VkQueue queue,
323 uint32_t cmdBufferCount,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600324 const VkCmdBuffer *pCmdBuffers)
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500325{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600326 bool32_t result = VK_TRUE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500327
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500328 // Verify Queue
329 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
330 if (pQueueInfo == NULL) {
331 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600332 sprintf(str, "Unknown Queue %p specified in vkQueueSubmit", queue);
333 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500334 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500335 else {
336 // Iterate through all CBs in pCmdBuffers
337 for (uint32_t i = 0; i < cmdBufferCount; i++) {
338 MT_CB_INFO* pCBInfo = getCBInfo(pCmdBuffers[i]);
339 if (!pCBInfo) {
340 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600341 sprintf(str, "Unable to find info for CB %p in order to check memory references in "
342 "vkQueueSubmit for queue %p",
343 (void*)pCmdBuffers[i], queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600344 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_INVALID_CB, "MEM", str);
345 result = VK_FALSE;
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500346 } else {
347 // Validate that all actual references are accounted for in pMemRefs
Tony Barbour8205d902015-04-16 15:59:00 -0600348 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500349 // Search for each memref in queues memreflist.
350 if (checkMemRef(queue, *it)) {
351 char str[1024];
352 sprintf(str, "Found Mem Obj %p binding to CB %p for queue %p", (*it), pCmdBuffers[i], queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600353 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500354 }
355 else {
356 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600357 sprintf(str, "Queue %p Memory reference list for Command Buffer %p is missing ref to mem obj %p",
358 queue, pCmdBuffers[i], (*it));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600359 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCmdBuffers[i], 0, MEMTRACK_INVALID_MEM_REF, "MEM", str);
360 result = VK_FALSE;
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500361 }
362 }
363 }
364 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600365 if (result == VK_TRUE) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500366 char str[1024];
367 sprintf(str, "Verified all memory dependencies for Queue %p are included in pMemRefs list", queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600368 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500369 // TODO : Could report mem refs in pMemRefs that AREN'T in mem list, that would be primarily informational
370 // Currently just noting that there is a difference
371 }
372 }
373
374 return result;
375}
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600376
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500377// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700378// Calls to this function should be wrapped in mutex
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600379static MT_MEM_OBJ_INFO* getMemObjInfo(
380 const VkDeviceMemory mem)
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700381{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500382 MT_MEM_OBJ_INFO* pMemObjInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500383
384 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500385 pMemObjInfo = memObjMap[mem];
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600386 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500387 return pMemObjInfo;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700388}
389
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600390static void addMemObjInfo(
391 const VkDeviceMemory mem,
392 const VkMemoryAllocInfo *pAllocInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700393{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500394 MT_MEM_OBJ_INFO* pInfo = new MT_MEM_OBJ_INFO;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600395 pInfo->refCount = 0;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600396 memset(&pInfo->allocInfo, 0, sizeof(VkMemoryAllocInfo));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500397
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800398 if (pAllocInfo) { // MEM alloc created by vkCreateSwapChainWSI() doesn't have alloc info struct
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600399 memcpy(&pInfo->allocInfo, pAllocInfo, sizeof(VkMemoryAllocInfo));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500400 // TODO: Update for real hardware, actually process allocation info structures
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500401 pInfo->allocInfo.pNext = NULL;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700402 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500403 pInfo->mem = mem;
404 memObjMap[mem] = pInfo;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700405}
406
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500407// Find CB Info and add mem binding to list container
408// Find Mem Obj Info and add CB binding to list container
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600409static bool32_t updateCBBinding(
410 const VkCmdBuffer cb,
411 const VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700412{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600413 bool32_t result = VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700414 // First update CB binding in MemObj mini CB list
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500415 MT_MEM_OBJ_INFO* pMemInfo = getMemObjInfo(mem);
416 if (!pMemInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700417 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600418 sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that mem obj.\n "
419 "Was it correctly allocated? Did it already get freed?", mem, cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600420 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
421 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600422 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500423 // Search for cmd buffer object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600424 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600425 for (list<VkCmdBuffer>::iterator it = pMemInfo->pCmdBufferBindings.begin(); it != pMemInfo->pCmdBufferBindings.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500426 if ((*it) == cb) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600427 found = VK_TRUE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500428 break;
429 }
430 }
431 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600432 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500433 pMemInfo->pCmdBufferBindings.push_front(cb);
434 pMemInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500435 }
436
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500437 // Now update CBInfo's Mem binding list
438 MT_CB_INFO* pCBInfo = getCBInfo(cb);
439 if (!pCBInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500440 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500441 sprintf(str, "Trying to bind mem obj %p to CB %p but no info for that CB. Was it CB incorrectly destroyed?", mem, cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600442 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
443 result = VK_FALSE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500444 } else {
445 // Search for memory object in cmd buffer's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600446 bool32_t found = VK_FALSE;
Tony Barbour8205d902015-04-16 15:59:00 -0600447 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500448 if ((*it) == mem) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600449 found = VK_TRUE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500450 break;
451 }
452 }
453 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600454 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500455 pCBInfo->pMemObjList.push_front(mem);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600456 }
457 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700458 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600459 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700460}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600461
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700462// Clear the CB Binding for mem
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700463// Calls to this function should be wrapped in mutex
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600464static void clearCBBinding(
465 const VkCmdBuffer cb,
466 const VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700467{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500468 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500469 // TODO : Having this check is not ideal, really if memInfo was deleted,
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700470 // its CB bindings should be cleared and then freeCBBindings wouldn't call
471 // us here with stale mem objs
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500472 if (pInfo) {
473 pInfo->pCmdBufferBindings.remove(cb);
474 pInfo->refCount--;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700475 }
476}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600477
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700478// Free bindings related to CB
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600479static bool32_t freeCBBindings(
480 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700481{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600482 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500483 MT_CB_INFO* pCBInfo = getCBInfo(cb);
484 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700485 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500486 sprintf(str, "Unable to find global CB info %p for deletion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600487 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
488 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600489 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500490 if (!fenceRetired(pCBInfo->fenceId)) {
491 deleteFenceInfo(pCBInfo->fenceId);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600492 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500493
Tony Barbour8205d902015-04-16 15:59:00 -0600494 for (list<VkDeviceMemory>::iterator it=pCBInfo->pMemObjList.begin(); it!=pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500495 clearCBBinding(cb, (*it));
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600496 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500497 pCBInfo->pMemObjList.clear();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700498 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600499 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700500}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600501
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500502// Delete CBInfo from list along with all of it's mini MemObjInfo
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500503// and also clear mem references to CB
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700504// TODO : When should this be called? There's no Destroy of CBs that I see
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600505static bool32_t deleteCBInfo(
506 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700507{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600508 bool32_t result = VK_TRUE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600509 result = freeCBBindings(cb);
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500510 // Delete the CBInfo info
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600511 if (result == VK_TRUE) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500512 if (cbMap.find(cb) != cbMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500513 MT_CB_INFO* pDelInfo = cbMap[cb];
514 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500515 cbMap.erase(cb);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600516 }
Ian Elliott81ac44c2015-01-13 17:52:38 -0700517 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600518 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700519}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600520
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700521// Delete the entire CB list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600522static bool32_t deleteCBInfoList(
523 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700524{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600525 bool32_t result = VK_TRUE;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600526 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500527 freeCBBindings((*ii).first);
528 delete (*ii).second;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700529 }
530 return result;
531}
532
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500533// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600534static void reportMemReferencesAndCleanUp(
535 MT_MEM_OBJ_INFO* pMemObjInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700536{
Tony Barboura938abb2015-04-22 11:36:22 -0600537 size_t cmdBufRefCount = pMemObjInfo->pCmdBufferBindings.size();
538 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500539
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500540 if ((pMemObjInfo->pCmdBufferBindings.size() + pMemObjInfo->pObjBindings.size()) != 0) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700541 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600542 sprintf(str, "Attempting to free memory object %p which still contains %lu references",
543 pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600544 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pMemObjInfo->mem, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700545 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500546
547 if (cmdBufRefCount > 0) {
548 for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
549 char str[1024];
550 sprintf(str, "Command Buffer %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
551 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
552 }
553 // Clear the list of hanging references
554 pMemObjInfo->pCmdBufferBindings.clear();
555 }
556
557 if (objRefCount > 0) {
558 for (list<VkObject>::const_iterator it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
559 char str[1024];
560 sprintf(str, "VK Object %p still has a reference to mem obj %p", (*it), pMemObjInfo->mem);
561 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (*it), 0, MEMTRACK_NONE, "MEM", str);
562 }
563 // Clear the list of hanging references
564 pMemObjInfo->pObjBindings.clear();
565 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700566}
567
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600568static void deleteMemObjInfo(
569 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700570{
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500571 if (memObjMap.find(mem) != memObjMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500572 MT_MEM_OBJ_INFO* pDelInfo = memObjMap[mem];
573 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500574 memObjMap.erase(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700575 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500576 else {
577 char str[1024];
578 sprintf(str, "Request to delete memory object %p not present in memory Object Map", mem);
579 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
580 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700581}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500582
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700583// Check if fence for given CB is completed
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600584static bool32_t checkCBCompleted(
585 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700586{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600587 bool32_t result = VK_TRUE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500588 MT_CB_INFO* pCBInfo = getCBInfo(cb);
589 if (!pCBInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700590 char str[1024];
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500591 sprintf(str, "Unable to find global CB info %p to check for completion", cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600592 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_INVALID_CB, "MEM", str);
593 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600594 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500595 if (!fenceRetired(pCBInfo->fenceId)) {
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600596 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600597 sprintf(str, "FenceId %" PRIx64", fence %p for CB %p has not been checked for completion",
598 pCBInfo->fenceId, getFenceFromId(pCBInfo->fenceId), cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600599 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, MEMTRACK_NONE, "MEM", str);
600 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600601 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700602 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600603 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700604}
605
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600606static bool32_t freeMemObjInfo(
607 VkDeviceMemory mem,
608 bool internal)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700609{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600610 bool32_t result = VK_TRUE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500611 // Parse global list to find info w/ mem
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500612 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
613 if (!pInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700614 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600615 sprintf(str, "Couldn't find mem info object for %p\n Was %p never allocated or previously freed?",
616 (void*)mem, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600617 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
618 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600619 } else {
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -0600620 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600621 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600622 sprintf(str, "Attempting to free memory associated with a Persistent Image, %p, "
623 "this should not be explicitly freed\n", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600624 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
625 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600626 } else {
627 // Clear any CB bindings for completed CBs
628 // TODO : Is there a better place to do this?
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500629
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600630 list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin();
631 list<VkCmdBuffer>::iterator temp;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500632 while (it != pInfo->pCmdBufferBindings.end()) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600633 if (VK_TRUE == checkCBCompleted(*it)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500634 temp = it;
635 ++temp;
636 freeCBBindings(*it);
637 it = temp;
638 } else {
639 ++it;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600640 }
641 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500642
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600643 // Now verify that no references to this mem obj remain
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500644 if (0 != pInfo->refCount) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500645 // If references remain, report the error and can search CB list to find references
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600646 char str[1024];
647 sprintf(str, "Freeing mem obj %p while it still has references", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600648 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREED_MEM_REF, "MEM", str);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500649 reportMemReferencesAndCleanUp(pInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600650 result = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600651 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600652 // Delete mem obj info
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500653 deleteMemObjInfo(mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700654 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700655 }
656 return result;
657}
658
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700659// Remove object binding performs 3 tasks:
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500660// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
661// 2. Decrement refCount for MemObjInfo
662// 3. Clear MemObjInfo ptr from ObjectInfo
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600663static bool32_t clearObjectBinding(
664 VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700665{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600666 bool32_t result = VK_FALSE;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500667 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
668 if (!pObjInfo) {
Tobin Ehlis62086412014-11-19 16:19:28 -0700669 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600670 sprintf(str, "Attempting to clear mem binding for object %p: devices, queues, command buffers, "
671 "shaders and memory objects do not have external memory requirements and it is "
672 "unneccessary to call bind/unbindObjectMemory on them.", object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600673 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600674 } else {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500675 if (!pObjInfo->pMemObjInfo) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600676 char str[1024];
677 sprintf(str, "Attempting to clear mem binding on obj %p but it has no binding.", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600678 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600679 } else {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500680 // This obj is bound to a memory object. Remove the reference to this object in that memory object's list, decrement the memObj's refcount
681 // and set the objects memory binding pointer to NULL.
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600682 for (list<VkObject>::iterator it = pObjInfo->pMemObjInfo->pObjBindings.begin(); it != pObjInfo->pMemObjInfo->pObjBindings.end(); ++it) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500683 if ((*it) == object) {
684 pObjInfo->pMemObjInfo->refCount--;
685 pObjInfo->pMemObjInfo->pObjBindings.erase(it);
686 pObjInfo->pMemObjInfo = NULL;
687 result = VK_TRUE;
688 break;
689 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600690 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600691 if (result == VK_FALSE) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600692 char str[1024];
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500693 sprintf(str, "While trying to clear mem binding for object %p, unable to find that object referenced by mem obj %p",
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500694 object, pObjInfo->pMemObjInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600695 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600696 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700697 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700698 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600699 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700700}
701
702// For NULL mem case, clear any previous binding Else...
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500703// Make sure given object is in global object map
Tobin Ehlis62086412014-11-19 16:19:28 -0700704// IF a previous binding existed, clear it
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500705// Add reference from objectInfo to memoryInfo
706// Add reference off of objInfo
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600707// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600708static bool32_t updateObjectBinding(
709 VkObject object,
710 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700711{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600712 bool32_t result = VK_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700713 // Handle NULL case separately, just clear previous binding & decrement reference
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600714 if (mem == VK_NULL_HANDLE) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700715 clearObjectBinding(object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600716 result = VK_TRUE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600717 } else {
718 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500719 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
720 if (!pObjInfo) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600721 sprintf(str, "Attempting to update Binding of Obj(%p) that's not in global list()", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600722 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
723 return VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600724 }
725 // non-null case so should have real mem obj
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500726 MT_MEM_OBJ_INFO* pInfo = getMemObjInfo(mem);
727 if (!pInfo) {
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500728 sprintf(str, "While trying to bind mem for obj %p, couldn't find info for mem obj %p", (void*)object, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600729 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", str);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600730 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500731 // Search for object in memory object's binding list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600732 bool32_t found = VK_FALSE;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600733 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500734 if ((*it) == object) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600735 found = VK_TRUE;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500736 break;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600737 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600738 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500739 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600740 if (found == VK_FALSE) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500741 pInfo->pObjBindings.push_front(object);
742 pInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500743 }
744
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500745 if (pObjInfo->pMemObjInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500746 clearObjectBinding(object); // Need to clear the previous object binding before setting new binding
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500747 sprintf(str, "Updating memory binding for object %p from mem obj %p to %p", object, pObjInfo->pMemObjInfo->mem, mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600748 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500749 }
750 // For image objects, make sure default memory state is correctly set
751 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600752 if (VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO == pObjInfo->sType) {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600753 if (pObjInfo->create_info.image_create_info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
754 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500755 // TODO:: More memory state transition stuff.
756 }
757 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500758 pObjInfo->pMemObjInfo = pInfo;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700759 }
760 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600761 return VK_TRUE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700762}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600763
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700764// Print details of global Obj tracking list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600765static void printObjList(
766 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700767{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500768 MT_OBJ_INFO* pInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500769 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500770 sprintf(str, "Details of Object list of size %lu elements", objectMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600771 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600772 for (map<VkObject, MT_OBJ_INFO*>::iterator ii=objectMap.begin(); ii!=objectMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500773 pInfo = (*ii).second;
774 sprintf(str, " ObjInfo %p has object %p, pMemObjInfo %p", pInfo, pInfo->object, pInfo->pMemObjInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600775 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pInfo->object, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700776 }
777}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600778
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700779// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600780static VkDeviceMemory getMemBindingFromObject(
781 const VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700782{
Tony Barbour8205d902015-04-16 15:59:00 -0600783 VkDeviceMemory mem = NULL;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500784 MT_OBJ_INFO* pObjInfo = getObjectInfo(object);
785 if (pObjInfo) {
786 if (pObjInfo->pMemObjInfo) {
787 mem = pObjInfo->pMemObjInfo->mem;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700788 }
789 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700790 char str[1024];
791 sprintf(str, "Trying to get mem binding for object %p but object has no mem binding", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600792 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700793 printObjList();
794 }
795 }
796 else {
Tobin Ehlis62086412014-11-19 16:19:28 -0700797 char str[1024];
798 sprintf(str, "Trying to get mem binding for object %p but no such object in global list", (void*)object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600799 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_INVALID_OBJECT, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700800 printObjList();
801 }
802 return mem;
803}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500804
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500805// Print details of MemObjInfo list
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600806static void printMemList(
807 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700808{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500809 MT_MEM_OBJ_INFO* pInfo = NULL;
Tobin Ehlis62086412014-11-19 16:19:28 -0700810 // Just printing each msg individually for now, may want to package these into single large print
811 char str[1024];
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500812 sprintf(str, "MEM INFO : Details of Memory Object list of size %lu elements", memObjMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600813 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500814
Tony Barbour8205d902015-04-16 15:59:00 -0600815 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500816 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500817
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500818 sprintf(str, " ===MemObjInfo at %p===", (void*)pInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600819 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500820 sprintf(str, " Mem object: %p", (void*)pInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600821 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500822 sprintf(str, " Ref Count: %u", pInfo->refCount);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600823 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500824 if (0 != pInfo->allocInfo.allocationSize) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600825 string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "{MEM}INFO : ");
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500826 sprintf(str, " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
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 } else {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800829 sprintf(str, " Mem Alloc info is NULL (alloc done by vkCreateSwapChainWSI())");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600830 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500831 }
832
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600833 sprintf(str, " VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
834 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600835 for (list<VkObject>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600836 sprintf(str, " VK OBJECT %p", (*it));
837 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500838 }
839
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600840 sprintf(str, " VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
841 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600842 for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600843 sprintf(str, " VK CB %p", (*it));
844 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700845 }
846 }
847}
848
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600849static void printCBList(
850 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700851{
Tobin Ehlis62086412014-11-19 16:19:28 -0700852 char str[1024] = {0};
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500853 MT_CB_INFO* pCBInfo = NULL;
854 sprintf(str, "Details of CB list of size %lu elements", cbMap.size());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600855 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500856
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600857 for (map<VkCmdBuffer, MT_CB_INFO*>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500858 pCBInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500859
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500860 sprintf(str, " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %p",
861 (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
862 (void*)getFenceFromId(pCBInfo->fenceId));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600863 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500864
Tony Barbour8205d902015-04-16 15:59:00 -0600865 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500866 sprintf(str, " Mem obj %p", (*it));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600867 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700868 }
869 }
870}
871
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600872static void initMemTracker(
873 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700874{
Jon Ashburnf57ea372014-12-22 13:24:15 -0700875 const char *strOpt;
876 // initialize MemTracker options
Ian Elliott7d0b5d22015-03-06 13:50:05 -0700877 getLayerOptionEnum("MemTrackerReportLevel", (uint32_t *) &g_reportingLevel);
878 g_actionIsDefault = getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &g_debugAction);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -0700879
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600880 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburnf57ea372014-12-22 13:24:15 -0700881 {
882 strOpt = getLayerOption("MemTrackerLogFilename");
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600883 if (strOpt) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700884 g_logFile = fopen(strOpt, "w");
Jon Ashburnf57ea372014-12-22 13:24:15 -0700885 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600886 if (g_logFile == NULL) {
Jon Ashburnf57ea372014-12-22 13:24:15 -0700887 g_logFile = stdout;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600888 }
Jon Ashburnf57ea372014-12-22 13:24:15 -0700889 }
890
891 // initialize Layer dispatch table
892 // TODO handle multiple GPUs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600893 PFN_vkGetProcAddr fpNextGPA;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700894 fpNextGPA = pCurObj->pGPA;
895 assert(fpNextGPA);
896
Tony Barbour8205d902015-04-16 15:59:00 -0600897 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
Chia-I Wu0f65b1e2015-01-04 23:11:43 +0800898
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600899 if (!globalLockInitialized)
900 {
901 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600902 // suggestion is to call this during vkCreateInstance(), and then we
903 // can clean it up during vkDestroyInstance(). However, that requires
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600904 // that the layer have per-instance locks. We need to come back and
905 // address this soon.
906 loader_platform_thread_create_mutex(&globalLock);
907 globalLockInitialized = 1;
908 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700909}
910
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600911VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
912 VkPhysicalDevice gpu,
913 const VkDeviceCreateInfo *pCreateInfo,
914 VkDevice *pDevice)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700915{
Jon Ashburn630e44f2015-04-08 21:33:34 -0600916 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -0700917 loader_platform_thread_once(&g_initOnce, initMemTracker);
Jon Ashburn630e44f2015-04-08 21:33:34 -0600918 VkResult result = nextTable.CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700919 // Save off device in case we need it to create Fences
920 globalDevice = *pDevice;
921 return result;
922}
923
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600924VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(
925 VkDevice device)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700926{
Tobin Ehlis62086412014-11-19 16:19:28 -0700927 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600928 sprintf(str, "Printing List details prior to vkDestroyDevice()");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600929 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600930 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_NONE, "MEM", str);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700931 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500932 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700933 printObjList();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600934 if (VK_FALSE == deleteCBInfoList()) {
935 sprintf(str, "Issue deleting global CB list in vkDestroyDevice()");
936 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, device, 0, MEMTRACK_INTERNAL_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -0700937 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700938 // Report any memory leaks
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500939 MT_MEM_OBJ_INFO* pInfo = NULL;
Tony Barbour8205d902015-04-16 15:59:00 -0600940 for (map<VkDeviceMemory, MT_MEM_OBJ_INFO*>::iterator ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -0500941 pInfo = (*ii).second;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500942
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500943 if (pInfo->allocInfo.allocationSize != 0) {
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600944 sprintf(str, "Mem Object %p has not been freed. You should clean up this memory by calling "
945 "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600946 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM", str);
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -0600947 }
Tobin Ehlis22d03232014-11-25 18:01:12 -0700948 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500949
950 // Queues persist until device is destroyed
951 deleteQueueInfoList();
952
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600953 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600954 VkResult result = nextTable.DestroyDevice(device);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700955 return result;
956}
957
Jon Ashburneb2728b2015-04-10 14:33:07 -0600958struct extProps {
959 uint32_t version;
960 const char * const name;
961};
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600962#define MEM_TRACKER_LAYER_EXT_ARRAY_SIZE 2
Jon Ashburneb2728b2015-04-10 14:33:07 -0600963static const struct extProps mtExts[MEM_TRACKER_LAYER_EXT_ARRAY_SIZE] = {
964 // TODO what is the version?
Jon Ashburnbdcd7562015-04-14 14:12:59 -0600965 0x10, "MemTracker",
966 0x10, "Validation"
Jon Ashburneb2728b2015-04-10 14:33:07 -0600967};
968
969VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600970 VkExtensionInfoType infoType,
971 uint32_t extensionIndex,
972 size_t *pDataSize,
973 void *pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -0600974{
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600975 // This entrypoint is NOT going to init its own dispatch table since loader calls here early
Jon Ashburneb2728b2015-04-10 14:33:07 -0600976 VkExtensionProperties *ext_props;
977 uint32_t *count;
978
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600979 if (pDataSize == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600980 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600981 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600982
983 switch (infoType) {
984 case VK_EXTENSION_INFO_TYPE_COUNT:
985 *pDataSize = sizeof(uint32_t);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600986 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600987 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600988 }
Jon Ashburneb2728b2015-04-10 14:33:07 -0600989 count = (uint32_t *) pData;
990 *count = MEM_TRACKER_LAYER_EXT_ARRAY_SIZE;
991 break;
992 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
993 *pDataSize = sizeof(VkExtensionProperties);
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600994 if (pData == NULL) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600995 return VK_SUCCESS;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600996 }
997 if (extensionIndex >= MEM_TRACKER_LAYER_EXT_ARRAY_SIZE) {
Jon Ashburneb2728b2015-04-10 14:33:07 -0600998 return VK_ERROR_INVALID_VALUE;
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600999 }
Jon Ashburneb2728b2015-04-10 14:33:07 -06001000 ext_props = (VkExtensionProperties *) pData;
1001 ext_props->version = mtExts[extensionIndex].version;
1002 strncpy(ext_props->extName, mtExts[extensionIndex].name,
1003 VK_MAX_EXTENSION_NAME);
1004 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
1005 break;
1006 default:
1007 return VK_ERROR_INVALID_VALUE;
1008 };
1009
1010 return VK_SUCCESS;
1011}
1012
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001013VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(
1014 VkPhysicalDevice gpu,
1015 size_t maxStringSize,
1016 size_t *pLayerCount,
1017 char* const *pOutLayers,
1018 void *pReserved)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001019{
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001020 if (gpu != NULL)
Jon Ashburn451c16f2014-11-25 11:08:42 -07001021 {
Jon Ashburn630e44f2015-04-08 21:33:34 -06001022 pCurObj = (VkBaseLayerObject *) gpu;
Ian Elliott81ac44c2015-01-13 17:52:38 -07001023 loader_platform_thread_once(&g_initOnce, initMemTracker);
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001024 VkResult result = nextTable.EnumerateLayers(gpu,
1025 maxStringSize, pLayerCount, pOutLayers, pReserved);
Jon Ashburn451c16f2014-11-25 11:08:42 -07001026 return result;
1027 } else
1028 {
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001029 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001030 return VK_ERROR_INVALID_POINTER;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001031 }
Jon Ashburn451c16f2014-11-25 11:08:42 -07001032 // This layer compatible with all GPUs
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001033 *pLayerCount = 1;
Chia-I Wua837c522014-12-16 10:47:33 +08001034 strncpy((char *) pOutLayers[0], "MemTracker", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001035 return VK_SUCCESS;
Jon Ashburn451c16f2014-11-25 11:08:42 -07001036 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001037}
1038
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001039VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
1040 VkDevice device,
1041 uint32_t queueNodeIndex,
1042 uint32_t queueIndex,
1043 VkQueue *pQueue)
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001044{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001045 VkResult result = nextTable.GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001046 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001047 loader_platform_thread_lock_mutex(&globalLock);
1048 addQueueInfo(*pQueue);
1049 loader_platform_thread_unlock_mutex(&globalLock);
1050 }
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001051 return result;
1052}
1053
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001054VK_LAYER_EXPORT VkResult VKAPI vkQueueAddMemReferences(
1055 VkQueue queue,
1056 uint32_t count,
1057 const VkDeviceMemory *pMems)
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001058{
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001059 VkResult result = nextTable.QueueAddMemReferences(queue, count, pMems);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001060 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001061 loader_platform_thread_lock_mutex(&globalLock);
1062
1063 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
1064 if (pQueueInfo == NULL) {
1065 char str[1024];
1066 sprintf(str, "Unknown Queue %p", queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001067 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001068 } else {
Tony Barboura938abb2015-04-22 11:36:22 -06001069 for (uint32_t i = 0; i < count; i++) {
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001070 if (checkMemRef(queue, pMems[i]) == VK_TRUE) {
1071 // Alread in list, just warn
1072 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001073 sprintf(str, "Request to add a memory reference (%p) to Queue %p -- ref is already "
1074 "present in the queue's reference list", pMems[i], queue);
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001075 layerCbMsg(VK_DBG_MSG_WARNING, VK_VALIDATION_LEVEL_0, pMems[i], 0, MEMTRACK_INVALID_MEM_REF, "MEM", str);
1076 } else {
1077 // Add to queue's memory reference list
1078 pQueueInfo->pMemRefList.push_front(pMems[i]);
1079 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001080 }
1081 }
1082 loader_platform_thread_unlock_mutex(&globalLock);
1083 }
1084 return result;
1085}
1086
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001087VK_LAYER_EXPORT VkResult VKAPI vkQueueRemoveMemReferences(
1088 VkQueue queue,
1089 uint32_t count,
1090 const VkDeviceMemory *pMems)
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001091{
1092 // TODO : Decrement ref count for this memory reference on this queue. Remove if ref count is zero.
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001093 VkResult result = nextTable.QueueRemoveMemReferences(queue, count, pMems);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001094 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001095 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001096
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001097 MT_QUEUE_INFO *pQueueInfo = queueMap[queue];
1098 if (pQueueInfo == NULL) {
1099 char str[1024];
1100 sprintf(str, "Unknown Queue %p", queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001101 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, queue, 0, MEMTRACK_INVALID_QUEUE, "MEM", str);
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001102 } else {
Tony Barboura938abb2015-04-22 11:36:22 -06001103 for (uint32_t i = 0; i < count; i++) {
Courtney Goeltzenleuchter3dd433a2015-04-27 15:00:47 -06001104 for (list<VkDeviceMemory>::iterator it = pQueueInfo->pMemRefList.begin(); it != pQueueInfo->pMemRefList.end();) {
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001105 if ((*it) == pMems[i]) {
1106 it = pQueueInfo->pMemRefList.erase(it);
Courtney Goeltzenleuchter3dd433a2015-04-27 15:00:47 -06001107 } else {
1108 ++it;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001109 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001110 }
1111 }
1112 }
1113 loader_platform_thread_unlock_mutex(&globalLock);
1114 }
1115 return result;
1116}
1117
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001118VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(
1119 VkQueue queue,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001120 uint32_t cmdBufferCount,
1121 const VkCmdBuffer *pCmdBuffers,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001122 VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001123{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001124 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001125 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001126 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001127 uint64_t fenceId = addFenceInfo(fence, queue);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001128
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001129 printMemList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001130 printCBList();
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001131 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001132 pCBInfo = getCBInfo(pCmdBuffers[i]);
1133 pCBInfo->fenceId = fenceId;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001134 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001135
Mark Lobodzinski2c01d182015-04-17 11:44:25 -05001136 validateQueueMemRefs(queue, cmdBufferCount, pCmdBuffers);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001137
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001138 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001139 VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, getFenceFromId(fenceId));
Courtney Goeltzenleuchtercfedf362015-04-02 13:39:07 -06001140 return result;
1141}
1142
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001143VK_LAYER_EXPORT VkResult VKAPI vkAllocMemory(
1144 VkDevice device,
1145 const VkMemoryAllocInfo *pAllocInfo,
1146 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001147{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001148 VkResult result = nextTable.AllocMemory(device, pAllocInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001149 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001150 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001151 addMemObjInfo(*pMem, pAllocInfo);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001152 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001153 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001154 return result;
1155}
1156
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001157VK_LAYER_EXPORT VkResult VKAPI vkFreeMemory(
1158 VkDevice device,
1159 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001160{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001161 /* From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed. Before
Tobin Ehlisa747e682014-11-25 14:47:20 -07001162 * freeing a memory object, an application must ensure the memory object is unbound from
1163 * all API objects referencing it and that it is not referenced by any queued command buffers
1164 */
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001165 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001166 if (VK_FALSE == freeMemObjInfo(mem, false)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001167 char str[1024];
1168 sprintf(str, "Issue while freeing mem obj %p", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001169 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_FREE_MEM_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001170 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001171 printMemList();
1172 printObjList();
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001173 printCBList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001174 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001175 VkResult result = nextTable.FreeMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001176 return result;
1177}
1178
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001179VK_LAYER_EXPORT VkResult VKAPI vkSetMemoryPriority(
1180 VkDevice device,
1181 VkDeviceMemory mem,
1182 VkMemoryPriority priority)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001183{
1184 // TODO : Update tracking for this alloc
1185 // Make sure memory is not pinned, which can't have priority set
Mike Stroyan230e6252015-04-17 12:36:38 -06001186 VkResult result = nextTable.SetMemoryPriority(device, mem, priority);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001187 return result;
1188}
1189
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001190VK_LAYER_EXPORT VkResult VKAPI vkMapMemory(
1191 VkDevice device,
1192 VkDeviceMemory mem,
1193 VkDeviceSize offset,
1194 VkDeviceSize size,
1195 VkFlags flags,
1196 void **ppData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001197{
1198 // TODO : Track when memory is mapped
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001199 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001200 MT_MEM_OBJ_INFO *pMemObj = getMemObjInfo(mem);
Tony Barbour8205d902015-04-16 15:59:00 -06001201 if ((pMemObj->allocInfo.memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001202 char str[1024];
Tony Barbour8205d902015-04-16 15:59:00 -06001203 sprintf(str, "Mapping Memory (%p) without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set", (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001204 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, mem, 0, MEMTRACK_INVALID_STATE, "MEM", str);
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001205 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001206 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001207 VkResult result = nextTable.MapMemory(device, mem, offset, size, flags, ppData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001208 return result;
1209}
1210
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001211VK_LAYER_EXPORT VkResult VKAPI vkUnmapMemory(
1212 VkDevice device,
1213 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001214{
1215 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
1216 // Make sure that memory was ever mapped to begin with
Mike Stroyan230e6252015-04-17 12:36:38 -06001217 VkResult result = nextTable.UnmapMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001218 return result;
1219}
1220
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001221VK_LAYER_EXPORT VkResult VKAPI vkPinSystemMemory(
1222 VkDevice device,
1223 const void *pSysMem,
1224 size_t memSize,
1225 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001226{
1227 // TODO : Track this
1228 // Verify that memory is actually pinnable
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001229 VkResult result = nextTable.PinSystemMemory(device, pSysMem, memSize, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001230 return result;
1231}
1232
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001233VK_LAYER_EXPORT VkResult VKAPI vkOpenSharedMemory(
1234 VkDevice device,
1235 const VkMemoryOpenInfo *pOpenInfo,
1236 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001237{
1238 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001239 VkResult result = nextTable.OpenSharedMemory(device, pOpenInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001240 return result;
1241}
1242
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001243VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerMemory(
1244 VkDevice device,
1245 const VkPeerMemoryOpenInfo *pOpenInfo,
1246 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001247{
1248 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001249 VkResult result = nextTable.OpenPeerMemory(device, pOpenInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001250 return result;
1251}
1252
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001253VK_LAYER_EXPORT VkResult VKAPI vkOpenPeerImage(
1254 VkDevice device,
1255 const VkPeerImageOpenInfo *pOpenInfo,
1256 VkImage *pImage,
1257 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001258{
1259 // TODO : Track this
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001260 VkResult result = nextTable.OpenPeerImage(device, pOpenInfo, pImage, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001261 return result;
1262}
1263
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001264VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(
1265 VkDevice device,
1266 VkObjectType objType,
1267 VkObject object)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001268{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001269 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001270
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001271 // First check if this is a CmdBuffer
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001272 if (NULL != getCBInfo((VkCmdBuffer)object)) {
1273 deleteCBInfo((VkCmdBuffer)object);
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001274 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001275
1276 if (objectMap.find(object) != objectMap.end()) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001277 MT_OBJ_INFO* pDelInfo = objectMap[object];
1278 if (pDelInfo->pMemObjInfo) {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001279 // Wsi allocated Memory is tied to image object so clear the binding and free that memory automatically
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001280 if (0 == pDelInfo->pMemObjInfo->allocInfo.allocationSize) { // Wsi allocated memory has NULL allocInfo w/ 0 size
Tony Barbour8205d902015-04-16 15:59:00 -06001281 VkDeviceMemory memToFree = pDelInfo->pMemObjInfo->mem;
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001282 clearObjectBinding(object);
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -06001283 freeMemObjInfo(memToFree, true);
1284 }
1285 else {
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001286 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001287 sprintf(str, "Destroying obj %p that is still bound to memory object %p\nYou should first clear binding "
1288 "by calling vkQueueBindObjectMemory(queue, %p, 0, VK_NULL_HANDLE, 0)",
1289 object, (void*)pDelInfo->pMemObjInfo->mem, object);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001290 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_DESTROY_OBJECT_ERROR, "MEM", str);
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001291 // From the spec : If an object has previous memory binding, it is required to unbind memory
1292 // from an API object before it is destroyed.
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001293 clearObjectBinding(object);
1294 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001295 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001296 delete pDelInfo;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001297 objectMap.erase(object);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001298 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05001299
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001300 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001301 VkResult result = nextTable.DestroyObject(device, objType, object);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001302 return result;
1303}
1304
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001305VK_LAYER_EXPORT VkResult VKAPI vkGetObjectInfo(
1306 VkDevice device,
1307 VkObjectType objType,
1308 VkObject object,
1309 VkObjectInfoType infoType,
1310 size_t *pDataSize,
1311 void *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001312{
1313 // TODO : What to track here?
Mark Lobodzinskicf26e072015-04-16 11:44:05 -05001314 // Could potentially save returned mem requirements and validate values passed into QueueBindObjectMemory for this object
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001315 // From spec : The only objects that are guaranteed to have no external memory requirements are devices, queues,
1316 // command buffers, shaders and memory objects.
Mike Stroyan230e6252015-04-17 12:36:38 -06001317 VkResult result = nextTable.GetObjectInfo(device, objType, object, infoType, pDataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001318 return result;
1319}
1320
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001321VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemory(
1322 VkQueue queue,
1323 VkObjectType objType,
1324 VkObject object,
1325 uint32_t allocationIdx,
1326 VkDeviceMemory mem,
1327 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001328{
Mike Stroyan230e6252015-04-17 12:36:38 -06001329 VkResult result = nextTable.QueueBindObjectMemory(queue, objType, object, allocationIdx, mem, offset);
1330 loader_platform_thread_lock_mutex(&globalLock);
1331 // Track objects tied to memory
1332 if (VK_FALSE == updateObjectBinding(object, mem)) {
1333 char str[1024];
1334 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
1335 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
1336 }
1337 printObjList();
1338 printMemList();
1339 loader_platform_thread_unlock_mutex(&globalLock);
1340 return result;
1341}
1342
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001343VK_LAYER_EXPORT VkResult VKAPI vkQueueBindObjectMemoryRange(
1344 VkQueue queue,
1345 VkObjectType objType,
1346 VkObject object,
1347 uint32_t allocationIdx,
1348 VkDeviceSize rangeOffset,
1349 VkDeviceSize rangeSize,
1350 VkDeviceMemory mem,
1351 VkDeviceSize memOffset)
Mike Stroyan230e6252015-04-17 12:36:38 -06001352{
1353 VkResult result = nextTable.QueueBindObjectMemoryRange(queue, objType, object, allocationIdx, rangeOffset, rangeSize, mem, memOffset);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001354 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001355 // Track objects tied to memory
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001356 if (VK_FALSE == updateObjectBinding(object, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001357 char str[1024];
1358 sprintf(str, "Unable to set object %p binding to mem obj %p", (void*)object, (void*)mem);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001359 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, object, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001360 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001361 printObjList();
1362 printMemList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001363 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001364 return result;
1365}
1366
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001367VK_LAYER_EXPORT VkResult VKAPI vkCreateFence(
1368 VkDevice device,
1369 const VkFenceCreateInfo *pCreateInfo,
1370 VkFence *pFence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001371{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001372 VkResult result = nextTable.CreateFence(device, pCreateInfo, pFence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001373 if (VK_SUCCESS == result) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001374 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001375 addObjectInfo(*pFence, pCreateInfo->sType, pCreateInfo, sizeof(VkFenceCreateInfo), "fence");
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001376 loader_platform_thread_unlock_mutex(&globalLock);
1377 }
1378 return result;
1379}
1380
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001381VK_LAYER_EXPORT VkResult VKAPI vkResetFences(
1382 VkDevice device,
1383 uint32_t fenceCount,
1384 VkFence *pFences)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001385{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001386 VkResult result = nextTable.ResetFences(device, fenceCount, pFences);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001387 if (VK_SUCCESS == result) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001388 loader_platform_thread_lock_mutex(&globalLock);
1389 // Reset fence state in fenceCreateInfo structure
1390 for (uint32_t i = 0; i < fenceCount; i++) {
1391 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1392 if (pObjectInfo != NULL) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001393 // Validate fences in SIGNALED state
Tobin Ehlisf29da382015-04-15 07:46:12 -06001394 if (!(pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Mark Lobodzinski56945182015-04-09 13:46:09 -05001395 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001396 sprintf(str, "Fence %p submitted to VkResetFences in UNSIGNALED STATE", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001397 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM", str);
1398 result = VK_ERROR_INVALID_VALUE;
Mark Lobodzinski56945182015-04-09 13:46:09 -05001399 }
1400 else {
1401 pObjectInfo->create_info.fence_create_info.flags =
Tobin Ehlisf29da382015-04-15 07:46:12 -06001402 static_cast<VkFenceCreateFlags>(pObjectInfo->create_info.fence_create_info.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski56945182015-04-09 13:46:09 -05001403 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001404 }
1405 }
1406 loader_platform_thread_unlock_mutex(&globalLock);
1407 }
1408 return result;
1409}
1410
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001411VK_LAYER_EXPORT VkResult VKAPI vkGetFenceStatus(
1412 VkDevice device,
1413 VkFence fence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001414{
Mike Stroyan230e6252015-04-17 12:36:38 -06001415 VkResult result = nextTable.GetFenceStatus(device, fence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001416 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001417 loader_platform_thread_lock_mutex(&globalLock);
1418 updateFenceTracking(fence);
1419 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001420 }
1421 return result;
1422}
1423
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001424VK_LAYER_EXPORT VkResult VKAPI vkWaitForFences(
1425 VkDevice device,
1426 uint32_t fenceCount,
1427 const VkFence *pFences,
1428 bool32_t waitAll,
1429 uint64_t timeout)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001430{
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001431 // Verify fence status of submitted fences
1432 for(uint32_t i = 0; i < fenceCount; i++) {
1433 MT_OBJ_INFO* pObjectInfo = getObjectInfo(pFences[i]);
1434 if (pObjectInfo != NULL) {
Tobin Ehlisf29da382015-04-15 07:46:12 -06001435 if (pObjectInfo->create_info.fence_create_info.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001436 char str[1024];
Mark Lobodzinski610be622015-04-14 14:09:32 -05001437 sprintf(str, "VkWaitForFences specified fence %p already in SIGNALED state.", pFences[i]);
Tobin Ehlisf29da382015-04-15 07:46:12 -06001438 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 -05001439 }
1440 }
1441 }
1442
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001443 VkResult result = nextTable.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001444 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001445
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001446 if (VK_SUCCESS == result) {
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001447 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001448 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001449 updateFenceTracking(pFences[i]);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001450 }
1451 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001452 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001453 loader_platform_thread_unlock_mutex(&globalLock);
1454 return result;
1455}
1456
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001457VK_LAYER_EXPORT VkResult VKAPI vkQueueWaitIdle(
1458 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001459{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001460 VkResult result = nextTable.QueueWaitIdle(queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001461 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001462 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001463 retireQueueFences(queue);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001464 loader_platform_thread_unlock_mutex(&globalLock);
1465 }
1466 return result;
1467}
1468
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001469VK_LAYER_EXPORT VkResult VKAPI vkDeviceWaitIdle(
1470 VkDevice device)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001471{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001472 VkResult result = nextTable.DeviceWaitIdle(device);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001473 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001474 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001475 retireDeviceFences(device);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001476 loader_platform_thread_unlock_mutex(&globalLock);
1477 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001478 return result;
1479}
1480
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001481VK_LAYER_EXPORT VkResult VKAPI vkCreateEvent(
1482 VkDevice device,
1483 const VkEventCreateInfo *pCreateInfo,
1484 VkEvent *pEvent)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001485{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001486 VkResult result = nextTable.CreateEvent(device, pCreateInfo, pEvent);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001487 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001488 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001489 addObjectInfo(*pEvent, pCreateInfo->sType, pCreateInfo, sizeof(VkEventCreateInfo), "event");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001490 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001491 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001492 return result;
1493}
1494
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001495VK_LAYER_EXPORT VkResult VKAPI vkCreateQueryPool(
1496 VkDevice device,
1497 const VkQueryPoolCreateInfo *pCreateInfo,
1498 VkQueryPool *pQueryPool)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001499{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001500 VkResult result = nextTable.CreateQueryPool(device, pCreateInfo, pQueryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001501 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001502 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001503 addObjectInfo(*pQueryPool, pCreateInfo->sType, pCreateInfo, sizeof(VkQueryPoolCreateInfo), "query_pool");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001504 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001505 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001506 return result;
1507}
1508
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001509VK_LAYER_EXPORT VkResult VKAPI vkCreateBuffer(
1510 VkDevice device,
1511 const VkBufferCreateInfo *pCreateInfo,
1512 VkBuffer *pBuffer)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001513{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001514 VkResult result = nextTable.CreateBuffer(device, pCreateInfo, pBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001515 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001516 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001517 addObjectInfo(*pBuffer, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferCreateInfo), "buffer");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001518 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001519 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001520 return result;
1521}
1522
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001523VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(
1524 VkDevice device,
1525 const VkBufferViewCreateInfo *pCreateInfo,
1526 VkBufferView *pView)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001527{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001528 VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001529 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001530 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001531 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkBufferViewCreateInfo), "buffer_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001532 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001533 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001534 return result;
1535}
1536
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001537VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(
1538 VkDevice device,
1539 const VkImageCreateInfo *pCreateInfo,
1540 VkImage *pImage)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001541{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001542 VkResult result = nextTable.CreateImage(device, pCreateInfo, pImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001543 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001544 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001545 addObjectInfo(*pImage, pCreateInfo->sType, pCreateInfo, sizeof(VkImageCreateInfo), "image");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001546 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001547 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001548 return result;
1549}
1550
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001551VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(
1552 VkDevice device,
1553 const VkImageViewCreateInfo *pCreateInfo,
1554 VkImageView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001555{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001556 VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001557 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001558 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001559 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkImageViewCreateInfo), "image_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001560 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001561 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001562 return result;
1563}
1564
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001565VK_LAYER_EXPORT VkResult VKAPI vkCreateColorAttachmentView(
1566 VkDevice device,
1567 const VkColorAttachmentViewCreateInfo *pCreateInfo,
1568 VkColorAttachmentView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001569{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001570 VkResult result = nextTable.CreateColorAttachmentView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001571 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001572 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001573 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkColorAttachmentViewCreateInfo), "color_attachment_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001574 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001575 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001576 return result;
1577}
1578
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001579VK_LAYER_EXPORT VkResult VKAPI vkCreateDepthStencilView(
1580 VkDevice device,
1581 const VkDepthStencilViewCreateInfo *pCreateInfo,
1582 VkDepthStencilView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001583{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001584 VkResult result = nextTable.CreateDepthStencilView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001585 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001586 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001587 addObjectInfo(*pView, pCreateInfo->sType, pCreateInfo, sizeof(VkDepthStencilViewCreateInfo), "ds_view");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001588 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001589 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001590 return result;
1591}
1592
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001593VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(
1594 VkDevice device,
1595 const VkShaderCreateInfo *pCreateInfo,
1596 VkShader *pShader)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001597{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001598 VkResult result = nextTable.CreateShader(device, pCreateInfo, pShader);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001599 return result;
1600}
1601
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001602VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(
1603 VkDevice device,
1604 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1605 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001606{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001607 VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
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(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
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
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001616VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001617 VkDevice device,
1618 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1619 VkPipeline basePipeline,
1620 VkPipeline *pPipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001621{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001622 VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001623 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001624 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001625 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo), "graphics_pipeline");
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -06001626 loader_platform_thread_unlock_mutex(&globalLock);
1627 }
1628 return result;
1629}
1630
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001631VK_LAYER_EXPORT VkResult VKAPI vkCreateComputePipeline(
1632 VkDevice device,
1633 const VkComputePipelineCreateInfo *pCreateInfo,
1634 VkPipeline *pPipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001635{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001636 VkResult result = nextTable.CreateComputePipeline(device, pCreateInfo, pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001637 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001638 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001639 addObjectInfo(*pPipeline, pCreateInfo->sType, pCreateInfo, sizeof(VkComputePipelineCreateInfo), "compute_pipeline");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001640 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001641 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001642 return result;
1643}
1644
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001645VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(
1646 VkDevice device,
1647 const VkSamplerCreateInfo *pCreateInfo,
1648 VkSampler *pSampler)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001649{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001650 VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001651 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001652 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001653 addObjectInfo(*pSampler, pCreateInfo->sType, pCreateInfo, sizeof(VkSamplerCreateInfo), "sampler");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001654 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001655 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001656 return result;
1657}
1658
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001659VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(
1660 VkDevice device,
1661 const VkDynamicVpStateCreateInfo *pCreateInfo,
1662 VkDynamicVpState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001663{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001664 VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001665 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001666 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001667 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo), "viewport_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001668 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001669 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001670 return result;
1671}
1672
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001673VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(
1674 VkDevice device,
1675 const VkDynamicRsStateCreateInfo *pCreateInfo,
1676 VkDynamicRsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001677{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001678 VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001679 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001680 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001681 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo), "raster_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001682 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001683 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001684 return result;
1685}
1686
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001687VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(
1688 VkDevice device,
1689 const VkDynamicCbStateCreateInfo *pCreateInfo,
1690 VkDynamicCbState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001691{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001692 VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001693 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001694 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001695 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo), "cb_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001696 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001697 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001698 return result;
1699}
1700
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001701VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(
1702 VkDevice device,
1703 const VkDynamicDsStateCreateInfo *pCreateInfo,
1704 VkDynamicDsState *pState)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001705{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001706 VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001707 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001708 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001709 addObjectInfo(*pState, pCreateInfo->sType, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo), "ds_state");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001710 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001711 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001712 return result;
1713}
1714
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001715VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(
1716 VkDevice device,
1717 const VkCmdBufferCreateInfo *pCreateInfo,
1718 VkCmdBuffer *pCmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001719{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001720 VkResult result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001721 // At time of cmd buffer creation, create global cmd buffer info for the returned cmd buffer
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001722 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001723 if (*pCmdBuffer)
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001724 addCBInfo(*pCmdBuffer);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001725 printCBList();
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001726 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001727 return result;
1728}
1729
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001730VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(
1731 VkCmdBuffer cmdBuffer,
1732 const VkCmdBufferBeginInfo *pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001733{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001734 // 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 -05001735 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1736 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001737 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001738 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001739 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001740 sprintf(str, "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
1741 "You must check CB flag before this call.", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001742 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 -07001743 }
1744 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001745 VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001746 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001747 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001748 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001749 return result;
1750}
1751
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001752VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(
1753 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001754{
1755 // TODO : Anything to do here?
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001756 VkResult result = nextTable.EndCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001757 return result;
1758}
1759
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001760VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(
1761 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001762{
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001763 // Verify that CB is complete (not in-flight)
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001764 MT_CB_INFO* pCBInfo = getCBInfo(cmdBuffer);
1765 if (pCBInfo && (!fenceRetired(pCBInfo->fenceId))) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001766 bool32_t cbDone = checkCBCompleted(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001767 if (VK_FALSE == cbDone) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001768 char str[1024];
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001769 sprintf(str, "Resetting CB %p before it has completed. You must check CB flag before "
1770 "calling vkResetCommandBuffer().", cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001771 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 -07001772 }
1773 }
1774 // Clear memory references as this point.
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001775 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001776 freeCBBindings(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001777 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001778 VkResult result = nextTable.ResetCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001779 return result;
1780}
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001781// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001782// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001783VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(
1784 VkCmdBuffer cmdBuffer,
1785 VkPipelineBindPoint pipelineBindPoint,
1786 VkPipeline pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001787{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001788#if 0
1789 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1790 if (getPipeline(pipeline)) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001791 MT_CB_INFO *pCBInfo = getCBInfo(cmdBuffer);
1792 if (pCBInfo) {
1793 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001794 } else {
1795 char str[1024];
1796 sprintf(str, "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001797 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 -07001798 }
1799 }
1800 else {
1801 char str[1024];
1802 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001803 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 -07001804 }
1805#endif
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001806 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
1807}
1808
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001809VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(
1810 VkCmdBuffer cmdBuffer,
1811 VkStateBindPoint stateBindPoint,
1812 VkDynamicStateObject state)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001813{
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001814 MT_OBJ_INFO *pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001815 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001816 MT_CB_INFO *pCmdBuf = getCBInfo(cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001817 if (!pCmdBuf) {
1818 char str[1024];
1819 sprintf(str, "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001820 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_INVALID_CB, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001821 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001822 pObjInfo = getObjectInfo(state);
1823 if (!pObjInfo) {
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001824 char str[1024];
1825 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001826 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, MEMTRACK_INVALID_OBJECT, "DD", str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001827 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001828 pCmdBuf->pDynamicState[stateBindPoint] = pObjInfo;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001829 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001830 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001831}
1832
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001833VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001834 VkCmdBuffer cmdBuffer,
1835 VkPipelineBindPoint pipelineBindPoint,
1836 uint32_t firstSet,
1837 uint32_t setCount,
1838 const VkDescriptorSet *pDescriptorSets,
1839 uint32_t dynamicOffsetCount,
1840 const uint32_t *pDynamicOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001841{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001842 // 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 -06001843 nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001844}
1845
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001846VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001847 VkCmdBuffer cmdBuffer,
1848 uint32_t startBinding,
1849 uint32_t bindingCount,
1850 const VkBuffer *pBuffers,
1851 const VkDeviceSize *pOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001852{
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001853 nextTable.CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001854}
1855
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001856VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(
1857 VkCmdBuffer cmdBuffer,
1858 VkBuffer buffer,
1859 VkDeviceSize offset,
1860 VkIndexType indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001861{
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001862 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001863}
1864
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001865VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(
1866 VkCmdBuffer cmdBuffer,
1867 VkBuffer buffer,
1868 VkDeviceSize offset,
1869 uint32_t count,
1870 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001871{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001872 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001873 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001874 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001875 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001876 sprintf(str, "In vkCmdDrawIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1877 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001878 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001879 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001880 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001881}
1882
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001883VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(
1884 VkCmdBuffer cmdBuffer,
1885 VkBuffer buffer,
1886 VkDeviceSize offset,
1887 uint32_t count,
1888 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001889{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001890 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001891 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001892 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001893 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001894 sprintf(str, "In vkCmdDrawIndexedIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1895 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001896 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001897 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001898 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001899}
1900
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001901VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(
1902 VkCmdBuffer cmdBuffer,
1903 VkBuffer buffer,
1904 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001905{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001906 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001907 VkDeviceMemory mem = getMemBindingFromObject(buffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001908 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001909 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001910 sprintf(str, "In vkCmdDispatchIndirect() call unable to update binding of buffer %p to cmdBuffer %p", buffer, cmdBuffer);
1911 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001912 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001913 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001914 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001915}
1916
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001917VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(
1918 VkCmdBuffer cmdBuffer,
1919 VkBuffer srcBuffer,
1920 VkBuffer destBuffer,
1921 uint32_t regionCount,
1922 const VkBufferCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001923{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001924 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001925 VkDeviceMemory mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001926 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001927 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001928 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1929 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001930 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001931 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001932 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001933 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001934 sprintf(str, "In vkCmdCopyBuffer() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
1935 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001936 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001937 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001938 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001939}
1940
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001941VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
1942 VkCmdBuffer cmdBuffer,
1943 VkImage srcImage,
1944 VkImageLayout srcImageLayout,
1945 VkImage destImage,
1946 VkImageLayout destImageLayout,
1947 uint32_t regionCount,
1948 const VkImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001949{
1950 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001951 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001952}
1953
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001954VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
1955 VkCmdBuffer cmdBuffer,
1956 VkImage srcImage,
1957 VkImageLayout srcImageLayout,
1958 VkImage destImage,
1959 VkImageLayout destImageLayout,
1960 uint32_t regionCount,
1961 const VkImageBlit *pRegions)
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001962{
1963 // TODO : Each image will have mem mapping so track them
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001964 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06001965}
1966
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001967VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
1968 VkCmdBuffer cmdBuffer,
1969 VkBuffer srcBuffer,
1970 VkImage destImage,
1971 VkImageLayout destImageLayout,
1972 uint32_t regionCount,
1973 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001974{
1975 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001976 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06001977 VkDeviceMemory mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001978 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001979 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001980 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
1981 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001982 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06001983
1984 mem = getMemBindingFromObject(srcBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001985 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07001986 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001987 sprintf(str, "In vkCmdCopyMemoryToImage() call unable to update binding of srcBuffer %p to cmdBuffer %p", srcBuffer, cmdBuffer);
1988 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07001989 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001990 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06001991 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001992}
1993
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001994VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
1995 VkCmdBuffer cmdBuffer,
1996 VkImage srcImage,
1997 VkImageLayout srcImageLayout,
1998 VkBuffer destBuffer,
1999 uint32_t regionCount,
2000 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002001{
2002 // TODO : Track this
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002003 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002004 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002005 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002006 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002007 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2008 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002009 }
Mark Lobodzinski15427102015-02-18 16:38:17 -06002010 mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002011 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002012 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002013 sprintf(str, "In vkCmdCopyImageToMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
2014 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002015 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002016 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06002017 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002018}
2019
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002020VK_LAYER_EXPORT void VKAPI vkCmdCloneImageData(
2021 VkCmdBuffer cmdBuffer,
2022 VkImage srcImage,
2023 VkImageLayout srcImageLayout,
2024 VkImage destImage,
2025 VkImageLayout destImageLayout)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002026{
2027 // TODO : Each image will have mem mapping so track them
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002028 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002029 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002030 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002031 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002032 sprintf(str, "In vkCmdCloneImageData() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2033 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002034 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002035 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002036 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002037 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002038 sprintf(str, "In vkCmdCloneImageData() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2039 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002040 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002041 loader_platform_thread_unlock_mutex(&globalLock);
Mike Stroyan55658c22014-12-04 11:08:39 +00002042 nextTable.CmdCloneImageData(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002043}
2044
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002045VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
2046 VkCmdBuffer cmdBuffer,
2047 VkBuffer destBuffer,
2048 VkDeviceSize destOffset,
2049 VkDeviceSize dataSize,
2050 const uint32_t *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002051{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002052 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002053 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002054 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002055 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002056 sprintf(str, "In vkCmdUpdateMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
2057 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002058 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002059 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002060 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002061}
2062
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002063VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
2064 VkCmdBuffer cmdBuffer,
2065 VkBuffer destBuffer,
2066 VkDeviceSize destOffset,
2067 VkDeviceSize fillSize,
2068 uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002069{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002070 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002071 VkDeviceMemory mem = getMemBindingFromObject(destBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002072 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002073 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002074 sprintf(str, "In vkCmdFillMemory() call unable to update binding of destBuffer %p to cmdBuffer %p", destBuffer, cmdBuffer);
2075 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002076 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002077 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis84c521c2015-01-19 08:42:29 -07002078 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002079}
2080
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002081VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2082 VkCmdBuffer cmdBuffer,
2083 VkImage image,
2084 VkImageLayout imageLayout,
2085 VkClearColor color,
2086 uint32_t rangeCount,
2087 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002088{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002089 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002090 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002091 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002092 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002093 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002094 sprintf(str, "In vkCmdClearColorImage() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
2095 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002096 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002097 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06002098 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, color, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002099}
2100
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002101VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(
2102 VkCmdBuffer cmdBuffer,
2103 VkImage image,
2104 VkImageLayout imageLayout,
2105 float depth,
2106 uint32_t stencil,
2107 uint32_t rangeCount,
2108 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002109{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002110 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002111 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002112 VkDeviceMemory mem = getMemBindingFromObject(image);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002113 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002114 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002115 sprintf(str, "In vkCmdClearDepthStencil() call unable to update binding of image buffer %p to cmdBuffer %p", image, cmdBuffer);
2116 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002117 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002118 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -06002119 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002120}
2121
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002122VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
2123 VkCmdBuffer cmdBuffer,
2124 VkImage srcImage,
2125 VkImageLayout srcImageLayout,
2126 VkImage destImage,
2127 VkImageLayout destImageLayout,
2128 uint32_t regionCount,
2129 const VkImageResolve *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002130{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002131 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002132 VkDeviceMemory mem = getMemBindingFromObject(srcImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002133 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002134 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002135 sprintf(str, "In vkCmdResolveImage() call unable to update binding of srcImage buffer %p to cmdBuffer %p", srcImage, cmdBuffer);
2136 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002137 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002138 mem = getMemBindingFromObject(destImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002139 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002140 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002141 sprintf(str, "In vkCmdResolveImage() call unable to update binding of destImage buffer %p to cmdBuffer %p", destImage, cmdBuffer);
2142 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002143 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002144 loader_platform_thread_unlock_mutex(&globalLock);
Tony Barbour11f74372015-04-13 15:02:52 -06002145 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002146}
2147
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002148VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(
2149 VkCmdBuffer cmdBuffer,
2150 VkQueryPool queryPool,
2151 uint32_t slot,
2152 VkFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002153{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002154 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002155 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002156 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002157 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002158 sprintf(str, "In vkCmdBeginQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2159 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002160 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002161 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002162 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2163}
2164
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002165VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(
2166 VkCmdBuffer cmdBuffer,
2167 VkQueryPool queryPool,
2168 uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002169{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002170 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002171 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002172 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002173 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002174 sprintf(str, "In vkCmdEndQuery() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2175 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002176 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002177 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002178 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2179}
2180
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002181VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(
2182 VkCmdBuffer cmdBuffer,
2183 VkQueryPool queryPool,
2184 uint32_t startQuery,
2185 uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002186{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002187 loader_platform_thread_lock_mutex(&globalLock);
Tony Barbour8205d902015-04-16 15:59:00 -06002188 VkDeviceMemory mem = getMemBindingFromObject(queryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002189 if (VK_FALSE == updateCBBinding(cmdBuffer, mem)) {
Tobin Ehlis62086412014-11-19 16:19:28 -07002190 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002191 sprintf(str, "In vkCmdResetQueryPool() call unable to update binding of queryPool buffer %p to cmdBuffer %p", queryPool, cmdBuffer);
2192 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
Tobin Ehlis62086412014-11-19 16:19:28 -07002193 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002194 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002195 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2196}
2197
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002198VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(
2199 VkInstance instance,
2200 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
2201 void *pUserData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002202{
Tobin Ehlis62086412014-11-19 16:19:28 -07002203 // This layer intercepts callbacks
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002204 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 -07002205 if (!pNewDbgFuncNode)
Tony Barbour8205d902015-04-16 15:59:00 -06002206 return VK_ERROR_OUT_OF_HOST_MEMORY;
Tobin Ehlis62086412014-11-19 16:19:28 -07002207 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2208 pNewDbgFuncNode->pUserData = pUserData;
Jon Ashburnf57ea372014-12-22 13:24:15 -07002209 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2210 g_pDbgFunctionHead = pNewDbgFuncNode;
Jon Ashburne4722392015-03-03 15:07:15 -07002211 // force callbacks if DebugAction hasn't been set already other than initial value
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002212 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002213 g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
Courtney Goeltzenleuchter9e3aafa2015-03-04 15:47:34 -07002214 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002215 VkResult result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002216 return result;
2217}
2218
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002219VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(
2220 VkInstance instance,
2221 VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002222{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002223 VK_LAYER_DBG_FUNCTION_NODE *pInfo = g_pDbgFunctionHead;
2224 VK_LAYER_DBG_FUNCTION_NODE *pPrev = pInfo;
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002225 while (pInfo) {
2226 if (pInfo->pfnMsgCallback == pfnMsgCallback) {
2227 pPrev->pNext = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002228 if (g_pDbgFunctionHead == pInfo) {
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002229 g_pDbgFunctionHead = pInfo->pNext;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002230 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002231 free(pInfo);
Tobin Ehlis62086412014-11-19 16:19:28 -07002232 break;
2233 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002234 pPrev = pInfo;
2235 pInfo = pInfo->pNext;
Tobin Ehlis62086412014-11-19 16:19:28 -07002236 }
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002237 if (g_pDbgFunctionHead == NULL) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002238 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002239 g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002240 } else {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002241 g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
Mark Lobodzinski283a4c22015-03-24 16:29:24 -05002242 }
Jon Ashburne4722392015-03-03 15:07:15 -07002243 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002244 VkResult result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002245 return result;
2246}
2247
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002248VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapChainWSI(
2249 VkDevice device,
2250 const VkSwapChainCreateInfoWSI *pCreateInfo,
2251 VkSwapChainWSI *pSwapChain)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002252{
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002253 VkResult result = nextTable.CreateSwapChainWSI(device, pCreateInfo, pSwapChain);
2254
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002255 if (VK_SUCCESS == result) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002256 loader_platform_thread_lock_mutex(&globalLock);
2257 addSwapChainInfo(*pSwapChain);
2258 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -07002259 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002260
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002261 return result;
2262}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002263
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002264VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapChainWSI(
2265 VkSwapChainWSI swapChain)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002266{
2267 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002268
2269 if (swapChainMap.find(swapChain) != swapChainMap.end()) {
2270 MT_SWAP_CHAIN_INFO* pInfo = swapChainMap[swapChain];
2271
2272 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2273 it != pInfo->images.end(); it++) {
2274 clearObjectBinding(it->image);
2275 freeMemObjInfo(it->memory, true);
2276
2277 MT_OBJ_INFO* pDelInfo = objectMap[it->image];
2278 delete pDelInfo;
2279 objectMap.erase(it->image);
2280 }
2281
2282 delete pInfo;
2283 swapChainMap.erase(swapChain);
2284 }
2285
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002286 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002287
2288 return nextTable.DestroySwapChainWSI(swapChain);
2289}
2290
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002291VK_LAYER_EXPORT VkResult VKAPI vkGetSwapChainInfoWSI(
2292 VkSwapChainWSI swapChain,
2293 VkSwapChainInfoTypeWSI infoType,
2294 size_t *pDataSize,
2295 void *pData)
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002296{
2297 VkResult result = nextTable.GetSwapChainInfoWSI(swapChain, infoType, pDataSize, pData);
2298
2299 if (infoType == VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI && result == VK_SUCCESS) {
2300 const size_t count = *pDataSize / sizeof(VkSwapChainImageInfoWSI);
2301 MT_SWAP_CHAIN_INFO *pInfo = swapChainMap[swapChain];
2302
2303 if (pInfo->images.empty()) {
2304 pInfo->images.resize(count);
2305 memcpy(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count);
2306
2307 for (std::vector<VkSwapChainImageInfoWSI>::const_iterator it = pInfo->images.begin();
2308 it != pInfo->images.end(); it++) {
2309 // Add image object, then insert the new Mem Object and then bind it to created image
2310 addObjectInfo(it->image, VK_STRUCTURE_TYPE_MAX_ENUM, &pInfo->createInfo, sizeof(pInfo->createInfo), "persistent_image");
2311 addMemObjInfo(it->memory, NULL);
2312 if (VK_FALSE == updateObjectBinding(it->image, it->memory)) {
2313 char str[1024];
2314 sprintf(str, "In vkGetSwapChainInfoWSI(), unable to set image %p binding to mem obj %p", (void*)it->image, (void*)it->memory);
2315 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, it->image, 0, MEMTRACK_MEMORY_BINDING_ERROR, "MEM", str);
2316 }
2317 }
2318 } else {
2319 const bool mismatch = (pInfo->images.size() != count ||
2320 memcmp(&pInfo->images[0], pData, sizeof(pInfo->images[0]) * count));
2321
2322 if (mismatch) {
2323 char str[1024];
2324 sprintf(str, "vkGetSwapChainInfoWSI(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI) returned mismatching data", swapChain);
Mike Stroyan230e6252015-04-17 12:36:38 -06002325 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 +08002326 }
2327 }
2328 }
2329
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002330 return result;
2331}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002332
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002333VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(
2334 VkPhysicalDevice gpu,
2335 const char *funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002336{
Jon Ashburn301c5f02015-04-06 10:58:22 -06002337 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Chia-I Wu706533e2015-01-05 13:18:57 +08002338
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002339 if (gpu == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002340 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002341 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002342 pCurObj = gpuw;
Ian Elliott81ac44c2015-01-13 17:52:38 -07002343 loader_platform_thread_once(&g_initOnce, initMemTracker);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002344
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002345 if (!strcmp(funcName, "vkGetProcAddr"))
2346 return (void *) vkGetProcAddr;
2347 if (!strcmp(funcName, "vkCreateDevice"))
2348 return (void*) vkCreateDevice;
2349 if (!strcmp(funcName, "vkDestroyDevice"))
2350 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002351 if (!strcmp(funcName, "vkEnumerateLayers"))
2352 return (void*) vkEnumerateLayers;
2353 if (!strcmp(funcName, "vkQueueSubmit"))
2354 return (void*) vkQueueSubmit;
2355 if (!strcmp(funcName, "vkAllocMemory"))
2356 return (void*) vkAllocMemory;
2357 if (!strcmp(funcName, "vkFreeMemory"))
2358 return (void*) vkFreeMemory;
2359 if (!strcmp(funcName, "vkSetMemoryPriority"))
2360 return (void*) vkSetMemoryPriority;
2361 if (!strcmp(funcName, "vkMapMemory"))
2362 return (void*) vkMapMemory;
2363 if (!strcmp(funcName, "vkUnmapMemory"))
2364 return (void*) vkUnmapMemory;
2365 if (!strcmp(funcName, "vkPinSystemMemory"))
2366 return (void*) vkPinSystemMemory;
2367 if (!strcmp(funcName, "vkOpenSharedMemory"))
2368 return (void*) vkOpenSharedMemory;
2369 if (!strcmp(funcName, "vkOpenPeerMemory"))
2370 return (void*) vkOpenPeerMemory;
2371 if (!strcmp(funcName, "vkOpenPeerImage"))
2372 return (void*) vkOpenPeerImage;
2373 if (!strcmp(funcName, "vkDestroyObject"))
2374 return (void*) vkDestroyObject;
2375 if (!strcmp(funcName, "vkGetObjectInfo"))
2376 return (void*) vkGetObjectInfo;
Mark Lobodzinskicf26e072015-04-16 11:44:05 -05002377 if (!strcmp(funcName, "vkQueueBindObjectMemory"))
2378 return (void*) vkQueueBindObjectMemory;
Mike Stroyan230e6252015-04-17 12:36:38 -06002379 if (!strcmp(funcName, "vkQueueBindObjectMemoryRange"))
2380 return (void*) vkQueueBindObjectMemoryRange;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002381 if (!strcmp(funcName, "vkCreateFence"))
2382 return (void*) vkCreateFence;
2383 if (!strcmp(funcName, "vkGetFenceStatus"))
2384 return (void*) vkGetFenceStatus;
2385 if (!strcmp(funcName, "vkResetFences"))
2386 return (void*) vkResetFences;
2387 if (!strcmp(funcName, "vkWaitForFences"))
2388 return (void*) vkWaitForFences;
2389 if (!strcmp(funcName, "vkQueueWaitIdle"))
2390 return (void*) vkQueueWaitIdle;
2391 if (!strcmp(funcName, "vkDeviceWaitIdle"))
2392 return (void*) vkDeviceWaitIdle;
2393 if (!strcmp(funcName, "vkCreateEvent"))
2394 return (void*) vkCreateEvent;
2395 if (!strcmp(funcName, "vkCreateQueryPool"))
2396 return (void*) vkCreateQueryPool;
2397 if (!strcmp(funcName, "vkCreateBuffer"))
2398 return (void*) vkCreateBuffer;
2399 if (!strcmp(funcName, "vkCreateBufferView"))
2400 return (void*) vkCreateBufferView;
2401 if (!strcmp(funcName, "vkCreateImage"))
2402 return (void*) vkCreateImage;
2403 if (!strcmp(funcName, "vkCreateImageView"))
2404 return (void*) vkCreateImageView;
2405 if (!strcmp(funcName, "vkCreateColorAttachmentView"))
2406 return (void*) vkCreateColorAttachmentView;
2407 if (!strcmp(funcName, "vkCreateDepthStencilView"))
2408 return (void*) vkCreateDepthStencilView;
2409 if (!strcmp(funcName, "vkCreateShader"))
2410 return (void*) vkCreateShader;
2411 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2412 return (void*) vkCreateGraphicsPipeline;
2413 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2414 return (void*) vkCreateGraphicsPipelineDerivative;
2415 if (!strcmp(funcName, "vkCreateComputePipeline"))
2416 return (void*) vkCreateComputePipeline;
2417 if (!strcmp(funcName, "vkCreateSampler"))
2418 return (void*) vkCreateSampler;
2419 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2420 return (void*) vkCreateDynamicViewportState;
2421 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2422 return (void*) vkCreateDynamicRasterState;
2423 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2424 return (void*) vkCreateDynamicColorBlendState;
2425 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2426 return (void*) vkCreateDynamicDepthStencilState;
2427 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2428 return (void*) vkCreateCommandBuffer;
2429 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2430 return (void*) vkBeginCommandBuffer;
2431 if (!strcmp(funcName, "vkEndCommandBuffer"))
2432 return (void*) vkEndCommandBuffer;
2433 if (!strcmp(funcName, "vkResetCommandBuffer"))
2434 return (void*) vkResetCommandBuffer;
2435 if (!strcmp(funcName, "vkCmdBindPipeline"))
2436 return (void*) vkCmdBindPipeline;
2437 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2438 return (void*) vkCmdBindDynamicStateObject;
2439 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2440 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002441 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2442 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002443 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2444 return (void*) vkCmdBindIndexBuffer;
2445 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2446 return (void*) vkCmdDrawIndirect;
2447 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2448 return (void*) vkCmdDrawIndexedIndirect;
2449 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2450 return (void*) vkCmdDispatchIndirect;
2451 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2452 return (void*) vkCmdCopyBuffer;
2453 if (!strcmp(funcName, "vkCmdCopyImage"))
2454 return (void*) vkCmdCopyImage;
2455 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2456 return (void*) vkCmdCopyBufferToImage;
2457 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2458 return (void*) vkCmdCopyImageToBuffer;
2459 if (!strcmp(funcName, "vkCmdCloneImageData"))
2460 return (void*) vkCmdCloneImageData;
2461 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2462 return (void*) vkCmdUpdateBuffer;
2463 if (!strcmp(funcName, "vkCmdFillBuffer"))
2464 return (void*) vkCmdFillBuffer;
2465 if (!strcmp(funcName, "vkCmdClearColorImage"))
2466 return (void*) vkCmdClearColorImage;
2467 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2468 return (void*) vkCmdClearDepthStencil;
2469 if (!strcmp(funcName, "vkCmdResolveImage"))
2470 return (void*) vkCmdResolveImage;
2471 if (!strcmp(funcName, "vkCmdBeginQuery"))
2472 return (void*) vkCmdBeginQuery;
2473 if (!strcmp(funcName, "vkCmdEndQuery"))
2474 return (void*) vkCmdEndQuery;
2475 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2476 return (void*) vkCmdResetQueryPool;
2477 if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
2478 return (void*) vkDbgRegisterMsgCallback;
2479 if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
2480 return (void*) vkDbgUnregisterMsgCallback;
2481 if (!strcmp(funcName, "vkGetDeviceQueue"))
2482 return (void*) vkGetDeviceQueue;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002483 if (!strcmp(funcName, "vkQueueAddMemReferences"))
2484 return (void*) vkQueueAddMemReferences;
2485 if (!strcmp(funcName, "vkQueueRemoveMemReferences"))
2486 return (void*) vkQueueRemoveMemReferences;
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002487 if (!strcmp(funcName, "vkCreateSwapChainWSI"))
2488 return (void*) vkCreateSwapChainWSI;
2489 if (!strcmp(funcName, "vkDestroySwapChainWSI"))
2490 return (void*) vkDestroySwapChainWSI;
2491 if (!strcmp(funcName, "vkGetSwapChainInfoWSI"))
2492 return (void*) vkGetSwapChainInfoWSI;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002493 else {
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002494 if (gpuw->pGPA == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002495 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002496 }
Tony Barbour8205d902015-04-16 15:59:00 -06002497 return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002498 }
2499}