blob: 92177a2fa586d8df33433491d16aa61c9d0ed471 [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.
Michael Lentinebfb5fd62015-09-23 17:43:16 -07005 * Copyright (C) 2015 Google, Inc.
Tobin Ehlis791a49c2014-11-10 12:29:12 -07006 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050018* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Tobin Ehlis791a49c2014-11-10 12:29:12 -070019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
Mark Lobodzinski4aad3642015-03-17 10:53:12 -050026#include <inttypes.h>
Tobin Ehlis791a49c2014-11-10 12:29:12 -070027#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <assert.h>
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050031#include <list>
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -050032#include <map>
Chia-I Wu5b66aa52015-04-16 22:02:10 +080033#include <vector>
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050034using namespace std;
35
Tobin Ehlis7a51d902015-07-03 10:34:49 -060036#include "vk_loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060037#include "vk_dispatch_table_helper.h"
38#include "vk_struct_string_helper_cpp.h"
Tobin Ehlis62086412014-11-19 16:19:28 -070039#include "mem_tracker.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060040#include "vk_layer_config.h"
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -060041#include "vk_layer_extension_utils.h"
Ian Elliott20f06872015-02-12 17:08:34 -070042// The following is #included again to catch certain OS-specific functions
43// being used:
Tobin Ehlis7a51d902015-07-03 10:34:49 -060044#include "vk_loader_platform.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060045#include "vk_layer_table.h"
46#include "vk_layer_data.h"
47#include "vk_layer_logging.h"
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -060048static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -050049
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -060050// WSI Image Objects bypass usual Image Object creation methods. A special Memory
51// Object value will be used to identify them internally.
52static const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY = static_cast<VkDeviceMemory>(-1);
53
Cody Northrop73bb6572015-09-28 15:09:32 -060054struct layer_data {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060055 debug_report_data *report_data;
56 // TODO: put instance data here
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -060057 VkDbgMsgCallback logging_callback;
Ian Elliottb134e842015-07-06 14:31:32 -060058 bool wsi_enabled;
Cody Northrop73bb6572015-09-28 15:09:32 -060059
60 layer_data() :
61 report_data(nullptr),
62 logging_callback(nullptr),
63 wsi_enabled(false)
64 {};
65};
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -050066
Tobin Ehlis92f12cd2015-07-08 17:08:02 -060067static unordered_map<void *, layer_data *> layer_data_map;
68
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060069static device_table_map mem_tracker_device_table_map;
70static instance_table_map mem_tracker_instance_table_map;
Mark Lobodzinski72346292015-07-02 16:49:40 -060071static VkPhysicalDeviceMemoryProperties memProps;
Jon Ashburnd9564002015-05-07 10:27:37 -060072
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060073// TODO : This can be much smarter, using separate locks for separate global data
74static int globalLockInitialized = 0;
75static loader_platform_thread_mutex globalLock;
Jon Ashburnf57ea372014-12-22 13:24:15 -070076
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070077#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070078
Tobin Ehlis92f12cd2015-07-08 17:08:02 -060079// Maps for tracking key structs related to MemTracker state
Mike Stroyan988caa42015-05-19 17:03:40 -060080unordered_map<VkCmdBuffer, MT_CB_INFO> cbMap;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -060081unordered_map<uint64_t, MT_MEM_OBJ_INFO> memObjMap;
82unordered_map<uint64_t, MT_FENCE_INFO> fenceMap; // Map fence to fence info
Mike Stroyan988caa42015-05-19 17:03:40 -060083unordered_map<VkQueue, MT_QUEUE_INFO> queueMap;
Ian Elliott338dedb2015-08-21 15:09:33 -060084unordered_map<uint64_t, MT_SWAP_CHAIN_INFO*> swapchainMap;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050085
Tobin Ehlis92f12cd2015-07-08 17:08:02 -060086// Images and Buffers are 2 objects that can have memory bound to them so they get special treatment
87unordered_map<uint64_t, MT_OBJ_BINDING_INFO> imageMap;
88unordered_map<uint64_t, MT_OBJ_BINDING_INFO> bufferMap;
89
Tobin Ehlis92f12cd2015-07-08 17:08:02 -060090static MT_OBJ_BINDING_INFO* get_object_binding_info(uint64_t handle, VkDbgObjectType type)
91{
92 MT_OBJ_BINDING_INFO* retValue = NULL;
93 switch (type)
94 {
95 case VK_OBJECT_TYPE_IMAGE:
96 {
97 auto it = imageMap.find(handle);
98 if (it != imageMap.end())
99 return &(*it).second;
100 break;
101 }
102 case VK_OBJECT_TYPE_BUFFER:
103 {
104 auto it = bufferMap.find(handle);
105 if (it != bufferMap.end())
106 return &(*it).second;
107 break;
108 }
109 }
110 return retValue;
111}
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500112// TODO : Add per-device fence completion
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600113static uint64_t g_currentFenceId = 1;
Mark Lobodzinski15427102015-02-18 16:38:17 -0600114
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600115template layer_data *get_my_data_ptr<layer_data>(
116 void *data_key,
117 std::unordered_map<void *, layer_data *> &data_map);
118
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600119debug_report_data *mdd(void* object)
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600120{
Courtney Goeltzenleuchterc086fb32015-06-13 21:39:35 -0600121 dispatch_key key = get_dispatch_key(object);
122 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Courtney Goeltzenleuchterab75b612015-06-13 21:40:22 -0600123#if DISPATCH_MAP_DEBUG
124 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
125#endif
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600126 return my_data->report_data;
127}
128
129debug_report_data *mid(VkInstance object)
130{
Courtney Goeltzenleuchterc086fb32015-06-13 21:39:35 -0600131 dispatch_key key = get_dispatch_key(object);
Tobin Ehlis8354e022015-09-01 11:46:36 -0600132 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Courtney Goeltzenleuchterab75b612015-06-13 21:40:22 -0600133#if DISPATCH_MAP_DEBUG
134 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
135#endif
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600136 return my_data->report_data;
137}
138
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500139// Add new queue for this device to map container
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500140static void add_queue_info(const VkQueue queue)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500141{
Mike Stroyan988caa42015-05-19 17:03:40 -0600142 MT_QUEUE_INFO* pInfo = &queueMap[queue];
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500143 pInfo->lastRetiredId = 0;
144 pInfo->lastSubmittedId = 0;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500145}
146
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500147static void delete_queue_info_list(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600148 void)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500149{
150 // Process queue list, cleaning up each entry before deleting
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500151 queueMap.clear();
152}
153
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500154static void add_swap_chain_info(
Ian Elliott338dedb2015-08-21 15:09:33 -0600155 const VkSwapchainKHR swapchain, const VkSwapchainCreateInfoKHR* pCI)
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800156{
157 MT_SWAP_CHAIN_INFO* pInfo = new MT_SWAP_CHAIN_INFO;
Ian Elliott338dedb2015-08-21 15:09:33 -0600158 memcpy(&pInfo->createInfo, pCI, sizeof(VkSwapchainCreateInfoKHR));
159 swapchainMap[swapchain.handle] = pInfo;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800160}
161
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500162// Add new CBInfo for this cb to map container
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500163static void add_cmd_buf_info(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600164 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700165{
Mike Stroyan988caa42015-05-19 17:03:40 -0600166 cbMap[cb].cmdBuffer = cb;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700167}
168
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500169// Return ptr to Info in CB map, or NULL if not found
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500170static MT_CB_INFO* get_cmd_buf_info(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600171 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700172{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600173 auto item = cbMap.find(cb);
Mike Stroyan53430332015-05-19 15:16:08 -0600174 if (item != cbMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600175 return &(*item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600176 } else {
177 return NULL;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600178 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700179}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600180
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600181static void add_object_binding_info(const uint64_t handle, const VkDbgObjectType type, const VkDeviceMemory mem)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500182{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600183 switch (type)
184 {
185 // Buffers and images are unique as their CreateInfo is in container struct
186 case VK_OBJECT_TYPE_BUFFER:
187 {
188 auto pCI = &bufferMap[handle];
189 pCI->mem = mem;
190 break;
191 }
192 case VK_OBJECT_TYPE_IMAGE:
193 {
194 auto pCI = &imageMap[handle];
195 pCI->mem = mem;
196 break;
197 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500198 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500199}
200
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600201static void add_object_create_info(const uint64_t handle, const VkDbgObjectType type, const void* pCreateInfo)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500202{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600203 // TODO : For any CreateInfo struct that has ptrs, need to deep copy them and appropriately clean up on Destroy
204 switch (type)
205 {
206 // Buffers and images are unique as their CreateInfo is in container struct
207 case VK_OBJECT_TYPE_BUFFER:
208 {
209 auto pCI = &bufferMap[handle];
210 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
211 memcpy(&pCI->create_info.buffer, pCreateInfo, sizeof(VkBufferCreateInfo));
212 break;
213 }
214 case VK_OBJECT_TYPE_IMAGE:
215 {
216 auto pCI = &imageMap[handle];
217 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
218 memcpy(&pCI->create_info.image, pCreateInfo, sizeof(VkImageCreateInfo));
219 break;
220 }
Mark Lobodzinski6aa1abd2015-09-01 11:19:08 -0600221 // Swap Chain is very unique, use imageMap, but copy in
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600222 // SwapChainCreatInfo's usage flags and set the mem value to a unique key. These is used by
223 // vkCreateImageView and internal MemTracker routines to distinguish swap chain images
Ian Elliott338dedb2015-08-21 15:09:33 -0600224 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600225 {
226 auto pCI = &imageMap[handle];
227 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600228 pCI->mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
Mark Lobodzinski6aa1abd2015-09-01 11:19:08 -0600229 pCI->create_info.image.usage =
Ian Elliott338dedb2015-08-21 15:09:33 -0600230 const_cast<VkSwapchainCreateInfoKHR*>(static_cast<const VkSwapchainCreateInfoKHR *>(pCreateInfo))->imageUsageFlags;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600231 break;
232 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600233 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500234}
235
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500236// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600237static VkBool32 add_fence_info(
238 VkFence fence,
239 VkQueue queue,
240 uint64_t *fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500241{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600242 VkBool32 skipCall = VK_FALSE;
243 *fenceId = g_currentFenceId++;
244
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -0500245 // If no fence, create an internal fence to track the submissions
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600246 if (fence.handle != 0) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600247 fenceMap[fence.handle].fenceId = *fenceId;
248 fenceMap[fence.handle].queue = queue;
Mark Lobodzinski56945182015-04-09 13:46:09 -0500249 // Validate that fence is in UNSIGNALED state
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600250 VkFenceCreateInfo* pFenceCI = &(fenceMap[fence.handle].createInfo);
251 if (pFenceCI->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600252 skipCall = log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_FENCE, fence.handle, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
253 "Fence %#" PRIxLEAST64 " submitted in SIGNALED state. Fences must be reset before being submitted", fence.handle);
Mark Lobodzinski56945182015-04-09 13:46:09 -0500254 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600255 } else {
256 // TODO : Do we need to create an internal fence here for tracking purposes?
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700257 }
Mike Stroyan53430332015-05-19 15:16:08 -0600258 // Update most recently submitted fence and fenceId for Queue
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600259 queueMap[queue].lastSubmittedId = *fenceId;
260 return skipCall;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500261}
262
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500263// Remove a fenceInfo from our list of fences/fenceIds
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500264static void delete_fence_info(
Mike Stroyan53430332015-05-19 15:16:08 -0600265 VkFence fence)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500266{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600267 fenceMap.erase(fence.handle);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500268}
269
Mike Stroyan53430332015-05-19 15:16:08 -0600270// Record information when a fence is known to be signalled
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500271static void update_fence_tracking(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600272 VkFence fence)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500273{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600274 auto fence_item = fenceMap.find(fence.handle);
Mike Stroyan53430332015-05-19 15:16:08 -0600275 if (fence_item != fenceMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600276 MT_FENCE_INFO *pCurFenceInfo = &(*fence_item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600277 VkQueue queue = pCurFenceInfo->queue;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600278 auto queue_item = queueMap.find(queue);
Mike Stroyan53430332015-05-19 15:16:08 -0600279 if (queue_item != queueMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600280 MT_QUEUE_INFO *pQueueInfo = &(*queue_item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600281 if (pQueueInfo->lastRetiredId < pCurFenceInfo->fenceId) {
282 pQueueInfo->lastRetiredId = pCurFenceInfo->fenceId;
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500283 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500284 }
285 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500286
Mike Stroyan53430332015-05-19 15:16:08 -0600287 // Update fence state in fenceCreateInfo structure
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600288 auto pFCI = &(fenceMap[fence.handle].createInfo);
289 pFCI->flags = static_cast<VkFenceCreateFlags>(pFCI->flags | VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500290}
291
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500292// Helper routine that updates the fence list for a specific queue to all-retired
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500293static void retire_queue_fences(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600294 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500295{
Mike Stroyan988caa42015-05-19 17:03:40 -0600296 MT_QUEUE_INFO *pQueueInfo = &queueMap[queue];
297 // Set queue's lastRetired to lastSubmitted indicating all fences completed
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600298 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700299}
300
Mike Stroyan988caa42015-05-19 17:03:40 -0600301// Helper routine that updates all queues to all-retired
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500302static void retire_device_fences(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600303 VkDevice device)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500304{
305 // Process each queue for device
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600306 // TODO: Add multiple device support
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600307 for (auto ii=queueMap.begin(); ii!=queueMap.end(); ++ii) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600308 // Set queue's lastRetired to lastSubmitted indicating all fences completed
309 MT_QUEUE_INFO *pQueueInfo = &(*ii).second;
310 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500311 }
312}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600313
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600314// Helper function to validate correct usage bits set for buffers or images
315// Verify that (actual & desired) flags != 0 or,
316// if strict is true, verify that (actual & desired) flags == desired
317// In case of error, report it via dbg callbacks
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600318static VkBool32 validate_usage_flags(void* disp_obj, VkFlags actual, VkFlags desired,
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600319 VkBool32 strict, uint64_t obj_handle, VkDbgObjectType obj_type,
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600320 char const* ty_str, char const* func_name, char const* usage_str)
321{
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600322 VkBool32 correct_usage = VK_FALSE;
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600323 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600324 if (strict)
325 correct_usage = ((actual & desired) == desired);
326 else
327 correct_usage = ((actual & desired) != 0);
328 if (!correct_usage) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600329 skipCall = log_msg(mdd(disp_obj), VK_DBG_REPORT_ERROR_BIT, obj_type, obj_handle, 0, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
330 "Invalid usage flag for %s %#" PRIxLEAST64 " used by %s. In this case, %s should have %s set during creation.",
331 ty_str, obj_handle, func_name, ty_str, usage_str);
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600332 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600333 return skipCall;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600334}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600335
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600336// Helper function to validate usage flags for images
337// Pulls image info and then sends actual vs. desired usage off to helper above where
338// an error will be flagged if usage is not correct
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600339static VkBool32 validate_image_usage_flags(void* disp_obj, VkImage image, VkFlags desired, VkBool32 strict,
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600340 char const* func_name, char const* usage_string)
341{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600342 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600343 MT_OBJ_BINDING_INFO* pBindInfo = get_object_binding_info(image.handle, VK_OBJECT_TYPE_IMAGE);
344 if (pBindInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600345 skipCall = validate_usage_flags(disp_obj, pBindInfo->create_info.image.usage, desired, strict,
346 image.handle, VK_OBJECT_TYPE_IMAGE, "image", func_name, usage_string);
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600347 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600348 return skipCall;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600349}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600350
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600351// Helper function to validate usage flags for buffers
352// Pulls buffer info and then sends actual vs. desired usage off to helper above where
353// an error will be flagged if usage is not correct
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600354static VkBool32 validate_buffer_usage_flags(void* disp_obj, VkBuffer buffer, VkFlags desired, VkBool32 strict,
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600355 char const* func_name, char const* usage_string)
356{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600357 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600358 MT_OBJ_BINDING_INFO* pBindInfo = get_object_binding_info(buffer.handle, VK_OBJECT_TYPE_BUFFER);
359 if (pBindInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600360 skipCall = validate_usage_flags(disp_obj, pBindInfo->create_info.buffer.usage, desired, strict,
361 buffer.handle, VK_OBJECT_TYPE_BUFFER, "buffer", func_name, usage_string);
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600362 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600363 return skipCall;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600364}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600365
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500366// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700367// Calls to this function should be wrapped in mutex
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500368static MT_MEM_OBJ_INFO* get_mem_obj_info(
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600369 const uint64_t device_mem_handle)
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700370{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600371 auto item = memObjMap.find(device_mem_handle);
Mike Stroyan53430332015-05-19 15:16:08 -0600372 if (item != memObjMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600373 return &(*item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600374 } else {
375 return NULL;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600376 }
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700377}
378
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500379static void add_mem_obj_info(
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600380 void* object,
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600381 const VkDeviceMemory mem,
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600382 const VkMemoryAllocInfo* pAllocInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700383{
Courtney Goeltzenleuchter0749c662015-06-13 21:29:26 -0600384 assert(object != NULL);
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -0600385
Ian Elliottb134e842015-07-06 14:31:32 -0600386 memcpy(&memObjMap[mem.handle].allocInfo, pAllocInfo, sizeof(VkMemoryAllocInfo));
387 // TODO: Update for real hardware, actually process allocation info structures
388 memObjMap[mem.handle].allocInfo.pNext = NULL;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600389 memObjMap[mem.handle].object = object;
390 memObjMap[mem.handle].refCount = 0;
391 memObjMap[mem.handle].mem = mem;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700392}
393
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500394// Find CB Info and add mem reference to list container
395// Find Mem Obj Info and add CB reference to list container
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600396static VkBool32 update_cmd_buf_and_mem_references(
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600397 const VkCmdBuffer cb,
398 const VkDeviceMemory mem,
399 const char *apiName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700400{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600401 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600402
403 // Skip validation if this image was created through WSI
404 if (mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
405
406 // First update CB binding in MemObj mini CB list
407 MT_MEM_OBJ_INFO* pMemInfo = get_mem_obj_info(mem.handle);
408 if (!pMemInfo) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600409 skipCall = log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600410 "In %s, trying to bind mem obj %#" PRIxLEAST64 " to CB %p but no info for that mem obj.\n "
411 "Was it correctly allocated? Did it already get freed?", apiName, mem.handle, cb);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500412 } else {
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600413 // Search for cmd buffer object in memory object's binding list
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600414 VkBool32 found = VK_FALSE;
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600415 if (pMemInfo->pCmdBufferBindings.size() > 0) {
416 for (list<VkCmdBuffer>::iterator it = pMemInfo->pCmdBufferBindings.begin(); it != pMemInfo->pCmdBufferBindings.end(); ++it) {
417 if ((*it) == cb) {
David Pinedof5997ab2015-04-27 16:36:17 -0600418 found = VK_TRUE;
419 break;
420 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500421 }
422 }
423 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600424 if (found == VK_FALSE) {
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600425 pMemInfo->pCmdBufferBindings.push_front(cb);
426 pMemInfo->refCount++;
427 }
428 // Now update CBInfo's Mem reference list
429 MT_CB_INFO* pCBInfo = get_cmd_buf_info(cb);
430 // TODO: keep track of all destroyed CBs so we know if this is a stale or simply invalid object
431 if (!pCBInfo) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600432 skipCall = log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cb, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600433 "Trying to bind mem obj %#" PRIxLEAST64 " to CB %p but no info for that CB. Was CB incorrectly destroyed?", mem.handle, cb);
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600434 } else {
435 // Search for memory object in cmd buffer's reference list
436 VkBool32 found = VK_FALSE;
437 if (pCBInfo->pMemObjList.size() > 0) {
438 for (auto it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
439 if ((*it) == mem) {
440 found = VK_TRUE;
441 break;
442 }
443 }
444 }
445 // If not present, add to list
446 if (found == VK_FALSE) {
447 pCBInfo->pMemObjList.push_front(mem);
448 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600449 }
450 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700451 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600452 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700453}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600454
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700455// Free bindings related to CB
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600456static VkBool32 clear_cmd_buf_and_mem_references(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600457 const VkCmdBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700458{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600459 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500460 MT_CB_INFO* pCBInfo = get_cmd_buf_info(cb);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500461 if (!pCBInfo) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600462 skipCall = log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cb, 0, MEMTRACK_INVALID_CB, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600463 "Unable to find global CB info %p for deletion", cb);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600464 } else {
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600465 if (pCBInfo->pMemObjList.size() > 0) {
466 list<VkDeviceMemory> mem_obj_list = pCBInfo->pMemObjList;
467 for (list<VkDeviceMemory>::iterator it=mem_obj_list.begin(); it!=mem_obj_list.end(); ++it) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600468 MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info((*it).handle);
469 pInfo->pCmdBufferBindings.remove(cb);
470 pInfo->refCount--;
David Pinedof5997ab2015-04-27 16:36:17 -0600471 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600472 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500473 pCBInfo->pMemObjList.clear();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700474 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600475 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700476}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600477
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700478// Delete the entire CB list
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600479static VkBool32 delete_cmd_buf_info_list(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600480 void)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700481{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600482 VkBool32 skipCall = VK_FALSE;
Mike Stroyan988caa42015-05-19 17:03:40 -0600483 for (unordered_map<VkCmdBuffer, MT_CB_INFO>::iterator ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600484 skipCall |= clear_cmd_buf_and_mem_references((*ii).first);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700485 }
Mike Stroyan988caa42015-05-19 17:03:40 -0600486 cbMap.clear();
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600487 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700488}
489
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500490// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600491static VkBool32 reportMemReferencesAndCleanUp(
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600492 MT_MEM_OBJ_INFO* pMemObjInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700493{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600494 VkBool32 skipCall = VK_FALSE;
Tony Barboura938abb2015-04-22 11:36:22 -0600495 size_t cmdBufRefCount = pMemObjInfo->pCmdBufferBindings.size();
496 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500497
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500498 if ((pMemObjInfo->pCmdBufferBindings.size() + pMemObjInfo->pObjBindings.size()) != 0) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600499 skipCall = log_msg(mdd(pMemObjInfo->object), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, pMemObjInfo->mem.handle, 0, MEMTRACK_FREED_MEM_REF, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600500 "Attempting to free memory object %#" PRIxLEAST64 " which still contains %lu references",
501 pMemObjInfo->mem.handle, (cmdBufRefCount + objRefCount));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700502 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500503
David Pinedof5997ab2015-04-27 16:36:17 -0600504 if (cmdBufRefCount > 0 && pMemObjInfo->pCmdBufferBindings.size() > 0) {
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500505 for (list<VkCmdBuffer>::const_iterator it = pMemObjInfo->pCmdBufferBindings.begin(); it != pMemObjInfo->pCmdBufferBindings.end(); ++it) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600506 // TODO : cmdBuffer should be source Obj here
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600507 log_msg(mdd(pMemObjInfo->object), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)(*it), 0, MEMTRACK_FREED_MEM_REF, "MEM",
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600508 "Command Buffer %p still has a reference to mem obj %#" PRIxLEAST64, (*it), pMemObjInfo->mem.handle);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500509 }
510 // Clear the list of hanging references
511 pMemObjInfo->pCmdBufferBindings.clear();
512 }
513
David Pinedof5997ab2015-04-27 16:36:17 -0600514 if (objRefCount > 0 && pMemObjInfo->pObjBindings.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600515 for (auto it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600516 log_msg(mdd(pMemObjInfo->object), VK_DBG_REPORT_INFO_BIT, it->type, it->handle, 0, MEMTRACK_FREED_MEM_REF, "MEM",
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600517 "VK Object %#" PRIxLEAST64 " still has a reference to mem obj %#" PRIxLEAST64, it->handle, pMemObjInfo->mem.handle);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500518 }
519 // Clear the list of hanging references
520 pMemObjInfo->pObjBindings.clear();
521 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600522 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700523}
524
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600525static VkBool32 deleteMemObjInfo(
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600526 void* object,
527 const uint64_t device_mem_handle)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700528{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600529 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600530 auto item = memObjMap.find(device_mem_handle);
Mike Stroyan53430332015-05-19 15:16:08 -0600531 if (item != memObjMap.end()) {
Mike Stroyan53430332015-05-19 15:16:08 -0600532 memObjMap.erase(item);
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600533 } else {
534 skipCall = log_msg(mdd(object), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, device_mem_handle, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
535 "Request to delete memory object %#" PRIxLEAST64 " not present in memory Object Map", device_mem_handle);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700536 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600537 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700538}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500539
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700540// Check if fence for given CB is completed
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600541static VkBool32 checkCBCompleted(
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600542 const VkCmdBuffer cb,
543 VkBool32 *complete)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700544{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600545 VkBool32 skipCall = VK_FALSE;
546 *complete = VK_TRUE;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500547 MT_CB_INFO* pCBInfo = get_cmd_buf_info(cb);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500548 if (!pCBInfo) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600549 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cb, 0,
550 MEMTRACK_INVALID_CB, "MEM", "Unable to find global CB info %p to check for completion", cb);
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600551 *complete = VK_FALSE;
Mike Stroyan53430332015-05-19 15:16:08 -0600552 } else if (pCBInfo->lastSubmittedQueue != NULL) {
553 VkQueue queue = pCBInfo->lastSubmittedQueue;
Mike Stroyan988caa42015-05-19 17:03:40 -0600554 MT_QUEUE_INFO *pQueueInfo = &queueMap[queue];
Mike Stroyan53430332015-05-19 15:16:08 -0600555 if (pCBInfo->fenceId > pQueueInfo->lastRetiredId) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600556 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cb, 0,
557 MEMTRACK_NONE, "MEM", "fence %#" PRIxLEAST64 " for CB %p has not been checked for completion",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600558 pCBInfo->lastSubmittedFence.handle, cb);
559 *complete = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600560 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700561 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600562 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700563}
564
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600565static VkBool32 freeMemObjInfo(
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600566 void* object,
Mark Lobodzinskia908b162015-04-21 15:33:04 -0600567 VkDeviceMemory mem,
568 bool internal)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700569{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600570 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500571 // Parse global list to find info w/ mem
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600572 MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(mem.handle);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500573 if (!pInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600574 skipCall = log_msg(mdd(object), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem.handle, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
575 "Couldn't find mem info object for %#" PRIxLEAST64 "\n Was %#" PRIxLEAST64 " never allocated or previously freed?",
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600576 mem.handle, mem.handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600577 } else {
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -0600578 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600579 skipCall = log_msg(mdd(pInfo->object), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem.handle, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
580 "Attempting to free memory associated with a Persistent Image, %#" PRIxLEAST64 ", "
581 "this should not be explicitly freed\n", mem.handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600582 } else {
583 // Clear any CB bindings for completed CBs
584 // TODO : Is there a better place to do this?
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500585
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600586 VkBool32 cmdBufferComplete = VK_FALSE;
Courtney Goeltzenleuchter38eca262015-06-13 21:36:49 -0600587 assert(pInfo->object != VK_NULL_HANDLE);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600588 list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin();
589 list<VkCmdBuffer>::iterator temp;
David Pinedof5997ab2015-04-27 16:36:17 -0600590 while (pInfo->pCmdBufferBindings.size() > 0 && it != pInfo->pCmdBufferBindings.end()) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600591 skipCall |= checkCBCompleted(*it, &cmdBufferComplete);
592 if (VK_TRUE == cmdBufferComplete) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500593 temp = it;
594 ++temp;
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600595 skipCall |= clear_cmd_buf_and_mem_references(*it);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500596 it = temp;
597 } else {
598 ++it;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600599 }
600 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500601
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600602 // Now verify that no references to this mem obj remain and remove bindings
Mark Lobodzinskid3d00162015-09-10 08:15:23 -0600603 if (0 != pInfo->refCount) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600604 skipCall |= reportMemReferencesAndCleanUp(pInfo);
Mark Lobodzinskid3d00162015-09-10 08:15:23 -0600605 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600606 // Delete mem obj info
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600607 skipCall |= deleteMemObjInfo(object, mem.handle);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700608 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700609 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600610 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700611}
612
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600613static const char *object_type_to_string(VkDbgObjectType type) {
614 switch (type)
615 {
616 case VK_OBJECT_TYPE_IMAGE:
617 return "image";
618 break;
619 case VK_OBJECT_TYPE_BUFFER:
620 return "image";
621 break;
622 case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
623 return "swapchain";
624 break;
625 default:
626 return "unknown";
627 }
628}
629
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700630// Remove object binding performs 3 tasks:
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500631// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
632// 2. Decrement refCount for MemObjInfo
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600633// 3. Clear mem binding for image/buffer by setting its handle to 0
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600634// TODO : This only applied to Buffer, Image, and Swapchain objects now, how should it be updated/customized?
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600635static VkBool32 clear_object_binding(void* dispObj, uint64_t handle, VkDbgObjectType type)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700636{
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600637 // TODO : Need to customize images/buffers/swapchains to track mem binding and clear it here appropriately
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600638 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600639 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(handle, type);
640 if (pObjBindInfo) {
641 MT_MEM_OBJ_INFO* pMemObjInfo = get_mem_obj_info(pObjBindInfo->mem.handle);
642 if (!pMemObjInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600643 skipCall = log_msg(mdd(dispObj), VK_DBG_REPORT_WARN_BIT, type, handle, 0, MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, "MEM",
644 "Attempting to clear mem binding on %s obj %#" PRIxLEAST64 " but it has no binding.",
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600645 object_type_to_string(type), handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600646 } else {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600647 // 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
648 // and set the objects memory binding pointer to NULL.
649 VkBool32 clearSucceeded = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600650 for (auto it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
651 if ((it->handle == handle) && (it->type == type)) {
652 pMemObjInfo->refCount--;
653 pMemObjInfo->pObjBindings.erase(it);
654 // TODO : Make sure this is a reasonable way to reset mem binding
655 pObjBindInfo->mem.handle = 0;
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600656 clearSucceeded = VK_TRUE;
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500657 break;
658 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600659 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600660 if (VK_FALSE == clearSucceeded ) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600661 skipCall |= log_msg(mdd(dispObj), VK_DBG_REPORT_ERROR_BIT, type, handle, 0, MEMTRACK_INVALID_OBJECT, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600662 "While trying to clear mem binding for %s obj %#" PRIxLEAST64 ", unable to find that object referenced by mem obj %#" PRIxLEAST64,
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600663 object_type_to_string(type), handle, pMemObjInfo->mem.handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600664 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700665 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700666 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600667 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700668}
669
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500670// For NULL mem case, output warning
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500671// Make sure given object is in global object map
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500672// IF a previous binding existed, output validation error
673// Otherwise, add reference from objectInfo to memoryInfo
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500674// Add reference off of objInfo
Courtney Goeltzenleuchterd2804562015-06-13 21:37:34 -0600675// device is required for error logging, need a dispatchable
676// object for that.
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600677static VkBool32 set_mem_binding(
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600678 void* dispatch_object,
679 VkDeviceMemory mem,
680 uint64_t handle,
681 VkDbgObjectType type,
682 const char *apiName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700683{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600684 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700685 // Handle NULL case separately, just clear previous binding & decrement reference
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600686 if (mem == VK_NULL_HANDLE) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600687 skipCall = log_msg(mdd(dispatch_object), VK_DBG_REPORT_WARN_BIT, type, handle, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600688 "In %s, attempting to Bind Obj(%#" PRIxLEAST64 ") to NULL", apiName, handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600689 } else {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600690 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(handle, type);
691 if (!pObjBindInfo) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600692 skipCall |= log_msg(mdd(dispatch_object), VK_DBG_REPORT_ERROR_BIT, type, handle, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600693 "In %s, attempting to update Binding of %s Obj(%#" PRIxLEAST64 ") that's not in global list()",
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600694 object_type_to_string(type), apiName, handle);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500695 } else {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600696 // non-null case so should have real mem obj
697 MT_MEM_OBJ_INFO* pMemInfo = get_mem_obj_info(mem.handle);
698 if (!pMemInfo) {
699 skipCall |= log_msg(mdd(dispatch_object), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem.handle,
700 0, MEMTRACK_INVALID_MEM_OBJ, "MEM", "In %s, while trying to bind mem for %s obj %#" PRIxLEAST64 ", couldn't find info for mem obj %#" PRIxLEAST64,
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600701 object_type_to_string(type), apiName, handle, mem.handle);
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600702 } else {
703 // TODO : Need to track mem binding for obj and report conflict here
704 MT_MEM_OBJ_INFO* pPrevBinding = get_mem_obj_info(pObjBindInfo->mem.handle);
705 if (pPrevBinding != NULL) {
706 skipCall |= log_msg(mdd(dispatch_object), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem.handle, 0, MEMTRACK_REBIND_OBJECT, "MEM",
707 "In %s, attempting to bind memory (%#" PRIxLEAST64 ") to object (%#" PRIxLEAST64 ") which has already been bound to mem object %#" PRIxLEAST64,
708 apiName, mem.handle, handle, pPrevBinding->mem.handle);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500709 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600710 else {
711 MT_OBJ_HANDLE_TYPE oht;
712 oht.handle = handle;
713 oht.type = type;
714 pMemInfo->pObjBindings.push_front(oht);
715 pMemInfo->refCount++;
716 // For image objects, make sure default memory state is correctly set
717 // TODO : What's the best/correct way to handle this?
718 if (VK_OBJECT_TYPE_IMAGE == type) {
719 VkImageCreateInfo ici = pObjBindInfo->create_info.image;
720 if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
721 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
722 // TODO:: More memory state transition stuff.
723 }
724 }
725 pObjBindInfo->mem = mem;
726 }
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500727 }
728 }
729 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600730 return skipCall;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500731}
732
733// For NULL mem case, clear any previous binding Else...
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600734// Make sure given object is in its object map
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500735// IF a previous binding existed, update binding
736// Add reference from objectInfo to memoryInfo
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600737// Add reference off of object's binding info
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500738// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600739static VkBool32 set_sparse_mem_binding(
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600740 void* dispObject,
741 VkDeviceMemory mem,
742 uint64_t handle,
743 VkDbgObjectType type,
744 const char *apiName)
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500745{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600746 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500747 // Handle NULL case separately, just clear previous binding & decrement reference
748 if (mem == VK_NULL_HANDLE) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600749 skipCall = clear_object_binding(dispObject, handle, type);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500750 } else {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600751 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(handle, type);
752 if (!pObjBindInfo) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600753 skipCall |= log_msg(mdd(dispObject), VK_DBG_REPORT_ERROR_BIT, type, handle, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600754 "In %s, attempting to update Binding of Obj(%#" PRIxLEAST64 ") that's not in global list()", apiName, handle);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500755 }
756 // non-null case so should have real mem obj
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600757 MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(mem.handle);
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600758 if (!pInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600759 skipCall |= log_msg(mdd(dispObject), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem.handle, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
760 "In %s, While trying to bind mem for obj %#" PRIxLEAST64 ", couldn't find info for mem obj %#" PRIxLEAST64, apiName, handle, mem.handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600761 } else {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500762 // Search for object in memory object's binding list
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600763 VkBool32 found = VK_FALSE;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600764 if (pInfo->pObjBindings.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600765 for (auto it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
766 if (((*it).handle == handle) && ((*it).type == type)) {
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600767 found = VK_TRUE;
768 break;
769 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600770 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600771 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500772 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600773 if (found == VK_FALSE) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600774 MT_OBJ_HANDLE_TYPE oht;
775 oht.handle = handle;
776 oht.type = type;
777 pInfo->pObjBindings.push_front(oht);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500778 pInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500779 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600780 // Need to set mem binding for this object
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600781 MT_MEM_OBJ_INFO* pPrevBinding = get_mem_obj_info(pObjBindInfo->mem.handle);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600782 pObjBindInfo->mem = mem;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700783 }
784 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600785 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700786}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600787
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600788template <typename T>
789void print_object_map_members(
790 void* dispObj,
791 T const& objectName,
792 VkDbgObjectType objectType,
793 const char *objectStr)
794{
795 for (auto const& element : objectName) {
796 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, objectType, 0, 0, MEMTRACK_NONE, "MEM",
797 " %s Object list contains %s Object %#" PRIxLEAST64 " ", objectStr, objectStr, element.first);
798 }
799}
800
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700801// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600802static VkBool32 get_mem_binding_from_object(
803 void* dispObj, const uint64_t handle, const VkDbgObjectType type, VkDeviceMemory *mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700804{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600805 VkBool32 skipCall = VK_FALSE;
806 mem->handle = 0;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600807 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(handle, type);
808 if (pObjBindInfo) {
809 if (pObjBindInfo->mem) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600810 *mem = pObjBindInfo->mem;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600811 } else {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600812 skipCall = log_msg(mdd(dispObj), VK_DBG_REPORT_ERROR_BIT, type, handle, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
813 "Trying to get mem binding for object %#" PRIxLEAST64 " but object has no mem binding", handle);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700814 }
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600815 } else {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600816 skipCall = log_msg(mdd(dispObj), VK_DBG_REPORT_ERROR_BIT, type, handle, 0, MEMTRACK_INVALID_OBJECT, "MEM",
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600817 "Trying to get mem binding for object %#" PRIxLEAST64 " but no such object in %s list",
818 handle, object_type_to_string(type));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700819 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600820 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700821}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500822
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500823// Print details of MemObjInfo list
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600824static void print_mem_list(
825 void* dispObj)
826{
827 MT_MEM_OBJ_INFO* pInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500828
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600829 // Early out if info is not requested
830 if (!(mdd(dispObj)->active_flags & VK_DBG_REPORT_INFO_BIT)) {
831 return;
832 }
833
834 // Just printing each msg individually for now, may want to package these into single large print
835 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
836 "Details of Memory Object list (of size %lu elements)", memObjMap.size());
837 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
838 "=============================");
839
840 if (memObjMap.size() <= 0)
841 return;
842
843 for (auto ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
844 pInfo = &(*ii).second;
845
846 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
847 " ===MemObjInfo at %p===", (void*)pInfo);
848 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
849 " Mem object: %#" PRIxLEAST64, (void*)pInfo->mem.handle);
850 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
851 " Ref Count: %u", pInfo->refCount);
852 if (0 != pInfo->allocInfo.allocationSize) {
853 string pAllocInfoMsg = vk_print_vkmemoryallocinfo(&pInfo->allocInfo, "MEM(INFO): ");
854 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
855 " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
856 } else {
857 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
Ian Elliott338dedb2015-08-21 15:09:33 -0600858 " Mem Alloc info is NULL (alloc done by vkCreateSwapchainKHR())");
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600859 }
860
861 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
862 " VK OBJECT Binding list of size %lu elements:", pInfo->pObjBindings.size());
863 if (pInfo->pObjBindings.size() > 0) {
864 for (list<MT_OBJ_HANDLE_TYPE>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
865 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
866 " VK OBJECT %p", (*it));
867 }
868 }
869
870 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
871 " VK Command Buffer (CB) binding list of size %lu elements", pInfo->pCmdBufferBindings.size());
872 if (pInfo->pCmdBufferBindings.size() > 0)
873 {
874 for (list<VkCmdBuffer>::iterator it = pInfo->pCmdBufferBindings.begin(); it != pInfo->pCmdBufferBindings.end(); ++it) {
875 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
876 " VK CB %p", (*it));
877 }
878 }
879 }
880}
881
882static void printCBList(
883 void* dispObj)
884{
885 MT_CB_INFO* pCBInfo = NULL;
886
887 // Early out if info is not requested
888 if (!(mdd(dispObj)->active_flags & VK_DBG_REPORT_INFO_BIT)) {
889 return;
890 }
891
892 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
893 "Details of CB list (of size %lu elements)", cbMap.size());
894 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
895 "==================");
896
897 if (cbMap.size() <= 0)
898 return;
899
900 for (auto ii=cbMap.begin(); ii!=cbMap.end(); ++ii) {
901 pCBInfo = &(*ii).second;
902
903 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
904 " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %#" PRIxLEAST64,
905 (void*)pCBInfo, (void*)pCBInfo->cmdBuffer, pCBInfo->fenceId,
906 pCBInfo->lastSubmittedFence.handle);
907
908 if (pCBInfo->pMemObjList.size() <= 0)
909 continue;
910 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
911 log_msg(mdd(dispObj), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, 0, 0, MEMTRACK_NONE, "MEM",
912 " Mem obj %p", (*it));
913 }
914 }
915}
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700916
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600917static void init_mem_tracker(
918 layer_data *my_data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700919{
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600920 uint32_t report_flags = 0;
921 uint32_t debug_action = 0;
922 FILE *log_output = NULL;
923 const char *option_str;
Jon Ashburnf57ea372014-12-22 13:24:15 -0700924 // initialize MemTracker options
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600925 report_flags = getLayerOptionFlags("MemTrackerReportFlags", 0);
926 getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &debug_action);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -0700927
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600928 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburnf57ea372014-12-22 13:24:15 -0700929 {
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600930 option_str = getLayerOption("MemTrackerLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -0600931 log_output = getLayerLogOutput(option_str, "MemTracker");
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600932 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
Jon Ashburnf57ea372014-12-22 13:24:15 -0700933 }
934
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600935 if (!globalLockInitialized)
936 {
937 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600938 // suggestion is to call this during vkCreateInstance(), and then we
939 // can clean it up during vkDestroyInstance(). However, that requires
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600940 // that the layer have per-instance locks. We need to come back and
941 // address this soon.
942 loader_platform_thread_create_mutex(&globalLock);
943 globalLockInitialized = 1;
944 }
Mark Lobodzinski72346292015-07-02 16:49:40 -0600945
946 // Zero out memory property data
947 memset(&memProps, 0, sizeof(VkPhysicalDeviceMemoryProperties));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700948}
949
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -0500950// hook DestroyInstance to remove tableInstanceMap entry
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600951VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -0500952{
Jeremy Hayesc8dff5f2015-06-18 10:25:55 -0600953 // Grab the key before the instance is destroyed.
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600954 dispatch_key key = get_dispatch_key(instance);
955 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(mem_tracker_instance_table_map, instance);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600956 pTable->DestroyInstance(instance);
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600957
958 // Clean up logging callback, if any
Courtney Goeltzenleuchter5b06b0c2015-06-16 16:58:52 -0600959 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600960 if (my_data->logging_callback) {
961 layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback);
962 }
963
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600964 layer_debug_report_destroy_instance(mid(instance));
965 layer_data_map.erase(pTable);
966
967 mem_tracker_instance_table_map.erase(key);
968 assert(mem_tracker_instance_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -0500969}
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600970
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600971VkResult VKAPI vkCreateInstance(
972 const VkInstanceCreateInfo* pCreateInfo,
973 VkInstance* pInstance)
974{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600975 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(mem_tracker_instance_table_map, *pInstance);
Courtney Goeltzenleuchterf4a2eba2015-06-08 14:58:39 -0600976 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600977
978 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600979 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
980 my_data->report_data = debug_report_create_instance(
981 pTable,
982 *pInstance,
983 pCreateInfo->extensionCount,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600984 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -0600985
986 init_mem_tracker(my_data);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -0600987 }
988 return result;
989}
990
Jon Ashburn7e07faf2015-06-18 15:02:58 -0600991static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
992{
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -0600993 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Jon Ashburn83334db2015-09-16 18:08:32 -0600994 VkLayerDispatchTable *pDisp = get_dispatch_table(mem_tracker_device_table_map, device);
995 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
996 pDisp->GetSurfacePropertiesKHR = (PFN_vkGetSurfacePropertiesKHR) gpa(device, "vkGetSurfacePropertiesKHR");
997 pDisp->GetSurfaceFormatsKHR = (PFN_vkGetSurfaceFormatsKHR) gpa(device, "vkGetSurfaceFormatsKHR");
998 pDisp->GetSurfacePresentModesKHR = (PFN_vkGetSurfacePresentModesKHR) gpa(device, "vkGetSurfacePresentModesKHR");
999 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
1000 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
1001 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
1002 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
1003 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
Ian Elliottb134e842015-07-06 14:31:32 -06001004 my_device_data->wsi_enabled = false;
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -06001005 for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
Ian Elliott338dedb2015-08-21 15:09:33 -06001006 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliottb134e842015-07-06 14:31:32 -06001007 my_device_data->wsi_enabled = true;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001008 }
1009}
1010
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001011VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(
1012 VkPhysicalDevice gpu,
1013 const VkDeviceCreateInfo *pCreateInfo,
1014 VkDevice *pDevice)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001015{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06001016 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(mem_tracker_device_table_map, *pDevice);
1017 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pDevice);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001018 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001019 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001020 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
1021 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001022 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001023 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001024 return result;
1025}
1026
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001027VK_LAYER_EXPORT void VKAPI vkDestroyDevice(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001028 VkDevice device)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001029{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001030 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001031 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001032 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE, (uint64_t)device, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001033 "Printing List details prior to vkDestroyDevice()");
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001034 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DEVICE, (uint64_t)device, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001035 "================================================");
1036 print_mem_list(device);
1037 printCBList(device);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001038 skipCall = delete_cmd_buf_info_list();
Tobin Ehlis22d03232014-11-25 18:01:12 -07001039 // Report any memory leaks
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001040 MT_MEM_OBJ_INFO* pInfo = NULL;
David Pinedof5997ab2015-04-27 16:36:17 -06001041 if (memObjMap.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001042 for (auto ii=memObjMap.begin(); ii!=memObjMap.end(); ++ii) {
Mike Stroyan988caa42015-05-19 17:03:40 -06001043 pInfo = &(*ii).second;
David Pinedof5997ab2015-04-27 16:36:17 -06001044 if (pInfo->allocInfo.allocationSize != 0) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001045 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, pInfo->mem.handle, 0, MEMTRACK_MEMORY_LEAK, "MEM",
1046 "Mem Object %p has not been freed. You should clean up this memory by calling "
1047 "vkFreeMemory(%p) prior to vkDestroyDevice().", pInfo->mem, pInfo->mem);
David Pinedof5997ab2015-04-27 16:36:17 -06001048 }
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -06001049 }
Tobin Ehlis22d03232014-11-25 18:01:12 -07001050 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001051 // Queues persist until device is destroyed
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001052 delete_queue_info_list();
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -06001053 layer_debug_report_destroy_device(device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001054 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05001055
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001056 dispatch_key key = get_dispatch_key(device);
Courtney Goeltzenleuchterab75b612015-06-13 21:40:22 -06001057#if DISPATCH_MAP_DEBUG
1058 fprintf(stderr, "Device: %p, key: %p\n", device, key);
1059#endif
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001060 VkLayerDispatchTable *pDisp = get_dispatch_table(mem_tracker_device_table_map, device);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001061 if (VK_FALSE == skipCall) {
1062 pDisp->DestroyDevice(device);
1063 }
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001064 mem_tracker_device_table_map.erase(key);
Courtney Goeltzenleuchter38eca262015-06-13 21:36:49 -06001065 assert(mem_tracker_device_table_map.size() == 0 && "Should not have any instance mappings hanging around");
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001066}
1067
Mark Lobodzinski72346292015-07-02 16:49:40 -06001068VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceMemoryProperties(
1069 VkPhysicalDevice physicalDevice,
1070 VkPhysicalDeviceMemoryProperties *pMemoryProperties)
1071{
1072 VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(mem_tracker_instance_table_map, physicalDevice);
1073 VkResult result = pInstanceTable->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
1074 if (result == VK_SUCCESS) {
1075 // copy mem props to local var...
1076 memcpy(&memProps, pMemoryProperties, sizeof(VkPhysicalDeviceMemoryProperties));
1077 }
1078 return result;
1079}
1080
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001081static const VkLayerProperties mtGlobalLayers[] = {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001082 {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001083 "MemTracker",
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001084 VK_API_VERSION,
1085 VK_MAKE_VERSION(0, 1, 0),
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001086 "Validation layer: MemTracker",
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001087 }
Jon Ashburneb2728b2015-04-10 14:33:07 -06001088};
1089
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001090VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001091 const char *pLayerName,
1092 uint32_t *pCount,
1093 VkExtensionProperties* pProperties)
Jon Ashburneb2728b2015-04-10 14:33:07 -06001094{
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001095 /* Mem tracker does not have any global extensions */
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001096 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -06001097}
1098
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001099VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001100 uint32_t *pCount,
1101 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -06001102{
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001103 return util_GetLayerProperties(ARRAY_SIZE(mtGlobalLayers),
1104 mtGlobalLayers,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001105 pCount, pProperties);
Jon Ashburneb2728b2015-04-10 14:33:07 -06001106}
1107
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001108VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001109 VkPhysicalDevice physicalDevice,
1110 const char* pLayerName,
1111 uint32_t* pCount,
1112 VkExtensionProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -06001113{
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001114 /* Mem tracker does not have any physical device extensions */
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001115 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001116}
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001117
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001118VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001119 VkPhysicalDevice physicalDevice,
1120 uint32_t* pCount,
1121 VkLayerProperties* pProperties)
1122{
1123 /* Mem tracker's physical device layers are the same as global */
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001124 return util_GetLayerProperties(ARRAY_SIZE(mtGlobalLayers), mtGlobalLayers,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001125 pCount, pProperties);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001126}
1127
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001128VK_LAYER_EXPORT VkResult VKAPI vkGetDeviceQueue(
1129 VkDevice device,
1130 uint32_t queueNodeIndex,
1131 uint32_t queueIndex,
1132 VkQueue *pQueue)
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001133{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001134 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001135 if (result == VK_SUCCESS) {
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001136 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001137 add_queue_info(*pQueue);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001138 loader_platform_thread_unlock_mutex(&globalLock);
1139 }
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001140 return result;
1141}
1142
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001143VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(
1144 VkQueue queue,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001145 uint32_t cmdBufferCount,
1146 const VkCmdBuffer *pCmdBuffers,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001147 VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001148{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001149 VkResult result = VK_ERROR_VALIDATION_FAILED;
1150
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001151 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001152 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001153 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001154 uint64_t fenceId = 0;
1155 VkBool32 skipCall = add_fence_info(fence, queue, &fenceId);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001156
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001157 print_mem_list(queue);
1158 printCBList(queue);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001159 for (uint32_t i = 0; i < cmdBufferCount; i++) {
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001160 pCBInfo = get_cmd_buf_info(pCmdBuffers[i]);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001161 pCBInfo->fenceId = fenceId;
Mike Stroyan53430332015-05-19 15:16:08 -06001162 pCBInfo->lastSubmittedFence = fence;
1163 pCBInfo->lastSubmittedQueue = queue;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001164 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001165
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001166 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001167 if (VK_FALSE == skipCall) {
1168 result = get_dispatch_table(mem_tracker_device_table_map, queue)->QueueSubmit(
1169 queue, cmdBufferCount, pCmdBuffers, fence);
1170 }
Courtney Goeltzenleuchtercfedf362015-04-02 13:39:07 -06001171 return result;
1172}
1173
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001174VK_LAYER_EXPORT VkResult VKAPI vkAllocMemory(
1175 VkDevice device,
1176 const VkMemoryAllocInfo *pAllocInfo,
1177 VkDeviceMemory *pMem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001178{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001179 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->AllocMemory(device, pAllocInfo, pMem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001180 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001181 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -06001182 add_mem_obj_info(device, *pMem, pAllocInfo);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001183 print_mem_list(device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001184 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001185 return result;
1186}
1187
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001188VK_LAYER_EXPORT void VKAPI vkFreeMemory(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001189 VkDevice device,
1190 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001191{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001192 /* From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed. Before
Tobin Ehlisa747e682014-11-25 14:47:20 -07001193 * freeing a memory object, an application must ensure the memory object is unbound from
1194 * all API objects referencing it and that it is not referenced by any queued command buffers
1195 */
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001196 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001197 freeMemObjInfo(device, mem, false);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001198 print_mem_list(device);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001199 printCBList(device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001200 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001201 get_dispatch_table(mem_tracker_device_table_map, device)->FreeMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001202}
1203
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001204VK_LAYER_EXPORT VkResult VKAPI vkMapMemory(
1205 VkDevice device,
1206 VkDeviceMemory mem,
1207 VkDeviceSize offset,
1208 VkDeviceSize size,
1209 VkFlags flags,
1210 void **ppData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001211{
1212 // TODO : Track when memory is mapped
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001213 VkBool32 skipCall = VK_FALSE;
1214 VkResult result = VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001215 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001216 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(mem.handle);
Mark Lobodzinski72346292015-07-02 16:49:40 -06001217 if ((memProps.memoryTypes[pMemObj->allocInfo.memoryTypeIndex].propertyFlags &
1218 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001219 skipCall = log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE_MEMORY, mem.handle, 0, MEMTRACK_INVALID_STATE, "MEM",
1220 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj %#" PRIxLEAST64, mem.handle);
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001221 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001222 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001223 if (VK_FALSE == skipCall) {
1224 result = get_dispatch_table(mem_tracker_device_table_map, device)->MapMemory(device, mem, offset, size, flags, ppData);
1225 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001226 return result;
1227}
1228
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001229VK_LAYER_EXPORT void VKAPI vkUnmapMemory(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001230 VkDevice device,
1231 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001232{
1233 // TODO : Track as memory gets unmapped, do we want to check what changed following map?
1234 // Make sure that memory was ever mapped to begin with
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001235 get_dispatch_table(mem_tracker_device_table_map, device)->UnmapMemory(device, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001236}
1237
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001238VK_LAYER_EXPORT void VKAPI vkDestroyFence(VkDevice device, VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001239{
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001240 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001241 delete_fence_info(fence);
1242 auto item = fenceMap.find(fence.handle);
1243 if (item != fenceMap.end()) {
1244 fenceMap.erase(item);
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001245 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001246 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001247 get_dispatch_table(mem_tracker_device_table_map, device)->DestroyFence(device, fence);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001248}
1249
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001250VK_LAYER_EXPORT void VKAPI vkDestroyBuffer(VkDevice device, VkBuffer buffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001251{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001252 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001253 loader_platform_thread_lock_mutex(&globalLock);
1254 auto item = bufferMap.find(buffer.handle);
1255 if (item != bufferMap.end()) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001256 skipCall = clear_object_binding(device, buffer.handle, VK_OBJECT_TYPE_BUFFER);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001257 bufferMap.erase(item);
1258 }
1259 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001260 if (VK_FALSE == skipCall) {
1261 get_dispatch_table(mem_tracker_device_table_map, device)->DestroyBuffer(device, buffer);
1262 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001263}
1264
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001265VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001266{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001267 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001268 loader_platform_thread_lock_mutex(&globalLock);
1269 auto item = imageMap.find(image.handle);
1270 if (item != imageMap.end()) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001271 skipCall = clear_object_binding(device, image.handle, VK_OBJECT_TYPE_IMAGE);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001272 imageMap.erase(item);
1273 }
1274 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001275 if (VK_FALSE == skipCall) {
1276 get_dispatch_table(mem_tracker_device_table_map, device)->DestroyImage(device, image);
1277 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001278}
1279
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001280VkResult VKAPI vkBindBufferMemory(
1281 VkDevice device,
1282 VkBuffer buffer,
1283 VkDeviceMemory mem,
1284 VkDeviceSize memOffset)
1285{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001286 VkResult result = VK_ERROR_VALIDATION_FAILED;
Mike Stroyan230e6252015-04-17 12:36:38 -06001287 loader_platform_thread_lock_mutex(&globalLock);
1288 // Track objects tied to memory
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001289 VkBool32 skipCall = set_mem_binding(device, mem, buffer.handle, VK_OBJECT_TYPE_BUFFER, "vkBindBufferMemory");
Tobin Ehlis33ce8fd2015-07-10 18:25:07 -06001290 add_object_binding_info(buffer.handle, VK_OBJECT_TYPE_BUFFER, mem);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001291 print_mem_list(device);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001292 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001293 if (VK_FALSE == skipCall) {
1294 result = get_dispatch_table(mem_tracker_device_table_map, device)->BindBufferMemory(device, buffer, mem, memOffset);
1295 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001296 return result;
1297}
1298
1299VkResult VKAPI vkBindImageMemory(
1300 VkDevice device,
1301 VkImage image,
1302 VkDeviceMemory mem,
1303 VkDeviceSize memOffset)
1304{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001305 VkResult result = VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001306 loader_platform_thread_lock_mutex(&globalLock);
1307 // Track objects tied to memory
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001308 VkBool32 skipCall = set_mem_binding(device, mem, image.handle, VK_OBJECT_TYPE_IMAGE, "vkBindImageMemory");
Tobin Ehlis33ce8fd2015-07-10 18:25:07 -06001309 add_object_binding_info(image.handle, VK_OBJECT_TYPE_IMAGE, mem);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001310 print_mem_list(device);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001311 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001312 if (VK_FALSE == skipCall) {
1313 result = get_dispatch_table(mem_tracker_device_table_map, device)->BindImageMemory(device, image, mem, memOffset);
1314 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001315 return result;
1316}
1317
1318VkResult VKAPI vkGetBufferMemoryRequirements(
1319 VkDevice device,
1320 VkBuffer buffer,
1321 VkMemoryRequirements* pMemoryRequirements)
1322{
1323 // TODO : What to track here?
1324 // Could potentially save returned mem requirements and validate values passed into BindBufferMemory
1325 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
1326 return result;
1327}
1328
1329VkResult VKAPI vkGetImageMemoryRequirements(
1330 VkDevice device,
1331 VkImage image,
1332 VkMemoryRequirements* pMemoryRequirements)
1333{
1334 // TODO : What to track here?
1335 // Could potentially save returned mem requirements and validate values passed into BindImageMemory
1336 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->GetImageMemoryRequirements(device, image, pMemoryRequirements);
1337 return result;
1338}
1339
1340VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseImageOpaqueMemory(
1341 VkQueue queue,
1342 VkImage image,
1343 uint32_t numBindings,
1344 const VkSparseMemoryBindInfo* pBindInfo)
1345{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001346 VkResult result = VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001347 loader_platform_thread_lock_mutex(&globalLock);
1348 // Track objects tied to memory
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001349 VkBool32 skipCall = set_sparse_mem_binding(queue, pBindInfo->mem, image.handle, VK_OBJECT_TYPE_IMAGE, "vkQueueBindSparseImageOpaqeMemory");
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001350 print_mem_list(queue);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001351 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001352 if (VK_FALSE == skipCall) {
1353 result = get_dispatch_table(mem_tracker_device_table_map, queue)->QueueBindSparseImageOpaqueMemory( queue, image, numBindings, pBindInfo);
1354 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001355 return result;
1356}
1357
1358VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseImageMemory(
1359 VkQueue queue,
1360 VkImage image,
1361 uint32_t numBindings,
1362 const VkSparseImageMemoryBindInfo* pBindInfo)
1363{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001364 VkResult result = VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001365 loader_platform_thread_lock_mutex(&globalLock);
1366 // Track objects tied to memory
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001367 VkBool32 skipCall = set_sparse_mem_binding(queue, pBindInfo->mem, image.handle, VK_OBJECT_TYPE_IMAGE, "vkQueueBindSparseImageMemory");
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001368 print_mem_list(queue);
Mike Stroyan230e6252015-04-17 12:36:38 -06001369 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001370 if (VK_FALSE == skipCall) {
1371 VkResult result = get_dispatch_table(mem_tracker_device_table_map, queue)->QueueBindSparseImageMemory(
1372 queue, image, numBindings, pBindInfo);
1373 }
Mike Stroyan230e6252015-04-17 12:36:38 -06001374 return result;
1375}
1376
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05001377VK_LAYER_EXPORT VkResult VKAPI vkQueueBindSparseBufferMemory(
Mark Lobodzinski83d4e6a2015-07-03 15:58:09 -06001378 VkQueue queue,
1379 VkBuffer buffer,
1380 uint32_t numBindings,
1381 const VkSparseMemoryBindInfo* pBindInfo)
Mike Stroyan230e6252015-04-17 12:36:38 -06001382{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001383 VkResult result = VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001384 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001385 // Track objects tied to memory
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001386 VkBool32 skipCall = set_sparse_mem_binding(queue, pBindInfo->mem, buffer.handle, VK_OBJECT_TYPE_BUFFER, "VkQueueBindSparseBufferMemory");
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001387 print_mem_list(queue);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001388 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001389 if (VK_FALSE == skipCall) {
1390 VkResult result = get_dispatch_table(mem_tracker_device_table_map, queue)->QueueBindSparseBufferMemory(
1391 queue, buffer, numBindings, pBindInfo);
1392 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001393 return result;
1394}
1395
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001396VK_LAYER_EXPORT VkResult VKAPI vkCreateFence(
1397 VkDevice device,
1398 const VkFenceCreateInfo *pCreateInfo,
1399 VkFence *pFence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001400{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001401 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateFence(device, pCreateInfo, pFence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001402 if (VK_SUCCESS == result) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001403 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001404 MT_FENCE_INFO* pFI = &fenceMap[pFence->handle];
1405 memset(pFI, 0, sizeof(MT_FENCE_INFO));
1406 memcpy(&(pFI->createInfo), pCreateInfo, sizeof(VkFenceCreateInfo));
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001407 loader_platform_thread_unlock_mutex(&globalLock);
1408 }
1409 return result;
1410}
1411
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001412VK_LAYER_EXPORT VkResult VKAPI vkResetFences(
1413 VkDevice device,
1414 uint32_t fenceCount,
Courtney Goeltzenleuchterf2e33ad2015-06-18 17:28:20 -06001415 const VkFence *pFences)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001416{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001417 VkResult result = VK_ERROR_VALIDATION_FAILED;
1418 VkBool32 skipCall = VK_FALSE;
1419
1420 loader_platform_thread_lock_mutex(&globalLock);
1421 // Reset fence state in fenceCreateInfo structure
1422 for (uint32_t i = 0; i < fenceCount; i++) {
1423 auto fence_item = fenceMap.find(pFences[i].handle);
1424 if (fence_item != fenceMap.end()) {
1425 // Validate fences in SIGNALED state
1426 if (!(fence_item->second.createInfo.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Michael Lentinebfb5fd62015-09-23 17:43:16 -07001427 skipCall = log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_FENCE, pFences[i].handle, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001428 "Fence %#" PRIxLEAST64 " submitted to VkResetFences in UNSIGNALED STATE", pFences[i].handle);
1429 }
1430 else {
1431 fence_item->second.createInfo.flags =
1432 static_cast<VkFenceCreateFlags>(fence_item->second.createInfo.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001433 }
1434 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001435 }
1436 loader_platform_thread_unlock_mutex(&globalLock);
1437 if (VK_FALSE == skipCall) {
1438 result = get_dispatch_table(mem_tracker_device_table_map, device)->ResetFences(device, fenceCount, pFences);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001439 }
1440 return result;
1441}
1442
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001443static inline VkBool32 verifyFenceStatus(VkDevice device, VkFence fence, const char* apiCall)
1444{
1445 VkBool32 skipCall = VK_FALSE;
1446 auto pFenceInfo = fenceMap.find(fence.handle);
1447 if (pFenceInfo != fenceMap.end()) {
1448 if (pFenceInfo->second.createInfo.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
1449 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_FENCE, fence.handle, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
1450 "%s specified fence %#" PRIxLEAST64 " already in SIGNALED state.", apiCall, fence.handle);
1451 }
1452 if (!pFenceInfo->second.queue) { // Checking status of unsubmitted fence
1453 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_FENCE, fence.handle, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
1454 "%s called for fence %#" PRIxLEAST64 " which has not been submitted on a Queue.", apiCall, fence.handle);
1455 }
1456 }
1457 return skipCall;
1458}
1459
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001460VK_LAYER_EXPORT VkResult VKAPI vkGetFenceStatus(
1461 VkDevice device,
1462 VkFence fence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001463{
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001464 VkBool32 skipCall = verifyFenceStatus(device, fence, "vkGetFenceStatus");
1465 if (skipCall)
1466 return VK_ERROR_VALIDATION_FAILED;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001467 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->GetFenceStatus(device, fence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001468 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001469 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001470 update_fence_tracking(fence);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001471 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001472 }
1473 return result;
1474}
1475
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001476VK_LAYER_EXPORT VkResult VKAPI vkWaitForFences(
1477 VkDevice device,
1478 uint32_t fenceCount,
1479 const VkFence *pFences,
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06001480 VkBool32 waitAll,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001481 uint64_t timeout)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001482{
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001483 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001484 // Verify fence status of submitted fences
1485 for(uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001486 skipCall |= verifyFenceStatus(device, pFences[i], "vkWaitForFences");
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001487 }
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001488 if (skipCall)
1489 return VK_ERROR_VALIDATION_FAILED;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001490 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001491 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001492
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001493 if (VK_SUCCESS == result) {
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001494 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001495 for(uint32_t i = 0; i < fenceCount; i++) {
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001496 update_fence_tracking(pFences[i]);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001497 }
1498 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001499 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001500 loader_platform_thread_unlock_mutex(&globalLock);
1501 return result;
1502}
1503
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001504VK_LAYER_EXPORT VkResult VKAPI vkQueueWaitIdle(
1505 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001506{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001507 VkResult result = get_dispatch_table(mem_tracker_device_table_map, queue)->QueueWaitIdle(queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001508 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001509 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001510 retire_queue_fences(queue);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001511 loader_platform_thread_unlock_mutex(&globalLock);
1512 }
1513 return result;
1514}
1515
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001516VK_LAYER_EXPORT VkResult VKAPI vkDeviceWaitIdle(
1517 VkDevice device)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001518{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001519 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->DeviceWaitIdle(device);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001520 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001521 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001522 retire_device_fences(device);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001523 loader_platform_thread_unlock_mutex(&globalLock);
1524 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001525 return result;
1526}
1527
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001528VK_LAYER_EXPORT VkResult VKAPI vkCreateEvent(
1529 VkDevice device,
1530 const VkEventCreateInfo *pCreateInfo,
1531 VkEvent *pEvent)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001532{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001533 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateEvent(device, pCreateInfo, pEvent);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001534 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001535 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001536 add_object_create_info(pEvent->handle, VK_OBJECT_TYPE_EVENT, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001537 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001538 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001539 return result;
1540}
1541
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001542VK_LAYER_EXPORT VkResult VKAPI vkCreateQueryPool(
1543 VkDevice device,
1544 const VkQueryPoolCreateInfo *pCreateInfo,
1545 VkQueryPool *pQueryPool)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001546{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001547 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateQueryPool(device, pCreateInfo, pQueryPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001548 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001549 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001550 add_object_create_info(pQueryPool->handle, VK_OBJECT_TYPE_QUERY_POOL, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001551 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001552 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001553 return result;
1554}
1555
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001556VK_LAYER_EXPORT VkResult VKAPI vkCreateBuffer(
1557 VkDevice device,
1558 const VkBufferCreateInfo *pCreateInfo,
1559 VkBuffer *pBuffer)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001560{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001561 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateBuffer(device, pCreateInfo, pBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001562 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001563 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001564 add_object_create_info(pBuffer->handle, VK_OBJECT_TYPE_BUFFER, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001565 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001566 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001567 return result;
1568}
1569
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001570VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(
1571 VkDevice device,
1572 const VkBufferViewCreateInfo *pCreateInfo,
1573 VkBufferView *pView)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001574{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001575 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001576 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001577 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001578 add_object_create_info(pView->handle, VK_OBJECT_TYPE_BUFFER_VIEW, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001579 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001580 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001581 return result;
1582}
1583
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001584VK_LAYER_EXPORT VkResult VKAPI vkCreateImage(
1585 VkDevice device,
1586 const VkImageCreateInfo *pCreateInfo,
1587 VkImage *pImage)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001588{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001589 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateImage(device, pCreateInfo, pImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001590 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001591 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001592 add_object_create_info(pImage->handle, VK_OBJECT_TYPE_IMAGE, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001593 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001594 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001595 return result;
1596}
1597
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001598VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(
1599 VkDevice device,
1600 const VkImageViewCreateInfo *pCreateInfo,
1601 VkImageView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001602{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001603 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001604 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001605 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001606 add_object_create_info(pView->handle, VK_OBJECT_TYPE_IMAGE_VIEW, pCreateInfo);
Tobin Ehlisd94ba722015-07-03 08:45:14 -06001607 // Validate that img has correct usage flags set
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -06001608 validate_image_usage_flags(
1609 device, pCreateInfo->image,
Courtney Goeltzenleuchterc3b8eea2015-09-10 14:14:11 -06001610 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -06001611 false, "vkCreateImageView()", "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT]_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001612 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001613 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001614 return result;
1615}
1616
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001617VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(
1618 VkDevice device,
1619 const VkShaderCreateInfo *pCreateInfo,
1620 VkShader *pShader)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001621{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001622 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateShader(device, pCreateInfo, pShader);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001623 if (result == VK_SUCCESS) {
1624 loader_platform_thread_lock_mutex(&globalLock);
1625 add_object_create_info(pShader->handle, VK_OBJECT_TYPE_SHADER, pCreateInfo);
1626 loader_platform_thread_unlock_mutex(&globalLock);
1627 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001628 return result;
1629}
1630
Jon Ashburn0d60d272015-07-09 15:02:25 -06001631//TODO do we need to intercept pipelineCache functions to track objects?
1632VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelines(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001633 VkDevice device,
Jon Ashburn0d60d272015-07-09 15:02:25 -06001634 VkPipelineCache pipelineCache,
1635 uint32_t count,
1636 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1637 VkPipeline *pPipelines)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001638{
Jon Ashburn0d60d272015-07-09 15:02:25 -06001639 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001640 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001641 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001642 for (int i = 0; i < count; i++) {
1643 add_object_create_info(pPipelines[i].handle, VK_OBJECT_TYPE_PIPELINE, &pCreateInfos[i]);
1644 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001645 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001646 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001647 return result;
1648}
1649
Jon Ashburn0d60d272015-07-09 15:02:25 -06001650VK_LAYER_EXPORT VkResult VKAPI vkCreateComputePipelines(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001651 VkDevice device,
Jon Ashburn0d60d272015-07-09 15:02:25 -06001652 VkPipelineCache pipelineCache,
1653 uint32_t count,
1654 const VkComputePipelineCreateInfo *pCreateInfos,
1655 VkPipeline *pPipelines)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001656{
Jon Ashburn0d60d272015-07-09 15:02:25 -06001657 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001658 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001659 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001660 for (int i = 0; i < count; i++) {
1661 add_object_create_info(pPipelines[i].handle, VK_OBJECT_TYPE_PIPELINE, &pCreateInfos[i]);
1662 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001663 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001664 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001665 return result;
1666}
1667
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001668VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(
1669 VkDevice device,
1670 const VkSamplerCreateInfo *pCreateInfo,
1671 VkSampler *pSampler)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001672{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001673 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001674 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001675 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001676 add_object_create_info(pSampler->handle, VK_OBJECT_TYPE_SAMPLER, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001677 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001678 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001679 return result;
1680}
1681
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001682VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(
1683 VkDevice device,
1684 const VkCmdBufferCreateInfo *pCreateInfo,
1685 VkCmdBuffer *pCmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001686{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001687 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001688 // At time of cmd buffer creation, create global cmd buffer info for the returned cmd buffer
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001689 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001690 if (*pCmdBuffer)
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001691 add_cmd_buf_info(*pCmdBuffer);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001692 printCBList(device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001693 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001694 return result;
1695}
1696
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001697VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(
1698 VkCmdBuffer cmdBuffer,
1699 const VkCmdBufferBeginInfo *pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001700{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001701 VkResult result = VK_ERROR_VALIDATION_FAILED;
1702 VkBool32 skipCall = VK_FALSE;
1703 VkBool32 cmdBufferComplete = VK_FALSE;
Mike Stroyan53430332015-05-19 15:16:08 -06001704 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001705 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001706 skipCall = checkCBCompleted(cmdBuffer, &cmdBufferComplete);
1707
1708 if (VK_FALSE == cmdBufferComplete) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001709 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1710 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001711 "You must check CB flag before this call.", cmdBuffer);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001712 }
Mike Stroyan53430332015-05-19 15:16:08 -06001713 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001714 if (VK_FALSE == skipCall) {
1715 result = get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->BeginCommandBuffer(cmdBuffer, pBeginInfo);
1716 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001717 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001718 clear_cmd_buf_and_mem_references(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001719 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001720 return result;
1721}
1722
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001723VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(
1724 VkCmdBuffer cmdBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001725{
1726 // TODO : Anything to do here?
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001727 VkResult result = get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->EndCommandBuffer(cmdBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001728 return result;
1729}
1730
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001731VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(
Cody Northropf02f9f82015-07-09 18:08:05 -06001732 VkCmdBuffer cmdBuffer,
1733 VkCmdBufferResetFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001734{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001735 VkResult result = VK_ERROR_VALIDATION_FAILED;
1736 VkBool32 skipCall = VK_FALSE;
1737 VkBool32 cmdBufferComplete = VK_FALSE;
Mike Stroyan53430332015-05-19 15:16:08 -06001738 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001739 // Verify that CB is complete (not in-flight)
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001740 skipCall = checkCBCompleted(cmdBuffer, &cmdBufferComplete);
1741 if (VK_FALSE == cmdBufferComplete) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001742 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1743 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", "Resetting CB %p before it has completed. You must check CB "
1744 "flag before calling vkResetCommandBuffer().", cmdBuffer);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001745 }
1746 // Clear memory references as this point.
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001747 skipCall |= clear_cmd_buf_and_mem_references(cmdBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001748 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001749 if (VK_FALSE == skipCall) {
1750 result = get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->ResetCommandBuffer(cmdBuffer, flags);
Courtney Goeltzenleuchter0d6857f2015-09-04 13:52:24 -06001751 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001752 return result;
1753}
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001754// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001755// need to account for that mem now having binding to given cmdBuffer
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001756VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(
1757 VkCmdBuffer cmdBuffer,
1758 VkPipelineBindPoint pipelineBindPoint,
1759 VkPipeline pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001760{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001761#if 0
1762 // TODO : If memory bound to pipeline, then need to tie that mem to cmdBuffer
1763 if (getPipeline(pipeline)) {
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001764 MT_CB_INFO *pCBInfo = get_cmd_buf_info(cmdBuffer);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001765 if (pCBInfo) {
1766 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001767 } else {
Courtney Goeltzenleuchter3e19bf62015-06-14 09:50:18 -06001768 "Attempt to bind Pipeline %p to non-existant command buffer %p!", (void*)pipeline, cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001769 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, MEMTRACK_INVALID_CB, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001770 }
1771 }
1772 else {
Courtney Goeltzenleuchter3e19bf62015-06-14 09:50:18 -06001773 "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001774 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001775 }
1776#endif
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001777 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001778}
1779
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001780VK_LAYER_EXPORT void VKAPI vkCmdSetViewport(
1781 VkCmdBuffer cmdBuffer,
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06001782 uint32_t viewportCount,
1783 const VkViewport* pViewports)
1784{
1785 VkBool32 skipCall = VK_FALSE;
1786 loader_platform_thread_lock_mutex(&globalLock);
1787 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1788 if (!pCmdBuf) {
1789 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1790 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1791 }
1792 loader_platform_thread_unlock_mutex(&globalLock);
1793 if (VK_FALSE == skipCall) {
1794 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetViewport(cmdBuffer, viewportCount, pViewports);
1795 }
1796}
1797
1798VK_LAYER_EXPORT void VKAPI vkCmdSetScissor(
1799 VkCmdBuffer cmdBuffer,
1800 uint32_t scissorCount,
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001801 const VkRect2D* pScissors)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001802{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001803 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001804 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -05001805 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001806 if (!pCmdBuf) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001807 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1808 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001809 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001810 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001811 if (VK_FALSE == skipCall) {
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06001812 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetScissor(cmdBuffer, scissorCount, pScissors);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001813 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001814}
1815
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001816VK_LAYER_EXPORT void VKAPI vkCmdSetLineWidth(VkCmdBuffer cmdBuffer, float lineWidth)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001817{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001818 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001819 loader_platform_thread_lock_mutex(&globalLock);
1820 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1821 if (!pCmdBuf) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001822 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1823 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001824 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001825 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001826 if (VK_FALSE == skipCall) {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001827 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetLineWidth(cmdBuffer, lineWidth);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001828 }
Cody Northropf5bd2252015-08-17 11:10:49 -06001829}
1830
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001831VK_LAYER_EXPORT void VKAPI vkCmdSetDepthBias(
1832 VkCmdBuffer cmdBuffer,
1833 float depthBias,
1834 float depthBiasClamp,
1835 float slopeScaledDepthBias)
Cody Northropf5bd2252015-08-17 11:10:49 -06001836{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001837 VkBool32 skipCall = VK_FALSE;
Cody Northropf5bd2252015-08-17 11:10:49 -06001838 loader_platform_thread_lock_mutex(&globalLock);
1839 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1840 if (!pCmdBuf) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001841 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1842 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Cody Northropf5bd2252015-08-17 11:10:49 -06001843 }
Cody Northropf5bd2252015-08-17 11:10:49 -06001844 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001845 if (VK_FALSE == skipCall) {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001846 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetDepthBias(cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001847 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001848}
1849
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001850VK_LAYER_EXPORT void VKAPI vkCmdSetBlendConstants(
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001851 VkCmdBuffer cmdBuffer,
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001852 const float blendConst[4])
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001853{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001854 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001855 loader_platform_thread_lock_mutex(&globalLock);
1856 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1857 if (!pCmdBuf) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001858 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1859 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001860 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001861 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001862 if (VK_FALSE == skipCall) {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001863 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetBlendConstants(cmdBuffer, blendConst);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001864 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001865}
1866
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001867VK_LAYER_EXPORT void VKAPI vkCmdSetDepthBounds(
1868 VkCmdBuffer cmdBuffer,
1869 float minDepthBounds,
1870 float maxDepthBounds)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001871{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001872 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001873 loader_platform_thread_lock_mutex(&globalLock);
1874 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1875 if (!pCmdBuf) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001876 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1877 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001878 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001879 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001880 if (VK_FALSE == skipCall) {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001881 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetDepthBounds(cmdBuffer, minDepthBounds, maxDepthBounds);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001882 }
Cody Northrop2605cb02015-08-18 15:21:16 -06001883}
1884
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001885VK_LAYER_EXPORT void VKAPI vkCmdSetStencilCompareMask(
1886 VkCmdBuffer cmdBuffer,
1887 VkStencilFaceFlags faceMask,
1888 uint32_t stencilCompareMask)
Cody Northrop2605cb02015-08-18 15:21:16 -06001889{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001890 VkBool32 skipCall = VK_FALSE;
Cody Northrop2605cb02015-08-18 15:21:16 -06001891 loader_platform_thread_lock_mutex(&globalLock);
1892 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1893 if (!pCmdBuf) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06001894 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1895 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
Cody Northrop2605cb02015-08-18 15:21:16 -06001896 }
Cody Northrop2605cb02015-08-18 15:21:16 -06001897 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001898 if (VK_FALSE == skipCall) {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06001899 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetStencilCompareMask(cmdBuffer, faceMask, stencilCompareMask);
1900 }
1901}
1902
1903VK_LAYER_EXPORT void VKAPI vkCmdSetStencilWriteMask(
1904 VkCmdBuffer cmdBuffer,
1905 VkStencilFaceFlags faceMask,
1906 uint32_t stencilWriteMask)
1907{
1908 VkBool32 skipCall = VK_FALSE;
1909 loader_platform_thread_lock_mutex(&globalLock);
1910 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1911 if (!pCmdBuf) {
1912 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1913 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1914 }
1915 loader_platform_thread_unlock_mutex(&globalLock);
1916 if (VK_FALSE == skipCall) {
1917 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetStencilWriteMask(cmdBuffer, faceMask, stencilWriteMask);
1918 }
1919}
1920
1921VK_LAYER_EXPORT void VKAPI vkCmdSetStencilReference(
1922 VkCmdBuffer cmdBuffer,
1923 VkStencilFaceFlags faceMask,
1924 uint32_t stencilReference)
1925{
1926 VkBool32 skipCall = VK_FALSE;
1927 loader_platform_thread_lock_mutex(&globalLock);
1928 MT_CB_INFO *pCmdBuf = get_cmd_buf_info(cmdBuffer);
1929 if (!pCmdBuf) {
1930 skipCall = log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0,
1931 MEMTRACK_INVALID_CB, "MEM", "Unable to find command buffer object %p, was it ever created?", (void*)cmdBuffer);
1932 }
1933 loader_platform_thread_unlock_mutex(&globalLock);
1934 if (VK_FALSE == skipCall) {
1935 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdSetStencilReference(cmdBuffer, faceMask, stencilReference);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001936 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001937}
1938
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001939VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001940 VkCmdBuffer cmdBuffer,
1941 VkPipelineBindPoint pipelineBindPoint,
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001942 VkPipelineLayout layout,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001943 uint32_t firstSet,
1944 uint32_t setCount,
1945 const VkDescriptorSet *pDescriptorSets,
1946 uint32_t dynamicOffsetCount,
1947 const uint32_t *pDynamicOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001948{
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07001949 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001950 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdBindDescriptorSets(
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06001951 cmdBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001952}
1953
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06001954VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001955 VkCmdBuffer cmdBuffer,
1956 uint32_t startBinding,
1957 uint32_t bindingCount,
1958 const VkBuffer *pBuffers,
1959 const VkDeviceSize *pOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001960{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001961 // TODO : Somewhere need to verify that VBs have correct usage state flagged
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001962 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wufb5062e2015-01-05 13:42:56 +08001963}
1964
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001965VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(
1966 VkCmdBuffer cmdBuffer,
1967 VkBuffer buffer,
1968 VkDeviceSize offset,
1969 VkIndexType indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001970{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001971 // TODO : Somewhere need to verify that IBs have correct usage state flagged
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001972 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001973}
1974
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001975VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(
1976 VkCmdBuffer cmdBuffer,
1977 VkBuffer buffer,
1978 VkDeviceSize offset,
1979 uint32_t count,
1980 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001981{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001982 VkDeviceMemory mem;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001983 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001984 VkBool32 skipCall = get_mem_binding_from_object(cmdBuffer, buffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
1985 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdDrawIndirect");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001986 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001987 if (VK_FALSE == skipCall) {
1988 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
1989 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001990}
1991
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001992VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(
1993 VkCmdBuffer cmdBuffer,
1994 VkBuffer buffer,
1995 VkDeviceSize offset,
1996 uint32_t count,
1997 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001998{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001999 VkDeviceMemory mem;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002000 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002001 VkBool32 skipCall = get_mem_binding_from_object(cmdBuffer, buffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2002 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdDrawIndexedIndirect");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002003 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002004 if (VK_FALSE == skipCall) {
2005 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
2006 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002007}
2008
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002009VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(
2010 VkCmdBuffer cmdBuffer,
2011 VkBuffer buffer,
2012 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002013{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002014 VkDeviceMemory mem;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002015 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002016 VkBool32 skipCall = get_mem_binding_from_object(cmdBuffer, buffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2017 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdDispatchIndirect");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002018 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002019 if (VK_FALSE == skipCall) {
2020 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdDispatchIndirect(cmdBuffer, buffer, offset);
2021 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002022}
2023
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002024VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(
2025 VkCmdBuffer cmdBuffer,
2026 VkBuffer srcBuffer,
2027 VkBuffer destBuffer,
2028 uint32_t regionCount,
2029 const VkBufferCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002030{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002031 VkDeviceMemory mem;
2032 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002033 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002034 skipCall = get_mem_binding_from_object(cmdBuffer, srcBuffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2035 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyBuffer");
2036 skipCall |= get_mem_binding_from_object(cmdBuffer, destBuffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2037 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002038 // Validate that SRC & DST buffers have correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002039 skipCall |= validate_buffer_usage_flags(cmdBuffer, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT, true, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT");
2040 skipCall |= validate_buffer_usage_flags(cmdBuffer, destBuffer, VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002041 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002042 if (VK_FALSE == skipCall) {
2043 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
2044 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002045}
2046
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002047VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(
2048 VkCmdBuffer cmdBuffer,
2049 VkImage srcImage,
2050 VkImageLayout srcImageLayout,
2051 VkImage destImage,
2052 VkImageLayout destImageLayout,
2053 uint32_t regionCount,
2054 const VkImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002055{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002056 VkDeviceMemory mem;
2057 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002058 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002059 // Validate that src & dst images have correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002060 skipCall = get_mem_binding_from_object(cmdBuffer, srcImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2061 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyImage");
2062 skipCall |= get_mem_binding_from_object(cmdBuffer, destImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2063 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyImage");
2064 skipCall |= validate_image_usage_flags(cmdBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, true, "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT");
2065 skipCall |= validate_image_usage_flags(cmdBuffer, destImage, VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002066 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002067 if (VK_FALSE == skipCall) {
2068 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdCopyImage(
2069 cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
2070 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002071}
2072
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002073VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(
2074 VkCmdBuffer cmdBuffer,
2075 VkImage srcImage,
2076 VkImageLayout srcImageLayout,
2077 VkImage destImage,
2078 VkImageLayout destImageLayout,
2079 uint32_t regionCount,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002080 const VkImageBlit *pRegions,
2081 VkTexFilter filter)
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06002082{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002083 VkDeviceMemory mem;
2084 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002085 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002086 // Validate that src & dst images have correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002087 skipCall = get_mem_binding_from_object(cmdBuffer, srcImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2088 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdBlitImage");
2089 skipCall |= get_mem_binding_from_object(cmdBuffer, destImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2090 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdBlitImage");
2091 skipCall |= validate_image_usage_flags(cmdBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, true, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT");
2092 skipCall |= validate_image_usage_flags(cmdBuffer, destImage, VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002093 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002094 if (VK_FALSE == skipCall) {
2095 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdBlitImage(
2096 cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
2097 }
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06002098}
2099
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002100VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(
2101 VkCmdBuffer cmdBuffer,
2102 VkBuffer srcBuffer,
2103 VkImage destImage,
2104 VkImageLayout destImageLayout,
2105 uint32_t regionCount,
2106 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002107{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002108 VkDeviceMemory mem;
2109 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002110 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002111 skipCall = get_mem_binding_from_object(cmdBuffer, destImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2112 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyBufferToImage");
2113 skipCall |= get_mem_binding_from_object(cmdBuffer, srcBuffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2114 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyBufferToImage");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002115 // Validate that src buff & dst image have correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002116 skipCall |= validate_buffer_usage_flags(cmdBuffer, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT, true, "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT");
2117 skipCall |= validate_image_usage_flags(cmdBuffer, destImage, VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002118 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002119 if (VK_FALSE == skipCall) {
2120 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdCopyBufferToImage(
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05002121 cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002122 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002123}
2124
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002125VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(
2126 VkCmdBuffer cmdBuffer,
2127 VkImage srcImage,
2128 VkImageLayout srcImageLayout,
2129 VkBuffer destBuffer,
2130 uint32_t regionCount,
2131 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002132{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002133 VkDeviceMemory mem;
2134 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002135 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002136 skipCall = get_mem_binding_from_object(cmdBuffer, srcImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2137 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyImageToBuffer");
2138 skipCall |= get_mem_binding_from_object(cmdBuffer, destBuffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2139 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdCopyImageToBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002140 // Validate that dst buff & src image have correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002141 skipCall |= validate_image_usage_flags(cmdBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, true, "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT");
2142 skipCall |= validate_buffer_usage_flags(cmdBuffer, destBuffer, VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002143 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002144 if (VK_FALSE == skipCall) {
2145 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(
2146 cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
2147 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002148}
2149
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002150VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(
2151 VkCmdBuffer cmdBuffer,
2152 VkBuffer destBuffer,
2153 VkDeviceSize destOffset,
2154 VkDeviceSize dataSize,
2155 const uint32_t *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002156{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002157 VkDeviceMemory mem;
2158 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002159 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002160 skipCall = get_mem_binding_from_object(cmdBuffer, destBuffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2161 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdUpdateBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002162 // Validate that dst buff has correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002163 skipCall |= validate_buffer_usage_flags(cmdBuffer, destBuffer, VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdUpdateBuffer()", "VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002164 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002165 if (VK_FALSE == skipCall) {
2166 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
2167 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002168}
2169
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002170VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(
2171 VkCmdBuffer cmdBuffer,
2172 VkBuffer destBuffer,
2173 VkDeviceSize destOffset,
2174 VkDeviceSize fillSize,
2175 uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002176{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002177 VkDeviceMemory mem;
2178 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002179 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002180 skipCall = get_mem_binding_from_object(cmdBuffer, destBuffer.handle, VK_OBJECT_TYPE_BUFFER, &mem);
2181 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdFillBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002182 // Validate that dst buff has correct usage flags set
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002183 skipCall |= validate_buffer_usage_flags(cmdBuffer, destBuffer, VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, true, "vkCmdFillBuffer()", "VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002184 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002185 if (VK_FALSE == skipCall) {
2186 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
2187 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002188}
2189
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002190VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2191 VkCmdBuffer cmdBuffer,
2192 VkImage image,
2193 VkImageLayout imageLayout,
Chris Forbese3105972015-06-24 14:34:53 +12002194 const VkClearColorValue *pColor,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002195 uint32_t rangeCount,
2196 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002197{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002198 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002199 VkDeviceMemory mem;
2200 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002201 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002202 skipCall = get_mem_binding_from_object(cmdBuffer, image.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2203 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdClearColorImage");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002204 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002205 if (VK_FALSE == skipCall) {
2206 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
2207 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002208}
2209
Chris Forbes2951d7d2015-06-22 17:21:59 +12002210VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
Courtney Goeltzenleuchter315ad992015-09-15 18:03:22 -06002211 VkCmdBuffer cmdBuffer,
2212 VkImage image,
2213 VkImageLayout imageLayout,
2214 const VkClearDepthStencilValue* pDepthStencil,
2215 uint32_t rangeCount,
2216 const VkImageSubresourceRange* pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002217{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002218 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002219 VkDeviceMemory mem;
2220 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002221 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002222 skipCall = get_mem_binding_from_object(cmdBuffer, image.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2223 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdClearDepthStencilImage");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002224 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002225 if (VK_FALSE == skipCall) {
2226 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(
Courtney Goeltzenleuchter315ad992015-09-15 18:03:22 -06002227 cmdBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002228 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002229}
2230
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002231VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(
2232 VkCmdBuffer cmdBuffer,
2233 VkImage srcImage,
2234 VkImageLayout srcImageLayout,
2235 VkImage destImage,
2236 VkImageLayout destImageLayout,
2237 uint32_t regionCount,
2238 const VkImageResolve *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002239{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002240 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002241 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002242 VkDeviceMemory mem;
2243 skipCall = get_mem_binding_from_object(cmdBuffer, srcImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2244 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdResolveImage");
2245 skipCall |= get_mem_binding_from_object(cmdBuffer, destImage.handle, VK_OBJECT_TYPE_IMAGE, &mem);
2246 skipCall |= update_cmd_buf_and_mem_references(cmdBuffer, mem, "vkCmdResolveImage");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002247 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002248 if (VK_FALSE == skipCall) {
2249 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdResolveImage(
2250 cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
2251 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002252}
2253
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002254VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(
2255 VkCmdBuffer cmdBuffer,
2256 VkQueryPool queryPool,
2257 uint32_t slot,
2258 VkFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002259{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002260 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002261}
2262
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002263VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(
2264 VkCmdBuffer cmdBuffer,
2265 VkQueryPool queryPool,
2266 uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002267{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002268 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdEndQuery(cmdBuffer, queryPool, slot);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002269}
2270
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002271VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(
2272 VkCmdBuffer cmdBuffer,
2273 VkQueryPool queryPool,
2274 uint32_t startQuery,
2275 uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002276{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002277 get_dispatch_table(mem_tracker_device_table_map, cmdBuffer)->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002278}
2279
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002280VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
2281 VkInstance instance,
2282 VkFlags msgFlags,
2283 const PFN_vkDbgMsgCallback pfnMsgCallback,
2284 void* pUserData,
2285 VkDbgMsgCallback* pMsgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002286{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002287 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(mem_tracker_instance_table_map, instance);
2288 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
2289 if (res == VK_SUCCESS) {
2290 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2291
2292 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
2293 }
2294 return res;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002295}
2296
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002297VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
2298 VkInstance instance,
2299 VkDbgMsgCallback msgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002300{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002301 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(mem_tracker_instance_table_map, instance);
2302 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
2303
2304 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2305 layer_destroy_msg_callback(my_data->report_data, msgCallback);
2306
2307 return res;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002308}
2309
Ian Elliott338dedb2015-08-21 15:09:33 -06002310VK_LAYER_EXPORT VkResult VKAPI vkCreateSwapchainKHR(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002311 VkDevice device,
Ian Elliott338dedb2015-08-21 15:09:33 -06002312 const VkSwapchainCreateInfoKHR *pCreateInfo,
2313 VkSwapchainKHR *pSwapchain)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002314{
Ian Elliott338dedb2015-08-21 15:09:33 -06002315 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->CreateSwapchainKHR(device, pCreateInfo, pSwapchain);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002316
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002317 if (VK_SUCCESS == result) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002318 loader_platform_thread_lock_mutex(&globalLock);
Ian Elliott338dedb2015-08-21 15:09:33 -06002319 add_swap_chain_info(*pSwapchain, pCreateInfo);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002320 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -07002321 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002322
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002323 return result;
2324}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002325
Ian Elliott338dedb2015-08-21 15:09:33 -06002326VK_LAYER_EXPORT VkResult VKAPI vkDestroySwapchainKHR(
Ian Elliottb134e842015-07-06 14:31:32 -06002327 VkDevice device,
Ian Elliott338dedb2015-08-21 15:09:33 -06002328 VkSwapchainKHR swapchain)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002329{
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002330 VkBool32 skipCall = VK_FALSE;
2331 VkResult result = VK_ERROR_VALIDATION_FAILED;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002332 loader_platform_thread_lock_mutex(&globalLock);
Ian Elliott338dedb2015-08-21 15:09:33 -06002333 if (swapchainMap.find(swapchain.handle) != swapchainMap.end()) {
2334 MT_SWAP_CHAIN_INFO* pInfo = swapchainMap[swapchain.handle];
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002335
David Pinedof5997ab2015-04-27 16:36:17 -06002336 if (pInfo->images.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002337 for (auto it = pInfo->images.begin(); it != pInfo->images.end(); it++) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002338 skipCall = clear_object_binding(device, it->handle, VK_OBJECT_TYPE_SWAPCHAIN_KHR);
Ian Elliottccac0232015-08-07 14:11:14 -06002339 auto image_item = imageMap.find(it->handle);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002340 if (image_item != imageMap.end())
2341 imageMap.erase(image_item);
David Pinedof5997ab2015-04-27 16:36:17 -06002342 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002343 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002344 delete pInfo;
Ian Elliott338dedb2015-08-21 15:09:33 -06002345 swapchainMap.erase(swapchain.handle);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002346 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002347 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002348 if (VK_FALSE == skipCall) {
2349 result = get_dispatch_table(mem_tracker_device_table_map, device)->DestroySwapchainKHR(device, swapchain);
2350 }
2351 return result;
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002352}
2353
Ian Elliott338dedb2015-08-21 15:09:33 -06002354VK_LAYER_EXPORT VkResult VKAPI vkGetSwapchainImagesKHR(
Ian Elliottb134e842015-07-06 14:31:32 -06002355 VkDevice device,
Ian Elliott338dedb2015-08-21 15:09:33 -06002356 VkSwapchainKHR swapchain,
Ian Elliottccac0232015-08-07 14:11:14 -06002357 uint32_t* pCount,
Ian Elliott338dedb2015-08-21 15:09:33 -06002358 VkImage* pSwapchainImages)
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002359{
Ian Elliott338dedb2015-08-21 15:09:33 -06002360 VkResult result = get_dispatch_table(mem_tracker_device_table_map, device)->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002361
Ian Elliott338dedb2015-08-21 15:09:33 -06002362 if (result == VK_SUCCESS && pSwapchainImages != NULL) {
Ian Elliottccac0232015-08-07 14:11:14 -06002363 const size_t count = *pCount;
Ian Elliott338dedb2015-08-21 15:09:33 -06002364 MT_SWAP_CHAIN_INFO *pInfo = swapchainMap[swapchain.handle];
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002365
2366 if (pInfo->images.empty()) {
2367 pInfo->images.resize(count);
Ian Elliott338dedb2015-08-21 15:09:33 -06002368 memcpy(&pInfo->images[0], pSwapchainImages, sizeof(pInfo->images[0]) * count);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002369
David Pinedof5997ab2015-04-27 16:36:17 -06002370 if (pInfo->images.size() > 0) {
Ian Elliottccac0232015-08-07 14:11:14 -06002371 for (std::vector<VkImage>::const_iterator it = pInfo->images.begin();
David Pinedof5997ab2015-04-27 16:36:17 -06002372 it != pInfo->images.end(); it++) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002373 // Add image object binding, then insert the new Mem Object and then bind it to created image
Ian Elliott338dedb2015-08-21 15:09:33 -06002374 add_object_create_info(it->handle, VK_OBJECT_TYPE_SWAPCHAIN_KHR, &pInfo->createInfo);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002375 }
2376 }
2377 } else {
Ian Elliottccac0232015-08-07 14:11:14 -06002378 const size_t count = *pCount;
Ian Elliott338dedb2015-08-21 15:09:33 -06002379 MT_SWAP_CHAIN_INFO *pInfo = swapchainMap[swapchain.handle];
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002380 const bool mismatch = (pInfo->images.size() != count ||
Ian Elliott338dedb2015-08-21 15:09:33 -06002381 memcmp(&pInfo->images[0], pSwapchainImages, sizeof(pInfo->images[0]) * count));
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002382
2383 if (mismatch) {
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06002384 log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_SWAPCHAIN_KHR, swapchain.handle, 0, MEMTRACK_NONE, "SWAP_CHAIN",
Ian Elliott338dedb2015-08-21 15:09:33 -06002385 "vkGetSwapchainInfoKHR(%p, VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_KHR) returned mismatching data", swapchain);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002386 }
2387 }
2388 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002389 return result;
2390}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002391
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002392VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(
Jon Ashburn1245cec2015-05-18 13:20:15 -06002393 VkDevice dev,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002394 const char *funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002395{
Jon Ashburn1245cec2015-05-18 13:20:15 -06002396 if (dev == NULL) {
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002397 return NULL;
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002398 }
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05002399
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002400 /* loader uses this to force layer initialization; device object is wrapped */
2401 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002402 initDeviceTable(mem_tracker_device_table_map, (const VkBaseLayerObject *) dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002403 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002404 }
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06002405 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002406 return (PFN_vkVoidFunction) vkCreateDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002407 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002408 return (PFN_vkVoidFunction) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002409 if (!strcmp(funcName, "vkQueueSubmit"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002410 return (PFN_vkVoidFunction) vkQueueSubmit;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002411 if (!strcmp(funcName, "vkAllocMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002412 return (PFN_vkVoidFunction) vkAllocMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002413 if (!strcmp(funcName, "vkFreeMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002414 return (PFN_vkVoidFunction) vkFreeMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002415 if (!strcmp(funcName, "vkMapMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002416 return (PFN_vkVoidFunction) vkMapMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002417 if (!strcmp(funcName, "vkUnmapMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002418 return (PFN_vkVoidFunction) vkUnmapMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002419 if (!strcmp(funcName, "vkDestroyFence"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002420 return (PFN_vkVoidFunction) vkDestroyFence;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002421 if (!strcmp(funcName, "vkDestroyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002422 return (PFN_vkVoidFunction) vkDestroyBuffer;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002423 if (!strcmp(funcName, "vkDestroyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002424 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002425 if (!strcmp(funcName, "vkBindBufferMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002426 return (PFN_vkVoidFunction) vkBindBufferMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002427 if (!strcmp(funcName, "vkBindImageMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002428 return (PFN_vkVoidFunction) vkBindImageMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002429 if (!strcmp(funcName, "vkGetBufferMemoryRequirements"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002430 return (PFN_vkVoidFunction) vkGetBufferMemoryRequirements;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002431 if (!strcmp(funcName, "vkGetImageMemoryRequirements"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002432 return (PFN_vkVoidFunction) vkGetImageMemoryRequirements;
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -05002433 if (!strcmp(funcName, "vkQueueBindSparseBufferMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002434 return (PFN_vkVoidFunction) vkQueueBindSparseBufferMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002435 if (!strcmp(funcName, "vkQueueBindSparseImageOpaqueMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002436 return (PFN_vkVoidFunction) vkQueueBindSparseImageOpaqueMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002437 if (!strcmp(funcName, "vkQueueBindSparseImageMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002438 return (PFN_vkVoidFunction) vkQueueBindSparseImageMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002439 if (!strcmp(funcName, "vkCreateFence"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002440 return (PFN_vkVoidFunction) vkCreateFence;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002441 if (!strcmp(funcName, "vkGetFenceStatus"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002442 return (PFN_vkVoidFunction) vkGetFenceStatus;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002443 if (!strcmp(funcName, "vkResetFences"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002444 return (PFN_vkVoidFunction) vkResetFences;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002445 if (!strcmp(funcName, "vkWaitForFences"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002446 return (PFN_vkVoidFunction) vkWaitForFences;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002447 if (!strcmp(funcName, "vkQueueWaitIdle"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002448 return (PFN_vkVoidFunction) vkQueueWaitIdle;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002449 if (!strcmp(funcName, "vkDeviceWaitIdle"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002450 return (PFN_vkVoidFunction) vkDeviceWaitIdle;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002451 if (!strcmp(funcName, "vkCreateEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002452 return (PFN_vkVoidFunction) vkCreateEvent;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002453 if (!strcmp(funcName, "vkCreateQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002454 return (PFN_vkVoidFunction) vkCreateQueryPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002455 if (!strcmp(funcName, "vkCreateBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002456 return (PFN_vkVoidFunction) vkCreateBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002457 if (!strcmp(funcName, "vkCreateBufferView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002458 return (PFN_vkVoidFunction) vkCreateBufferView;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002459 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002460 return (PFN_vkVoidFunction) vkCreateImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002461 if (!strcmp(funcName, "vkCreateImageView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002462 return (PFN_vkVoidFunction) vkCreateImageView;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002463 if (!strcmp(funcName, "vkCreateShader"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002464 return (PFN_vkVoidFunction) vkCreateShader;
Jon Ashburn0d60d272015-07-09 15:02:25 -06002465 if (!strcmp(funcName, "vkCreateGraphicsPipelines"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002466 return (PFN_vkVoidFunction) vkCreateGraphicsPipelines;
Jon Ashburn0d60d272015-07-09 15:02:25 -06002467 if (!strcmp(funcName, "vkCreateComputePipelines"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002468 return (PFN_vkVoidFunction) vkCreateComputePipelines;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002469 if (!strcmp(funcName, "vkCreateSampler"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002470 return (PFN_vkVoidFunction) vkCreateSampler;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002471 if (!strcmp(funcName, "vkCreateCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002472 return (PFN_vkVoidFunction) vkCreateCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002473 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002474 return (PFN_vkVoidFunction) vkBeginCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002475 if (!strcmp(funcName, "vkEndCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002476 return (PFN_vkVoidFunction) vkEndCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002477 if (!strcmp(funcName, "vkResetCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002478 return (PFN_vkVoidFunction) vkResetCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002479 if (!strcmp(funcName, "vkCmdBindPipeline"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002480 return (PFN_vkVoidFunction) vkCmdBindPipeline;
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002481 if (!strcmp(funcName, "vkCmdSetViewport"))
2482 return (PFN_vkVoidFunction) vkCmdSetViewport;
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002483 if (!strcmp(funcName, "vkCmdSetScissor"))
2484 return (PFN_vkVoidFunction) vkCmdSetScissor;
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002485 if (!strcmp(funcName, "vkCmdSetLineWidth"))
2486 return (PFN_vkVoidFunction) vkCmdSetLineWidth;
2487 if (!strcmp(funcName, "vkCmdSetDepthBias"))
2488 return (PFN_vkVoidFunction) vkCmdSetDepthBias;
2489 if (!strcmp(funcName, "vkCmdSetBlendConstants"))
2490 return (PFN_vkVoidFunction) vkCmdSetBlendConstants;
2491 if (!strcmp(funcName, "vkCmdSetDepthBounds"))
2492 return (PFN_vkVoidFunction) vkCmdSetDepthBounds;
2493 if (!strcmp(funcName, "vkCmdSetStencilCompareMask"))
2494 return (PFN_vkVoidFunction) vkCmdSetStencilCompareMask;
2495 if (!strcmp(funcName, "vkCmdSetStencilWriteMask"))
2496 return (PFN_vkVoidFunction) vkCmdSetStencilWriteMask;
2497 if (!strcmp(funcName, "vkCmdSetStencilReference"))
2498 return (PFN_vkVoidFunction) vkCmdSetStencilReference;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002499 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002500 return (PFN_vkVoidFunction) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002501 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002502 return (PFN_vkVoidFunction) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002503 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002504 return (PFN_vkVoidFunction) vkCmdBindIndexBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002505 if (!strcmp(funcName, "vkCmdDrawIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002506 return (PFN_vkVoidFunction) vkCmdDrawIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002507 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002508 return (PFN_vkVoidFunction) vkCmdDrawIndexedIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002509 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002510 return (PFN_vkVoidFunction) vkCmdDispatchIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002511 if (!strcmp(funcName, "vkCmdCopyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002512 return (PFN_vkVoidFunction) vkCmdCopyBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002513 if (!strcmp(funcName, "vkCmdCopyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002514 return (PFN_vkVoidFunction) vkCmdCopyImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002515 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002516 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002517 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002518 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002519 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002520 return (PFN_vkVoidFunction) vkCmdUpdateBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002521 if (!strcmp(funcName, "vkCmdFillBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002522 return (PFN_vkVoidFunction) vkCmdFillBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002523 if (!strcmp(funcName, "vkCmdClearColorImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002524 return (PFN_vkVoidFunction) vkCmdClearColorImage;
Chris Forbes2951d7d2015-06-22 17:21:59 +12002525 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002526 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002527 if (!strcmp(funcName, "vkCmdResolveImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002528 return (PFN_vkVoidFunction) vkCmdResolveImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002529 if (!strcmp(funcName, "vkCmdBeginQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002530 return (PFN_vkVoidFunction) vkCmdBeginQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002531 if (!strcmp(funcName, "vkCmdEndQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002532 return (PFN_vkVoidFunction) vkCmdEndQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002533 if (!strcmp(funcName, "vkCmdResetQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002534 return (PFN_vkVoidFunction) vkCmdResetQueryPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002535 if (!strcmp(funcName, "vkGetDeviceQueue"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002536 return (PFN_vkVoidFunction) vkGetDeviceQueue;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06002537
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -06002538 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
Ian Elliottb134e842015-07-06 14:31:32 -06002539 if (my_device_data->wsi_enabled)
Jon Ashburn7e07faf2015-06-18 15:02:58 -06002540 {
Ian Elliott338dedb2015-08-21 15:09:33 -06002541 if (!strcmp(funcName, "vkCreateSwapchainKHR"))
2542 return (PFN_vkVoidFunction) vkCreateSwapchainKHR;
2543 if (!strcmp(funcName, "vkDestroySwapchainKHR"))
2544 return (PFN_vkVoidFunction) vkDestroySwapchainKHR;
2545 if (!strcmp(funcName, "vkGetSwapchainImagesKHR"))
2546 return (PFN_vkVoidFunction) vkGetSwapchainImagesKHR;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06002547 }
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06002548
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -06002549 VkLayerDispatchTable *pDisp = get_dispatch_table(mem_tracker_device_table_map, dev);
2550 if (pDisp->GetDeviceProcAddr == NULL)
2551 return NULL;
2552 return pDisp->GetDeviceProcAddr(dev, funcName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06002553}
2554
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002555VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(
Jon Ashburn79b78ac2015-05-05 14:22:52 -06002556 VkInstance instance,
2557 const char *funcName)
2558{
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002559 PFN_vkVoidFunction fptr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -06002560 if (instance == NULL) {
2561 return NULL;
2562 }
Jon Ashburnd9564002015-05-07 10:27:37 -06002563
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002564 /* loader uses this to force layer initialization; instance object is wrapped */
2565 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002566 initInstanceTable(mem_tracker_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002567 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002568 }
2569
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05002570 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002571 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06002572 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002573 return (PFN_vkVoidFunction) vkCreateInstance;
Mark Lobodzinski72346292015-07-02 16:49:40 -06002574 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06002575 return (PFN_vkVoidFunction) vkGetPhysicalDeviceMemoryProperties;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06002576 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
2577 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
2578 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
2579 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
2580 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
2581 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
2582 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
2583 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06002584
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002585 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2586 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06002587 if (fptr)
2588 return fptr;
2589
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002590 {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002591 if (get_dispatch_table(mem_tracker_instance_table_map, instance)->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06002592 return NULL;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002593 return get_dispatch_table(mem_tracker_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002594 }
2595}