blob: c840d5d3e66304b9baf2838cf129c0c26852b2d6 [file] [log] [blame]
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
Tobin Ehlis6663f492014-11-10 12:29:12 -07005 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -07006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials
11 * are furnished to do so, subject to the following conditions:
Tobin Ehlis6663f492014-11-10 12:29:12 -070012 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070013 * The above copyright notice(s) and this permission notice shall be included
14 * in all copies or substantial portions of the Materials.
Tobin Ehlis6663f492014-11-10 12:29:12 -070015 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070016 * The Materials are Confidential Information as defined by the Khronos
17 * Membership Agreement until designated non-confidential by Khronos, at which
18 * point this condition clause shall be removed.
Tobin Ehlis6663f492014-11-10 12:29:12 -070019 *
Mark Lobodzinski6eda00a2016-02-02 15:55:36 -070020 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 *
24 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
27 * USE OR OTHER DEALINGS IN THE MATERIALS
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060028 *
29 * Author: Cody Northrop <cody@lunarg.com>
30 * Author: Jon Ashburn <jon@lunarg.com>
31 * Author: Mark Lobodzinski <mark@lunarg.com>
32 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlis6663f492014-11-10 12:29:12 -070033 */
34
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -050035#include <inttypes.h>
Tobin Ehlis6663f492014-11-10 12:29:12 -070036#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <assert.h>
Michael Lentine1e171aa2016-01-06 19:17:59 -060040#include <functional>
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050041#include <list>
Mark Lobodzinski76c991d2015-05-20 16:16:37 -050042#include <map>
Chia-I Wuf8693382015-04-16 22:02:10 +080043#include <vector>
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -050044using namespace std;
45
Tobin Ehlisb835d1b2015-07-03 10:34:49 -060046#include "vk_loader_platform.h"
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060047#include "vk_dispatch_table_helper.h"
48#include "vk_struct_string_helper_cpp.h"
Tobin Ehliscd9223b2014-11-19 16:19:28 -070049#include "mem_tracker.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060050#include "vk_layer_config.h"
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060051#include "vk_layer_extension_utils.h"
Tobin Ehlisa0cb02e2015-07-03 10:15:26 -060052#include "vk_layer_table.h"
53#include "vk_layer_data.h"
54#include "vk_layer_logging.h"
Courtney Goeltzenleuchterd54749c2015-07-05 11:17:01 -060055static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski76c991d2015-05-20 16:16:37 -050056
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070057// WSI Image Objects bypass usual Image Object creation methods. A special
58// Memory
Mark Lobodzinski348803a2015-09-11 15:56:51 -060059// Object value will be used to identify them internally.
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070060static const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY =
61 (VkDeviceMemory)(-1);
Mark Lobodzinski348803a2015-09-11 15:56:51 -060062
Cody Northrop55443ef2015-09-28 15:09:32 -060063struct layer_data {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070064 debug_report_data *report_data;
65 std::vector<VkDebugReportCallbackEXT> logging_callback;
66 VkLayerDispatchTable *device_dispatch_table;
67 VkLayerInstanceDispatchTable *instance_dispatch_table;
68 VkBool32 wsi_enabled;
69 uint64_t currentFenceId;
70 VkPhysicalDeviceProperties properties;
71 unordered_map<VkDeviceMemory, vector<MEMORY_RANGE>> bufferRanges,
72 imageRanges;
Tobin Ehlis57b55082015-10-29 09:03:52 -060073 // Maps for tracking key structs related to MemTracker state
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070074 unordered_map<VkCommandBuffer, MT_CB_INFO> cbMap;
75 unordered_map<VkCommandPool, MT_CMD_POOL_INFO> commandPoolMap;
76 unordered_map<VkDeviceMemory, MT_MEM_OBJ_INFO> memObjMap;
77 unordered_map<VkFence, MT_FENCE_INFO> fenceMap;
78 unordered_map<VkQueue, MT_QUEUE_INFO> queueMap;
79 unordered_map<VkSwapchainKHR, MT_SWAP_CHAIN_INFO *> swapchainMap;
80 unordered_map<VkSemaphore, MtSemaphoreState> semaphoreMap;
81 unordered_map<VkFramebuffer, MT_FB_INFO> fbMap;
82 unordered_map<VkRenderPass, MT_PASS_INFO> passMap;
83 unordered_map<VkImageView, MT_IMAGE_VIEW_INFO> imageViewMap;
84 // Images and Buffers are 2 objects that can have memory bound to them so
85 // they get special treatment
86 unordered_map<uint64_t, MT_OBJ_BINDING_INFO> imageMap;
87 unordered_map<uint64_t, MT_OBJ_BINDING_INFO> bufferMap;
Cody Northrop55443ef2015-09-28 15:09:32 -060088
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070089 layer_data()
90 : report_data(nullptr), device_dispatch_table(nullptr),
91 instance_dispatch_table(nullptr), wsi_enabled(VK_FALSE),
92 currentFenceId(1){};
Cody Northrop55443ef2015-09-28 15:09:32 -060093};
Mark Lobodzinski76c991d2015-05-20 16:16:37 -050094
Tobin Ehlis257d9742015-07-08 17:08:02 -060095static unordered_map<void *, layer_data *> layer_data_map;
96
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -060097static VkPhysicalDeviceMemoryProperties memProps;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -060098
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -070099static VkBool32 clear_cmd_buf_and_mem_references(layer_data *my_data,
100 const VkCommandBuffer cb);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -0700101
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700102// TODO : This can be much smarter, using separate locks for separate global
103// data
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600104static int globalLockInitialized = 0;
105static loader_platform_thread_mutex globalLock;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -0700106
Tobin Ehlisc145be82015-01-08 15:22:32 -0700107#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlisc145be82015-01-08 15:22:32 -0700108
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700109static MT_OBJ_BINDING_INFO *
110get_object_binding_info(layer_data *my_data, uint64_t handle,
111 VkDebugReportObjectTypeEXT type) {
112 MT_OBJ_BINDING_INFO *retValue = NULL;
113 switch (type) {
114 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
115 auto it = my_data->imageMap.find(handle);
116 if (it != my_data->imageMap.end())
117 return &(*it).second;
118 break;
119 }
120 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
121 auto it = my_data->bufferMap.find(handle);
122 if (it != my_data->bufferMap.end())
123 return &(*it).second;
124 break;
125 }
Tobin Ehlis257d9742015-07-08 17:08:02 -0600126 }
127 return retValue;
128}
Mark Lobodzinskic52b7752015-02-18 16:38:17 -0600129
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700130template layer_data *
131get_my_data_ptr<layer_data>(void *data_key,
132 std::unordered_map<void *, layer_data *> &data_map);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -0600133
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500134// Add new queue for this device to map container
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700135static void add_queue_info(layer_data *my_data, const VkQueue queue) {
136 MT_QUEUE_INFO *pInfo = &my_data->queueMap[queue];
137 pInfo->lastRetiredId = 0;
Mark Lobodzinski50932972015-04-02 20:49:09 -0500138 pInfo->lastSubmittedId = 0;
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500139}
140
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700141static void delete_queue_info_list(layer_data *my_data) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500142 // Process queue list, cleaning up each entry before deleting
Tobin Ehlis57b55082015-10-29 09:03:52 -0600143 my_data->queueMap.clear();
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500144}
145
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700146static void add_swap_chain_info(layer_data *my_data,
147 const VkSwapchainKHR swapchain,
148 const VkSwapchainCreateInfoKHR *pCI) {
149 MT_SWAP_CHAIN_INFO *pInfo = new MT_SWAP_CHAIN_INFO;
Ian Elliott7e40db92015-08-21 15:09:33 -0600150 memcpy(&pInfo->createInfo, pCI, sizeof(VkSwapchainCreateInfoKHR));
Tobin Ehlis57b55082015-10-29 09:03:52 -0600151 my_data->swapchainMap[swapchain] = pInfo;
Chia-I Wuf8693382015-04-16 22:02:10 +0800152}
153
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500154// Add new CBInfo for this cb to map container
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700155static void add_cmd_buf_info(layer_data *my_data, VkCommandPool commandPool,
156 const VkCommandBuffer cb) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800157 my_data->cbMap[cb].commandBuffer = cb;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -0700158 my_data->commandPoolMap[commandPool].pCommandBuffers.push_front(cb);
159}
160
161// Delete CBInfo from container and clear mem references to CB
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700162static VkBool32 delete_cmd_buf_info(layer_data *my_data,
163 VkCommandPool commandPool,
164 const VkCommandBuffer cb) {
Mark Lobodzinskif4945f82015-11-13 13:47:01 -0700165 VkBool32 result = VK_TRUE;
166 result = clear_cmd_buf_and_mem_references(my_data, cb);
167 // Delete the CBInfo info
Mark Lobodzinski21eea362016-01-19 16:08:36 -0700168 if (result != VK_TRUE) {
Mark Lobodzinskif4945f82015-11-13 13:47:01 -0700169 my_data->commandPoolMap[commandPool].pCommandBuffers.remove(cb);
170 my_data->cbMap.erase(cb);
171 }
172 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700173}
174
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500175// Return ptr to Info in CB map, or NULL if not found
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700176static MT_CB_INFO *get_cmd_buf_info(layer_data *my_data,
177 const VkCommandBuffer cb) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600178 auto item = my_data->cbMap.find(cb);
179 if (item != my_data->cbMap.end()) {
Mike Stroyandd7aed72015-05-19 17:03:40 -0600180 return &(*item).second;
Mike Stroyan950496e2015-05-19 15:16:08 -0600181 } else {
182 return NULL;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600183 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700184}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600185
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700186static void add_object_binding_info(layer_data *my_data, const uint64_t handle,
187 const VkDebugReportObjectTypeEXT type,
188 const VkDeviceMemory mem) {
189 switch (type) {
190 // Buffers and images are unique as their CreateInfo is in container struct
191 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
192 auto pCI = &my_data->bufferMap[handle];
193 pCI->mem = mem;
194 break;
195 }
196 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
197 auto pCI = &my_data->imageMap[handle];
198 pCI->mem = mem;
199 break;
200 }
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500201 }
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500202}
203
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700204static void add_object_create_info(layer_data *my_data, const uint64_t handle,
205 const VkDebugReportObjectTypeEXT type,
206 const void *pCreateInfo) {
207 // TODO : For any CreateInfo struct that has ptrs, need to deep copy them
208 // and appropriately clean up on Destroy
209 switch (type) {
210 // Buffers and images are unique as their CreateInfo is in container struct
211 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
212 auto pCI = &my_data->bufferMap[handle];
213 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
214 memcpy(&pCI->create_info.buffer, pCreateInfo,
215 sizeof(VkBufferCreateInfo));
216 break;
217 }
218 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
219 auto pCI = &my_data->imageMap[handle];
220 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
221 memcpy(&pCI->create_info.image, pCreateInfo, sizeof(VkImageCreateInfo));
222 break;
223 }
224 // Swap Chain is very unique, use my_data->imageMap, but copy in
225 // SwapChainCreatInfo's usage flags and set the mem value to a unique key.
226 // These is used by
227 // vkCreateImageView and internal MemTracker routines to distinguish swap
228 // chain images
229 case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: {
230 auto pCI = &my_data->imageMap[handle];
231 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
232 pCI->mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
233 pCI->valid = false;
234 pCI->create_info.image.usage =
235 const_cast<VkSwapchainCreateInfoKHR *>(
236 static_cast<const VkSwapchainCreateInfoKHR *>(pCreateInfo))
237 ->imageUsage;
238 break;
239 }
Tobin Ehlis257d9742015-07-08 17:08:02 -0600240 }
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500241}
242
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500243// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700244static VkBool32 add_fence_info(layer_data *my_data, VkFence fence,
245 VkQueue queue, uint64_t *fenceId) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600246 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis57b55082015-10-29 09:03:52 -0600247 *fenceId = my_data->currentFenceId++;
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600248
Mark Lobodzinski76c991d2015-05-20 16:16:37 -0500249 // If no fence, create an internal fence to track the submissions
Chia-I Wue2fc5522015-10-26 20:04:44 +0800250 if (fence != VK_NULL_HANDLE) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600251 my_data->fenceMap[fence].fenceId = *fenceId;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700252 my_data->fenceMap[fence].queue = queue;
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -0500253 // Validate that fence is in UNSIGNALED state
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700254 VkFenceCreateInfo *pFenceCI = &(my_data->fenceMap[fence].createInfo);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600255 if (pFenceCI->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700256 skipCall = log_msg(
257 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
258 VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t)fence,
259 __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
260 "Fence %#" PRIxLEAST64 " submitted in SIGNALED state. Fences "
261 "must be reset before being submitted",
262 (uint64_t)fence);
Mark Lobodzinskiabc1bc42015-04-09 13:46:09 -0500263 }
Tobin Ehlis257d9742015-07-08 17:08:02 -0600264 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700265 // TODO : Do we need to create an internal fence here for tracking
266 // purposes?
Tobin Ehlis6663f492014-11-10 12:29:12 -0700267 }
Mike Stroyan950496e2015-05-19 15:16:08 -0600268 // Update most recently submitted fence and fenceId for Queue
Tobin Ehlis57b55082015-10-29 09:03:52 -0600269 my_data->queueMap[queue].lastSubmittedId = *fenceId;
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600270 return skipCall;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500271}
272
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500273// Remove a fenceInfo from our list of fences/fenceIds
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700274static void delete_fence_info(layer_data *my_data, VkFence fence) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600275 my_data->fenceMap.erase(fence);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500276}
277
Mike Stroyan950496e2015-05-19 15:16:08 -0600278// Record information when a fence is known to be signalled
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700279static void update_fence_tracking(layer_data *my_data, VkFence fence) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600280 auto fence_item = my_data->fenceMap.find(fence);
281 if (fence_item != my_data->fenceMap.end()) {
Mike Stroyandd7aed72015-05-19 17:03:40 -0600282 MT_FENCE_INFO *pCurFenceInfo = &(*fence_item).second;
Mike Stroyan950496e2015-05-19 15:16:08 -0600283 VkQueue queue = pCurFenceInfo->queue;
Tobin Ehlis57b55082015-10-29 09:03:52 -0600284 auto queue_item = my_data->queueMap.find(queue);
285 if (queue_item != my_data->queueMap.end()) {
Mike Stroyandd7aed72015-05-19 17:03:40 -0600286 MT_QUEUE_INFO *pQueueInfo = &(*queue_item).second;
Mike Stroyan950496e2015-05-19 15:16:08 -0600287 if (pQueueInfo->lastRetiredId < pCurFenceInfo->fenceId) {
288 pQueueInfo->lastRetiredId = pCurFenceInfo->fenceId;
Mark Lobodzinski148e1582015-04-07 16:07:57 -0500289 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500290 }
291 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500292
Mike Stroyan950496e2015-05-19 15:16:08 -0600293 // Update fence state in fenceCreateInfo structure
Tobin Ehlis57b55082015-10-29 09:03:52 -0600294 auto pFCI = &(my_data->fenceMap[fence].createInfo);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700295 pFCI->flags = static_cast<VkFenceCreateFlags>(pFCI->flags |
296 VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500297}
298
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700299// Helper routine that updates the fence list for a specific queue to
300// all-retired
301static void retire_queue_fences(layer_data *my_data, VkQueue queue) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600302 MT_QUEUE_INFO *pQueueInfo = &my_data->queueMap[queue];
Mike Stroyandd7aed72015-05-19 17:03:40 -0600303 // Set queue's lastRetired to lastSubmitted indicating all fences completed
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600304 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700305}
306
Mike Stroyandd7aed72015-05-19 17:03:40 -0600307// Helper routine that updates all queues to all-retired
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700308static void retire_device_fences(layer_data *my_data, VkDevice device) {
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500309 // Process each queue for device
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600310 // TODO: Add multiple device support
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700311 for (auto ii = my_data->queueMap.begin(); ii != my_data->queueMap.end();
312 ++ii) {
313 // Set queue's lastRetired to lastSubmitted indicating all fences
314 // completed
Mike Stroyandd7aed72015-05-19 17:03:40 -0600315 MT_QUEUE_INFO *pQueueInfo = &(*ii).second;
316 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500317 }
318}
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600319
Tobin Ehlis41376e12015-07-03 08:45:14 -0600320// Helper function to validate correct usage bits set for buffers or images
321// Verify that (actual & desired) flags != 0 or,
322// if strict is true, verify that (actual & desired) flags == desired
323// In case of error, report it via dbg callbacks
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700324static VkBool32 validate_usage_flags(layer_data *my_data, void *disp_obj,
325 VkFlags actual, VkFlags desired,
326 VkBool32 strict, uint64_t obj_handle,
327 VkDebugReportObjectTypeEXT obj_type,
328 char const *ty_str, char const *func_name,
329 char const *usage_str) {
Courtney Goeltzenleuchtercd2a0992015-07-09 11:44:38 -0600330 VkBool32 correct_usage = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700331 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis41376e12015-07-03 08:45:14 -0600332 if (strict)
333 correct_usage = ((actual & desired) == desired);
334 else
335 correct_usage = ((actual & desired) != 0);
336 if (!correct_usage) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700337 skipCall = log_msg(
338 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj_type,
339 obj_handle, __LINE__, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
340 "Invalid usage flag for %s %#" PRIxLEAST64
341 " used by %s. In this case, %s should have %s set during creation.",
342 ty_str, obj_handle, func_name, ty_str, usage_str);
Tobin Ehlis41376e12015-07-03 08:45:14 -0600343 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600344 return skipCall;
Tobin Ehlis41376e12015-07-03 08:45:14 -0600345}
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600346
Tobin Ehlis41376e12015-07-03 08:45:14 -0600347// Helper function to validate usage flags for images
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700348// Pulls image info and then sends actual vs. desired usage off to helper above
349// where
Tobin Ehlis41376e12015-07-03 08:45:14 -0600350// an error will be flagged if usage is not correct
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700351static VkBool32 validate_image_usage_flags(layer_data *my_data, void *disp_obj,
352 VkImage image, VkFlags desired,
353 VkBool32 strict,
354 char const *func_name,
355 char const *usage_string) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600356 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700357 MT_OBJ_BINDING_INFO *pBindInfo = get_object_binding_info(
358 my_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600359 if (pBindInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700360 skipCall = validate_usage_flags(
361 my_data, disp_obj, pBindInfo->create_info.image.usage, desired,
362 strict, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
363 "image", func_name, usage_string);
Tobin Ehlis41376e12015-07-03 08:45:14 -0600364 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600365 return skipCall;
Tobin Ehlis41376e12015-07-03 08:45:14 -0600366}
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600367
Tobin Ehlis41376e12015-07-03 08:45:14 -0600368// Helper function to validate usage flags for buffers
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700369// Pulls buffer info and then sends actual vs. desired usage off to helper above
370// where
Tobin Ehlis41376e12015-07-03 08:45:14 -0600371// an error will be flagged if usage is not correct
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700372static VkBool32 validate_buffer_usage_flags(layer_data *my_data, void *disp_obj,
373 VkBuffer buffer, VkFlags desired,
374 VkBool32 strict,
375 char const *func_name,
376 char const *usage_string) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600377 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700378 MT_OBJ_BINDING_INFO *pBindInfo = get_object_binding_info(
379 my_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600380 if (pBindInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700381 skipCall = validate_usage_flags(
382 my_data, disp_obj, pBindInfo->create_info.buffer.usage, desired,
383 strict, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
384 "buffer", func_name, usage_string);
Tobin Ehlis41376e12015-07-03 08:45:14 -0600385 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600386 return skipCall;
Tobin Ehlis41376e12015-07-03 08:45:14 -0600387}
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600388
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500389// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -0700390// Calls to this function should be wrapped in mutex
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700391static MT_MEM_OBJ_INFO *get_mem_obj_info(layer_data *my_data,
392 const VkDeviceMemory mem) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600393 auto item = my_data->memObjMap.find(mem);
394 if (item != my_data->memObjMap.end()) {
Mike Stroyandd7aed72015-05-19 17:03:40 -0600395 return &(*item).second;
Mike Stroyan950496e2015-05-19 15:16:08 -0600396 } else {
397 return NULL;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600398 }
Tobin Ehlisc145be82015-01-08 15:22:32 -0700399}
400
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700401static void add_mem_obj_info(layer_data *my_data, void *object,
402 const VkDeviceMemory mem,
403 const VkMemoryAllocateInfo *pAllocateInfo) {
Courtney Goeltzenleuchter17fd5ce2015-06-13 21:29:26 -0600404 assert(object != NULL);
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -0600405
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700406 memcpy(&my_data->memObjMap[mem].allocInfo, pAllocateInfo,
407 sizeof(VkMemoryAllocateInfo));
408 // TODO: Update for real hardware, actually process allocation info
409 // structures
Tobin Ehlis57b55082015-10-29 09:03:52 -0600410 my_data->memObjMap[mem].allocInfo.pNext = NULL;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700411 my_data->memObjMap[mem].object = object;
412 my_data->memObjMap[mem].refCount = 0;
413 my_data->memObjMap[mem].mem = mem;
Mark Lobodzinskia33d1ed2015-12-11 11:17:49 -0700414 my_data->memObjMap[mem].memRange.offset = 0;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700415 my_data->memObjMap[mem].memRange.size = 0;
416 my_data->memObjMap[mem].pData = 0;
417 my_data->memObjMap[mem].pDriverData = 0;
418 my_data->memObjMap[mem].valid = false;
Michael Lentine80d51872015-11-24 17:55:33 -0600419}
420
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700421static VkBool32 validate_memory_is_valid(layer_data *my_data,
422 VkDeviceMemory mem,
423 const char *functionName,
424 VkImage image = VK_NULL_HANDLE) {
Michael Lentine80d51872015-11-24 17:55:33 -0600425 if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700426 MT_OBJ_BINDING_INFO *pBindInfo = get_object_binding_info(
427 my_data, (uint64_t)(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Michael Lentine80d51872015-11-24 17:55:33 -0600428 if (pBindInfo && !pBindInfo->valid) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700429 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
430 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
431 (uint64_t)(mem), __LINE__,
432 MEMTRACK_INVALID_USAGE_FLAG, "MEM",
433 "%s: Cannot read invalid swapchain image %" PRIx64
434 ", please fill the memory before using.",
435 functionName, (uint64_t)(image));
Michael Lentine80d51872015-11-24 17:55:33 -0600436 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700437 } else {
Michael Lentine80d51872015-11-24 17:55:33 -0600438 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(my_data, mem);
439 if (pMemObj && !pMemObj->valid) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700440 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
441 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
442 (uint64_t)(mem), __LINE__,
443 MEMTRACK_INVALID_USAGE_FLAG, "MEM",
444 "%s: Cannot read invalid memory %" PRIx64
445 ", please fill the memory before using.",
446 functionName, (uint64_t)(mem));
Michael Lentine80d51872015-11-24 17:55:33 -0600447 }
448 }
449 return false;
450}
451
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700452static void set_memory_valid(layer_data *my_data, VkDeviceMemory mem,
453 bool valid, VkImage image = VK_NULL_HANDLE) {
Michael Lentine80d51872015-11-24 17:55:33 -0600454 if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700455 MT_OBJ_BINDING_INFO *pBindInfo = get_object_binding_info(
456 my_data, (uint64_t)(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Michael Lentine80d51872015-11-24 17:55:33 -0600457 if (pBindInfo) {
458 pBindInfo->valid = valid;
459 }
460 } else {
461 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(my_data, mem);
462 if (pMemObj) {
463 pMemObj->valid = valid;
464 }
465 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700466}
467
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500468// Find CB Info and add mem reference to list container
469// Find Mem Obj Info and add CB reference to list container
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700470static VkBool32 update_cmd_buf_and_mem_references(layer_data *my_data,
471 const VkCommandBuffer cb,
472 const VkDeviceMemory mem,
473 const char *apiName) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600474 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600475
476 // Skip validation if this image was created through WSI
477 if (mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
478
479 // First update CB binding in MemObj mini CB list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700480 MT_MEM_OBJ_INFO *pMemInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700481 if (pMemInfo) {
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600482 // Search for cmd buffer object in memory object's binding list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700483 VkBool32 found = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800484 if (pMemInfo->pCommandBufferBindings.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700485 for (list<VkCommandBuffer>::iterator it =
486 pMemInfo->pCommandBufferBindings.begin();
487 it != pMemInfo->pCommandBufferBindings.end(); ++it) {
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600488 if ((*it) == cb) {
David Pinedod8f83d82015-04-27 16:36:17 -0600489 found = VK_TRUE;
490 break;
491 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500492 }
493 }
494 // If not present, add to list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600495 if (found == VK_FALSE) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800496 pMemInfo->pCommandBufferBindings.push_front(cb);
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600497 pMemInfo->refCount++;
498 }
499 // Now update CBInfo's Mem reference list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700500 MT_CB_INFO *pCBInfo = get_cmd_buf_info(my_data, cb);
501 // TODO: keep track of all destroyed CBs so we know if this is a
502 // stale or simply invalid object
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700503 if (pCBInfo) {
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600504 // Search for memory object in cmd buffer's reference list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700505 VkBool32 found = VK_FALSE;
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600506 if (pCBInfo->pMemObjList.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700507 for (auto it = pCBInfo->pMemObjList.begin();
508 it != pCBInfo->pMemObjList.end(); ++it) {
Mark Lobodzinski348803a2015-09-11 15:56:51 -0600509 if ((*it) == mem) {
510 found = VK_TRUE;
511 break;
512 }
513 }
514 }
515 // If not present, add to list
516 if (found == VK_FALSE) {
517 pCBInfo->pMemObjList.push_front(mem);
518 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600519 }
520 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700521 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600522 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700523}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600524
Tobin Ehlis6663f492014-11-10 12:29:12 -0700525// Free bindings related to CB
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700526static VkBool32 clear_cmd_buf_and_mem_references(layer_data *my_data,
527 const VkCommandBuffer cb) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600528 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700529 MT_CB_INFO *pCBInfo = get_cmd_buf_info(my_data, cb);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700530
531 if (pCBInfo && (pCBInfo->pMemObjList.size() > 0)) {
532 list<VkDeviceMemory> mem_obj_list = pCBInfo->pMemObjList;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700533 for (list<VkDeviceMemory>::iterator it = mem_obj_list.begin();
534 it != mem_obj_list.end(); ++it) {
535 MT_MEM_OBJ_INFO *pInfo = get_mem_obj_info(my_data, *it);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700536 if (pInfo) {
537 pInfo->pCommandBufferBindings.remove(cb);
538 pInfo->refCount--;
David Pinedod8f83d82015-04-27 16:36:17 -0600539 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600540 }
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500541 pCBInfo->pMemObjList.clear();
Michael Lentine1e171aa2016-01-06 19:17:59 -0600542 pCBInfo->validate_functions.clear();
Tobin Ehlis6663f492014-11-10 12:29:12 -0700543 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600544 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700545}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600546
Tobin Ehlis6663f492014-11-10 12:29:12 -0700547// Delete the entire CB list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700548static VkBool32 delete_cmd_buf_info_list(layer_data *my_data) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600549 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700550 for (unordered_map<VkCommandBuffer, MT_CB_INFO>::iterator ii =
551 my_data->cbMap.begin();
552 ii != my_data->cbMap.end(); ++ii) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600553 skipCall |= clear_cmd_buf_and_mem_references(my_data, (*ii).first);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700554 }
Tobin Ehlis57b55082015-10-29 09:03:52 -0600555 my_data->cbMap.clear();
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600556 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700557}
558
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500559// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700560static VkBool32 reportMemReferencesAndCleanUp(layer_data *my_data,
561 MT_MEM_OBJ_INFO *pMemObjInfo) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600562 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800563 size_t cmdBufRefCount = pMemObjInfo->pCommandBufferBindings.size();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700564 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500565
Michael Lentinea25a6342015-11-23 17:52:53 -0600566 if ((pMemObjInfo->pCommandBufferBindings.size()) != 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700567 skipCall = log_msg(
568 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
569 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
570 (uint64_t)pMemObjInfo->mem, __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
571 "Attempting to free memory object %#" PRIxLEAST64
572 " which still contains " PRINTF_SIZE_T_SPECIFIER " references",
573 (uint64_t)pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700574 }
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500575
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800576 if (cmdBufRefCount > 0 && pMemObjInfo->pCommandBufferBindings.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700577 for (list<VkCommandBuffer>::const_iterator it =
578 pMemObjInfo->pCommandBufferBindings.begin();
579 it != pMemObjInfo->pCommandBufferBindings.end(); ++it) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800580 // TODO : CommandBuffer should be source Obj here
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700581 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
582 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
583 (uint64_t)(*it), __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
584 "Command Buffer %p still has a reference to mem obj "
585 "%#" PRIxLEAST64,
586 (*it), (uint64_t)pMemObjInfo->mem);
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500587 }
588 // Clear the list of hanging references
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800589 pMemObjInfo->pCommandBufferBindings.clear();
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500590 }
591
David Pinedod8f83d82015-04-27 16:36:17 -0600592 if (objRefCount > 0 && pMemObjInfo->pObjBindings.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700593 for (auto it = pMemObjInfo->pObjBindings.begin();
594 it != pMemObjInfo->pObjBindings.end(); ++it) {
595 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
596 it->type, it->handle, __LINE__, MEMTRACK_FREED_MEM_REF,
597 "MEM", "VK Object %#" PRIxLEAST64
598 " still has a reference to mem obj %#" PRIxLEAST64,
599 it->handle, (uint64_t)pMemObjInfo->mem);
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500600 }
601 // Clear the list of hanging references
602 pMemObjInfo->pObjBindings.clear();
603 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600604 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700605}
606
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700607static VkBool32 deleteMemObjInfo(layer_data *my_data, void *object,
608 VkDeviceMemory mem) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600609 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis57b55082015-10-29 09:03:52 -0600610 auto item = my_data->memObjMap.find(mem);
611 if (item != my_data->memObjMap.end()) {
612 my_data->memObjMap.erase(item);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600613 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700614 skipCall =
615 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
616 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
617 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MEM_OBJ, "MEM",
618 "Request to delete memory object %#" PRIxLEAST64
619 " not present in memory Object Map",
620 (uint64_t)mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700621 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600622 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700623}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -0500624
Tobin Ehlis6663f492014-11-10 12:29:12 -0700625// Check if fence for given CB is completed
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700626static VkBool32 checkCBCompleted(layer_data *my_data, const VkCommandBuffer cb,
627 VkBool32 *complete) {
628 MT_CB_INFO *pCBInfo = get_cmd_buf_info(my_data, cb);
629 VkBool32 skipCall = VK_FALSE;
630 *complete = VK_TRUE;
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700631
632 if (pCBInfo) {
633 if (pCBInfo->lastSubmittedQueue != NULL) {
634 VkQueue queue = pCBInfo->lastSubmittedQueue;
635 MT_QUEUE_INFO *pQueueInfo = &my_data->queueMap[queue];
636 if (pCBInfo->fenceId > pQueueInfo->lastRetiredId) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700637 skipCall =
638 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
639 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
640 (uint64_t)cb, __LINE__, MEMTRACK_NONE, "MEM",
641 "fence %#" PRIxLEAST64
642 " for CB %p has not been checked for completion",
643 (uint64_t)pCBInfo->lastSubmittedFence, cb);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700644 *complete = VK_FALSE;
645 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600646 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700647 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600648 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700649}
650
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700651static VkBool32 freeMemObjInfo(layer_data *my_data, void *object,
652 VkDeviceMemory mem, VkBool32 internal) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600653 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500654 // Parse global list to find info w/ mem
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700655 MT_MEM_OBJ_INFO *pInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700656 if (pInfo) {
Courtney Goeltzenleuchter1c943a72015-03-26 16:15:39 -0600657 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700658 // TODO: Verify against Valid Use section
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700659 skipCall =
660 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
661 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
662 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MEM_OBJ,
663 "MEM", "Attempting to free memory associated with a "
664 "Persistent Image, %#" PRIxLEAST64 ", "
665 "this should not be explicitly freed\n",
666 (uint64_t)mem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600667 } else {
668 // Clear any CB bindings for completed CBs
669 // TODO : Is there a better place to do this?
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500670
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800671 VkBool32 commandBufferComplete = VK_FALSE;
Courtney Goeltzenleuchter10100442015-06-13 21:36:49 -0600672 assert(pInfo->object != VK_NULL_HANDLE);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700673 list<VkCommandBuffer>::iterator it =
674 pInfo->pCommandBufferBindings.begin();
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800675 list<VkCommandBuffer>::iterator temp;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700676 while (pInfo->pCommandBufferBindings.size() > 0 &&
677 it != pInfo->pCommandBufferBindings.end()) {
678 skipCall |=
679 checkCBCompleted(my_data, *it, &commandBufferComplete);
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800680 if (VK_TRUE == commandBufferComplete) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500681 temp = it;
682 ++temp;
Tobin Ehlis57b55082015-10-29 09:03:52 -0600683 skipCall |= clear_cmd_buf_and_mem_references(my_data, *it);
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500684 it = temp;
685 } else {
686 ++it;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600687 }
688 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500689
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700690 // Now verify that no references to this mem obj remain and remove
691 // bindings
Mark Lobodzinski7b772332015-09-10 08:15:23 -0600692 if (0 != pInfo->refCount) {
Tobin Ehlis39fce0f2015-10-29 09:55:19 -0600693 skipCall |= reportMemReferencesAndCleanUp(my_data, pInfo);
Mark Lobodzinski7b772332015-09-10 08:15:23 -0600694 }
Courtney Goeltzenleuchter2f3f8a22015-04-14 00:01:21 -0600695 // Delete mem obj info
Tobin Ehlis57b55082015-10-29 09:03:52 -0600696 skipCall |= deleteMemObjInfo(my_data, object, mem);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700697 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700698 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600699 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700700}
701
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700702static const char *object_type_to_string(VkDebugReportObjectTypeEXT type) {
703 switch (type) {
704 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
705 return "image";
706 break;
707 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
708 return "buffer";
709 break;
710 case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
711 return "swapchain";
712 break;
713 default:
714 return "unknown";
Mark Lobodzinskie8229fb2015-09-15 16:10:17 -0600715 }
716}
717
Tobin Ehlis6663f492014-11-10 12:29:12 -0700718// Remove object binding performs 3 tasks:
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500719// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
720// 2. Decrement refCount for MemObjInfo
Tobin Ehlis257d9742015-07-08 17:08:02 -0600721// 3. Clear mem binding for image/buffer by setting its handle to 0
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700722// TODO : This only applied to Buffer, Image, and Swapchain objects now, how
723// should it be updated/customized?
724static VkBool32 clear_object_binding(layer_data *my_data, void *dispObj,
725 uint64_t handle,
726 VkDebugReportObjectTypeEXT type) {
727 // TODO : Need to customize images/buffers/swapchains to track mem binding
728 // and clear it here appropriately
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600729 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700730 MT_OBJ_BINDING_INFO *pObjBindInfo =
731 get_object_binding_info(my_data, handle, type);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600732 if (pObjBindInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700733 MT_MEM_OBJ_INFO *pMemObjInfo =
734 get_mem_obj_info(my_data, pObjBindInfo->mem);
Michael Lentinea25a6342015-11-23 17:52:53 -0600735 // TODO : Make sure this is a reasonable way to reset mem binding
736 pObjBindInfo->mem = VK_NULL_HANDLE;
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700737 if (pMemObjInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700738 // This obj is bound to a memory object. Remove the reference to
739 // this object in that memory object's list, decrement the memObj's
740 // refcount
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600741 // and set the objects memory binding pointer to NULL.
742 VkBool32 clearSucceeded = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700743 for (auto it = pMemObjInfo->pObjBindings.begin();
744 it != pMemObjInfo->pObjBindings.end(); ++it) {
Tobin Ehlis257d9742015-07-08 17:08:02 -0600745 if ((it->handle == handle) && (it->type == type)) {
746 pMemObjInfo->refCount--;
747 pMemObjInfo->pObjBindings.erase(it);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600748 clearSucceeded = VK_TRUE;
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500749 break;
750 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600751 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700752 if (VK_FALSE == clearSucceeded) {
753 skipCall |= log_msg(
754 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type,
755 handle, __LINE__, MEMTRACK_INVALID_OBJECT, "MEM",
756 "While trying to clear mem binding for %s obj "
757 "%#" PRIxLEAST64 ", unable to find that object referenced "
758 "by mem obj %#" PRIxLEAST64,
759 object_type_to_string(type), handle,
760 (uint64_t)pMemObjInfo->mem);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600761 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700762 }
Tobin Ehlis6663f492014-11-10 12:29:12 -0700763 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600764 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700765}
766
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500767// For NULL mem case, output warning
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500768// Make sure given object is in global object map
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500769// IF a previous binding existed, output validation error
770// Otherwise, add reference from objectInfo to memoryInfo
Mark Lobodzinski223ca202015-04-02 08:52:53 -0500771// Add reference off of objInfo
Courtney Goeltzenleuchter540d3492015-06-13 21:37:34 -0600772// device is required for error logging, need a dispatchable
773// object for that.
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700774static VkBool32 set_mem_binding(layer_data *my_data, void *dispatch_object,
775 VkDeviceMemory mem, uint64_t handle,
776 VkDebugReportObjectTypeEXT type,
777 const char *apiName) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600778 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700779 // Handle NULL case separately, just clear previous binding & decrement
780 // reference
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600781 if (mem == VK_NULL_HANDLE) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700782 // TODO: Verify against Valid Use section of spec.
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700783 skipCall =
784 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, type,
785 handle, __LINE__, MEMTRACK_INVALID_MEM_OBJ, "MEM",
786 "In %s, attempting to Bind Obj(%#" PRIxLEAST64 ") to NULL",
787 apiName, handle);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600788 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700789 MT_OBJ_BINDING_INFO *pObjBindInfo =
790 get_object_binding_info(my_data, handle, type);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600791 if (!pObjBindInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700792 skipCall |= log_msg(
793 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type,
794 handle, __LINE__, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
795 "In %s, attempting to update Binding of %s Obj(%#" PRIxLEAST64
796 ") that's not in global list()",
797 object_type_to_string(type), apiName, handle);
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500798 } else {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600799 // non-null case so should have real mem obj
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700800 MT_MEM_OBJ_INFO *pMemInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700801 if (pMemInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700802 // TODO : Need to track mem binding for obj and report conflict
803 // here
804 MT_MEM_OBJ_INFO *pPrevBinding =
805 get_mem_obj_info(my_data, pObjBindInfo->mem);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600806 if (pPrevBinding != NULL) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700807 skipCall |= log_msg(
808 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
809 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
810 (uint64_t)mem, __LINE__, MEMTRACK_REBIND_OBJECT, "MEM",
811 "In %s, attempting to bind memory (%#" PRIxLEAST64
812 ") to object (%#" PRIxLEAST64 ") which has already "
813 "been bound to mem "
814 "object %#" PRIxLEAST64,
815 apiName, (uint64_t)mem, handle,
816 (uint64_t)pPrevBinding->mem);
817 } else {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600818 MT_OBJ_HANDLE_TYPE oht;
819 oht.handle = handle;
820 oht.type = type;
821 pMemInfo->pObjBindings.push_front(oht);
822 pMemInfo->refCount++;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700823 // For image objects, make sure default memory state is
824 // correctly set
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600825 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700826 if (VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT == type) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600827 VkImageCreateInfo ici = pObjBindInfo->create_info.image;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700828 if (ici.usage &
829 (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
830 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600831 // TODO:: More memory state transition stuff.
832 }
833 }
834 pObjBindInfo->mem = mem;
835 }
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500836 }
837 }
838 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600839 return skipCall;
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500840}
841
842// For NULL mem case, clear any previous binding Else...
Tobin Ehlis257d9742015-07-08 17:08:02 -0600843// Make sure given object is in its object map
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500844// IF a previous binding existed, update binding
845// Add reference from objectInfo to memoryInfo
Tobin Ehlis257d9742015-07-08 17:08:02 -0600846// Add reference off of object's binding info
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500847// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700848static VkBool32 set_sparse_mem_binding(layer_data *my_data, void *dispObject,
849 VkDeviceMemory mem, uint64_t handle,
850 VkDebugReportObjectTypeEXT type,
851 const char *apiName) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600852 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700853 // Handle NULL case separately, just clear previous binding & decrement
854 // reference
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500855 if (mem == VK_NULL_HANDLE) {
Tobin Ehlis57b55082015-10-29 09:03:52 -0600856 skipCall = clear_object_binding(my_data, dispObject, handle, type);
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500857 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700858 MT_OBJ_BINDING_INFO *pObjBindInfo =
859 get_object_binding_info(my_data, handle, type);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600860 if (!pObjBindInfo) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700861 skipCall |= log_msg(
862 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type,
863 handle, __LINE__, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
864 "In %s, attempting to update Binding of Obj(%#" PRIxLEAST64
865 ") that's not in global list()",
866 apiName, handle);
Mark Lobodzinski944aab12015-06-05 13:59:04 -0500867 }
868 // non-null case so should have real mem obj
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700869 MT_MEM_OBJ_INFO *pInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -0700870 if (pInfo) {
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500871 // Search for object in memory object's binding list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700872 VkBool32 found = VK_FALSE;
Courtney Goeltzenleuchtere4171f02015-04-29 10:51:48 -0600873 if (pInfo->pObjBindings.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700874 for (auto it = pInfo->pObjBindings.begin();
875 it != pInfo->pObjBindings.end(); ++it) {
Tobin Ehlis257d9742015-07-08 17:08:02 -0600876 if (((*it).handle == handle) && ((*it).type == type)) {
Courtney Goeltzenleuchtere4171f02015-04-29 10:51:48 -0600877 found = VK_TRUE;
878 break;
879 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600880 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600881 }
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500882 // If not present, add to list
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600883 if (found == VK_FALSE) {
Tobin Ehlis257d9742015-07-08 17:08:02 -0600884 MT_OBJ_HANDLE_TYPE oht;
885 oht.handle = handle;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700886 oht.type = type;
Tobin Ehlis257d9742015-07-08 17:08:02 -0600887 pInfo->pObjBindings.push_front(oht);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500888 pInfo->refCount++;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500889 }
Tobin Ehlis257d9742015-07-08 17:08:02 -0600890 // Need to set mem binding for this object
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700891 MT_MEM_OBJ_INFO *pPrevBinding =
892 get_mem_obj_info(my_data, pObjBindInfo->mem);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600893 pObjBindInfo->mem = mem;
Tobin Ehlis8be20fd2015-01-07 17:49:29 -0700894 }
895 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600896 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700897}
Mark Lobodzinski93f494b2015-03-02 20:23:52 -0600898
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700899template <typename T>
900void print_object_map_members(layer_data *my_data, void *dispObj,
901 T const &objectName,
902 VkDebugReportObjectTypeEXT objectType,
903 const char *objectStr) {
904 for (auto const &element : objectName) {
905 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, objectType,
906 0, __LINE__, MEMTRACK_NONE, "MEM",
907 " %s Object list contains %s Object %#" PRIxLEAST64 " ",
908 objectStr, objectStr, element.first);
Mark Lobodzinski524df112015-08-10 14:37:52 -0600909 }
910}
911
Tobin Ehlis6663f492014-11-10 12:29:12 -0700912// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700913static VkBool32 get_mem_binding_from_object(
914 layer_data *my_data, void *dispObj, const uint64_t handle,
915 const VkDebugReportObjectTypeEXT type, VkDeviceMemory *mem) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600916 VkBool32 skipCall = VK_FALSE;
Chia-I Wue2fc5522015-10-26 20:04:44 +0800917 *mem = VK_NULL_HANDLE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700918 MT_OBJ_BINDING_INFO *pObjBindInfo =
919 get_object_binding_info(my_data, handle, type);
Tobin Ehlis257d9742015-07-08 17:08:02 -0600920 if (pObjBindInfo) {
921 if (pObjBindInfo->mem) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600922 *mem = pObjBindInfo->mem;
Courtney Goeltzenleuchtere4171f02015-04-29 10:51:48 -0600923 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700924 skipCall = log_msg(
925 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type,
926 handle, __LINE__, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
927 "Trying to get mem binding for object %#" PRIxLEAST64
928 " but object has no mem binding",
929 handle);
Tobin Ehlis6663f492014-11-10 12:29:12 -0700930 }
Courtney Goeltzenleuchtere4171f02015-04-29 10:51:48 -0600931 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700932 skipCall =
933 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type,
934 handle, __LINE__, MEMTRACK_INVALID_OBJECT, "MEM",
935 "Trying to get mem binding for object %#" PRIxLEAST64
936 " but no such object in %s list",
937 handle, object_type_to_string(type));
Tobin Ehlis6663f492014-11-10 12:29:12 -0700938 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -0600939 return skipCall;
Tobin Ehlis6663f492014-11-10 12:29:12 -0700940}
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500941
Mark Lobodzinski6434eff2015-03-31 16:05:35 -0500942// Print details of MemObjInfo list
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700943static void print_mem_list(layer_data *my_data, void *dispObj) {
944 MT_MEM_OBJ_INFO *pInfo = NULL;
Mark Lobodzinskib6ddb462015-03-24 16:29:24 -0500945
Mark Lobodzinski524df112015-08-10 14:37:52 -0600946 // Early out if info is not requested
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700947 if (!(my_data->report_data->active_flags & VK_DEBUG_REPORT_INFO_BIT_EXT)) {
Mark Lobodzinski524df112015-08-10 14:37:52 -0600948 return;
949 }
950
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700951 // Just printing each msg individually for now, may want to package these
952 // into single large print
953 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
954 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
955 MEMTRACK_NONE, "MEM",
956 "Details of Memory Object list (of size " PRINTF_SIZE_T_SPECIFIER
957 " elements)",
958 my_data->memObjMap.size());
959 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
960 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
961 MEMTRACK_NONE, "MEM", "=============================");
Mark Lobodzinski524df112015-08-10 14:37:52 -0600962
Tobin Ehlis57b55082015-10-29 09:03:52 -0600963 if (my_data->memObjMap.size() <= 0)
Mark Lobodzinski524df112015-08-10 14:37:52 -0600964 return;
965
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700966 for (auto ii = my_data->memObjMap.begin(); ii != my_data->memObjMap.end();
967 ++ii) {
Mark Lobodzinski524df112015-08-10 14:37:52 -0600968 pInfo = &(*ii).second;
969
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700970 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
971 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
972 MEMTRACK_NONE, "MEM", " ===MemObjInfo at %p===",
973 (void *)pInfo);
974 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
975 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
976 MEMTRACK_NONE, "MEM", " Mem object: %#" PRIxLEAST64,
977 (uint64_t)(pInfo->mem));
978 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
979 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
980 MEMTRACK_NONE, "MEM", " Ref Count: %u", pInfo->refCount);
Mark Lobodzinski524df112015-08-10 14:37:52 -0600981 if (0 != pInfo->allocInfo.allocationSize) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700982 string pAllocInfoMsg = vk_print_vkmemoryallocateinfo(
983 &pInfo->allocInfo, "MEM(INFO): ");
984 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
985 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
986 MEMTRACK_NONE, "MEM", " Mem Alloc info:\n%s",
987 pAllocInfoMsg.c_str());
Mark Lobodzinski524df112015-08-10 14:37:52 -0600988 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700989 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
990 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
991 MEMTRACK_NONE, "MEM", " Mem Alloc info is NULL (alloc "
992 "done by vkCreateSwapchainKHR())");
Mark Lobodzinski524df112015-08-10 14:37:52 -0600993 }
994
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -0700995 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
996 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
997 MEMTRACK_NONE, "MEM",
998 " VK OBJECT Binding list of size " PRINTF_SIZE_T_SPECIFIER
999 " elements:",
1000 pInfo->pObjBindings.size());
Mark Lobodzinski524df112015-08-10 14:37:52 -06001001 if (pInfo->pObjBindings.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001002 for (list<MT_OBJ_HANDLE_TYPE>::iterator it =
1003 pInfo->pObjBindings.begin();
1004 it != pInfo->pObjBindings.end(); ++it) {
1005 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1006 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
1007 __LINE__, MEMTRACK_NONE, "MEM",
Michael Lentine010f4692015-11-03 16:19:46 -08001008 " VK OBJECT %" PRIu64, it->handle);
Mark Lobodzinski524df112015-08-10 14:37:52 -06001009 }
1010 }
1011
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001012 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1013 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
1014 MEMTRACK_NONE, "MEM",
1015 " VK Command Buffer (CB) binding list of "
1016 "size " PRINTF_SIZE_T_SPECIFIER " elements",
1017 pInfo->pCommandBufferBindings.size());
1018 if (pInfo->pCommandBufferBindings.size() > 0) {
1019 for (list<VkCommandBuffer>::iterator it =
1020 pInfo->pCommandBufferBindings.begin();
1021 it != pInfo->pCommandBufferBindings.end(); ++it) {
1022 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1023 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
1024 __LINE__, MEMTRACK_NONE, "MEM", " VK CB %p",
1025 (*it));
Mark Lobodzinski524df112015-08-10 14:37:52 -06001026 }
1027 }
1028 }
1029}
1030
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001031static void printCBList(layer_data *my_data, void *dispObj) {
1032 MT_CB_INFO *pCBInfo = NULL;
Mark Lobodzinski524df112015-08-10 14:37:52 -06001033
1034 // Early out if info is not requested
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001035 if (!(my_data->report_data->active_flags & VK_DEBUG_REPORT_INFO_BIT_EXT)) {
Mark Lobodzinski524df112015-08-10 14:37:52 -06001036 return;
1037 }
1038
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001039 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1040 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
1041 MEMTRACK_NONE, "MEM",
1042 "Details of CB list (of size " PRINTF_SIZE_T_SPECIFIER " elements)",
1043 my_data->cbMap.size());
1044 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1045 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
1046 MEMTRACK_NONE, "MEM", "==================");
Mark Lobodzinski524df112015-08-10 14:37:52 -06001047
Tobin Ehlis57b55082015-10-29 09:03:52 -06001048 if (my_data->cbMap.size() <= 0)
Mark Lobodzinski524df112015-08-10 14:37:52 -06001049 return;
1050
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001051 for (auto ii = my_data->cbMap.begin(); ii != my_data->cbMap.end(); ++ii) {
Mark Lobodzinski524df112015-08-10 14:37:52 -06001052 pCBInfo = &(*ii).second;
1053
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001054 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1055 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
1056 MEMTRACK_NONE, "MEM",
1057 " CB Info (%p) has CB %p, fenceId %" PRIx64
1058 ", and fence %#" PRIxLEAST64,
1059 (void *)pCBInfo, (void *)pCBInfo->commandBuffer,
1060 pCBInfo->fenceId, (uint64_t)pCBInfo->lastSubmittedFence);
Mark Lobodzinski524df112015-08-10 14:37:52 -06001061
1062 if (pCBInfo->pMemObjList.size() <= 0)
1063 continue;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001064 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin();
1065 it != pCBInfo->pMemObjList.end(); ++it) {
1066 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1067 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
1068 MEMTRACK_NONE, "MEM", " Mem obj %" PRIu64,
1069 (uint64_t)(*it));
Mark Lobodzinski524df112015-08-10 14:37:52 -06001070 }
1071 }
1072}
Tobin Ehlis6663f492014-11-10 12:29:12 -07001073
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001074static void init_mem_tracker(layer_data *my_data,
1075 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchter6f484322015-06-14 11:37:01 -06001076 uint32_t report_flags = 0;
1077 uint32_t debug_action = 0;
1078 FILE *log_output = NULL;
1079 const char *option_str;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001080 VkDebugReportCallbackEXT callback;
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001081 // initialize MemTracker options
Courtney Goeltzenleuchter6f484322015-06-14 11:37:01 -06001082 report_flags = getLayerOptionFlags("MemTrackerReportFlags", 0);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001083 getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *)&debug_action);
Tobin Ehlisee702232015-01-08 14:26:53 -07001084
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001085 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
Courtney Goeltzenleuchter6f484322015-06-14 11:37:01 -06001086 option_str = getLayerOption("MemTrackerLogFilename");
Tobin Ehlisb1df55e2015-09-15 09:55:54 -06001087 log_output = getLayerLogOutput(option_str, "MemTracker");
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001088 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001089 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001090 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001091 dbgInfo.pfnCallback = log_callback;
1092 dbgInfo.pUserData = log_output;
1093 dbgInfo.flags = report_flags;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001094 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator,
1095 &callback);
Courtney Goeltzenleuchter0036b572015-10-05 15:59:26 -06001096 my_data->logging_callback.push_back(callback);
1097 }
1098
1099 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001100 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001101 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001102 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001103 dbgInfo.pfnCallback = win32_debug_output_msg;
1104 dbgInfo.pUserData = log_output;
1105 dbgInfo.flags = report_flags;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001106 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator,
1107 &callback);
Courtney Goeltzenleuchter0036b572015-10-05 15:59:26 -06001108 my_data->logging_callback.push_back(callback);
Jon Ashburn7d7b3cf2014-12-22 13:24:15 -07001109 }
1110
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001111 if (!globalLockInitialized) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001112 loader_platform_thread_create_mutex(&globalLock);
1113 globalLockInitialized = 1;
1114 }
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -06001115
1116 // Zero out memory property data
1117 memset(&memProps, 0, sizeof(VkPhysicalDeviceMemoryProperties));
Tobin Ehlis6663f492014-11-10 12:29:12 -07001118}
1119
Mark Lobodzinski76c991d2015-05-20 16:16:37 -05001120// hook DestroyInstance to remove tableInstanceMap entry
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001121VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1122 vkDestroyInstance(VkInstance instance,
1123 const VkAllocationCallbacks *pAllocator) {
Jeremy Hayes35f8afc2015-06-18 10:25:55 -06001124 // Grab the key before the instance is destroyed.
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -06001125 dispatch_key key = get_dispatch_key(instance);
Tobin Ehliscdd73272015-10-28 16:25:11 -06001126 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
1127 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wuf7458c52015-10-26 21:10:41 +08001128 pTable->DestroyInstance(instance, pAllocator);
Courtney Goeltzenleuchter6f484322015-06-14 11:37:01 -06001129
1130 // Clean up logging callback, if any
Courtney Goeltzenleuchter0036b572015-10-05 15:59:26 -06001131 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001132 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07001133 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchter0036b572015-10-05 15:59:26 -06001134 my_data->logging_callback.pop_back();
Courtney Goeltzenleuchter6f484322015-06-14 11:37:01 -06001135 }
1136
Tobin Ehliscdd73272015-10-28 16:25:11 -06001137 layer_debug_report_destroy_instance(my_data->report_data);
1138 delete my_data->instance_dispatch_table;
1139 layer_data_map.erase(key);
1140 if (layer_data_map.empty()) {
1141 // Release mutex when destroying last instance
1142 loader_platform_thread_delete_mutex(&globalLock);
1143 globalLockInitialized = 0;
1144 }
Mark Lobodzinski76c991d2015-05-20 16:16:37 -05001145}
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001146
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001147VKAPI_ATTR VkResult VKAPI_CALL
1148 vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
1149 const VkAllocationCallbacks *pAllocator,
1150 VkInstance *pInstance) {
1151 VkLayerInstanceCreateInfo *chain_info =
1152 get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06001153
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001154 assert(chain_info->u.pLayerInfo);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001155 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
1156 chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1157 PFN_vkCreateInstance fpCreateInstance =
1158 (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001159 if (fpCreateInstance == NULL) {
1160 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06001161 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001162
1163 // Advance the link info for the next element on the chain
1164 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
1165
1166 VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
1167 if (result != VK_SUCCESS) {
1168 return result;
1169 }
1170
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001171 layer_data *my_data =
1172 get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001173 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001174 layer_init_instance_dispatch_table(
1175 *pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001176
1177 my_data->report_data = debug_report_create_instance(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001178 my_data->instance_dispatch_table, *pInstance,
1179 pCreateInfo->enabledExtensionCount,
1180 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001181
1182 init_mem_tracker(my_data, pAllocator);
1183
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06001184 return result;
1185}
1186
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -07001187static void
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001188createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo,
1189 VkDevice device) {
1190 layer_data *my_device_data =
1191 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehliscdd73272015-10-28 16:25:11 -06001192 VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
Jon Ashburn8acd2332015-09-16 18:08:32 -06001193 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001194 pDisp->CreateSwapchainKHR =
1195 (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
1196 pDisp->DestroySwapchainKHR =
1197 (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
1198 pDisp->GetSwapchainImagesKHR =
1199 (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
1200 pDisp->AcquireNextImageKHR =
1201 (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
1202 pDisp->QueuePresentKHR =
1203 (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
Michael Lentine685f61c2015-10-29 10:41:47 -07001204 my_device_data->wsi_enabled = VK_FALSE;
Jon Ashburnf19916e2016-01-11 13:12:43 -07001205 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001206 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
1207 VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliott1064fe32015-07-06 14:31:32 -06001208 my_device_data->wsi_enabled = true;
Jon Ashburn747f2b62015-06-18 15:02:58 -06001209 }
1210}
1211
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001212VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1213 vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
1214 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
1215 VkLayerDeviceCreateInfo *chain_info =
1216 get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001217
1218 assert(chain_info->u.pLayerInfo);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001219 PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
1220 chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1221 PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr =
1222 chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
1223 PFN_vkCreateDevice fpCreateDevice =
1224 (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice");
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001225 if (fpCreateDevice == NULL) {
1226 return VK_ERROR_INITIALIZATION_FAILED;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001227 }
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001228
1229 // Advance the link info for the next element on the chain
1230 chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
1231
1232 VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
1233 if (result != VK_SUCCESS) {
1234 return result;
1235 }
1236
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001237 layer_data *my_instance_data =
1238 get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
1239 layer_data *my_device_data =
1240 get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001241
1242 // Setup device dispatch table
1243 my_device_data->device_dispatch_table = new VkLayerDispatchTable;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001244 layer_init_device_dispatch_table(
1245 *pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001246
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001247 my_device_data->report_data = layer_debug_report_create_device(
1248 my_instance_data->report_data, *pDevice);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001249 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001250 my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(
1251 gpu, &my_device_data->properties);
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07001252
Tobin Ehlis6663f492014-11-10 12:29:12 -07001253 return result;
1254}
1255
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001256VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1257 vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06001258 dispatch_key key = get_dispatch_key(device);
1259 layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001260 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001261 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001262 log_msg(my_device_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1263 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device, __LINE__,
1264 MEMTRACK_NONE, "MEM",
1265 "Printing List details prior to vkDestroyDevice()");
1266 log_msg(my_device_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
1267 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device, __LINE__,
1268 MEMTRACK_NONE, "MEM",
1269 "================================================");
Tobin Ehlis57b55082015-10-29 09:03:52 -06001270 print_mem_list(my_device_data, device);
1271 printCBList(my_device_data, device);
1272 skipCall = delete_cmd_buf_info_list(my_device_data);
Tobin Ehlisb54ef782014-11-25 18:01:12 -07001273 // Report any memory leaks
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001274 MT_MEM_OBJ_INFO *pInfo = NULL;
Tobin Ehlis57b55082015-10-29 09:03:52 -06001275 if (my_device_data->memObjMap.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001276 for (auto ii = my_device_data->memObjMap.begin();
1277 ii != my_device_data->memObjMap.end(); ++ii) {
Mike Stroyandd7aed72015-05-19 17:03:40 -06001278 pInfo = &(*ii).second;
David Pinedod8f83d82015-04-27 16:36:17 -06001279 if (pInfo->allocInfo.allocationSize != 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001280 // Valid Usage: All child objects created on device must have
1281 // been destroyed prior to destroying device
1282 skipCall |= log_msg(
1283 my_device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
1284 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1285 (uint64_t)pInfo->mem, __LINE__, MEMTRACK_MEMORY_LEAK, "MEM",
1286 "Mem Object %" PRIu64 " has not been freed. You should "
1287 "clean up this memory by calling "
1288 "vkFreeMemory(%" PRIu64 ") prior to vkDestroyDevice().",
1289 (uint64_t)(pInfo->mem), (uint64_t)(pInfo->mem));
David Pinedod8f83d82015-04-27 16:36:17 -06001290 }
Mark Lobodzinski2f3b19b2015-02-18 18:06:24 -06001291 }
Tobin Ehlisb54ef782014-11-25 18:01:12 -07001292 }
Mark Lobodzinski223ca202015-04-02 08:52:53 -05001293 // Queues persist until device is destroyed
Tobin Ehlis57b55082015-10-29 09:03:52 -06001294 delete_queue_info_list(my_device_data);
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -06001295 layer_debug_report_destroy_device(device);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001296 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski76c991d2015-05-20 16:16:37 -05001297
Courtney Goeltzenleuchter89d68442015-06-13 21:40:22 -06001298#if DISPATCH_MAP_DEBUG
1299 fprintf(stderr, "Device: %p, key: %p\n", device, key);
1300#endif
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001301 VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001302 if (VK_FALSE == skipCall) {
Chia-I Wuf7458c52015-10-26 21:10:41 +08001303 pDisp->DestroyDevice(device, pAllocator);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001304 }
Tobin Ehliscdd73272015-10-28 16:25:11 -06001305 delete my_device_data->device_dispatch_table;
1306 layer_data_map.erase(key);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001307}
1308
Chia-I Wu9ab61502015-11-06 06:42:02 +08001309VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001310 VkPhysicalDevice physicalDevice,
1311 VkPhysicalDeviceMemoryProperties *pMemoryProperties) {
1312 layer_data *my_data =
1313 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1314 VkLayerInstanceDispatchTable *pInstanceTable =
1315 my_data->instance_dispatch_table;
1316 pInstanceTable->GetPhysicalDeviceMemoryProperties(physicalDevice,
1317 pMemoryProperties);
1318 memcpy(&memProps, pMemoryProperties,
1319 sizeof(VkPhysicalDeviceMemoryProperties));
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -06001320}
1321
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -07001322static const VkExtensionProperties instance_extensions[] = {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001323 {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
Jon Ashburn9fd4cc42015-04-10 14:33:07 -06001324
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001325VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1326 vkEnumerateInstanceExtensionProperties(const char *pLayerName,
1327 uint32_t *pCount,
1328 VkExtensionProperties *pProperties) {
1329 return util_GetExtensionProperties(1, instance_extensions, pCount,
1330 pProperties);
Tony Barbour59a47322015-06-24 16:06:58 -06001331}
1332
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001333static const VkLayerProperties mtGlobalLayers[] = {{
1334 "VK_LAYER_LUNARG_mem_tracker", VK_API_VERSION, VK_MAKE_VERSION(0, 1, 0),
1335 "Validation layer: mem_tracker",
1336}};
Courtney Goeltzenleuchter52857662015-12-01 14:08:28 -07001337
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001338VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1339 vkEnumerateInstanceLayerProperties(uint32_t *pCount,
1340 VkLayerProperties *pProperties) {
1341 return util_GetLayerProperties(ARRAY_SIZE(mtGlobalLayers), mtGlobalLayers,
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -06001342 pCount, pProperties);
Jon Ashburn9fd4cc42015-04-10 14:33:07 -06001343}
1344
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001345VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1346 vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
1347 const char *pLayerName,
1348 uint32_t *pCount,
1349 VkExtensionProperties *pProperties) {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -06001350 /* Mem tracker does not have any physical device extensions */
Jon Ashburn751c4842015-11-02 17:37:20 -07001351 if (pLayerName == NULL) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001352 layer_data *my_data =
1353 get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1354 VkLayerInstanceDispatchTable *pInstanceTable =
1355 my_data->instance_dispatch_table;
Jon Ashburn751c4842015-11-02 17:37:20 -07001356 return pInstanceTable->EnumerateDeviceExtensionProperties(
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -07001357 physicalDevice, NULL, pCount, pProperties);
Jon Ashburn751c4842015-11-02 17:37:20 -07001358 } else {
1359 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
1360 }
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -06001361}
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06001362
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001363VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1364 vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
1365 uint32_t *pCount,
1366 VkLayerProperties *pProperties) {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -06001367 /* Mem tracker's physical device layers are the same as global */
Courtney Goeltzenleuchtere7481332015-07-07 10:04:16 -06001368 return util_GetLayerProperties(ARRAY_SIZE(mtGlobalLayers), mtGlobalLayers,
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -06001369 pCount, pProperties);
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06001370}
1371
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001372VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1373 vkGetDeviceQueue(VkDevice device, uint32_t queueNodeIndex,
1374 uint32_t queueIndex, VkQueue *pQueue) {
1375 layer_data *my_data =
1376 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1377 my_data->device_dispatch_table->GetDeviceQueue(device, queueNodeIndex,
1378 queueIndex, pQueue);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -06001379 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001380 add_queue_info(my_data, *pQueue);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -06001381 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski748eddf2015-03-31 16:05:35 -05001382}
1383
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001384VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1385 vkQueueSubmit(VkQueue queue, uint32_t submitCount,
1386 const VkSubmitInfo *pSubmits, VkFence fence) {
1387 layer_data *my_data =
1388 get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001389 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001390
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001391 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001392 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001393 MT_CB_INFO *pCBInfo = NULL;
1394 uint64_t fenceId = 0;
Tobin Ehlis57b55082015-10-29 09:03:52 -06001395 VkBool32 skipCall = add_fence_info(my_data, fence, queue, &fenceId);
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001396
Tobin Ehlis57b55082015-10-29 09:03:52 -06001397 print_mem_list(my_data, queue);
1398 printCBList(my_data, queue);
Courtney Goeltzenleuchter646b9072015-10-20 18:04:07 -06001399 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Chia-I Wu40cf0ae2015-10-26 17:20:32 +08001400 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Chia-I Wud50a7d72015-10-26 20:48:51 +08001401 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Tobin Ehlis57b55082015-10-29 09:03:52 -06001402 pCBInfo = get_cmd_buf_info(my_data, submit->pCommandBuffers[i]);
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -07001403 if (pCBInfo) {
1404 pCBInfo->fenceId = fenceId;
1405 pCBInfo->lastSubmittedFence = fence;
1406 pCBInfo->lastSubmittedQueue = queue;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001407 for (auto &function : pCBInfo->validate_functions) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06001408 skipCall |= function();
1409 }
Mark Lobodzinski0dce80e2015-11-19 15:45:36 -07001410 }
Courtney Goeltzenleuchter646b9072015-10-20 18:04:07 -06001411 }
Chia-I Wua690b412015-10-29 22:01:53 +08001412
Chia-I Wud50a7d72015-10-26 20:48:51 +08001413 for (uint32_t i = 0; i < submit->waitSemaphoreCount; i++) {
Chia-I Wua690b412015-10-29 22:01:53 +08001414 VkSemaphore sem = submit->pWaitSemaphores[i];
1415
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001416 if (my_data->semaphoreMap.find(sem) !=
1417 my_data->semaphoreMap.end()) {
1418 if (my_data->semaphoreMap[sem] !=
1419 MEMTRACK_SEMAPHORE_STATE_SIGNALLED) {
1420 skipCall = log_msg(
1421 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1422 VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
1423 (uint64_t)sem, __LINE__, MEMTRACK_NONE, "SEMAPHORE",
1424 "vkQueueSubmit: Semaphore must be in signaled state "
1425 "before passing to pWaitSemaphores");
Chia-I Wua690b412015-10-29 22:01:53 +08001426 }
Tobin Ehlis57b55082015-10-29 09:03:52 -06001427 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_WAIT;
Chia-I Wua690b412015-10-29 22:01:53 +08001428 }
1429 }
Chia-I Wud50a7d72015-10-26 20:48:51 +08001430 for (uint32_t i = 0; i < submit->signalSemaphoreCount; i++) {
Norbert Nopperb63edf32016-01-08 18:35:19 +01001431 VkSemaphore sem = submit->pSignalSemaphores[i];
Chia-I Wua690b412015-10-29 22:01:53 +08001432
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001433 if (my_data->semaphoreMap.find(sem) !=
1434 my_data->semaphoreMap.end()) {
1435 if (my_data->semaphoreMap[sem] !=
1436 MEMTRACK_SEMAPHORE_STATE_UNSET) {
1437 skipCall = log_msg(
1438 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1439 VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
1440 (uint64_t)sem, __LINE__, MEMTRACK_NONE, "SEMAPHORE",
1441 "vkQueueSubmit: Semaphore must not be currently "
1442 "signaled or in a wait state");
Chia-I Wua690b412015-10-29 22:01:53 +08001443 }
Tobin Ehlis57b55082015-10-29 09:03:52 -06001444 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_SIGNALLED;
Chia-I Wua690b412015-10-29 22:01:53 +08001445 }
1446 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001447 }
Mark Lobodzinskied450b02015-04-07 13:38:21 -05001448
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001449 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001450 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001451 result = my_data->device_dispatch_table->QueueSubmit(queue, submitCount,
1452 pSubmits, fence);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001453 }
Chia-I Wua690b412015-10-29 22:01:53 +08001454
1455 loader_platform_thread_lock_mutex(&globalLock);
1456 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Chia-I Wu40cf0ae2015-10-26 17:20:32 +08001457 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Chia-I Wud50a7d72015-10-26 20:48:51 +08001458 for (uint32_t i = 0; i < submit->waitSemaphoreCount; i++) {
Chia-I Wua690b412015-10-29 22:01:53 +08001459 VkSemaphore sem = submit->pWaitSemaphores[i];
1460
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001461 if (my_data->semaphoreMap.find(sem) !=
1462 my_data->semaphoreMap.end()) {
Tobin Ehlis57b55082015-10-29 09:03:52 -06001463 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_UNSET;
Chia-I Wua690b412015-10-29 22:01:53 +08001464 }
1465 }
1466 }
1467 loader_platform_thread_unlock_mutex(&globalLock);
1468
Courtney Goeltzenleuchterd3fb9552015-04-02 13:39:07 -06001469 return result;
1470}
1471
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001472VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1473 vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
1474 const VkAllocationCallbacks *pAllocator,
1475 VkDeviceMemory *pMemory) {
1476 layer_data *my_data =
1477 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1478 VkResult result = my_data->device_dispatch_table->AllocateMemory(
1479 device, pAllocateInfo, pAllocator, pMemory);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001480 // TODO : Track allocations and overall size here
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001481 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001482 add_mem_obj_info(my_data, device, *pMemory, pAllocateInfo);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001483 print_mem_list(my_data, device);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001484 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001485 return result;
1486}
1487
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001488VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1489 vkFreeMemory(VkDevice device, VkDeviceMemory mem,
1490 const VkAllocationCallbacks *pAllocator) {
1491 layer_data *my_data =
1492 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001493 my_data->bufferRanges.erase(mem);
1494 my_data->imageRanges.erase(mem);
Michael Lentinea25a6342015-11-23 17:52:53 -06001495
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001496 // From spec : A memory object is freed by calling vkFreeMemory() when it is
1497 // no longer needed.
1498 // Before freeing a memory object, an application must ensure the memory
1499 // object is no longer
1500 // in use by the device—for example by command buffers queued for execution.
1501 // The memory need
1502 // not yet be unbound from all images and buffers, but any further use of
1503 // those images or
1504 // buffers (on host or device) for anything other than destroying those
1505 // objects will result in
Michael Lentinea25a6342015-11-23 17:52:53 -06001506 // undefined behavior.
1507
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001508 loader_platform_thread_lock_mutex(&globalLock);
Michael Lentine685f61c2015-10-29 10:41:47 -07001509 freeMemObjInfo(my_data, device, mem, VK_FALSE);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001510 print_mem_list(my_data, device);
1511 printCBList(my_data, device);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001512 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wuf7458c52015-10-26 21:10:41 +08001513 my_data->device_dispatch_table->FreeMemory(device, mem, pAllocator);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001514}
1515
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001516VkBool32 validateMemRange(layer_data *my_data, VkDeviceMemory mem,
1517 VkDeviceSize offset, VkDeviceSize size) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001518 VkBool32 skipCall = VK_FALSE;
Michael Lentine48f50662015-10-28 16:26:14 -07001519
Mark Lobodzinski4272e9b2015-11-19 14:13:44 -07001520 if (size == 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001521 // TODO: a size of 0 is not listed as an invalid use in the spec, should
1522 // it be?
1523 skipCall =
1524 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
1525 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1526 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
1527 "VkMapMemory: Attempting to map memory range of size zero");
Mark Lobodzinski4272e9b2015-11-19 14:13:44 -07001528 }
1529
Michael Lentine48f50662015-10-28 16:26:14 -07001530 auto mem_element = my_data->memObjMap.find(mem);
1531 if (mem_element != my_data->memObjMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001532 // It is an application error to call VkMapMemory on an object that is
1533 // already mapped
Mark Lobodzinski4272e9b2015-11-19 14:13:44 -07001534 if (mem_element->second.memRange.size != 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001535 skipCall =
1536 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1537 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1538 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
1539 "VkMapMemory: Attempting to map memory on an "
1540 "already-mapped object %#" PRIxLEAST64,
1541 (uint64_t)mem);
Mark Lobodzinski4272e9b2015-11-19 14:13:44 -07001542 }
1543
1544 // Validate that offset + size is within object's allocationSize
Mark Lobodzinskicb5de952015-12-11 14:55:11 -07001545 if (size == VK_WHOLE_SIZE) {
1546 if (offset >= mem_element->second.allocInfo.allocationSize) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001547 skipCall = log_msg(
1548 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1549 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1550 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
1551 "Mapping Memory from %" PRIu64 " to %" PRIu64
1552 " with total array size %" PRIu64,
1553 offset, mem_element->second.allocInfo.allocationSize,
1554 mem_element->second.allocInfo.allocationSize);
Mark Lobodzinskicb5de952015-12-11 14:55:11 -07001555 }
1556 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001557 if ((offset + size) >
1558 mem_element->second.allocInfo.allocationSize) {
1559 skipCall =
1560 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1561 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1562 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP,
1563 "MEM", "Mapping Memory from %" PRIu64 " to %" PRIu64
1564 " with total array size %" PRIu64,
1565 offset, size + offset,
1566 mem_element->second.allocInfo.allocationSize);
Mark Lobodzinskicb5de952015-12-11 14:55:11 -07001567 }
Michael Lentine48f50662015-10-28 16:26:14 -07001568 }
1569 }
Michael Lentine685f61c2015-10-29 10:41:47 -07001570 return skipCall;
1571}
1572
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001573void storeMemRanges(layer_data *my_data, VkDeviceMemory mem,
1574 VkDeviceSize offset, VkDeviceSize size) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001575 auto mem_element = my_data->memObjMap.find(mem);
1576 if (mem_element != my_data->memObjMap.end()) {
1577 MemRange new_range;
1578 new_range.offset = offset;
1579 new_range.size = size;
1580 mem_element->second.memRange = new_range;
1581 }
1582}
1583
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001584VkBool32 deleteMemRanges(layer_data *my_data, VkDeviceMemory mem) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001585 VkBool32 skipCall = VK_FALSE;
1586 auto mem_element = my_data->memObjMap.find(mem);
1587 if (mem_element != my_data->memObjMap.end()) {
1588 if (!mem_element->second.memRange.size) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07001589 // Valid Usage: memory must currently be mapped
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001590 skipCall =
1591 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
1592 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1593 (uint64_t)mem, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
1594 "Unmapping Memory without memory being mapped: mem obj "
1595 "%#" PRIxLEAST64,
1596 (uint64_t)mem);
Michael Lentine685f61c2015-10-29 10:41:47 -07001597 }
1598 mem_element->second.memRange.size = 0;
1599 if (mem_element->second.pData) {
1600 free(mem_element->second.pData);
1601 mem_element->second.pData = 0;
1602 }
1603 }
1604 return skipCall;
1605}
1606
1607static char NoncoherentMemoryFillValue = 0xb;
1608
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001609void initializeAndTrackMemory(layer_data *my_data, VkDeviceMemory mem,
1610 VkDeviceSize size, void **ppData) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001611 auto mem_element = my_data->memObjMap.find(mem);
1612 if (mem_element != my_data->memObjMap.end()) {
1613 mem_element->second.pDriverData = *ppData;
1614 uint32_t index = mem_element->second.allocInfo.memoryTypeIndex;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001615 if (memProps.memoryTypes[index].propertyFlags &
1616 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001617 mem_element->second.pData = 0;
1618 } else {
Chris Forbesa699ddb2016-01-14 15:57:46 +13001619 if (size == VK_WHOLE_SIZE) {
1620 size = mem_element->second.allocInfo.allocationSize;
1621 }
Mark Young93ecb1d2016-01-13 13:47:16 -07001622 size_t convSize = (size_t)(size);
1623 mem_element->second.pData = malloc(2 * convSize);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001624 memset(mem_element->second.pData, NoncoherentMemoryFillValue,
1625 2 * convSize);
1626 *ppData =
1627 static_cast<char *>(mem_element->second.pData) + (convSize / 2);
Michael Lentine685f61c2015-10-29 10:41:47 -07001628 }
1629 }
Michael Lentine48f50662015-10-28 16:26:14 -07001630}
1631
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001632VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1633 vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset,
1634 VkDeviceSize size, VkFlags flags, void **ppData) {
1635 layer_data *my_data =
1636 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1637 VkBool32 skipCall = VK_FALSE;
1638 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001639 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001640 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(my_data, mem);
Michael Lentine80d51872015-11-24 17:55:33 -06001641 if (pMemObj) {
1642 pMemObj->valid = true;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001643 if ((memProps.memoryTypes[pMemObj->allocInfo.memoryTypeIndex]
1644 .propertyFlags &
Michael Lentine80d51872015-11-24 17:55:33 -06001645 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001646 skipCall = log_msg(
1647 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1648 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem,
1649 __LINE__, MEMTRACK_INVALID_STATE, "MEM",
1650 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT "
1651 "set: mem obj %#" PRIxLEAST64,
1652 (uint64_t)mem);
Michael Lentine80d51872015-11-24 17:55:33 -06001653 }
Mark Lobodzinski95152dc2015-02-25 12:16:04 -06001654 }
Michael Lentine685f61c2015-10-29 10:41:47 -07001655 skipCall |= validateMemRange(my_data, mem, offset, size);
1656 storeMemRanges(my_data, mem, offset, size);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001657 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001658 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001659 result = my_data->device_dispatch_table->MapMemory(device, mem, offset,
1660 size, flags, ppData);
Michael Lentine685f61c2015-10-29 10:41:47 -07001661 initializeAndTrackMemory(my_data, mem, size, ppData);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001662 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001663 return result;
1664}
1665
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001666VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1667 vkUnmapMemory(VkDevice device, VkDeviceMemory mem) {
1668 layer_data *my_data =
1669 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1670 VkBool32 skipCall = VK_FALSE;
Michael Lentine685f61c2015-10-29 10:41:47 -07001671
1672 loader_platform_thread_lock_mutex(&globalLock);
1673 skipCall |= deleteMemRanges(my_data, mem);
1674 loader_platform_thread_unlock_mutex(&globalLock);
1675 if (VK_FALSE == skipCall) {
1676 my_data->device_dispatch_table->UnmapMemory(device, mem);
1677 }
1678}
1679
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001680VkBool32 validateMemoryIsMapped(layer_data *my_data, uint32_t memRangeCount,
1681 const VkMappedMemoryRange *pMemRanges) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001682 VkBool32 skipCall = VK_FALSE;
1683 for (uint32_t i = 0; i < memRangeCount; ++i) {
1684 auto mem_element = my_data->memObjMap.find(pMemRanges[i].memory);
1685 if (mem_element != my_data->memObjMap.end()) {
1686 if (mem_element->second.memRange.offset > pMemRanges[i].offset ||
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001687 (mem_element->second.memRange.offset +
1688 mem_element->second.memRange.size) <
1689 (pMemRanges[i].offset + pMemRanges[i].size)) {
1690 skipCall |=
1691 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1692 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1693 (uint64_t)pMemRanges[i].memory, __LINE__,
1694 MEMTRACK_INVALID_MAP, "MEM",
1695 "Memory must be mapped before it can be flushed or "
1696 "invalidated.");
Michael Lentine685f61c2015-10-29 10:41:47 -07001697 }
1698 }
1699 }
1700 return skipCall;
1701}
1702
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001703VkBool32 validateAndCopyNoncoherentMemoryToDriver(
1704 layer_data *my_data, uint32_t memRangeCount,
1705 const VkMappedMemoryRange *pMemRanges) {
Michael Lentine685f61c2015-10-29 10:41:47 -07001706 VkBool32 skipCall = VK_FALSE;
1707 for (uint32_t i = 0; i < memRangeCount; ++i) {
1708 auto mem_element = my_data->memObjMap.find(pMemRanges[i].memory);
1709 if (mem_element != my_data->memObjMap.end()) {
1710 if (mem_element->second.pData) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001711 VkDeviceSize size = mem_element->second.memRange.size;
Michael Lentine685f61c2015-10-29 10:41:47 -07001712 VkDeviceSize half_size = (size / 2);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001713 char *data = static_cast<char *>(mem_element->second.pData);
Michael Lentine685f61c2015-10-29 10:41:47 -07001714 for (auto j = 0; j < half_size; ++j) {
1715 if (data[j] != NoncoherentMemoryFillValue) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001716 skipCall |= log_msg(
1717 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1718 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1719 (uint64_t)pMemRanges[i].memory, __LINE__,
1720 MEMTRACK_INVALID_MAP, "MEM", "Memory overflow was "
1721 "detected on mem obj "
1722 "%" PRIxLEAST64,
1723 (uint64_t)pMemRanges[i].memory);
Michael Lentine685f61c2015-10-29 10:41:47 -07001724 }
1725 }
1726 for (auto j = size + half_size; j < 2 * size; ++j) {
1727 if (data[j] != NoncoherentMemoryFillValue) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001728 skipCall |= log_msg(
1729 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1730 VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1731 (uint64_t)pMemRanges[i].memory, __LINE__,
1732 MEMTRACK_INVALID_MAP, "MEM", "Memory overflow was "
1733 "detected on mem obj "
1734 "%" PRIxLEAST64,
1735 (uint64_t)pMemRanges[i].memory);
Michael Lentine685f61c2015-10-29 10:41:47 -07001736 }
1737 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001738 memcpy(mem_element->second.pDriverData,
1739 static_cast<void *>(data + (size_t)(half_size)),
1740 (size_t)(size));
Michael Lentine685f61c2015-10-29 10:41:47 -07001741 }
1742 }
1743 }
1744 return skipCall;
1745}
1746
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001747VK_LAYER_EXPORT VkResult VKAPI_CALL
1748 vkFlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount,
1749 const VkMappedMemoryRange *pMemRanges) {
1750 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
1751 VkBool32 skipCall = VK_FALSE;
1752 layer_data *my_data =
1753 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Michael Lentine685f61c2015-10-29 10:41:47 -07001754
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001755 skipCall |= validateAndCopyNoncoherentMemoryToDriver(my_data, memRangeCount,
1756 pMemRanges);
1757 skipCall |= validateMemoryIsMapped(my_data, memRangeCount, pMemRanges);
1758 if (VK_FALSE == skipCall) {
1759 result = my_data->device_dispatch_table->FlushMappedMemoryRanges(
1760 device, memRangeCount, pMemRanges);
Michael Lentine685f61c2015-10-29 10:41:47 -07001761 }
1762 return result;
1763}
1764
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001765VK_LAYER_EXPORT VkResult VKAPI_CALL
1766 vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount,
1767 const VkMappedMemoryRange *pMemRanges) {
1768 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
1769 VkBool32 skipCall = VK_FALSE;
1770 layer_data *my_data =
1771 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Michael Lentine685f61c2015-10-29 10:41:47 -07001772
1773 skipCall |= validateMemoryIsMapped(my_data, memRangeCount, pMemRanges);
1774 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001775 result = my_data->device_dispatch_table->InvalidateMappedMemoryRanges(
1776 device, memRangeCount, pMemRanges);
Michael Lentine685f61c2015-10-29 10:41:47 -07001777 }
1778 return result;
Tobin Ehlis6663f492014-11-10 12:29:12 -07001779}
1780
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001781VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1782 vkDestroyFence(VkDevice device, VkFence fence,
1783 const VkAllocationCallbacks *pAllocator) {
1784 layer_data *my_data =
1785 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001786 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001787 delete_fence_info(my_data, fence);
1788 auto item = my_data->fenceMap.find(fence);
1789 if (item != my_data->fenceMap.end()) {
1790 my_data->fenceMap.erase(item);
Tobin Ehlisa98df732014-11-27 07:52:04 -07001791 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06001792 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wuf7458c52015-10-26 21:10:41 +08001793 my_data->device_dispatch_table->DestroyFence(device, fence, pAllocator);
Tobin Ehlis6663f492014-11-10 12:29:12 -07001794}
1795
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001796VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1797 vkDestroyBuffer(VkDevice device, VkBuffer buffer,
1798 const VkAllocationCallbacks *pAllocator) {
1799 layer_data *my_data =
1800 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001801 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis257d9742015-07-08 17:08:02 -06001802 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001803 auto item = my_data->bufferMap.find((uint64_t)buffer);
1804 if (item != my_data->bufferMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001805 skipCall = clear_object_binding(my_data, device, (uint64_t)buffer,
1806 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001807 my_data->bufferMap.erase(item);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001808 }
1809 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001810 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001811 my_data->device_dispatch_table->DestroyBuffer(device, buffer,
1812 pAllocator);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001813 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07001814}
1815
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001816VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1817 vkDestroyImage(VkDevice device, VkImage image,
1818 const VkAllocationCallbacks *pAllocator) {
1819 layer_data *my_data =
1820 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001821 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis257d9742015-07-08 17:08:02 -06001822 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001823 auto item = my_data->imageMap.find((uint64_t)image);
1824 if (item != my_data->imageMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001825 skipCall = clear_object_binding(my_data, device, (uint64_t)image,
1826 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Tobin Ehlis57b55082015-10-29 09:03:52 -06001827 my_data->imageMap.erase(item);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001828 }
1829 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001830 if (VK_FALSE == skipCall) {
Chia-I Wuf7458c52015-10-26 21:10:41 +08001831 my_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001832 }
Tobin Ehlis257d9742015-07-08 17:08:02 -06001833}
1834
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001835VkBool32 print_memory_range_error(layer_data *my_data,
1836 const uint64_t object_handle,
1837 const uint64_t other_handle,
1838 VkDebugReportObjectTypeEXT object_type) {
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001839 if (object_type == VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001840 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1841 object_type, object_handle, 0, MEMTRACK_INVALID_ALIASING,
1842 "MEM",
1843 "Buffer %" PRIx64 " is alised with image %" PRIx64,
1844 object_handle, other_handle);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001845 } else {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001846 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
1847 object_type, object_handle, 0, MEMTRACK_INVALID_ALIASING,
1848 "MEM",
1849 "Image %" PRIx64 " is alised with buffer %" PRIx64,
1850 object_handle, other_handle);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001851 }
1852}
1853
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001854VkBool32 validate_memory_range(
1855 layer_data *my_data,
1856 const unordered_map<VkDeviceMemory, vector<MEMORY_RANGE>> &memory,
1857 const MEMORY_RANGE &new_range, VkDebugReportObjectTypeEXT object_type) {
Mark Young2bcc2c12016-01-06 16:17:03 -07001858 VkBool32 skip_call = false;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001859 if (!memory.count(new_range.memory))
1860 return false;
1861 const vector<MEMORY_RANGE> &ranges = memory.at(new_range.memory);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001862 for (auto range : ranges) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001863 if ((range.end & ~(my_data->properties.limits.bufferImageGranularity -
1864 1)) < new_range.start)
1865 continue;
1866 if (range.start >
1867 (new_range.end &
1868 ~(my_data->properties.limits.bufferImageGranularity - 1)))
1869 continue;
1870 skip_call |= print_memory_range_error(my_data, new_range.handle,
1871 range.handle, object_type);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001872 }
1873 return skip_call;
1874}
1875
Mark Young2bcc2c12016-01-06 16:17:03 -07001876VkBool32 validate_buffer_image_aliasing(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001877 layer_data *my_data, uint64_t handle, VkDeviceMemory mem,
1878 VkDeviceSize memoryOffset, VkMemoryRequirements memRequirements,
1879 unordered_map<VkDeviceMemory, vector<MEMORY_RANGE>> &ranges,
1880 const unordered_map<VkDeviceMemory, vector<MEMORY_RANGE>> &other_ranges,
1881 VkDebugReportObjectTypeEXT object_type) {
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001882 MEMORY_RANGE range;
1883 range.handle = handle;
1884 range.memory = mem;
1885 range.start = memoryOffset;
1886 range.end = memoryOffset + memRequirements.size - 1;
1887 ranges[mem].push_back(range);
1888 return validate_memory_range(my_data, other_ranges, range, object_type);
1889}
1890
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001891VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1892 vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem,
1893 VkDeviceSize memoryOffset) {
1894 layer_data *my_data =
1895 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001896 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mike Stroyanb050c682015-04-17 12:36:38 -06001897 loader_platform_thread_lock_mutex(&globalLock);
1898 // Track objects tied to memory
Mark Young93ecb1d2016-01-13 13:47:16 -07001899 uint64_t buffer_handle = (uint64_t)(buffer);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001900 VkBool32 skipCall = set_mem_binding(my_data, device, mem, buffer_handle,
1901 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
1902 "vkBindBufferMemory");
1903 add_object_binding_info(my_data, buffer_handle,
1904 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, mem);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001905 {
1906 VkMemoryRequirements memRequirements;
1907 vkGetBufferMemoryRequirements(device, buffer, &memRequirements);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001908 skipCall |= validate_buffer_image_aliasing(
1909 my_data, buffer_handle, mem, memoryOffset, memRequirements,
1910 my_data->bufferRanges, my_data->imageRanges,
1911 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001912 }
Tobin Ehlis57b55082015-10-29 09:03:52 -06001913 print_mem_list(my_data, device);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001914 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001915 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001916 result = my_data->device_dispatch_table->BindBufferMemory(
1917 device, buffer, mem, memoryOffset);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001918 }
Tobin Ehlis257d9742015-07-08 17:08:02 -06001919 return result;
1920}
1921
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001922VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1923 vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem,
1924 VkDeviceSize memoryOffset) {
1925 layer_data *my_data =
1926 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001927 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis257d9742015-07-08 17:08:02 -06001928 loader_platform_thread_lock_mutex(&globalLock);
1929 // Track objects tied to memory
Mark Young93ecb1d2016-01-13 13:47:16 -07001930 uint64_t image_handle = (uint64_t)(image);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001931 VkBool32 skipCall = set_mem_binding(my_data, device, mem, image_handle,
1932 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
1933 "vkBindImageMemory");
1934 add_object_binding_info(my_data, image_handle,
1935 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, mem);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001936 {
1937 VkMemoryRequirements memRequirements;
1938 vkGetImageMemoryRequirements(device, image, &memRequirements);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001939 skipCall |= validate_buffer_image_aliasing(
1940 my_data, image_handle, mem, memoryOffset, memRequirements,
1941 my_data->imageRanges, my_data->bufferRanges,
1942 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Michael Lentine85bb2ef2015-12-22 17:30:09 -06001943 }
Tobin Ehlis57b55082015-10-29 09:03:52 -06001944 print_mem_list(my_data, device);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001945 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001946 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001947 result = my_data->device_dispatch_table->BindImageMemory(
1948 device, image, mem, memoryOffset);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06001949 }
Tobin Ehlis257d9742015-07-08 17:08:02 -06001950 return result;
1951}
1952
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001953VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1954 vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer,
1955 VkMemoryRequirements *pMemoryRequirements) {
1956 layer_data *my_data =
1957 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001958 // TODO : What to track here?
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001959 // Could potentially save returned mem requirements and validate values
1960 // passed into BindBufferMemory
1961 my_data->device_dispatch_table->GetBufferMemoryRequirements(
1962 device, buffer, pMemoryRequirements);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001963}
1964
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001965VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
1966 vkGetImageMemoryRequirements(VkDevice device, VkImage image,
1967 VkMemoryRequirements *pMemoryRequirements) {
1968 layer_data *my_data =
1969 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001970 // TODO : What to track here?
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001971 // Could potentially save returned mem requirements and validate values
1972 // passed into BindImageMemory
1973 my_data->device_dispatch_table->GetImageMemoryRequirements(
1974 device, image, pMemoryRequirements);
Tobin Ehlis257d9742015-07-08 17:08:02 -06001975}
1976
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001977VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
1978 vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount,
1979 const VkBindSparseInfo *pBindInfo, VkFence fence) {
1980 layer_data *my_data =
1981 get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07001982 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08001983 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis257d9742015-07-08 17:08:02 -06001984
Tobin Ehlis257d9742015-07-08 17:08:02 -06001985 loader_platform_thread_lock_mutex(&globalLock);
Mike Stroyanb050c682015-04-17 12:36:38 -06001986
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08001987 for (uint32_t i = 0; i < bindInfoCount; i++) {
1988 // Track objects tied to memory
1989 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07001990 for (uint32_t k = 0; k < pBindInfo[i].pBufferBinds[j].bindCount;
1991 k++) {
1992 if (set_sparse_mem_binding(
1993 my_data, queue,
1994 pBindInfo[i].pBufferBinds[j].pBinds[k].memory,
1995 (uint64_t)pBindInfo[i].pBufferBinds[j].buffer,
1996 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
1997 "vkQueueBindSparse"))
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08001998 skipCall = VK_TRUE;
1999 }
2000 }
2001 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002002 for (uint32_t k = 0;
2003 k < pBindInfo[i].pImageOpaqueBinds[j].bindCount; k++) {
2004 if (set_sparse_mem_binding(
2005 my_data, queue,
2006 pBindInfo[i].pImageOpaqueBinds[j].pBinds[k].memory,
2007 (uint64_t)pBindInfo[i].pImageOpaqueBinds[j].image,
2008 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
2009 "vkQueueBindSparse"))
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08002010 skipCall = VK_TRUE;
2011 }
2012 }
2013 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002014 for (uint32_t k = 0; k < pBindInfo[i].pImageBinds[j].bindCount;
2015 k++) {
2016 if (set_sparse_mem_binding(
2017 my_data, queue,
2018 pBindInfo[i].pImageBinds[j].pBinds[k].memory,
2019 (uint64_t)pBindInfo[i].pImageBinds[j].image,
2020 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
2021 "vkQueueBindSparse"))
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08002022 skipCall = VK_TRUE;
2023 }
2024 }
2025 }
2026
Tobin Ehlis57b55082015-10-29 09:03:52 -06002027 print_mem_list(my_data, queue);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002028 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002029 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002030 result = my_data->device_dispatch_table->QueueBindSparse(
2031 queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002032 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002033 return result;
2034}
2035
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002036VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2037 vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo,
2038 const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
2039 layer_data *my_data =
2040 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2041 VkResult result = my_data->device_dispatch_table->CreateFence(
2042 device, pCreateInfo, pAllocator, pFence);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002043 if (VK_SUCCESS == result) {
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002044 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002045 MT_FENCE_INFO *pFI = &my_data->fenceMap[*pFence];
Tobin Ehlis257d9742015-07-08 17:08:02 -06002046 memset(pFI, 0, sizeof(MT_FENCE_INFO));
2047 memcpy(&(pFI->createInfo), pCreateInfo, sizeof(VkFenceCreateInfo));
Mark Lobodzinski6fd65922016-01-05 16:38:09 -07002048 if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
2049 pFI->firstTimeFlag = VK_TRUE;
2050 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002051 loader_platform_thread_unlock_mutex(&globalLock);
2052 }
2053 return result;
2054}
2055
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002056VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2057 vkResetFences(VkDevice device, uint32_t fenceCount,
2058 const VkFence *pFences) {
2059 layer_data *my_data =
2060 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2061 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002062 VkBool32 skipCall = VK_FALSE;
2063
2064 loader_platform_thread_lock_mutex(&globalLock);
2065 // Reset fence state in fenceCreateInfo structure
2066 for (uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlis57b55082015-10-29 09:03:52 -06002067 auto fence_item = my_data->fenceMap.find(pFences[i]);
2068 if (fence_item != my_data->fenceMap.end()) {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002069 // Validate fences in SIGNALED state
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002070 if (!(fence_item->second.createInfo.flags &
2071 VK_FENCE_CREATE_SIGNALED_BIT)) {
2072 // TODO: I don't see a Valid Usage section for ResetFences. This
2073 // behavior should be documented there.
2074 skipCall = log_msg(
2075 my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
2076 VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t)pFences[i],
2077 __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
2078 "Fence %#" PRIxLEAST64
2079 " submitted to VkResetFences in UNSIGNALED STATE",
2080 (uint64_t)pFences[i]);
2081 } else {
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002082 fence_item->second.createInfo.flags =
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002083 static_cast<VkFenceCreateFlags>(
2084 fence_item->second.createInfo.flags &
2085 ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski148e1582015-04-07 16:07:57 -05002086 }
2087 }
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002088 }
2089 loader_platform_thread_unlock_mutex(&globalLock);
2090 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002091 result = my_data->device_dispatch_table->ResetFences(device, fenceCount,
2092 pFences);
Mark Lobodzinski148e1582015-04-07 16:07:57 -05002093 }
2094 return result;
2095}
2096
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002097static inline VkBool32 verifyFenceStatus(VkDevice device, VkFence fence,
2098 const char *apiCall) {
2099 layer_data *my_data =
2100 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlisc4f105d2015-09-14 13:25:57 -06002101 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis57b55082015-10-29 09:03:52 -06002102 auto pFenceInfo = my_data->fenceMap.find(fence);
2103 if (pFenceInfo != my_data->fenceMap.end()) {
Mark Lobodzinski6fd65922016-01-05 16:38:09 -07002104 if (pFenceInfo->second.firstTimeFlag != VK_TRUE) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002105 if ((pFenceInfo->second.createInfo.flags &
2106 VK_FENCE_CREATE_SIGNALED_BIT) &&
2107 pFenceInfo->second.firstTimeFlag != VK_TRUE) {
2108 skipCall |= log_msg(
2109 my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT,
2110 VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t)fence,
2111 __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
2112 "%s specified fence %#" PRIxLEAST64
2113 " already in SIGNALED state.",
2114 apiCall, (uint64_t)fence);
Mark Lobodzinski6fd65922016-01-05 16:38:09 -07002115 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002116 if (!pFenceInfo->second
2117 .queue) { // Checking status of unsubmitted fence
2118 skipCall |= log_msg(
2119 my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
2120 VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t)fence,
2121 __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM",
2122 "%s called for fence %#" PRIxLEAST64
2123 " which has not been submitted on a Queue.",
2124 apiCall, (uint64_t)fence);
Mark Lobodzinski6fd65922016-01-05 16:38:09 -07002125 }
2126 } else {
2127 pFenceInfo->second.firstTimeFlag = VK_FALSE;
Tobin Ehlisc4f105d2015-09-14 13:25:57 -06002128 }
2129 }
2130 return skipCall;
2131}
2132
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002133VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2134 vkGetFenceStatus(VkDevice device, VkFence fence) {
2135 layer_data *my_data =
2136 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlisc4f105d2015-09-14 13:25:57 -06002137 VkBool32 skipCall = verifyFenceStatus(device, fence, "vkGetFenceStatus");
2138 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07002139 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002140 VkResult result =
2141 my_data->device_dispatch_table->GetFenceStatus(device, fence);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002142 if (VK_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002143 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06002144 update_fence_tracking(my_data, fence);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002145 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002146 }
2147 return result;
2148}
2149
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002150VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2151 vkWaitForFences(VkDevice device, uint32_t fenceCount,
2152 const VkFence *pFences, VkBool32 waitAll,
2153 uint64_t timeout) {
2154 layer_data *my_data =
2155 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlisc4f105d2015-09-14 13:25:57 -06002156 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski148e1582015-04-07 16:07:57 -05002157 // Verify fence status of submitted fences
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002158 for (uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlisc4f105d2015-09-14 13:25:57 -06002159 skipCall |= verifyFenceStatus(device, pFences[i], "vkWaitForFences");
Mark Lobodzinski148e1582015-04-07 16:07:57 -05002160 }
Tobin Ehlisc4f105d2015-09-14 13:25:57 -06002161 if (skipCall)
Courtney Goeltzenleuchter52fee652015-12-10 16:41:22 -07002162 return VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002163 VkResult result = my_data->device_dispatch_table->WaitForFences(
2164 device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002165 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski50932972015-04-02 20:49:09 -05002166
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002167 if (VK_SUCCESS == result) {
Mark Lobodzinski50932972015-04-02 20:49:09 -05002168 if (waitAll || fenceCount == 1) { // Clear all the fences
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002169 for (uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlis57b55082015-10-29 09:03:52 -06002170 update_fence_tracking(my_data, pFences[i]);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002171 }
2172 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002173 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002174 loader_platform_thread_unlock_mutex(&globalLock);
2175 return result;
2176}
2177
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002178VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue) {
2179 layer_data *my_data =
2180 get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Tobin Ehliscdd73272015-10-28 16:25:11 -06002181 VkResult result = my_data->device_dispatch_table->QueueWaitIdle(queue);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002182 if (VK_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002183 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06002184 retire_queue_fences(my_data, queue);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002185 loader_platform_thread_unlock_mutex(&globalLock);
2186 }
2187 return result;
2188}
2189
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002190VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2191 vkDeviceWaitIdle(VkDevice device) {
2192 layer_data *my_data =
2193 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehliscdd73272015-10-28 16:25:11 -06002194 VkResult result = my_data->device_dispatch_table->DeviceWaitIdle(device);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002195 if (VK_SUCCESS == result) {
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002196 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06002197 retire_device_fences(my_data, device);
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05002198 loader_platform_thread_unlock_mutex(&globalLock);
2199 }
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002200 return result;
2201}
2202
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002203VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2204 vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
2205 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
2206 layer_data *my_data =
2207 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2208 VkResult result = my_data->device_dispatch_table->CreateBuffer(
2209 device, pCreateInfo, pAllocator, pBuffer);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002210 if (VK_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002211 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002212 add_object_create_info(my_data, (uint64_t)*pBuffer,
2213 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
2214 pCreateInfo);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002215 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic52b7752015-02-18 16:38:17 -06002216 }
Tobin Ehlis7265e832015-01-19 08:42:29 -07002217 return result;
2218}
2219
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002220VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2221 vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
2222 const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
2223 layer_data *my_data =
2224 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2225 VkResult result = my_data->device_dispatch_table->CreateImage(
2226 device, pCreateInfo, pAllocator, pImage);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002227 if (VK_SUCCESS == result) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002228 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002229 add_object_create_info(my_data, (uint64_t)*pImage,
2230 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
2231 pCreateInfo);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002232 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07002233 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002234 return result;
2235}
2236
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002237VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2238 vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
2239 const VkAllocationCallbacks *pAllocator,
2240 VkImageView *pView) {
2241 layer_data *my_data =
2242 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2243 VkResult result = my_data->device_dispatch_table->CreateImageView(
2244 device, pCreateInfo, pAllocator, pView);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002245 if (result == VK_SUCCESS) {
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002246 loader_platform_thread_lock_mutex(&globalLock);
Michael Lentine80d51872015-11-24 17:55:33 -06002247 my_data->imageViewMap[*pView].image = pCreateInfo->image;
Tobin Ehlis41376e12015-07-03 08:45:14 -06002248 // Validate that img has correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002249 validate_image_usage_flags(
2250 my_data, device, pCreateInfo->image,
2251 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
2252 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
2253 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
2254 VK_FALSE, "vkCreateImageView()",
2255 "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT]_BIT");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002256 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis8be20fd2015-01-07 17:49:29 -07002257 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002258 return result;
2259}
2260
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002261VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2262 vkCreateBufferView(VkDevice device,
2263 const VkBufferViewCreateInfo *pCreateInfo,
2264 const VkAllocationCallbacks *pAllocator,
2265 VkBufferView *pView) {
2266 layer_data *my_data =
2267 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2268 VkResult result = my_data->device_dispatch_table->CreateBufferView(
2269 device, pCreateInfo, pAllocator, pView);
Mark Lobodzinski50b51e62015-10-27 09:53:00 -06002270 if (result == VK_SUCCESS) {
2271 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002272 // In order to create a valid buffer view, the buffer must have been
2273 // created with at least one of the
2274 // following flags: UNIFORM_TEXEL_BUFFER_BIT or
2275 // STORAGE_TEXEL_BUFFER_BIT
2276 validate_buffer_usage_flags(
2277 my_data, device, pCreateInfo->buffer,
2278 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
2279 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
2280 VK_FALSE, "vkCreateBufferView()",
2281 "VK_BUFFER_USAGE_[STORAGE|UNIFORM]_TEXEL_BUFFER_BIT");
Mark Lobodzinski50b51e62015-10-27 09:53:00 -06002282 loader_platform_thread_unlock_mutex(&globalLock);
2283 }
2284 return result;
2285}
2286
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002287VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2288 vkAllocateCommandBuffers(VkDevice device,
2289 const VkCommandBufferAllocateInfo *pCreateInfo,
2290 VkCommandBuffer *pCommandBuffer) {
2291 layer_data *my_data =
2292 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2293 VkResult result = my_data->device_dispatch_table->AllocateCommandBuffers(
2294 device, pCreateInfo, pCommandBuffer);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002295
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002296 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib8df78c2015-11-20 14:33:48 -07002297 if (VK_SUCCESS == result) {
Jon Ashburnf19916e2016-01-11 13:12:43 -07002298 for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002299 add_cmd_buf_info(my_data, pCreateInfo->commandPool,
2300 pCommandBuffer[i]);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002301 }
2302 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002303 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskib8df78c2015-11-20 14:33:48 -07002304 printCBList(my_data, device);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002305 return result;
2306}
2307
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002308VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2309 vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2310 uint32_t commandBufferCount,
2311 const VkCommandBuffer *pCommandBuffers) {
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002312 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002313 layer_data *my_data =
2314 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002315
2316 loader_platform_thread_lock_mutex(&globalLock);
2317 for (uint32_t i = 0; i < commandBufferCount; i++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002318 skipCall |=
2319 delete_cmd_buf_info(my_data, commandPool, pCommandBuffers[i]);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002320 }
2321 printCBList(my_data, device);
2322 loader_platform_thread_unlock_mutex(&globalLock);
2323
2324 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002325 my_data->device_dispatch_table->FreeCommandBuffers(
2326 device, commandPool, commandBufferCount, pCommandBuffers);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002327 }
2328}
2329
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002330VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2331 vkCreateCommandPool(VkDevice device,
2332 const VkCommandPoolCreateInfo *pCreateInfo,
2333 const VkAllocationCallbacks *pAllocator,
2334 VkCommandPool *pCommandPool) {
2335 layer_data *my_data =
2336 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2337 VkResult result = my_data->device_dispatch_table->CreateCommandPool(
2338 device, pCreateInfo, pAllocator, pCommandPool);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002339
2340 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskie2f93cb2015-11-19 08:31:31 -07002341
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002342 // Add cmd pool to map
2343 my_data->commandPoolMap[*pCommandPool].createFlags = pCreateInfo->flags;
2344 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskie2f93cb2015-11-19 08:31:31 -07002345
2346 return result;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002347}
2348
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002349VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2350 vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool,
2351 const VkAllocationCallbacks *pAllocator) {
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002352 VkBool32 commandBufferComplete = VK_FALSE;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002353 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002354 // Verify that command buffers in pool are complete (not in-flight)
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002355 layer_data *my_data =
2356 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002357 for (auto it = my_data->commandPoolMap[commandPool].pCommandBuffers.begin();
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002358 it != my_data->commandPoolMap[commandPool].pCommandBuffers.end();
2359 it++) {
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002360 commandBufferComplete = VK_FALSE;
2361 skipCall = checkCBCompleted(my_data, *it, &commandBufferComplete);
2362 if (VK_FALSE == commandBufferComplete) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002363 skipCall |= log_msg(
2364 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2365 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)(*it),
2366 __LINE__, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM",
2367 "Destroying Command Pool 0x%" PRIxLEAST64 " before "
2368 "its command buffer (0x%" PRIxLEAST64 ") has completed.",
2369 (uint64_t)(commandPool), reinterpret_cast<uint64_t>(*it));
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002370 }
2371 }
2372
2373 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002374 my_data->device_dispatch_table->DestroyCommandPool(device, commandPool,
2375 pAllocator);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002376 }
2377
Mark Lobodzinskib8df78c2015-11-20 14:33:48 -07002378 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002379 auto item = my_data->commandPoolMap[commandPool].pCommandBuffers.begin();
2380 // Remove command buffers from command buffer map
2381 while (item != my_data->commandPoolMap[commandPool].pCommandBuffers.end()) {
2382 auto del_item = item++;
2383 delete_cmd_buf_info(my_data, commandPool, *del_item);
2384 }
2385 my_data->commandPoolMap.erase(commandPool);
Mark Lobodzinskib8df78c2015-11-20 14:33:48 -07002386 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002387}
2388
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002389VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2390 vkResetCommandPool(VkDevice device, VkCommandPool commandPool,
2391 VkCommandPoolResetFlags flags) {
2392 layer_data *my_data =
2393 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2394 VkBool32 commandBufferComplete = VK_FALSE;
2395 VkBool32 skipCall = VK_FALSE;
2396 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002397
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002398 auto it = my_data->commandPoolMap[commandPool].pCommandBuffers.begin();
2399 // Verify that CB's in pool are complete (not in-flight)
2400 while (it != my_data->commandPoolMap[commandPool].pCommandBuffers.end()) {
2401 skipCall = checkCBCompleted(my_data, (*it), &commandBufferComplete);
2402 if (VK_FALSE == commandBufferComplete) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002403 skipCall |= log_msg(
2404 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2405 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)(*it),
2406 __LINE__, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM",
2407 "Resetting CB %p before it has completed. You must check CB "
2408 "flag before calling vkResetCommandBuffer().",
2409 (*it));
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002410 } else {
Mark Lobodzinskib8df78c2015-11-20 14:33:48 -07002411 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002412 // Clear memory references at this point.
2413 skipCall |= clear_cmd_buf_and_mem_references(my_data, (*it));
Mark Lobodzinskib8df78c2015-11-20 14:33:48 -07002414 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002415 }
Tobin Ehlisac0ef842015-12-14 13:46:38 -07002416 ++it;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002417 }
Mark Lobodzinskie2f93cb2015-11-19 08:31:31 -07002418
2419 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002420 result = my_data->device_dispatch_table->ResetCommandPool(
2421 device, commandPool, flags);
Mark Lobodzinskie2f93cb2015-11-19 08:31:31 -07002422 }
2423
2424 return result;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002425}
2426
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002427VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2428 vkBeginCommandBuffer(VkCommandBuffer commandBuffer,
2429 const VkCommandBufferBeginInfo *pBeginInfo) {
2430 layer_data *my_data =
2431 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
2432 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
2433 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002434 VkBool32 commandBufferComplete = VK_FALSE;
Mike Stroyan950496e2015-05-19 15:16:08 -06002435 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002436
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002437 // This implicitly resets the Cmd Buffer so make sure any fence is done and
2438 // then clear memory references
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002439 skipCall = checkCBCompleted(my_data, commandBuffer, &commandBufferComplete);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002440
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002441 if (VK_FALSE == commandBufferComplete) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002442 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2443 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2444 (uint64_t)commandBuffer, __LINE__,
2445 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM",
2446 "Calling vkBeginCommandBuffer() on active CB %p "
2447 "before it has completed. "
2448 "You must check CB flag before this call.",
2449 commandBuffer);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002450 }
Mike Stroyan950496e2015-05-19 15:16:08 -06002451 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002452 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002453 result = my_data->device_dispatch_table->BeginCommandBuffer(
2454 commandBuffer, pBeginInfo);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002455 }
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002456 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002457 clear_cmd_buf_and_mem_references(my_data, commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002458 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002459 return result;
2460}
2461
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002462VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2463 vkEndCommandBuffer(VkCommandBuffer commandBuffer) {
2464 layer_data *my_data =
2465 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002466 // TODO : Anything to do here?
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002467 VkResult result =
2468 my_data->device_dispatch_table->EndCommandBuffer(commandBuffer);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002469 return result;
2470}
2471
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002472VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
2473 vkResetCommandBuffer(VkCommandBuffer commandBuffer,
2474 VkCommandBufferResetFlags flags) {
2475 layer_data *my_data =
2476 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
2477 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
2478 VkBool32 skipCall = VK_FALSE;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002479 VkBool32 commandBufferComplete = VK_FALSE;
Mike Stroyan950496e2015-05-19 15:16:08 -06002480 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002481
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002482 // Verify that CB is complete (not in-flight)
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002483 skipCall = checkCBCompleted(my_data, commandBuffer, &commandBufferComplete);
2484 if (VK_FALSE == commandBufferComplete) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002485 skipCall |= log_msg(
2486 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2487 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2488 (uint64_t)commandBuffer, __LINE__,
2489 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM",
2490 "Resetting CB %p before it has completed. You must check CB "
2491 "flag before calling vkResetCommandBuffer().",
2492 commandBuffer);
Tobin Ehlisc9dbcd52015-03-04 08:38:22 -07002493 }
2494 // Clear memory references as this point.
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002495 skipCall |= clear_cmd_buf_and_mem_references(my_data, commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002496 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002497 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002498 result = my_data->device_dispatch_table->ResetCommandBuffer(
2499 commandBuffer, flags);
Courtney Goeltzenleuchter06640832015-09-04 13:52:24 -06002500 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002501 return result;
2502}
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07002503
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002504// TODO : For any vkCmdBind* calls that include an object which has mem bound to
2505// it,
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002506// need to account for that mem now having binding to given commandBuffer
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002507VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2508 vkCmdBindPipeline(VkCommandBuffer commandBuffer,
2509 VkPipelineBindPoint pipelineBindPoint,
2510 VkPipeline pipeline) {
2511 layer_data *my_data =
2512 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tobin Ehlisc145be82015-01-08 15:22:32 -07002513#if 0
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002514 // TODO : If memory bound to pipeline, then need to tie that mem to commandBuffer
Tobin Ehlisc145be82015-01-08 15:22:32 -07002515 if (getPipeline(pipeline)) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +08002516 MT_CB_INFO *pCBInfo = get_cmd_buf_info(my_data, commandBuffer);
Mark Lobodzinski6434eff2015-03-31 16:05:35 -05002517 if (pCBInfo) {
2518 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlisc145be82015-01-08 15:22:32 -07002519 }
2520 }
2521 else {
Courtney Goeltzenleuchterb9f0bf32015-06-14 09:50:18 -06002522 "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Mark Lobodzinskiebd34662016-01-04 13:43:45 -07002523 layerCbMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, pipeline, __LINE__, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlisc145be82015-01-08 15:22:32 -07002524 }
2525#endif
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002526 my_data->device_dispatch_table->CmdBindPipeline(
2527 commandBuffer, pipelineBindPoint, pipeline);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002528}
2529
Chia-I Wu9ab61502015-11-06 06:42:02 +08002530VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002531 VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
2532 VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount,
2533 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
2534 const uint32_t *pDynamicOffsets) {
2535 layer_data *my_data =
2536 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
2537 // TODO : Somewhere need to verify that all textures referenced by shaders
2538 // in DS are in some type of *SHADER_READ* state
Tobin Ehliscdd73272015-10-28 16:25:11 -06002539 my_data->device_dispatch_table->CmdBindDescriptorSets(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002540 commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
2541 pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002542}
2543
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002544VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2545 vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding,
2546 uint32_t bindingCount, const VkBuffer *pBuffers,
2547 const VkDeviceSize *pOffsets) {
2548 layer_data *my_data =
2549 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Youngad779052016-01-06 14:26:04 -07002550 VkBool32 skip_call = false;
2551 for (uint32_t i = 0; i < bindingCount; ++i) {
Michael Lentine80d51872015-11-24 17:55:33 -06002552 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002553 skip_call |= get_mem_binding_from_object(
2554 my_data, commandBuffer, (uint64_t)(pBuffers[i]),
Michael Lentine80d51872015-11-24 17:55:33 -06002555 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002556 auto cb_data = my_data->cbMap.find(commandBuffer);
2557 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002558 std::function<VkBool32()> function = [=]() {
2559 return validate_memory_is_valid(my_data, mem,
2560 "vkCmdBindVertexBuffers()");
2561 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002562 cb_data->second.validate_functions.push_back(function);
2563 }
Michael Lentine80d51872015-11-24 17:55:33 -06002564 }
Tobin Ehlis257d9742015-07-08 17:08:02 -06002565 // TODO : Somewhere need to verify that VBs have correct usage state flagged
Michael Lentine80d51872015-11-24 17:55:33 -06002566 if (!skip_call)
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002567 my_data->device_dispatch_table->CmdBindVertexBuffers(
2568 commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wu19156822015-01-05 13:42:56 +08002569}
2570
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002571VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2572 vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer,
2573 VkDeviceSize offset, VkIndexType indexType) {
2574 layer_data *my_data =
2575 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Michael Lentine80d51872015-11-24 17:55:33 -06002576 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002577 VkBool32 skip_call = get_mem_binding_from_object(
2578 my_data, commandBuffer, (uint64_t)(buffer),
2579 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002580 auto cb_data = my_data->cbMap.find(commandBuffer);
2581 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002582 std::function<VkBool32()> function = [=]() {
2583 return validate_memory_is_valid(my_data, mem,
2584 "vkCmdBindIndexBuffer()");
2585 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002586 cb_data->second.validate_functions.push_back(function);
2587 }
Tobin Ehlis257d9742015-07-08 17:08:02 -06002588 // TODO : Somewhere need to verify that IBs have correct usage state flagged
Michael Lentine80d51872015-11-24 17:55:33 -06002589 if (!skip_call)
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002590 my_data->device_dispatch_table->CmdBindIndexBuffer(
2591 commandBuffer, buffer, offset, indexType);
Tobin Ehlis6663f492014-11-10 12:29:12 -07002592}
2593
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002594VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2595 vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2596 VkDeviceSize offset, uint32_t count, uint32_t stride) {
2597 layer_data *my_data =
2598 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002599 VkDeviceMemory mem;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002600 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002601 VkBool32 skipCall = get_mem_binding_from_object(
2602 my_data, commandBuffer, (uint64_t)buffer,
2603 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
2604 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2605 "vkCmdDrawIndirect");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002606 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002607 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002608 my_data->device_dispatch_table->CmdDrawIndirect(commandBuffer, buffer,
2609 offset, count, stride);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002610 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002611}
2612
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002613VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2614 vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2615 VkDeviceSize offset, uint32_t count,
2616 uint32_t stride) {
2617 layer_data *my_data =
2618 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002619 VkDeviceMemory mem;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002620 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002621 VkBool32 skipCall = get_mem_binding_from_object(
2622 my_data, commandBuffer, (uint64_t)buffer,
2623 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
2624 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2625 "vkCmdDrawIndexedIndirect");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002626 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002627 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002628 my_data->device_dispatch_table->CmdDrawIndexedIndirect(
2629 commandBuffer, buffer, offset, count, stride);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002630 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002631}
2632
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002633VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2634 vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2635 VkDeviceSize offset) {
2636 layer_data *my_data =
2637 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002638 VkDeviceMemory mem;
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002639 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002640 VkBool32 skipCall = get_mem_binding_from_object(
2641 my_data, commandBuffer, (uint64_t)buffer,
2642 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
2643 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2644 "vkCmdDispatchIndirect");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002645 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002646 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002647 my_data->device_dispatch_table->CmdDispatchIndirect(commandBuffer,
2648 buffer, offset);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002649 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002650}
2651
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002652VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2653 vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
2654 VkBuffer dstBuffer, uint32_t regionCount,
2655 const VkBufferCopy *pRegions) {
2656 layer_data *my_data =
2657 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002658 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002659 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002660 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002661 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002662 skipCall = get_mem_binding_from_object(
2663 my_data, commandBuffer, (uint64_t)srcBuffer,
2664 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002665 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002666 std::function<VkBool32()> function = [=]() {
2667 return validate_memory_is_valid(my_data, mem, "vkCmdCopyBuffer()");
2668 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002669 cb_data->second.validate_functions.push_back(function);
2670 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002671 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2672 "vkCmdCopyBuffer");
2673 skipCall |= get_mem_binding_from_object(
2674 my_data, commandBuffer, (uint64_t)dstBuffer,
2675 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002676 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002677 std::function<VkBool32()> function = [=]() {
2678 set_memory_valid(my_data, mem, true);
2679 return VK_FALSE;
2680 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002681 cb_data->second.validate_functions.push_back(function);
2682 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002683 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2684 "vkCmdCopyBuffer");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002685 // Validate that SRC & DST buffers have correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002686 skipCall |= validate_buffer_usage_flags(
2687 my_data, commandBuffer, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
2688 true, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
2689 skipCall |= validate_buffer_usage_flags(
2690 my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2691 true, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002692 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002693 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002694 my_data->device_dispatch_table->CmdCopyBuffer(
2695 commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002696 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002697}
2698
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002699VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2700 vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,
2701 VkQueryPool queryPool, uint32_t firstQuery,
2702 uint32_t queryCount, VkBuffer dstBuffer,
2703 VkDeviceSize dstOffset, VkDeviceSize destStride,
2704 VkQueryResultFlags flags) {
2705 layer_data *my_data =
2706 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyan2ed39272015-10-15 08:42:32 -06002707 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002708 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002709 auto cb_data = my_data->cbMap.find(commandBuffer);
Mike Stroyan2ed39272015-10-15 08:42:32 -06002710 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002711 skipCall |= get_mem_binding_from_object(
2712 my_data, commandBuffer, (uint64_t)dstBuffer,
2713 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002714 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002715 std::function<VkBool32()> function = [=]() {
2716 set_memory_valid(my_data, mem, true);
2717 return VK_FALSE;
2718 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002719 cb_data->second.validate_functions.push_back(function);
2720 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002721 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2722 "vkCmdCopyQueryPoolResults");
Mike Stroyan2ed39272015-10-15 08:42:32 -06002723 // Validate that DST buffer has correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002724 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, dstBuffer,
2725 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2726 true, "vkCmdCopyQueryPoolResults()",
2727 "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mike Stroyan2ed39272015-10-15 08:42:32 -06002728 loader_platform_thread_unlock_mutex(&globalLock);
2729 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002730 my_data->device_dispatch_table->CmdCopyQueryPoolResults(
2731 commandBuffer, queryPool, firstQuery, queryCount, dstBuffer,
2732 dstOffset, destStride, flags);
Mike Stroyan2ed39272015-10-15 08:42:32 -06002733 }
2734}
2735
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002736VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2737 vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2738 VkImageLayout srcImageLayout, VkImage dstImage,
2739 VkImageLayout dstImageLayout, uint32_t regionCount,
2740 const VkImageCopy *pRegions) {
2741 layer_data *my_data =
2742 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002743 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002744 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002745 auto cb_data = my_data->cbMap.find(commandBuffer);
Tobin Ehlis41376e12015-07-03 08:45:14 -06002746 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41376e12015-07-03 08:45:14 -06002747 // Validate that src & dst images have correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002748 skipCall = get_mem_binding_from_object(
2749 my_data, commandBuffer, (uint64_t)srcImage,
2750 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002751 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002752 std::function<VkBool32()> function = [=]() {
2753 return validate_memory_is_valid(my_data, mem, "vkCmdCopyImage()",
2754 srcImage);
2755 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002756 cb_data->second.validate_functions.push_back(function);
2757 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002758 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2759 "vkCmdCopyImage");
2760 skipCall |= get_mem_binding_from_object(
2761 my_data, commandBuffer, (uint64_t)dstImage,
2762 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002763 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002764 std::function<VkBool32()> function = [=]() {
2765 set_memory_valid(my_data, mem, true, dstImage);
2766 return VK_FALSE;
2767 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002768 cb_data->second.validate_functions.push_back(function);
2769 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002770 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2771 "vkCmdCopyImage");
2772 skipCall |= validate_image_usage_flags(
2773 my_data, commandBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
2774 "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
2775 skipCall |= validate_image_usage_flags(
2776 my_data, commandBuffer, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
2777 "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002778 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002779 if (VK_FALSE == skipCall) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06002780 my_data->device_dispatch_table->CmdCopyImage(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002781 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
2782 regionCount, pRegions);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002783 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002784}
2785
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002786VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2787 vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2788 VkImageLayout srcImageLayout, VkImage dstImage,
2789 VkImageLayout dstImageLayout, uint32_t regionCount,
2790 const VkImageBlit *pRegions, VkFilter filter) {
2791 layer_data *my_data =
2792 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002793 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002794 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002795 auto cb_data = my_data->cbMap.find(commandBuffer);
Tobin Ehlis41376e12015-07-03 08:45:14 -06002796 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis41376e12015-07-03 08:45:14 -06002797 // Validate that src & dst images have correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002798 skipCall = get_mem_binding_from_object(
2799 my_data, commandBuffer, (uint64_t)srcImage,
2800 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002801 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002802 std::function<VkBool32()> function = [=]() {
2803 return validate_memory_is_valid(my_data, mem, "vkCmdBlitImage()",
2804 srcImage);
2805 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002806 cb_data->second.validate_functions.push_back(function);
2807 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002808 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2809 "vkCmdBlitImage");
2810 skipCall |= get_mem_binding_from_object(
2811 my_data, commandBuffer, (uint64_t)dstImage,
2812 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002813 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002814 std::function<VkBool32()> function = [=]() {
2815 set_memory_valid(my_data, mem, true, dstImage);
2816 return VK_FALSE;
2817 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002818 cb_data->second.validate_functions.push_back(function);
2819 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002820 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2821 "vkCmdBlitImage");
2822 skipCall |= validate_image_usage_flags(
2823 my_data, commandBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
2824 "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
2825 skipCall |= validate_image_usage_flags(
2826 my_data, commandBuffer, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
2827 "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002828 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002829 if (VK_FALSE == skipCall) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06002830 my_data->device_dispatch_table->CmdBlitImage(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002831 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
2832 regionCount, pRegions, filter);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002833 }
Courtney Goeltzenleuchter89299fa2015-03-08 17:02:18 -06002834}
2835
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002836VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2837 vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
2838 VkImage dstImage, VkImageLayout dstImageLayout,
2839 uint32_t regionCount,
2840 const VkBufferImageCopy *pRegions) {
2841 layer_data *my_data =
2842 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002843 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002844 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002845 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002846 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002847 skipCall = get_mem_binding_from_object(
2848 my_data, commandBuffer, (uint64_t)dstImage,
2849 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002850 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002851 std::function<VkBool32()> function = [=]() {
2852 set_memory_valid(my_data, mem, true, dstImage);
2853 return VK_FALSE;
2854 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002855 cb_data->second.validate_functions.push_back(function);
2856 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002857 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2858 "vkCmdCopyBufferToImage");
2859 skipCall |= get_mem_binding_from_object(
2860 my_data, commandBuffer, (uint64_t)srcBuffer,
2861 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002862 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002863 std::function<VkBool32()> function = [=]() {
2864 return validate_memory_is_valid(my_data, mem,
2865 "vkCmdCopyBufferToImage()");
2866 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002867 cb_data->second.validate_functions.push_back(function);
2868 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002869 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2870 "vkCmdCopyBufferToImage");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002871 // Validate that src buff & dst image have correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002872 skipCall |= validate_buffer_usage_flags(
2873 my_data, commandBuffer, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
2874 true, "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
2875 skipCall |= validate_image_usage_flags(
2876 my_data, commandBuffer, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
2877 "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002878 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002879 if (VK_FALSE == skipCall) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06002880 my_data->device_dispatch_table->CmdCopyBufferToImage(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002881 commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount,
2882 pRegions);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002883 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002884}
2885
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002886VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2887 vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
2888 VkImageLayout srcImageLayout, VkBuffer dstBuffer,
2889 uint32_t regionCount,
2890 const VkBufferImageCopy *pRegions) {
2891 layer_data *my_data =
2892 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002893 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002894 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002895 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002896 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002897 skipCall = get_mem_binding_from_object(
2898 my_data, commandBuffer, (uint64_t)srcImage,
2899 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002900 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002901 std::function<VkBool32()> function = [=]() {
2902 return validate_memory_is_valid(
2903 my_data, mem, "vkCmdCopyImageToBuffer()", srcImage);
2904 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002905 cb_data->second.validate_functions.push_back(function);
2906 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002907 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2908 "vkCmdCopyImageToBuffer");
2909 skipCall |= get_mem_binding_from_object(
2910 my_data, commandBuffer, (uint64_t)dstBuffer,
2911 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002912 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002913 std::function<VkBool32()> function = [=]() {
2914 set_memory_valid(my_data, mem, true);
2915 return VK_FALSE;
2916 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002917 cb_data->second.validate_functions.push_back(function);
2918 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002919 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2920 "vkCmdCopyImageToBuffer");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002921 // Validate that dst buff & src image have correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002922 skipCall |= validate_image_usage_flags(
2923 my_data, commandBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
2924 "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
2925 skipCall |= validate_buffer_usage_flags(
2926 my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2927 true, "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002928 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002929 if (VK_FALSE == skipCall) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06002930 my_data->device_dispatch_table->CmdCopyImageToBuffer(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002931 commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount,
2932 pRegions);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002933 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002934}
2935
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002936VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2937 vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2938 VkDeviceSize dstOffset, VkDeviceSize dataSize,
2939 const uint32_t *pData) {
2940 layer_data *my_data =
2941 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002942 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002943 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002944 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002945 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002946 skipCall = get_mem_binding_from_object(
2947 my_data, commandBuffer, (uint64_t)dstBuffer,
2948 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002949 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002950 std::function<VkBool32()> function = [=]() {
2951 set_memory_valid(my_data, mem, true);
2952 return VK_FALSE;
2953 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002954 cb_data->second.validate_functions.push_back(function);
2955 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002956 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2957 "vkCmdUpdateBuffer");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002958 // Validate that dst buff has correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002959 skipCall |= validate_buffer_usage_flags(
2960 my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2961 true, "vkCmdUpdateBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002962 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002963 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002964 my_data->device_dispatch_table->CmdUpdateBuffer(
2965 commandBuffer, dstBuffer, dstOffset, dataSize, pData);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002966 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002967}
2968
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002969VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
2970 vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2971 VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
2972 layer_data *my_data =
2973 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002974 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002975 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06002976 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002977 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002978 skipCall = get_mem_binding_from_object(
2979 my_data, commandBuffer, (uint64_t)dstBuffer,
2980 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06002981 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002982 std::function<VkBool32()> function = [=]() {
2983 set_memory_valid(my_data, mem, true);
2984 return VK_FALSE;
2985 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06002986 cb_data->second.validate_functions.push_back(function);
2987 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002988 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
2989 "vkCmdFillBuffer");
Tobin Ehlis41376e12015-07-03 08:45:14 -06002990 // Validate that dst buff has correct usage flags set
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002991 skipCall |= validate_buffer_usage_flags(
2992 my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
2993 true, "vkCmdFillBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06002994 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002995 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07002996 my_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer,
2997 dstOffset, size, data);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06002998 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07002999}
3000
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003001VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3002 vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
3003 VkImageLayout imageLayout,
3004 const VkClearColorValue *pColor, uint32_t rangeCount,
3005 const VkImageSubresourceRange *pRanges) {
3006 layer_data *my_data =
3007 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003008 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003009 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003010 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06003011 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06003012 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003013 skipCall = get_mem_binding_from_object(
3014 my_data, commandBuffer, (uint64_t)image,
3015 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06003016 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003017 std::function<VkBool32()> function = [=]() {
3018 set_memory_valid(my_data, mem, true, image);
3019 return VK_FALSE;
3020 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003021 cb_data->second.validate_functions.push_back(function);
3022 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003023 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
3024 "vkCmdClearColorImage");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06003025 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003026 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003027 my_data->device_dispatch_table->CmdClearColorImage(
3028 commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003029 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07003030}
3031
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003032VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3033 vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image,
3034 VkImageLayout imageLayout,
3035 const VkClearDepthStencilValue *pDepthStencil,
3036 uint32_t rangeCount,
3037 const VkImageSubresourceRange *pRanges) {
3038 layer_data *my_data =
3039 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003040 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003041 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003042 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06003043 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06003044 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003045 skipCall = get_mem_binding_from_object(
3046 my_data, commandBuffer, (uint64_t)image,
3047 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06003048 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003049 std::function<VkBool32()> function = [=]() {
3050 set_memory_valid(my_data, mem, true, image);
3051 return VK_FALSE;
3052 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003053 cb_data->second.validate_functions.push_back(function);
3054 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003055 skipCall |= update_cmd_buf_and_mem_references(
3056 my_data, commandBuffer, mem, "vkCmdClearDepthStencilImage");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06003057 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003058 if (VK_FALSE == skipCall) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06003059 my_data->device_dispatch_table->CmdClearDepthStencilImage(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003060 commandBuffer, image, imageLayout, pDepthStencil, rangeCount,
3061 pRanges);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003062 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07003063}
3064
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003065VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3066 vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage,
3067 VkImageLayout srcImageLayout, VkImage dstImage,
3068 VkImageLayout dstImageLayout, uint32_t regionCount,
3069 const VkImageResolve *pRegions) {
3070 layer_data *my_data =
3071 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003072 VkBool32 skipCall = VK_FALSE;
Michael Lentine1e171aa2016-01-06 19:17:59 -06003073 auto cb_data = my_data->cbMap.find(commandBuffer);
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06003074 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003075 VkDeviceMemory mem;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003076 skipCall = get_mem_binding_from_object(
3077 my_data, commandBuffer, (uint64_t)srcImage,
3078 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06003079 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003080 std::function<VkBool32()> function = [=]() {
3081 return validate_memory_is_valid(my_data, mem, "vkCmdResolveImage()",
3082 srcImage);
3083 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003084 cb_data->second.validate_functions.push_back(function);
3085 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003086 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
3087 "vkCmdResolveImage");
3088 skipCall |= get_mem_binding_from_object(
3089 my_data, commandBuffer, (uint64_t)dstImage,
3090 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine1e171aa2016-01-06 19:17:59 -06003091 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003092 std::function<VkBool32()> function = [=]() {
3093 set_memory_valid(my_data, mem, true, dstImage);
3094 return VK_FALSE;
3095 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003096 cb_data->second.validate_functions.push_back(function);
3097 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003098 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem,
3099 "vkCmdResolveImage");
Mark Lobodzinski93f494b2015-03-02 20:23:52 -06003100 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003101 if (VK_FALSE == skipCall) {
Tobin Ehliscdd73272015-10-28 16:25:11 -06003102 my_data->device_dispatch_table->CmdResolveImage(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003103 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
3104 regionCount, pRegions);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003105 }
Tobin Ehlis6663f492014-11-10 12:29:12 -07003106}
3107
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003108VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3109 vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3110 uint32_t slot, VkFlags flags) {
3111 layer_data *my_data =
3112 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
3113 my_data->device_dispatch_table->CmdBeginQuery(commandBuffer, queryPool,
3114 slot, flags);
Tobin Ehlis6663f492014-11-10 12:29:12 -07003115}
3116
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003117VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3118 vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3119 uint32_t slot) {
3120 layer_data *my_data =
3121 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Chia-I Wu3432a0c2015-10-27 18:04:07 +08003122 my_data->device_dispatch_table->CmdEndQuery(commandBuffer, queryPool, slot);
Tobin Ehlis6663f492014-11-10 12:29:12 -07003123}
3124
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003125VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3126 vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool,
3127 uint32_t firstQuery, uint32_t queryCount) {
3128 layer_data *my_data =
3129 get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
3130 my_data->device_dispatch_table->CmdResetQueryPool(commandBuffer, queryPool,
3131 firstQuery, queryCount);
Tobin Ehlis6663f492014-11-10 12:29:12 -07003132}
3133
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07003134VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003135 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
3136 const VkAllocationCallbacks *pAllocator,
3137 VkDebugReportCallbackEXT *pMsgCallback) {
3138 layer_data *my_data =
3139 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehliscdd73272015-10-28 16:25:11 -06003140 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003141 VkResult res = pTable->CreateDebugReportCallbackEXT(
3142 instance, pCreateInfo, pAllocator, pMsgCallback);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -06003143 if (res == VK_SUCCESS) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003144 res = layer_create_msg_callback(my_data->report_data, pCreateInfo,
3145 pAllocator, pMsgCallback);
Courtney Goeltzenleuchtere45acec2015-06-14 12:03:26 -06003146 }
3147 return res;
Tobin Ehlis6663f492014-11-10 12:29:12 -07003148}
3149
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003150VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3151 vkDestroyDebugReportCallbackEXT(VkInstance instance,
3152 VkDebugReportCallbackEXT msgCallback,
3153 const VkAllocationCallbacks *pAllocator) {
3154 layer_data *my_data =
3155 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehliscdd73272015-10-28 16:25:11 -06003156 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07003157 pTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -07003158 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Tobin Ehlis6663f492014-11-10 12:29:12 -07003159}
3160
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003161VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3162 vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
3163 VkDebugReportObjectTypeEXT objType, uint64_t object,
3164 size_t location, int32_t msgCode,
3165 const char *pLayerPrefix, const char *pMsg) {
3166 layer_data *my_data =
3167 get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
3168 my_data->instance_dispatch_table->DebugReportMessageEXT(
3169 instance, flags, objType, object, location, msgCode, pLayerPrefix,
3170 pMsg);
Courtney Goeltzenleuchterf0de7242015-12-01 14:10:55 -07003171}
3172
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003173VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3174 vkCreateSwapchainKHR(VkDevice device,
3175 const VkSwapchainCreateInfoKHR *pCreateInfo,
3176 const VkAllocationCallbacks *pAllocator,
3177 VkSwapchainKHR *pSwapchain) {
3178 layer_data *my_data =
3179 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
3180 VkResult result = my_data->device_dispatch_table->CreateSwapchainKHR(
3181 device, pCreateInfo, pAllocator, pSwapchain);
Chia-I Wuf8693382015-04-16 22:02:10 +08003182
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003183 if (VK_SUCCESS == result) {
Chia-I Wuf8693382015-04-16 22:02:10 +08003184 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06003185 add_swap_chain_info(my_data, *pSwapchain, pCreateInfo);
Chia-I Wuf8693382015-04-16 22:02:10 +08003186 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehliscd9223b2014-11-19 16:19:28 -07003187 }
Chia-I Wuf8693382015-04-16 22:02:10 +08003188
Tobin Ehlis6663f492014-11-10 12:29:12 -07003189 return result;
3190}
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05003191
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003192VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3193 vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
3194 const VkAllocationCallbacks *pAllocator) {
3195 layer_data *my_data =
3196 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003197 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05003198 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06003199 if (my_data->swapchainMap.find(swapchain) != my_data->swapchainMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003200 MT_SWAP_CHAIN_INFO *pInfo = my_data->swapchainMap[swapchain];
Chia-I Wuf8693382015-04-16 22:02:10 +08003201
David Pinedod8f83d82015-04-27 16:36:17 -06003202 if (pInfo->images.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003203 for (auto it = pInfo->images.begin(); it != pInfo->images.end();
3204 it++) {
3205 skipCall = clear_object_binding(
3206 my_data, device, (uint64_t)*it,
3207 VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
Tobin Ehlis57b55082015-10-29 09:03:52 -06003208 auto image_item = my_data->imageMap.find((uint64_t)*it);
3209 if (image_item != my_data->imageMap.end())
3210 my_data->imageMap.erase(image_item);
David Pinedod8f83d82015-04-27 16:36:17 -06003211 }
Chia-I Wuf8693382015-04-16 22:02:10 +08003212 }
Chia-I Wuf8693382015-04-16 22:02:10 +08003213 delete pInfo;
Tobin Ehlis57b55082015-10-29 09:03:52 -06003214 my_data->swapchainMap.erase(swapchain);
Chia-I Wuf8693382015-04-16 22:02:10 +08003215 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05003216 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003217 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003218 my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain,
3219 pAllocator);
Mark Lobodzinski5fcc4212015-09-14 17:43:42 -06003220 }
Chia-I Wuf8693382015-04-16 22:02:10 +08003221}
3222
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003223VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3224 vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
3225 uint32_t *pCount, VkImage *pSwapchainImages) {
3226 layer_data *my_data =
3227 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
3228 VkResult result = my_data->device_dispatch_table->GetSwapchainImagesKHR(
3229 device, swapchain, pCount, pSwapchainImages);
Chia-I Wuf8693382015-04-16 22:02:10 +08003230
Ian Elliott7e40db92015-08-21 15:09:33 -06003231 if (result == VK_SUCCESS && pSwapchainImages != NULL) {
Ian Elliott2b6b68a2015-08-07 14:11:14 -06003232 const size_t count = *pCount;
Tobin Ehlis57b55082015-10-29 09:03:52 -06003233 MT_SWAP_CHAIN_INFO *pInfo = my_data->swapchainMap[swapchain];
Chia-I Wuf8693382015-04-16 22:02:10 +08003234
3235 if (pInfo->images.empty()) {
3236 pInfo->images.resize(count);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003237 memcpy(&pInfo->images[0], pSwapchainImages,
3238 sizeof(pInfo->images[0]) * count);
Chia-I Wuf8693382015-04-16 22:02:10 +08003239
David Pinedod8f83d82015-04-27 16:36:17 -06003240 if (pInfo->images.size() > 0) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003241 for (std::vector<VkImage>::const_iterator it =
3242 pInfo->images.begin();
David Pinedod8f83d82015-04-27 16:36:17 -06003243 it != pInfo->images.end(); it++) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003244 // Add image object binding, then insert the new Mem Object
3245 // and then bind it to created image
3246 add_object_create_info(
3247 my_data, (uint64_t)*it,
3248 VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
3249 &pInfo->createInfo);
Chia-I Wuf8693382015-04-16 22:02:10 +08003250 }
3251 }
3252 } else {
Ian Elliott2b6b68a2015-08-07 14:11:14 -06003253 const size_t count = *pCount;
Tobin Ehlis57b55082015-10-29 09:03:52 -06003254 MT_SWAP_CHAIN_INFO *pInfo = my_data->swapchainMap[swapchain];
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003255 const VkBool32 mismatch =
3256 (pInfo->images.size() != count ||
3257 memcmp(&pInfo->images[0], pSwapchainImages,
3258 sizeof(pInfo->images[0]) * count));
Chia-I Wuf8693382015-04-16 22:02:10 +08003259
3260 if (mismatch) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -07003261 // TODO: Verify against Valid Usage section of extension
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003262 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT,
3263 VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
3264 (uint64_t)swapchain, __LINE__, MEMTRACK_NONE,
3265 "SWAP_CHAIN",
3266 "vkGetSwapchainInfoKHR(%" PRIu64
3267 ", VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_KHR) "
3268 "returned mismatching data",
3269 (uint64_t)(swapchain));
Chia-I Wuf8693382015-04-16 22:02:10 +08003270 }
3271 }
3272 }
Mark Lobodzinskie61ebe72015-03-17 10:53:12 -05003273 return result;
3274}
Tobin Ehlis6663f492014-11-10 12:29:12 -07003275
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003276VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3277 vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
3278 uint64_t timeout, VkSemaphore semaphore,
3279 VkFence fence, uint32_t *pImageIndex) {
3280 layer_data *my_data =
3281 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
3282 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003283 VkBool32 skipCall = VK_FALSE;
3284
3285 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06003286 if (my_data->semaphoreMap.find(semaphore) != my_data->semaphoreMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003287 if (my_data->semaphoreMap[semaphore] !=
3288 MEMTRACK_SEMAPHORE_STATE_UNSET) {
3289 skipCall = log_msg(
3290 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3291 VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, (uint64_t)semaphore,
3292 __LINE__, MEMTRACK_NONE, "SEMAPHORE",
3293 "vkAcquireNextImageKHR: Semaphore must not be currently "
3294 "signaled or in a wait state");
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003295 }
Tobin Ehlis57b55082015-10-29 09:03:52 -06003296 my_data->semaphoreMap[semaphore] = MEMTRACK_SEMAPHORE_STATE_SIGNALLED;
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003297 }
3298 loader_platform_thread_unlock_mutex(&globalLock);
3299 if (VK_FALSE == skipCall) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003300 result = my_data->device_dispatch_table->AcquireNextImageKHR(
3301 device, swapchain, timeout, semaphore, fence, pImageIndex);
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003302 }
3303 return result;
3304}
3305
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003306VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3307 vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003308 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003309 layer_data *my_data =
3310 get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Mark Youngad779052016-01-06 14:26:04 -07003311 VkBool32 skip_call = false;
Michael Lentine80d51872015-11-24 17:55:33 -06003312 VkDeviceMemory mem;
Mark Youngad779052016-01-06 14:26:04 -07003313 for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003314 MT_SWAP_CHAIN_INFO *pInfo =
3315 my_data->swapchainMap[pPresentInfo->pSwapchains[i]];
Michael Lentine80d51872015-11-24 17:55:33 -06003316 VkImage image = pInfo->images[pPresentInfo->pImageIndices[i]];
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003317 skip_call |= get_mem_binding_from_object(
3318 my_data, queue, (uint64_t)(image),
3319 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
3320 skip_call |= validate_memory_is_valid(my_data, mem,
3321 "vkQueuePresentKHR()", image);
Michael Lentine80d51872015-11-24 17:55:33 -06003322 }
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003323 if (!skip_call) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003324 result = my_data->device_dispatch_table->QueuePresentKHR(queue,
3325 pPresentInfo);
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003326 }
Mark Lobodzinskibedae9c2016-01-19 16:27:27 -07003327
3328 loader_platform_thread_lock_mutex(&globalLock);
3329 for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; i++) {
3330 VkSemaphore sem = pPresentInfo->pWaitSemaphores[i];
3331 if (my_data->semaphoreMap.find(sem) != my_data->semaphoreMap.end()) {
3332 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_UNSET;
3333 }
3334 }
3335 loader_platform_thread_unlock_mutex(&globalLock);
3336
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003337 return result;
Michael Lentine80d51872015-11-24 17:55:33 -06003338}
3339
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003340VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3341 vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
3342 const VkAllocationCallbacks *pAllocator,
3343 VkSemaphore *pSemaphore) {
3344 layer_data *my_data =
3345 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
3346 VkResult result = my_data->device_dispatch_table->CreateSemaphore(
3347 device, pCreateInfo, pAllocator, pSemaphore);
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003348 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wue2fc5522015-10-26 20:04:44 +08003349 if (*pSemaphore != VK_NULL_HANDLE) {
Tobin Ehlis57b55082015-10-29 09:03:52 -06003350 my_data->semaphoreMap[*pSemaphore] = MEMTRACK_SEMAPHORE_STATE_UNSET;
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003351 }
3352 loader_platform_thread_unlock_mutex(&globalLock);
3353 return result;
3354}
3355
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003356VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3357 vkDestroySemaphore(VkDevice device, VkSemaphore semaphore,
3358 const VkAllocationCallbacks *pAllocator) {
3359 layer_data *my_data =
3360 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003361 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis57b55082015-10-29 09:03:52 -06003362 auto item = my_data->semaphoreMap.find(semaphore);
3363 if (item != my_data->semaphoreMap.end()) {
3364 my_data->semaphoreMap.erase(item);
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003365 }
3366 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003367 my_data->device_dispatch_table->DestroySemaphore(device, semaphore,
3368 pAllocator);
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003369}
3370
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003371VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3372 vkCreateFramebuffer(VkDevice device,
3373 const VkFramebufferCreateInfo *pCreateInfo,
3374 const VkAllocationCallbacks *pAllocator,
3375 VkFramebuffer *pFramebuffer) {
3376 layer_data *my_data =
3377 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
3378 VkResult result = my_data->device_dispatch_table->CreateFramebuffer(
3379 device, pCreateInfo, pAllocator, pFramebuffer);
Mark Youngad779052016-01-06 14:26:04 -07003380 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Michael Lentine80d51872015-11-24 17:55:33 -06003381 VkImageView view = pCreateInfo->pAttachments[i];
3382 loader_platform_thread_lock_mutex(&globalLock);
3383 auto view_data = my_data->imageViewMap.find(view);
3384 if (view_data == my_data->imageViewMap.end()) {
3385 loader_platform_thread_unlock_mutex(&globalLock);
3386 continue;
3387 }
3388 MT_FB_ATTACHMENT_INFO fb_info;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003389 get_mem_binding_from_object(
3390 my_data, device, (uint64_t)(view_data->second.image),
3391 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &fb_info.mem);
Michael Lentine80d51872015-11-24 17:55:33 -06003392 fb_info.image = view_data->second.image;
3393 my_data->fbMap[*pFramebuffer].attachments.push_back(fb_info);
3394 loader_platform_thread_unlock_mutex(&globalLock);
3395 }
3396 return result;
3397}
3398
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003399VKAPI_ATTR void VKAPI_CALL
3400 vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer,
3401 const VkAllocationCallbacks *pAllocator) {
3402 layer_data *my_data =
3403 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003404
3405 auto item = my_data->fbMap.find(framebuffer);
3406 loader_platform_thread_lock_mutex(&globalLock);
3407 if (item != my_data->fbMap.end()) {
3408 my_data->fbMap.erase(framebuffer);
3409 }
3410 loader_platform_thread_unlock_mutex(&globalLock);
3411
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003412 my_data->device_dispatch_table->DestroyFramebuffer(device, framebuffer,
3413 pAllocator);
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003414}
3415
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003416VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
3417 vkCreateRenderPass(VkDevice device,
3418 const VkRenderPassCreateInfo *pCreateInfo,
3419 const VkAllocationCallbacks *pAllocator,
3420 VkRenderPass *pRenderPass) {
3421 layer_data *my_data =
3422 get_my_data_ptr(get_dispatch_key(device), layer_data_map);
3423 VkResult result = my_data->device_dispatch_table->CreateRenderPass(
3424 device, pCreateInfo, pAllocator, pRenderPass);
Mark Youngad779052016-01-06 14:26:04 -07003425 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
Michael Lentine80d51872015-11-24 17:55:33 -06003426 VkAttachmentDescription desc = pCreateInfo->pAttachments[i];
3427 MT_PASS_ATTACHMENT_INFO pass_info;
3428 pass_info.load_op = desc.loadOp;
3429 pass_info.store_op = desc.storeOp;
Michael Lentineb4979492015-12-22 11:36:14 -06003430 pass_info.attachment = i;
Michael Lentine80d51872015-11-24 17:55:33 -06003431 loader_platform_thread_lock_mutex(&globalLock);
3432 my_data->passMap[*pRenderPass].attachments.push_back(pass_info);
3433 loader_platform_thread_unlock_mutex(&globalLock);
3434 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003435 // TODO: Maybe fill list and then copy instead of locking
Michael Lentineb4979492015-12-22 11:36:14 -06003436 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003437 std::unordered_map<uint32_t, bool> &attachment_first_read =
3438 my_data->passMap[*pRenderPass].attachment_first_read;
3439 std::unordered_map<uint32_t, VkImageLayout> &attachment_first_layout =
3440 my_data->passMap[*pRenderPass].attachment_first_layout;
Michael Lentineb4979492015-12-22 11:36:14 -06003441 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003442 const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
Michael Lentineb4979492015-12-22 11:36:14 -06003443 for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
3444 uint32_t attachment = subpass.pInputAttachments[j].attachment;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003445 if (attachment_first_read.count(attachment))
3446 continue;
Michael Lentineb4979492015-12-22 11:36:14 -06003447 attachment_first_read.insert(std::make_pair(attachment, true));
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003448 attachment_first_layout.insert(std::make_pair(
3449 attachment, subpass.pInputAttachments[j].layout));
Michael Lentineb4979492015-12-22 11:36:14 -06003450 }
3451 for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
3452 uint32_t attachment = subpass.pColorAttachments[j].attachment;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003453 if (attachment_first_read.count(attachment))
3454 continue;
Michael Lentineb4979492015-12-22 11:36:14 -06003455 attachment_first_read.insert(std::make_pair(attachment, false));
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003456 attachment_first_layout.insert(std::make_pair(
3457 attachment, subpass.pColorAttachments[j].layout));
Michael Lentineb4979492015-12-22 11:36:14 -06003458 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003459 if (subpass.pDepthStencilAttachment &&
3460 subpass.pDepthStencilAttachment->attachment !=
3461 VK_ATTACHMENT_UNUSED) {
Michael Lentineb4979492015-12-22 11:36:14 -06003462 uint32_t attachment = subpass.pDepthStencilAttachment->attachment;
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003463 if (attachment_first_read.count(attachment))
3464 continue;
Michael Lentineb4979492015-12-22 11:36:14 -06003465 attachment_first_read.insert(std::make_pair(attachment, false));
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003466 attachment_first_layout.insert(std::make_pair(
3467 attachment, subpass.pDepthStencilAttachment->layout));
Michael Lentineb4979492015-12-22 11:36:14 -06003468 }
3469 }
3470 loader_platform_thread_unlock_mutex(&globalLock);
3471
Michael Lentine80d51872015-11-24 17:55:33 -06003472 return result;
3473}
3474
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003475VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3476 vkCmdBeginRenderPass(VkCommandBuffer cmdBuffer,
3477 const VkRenderPassBeginInfo *pRenderPassBegin,
3478 VkSubpassContents contents) {
3479 layer_data *my_data =
3480 get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Mark Youngad779052016-01-06 14:26:04 -07003481 VkBool32 skip_call = false;
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003482 if (pRenderPassBegin) {
3483 loader_platform_thread_lock_mutex(&globalLock);
3484 auto pass_data = my_data->passMap.find(pRenderPassBegin->renderPass);
3485 if (pass_data != my_data->passMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003486 MT_PASS_INFO &pass_info = pass_data->second;
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003487 pass_info.fb = pRenderPassBegin->framebuffer;
Michael Lentine1e171aa2016-01-06 19:17:59 -06003488 auto cb_data = my_data->cbMap.find(cmdBuffer);
Mark Young93ecb1d2016-01-13 13:47:16 -07003489 for (size_t i = 0; i < pass_info.attachments.size(); ++i) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003490 MT_FB_ATTACHMENT_INFO &fb_info =
3491 my_data->fbMap[pass_info.fb].attachments[i];
3492 if (pass_info.attachments[i].load_op ==
3493 VK_ATTACHMENT_LOAD_OP_CLEAR) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06003494 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003495 std::function<VkBool32()> function = [=]() {
3496 set_memory_valid(my_data, fb_info.mem, true,
3497 fb_info.image);
3498 return VK_FALSE;
3499 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003500 cb_data->second.validate_functions.push_back(function);
3501 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003502 VkImageLayout &attachment_layout =
3503 pass_info.attachment_first_layout
3504 [pass_info.attachments[i].attachment];
3505 if (attachment_layout ==
3506 VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL ||
3507 attachment_layout ==
3508 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
3509 skip_call |= log_msg(
3510 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
3511 VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
3512 (uint64_t)(pRenderPassBegin->renderPass), __LINE__,
3513 MEMTRACK_INVALID_LAYOUT, "MEM",
3514 "Cannot clear attachment %d with invalid first "
3515 "layout %d.",
3516 pass_info.attachments[i].attachment,
3517 attachment_layout);
Michael Lentinea4c95d92015-12-28 10:17:32 -06003518 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003519 } else if (pass_info.attachments[i].load_op ==
3520 VK_ATTACHMENT_LOAD_OP_DONT_CARE) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06003521 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003522 std::function<VkBool32()> function = [=]() {
3523 set_memory_valid(my_data, fb_info.mem, false,
3524 fb_info.image);
3525 return VK_FALSE;
3526 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003527 cb_data->second.validate_functions.push_back(function);
3528 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003529 } else if (pass_info.attachments[i].load_op ==
3530 VK_ATTACHMENT_LOAD_OP_LOAD) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06003531 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003532 std::function<VkBool32()> function = [=]() {
3533 return validate_memory_is_valid(
3534 my_data, fb_info.mem, "vkCmdBeginRenderPass()",
3535 fb_info.image);
3536 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003537 cb_data->second.validate_functions.push_back(function);
3538 }
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003539 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003540 if (pass_info.attachment_first_read[pass_info.attachments[i]
3541 .attachment]) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06003542 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003543 std::function<VkBool32()> function = [=]() {
3544 return validate_memory_is_valid(
3545 my_data, fb_info.mem, "vkCmdBeginRenderPass()",
3546 fb_info.image);
3547 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003548 cb_data->second.validate_functions.push_back(function);
3549 }
Michael Lentineb4979492015-12-22 11:36:14 -06003550 }
Michael Lentine80d51872015-11-24 17:55:33 -06003551 }
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003552 if (cb_data != my_data->cbMap.end()) {
3553 cb_data->second.pass = pRenderPassBegin->renderPass;
3554 }
Michael Lentine80d51872015-11-24 17:55:33 -06003555 }
3556 loader_platform_thread_unlock_mutex(&globalLock);
3557 }
3558 if (!skip_call)
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003559 return my_data->device_dispatch_table->CmdBeginRenderPass(
3560 cmdBuffer, pRenderPassBegin, contents);
Michael Lentine80d51872015-11-24 17:55:33 -06003561}
3562
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003563VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL
3564 vkCmdEndRenderPass(VkCommandBuffer cmdBuffer) {
3565 layer_data *my_data =
3566 get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Michael Lentine80d51872015-11-24 17:55:33 -06003567 auto cb_data = my_data->cbMap.find(cmdBuffer);
3568 if (cb_data != my_data->cbMap.end()) {
3569 auto pass_data = my_data->passMap.find(cb_data->second.pass);
3570 if (pass_data != my_data->passMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003571 MT_PASS_INFO &pass_info = pass_data->second;
Mark Young93ecb1d2016-01-13 13:47:16 -07003572 for (size_t i = 0; i < pass_info.attachments.size(); ++i) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003573 MT_FB_ATTACHMENT_INFO &fb_info =
3574 my_data->fbMap[pass_info.fb].attachments[i];
3575 if (pass_info.attachments[i].store_op ==
3576 VK_ATTACHMENT_STORE_OP_STORE) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06003577 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003578 std::function<VkBool32()> function = [=]() {
3579 set_memory_valid(my_data, fb_info.mem, true,
3580 fb_info.image);
3581 return VK_FALSE;
3582 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003583 cb_data->second.validate_functions.push_back(function);
3584 }
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003585 } else if (pass_info.attachments[i].store_op ==
3586 VK_ATTACHMENT_STORE_OP_DONT_CARE) {
Michael Lentine1e171aa2016-01-06 19:17:59 -06003587 if (cb_data != my_data->cbMap.end()) {
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003588 std::function<VkBool32()> function = [=]() {
3589 set_memory_valid(my_data, fb_info.mem, false,
3590 fb_info.image);
3591 return VK_FALSE;
3592 };
Michael Lentine1e171aa2016-01-06 19:17:59 -06003593 cb_data->second.validate_functions.push_back(function);
3594 }
Michael Lentine80d51872015-11-24 17:55:33 -06003595 }
3596 }
3597 }
3598 }
3599 my_data->device_dispatch_table->CmdEndRenderPass(cmdBuffer);
3600}
3601
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003602VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
3603 vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003604 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003605 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003606 if (!strcmp(funcName, "vkDestroyDevice"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003607 return (PFN_vkVoidFunction)vkDestroyDevice;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003608 if (!strcmp(funcName, "vkQueueSubmit"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003609 return (PFN_vkVoidFunction)vkQueueSubmit;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08003610 if (!strcmp(funcName, "vkAllocateMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003611 return (PFN_vkVoidFunction)vkAllocateMemory;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003612 if (!strcmp(funcName, "vkFreeMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003613 return (PFN_vkVoidFunction)vkFreeMemory;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003614 if (!strcmp(funcName, "vkMapMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003615 return (PFN_vkVoidFunction)vkMapMemory;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003616 if (!strcmp(funcName, "vkUnmapMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003617 return (PFN_vkVoidFunction)vkUnmapMemory;
Michael Lentine685f61c2015-10-29 10:41:47 -07003618 if (!strcmp(funcName, "vkFlushMappedMemoryRanges"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003619 return (PFN_vkVoidFunction)vkFlushMappedMemoryRanges;
Michael Lentine685f61c2015-10-29 10:41:47 -07003620 if (!strcmp(funcName, "vkInvalidateMappedMemoryRanges"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003621 return (PFN_vkVoidFunction)vkInvalidateMappedMemoryRanges;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003622 if (!strcmp(funcName, "vkDestroyFence"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003623 return (PFN_vkVoidFunction)vkDestroyFence;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003624 if (!strcmp(funcName, "vkDestroyBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003625 return (PFN_vkVoidFunction)vkDestroyBuffer;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003626 if (!strcmp(funcName, "vkDestroyImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003627 return (PFN_vkVoidFunction)vkDestroyImage;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003628 if (!strcmp(funcName, "vkBindBufferMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003629 return (PFN_vkVoidFunction)vkBindBufferMemory;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003630 if (!strcmp(funcName, "vkBindImageMemory"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003631 return (PFN_vkVoidFunction)vkBindImageMemory;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003632 if (!strcmp(funcName, "vkGetBufferMemoryRequirements"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003633 return (PFN_vkVoidFunction)vkGetBufferMemoryRequirements;
Tobin Ehlis257d9742015-07-08 17:08:02 -06003634 if (!strcmp(funcName, "vkGetImageMemoryRequirements"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003635 return (PFN_vkVoidFunction)vkGetImageMemoryRequirements;
Chia-I Wu1ff4c3d2015-10-26 16:55:27 +08003636 if (!strcmp(funcName, "vkQueueBindSparse"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003637 return (PFN_vkVoidFunction)vkQueueBindSparse;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003638 if (!strcmp(funcName, "vkCreateFence"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003639 return (PFN_vkVoidFunction)vkCreateFence;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003640 if (!strcmp(funcName, "vkGetFenceStatus"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003641 return (PFN_vkVoidFunction)vkGetFenceStatus;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003642 if (!strcmp(funcName, "vkResetFences"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003643 return (PFN_vkVoidFunction)vkResetFences;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003644 if (!strcmp(funcName, "vkWaitForFences"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003645 return (PFN_vkVoidFunction)vkWaitForFences;
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003646 if (!strcmp(funcName, "vkCreateSemaphore"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003647 return (PFN_vkVoidFunction)vkCreateSemaphore;
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003648 if (!strcmp(funcName, "vkDestroySemaphore"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003649 return (PFN_vkVoidFunction)vkDestroySemaphore;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003650 if (!strcmp(funcName, "vkQueueWaitIdle"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003651 return (PFN_vkVoidFunction)vkQueueWaitIdle;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003652 if (!strcmp(funcName, "vkDeviceWaitIdle"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003653 return (PFN_vkVoidFunction)vkDeviceWaitIdle;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003654 if (!strcmp(funcName, "vkCreateBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003655 return (PFN_vkVoidFunction)vkCreateBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003656 if (!strcmp(funcName, "vkCreateImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003657 return (PFN_vkVoidFunction)vkCreateImage;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003658 if (!strcmp(funcName, "vkCreateImageView"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003659 return (PFN_vkVoidFunction)vkCreateImageView;
Mark Lobodzinski50b51e62015-10-27 09:53:00 -06003660 if (!strcmp(funcName, "vkCreateBufferView"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003661 return (PFN_vkVoidFunction)vkCreateBufferView;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08003662 if (!strcmp(funcName, "vkAllocateCommandBuffers"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003663 return (PFN_vkVoidFunction)vkAllocateCommandBuffers;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07003664 if (!strcmp(funcName, "vkFreeCommandBuffers"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003665 return (PFN_vkVoidFunction)vkFreeCommandBuffers;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07003666 if (!strcmp(funcName, "vkCreateCommandPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003667 return (PFN_vkVoidFunction)vkCreateCommandPool;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07003668 if (!strcmp(funcName, "vkDestroyCommandPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003669 return (PFN_vkVoidFunction)vkDestroyCommandPool;
Mark Lobodzinskif4945f82015-11-13 13:47:01 -07003670 if (!strcmp(funcName, "vkResetCommandPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003671 return (PFN_vkVoidFunction)vkResetCommandPool;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003672 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003673 return (PFN_vkVoidFunction)vkBeginCommandBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003674 if (!strcmp(funcName, "vkEndCommandBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003675 return (PFN_vkVoidFunction)vkEndCommandBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003676 if (!strcmp(funcName, "vkResetCommandBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003677 return (PFN_vkVoidFunction)vkResetCommandBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003678 if (!strcmp(funcName, "vkCmdBindPipeline"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003679 return (PFN_vkVoidFunction)vkCmdBindPipeline;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003680 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003681 return (PFN_vkVoidFunction)vkCmdBindDescriptorSets;
Courtney Goeltzenleuchterf68ad722015-04-16 13:38:46 -06003682 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003683 return (PFN_vkVoidFunction)vkCmdBindVertexBuffers;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003684 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003685 return (PFN_vkVoidFunction)vkCmdBindIndexBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003686 if (!strcmp(funcName, "vkCmdDrawIndirect"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003687 return (PFN_vkVoidFunction)vkCmdDrawIndirect;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003688 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003689 return (PFN_vkVoidFunction)vkCmdDrawIndexedIndirect;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003690 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
Mike Stroyan2ed39272015-10-15 08:42:32 -06003691 return (PFN_vkVoidFunction)vkCmdDispatchIndirect;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003692 if (!strcmp(funcName, "vkCmdCopyBuffer"))
Mike Stroyan2ed39272015-10-15 08:42:32 -06003693 return (PFN_vkVoidFunction)vkCmdCopyBuffer;
3694 if (!strcmp(funcName, "vkCmdCopyQueryPoolResults"))
3695 return (PFN_vkVoidFunction)vkCmdCopyQueryPoolResults;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003696 if (!strcmp(funcName, "vkCmdCopyImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003697 return (PFN_vkVoidFunction)vkCmdCopyImage;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003698 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003699 return (PFN_vkVoidFunction)vkCmdCopyBufferToImage;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003700 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003701 return (PFN_vkVoidFunction)vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003702 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003703 return (PFN_vkVoidFunction)vkCmdUpdateBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003704 if (!strcmp(funcName, "vkCmdFillBuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003705 return (PFN_vkVoidFunction)vkCmdFillBuffer;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003706 if (!strcmp(funcName, "vkCmdClearColorImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003707 return (PFN_vkVoidFunction)vkCmdClearColorImage;
Chris Forbesd9be82b2015-06-22 17:21:59 +12003708 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003709 return (PFN_vkVoidFunction)vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003710 if (!strcmp(funcName, "vkCmdResolveImage"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003711 return (PFN_vkVoidFunction)vkCmdResolveImage;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003712 if (!strcmp(funcName, "vkCmdBeginQuery"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003713 return (PFN_vkVoidFunction)vkCmdBeginQuery;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003714 if (!strcmp(funcName, "vkCmdEndQuery"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003715 return (PFN_vkVoidFunction)vkCmdEndQuery;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003716 if (!strcmp(funcName, "vkCmdResetQueryPool"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003717 return (PFN_vkVoidFunction)vkCmdResetQueryPool;
Michael Lentine80d51872015-11-24 17:55:33 -06003718 if (!strcmp(funcName, "vkCreateRenderPass"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003719 return (PFN_vkVoidFunction)vkCreateRenderPass;
Michael Lentine80d51872015-11-24 17:55:33 -06003720 if (!strcmp(funcName, "vkCmdBeginRenderPass"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003721 return (PFN_vkVoidFunction)vkCmdBeginRenderPass;
Michael Lentine80d51872015-11-24 17:55:33 -06003722 if (!strcmp(funcName, "vkCmdEndRenderPass"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003723 return (PFN_vkVoidFunction)vkCmdEndRenderPass;
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06003724 if (!strcmp(funcName, "vkGetDeviceQueue"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003725 return (PFN_vkVoidFunction)vkGetDeviceQueue;
Michael Lentine80d51872015-11-24 17:55:33 -06003726 if (!strcmp(funcName, "vkCreateFramebuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003727 return (PFN_vkVoidFunction)vkCreateFramebuffer;
Mark Lobodzinski9a4d4092015-12-18 09:24:52 -07003728 if (!strcmp(funcName, "vkDestroyFramebuffer"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003729 return (PFN_vkVoidFunction)vkDestroyFramebuffer;
Jon Ashburn747f2b62015-06-18 15:02:58 -06003730
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003731 if (dev == NULL)
3732 return NULL;
3733
3734 layer_data *my_data;
Tobin Ehliscdd73272015-10-28 16:25:11 -06003735 my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003736 if (my_data->wsi_enabled) {
Ian Elliott7e40db92015-08-21 15:09:33 -06003737 if (!strcmp(funcName, "vkCreateSwapchainKHR"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003738 return (PFN_vkVoidFunction)vkCreateSwapchainKHR;
Ian Elliott7e40db92015-08-21 15:09:33 -06003739 if (!strcmp(funcName, "vkDestroySwapchainKHR"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003740 return (PFN_vkVoidFunction)vkDestroySwapchainKHR;
Ian Elliott7e40db92015-08-21 15:09:33 -06003741 if (!strcmp(funcName, "vkGetSwapchainImagesKHR"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003742 return (PFN_vkVoidFunction)vkGetSwapchainImagesKHR;
Mark Lobodzinskib9644ee2015-10-08 10:44:07 -06003743 if (!strcmp(funcName, "vkAcquireNextImageKHR"))
3744 return (PFN_vkVoidFunction)vkAcquireNextImageKHR;
Michael Lentine80d51872015-11-24 17:55:33 -06003745 if (!strcmp(funcName, "vkQueuePresentKHR"))
3746 return (PFN_vkVoidFunction)vkQueuePresentKHR;
Jon Ashburn747f2b62015-06-18 15:02:58 -06003747 }
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06003748
Tobin Ehliscdd73272015-10-28 16:25:11 -06003749 VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
Courtney Goeltzenleuchterd54749c2015-07-05 11:17:01 -06003750 if (pDisp->GetDeviceProcAddr == NULL)
3751 return NULL;
3752 return pDisp->GetDeviceProcAddr(dev, funcName);
Jon Ashburnf6b33db2015-05-05 14:22:52 -06003753}
3754
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003755VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
3756 vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
Courtney Goeltzenleuchter2d3ba632015-07-12 14:35:22 -06003757 PFN_vkVoidFunction fptr;
Jon Ashburn8c5cbcf2015-05-07 10:27:37 -06003758
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003759 if (!strcmp(funcName, "vkGetInstanceProcAddr"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003760 return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003761 if (!strcmp(funcName, "vkGetDeviceProcAddr"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003762 return (PFN_vkVoidFunction)vkGetDeviceProcAddr;
Mark Lobodzinski76c991d2015-05-20 16:16:37 -05003763 if (!strcmp(funcName, "vkDestroyInstance"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003764 return (PFN_vkVoidFunction)vkDestroyInstance;
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06003765 if (!strcmp(funcName, "vkCreateInstance"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003766 return (PFN_vkVoidFunction)vkCreateInstance;
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -06003767 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003768 return (PFN_vkVoidFunction)vkGetPhysicalDeviceMemoryProperties;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003769 if (!strcmp(funcName, "vkCreateDevice"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003770 return (PFN_vkVoidFunction)vkCreateDevice;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06003771 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003772 return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06003773 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003774 return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06003775 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003776 return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -06003777 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003778 return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties;
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06003779
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003780 if (instance == NULL)
3781 return NULL;
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -06003782
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003783 layer_data *my_data;
3784 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
3785
3786 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003787 if (fptr)
3788 return fptr;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003789
Mark Lobodzinskib39d9e62016-02-02 17:06:29 -07003790 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchter00150eb2016-01-08 12:18:43 -07003791 if (pTable->GetInstanceProcAddr == NULL)
3792 return NULL;
3793 return pTable->GetInstanceProcAddr(instance, funcName);
Tobin Ehlis6663f492014-11-10 12:29:12 -07003794}