blob: d3e9a92a2b1e001ee4a697d7965211b440beaaa9 [file] [log] [blame]
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001/*
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002 *
Courtney Goeltzenleuchter8a17da52015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Michael Lentinebfb5fd62015-09-23 17:43:16 -07004 * Copyright (C) 2015 Google, Inc.
Tobin Ehlis791a49c2014-11-10 12:29:12 -07005 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050017* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Tobin Ehlis791a49c2014-11-10 12:29:12 -070018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060023 *
24 * Author: Cody Northrop <cody@lunarg.com>
25 * Author: Jon Ashburn <jon@lunarg.com>
26 * Author: Mark Lobodzinski <mark@lunarg.com>
27 * Author: Tobin Ehlis <tobin@lunarg.com>
Tobin Ehlis791a49c2014-11-10 12:29:12 -070028 */
29
Mark Lobodzinski4aad3642015-03-17 10:53:12 -050030#include <inttypes.h>
Tobin Ehlis791a49c2014-11-10 12:29:12 -070031#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <assert.h>
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050035#include <list>
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -050036#include <map>
Chia-I Wu5b66aa52015-04-16 22:02:10 +080037#include <vector>
Mark Lobodzinski283a4c22015-03-24 16:29:24 -050038using namespace std;
39
Tobin Ehlis7a51d902015-07-03 10:34:49 -060040#include "vk_loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060041#include "vk_dispatch_table_helper.h"
42#include "vk_struct_string_helper_cpp.h"
Tobin Ehlis62086412014-11-19 16:19:28 -070043#include "mem_tracker.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060044#include "vk_layer_config.h"
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -060045#include "vk_layer_extension_utils.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060046#include "vk_layer_table.h"
47#include "vk_layer_data.h"
48#include "vk_layer_logging.h"
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -060049static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -050050
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -060051// WSI Image Objects bypass usual Image Object creation methods. A special Memory
52// Object value will be used to identify them internally.
Chia-I Wue420a332015-10-26 20:04:44 +080053static const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY = (VkDeviceMemory)(-1);
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -060054
Cody Northrop73bb6572015-09-28 15:09:32 -060055struct layer_data {
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -070056 debug_report_data *report_data;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -070057 std::vector<VkDebugReportCallbackEXT> logging_callback;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -070058 VkLayerDispatchTable *device_dispatch_table;
59 VkLayerInstanceDispatchTable *instance_dispatch_table;
60 VkBool32 wsi_enabled;
61 uint64_t currentFenceId;
Tobin Ehlis96310ff2015-10-29 09:03:52 -060062 // Maps for tracking key structs related to MemTracker state
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -070063 unordered_map<VkCommandBuffer, MT_CB_INFO> cbMap;
64 unordered_map<VkCommandPool, MT_CMD_POOL_INFO> commandPoolMap;
65 unordered_map<VkDeviceMemory, MT_MEM_OBJ_INFO> memObjMap;
66 unordered_map<VkFence, MT_FENCE_INFO> fenceMap;
67 unordered_map<VkQueue, MT_QUEUE_INFO> queueMap;
68 unordered_map<VkSwapchainKHR, MT_SWAP_CHAIN_INFO*> swapchainMap;
69 unordered_map<VkSemaphore, MtSemaphoreState> semaphoreMap;
Michael Lentine6306a5a2015-11-24 17:55:33 -060070 unordered_map<VkFramebuffer, MT_FB_INFO> fbMap;
71 unordered_map<VkRenderPass, MT_PASS_INFO> passMap;
72 unordered_map<VkImageView, MT_IMAGE_VIEW_INFO> imageViewMap;
Tobin Ehlis96310ff2015-10-29 09:03:52 -060073 // Images and Buffers are 2 objects that can have memory bound to them so they get special treatment
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -070074 unordered_map<uint64_t, MT_OBJ_BINDING_INFO> imageMap;
75 unordered_map<uint64_t, MT_OBJ_BINDING_INFO> bufferMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060076
77 layer_data() :
78 report_data(nullptr),
Tobin Ehlis94680ea2015-10-28 16:25:11 -060079 device_dispatch_table(nullptr),
80 instance_dispatch_table(nullptr),
Michael Lentine62c60c32015-10-29 10:41:47 -070081 wsi_enabled(VK_FALSE),
Tobin Ehlis96310ff2015-10-29 09:03:52 -060082 currentFenceId(1)
Cody Northrop73bb6572015-09-28 15:09:32 -060083 {};
84};
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -050085
Tobin Ehlis92f12cd2015-07-08 17:08:02 -060086static unordered_map<void *, layer_data *> layer_data_map;
87
Mark Lobodzinski72346292015-07-02 16:49:40 -060088static VkPhysicalDeviceMemoryProperties memProps;
Jon Ashburnd9564002015-05-07 10:27:37 -060089
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -070090static VkBool32 clear_cmd_buf_and_mem_references(layer_data* my_data, const VkCommandBuffer cb);
91
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -060092// TODO : This can be much smarter, using separate locks for separate global data
93static int globalLockInitialized = 0;
94static loader_platform_thread_mutex globalLock;
Jon Ashburnf57ea372014-12-22 13:24:15 -070095
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070096#define MAX_BINDING 0xFFFFFFFF
Tobin Ehlis2836a7d2015-01-08 15:22:32 -070097
Mark Lobodzinskie90aca12015-11-19 15:45:36 -070098static MT_OBJ_BINDING_INFO*
99 get_object_binding_info(
100 layer_data *my_data,
101 uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700102 VkDebugReportObjectTypeEXT type)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600103{
104 MT_OBJ_BINDING_INFO* retValue = NULL;
105 switch (type)
106 {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700107 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600108 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600109 auto it = my_data->imageMap.find(handle);
110 if (it != my_data->imageMap.end())
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600111 return &(*it).second;
112 break;
113 }
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700114 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600115 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600116 auto it = my_data->bufferMap.find(handle);
117 if (it != my_data->bufferMap.end())
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600118 return &(*it).second;
119 break;
120 }
121 }
122 return retValue;
123}
Mark Lobodzinski15427102015-02-18 16:38:17 -0600124
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600125template layer_data *get_my_data_ptr<layer_data>(
126 void *data_key,
127 std::unordered_map<void *, layer_data *> &data_map);
128
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500129// Add new queue for this device to map container
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700130static void
131add_queue_info(
132 layer_data *my_data,
133 const VkQueue queue)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500134{
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600135 MT_QUEUE_INFO* pInfo = &my_data->queueMap[queue];
Mark Lobodzinski8ee96342015-04-02 20:49:09 -0500136 pInfo->lastRetiredId = 0;
137 pInfo->lastSubmittedId = 0;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500138}
139
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700140static void
141delete_queue_info_list(
142 layer_data* my_data)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500143{
144 // Process queue list, cleaning up each entry before deleting
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600145 my_data->queueMap.clear();
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500146}
147
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700148static void
149add_swap_chain_info(
150 layer_data *my_data,
151 const VkSwapchainKHR swapchain,
152 const VkSwapchainCreateInfoKHR *pCI)
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800153{
154 MT_SWAP_CHAIN_INFO* pInfo = new MT_SWAP_CHAIN_INFO;
Ian Elliott338dedb2015-08-21 15:09:33 -0600155 memcpy(&pInfo->createInfo, pCI, sizeof(VkSwapchainCreateInfoKHR));
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600156 my_data->swapchainMap[swapchain] = pInfo;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800157}
158
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500159// Add new CBInfo for this cb to map container
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700160static void
161add_cmd_buf_info(
162 layer_data *my_data,
163 VkCommandPool commandPool,
164 const VkCommandBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700165{
Chia-I Wu1f851912015-10-27 18:04:07 +0800166 my_data->cbMap[cb].commandBuffer = cb;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -0700167 my_data->commandPoolMap[commandPool].pCommandBuffers.push_front(cb);
168}
169
170// Delete CBInfo from container and clear mem references to CB
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700171static VkBool32
172delete_cmd_buf_info(
173 layer_data *my_data,
174 VkCommandPool commandPool,
175 const VkCommandBuffer cb)
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -0700176{
177 VkBool32 result = VK_TRUE;
178 result = clear_cmd_buf_and_mem_references(my_data, cb);
179 // Delete the CBInfo info
180 if (result == VK_TRUE) {
181 my_data->commandPoolMap[commandPool].pCommandBuffers.remove(cb);
182 my_data->cbMap.erase(cb);
183 }
184 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700185}
186
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500187// Return ptr to Info in CB map, or NULL if not found
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700188static MT_CB_INFO*
189get_cmd_buf_info(
190 layer_data *my_data,
191 const VkCommandBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700192{
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600193 auto item = my_data->cbMap.find(cb);
194 if (item != my_data->cbMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600195 return &(*item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600196 } else {
197 return NULL;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600198 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700199}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600200
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700201static void
202add_object_binding_info(
203 layer_data *my_data,
204 const uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700205 const VkDebugReportObjectTypeEXT type,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700206 const VkDeviceMemory mem)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500207{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600208 switch (type)
209 {
210 // Buffers and images are unique as their CreateInfo is in container struct
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700211 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600212 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600213 auto pCI = &my_data->bufferMap[handle];
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600214 pCI->mem = mem;
215 break;
216 }
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700217 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600218 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600219 auto pCI = &my_data->imageMap[handle];
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600220 pCI->mem = mem;
221 break;
222 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500223 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500224}
225
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700226static void
227add_object_create_info(
228 layer_data *my_data,
229 const uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700230 const VkDebugReportObjectTypeEXT type,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700231 const void *pCreateInfo)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500232{
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600233 // TODO : For any CreateInfo struct that has ptrs, need to deep copy them and appropriately clean up on Destroy
234 switch (type)
235 {
236 // Buffers and images are unique as their CreateInfo is in container struct
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700237 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600238 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600239 auto pCI = &my_data->bufferMap[handle];
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600240 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
241 memcpy(&pCI->create_info.buffer, pCreateInfo, sizeof(VkBufferCreateInfo));
242 break;
243 }
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700244 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600245 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600246 auto pCI = &my_data->imageMap[handle];
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600247 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
248 memcpy(&pCI->create_info.image, pCreateInfo, sizeof(VkImageCreateInfo));
249 break;
250 }
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600251 // Swap Chain is very unique, use my_data->imageMap, but copy in
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600252 // SwapChainCreatInfo's usage flags and set the mem value to a unique key. These is used by
253 // vkCreateImageView and internal MemTracker routines to distinguish swap chain images
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700254 case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600255 {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600256 auto pCI = &my_data->imageMap[handle];
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600257 memset(pCI, 0, sizeof(MT_OBJ_BINDING_INFO));
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600258 pCI->mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
Michael Lentine6306a5a2015-11-24 17:55:33 -0600259 pCI->valid = false;
Mark Lobodzinski6aa1abd2015-09-01 11:19:08 -0600260 pCI->create_info.image.usage =
Ian Elliottc623ba52015-11-20 14:13:17 -0700261 const_cast<VkSwapchainCreateInfoKHR*>(static_cast<const VkSwapchainCreateInfoKHR *>(pCreateInfo))->imageUsage;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600262 break;
263 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600264 }
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500265}
266
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500267// Add a fence, creating one if necessary to our list of fences/fenceIds
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700268static VkBool32
269add_fence_info(
270 layer_data *my_data,
271 VkFence fence,
272 VkQueue queue,
273 uint64_t *fenceId)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500274{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600275 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600276 *fenceId = my_data->currentFenceId++;
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600277
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -0500278 // If no fence, create an internal fence to track the submissions
Chia-I Wue420a332015-10-26 20:04:44 +0800279 if (fence != VK_NULL_HANDLE) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600280 my_data->fenceMap[fence].fenceId = *fenceId;
281 my_data->fenceMap[fence].queue = queue;
Mark Lobodzinski56945182015-04-09 13:46:09 -0500282 // Validate that fence is in UNSIGNALED state
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600283 VkFenceCreateInfo* pFenceCI = &(my_data->fenceMap[fence].createInfo);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600284 if (pFenceCI->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700285 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t) fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +0800286 "Fence %#" PRIxLEAST64 " submitted in SIGNALED state. Fences must be reset before being submitted", (uint64_t) fence);
Mark Lobodzinski56945182015-04-09 13:46:09 -0500287 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600288 } else {
289 // TODO : Do we need to create an internal fence here for tracking purposes?
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700290 }
Mike Stroyan53430332015-05-19 15:16:08 -0600291 // Update most recently submitted fence and fenceId for Queue
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600292 my_data->queueMap[queue].lastSubmittedId = *fenceId;
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600293 return skipCall;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500294}
295
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500296// Remove a fenceInfo from our list of fences/fenceIds
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700297static void
298delete_fence_info(
299 layer_data *my_data,
300 VkFence fence)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500301{
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600302 my_data->fenceMap.erase(fence);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500303}
304
Mike Stroyan53430332015-05-19 15:16:08 -0600305// Record information when a fence is known to be signalled
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700306static void
307update_fence_tracking(
308 layer_data *my_data,
309 VkFence fence)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500310{
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600311 auto fence_item = my_data->fenceMap.find(fence);
312 if (fence_item != my_data->fenceMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600313 MT_FENCE_INFO *pCurFenceInfo = &(*fence_item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600314 VkQueue queue = pCurFenceInfo->queue;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600315 auto queue_item = my_data->queueMap.find(queue);
316 if (queue_item != my_data->queueMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600317 MT_QUEUE_INFO *pQueueInfo = &(*queue_item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600318 if (pQueueInfo->lastRetiredId < pCurFenceInfo->fenceId) {
319 pQueueInfo->lastRetiredId = pCurFenceInfo->fenceId;
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -0500320 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500321 }
322 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500323
Mike Stroyan53430332015-05-19 15:16:08 -0600324 // Update fence state in fenceCreateInfo structure
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600325 auto pFCI = &(my_data->fenceMap[fence].createInfo);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600326 pFCI->flags = static_cast<VkFenceCreateFlags>(pFCI->flags | VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500327}
328
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500329// Helper routine that updates the fence list for a specific queue to all-retired
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700330static void
331retire_queue_fences(
332 layer_data *my_data,
333 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500334{
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600335 MT_QUEUE_INFO *pQueueInfo = &my_data->queueMap[queue];
Mike Stroyan988caa42015-05-19 17:03:40 -0600336 // Set queue's lastRetired to lastSubmitted indicating all fences completed
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600337 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700338}
339
Mike Stroyan988caa42015-05-19 17:03:40 -0600340// Helper routine that updates all queues to all-retired
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700341static void
342retire_device_fences(
343 layer_data *my_data,
344 VkDevice device)
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500345{
346 // Process each queue for device
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600347 // TODO: Add multiple device support
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600348 for (auto ii=my_data->queueMap.begin(); ii!=my_data->queueMap.end(); ++ii) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600349 // Set queue's lastRetired to lastSubmitted indicating all fences completed
350 MT_QUEUE_INFO *pQueueInfo = &(*ii).second;
351 pQueueInfo->lastRetiredId = pQueueInfo->lastSubmittedId;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500352 }
353}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600354
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600355// Helper function to validate correct usage bits set for buffers or images
356// Verify that (actual & desired) flags != 0 or,
357// if strict is true, verify that (actual & desired) flags == desired
358// In case of error, report it via dbg callbacks
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700359static VkBool32
360validate_usage_flags(
361 layer_data *my_data,
362 void *disp_obj,
363 VkFlags actual,
364 VkFlags desired,
365 VkBool32 strict,
366 uint64_t obj_handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700367 VkDebugReportObjectTypeEXT obj_type,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700368 char const *ty_str,
369 char const *func_name,
370 char const *usage_str)
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600371{
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600372 VkBool32 correct_usage = VK_FALSE;
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600373 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600374 if (strict)
375 correct_usage = ((actual & desired) == desired);
376 else
377 correct_usage = ((actual & desired) != 0);
378 if (!correct_usage) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700379 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj_type, obj_handle, 0, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600380 "Invalid usage flag for %s %#" PRIxLEAST64 " used by %s. In this case, %s should have %s set during creation.",
381 ty_str, obj_handle, func_name, ty_str, usage_str);
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600382 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600383 return skipCall;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600384}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600385
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600386// Helper function to validate usage flags for images
387// Pulls image info and then sends actual vs. desired usage off to helper above where
388// an error will be flagged if usage is not correct
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700389static VkBool32
390validate_image_usage_flags(
391 layer_data *my_data,
392 void *disp_obj,
393 VkImage image,
394 VkFlags desired,
395 VkBool32 strict,
396 char const *func_name,
397 char const *usage_string)
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600398{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600399 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700400 MT_OBJ_BINDING_INFO* pBindInfo = get_object_binding_info(my_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600401 if (pBindInfo) {
Tobin Ehlis1c49d782015-10-29 09:55:19 -0600402 skipCall = validate_usage_flags(my_data, disp_obj, pBindInfo->create_info.image.usage, desired, strict,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700403 (uint64_t) image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "image", func_name, usage_string);
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600404 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600405 return skipCall;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600406}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600407
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600408// Helper function to validate usage flags for buffers
409// Pulls buffer info and then sends actual vs. desired usage off to helper above where
410// an error will be flagged if usage is not correct
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700411static VkBool32
412validate_buffer_usage_flags(
413 layer_data *my_data,
414 void *disp_obj,
415 VkBuffer buffer,
416 VkFlags desired,
417 VkBool32 strict,
418 char const *func_name,
419 char const *usage_string)
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600420{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600421 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700422 MT_OBJ_BINDING_INFO* pBindInfo = get_object_binding_info(my_data, (uint64_t) buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600423 if (pBindInfo) {
Tobin Ehlis1c49d782015-10-29 09:55:19 -0600424 skipCall = validate_usage_flags(my_data, disp_obj, pBindInfo->create_info.buffer.usage, desired, strict,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700425 (uint64_t) buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "buffer", func_name, usage_string);
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600426 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600427 return skipCall;
Tobin Ehlisd94ba722015-07-03 08:45:14 -0600428}
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600429
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500430// Return ptr to info in map container containing mem, or NULL if not found
Tobin Ehlis77b3abb2015-03-04 08:38:22 -0700431// Calls to this function should be wrapped in mutex
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700432static MT_MEM_OBJ_INFO*
433get_mem_obj_info(
434 layer_data *my_data,
435 const VkDeviceMemory mem)
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700436{
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600437 auto item = my_data->memObjMap.find(mem);
438 if (item != my_data->memObjMap.end()) {
Mike Stroyan988caa42015-05-19 17:03:40 -0600439 return &(*item).second;
Mike Stroyan53430332015-05-19 15:16:08 -0600440 } else {
441 return NULL;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600442 }
Tobin Ehlis2836a7d2015-01-08 15:22:32 -0700443}
444
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700445static void
446add_mem_obj_info(
447 layer_data *my_data,
448 void *object,
449 const VkDeviceMemory mem,
450 const VkMemoryAllocateInfo *pAllocateInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700451{
Courtney Goeltzenleuchter0749c662015-06-13 21:29:26 -0600452 assert(object != NULL);
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -0600453
Chia-I Wu1f851912015-10-27 18:04:07 +0800454 memcpy(&my_data->memObjMap[mem].allocInfo, pAllocateInfo, sizeof(VkMemoryAllocateInfo));
Ian Elliottb134e842015-07-06 14:31:32 -0600455 // TODO: Update for real hardware, actually process allocation info structures
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600456 my_data->memObjMap[mem].allocInfo.pNext = NULL;
Mark Lobodzinskic3fc95c2015-12-11 11:17:49 -0700457 my_data->memObjMap[mem].object = object;
458 my_data->memObjMap[mem].refCount = 0;
459 my_data->memObjMap[mem].mem = mem;
460 my_data->memObjMap[mem].memRange.offset = 0;
461 my_data->memObjMap[mem].memRange.size = 0;
462 my_data->memObjMap[mem].pData = 0;
463 my_data->memObjMap[mem].pDriverData = 0;
Michael Lentine6306a5a2015-11-24 17:55:33 -0600464 my_data->memObjMap[mem].valid = false;
465}
466
467static bool validate_memory_is_valid(layer_data *my_data, VkDeviceMemory mem, VkImage image = VK_NULL_HANDLE) {
468 if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
469 MT_OBJ_BINDING_INFO* pBindInfo = get_object_binding_info(my_data, reinterpret_cast<uint64_t>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
470 if (pBindInfo && !pBindInfo->valid) {
471 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, reinterpret_cast<uint64_t>(mem), 0, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
472 "Cannot read invalid swapchain image %" PRIx64 ", please fill the memory before using.", reinterpret_cast<uint64_t>(image));
473 }
474 }
475 else {
476 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(my_data, mem);
477 if (pMemObj && !pMemObj->valid) {
478 return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, reinterpret_cast<uint64_t>(mem), 0, MEMTRACK_INVALID_USAGE_FLAG, "MEM",
479 "Cannot read invalid memory %" PRIx64 ", please fill the memory before using.", reinterpret_cast<uint64_t>(mem));
480 }
481 }
482 return false;
483}
484
485static void set_memory_valid(layer_data *my_data, VkDeviceMemory mem, bool valid, VkImage image = VK_NULL_HANDLE) {
486 if (mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
487 MT_OBJ_BINDING_INFO* pBindInfo = get_object_binding_info(my_data, reinterpret_cast<uint64_t>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
488 if (pBindInfo) {
489 pBindInfo->valid = valid;
490 }
491 } else {
492 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(my_data, mem);
493 if (pMemObj) {
494 pMemObj->valid = valid;
495 }
496 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700497}
498
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500499// Find CB Info and add mem reference to list container
500// Find Mem Obj Info and add CB reference to list container
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700501static VkBool32
502update_cmd_buf_and_mem_references(
503 layer_data *my_data,
504 const VkCommandBuffer cb,
505 const VkDeviceMemory mem,
506 const char *apiName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700507{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600508 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600509
510 // Skip validation if this image was created through WSI
511 if (mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
512
513 // First update CB binding in MemObj mini CB list
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600514 MT_MEM_OBJ_INFO* pMemInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700515 if (pMemInfo) {
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600516 // Search for cmd buffer object in memory object's binding list
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600517 VkBool32 found = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800518 if (pMemInfo->pCommandBufferBindings.size() > 0) {
519 for (list<VkCommandBuffer>::iterator it = pMemInfo->pCommandBufferBindings.begin(); it != pMemInfo->pCommandBufferBindings.end(); ++it) {
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600520 if ((*it) == cb) {
David Pinedof5997ab2015-04-27 16:36:17 -0600521 found = VK_TRUE;
522 break;
523 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500524 }
525 }
526 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600527 if (found == VK_FALSE) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800528 pMemInfo->pCommandBufferBindings.push_front(cb);
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600529 pMemInfo->refCount++;
530 }
531 // Now update CBInfo's Mem reference list
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600532 MT_CB_INFO* pCBInfo = get_cmd_buf_info(my_data, cb);
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600533 // TODO: keep track of all destroyed CBs so we know if this is a stale or simply invalid object
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700534 if (pCBInfo) {
Mark Lobodzinskibe0eb4e2015-09-11 15:56:51 -0600535 // Search for memory object in cmd buffer's reference list
536 VkBool32 found = VK_FALSE;
537 if (pCBInfo->pMemObjList.size() > 0) {
538 for (auto it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
539 if ((*it) == mem) {
540 found = VK_TRUE;
541 break;
542 }
543 }
544 }
545 // If not present, add to list
546 if (found == VK_FALSE) {
547 pCBInfo->pMemObjList.push_front(mem);
548 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600549 }
550 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700551 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600552 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700553}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600554
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700555// Free bindings related to CB
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700556static VkBool32
557clear_cmd_buf_and_mem_references(
558 layer_data *my_data,
559 const VkCommandBuffer cb)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700560{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600561 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600562 MT_CB_INFO* pCBInfo = get_cmd_buf_info(my_data, cb);
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700563
564 if (pCBInfo && (pCBInfo->pMemObjList.size() > 0)) {
565 list<VkDeviceMemory> mem_obj_list = pCBInfo->pMemObjList;
566 for (list<VkDeviceMemory>::iterator it=mem_obj_list.begin(); it!=mem_obj_list.end(); ++it) {
567 MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(my_data, *it);
568 if (pInfo) {
569 pInfo->pCommandBufferBindings.remove(cb);
570 pInfo->refCount--;
David Pinedof5997ab2015-04-27 16:36:17 -0600571 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600572 }
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500573 pCBInfo->pMemObjList.clear();
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700574 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600575 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700576}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600577
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700578// Delete the entire CB list
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700579static VkBool32
580delete_cmd_buf_info_list(
581 layer_data* my_data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700582{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600583 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800584 for (unordered_map<VkCommandBuffer, MT_CB_INFO>::iterator ii=my_data->cbMap.begin(); ii!=my_data->cbMap.end(); ++ii) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600585 skipCall |= clear_cmd_buf_and_mem_references(my_data, (*ii).first);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700586 }
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600587 my_data->cbMap.clear();
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600588 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700589}
590
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500591// For given MemObjInfo, report Obj & CB bindings
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700592static VkBool32
593reportMemReferencesAndCleanUp(
594 layer_data *my_data,
595 MT_MEM_OBJ_INFO *pMemObjInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700596{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600597 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +0800598 size_t cmdBufRefCount = pMemObjInfo->pCommandBufferBindings.size();
Tony Barboura938abb2015-04-22 11:36:22 -0600599 size_t objRefCount = pMemObjInfo->pObjBindings.size();
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500600
Michael Lentinedcae1f92015-11-23 17:52:53 -0600601 if ((pMemObjInfo->pCommandBufferBindings.size()) != 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700602 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t) pMemObjInfo->mem, 0, MEMTRACK_FREED_MEM_REF, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800603 "Attempting to free memory object %#" PRIxLEAST64 " which still contains " PRINTF_SIZE_T_SPECIFIER " references",
Chia-I Wue420a332015-10-26 20:04:44 +0800604 (uint64_t) pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700605 }
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500606
Chia-I Wu1f851912015-10-27 18:04:07 +0800607 if (cmdBufRefCount > 0 && pMemObjInfo->pCommandBufferBindings.size() > 0) {
608 for (list<VkCommandBuffer>::const_iterator it = pMemObjInfo->pCommandBufferBindings.begin(); it != pMemObjInfo->pCommandBufferBindings.end(); ++it) {
609 // TODO : CommandBuffer should be source Obj here
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700610 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)(*it), 0, MEMTRACK_FREED_MEM_REF, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +0800611 "Command Buffer %p still has a reference to mem obj %#" PRIxLEAST64, (*it), (uint64_t) pMemObjInfo->mem);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500612 }
613 // Clear the list of hanging references
Chia-I Wu1f851912015-10-27 18:04:07 +0800614 pMemObjInfo->pCommandBufferBindings.clear();
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500615 }
616
David Pinedof5997ab2015-04-27 16:36:17 -0600617 if (objRefCount > 0 && pMemObjInfo->pObjBindings.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600618 for (auto it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700619 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, it->type, it->handle, 0, MEMTRACK_FREED_MEM_REF, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +0800620 "VK Object %#" PRIxLEAST64 " still has a reference to mem obj %#" PRIxLEAST64, it->handle, (uint64_t) pMemObjInfo->mem);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500621 }
622 // Clear the list of hanging references
623 pMemObjInfo->pObjBindings.clear();
624 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600625 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700626}
627
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700628static VkBool32
629deleteMemObjInfo(
630 layer_data *my_data,
631 void *object,
632 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700633{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600634 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600635 auto item = my_data->memObjMap.find(mem);
636 if (item != my_data->memObjMap.end()) {
637 my_data->memObjMap.erase(item);
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600638 } else {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700639 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t) mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +0800640 "Request to delete memory object %#" PRIxLEAST64 " not present in memory Object Map", (uint64_t) mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700641 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600642 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700643}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -0500644
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700645// Check if fence for given CB is completed
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700646static VkBool32
647checkCBCompleted(
648 layer_data *my_data,
Chia-I Wu1f851912015-10-27 18:04:07 +0800649 const VkCommandBuffer cb,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700650 VkBool32 *complete)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700651{
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700652 MT_CB_INFO *pCBInfo = get_cmd_buf_info(my_data, cb);
653 VkBool32 skipCall = VK_FALSE;
654 *complete = VK_TRUE;
655
656 if (pCBInfo) {
657 if (pCBInfo->lastSubmittedQueue != NULL) {
658 VkQueue queue = pCBInfo->lastSubmittedQueue;
659 MT_QUEUE_INFO *pQueueInfo = &my_data->queueMap[queue];
660 if (pCBInfo->fenceId > pQueueInfo->lastRetiredId) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700661 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)cb, 0,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700662 MEMTRACK_NONE, "MEM", "fence %#" PRIxLEAST64 " for CB %p has not been checked for completion",
663 (uint64_t) pCBInfo->lastSubmittedFence, cb);
664 *complete = VK_FALSE;
665 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600666 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700667 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600668 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700669}
670
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700671static VkBool32
672freeMemObjInfo(
673 layer_data *my_data,
674 void* object,
675 VkDeviceMemory mem,
676 VkBool32 internal)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700677{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600678 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500679 // Parse global list to find info w/ mem
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600680 MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700681 if (pInfo) {
Courtney Goeltzenleuchterc4804862015-03-26 16:15:39 -0600682 if (pInfo->allocInfo.allocationSize == 0 && !internal) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700683 // TODO: Verify against Valid Use section
684 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t) mem, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600685 "Attempting to free memory associated with a Persistent Image, %#" PRIxLEAST64 ", "
Chia-I Wue420a332015-10-26 20:04:44 +0800686 "this should not be explicitly freed\n", (uint64_t) mem);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600687 } else {
688 // Clear any CB bindings for completed CBs
689 // TODO : Is there a better place to do this?
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500690
Chia-I Wu1f851912015-10-27 18:04:07 +0800691 VkBool32 commandBufferComplete = VK_FALSE;
Courtney Goeltzenleuchter38eca262015-06-13 21:36:49 -0600692 assert(pInfo->object != VK_NULL_HANDLE);
Chia-I Wu1f851912015-10-27 18:04:07 +0800693 list<VkCommandBuffer>::iterator it = pInfo->pCommandBufferBindings.begin();
694 list<VkCommandBuffer>::iterator temp;
695 while (pInfo->pCommandBufferBindings.size() > 0 && it != pInfo->pCommandBufferBindings.end()) {
696 skipCall |= checkCBCompleted(my_data, *it, &commandBufferComplete);
697 if (VK_TRUE == commandBufferComplete) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500698 temp = it;
699 ++temp;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600700 skipCall |= clear_cmd_buf_and_mem_references(my_data, *it);
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500701 it = temp;
702 } else {
703 ++it;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600704 }
705 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500706
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600707 // Now verify that no references to this mem obj remain and remove bindings
Mark Lobodzinskid3d00162015-09-10 08:15:23 -0600708 if (0 != pInfo->refCount) {
Tobin Ehlis1c49d782015-10-29 09:55:19 -0600709 skipCall |= reportMemReferencesAndCleanUp(my_data, pInfo);
Mark Lobodzinskid3d00162015-09-10 08:15:23 -0600710 }
Courtney Goeltzenleuchterc6b048f2015-04-14 00:01:21 -0600711 // Delete mem obj info
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600712 skipCall |= deleteMemObjInfo(my_data, object, mem);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700713 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700714 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600715 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700716}
717
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700718static const char*
719object_type_to_string(
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700720 VkDebugReportObjectTypeEXT type)
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700721{
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600722 switch (type)
723 {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700724 case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600725 return "image";
726 break;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700727 case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600728 return "image";
729 break;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700730 case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600731 return "swapchain";
732 break;
733 default:
734 return "unknown";
735 }
736}
737
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700738// Remove object binding performs 3 tasks:
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500739// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
740// 2. Decrement refCount for MemObjInfo
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600741// 3. Clear mem binding for image/buffer by setting its handle to 0
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600742// TODO : This only applied to Buffer, Image, and Swapchain objects now, how should it be updated/customized?
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700743static VkBool32
744clear_object_binding(
745 layer_data *my_data,
746 void *dispObj,
747 uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700748 VkDebugReportObjectTypeEXT type)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700749{
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600750 // TODO : Need to customize images/buffers/swapchains to track mem binding and clear it here appropriately
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600751 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600752 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(my_data, handle, type);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600753 if (pObjBindInfo) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600754 MT_MEM_OBJ_INFO* pMemObjInfo = get_mem_obj_info(my_data, pObjBindInfo->mem);
Michael Lentinedcae1f92015-11-23 17:52:53 -0600755 // TODO : Make sure this is a reasonable way to reset mem binding
756 pObjBindInfo->mem = VK_NULL_HANDLE;
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700757 if (pMemObjInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600758 // This obj is bound to a memory object. Remove the reference to this object in that memory object's list, decrement the memObj's refcount
759 // and set the objects memory binding pointer to NULL.
760 VkBool32 clearSucceeded = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600761 for (auto it = pMemObjInfo->pObjBindings.begin(); it != pMemObjInfo->pObjBindings.end(); ++it) {
762 if ((it->handle == handle) && (it->type == type)) {
763 pMemObjInfo->refCount--;
764 pMemObjInfo->pObjBindings.erase(it);
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600765 clearSucceeded = VK_TRUE;
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500766 break;
767 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600768 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600769 if (VK_FALSE == clearSucceeded ) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700770 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, 0, MEMTRACK_INVALID_OBJECT, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600771 "While trying to clear mem binding for %s obj %#" PRIxLEAST64 ", unable to find that object referenced by mem obj %#" PRIxLEAST64,
Chia-I Wue420a332015-10-26 20:04:44 +0800772 object_type_to_string(type), handle, (uint64_t) pMemObjInfo->mem);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600773 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700774 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700775 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600776 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700777}
778
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500779// For NULL mem case, output warning
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500780// Make sure given object is in global object map
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500781// IF a previous binding existed, output validation error
782// Otherwise, add reference from objectInfo to memoryInfo
Mark Lobodzinski85a83982015-04-02 08:52:53 -0500783// Add reference off of objInfo
Courtney Goeltzenleuchterd2804562015-06-13 21:37:34 -0600784// device is required for error logging, need a dispatchable
785// object for that.
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700786static VkBool32
787set_mem_binding(
788 layer_data *my_data,
789 void *dispatch_object,
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600790 VkDeviceMemory mem,
791 uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700792 VkDebugReportObjectTypeEXT type,
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600793 const char *apiName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700794{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600795 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700796 // Handle NULL case separately, just clear previous binding & decrement reference
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600797 if (mem == VK_NULL_HANDLE) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700798 // TODO: Verify against Valid Use section of spec.
799 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, type, handle, 0, MEMTRACK_INVALID_MEM_OBJ, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600800 "In %s, attempting to Bind Obj(%#" PRIxLEAST64 ") to NULL", apiName, handle);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600801 } else {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600802 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(my_data, handle, type);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600803 if (!pObjBindInfo) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700804 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600805 "In %s, attempting to update Binding of %s Obj(%#" PRIxLEAST64 ") that's not in global list()",
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600806 object_type_to_string(type), apiName, handle);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500807 } else {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600808 // non-null case so should have real mem obj
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600809 MT_MEM_OBJ_INFO* pMemInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700810 if (pMemInfo) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600811 // TODO : Need to track mem binding for obj and report conflict here
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600812 MT_MEM_OBJ_INFO* pPrevBinding = get_mem_obj_info(my_data, pObjBindInfo->mem);
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600813 if (pPrevBinding != NULL) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700814 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t) mem, 0, MEMTRACK_REBIND_OBJECT, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600815 "In %s, attempting to bind memory (%#" PRIxLEAST64 ") to object (%#" PRIxLEAST64 ") which has already been bound to mem object %#" PRIxLEAST64,
Chia-I Wue420a332015-10-26 20:04:44 +0800816 apiName, (uint64_t) mem, handle, (uint64_t) pPrevBinding->mem);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500817 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600818 else {
819 MT_OBJ_HANDLE_TYPE oht;
820 oht.handle = handle;
821 oht.type = type;
822 pMemInfo->pObjBindings.push_front(oht);
823 pMemInfo->refCount++;
824 // For image objects, make sure default memory state is correctly set
825 // TODO : What's the best/correct way to handle this?
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700826 if (VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT == type) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600827 VkImageCreateInfo ici = pObjBindInfo->create_info.image;
828 if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
829 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
830 // TODO:: More memory state transition stuff.
831 }
832 }
833 pObjBindInfo->mem = mem;
834 }
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500835 }
836 }
837 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600838 return skipCall;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500839}
840
841// For NULL mem case, clear any previous binding Else...
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600842// Make sure given object is in its object map
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500843// IF a previous binding existed, update binding
844// Add reference from objectInfo to memoryInfo
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600845// Add reference off of object's binding info
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500846// Return VK_TRUE if addition is successful, VK_FALSE otherwise
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700847static VkBool32
848set_sparse_mem_binding(
849 layer_data *my_data,
850 void *dispObject,
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600851 VkDeviceMemory mem,
852 uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700853 VkDebugReportObjectTypeEXT type,
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600854 const char *apiName)
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500855{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600856 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500857 // Handle NULL case separately, just clear previous binding & decrement reference
858 if (mem == VK_NULL_HANDLE) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600859 skipCall = clear_object_binding(my_data, dispObject, handle, type);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500860 } else {
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600861 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(my_data, handle, type);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600862 if (!pObjBindInfo) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700863 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600864 "In %s, attempting to update Binding of Obj(%#" PRIxLEAST64 ") that's not in global list()", apiName, handle);
Mark Lobodzinskic66c6712015-06-05 13:59:04 -0500865 }
866 // non-null case so should have real mem obj
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600867 MT_MEM_OBJ_INFO* pInfo = get_mem_obj_info(my_data, mem);
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700868 if (pInfo) {
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500869 // Search for object in memory object's binding list
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600870 VkBool32 found = VK_FALSE;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600871 if (pInfo->pObjBindings.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600872 for (auto it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
873 if (((*it).handle == handle) && ((*it).type == type)) {
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600874 found = VK_TRUE;
875 break;
876 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600877 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600878 }
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500879 // If not present, add to list
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600880 if (found == VK_FALSE) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600881 MT_OBJ_HANDLE_TYPE oht;
882 oht.handle = handle;
883 oht.type = type;
884 pInfo->pObjBindings.push_front(oht);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500885 pInfo->refCount++;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500886 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600887 // Need to set mem binding for this object
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600888 MT_MEM_OBJ_INFO* pPrevBinding = get_mem_obj_info(my_data, pObjBindInfo->mem);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600889 pObjBindInfo->mem = mem;
Tobin Ehlis6aa77422015-01-07 17:49:29 -0700890 }
891 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600892 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700893}
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -0600894
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700895template <typename T> void
896print_object_map_members(
897 layer_data *my_data,
898 void *dispObj,
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600899 T const& objectName,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700900 VkDebugReportObjectTypeEXT objectType,
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600901 const char *objectStr)
902{
903 for (auto const& element : objectName) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700904 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, objectType, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600905 " %s Object list contains %s Object %#" PRIxLEAST64 " ", objectStr, objectStr, element.first);
906 }
907}
908
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700909// For given Object, get 'mem' obj that it's bound to or NULL if no binding
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700910static VkBool32
911get_mem_binding_from_object(
912 layer_data *my_data,
913 void *dispObj,
914 const uint64_t handle,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700915 const VkDebugReportObjectTypeEXT type,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700916 VkDeviceMemory *mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700917{
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600918 VkBool32 skipCall = VK_FALSE;
Chia-I Wue420a332015-10-26 20:04:44 +0800919 *mem = VK_NULL_HANDLE;
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600920 MT_OBJ_BINDING_INFO* pObjBindInfo = get_object_binding_info(my_data, handle, type);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -0600921 if (pObjBindInfo) {
922 if (pObjBindInfo->mem) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600923 *mem = pObjBindInfo->mem;
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600924 } else {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700925 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, 0, MEMTRACK_MISSING_MEM_BINDINGS, "MEM",
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600926 "Trying to get mem binding for object %#" PRIxLEAST64 " but object has no mem binding", handle);
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700927 }
Courtney Goeltzenleuchtera43cbbf2015-04-29 10:51:48 -0600928 } else {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700929 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, 0, MEMTRACK_INVALID_OBJECT, "MEM",
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -0600930 "Trying to get mem binding for object %#" PRIxLEAST64 " but no such object in %s list",
931 handle, object_type_to_string(type));
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700932 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -0600933 return skipCall;
Tobin Ehlis791a49c2014-11-10 12:29:12 -0700934}
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500935
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -0500936// Print details of MemObjInfo list
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700937static void
938print_mem_list(
939 layer_data *my_data,
940 void *dispObj)
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600941{
942 MT_MEM_OBJ_INFO* pInfo = NULL;
Mark Lobodzinski283a4c22015-03-24 16:29:24 -0500943
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600944 // Early out if info is not requested
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700945 if (!(my_data->report_data->active_flags & VK_DEBUG_REPORT_INFO_BIT_EXT)) {
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600946 return;
947 }
948
949 // Just printing each msg individually for now, may want to package these into single large print
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700950 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800951 "Details of Memory Object list (of size " PRINTF_SIZE_T_SPECIFIER " elements)", my_data->memObjMap.size());
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700952 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600953 "=============================");
954
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600955 if (my_data->memObjMap.size() <= 0)
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600956 return;
957
Tobin Ehlis96310ff2015-10-29 09:03:52 -0600958 for (auto ii=my_data->memObjMap.begin(); ii!=my_data->memObjMap.end(); ++ii) {
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600959 pInfo = &(*ii).second;
960
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700961 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600962 " ===MemObjInfo at %p===", (void*)pInfo);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700963 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800964 " Mem object: %#" PRIxLEAST64, reinterpret_cast<uint64_t>(pInfo->mem));
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700965 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600966 " Ref Count: %u", pInfo->refCount);
967 if (0 != pInfo->allocInfo.allocationSize) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800968 string pAllocInfoMsg = vk_print_vkmemoryallocateinfo(&pInfo->allocInfo, "MEM(INFO): ");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700969 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600970 " Mem Alloc info:\n%s", pAllocInfoMsg.c_str());
971 } else {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700972 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Ian Elliott338dedb2015-08-21 15:09:33 -0600973 " Mem Alloc info is NULL (alloc done by vkCreateSwapchainKHR())");
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600974 }
975
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700976 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800977 " VK OBJECT Binding list of size " PRINTF_SIZE_T_SPECIFIER " elements:", pInfo->pObjBindings.size());
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600978 if (pInfo->pObjBindings.size() > 0) {
979 for (list<MT_OBJ_HANDLE_TYPE>::iterator it = pInfo->pObjBindings.begin(); it != pInfo->pObjBindings.end(); ++it) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700980 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800981 " VK OBJECT %" PRIu64, it->handle);
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600982 }
983 }
984
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700985 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -0800986 " VK Command Buffer (CB) binding list of size " PRINTF_SIZE_T_SPECIFIER " elements", pInfo->pCommandBufferBindings.size());
Chia-I Wu1f851912015-10-27 18:04:07 +0800987 if (pInfo->pCommandBufferBindings.size() > 0)
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600988 {
Chia-I Wu1f851912015-10-27 18:04:07 +0800989 for (list<VkCommandBuffer>::iterator it = pInfo->pCommandBufferBindings.begin(); it != pInfo->pCommandBufferBindings.end(); ++it) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700990 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -0600991 " VK CB %p", (*it));
992 }
993 }
994 }
995}
996
Mark Lobodzinskie90aca12015-11-19 15:45:36 -0700997static void
998printCBList(
999 layer_data *my_data,
1000 void *dispObj)
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001001{
1002 MT_CB_INFO* pCBInfo = NULL;
1003
1004 // Early out if info is not requested
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001005 if (!(my_data->report_data->active_flags & VK_DEBUG_REPORT_INFO_BIT_EXT)) {
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001006 return;
1007 }
1008
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001009 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001010 "Details of CB list (of size " PRINTF_SIZE_T_SPECIFIER " elements)", my_data->cbMap.size());
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001011 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001012 "==================");
1013
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001014 if (my_data->cbMap.size() <= 0)
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001015 return;
1016
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001017 for (auto ii=my_data->cbMap.begin(); ii!=my_data->cbMap.end(); ++ii) {
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001018 pCBInfo = &(*ii).second;
1019
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001020 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001021 " CB Info (%p) has CB %p, fenceId %" PRIx64", and fence %#" PRIxLEAST64,
Chia-I Wu1f851912015-10-27 18:04:07 +08001022 (void*)pCBInfo, (void*)pCBInfo->commandBuffer, pCBInfo->fenceId,
Chia-I Wue420a332015-10-26 20:04:44 +08001023 (uint64_t) pCBInfo->lastSubmittedFence);
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001024
1025 if (pCBInfo->pMemObjList.size() <= 0)
1026 continue;
1027 for (list<VkDeviceMemory>::iterator it = pCBInfo->pMemObjList.begin(); it != pCBInfo->pMemObjList.end(); ++it) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001028 log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, 0, MEMTRACK_NONE, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001029 " Mem obj %" PRIu64, reinterpret_cast<uint64_t>(*it));
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001030 }
1031 }
1032}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001033
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001034static void
1035init_mem_tracker(
Courtney Goeltzenleuchterb03a0bf2015-11-25 14:31:49 -07001036 layer_data *my_data,
1037 const VkAllocationCallbacks *pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001038{
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001039 uint32_t report_flags = 0;
1040 uint32_t debug_action = 0;
1041 FILE *log_output = NULL;
1042 const char *option_str;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001043 VkDebugReportCallbackEXT callback;
Jon Ashburnf57ea372014-12-22 13:24:15 -07001044 // initialize MemTracker options
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001045 report_flags = getLayerOptionFlags("MemTrackerReportFlags", 0);
1046 getLayerOptionEnum("MemTrackerDebugAction", (uint32_t *) &debug_action);
Tobin Ehlis5b7acaa2015-01-08 14:26:53 -07001047
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001048 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
Jon Ashburnf57ea372014-12-22 13:24:15 -07001049 {
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001050 option_str = getLayerOption("MemTrackerLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -06001051 log_output = getLayerLogOutput(option_str, "MemTracker");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001052 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07001053 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001054 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07001055 dbgInfo.pfnCallback = log_callback;
1056 dbgInfo.pUserData = log_output;
1057 dbgInfo.flags = report_flags;
1058 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
Courtney Goeltzenleuchter26f2b232015-10-05 15:59:26 -06001059 my_data->logging_callback.push_back(callback);
1060 }
1061
1062 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001063 VkDebugReportCallbackCreateInfoEXT dbgInfo;
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07001064 memset(&dbgInfo, 0, sizeof(dbgInfo));
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001065 dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07001066 dbgInfo.pfnCallback = win32_debug_output_msg;
1067 dbgInfo.pUserData = log_output;
1068 dbgInfo.flags = report_flags;
1069 layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, &callback);
Courtney Goeltzenleuchter26f2b232015-10-05 15:59:26 -06001070 my_data->logging_callback.push_back(callback);
Jon Ashburnf57ea372014-12-22 13:24:15 -07001071 }
1072
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001073 if (!globalLockInitialized)
1074 {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001075 loader_platform_thread_create_mutex(&globalLock);
1076 globalLockInitialized = 1;
1077 }
Mark Lobodzinski72346292015-07-02 16:49:40 -06001078
1079 // Zero out memory property data
1080 memset(&memProps, 0, sizeof(VkPhysicalDeviceMemoryProperties));
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001081}
1082
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05001083// hook DestroyInstance to remove tableInstanceMap entry
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001084VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
1085 VkInstance instance,
1086 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05001087{
Jeremy Hayesc8dff5f2015-06-18 10:25:55 -06001088 // Grab the key before the instance is destroyed.
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001089 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001090 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
1091 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +08001092 pTable->DestroyInstance(instance, pAllocator);
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001093
1094 // Clean up logging callback, if any
Courtney Goeltzenleuchter26f2b232015-10-05 15:59:26 -06001095 while (my_data->logging_callback.size() > 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001096 VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07001097 layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
Courtney Goeltzenleuchter26f2b232015-10-05 15:59:26 -06001098 my_data->logging_callback.pop_back();
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001099 }
1100
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001101 layer_debug_report_destroy_instance(my_data->report_data);
1102 delete my_data->instance_dispatch_table;
1103 layer_data_map.erase(key);
1104 if (layer_data_map.empty()) {
1105 // Release mutex when destroying last instance
1106 loader_platform_thread_delete_mutex(&globalLock);
1107 globalLockInitialized = 0;
1108 }
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05001109}
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001110
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001111VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
Courtney Goeltzenleuchterb03a0bf2015-11-25 14:31:49 -07001112 const VkInstanceCreateInfo* pCreateInfo,
1113 const VkAllocationCallbacks* pAllocator,
1114 VkInstance* pInstance)
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001115{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001116 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
1117 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +08001118 VkResult result = pTable->CreateInstance(pCreateInfo, pAllocator, pInstance);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001119
1120 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001121 my_data->report_data = debug_report_create_instance(
1122 pTable,
1123 *pInstance,
Chia-I Wu763a7492015-10-26 20:48:51 +08001124 pCreateInfo->enabledExtensionNameCount,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001125 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchterc3c29bd2015-06-14 11:37:01 -06001126
Courtney Goeltzenleuchterb03a0bf2015-11-25 14:31:49 -07001127 init_mem_tracker(my_data, pAllocator);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001128 }
1129 return result;
1130}
1131
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001132static void
1133createDeviceRegisterExtensions(
1134 const VkDeviceCreateInfo *pCreateInfo,
1135 VkDevice device)
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001136{
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -06001137 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001138 VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
Jon Ashburn83334db2015-09-16 18:08:32 -06001139 PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
Jon Ashburn83334db2015-09-16 18:08:32 -06001140 pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) gpa(device, "vkCreateSwapchainKHR");
1141 pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) gpa(device, "vkDestroySwapchainKHR");
1142 pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) gpa(device, "vkGetSwapchainImagesKHR");
1143 pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) gpa(device, "vkAcquireNextImageKHR");
1144 pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR) gpa(device, "vkQueuePresentKHR");
Michael Lentine62c60c32015-10-29 10:41:47 -07001145 my_device_data->wsi_enabled = VK_FALSE;
Chia-I Wu763a7492015-10-26 20:48:51 +08001146 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Ian Elliott64070a82015-11-17 17:29:40 -07001147 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0)
Ian Elliottb134e842015-07-06 14:31:32 -06001148 my_device_data->wsi_enabled = true;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001149 }
1150}
1151
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001152VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001153 VkPhysicalDevice gpu,
1154 const VkDeviceCreateInfo *pCreateInfo,
1155 const VkAllocationCallbacks *pAllocator,
1156 VkDevice *pDevice)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001157{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001158 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
1159 VkLayerDispatchTable *pDeviceTable = my_device_data->device_dispatch_table;
Chia-I Wu69f40122015-10-26 21:10:41 +08001160 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001161 if (result == VK_SUCCESS) {
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001162 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06001163 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001164 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001165 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001166 return result;
1167}
1168
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001169VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001170 VkDevice device,
1171 const VkAllocationCallbacks *pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001172{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001173 dispatch_key key = get_dispatch_key(device);
1174 layer_data *my_device_data = get_my_data_ptr(key, layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001175 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001176 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001177 log_msg(my_device_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001178 "Printing List details prior to vkDestroyDevice()");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001179 log_msg(my_device_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device, 0, MEMTRACK_NONE, "MEM",
Mark Lobodzinskid0273662015-08-10 14:37:52 -06001180 "================================================");
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001181 print_mem_list(my_device_data, device);
1182 printCBList(my_device_data, device);
1183 skipCall = delete_cmd_buf_info_list(my_device_data);
Tobin Ehlis22d03232014-11-25 18:01:12 -07001184 // Report any memory leaks
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001185 MT_MEM_OBJ_INFO* pInfo = NULL;
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001186 if (my_device_data->memObjMap.size() > 0) {
1187 for (auto ii=my_device_data->memObjMap.begin(); ii!=my_device_data->memObjMap.end(); ++ii) {
Mike Stroyan988caa42015-05-19 17:03:40 -06001188 pInfo = &(*ii).second;
David Pinedof5997ab2015-04-27 16:36:17 -06001189 if (pInfo->allocInfo.allocationSize != 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001190 // Valid Usage: All child objects created on device must have been destroyed prior to destroying device
1191 skipCall |= log_msg(my_device_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t) pInfo->mem, 0, MEMTRACK_MEMORY_LEAK, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001192 "Mem Object %" PRIu64 " has not been freed. You should clean up this memory by calling "
1193 "vkFreeMemory(%" PRIu64 ") prior to vkDestroyDevice().", reinterpret_cast<uint64_t>(pInfo->mem), reinterpret_cast<uint64_t>(pInfo->mem));
David Pinedof5997ab2015-04-27 16:36:17 -06001194 }
Mark Lobodzinskidaa1d432015-02-18 18:06:24 -06001195 }
Tobin Ehlis22d03232014-11-25 18:01:12 -07001196 }
Mark Lobodzinski85a83982015-04-02 08:52:53 -05001197 // Queues persist until device is destroyed
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001198 delete_queue_info_list(my_device_data);
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -06001199 layer_debug_report_destroy_device(device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001200 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05001201
Courtney Goeltzenleuchterab75b612015-06-13 21:40:22 -06001202#if DISPATCH_MAP_DEBUG
1203 fprintf(stderr, "Device: %p, key: %p\n", device, key);
1204#endif
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001205 VkLayerDispatchTable *pDisp = my_device_data->device_dispatch_table;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001206 if (VK_FALSE == skipCall) {
Chia-I Wu69f40122015-10-26 21:10:41 +08001207 pDisp->DestroyDevice(device, pAllocator);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001208 }
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001209 delete my_device_data->device_dispatch_table;
1210 layer_data_map.erase(key);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001211}
1212
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001213VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
Mark Lobodzinski72346292015-07-02 16:49:40 -06001214 VkPhysicalDevice physicalDevice,
1215 VkPhysicalDeviceMemoryProperties *pMemoryProperties)
1216{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001217 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1218 VkLayerInstanceDispatchTable *pInstanceTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -06001219 pInstanceTable->GetPhysicalDeviceMemoryProperties(physicalDevice, pMemoryProperties);
1220 memcpy(&memProps, pMemoryProperties, sizeof(VkPhysicalDeviceMemoryProperties));
Mark Lobodzinski72346292015-07-02 16:49:40 -06001221}
1222
Courtney Goeltzenleuchterd89520d2015-12-01 14:08:28 -07001223static const VkExtensionProperties instance_extensions[] = {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001224 {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001225 VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
1226 VK_EXT_DEBUG_REPORT_REVISION
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001227 }
Jon Ashburneb2728b2015-04-10 14:33:07 -06001228};
1229
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001230VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001231 const char *pLayerName,
1232 uint32_t *pCount,
1233 VkExtensionProperties *pProperties)
Jon Ashburneb2728b2015-04-10 14:33:07 -06001234{
Courtney Goeltzenleuchterd89520d2015-12-01 14:08:28 -07001235 return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties);
Tony Barbour426b9052015-06-24 16:06:58 -06001236}
1237
Courtney Goeltzenleuchterd89520d2015-12-01 14:08:28 -07001238static const VkLayerProperties mtGlobalLayers[] = {
1239 {
Michael Lentine5d96e522015-12-11 10:49:51 -08001240 "VK_LAYER_LUNARG_mem_tracker",
Courtney Goeltzenleuchterd89520d2015-12-01 14:08:28 -07001241 VK_API_VERSION,
1242 VK_MAKE_VERSION(0, 1, 0),
1243 "Validation layer: MemTracker",
1244 }
1245};
1246
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001247VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001248 uint32_t *pCount,
1249 VkLayerProperties *pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -06001250{
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001251 return util_GetLayerProperties(ARRAY_SIZE(mtGlobalLayers),
1252 mtGlobalLayers,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001253 pCount, pProperties);
Jon Ashburneb2728b2015-04-10 14:33:07 -06001254}
1255
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001256VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001257 VkPhysicalDevice physicalDevice,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001258 const char *pLayerName,
1259 uint32_t *pCount,
1260 VkExtensionProperties *pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -06001261{
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001262 /* Mem tracker does not have any physical device extensions */
Jon Ashburnaff81ff2015-11-02 17:37:20 -07001263 if (pLayerName == NULL) {
1264 layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
1265 VkLayerInstanceDispatchTable *pInstanceTable = my_data->instance_dispatch_table;
1266 return pInstanceTable->EnumerateDeviceExtensionProperties(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001267 physicalDevice, NULL, pCount, pProperties);
Jon Ashburnaff81ff2015-11-02 17:37:20 -07001268 } else {
1269 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
1270 }
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001271}
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001272
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001273VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001274 VkPhysicalDevice physicalDevice,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001275 uint32_t *pCount,
1276 VkLayerProperties *pProperties)
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001277{
1278 /* Mem tracker's physical device layers are the same as global */
Courtney Goeltzenleuchter63466a52015-07-07 10:04:16 -06001279 return util_GetLayerProperties(ARRAY_SIZE(mtGlobalLayers), mtGlobalLayers,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001280 pCount, pProperties);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06001281}
1282
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001283VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001284 VkDevice device,
1285 uint32_t queueNodeIndex,
1286 uint32_t queueIndex,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001287 VkQueue *pQueue)
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001288{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001289 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1290 my_data->device_dispatch_table->GetDeviceQueue(device, queueNodeIndex, queueIndex, pQueue);
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -06001291 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001292 add_queue_info(my_data, *pQueue);
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -06001293 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski55e53d92015-03-31 16:05:35 -05001294}
1295
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001296VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001297 VkQueue queue,
Courtney Goeltzenleuchter3ec31622015-10-20 18:04:07 -06001298 uint32_t submitCount,
Chia-I Wu483e7702015-10-26 17:20:32 +08001299 const VkSubmitInfo *pSubmits,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001300 VkFence fence)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001301{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001302 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001303 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001304
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001305 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001306 // TODO : Need to track fence and clear mem references when fence clears
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05001307 MT_CB_INFO* pCBInfo = NULL;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001308 uint64_t fenceId = 0;
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001309 VkBool32 skipCall = add_fence_info(my_data, fence, queue, &fenceId);
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001310
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001311 print_mem_list(my_data, queue);
1312 printCBList(my_data, queue);
Courtney Goeltzenleuchter3ec31622015-10-20 18:04:07 -06001313 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Chia-I Wu483e7702015-10-26 17:20:32 +08001314 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Chia-I Wu763a7492015-10-26 20:48:51 +08001315 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001316 pCBInfo = get_cmd_buf_info(my_data, submit->pCommandBuffers[i]);
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001317 if (pCBInfo) {
1318 pCBInfo->fenceId = fenceId;
1319 pCBInfo->lastSubmittedFence = fence;
1320 pCBInfo->lastSubmittedQueue = queue;
1321 }
Courtney Goeltzenleuchter3ec31622015-10-20 18:04:07 -06001322 }
Chia-I Wude841af2015-10-29 22:01:53 +08001323
Chia-I Wu763a7492015-10-26 20:48:51 +08001324 for (uint32_t i = 0; i < submit->waitSemaphoreCount; i++) {
Chia-I Wude841af2015-10-29 22:01:53 +08001325 VkSemaphore sem = submit->pWaitSemaphores[i];
1326
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001327 if (my_data->semaphoreMap.find(sem) != my_data->semaphoreMap.end()) {
1328 if (my_data->semaphoreMap[sem] != MEMTRACK_SEMAPHORE_STATE_SIGNALLED) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001329 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, (uint64_t) sem,
Chia-I Wude841af2015-10-29 22:01:53 +08001330 0, MEMTRACK_NONE, "SEMAPHORE",
1331 "vkQueueSubmit: Semaphore must be in signaled state before passing to pWaitSemaphores");
1332 }
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001333 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_WAIT;
Chia-I Wude841af2015-10-29 22:01:53 +08001334 }
1335 }
Chia-I Wu763a7492015-10-26 20:48:51 +08001336 for (uint32_t i = 0; i < submit->signalSemaphoreCount; i++) {
Chia-I Wude841af2015-10-29 22:01:53 +08001337 VkSemaphore sem = submit->pWaitSemaphores[i];
1338
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001339 if (my_data->semaphoreMap.find(sem) != my_data->semaphoreMap.end()) {
1340 if (my_data->semaphoreMap[sem] != MEMTRACK_SEMAPHORE_STATE_UNSET) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001341 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, (uint64_t) sem,
Chia-I Wude841af2015-10-29 22:01:53 +08001342 0, MEMTRACK_NONE, "SEMAPHORE",
1343 "vkQueueSubmit: Semaphore must not be currently signaled or in a wait state");
1344 }
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001345 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_SIGNALLED;
Chia-I Wude841af2015-10-29 22:01:53 +08001346 }
1347 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001348 }
Mark Lobodzinskibe783fe2015-04-07 13:38:21 -05001349
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001350 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001351 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001352 result = my_data->device_dispatch_table->QueueSubmit(
Chia-I Wu483e7702015-10-26 17:20:32 +08001353 queue, submitCount, pSubmits, fence);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001354 }
Chia-I Wude841af2015-10-29 22:01:53 +08001355
1356 loader_platform_thread_lock_mutex(&globalLock);
1357 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Chia-I Wu483e7702015-10-26 17:20:32 +08001358 const VkSubmitInfo *submit = &pSubmits[submit_idx];
Chia-I Wu763a7492015-10-26 20:48:51 +08001359 for (uint32_t i = 0; i < submit->waitSemaphoreCount; i++) {
Chia-I Wude841af2015-10-29 22:01:53 +08001360 VkSemaphore sem = submit->pWaitSemaphores[i];
1361
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001362 if (my_data->semaphoreMap.find(sem) != my_data->semaphoreMap.end()) {
1363 my_data->semaphoreMap[sem] = MEMTRACK_SEMAPHORE_STATE_UNSET;
Chia-I Wude841af2015-10-29 22:01:53 +08001364 }
1365 }
1366 }
1367 loader_platform_thread_unlock_mutex(&globalLock);
1368
Courtney Goeltzenleuchtercfedf362015-04-02 13:39:07 -06001369 return result;
1370}
1371
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001372VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001373 VkDevice device,
1374 const VkMemoryAllocateInfo *pAllocateInfo,
1375 const VkAllocationCallbacks *pAllocator,
1376 VkDeviceMemory *pMemory)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001377{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001378 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu1f851912015-10-27 18:04:07 +08001379 VkResult result = my_data->device_dispatch_table->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001380 // TODO : Track allocations and overall size here
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001381 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu1f851912015-10-27 18:04:07 +08001382 add_mem_obj_info(my_data, device, *pMemory, pAllocateInfo);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001383 print_mem_list(my_data, device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001384 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001385 return result;
1386}
1387
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001388VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkFreeMemory(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001389 VkDevice device,
1390 VkDeviceMemory mem,
1391 const VkAllocationCallbacks *pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001392{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001393 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Michael Lentinedcae1f92015-11-23 17:52:53 -06001394
1395 // From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed.
1396 // Before freeing a memory object, an application must ensure the memory object is no longer
1397 // in use by the device—for example by command buffers queued for execution. The memory need
1398 // not yet be unbound from all images and buffers, but any further use of those images or
1399 // buffers (on host or device) for anything other than destroying those objects will result in
1400 // undefined behavior.
1401
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001402 loader_platform_thread_lock_mutex(&globalLock);
Michael Lentine62c60c32015-10-29 10:41:47 -07001403 freeMemObjInfo(my_data, device, mem, VK_FALSE);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001404 print_mem_list(my_data, device);
1405 printCBList(my_data, device);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001406 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu69f40122015-10-26 21:10:41 +08001407 my_data->device_dispatch_table->FreeMemory(device, mem, pAllocator);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001408}
1409
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001410VkBool32
1411validateMemRange(
Michael Lentine62c60c32015-10-29 10:41:47 -07001412 layer_data *my_data,
Michael Lentine4fbbaa32015-10-28 16:26:14 -07001413 VkDeviceMemory mem,
1414 VkDeviceSize offset,
1415 VkDeviceSize size)
1416{
Michael Lentine62c60c32015-10-29 10:41:47 -07001417 VkBool32 skipCall = VK_FALSE;
Michael Lentine4fbbaa32015-10-28 16:26:14 -07001418
Mark Lobodzinski6c3c6802015-11-19 14:13:44 -07001419 if (size == 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001420 // TODO: a size of 0 is not listed as an invalid use in the spec, should it be?
1421 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, 0,
Mark Lobodzinski6c3c6802015-11-19 14:13:44 -07001422 MEMTRACK_INVALID_MAP, "MEM", "VkMapMemory: Attempting to map memory range of size zero");
1423 }
1424
Michael Lentine4fbbaa32015-10-28 16:26:14 -07001425 auto mem_element = my_data->memObjMap.find(mem);
1426 if (mem_element != my_data->memObjMap.end()) {
Mark Lobodzinski6c3c6802015-11-19 14:13:44 -07001427 // It is an application error to call VkMapMemory on an object that is already mapped
1428 if (mem_element->second.memRange.size != 0) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001429 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, 0,
Mark Lobodzinski6c3c6802015-11-19 14:13:44 -07001430 MEMTRACK_INVALID_MAP, "MEM", "VkMapMemory: Attempting to map memory on an already-mapped object %#" PRIxLEAST64, (uint64_t)mem);
1431 }
1432
1433 // Validate that offset + size is within object's allocationSize
Mark Lobodzinski87229c42015-12-11 14:55:11 -07001434 if (size == VK_WHOLE_SIZE) {
1435 if (offset >= mem_element->second.allocInfo.allocationSize) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001436 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, 0,
Mark Lobodzinski87229c42015-12-11 14:55:11 -07001437 MEMTRACK_INVALID_MAP, "MEM", "Mapping Memory from %" PRIu64 " to %" PRIu64 " with total array size %" PRIu64,
1438 offset, mem_element->second.allocInfo.allocationSize, mem_element->second.allocInfo.allocationSize);
1439 }
1440 } else {
1441 if ((offset + size) > mem_element->second.allocInfo.allocationSize) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001442 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, 0,
Mark Lobodzinski87229c42015-12-11 14:55:11 -07001443 MEMTRACK_INVALID_MAP, "MEM", "Mapping Memory from %" PRIu64 " to %" PRIu64 " with total array size %" PRIu64,
1444 offset, size + offset, mem_element->second.allocInfo.allocationSize);
1445 }
Michael Lentine4fbbaa32015-10-28 16:26:14 -07001446 }
1447 }
Michael Lentine62c60c32015-10-29 10:41:47 -07001448 return skipCall;
1449}
1450
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001451void
1452storeMemRanges(
Michael Lentine62c60c32015-10-29 10:41:47 -07001453 layer_data *my_data,
1454 VkDeviceMemory mem,
1455 VkDeviceSize offset,
1456 VkDeviceSize size)
1457 {
1458 auto mem_element = my_data->memObjMap.find(mem);
1459 if (mem_element != my_data->memObjMap.end()) {
1460 MemRange new_range;
1461 new_range.offset = offset;
1462 new_range.size = size;
1463 mem_element->second.memRange = new_range;
1464 }
1465}
1466
1467VkBool32 deleteMemRanges(
1468 layer_data *my_data,
1469 VkDeviceMemory mem)
1470{
1471 VkBool32 skipCall = VK_FALSE;
1472 auto mem_element = my_data->memObjMap.find(mem);
1473 if (mem_element != my_data->memObjMap.end()) {
1474 if (!mem_element->second.memRange.size) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001475 // Valid Usage: memory must currently be mapped
1476 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, 0, MEMTRACK_INVALID_MAP, "MEM",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001477 "Unmapping Memory without memory being mapped: mem obj %#" PRIxLEAST64, (uint64_t)mem);
Michael Lentine62c60c32015-10-29 10:41:47 -07001478 }
1479 mem_element->second.memRange.size = 0;
1480 if (mem_element->second.pData) {
1481 free(mem_element->second.pData);
1482 mem_element->second.pData = 0;
1483 }
1484 }
1485 return skipCall;
1486}
1487
1488static char NoncoherentMemoryFillValue = 0xb;
1489
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001490void
1491initializeAndTrackMemory(
Michael Lentine62c60c32015-10-29 10:41:47 -07001492 layer_data *my_data,
1493 VkDeviceMemory mem,
1494 VkDeviceSize size,
1495 void **ppData)
1496{
1497 auto mem_element = my_data->memObjMap.find(mem);
1498 if (mem_element != my_data->memObjMap.end()) {
1499 mem_element->second.pDriverData = *ppData;
1500 uint32_t index = mem_element->second.allocInfo.memoryTypeIndex;
1501 if (memProps.memoryTypes[index].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
1502 mem_element->second.pData = 0;
1503 } else {
1504 mem_element->second.pData = malloc(2 * size);
1505 memset(mem_element->second.pData, NoncoherentMemoryFillValue, 2 * size);
1506 *ppData = static_cast<char*>(mem_element->second.pData) + (size / 2);
1507 }
1508 }
Michael Lentine4fbbaa32015-10-28 16:26:14 -07001509}
1510
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001511VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001512 VkDevice device,
1513 VkDeviceMemory mem,
1514 VkDeviceSize offset,
1515 VkDeviceSize size,
1516 VkFlags flags,
1517 void **ppData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001518{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001519 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Michael Lentine62c60c32015-10-29 10:41:47 -07001520 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001521 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001522 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001523 MT_MEM_OBJ_INFO *pMemObj = get_mem_obj_info(my_data, mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06001524 if (pMemObj) {
1525 pMemObj->valid = true;
1526 if ((memProps.memoryTypes[pMemObj->allocInfo.memoryTypeIndex].propertyFlags &
1527 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) {
1528 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
1529 (uint64_t) mem, 0, MEMTRACK_INVALID_STATE, "MEM",
1530 "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj %#" PRIxLEAST64, (uint64_t) mem);
1531 }
Mark Lobodzinski06f60b82015-02-25 12:16:04 -06001532 }
Michael Lentine62c60c32015-10-29 10:41:47 -07001533 skipCall |= validateMemRange(my_data, mem, offset, size);
1534 storeMemRanges(my_data, mem, offset, size);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001535 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001536 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001537 result = my_data->device_dispatch_table->MapMemory(device, mem, offset, size, flags, ppData);
Michael Lentine62c60c32015-10-29 10:41:47 -07001538 initializeAndTrackMemory(my_data, mem, size, ppData);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001539 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001540 return result;
1541}
1542
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001543VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001544 VkDevice device,
1545 VkDeviceMemory mem)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001546{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001547 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Michael Lentine62c60c32015-10-29 10:41:47 -07001548 VkBool32 skipCall = VK_FALSE;
1549
1550 loader_platform_thread_lock_mutex(&globalLock);
1551 skipCall |= deleteMemRanges(my_data, mem);
1552 loader_platform_thread_unlock_mutex(&globalLock);
1553 if (VK_FALSE == skipCall) {
1554 my_data->device_dispatch_table->UnmapMemory(device, mem);
1555 }
1556}
1557
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001558VkBool32
1559validateMemoryIsMapped(
1560 layer_data *my_data,
1561 uint32_t memRangeCount,
1562 const VkMappedMemoryRange *pMemRanges)
1563{
Michael Lentine62c60c32015-10-29 10:41:47 -07001564 VkBool32 skipCall = VK_FALSE;
1565 for (uint32_t i = 0; i < memRangeCount; ++i) {
1566 auto mem_element = my_data->memObjMap.find(pMemRanges[i].memory);
1567 if (mem_element != my_data->memObjMap.end()) {
1568 if (mem_element->second.memRange.offset > pMemRanges[i].offset ||
1569 (mem_element->second.memRange.offset + mem_element->second.memRange.size) < (pMemRanges[i].offset + pMemRanges[i].size)) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001570 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory,
Michael Lentine62c60c32015-10-29 10:41:47 -07001571 0, MEMTRACK_INVALID_MAP, "MEM", "Memory must be mapped before it can be flushed or invalidated.");
1572 }
1573 }
1574 }
1575 return skipCall;
1576}
1577
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001578VkBool32
1579validateAndCopyNoncoherentMemoryToDriver(
1580 layer_data *my_data,
1581 uint32_t memRangeCount,
1582 const VkMappedMemoryRange *pMemRanges)
1583{
Michael Lentine62c60c32015-10-29 10:41:47 -07001584 VkBool32 skipCall = VK_FALSE;
1585 for (uint32_t i = 0; i < memRangeCount; ++i) {
1586 auto mem_element = my_data->memObjMap.find(pMemRanges[i].memory);
1587 if (mem_element != my_data->memObjMap.end()) {
1588 if (mem_element->second.pData) {
1589 VkDeviceSize size = mem_element->second.memRange.size;
1590 VkDeviceSize half_size = (size / 2);
1591 char* data = static_cast<char*>(mem_element->second.pData);
1592 for (auto j = 0; j < half_size; ++j) {
1593 if (data[j] != NoncoherentMemoryFillValue) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001594 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001595 0, MEMTRACK_INVALID_MAP, "MEM", "Memory overflow was detected on mem obj %" PRIxLEAST64, (uint64_t)pMemRanges[i].memory);
Michael Lentine62c60c32015-10-29 10:41:47 -07001596 }
1597 }
1598 for (auto j = size + half_size; j < 2 * size; ++j) {
1599 if (data[j] != NoncoherentMemoryFillValue) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001600 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory,
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08001601 0, MEMTRACK_INVALID_MAP, "MEM", "Memory overflow was detected on mem obj %" PRIxLEAST64, (uint64_t)pMemRanges[i].memory);
Michael Lentine62c60c32015-10-29 10:41:47 -07001602 }
1603 }
1604 memcpy(mem_element->second.pDriverData, static_cast<void*>(data + half_size), size);
1605 }
1606 }
1607 }
1608 return skipCall;
1609}
1610
1611VK_LAYER_EXPORT VkResult vkFlushMappedMemoryRanges(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001612 VkDevice device,
1613 uint32_t memRangeCount,
1614 const VkMappedMemoryRange *pMemRanges)
Michael Lentine62c60c32015-10-29 10:41:47 -07001615{
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001616 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine62c60c32015-10-29 10:41:47 -07001617 VkBool32 skipCall = VK_FALSE;
1618 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1619
1620 skipCall |= validateAndCopyNoncoherentMemoryToDriver(my_data, memRangeCount, pMemRanges);
1621 skipCall |= validateMemoryIsMapped(my_data, memRangeCount, pMemRanges);
1622 if (VK_FALSE == skipCall ) {
1623 result = my_data->device_dispatch_table->FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
1624 }
1625 return result;
1626}
1627
1628VK_LAYER_EXPORT VkResult vkInvalidateMappedMemoryRanges(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001629 VkDevice device,
1630 uint32_t memRangeCount,
1631 const VkMappedMemoryRange *pMemRanges)
Michael Lentine62c60c32015-10-29 10:41:47 -07001632{
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001633 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine62c60c32015-10-29 10:41:47 -07001634 VkBool32 skipCall = VK_FALSE;
1635 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1636
1637 skipCall |= validateMemoryIsMapped(my_data, memRangeCount, pMemRanges);
1638 if (VK_FALSE == skipCall) {
1639 result = my_data->device_dispatch_table->InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
1640 }
1641 return result;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001642}
1643
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001644VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyFence(
1645 VkDevice device,
1646 VkFence fence,
1647 const VkAllocationCallbacks *pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001648{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001649 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001650 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001651 delete_fence_info(my_data, fence);
1652 auto item = my_data->fenceMap.find(fence);
1653 if (item != my_data->fenceMap.end()) {
1654 my_data->fenceMap.erase(item);
Tobin Ehlise6884ef2014-11-27 07:52:04 -07001655 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001656 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu69f40122015-10-26 21:10:41 +08001657 my_data->device_dispatch_table->DestroyFence(device, fence, pAllocator);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001658}
1659
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001660VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(
1661 VkDevice device,
1662 VkBuffer buffer,
1663 const VkAllocationCallbacks *pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001664{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001665 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001666 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001667 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001668 auto item = my_data->bufferMap.find((uint64_t)buffer);
1669 if (item != my_data->bufferMap.end()) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001670 skipCall = clear_object_binding(my_data, device, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001671 my_data->bufferMap.erase(item);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001672 }
1673 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001674 if (VK_FALSE == skipCall) {
Chia-I Wu69f40122015-10-26 21:10:41 +08001675 my_data->device_dispatch_table->DestroyBuffer(device, buffer, pAllocator);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001676 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001677}
1678
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001679VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyImage(
1680 VkDevice device,
1681 VkImage image,
1682 const VkAllocationCallbacks *pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001683{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001684 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001685 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001686 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001687 auto item = my_data->imageMap.find((uint64_t)image);
1688 if (item != my_data->imageMap.end()) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001689 skipCall = clear_object_binding(my_data, device, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001690 my_data->imageMap.erase(item);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001691 }
1692 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001693 if (VK_FALSE == skipCall) {
Chia-I Wu69f40122015-10-26 21:10:41 +08001694 my_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001695 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001696}
1697
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001698VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(
1699 VkDevice device,
1700 VkBuffer buffer,
1701 VkDeviceMemory mem,
1702 VkDeviceSize memoryOffset)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001703{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001704 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001705 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mike Stroyan230e6252015-04-17 12:36:38 -06001706 loader_platform_thread_lock_mutex(&globalLock);
1707 // Track objects tied to memory
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001708 VkBool32 skipCall = set_mem_binding(my_data, device, mem, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory");
1709 add_object_binding_info(my_data, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, mem);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001710 print_mem_list(my_data, device);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001711 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001712 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08001713 result = my_data->device_dispatch_table->BindBufferMemory(device, buffer, mem, memoryOffset);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001714 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001715 return result;
1716}
1717
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001718VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(
1719 VkDevice device,
1720 VkImage image,
1721 VkDeviceMemory mem,
1722 VkDeviceSize memoryOffset)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001723{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001724 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001725 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001726 loader_platform_thread_lock_mutex(&globalLock);
1727 // Track objects tied to memory
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001728 VkBool32 skipCall = set_mem_binding(my_data, device, mem, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory");
1729 add_object_binding_info(my_data, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, mem);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001730 print_mem_list(my_data, device);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001731 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001732 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08001733 result = my_data->device_dispatch_table->BindImageMemory(device, image, mem, memoryOffset);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001734 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001735 return result;
1736}
1737
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001738VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(
1739 VkDevice device,
1740 VkBuffer buffer,
1741 VkMemoryRequirements *pMemoryRequirements)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001742{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001743 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001744 // TODO : What to track here?
1745 // Could potentially save returned mem requirements and validate values passed into BindBufferMemory
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001746 my_data->device_dispatch_table->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001747}
1748
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001749VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(
1750 VkDevice device,
1751 VkImage image,
1752 VkMemoryRequirements *pMemoryRequirements)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001753{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001754 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001755 // TODO : What to track here?
1756 // Could potentially save returned mem requirements and validate values passed into BindImageMemory
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001757 my_data->device_dispatch_table->GetImageMemoryRequirements(device, image, pMemoryRequirements);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001758}
1759
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001760VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001761 VkQueue queue,
1762 uint32_t bindInfoCount,
1763 const VkBindSparseInfo *pBindInfo,
1764 VkFence fence)
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001765{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001766 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001767 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Chia-I Wu06809d52015-10-26 16:55:27 +08001768 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001769
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001770 loader_platform_thread_lock_mutex(&globalLock);
Mike Stroyan230e6252015-04-17 12:36:38 -06001771
Chia-I Wu06809d52015-10-26 16:55:27 +08001772 for (uint32_t i = 0; i < bindInfoCount; i++) {
1773 // Track objects tied to memory
1774 for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++) {
1775 for (uint32_t k = 0; k < pBindInfo[i].pBufferBinds[j].bindCount; k++) {
1776 if (set_sparse_mem_binding(my_data, queue,
Chia-I Wuc04519c2015-10-27 17:53:18 +08001777 pBindInfo[i].pBufferBinds[j].pBinds[k].memory,
Chia-I Wu06809d52015-10-26 16:55:27 +08001778 (uint64_t) pBindInfo[i].pBufferBinds[j].buffer,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001779 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkQueueBindSparse"))
Chia-I Wu06809d52015-10-26 16:55:27 +08001780 skipCall = VK_TRUE;
1781 }
1782 }
1783 for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++) {
1784 for (uint32_t k = 0; k < pBindInfo[i].pImageOpaqueBinds[j].bindCount; k++) {
1785 if (set_sparse_mem_binding(my_data, queue,
Chia-I Wuc04519c2015-10-27 17:53:18 +08001786 pBindInfo[i].pImageOpaqueBinds[j].pBinds[k].memory,
Chia-I Wu06809d52015-10-26 16:55:27 +08001787 (uint64_t) pBindInfo[i].pImageOpaqueBinds[j].image,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001788 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkQueueBindSparse"))
Chia-I Wu06809d52015-10-26 16:55:27 +08001789 skipCall = VK_TRUE;
1790 }
1791 }
1792 for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++) {
1793 for (uint32_t k = 0; k < pBindInfo[i].pImageBinds[j].bindCount; k++) {
1794 if (set_sparse_mem_binding(my_data, queue,
Chia-I Wuc04519c2015-10-27 17:53:18 +08001795 pBindInfo[i].pImageBinds[j].pBinds[k].memory,
Chia-I Wu06809d52015-10-26 16:55:27 +08001796 (uint64_t) pBindInfo[i].pImageBinds[j].image,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001797 VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkQueueBindSparse"))
Chia-I Wu06809d52015-10-26 16:55:27 +08001798 skipCall = VK_TRUE;
1799 }
1800 }
1801 }
1802
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001803 print_mem_list(my_data, queue);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001804 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001805 if (VK_FALSE == skipCall) {
Chia-I Wu06809d52015-10-26 16:55:27 +08001806 result = my_data->device_dispatch_table->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001807 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001808 return result;
1809}
1810
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001811VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001812 VkDevice device,
1813 const VkFenceCreateInfo *pCreateInfo,
1814 const VkAllocationCallbacks *pAllocator,
1815 VkFence *pFence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001816{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001817 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +08001818 VkResult result = my_data->device_dispatch_table->CreateFence(device, pCreateInfo, pAllocator, pFence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001819 if (VK_SUCCESS == result) {
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001820 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001821 MT_FENCE_INFO* pFI = &my_data->fenceMap[*pFence];
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06001822 memset(pFI, 0, sizeof(MT_FENCE_INFO));
1823 memcpy(&(pFI->createInfo), pCreateInfo, sizeof(VkFenceCreateInfo));
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001824 loader_platform_thread_unlock_mutex(&globalLock);
1825 }
1826 return result;
1827}
1828
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001829VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001830 VkDevice device,
1831 uint32_t fenceCount,
1832 const VkFence *pFences)
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001833{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001834 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001835 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001836 VkBool32 skipCall = VK_FALSE;
1837
1838 loader_platform_thread_lock_mutex(&globalLock);
1839 // Reset fence state in fenceCreateInfo structure
1840 for (uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001841 auto fence_item = my_data->fenceMap.find(pFences[i]);
1842 if (fence_item != my_data->fenceMap.end()) {
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001843 // Validate fences in SIGNALED state
1844 if (!(fence_item->second.createInfo.flags & VK_FENCE_CREATE_SIGNALED_BIT)) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001845 // TODO: I don't see a Valid Usage section for ResetFences. This behavior should be documented there.
1846 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t) pFences[i], 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +08001847 "Fence %#" PRIxLEAST64 " submitted to VkResetFences in UNSIGNALED STATE", (uint64_t) pFences[i]);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001848 }
1849 else {
1850 fence_item->second.createInfo.flags =
1851 static_cast<VkFenceCreateFlags>(fence_item->second.createInfo.flags & ~VK_FENCE_CREATE_SIGNALED_BIT);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001852 }
1853 }
Mark Lobodzinski87db5012015-09-14 17:43:42 -06001854 }
1855 loader_platform_thread_unlock_mutex(&globalLock);
1856 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001857 result = my_data->device_dispatch_table->ResetFences(device, fenceCount, pFences);
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001858 }
1859 return result;
1860}
1861
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001862static inline VkBool32
1863verifyFenceStatus(
1864 VkDevice device,
1865 VkFence fence,
1866 const char *apiCall)
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001867{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001868 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001869 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001870 auto pFenceInfo = my_data->fenceMap.find(fence);
1871 if (pFenceInfo != my_data->fenceMap.end()) {
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001872 if (pFenceInfo->second.createInfo.flags & VK_FENCE_CREATE_SIGNALED_BIT) {
Mark Lobodzinski7c0617e2015-11-12 10:11:21 -07001873 // TODO: Possibly move this to a lower-level warning if we ever add, say, a VERBOSE warning option. There are too many
1874 // cases where ISVs want to be able to do this to make it a normal warning or perf-warning.
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001875 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t) fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +08001876 "%s specified fence %#" PRIxLEAST64 " already in SIGNALED state.", apiCall, (uint64_t) fence);
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001877 }
1878 if (!pFenceInfo->second.queue) { // Checking status of unsubmitted fence
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001879 // TODO: I don't see a Valid Usage section for ResetFences. This behavior should be documented there.
1880 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, (uint64_t) fence, 0, MEMTRACK_INVALID_FENCE_STATE, "MEM",
Chia-I Wue420a332015-10-26 20:04:44 +08001881 "%s called for fence %#" PRIxLEAST64 " which has not been submitted on a Queue.", apiCall, (uint64_t) fence);
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001882 }
1883 }
1884 return skipCall;
1885}
1886
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001887VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001888 VkDevice device,
1889 VkFence fence)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001890{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001891 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001892 VkBool32 skipCall = verifyFenceStatus(device, fence, "vkGetFenceStatus");
1893 if (skipCall)
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001894 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001895 VkResult result = my_data->device_dispatch_table->GetFenceStatus(device, fence);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001896 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001897 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001898 update_fence_tracking(my_data, fence);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001899 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001900 }
1901 return result;
1902}
1903
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001904VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001905 VkDevice device,
1906 uint32_t fenceCount,
1907 const VkFence *pFences,
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06001908 VkBool32 waitAll,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001909 uint64_t timeout)
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001910{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001911 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001912 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001913 // Verify fence status of submitted fences
1914 for(uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001915 skipCall |= verifyFenceStatus(device, pFences[i], "vkWaitForFences");
Mark Lobodzinskiebe814d2015-04-07 16:07:57 -05001916 }
Tobin Ehlis21d6a742015-09-14 13:25:57 -06001917 if (skipCall)
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07001918 return VK_ERROR_VALIDATION_FAILED_EXT;
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001919 VkResult result = my_data->device_dispatch_table->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001920 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001921
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001922 if (VK_SUCCESS == result) {
Mark Lobodzinski8ee96342015-04-02 20:49:09 -05001923 if (waitAll || fenceCount == 1) { // Clear all the fences
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001924 for(uint32_t i = 0; i < fenceCount; i++) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001925 update_fence_tracking(my_data, pFences[i]);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001926 }
1927 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001928 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001929 loader_platform_thread_unlock_mutex(&globalLock);
1930 return result;
1931}
1932
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001933VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001934 VkQueue queue)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001935{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001936 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
1937 VkResult result = my_data->device_dispatch_table->QueueWaitIdle(queue);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001938 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001939 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001940 retire_queue_fences(my_data, queue);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001941 loader_platform_thread_unlock_mutex(&globalLock);
1942 }
1943 return result;
1944}
1945
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001946VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001947 VkDevice device)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001948{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001949 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1950 VkResult result = my_data->device_dispatch_table->DeviceWaitIdle(device);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001951 if (VK_SUCCESS == result) {
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001952 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06001953 retire_device_fences(my_data, device);
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05001954 loader_platform_thread_unlock_mutex(&globalLock);
1955 }
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07001956 return result;
1957}
1958
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001959VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001960 VkDevice device,
1961 const VkBufferCreateInfo *pCreateInfo,
1962 const VkAllocationCallbacks *pAllocator,
1963 VkBuffer *pBuffer)
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001964{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001965 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +08001966 VkResult result = my_data->device_dispatch_table->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001967 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001968 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001969 add_object_create_info(my_data, (uint64_t)*pBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001970 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski15427102015-02-18 16:38:17 -06001971 }
Tobin Ehlis84c521c2015-01-19 08:42:29 -07001972 return result;
1973}
1974
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001975VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001976 VkDevice device,
1977 const VkImageCreateInfo *pCreateInfo,
1978 const VkAllocationCallbacks *pAllocator,
1979 VkImage *pImage)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001980{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001981 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +08001982 VkResult result = my_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001983 if (VK_SUCCESS == result) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001984 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07001985 add_object_create_info(my_data, (uint64_t)*pImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, pCreateInfo);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06001986 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07001987 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001988 return result;
1989}
1990
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08001991VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001992 VkDevice device,
1993 const VkImageViewCreateInfo *pCreateInfo,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07001994 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06001995 VkImageView *pView)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07001996{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06001997 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +08001998 VkResult result = my_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001999 if (result == VK_SUCCESS) {
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002000 loader_platform_thread_lock_mutex(&globalLock);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002001 my_data->imageViewMap[*pView].image = pCreateInfo->image;
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002002 // Validate that img has correct usage flags set
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002003 validate_image_usage_flags(my_data, device, pCreateInfo->image,
Courtney Goeltzenleuchterc3b8eea2015-09-10 14:14:11 -06002004 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
Michael Lentine62c60c32015-10-29 10:41:47 -07002005 VK_FALSE, "vkCreateImageView()", "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT]_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002006 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis6aa77422015-01-07 17:49:29 -07002007 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002008 return result;
2009}
2010
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002011VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(
Mark Lobodzinskiab5c3d52015-10-27 09:53:00 -06002012 VkDevice device,
2013 const VkBufferViewCreateInfo *pCreateInfo,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002014 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinskiab5c3d52015-10-27 09:53:00 -06002015 VkBufferView *pView)
2016{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002017 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +08002018 VkResult result = my_data->device_dispatch_table->CreateBufferView(device, pCreateInfo, pAllocator, pView);
Mark Lobodzinskiab5c3d52015-10-27 09:53:00 -06002019 if (result == VK_SUCCESS) {
2020 loader_platform_thread_lock_mutex(&globalLock);
2021 // In order to create a valid buffer view, the buffer must have been created with at least one of the
2022 // following flags: UNIFORM_TEXEL_BUFFER_BIT or STORAGE_TEXEL_BUFFER_BIT
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002023 validate_buffer_usage_flags(my_data, device, pCreateInfo->buffer,
Mark Lobodzinskiab5c3d52015-10-27 09:53:00 -06002024 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
Michael Lentine62c60c32015-10-29 10:41:47 -07002025 VK_FALSE, "vkCreateBufferView()", "VK_BUFFER_USAGE_[STORAGE|UNIFORM]_TEXEL_BUFFER_BIT");
Mark Lobodzinskiab5c3d52015-10-27 09:53:00 -06002026 loader_platform_thread_unlock_mutex(&globalLock);
2027 }
2028 return result;
2029}
2030
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002031VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002032 VkDevice device,
Chia-I Wu1f851912015-10-27 18:04:07 +08002033 const VkCommandBufferAllocateInfo *pCreateInfo,
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002034 VkCommandBuffer *pCommandBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002035{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002036 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002037 VkResult result = my_data->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
2038
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002039 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski13b66742015-11-20 14:33:48 -07002040 if (VK_SUCCESS == result) {
2041 for (uint32_t i = 0; i < pCreateInfo->bufferCount; i++) {
2042 add_cmd_buf_info(my_data, pCreateInfo->commandPool, pCommandBuffer[i]);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002043 }
2044 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002045 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski13b66742015-11-20 14:33:48 -07002046 printCBList(my_data, device);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002047 return result;
2048}
2049
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002050VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(
2051 VkDevice device,
2052 VkCommandPool commandPool,
2053 uint32_t commandBufferCount,
2054 const VkCommandBuffer *pCommandBuffers)
2055{
2056 VkBool32 skipCall = VK_FALSE;
2057 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2058
2059 loader_platform_thread_lock_mutex(&globalLock);
2060 for (uint32_t i = 0; i < commandBufferCount; i++) {
2061 skipCall |= delete_cmd_buf_info(my_data, commandPool, pCommandBuffers[i]);
2062 }
2063 printCBList(my_data, device);
2064 loader_platform_thread_unlock_mutex(&globalLock);
2065
2066 if (VK_FALSE == skipCall) {
2067 my_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
2068 }
2069}
2070
2071VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002072 VkDevice device,
2073 const VkCommandPoolCreateInfo *pCreateInfo,
2074 const VkAllocationCallbacks *pAllocator,
2075 VkCommandPool *pCommandPool)
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002076{
2077 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinskif2aff492015-11-19 08:31:31 -07002078 VkResult result = my_data->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002079
2080 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskif2aff492015-11-19 08:31:31 -07002081
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002082 // Add cmd pool to map
2083 my_data->commandPoolMap[*pCommandPool].createFlags = pCreateInfo->flags;
2084 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskif2aff492015-11-19 08:31:31 -07002085
2086 return result;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002087}
2088
2089VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002090 VkDevice device,
2091 VkCommandPool commandPool,
2092 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002093{
2094 VkBool32 commandBufferComplete = VK_FALSE;
2095 VkBool32 skipCall = VK_FALSE;
2096 // Verify that command buffers in pool are complete (not in-flight)
2097 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2098 for (auto it = my_data->commandPoolMap[commandPool].pCommandBuffers.begin();
2099 it != my_data->commandPoolMap[commandPool].pCommandBuffers.end(); it++) {
2100 commandBufferComplete = VK_FALSE;
2101 skipCall = checkCBCompleted(my_data, *it, &commandBufferComplete);
2102 if (VK_FALSE == commandBufferComplete) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002103 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)(*it), 0,
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002104 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", "Destroying Command Pool 0x%" PRIxLEAST64 " before "
2105 "its command buffer (0x%" PRIxLEAST64 ") has completed.", reinterpret_cast<uint64_t>(commandPool),
2106 reinterpret_cast<uint64_t>(*it));
2107 }
2108 }
2109
2110 if (VK_FALSE == skipCall) {
2111 my_data->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
2112 }
2113
Mark Lobodzinski13b66742015-11-20 14:33:48 -07002114 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002115 auto item = my_data->commandPoolMap[commandPool].pCommandBuffers.begin();
2116 // Remove command buffers from command buffer map
2117 while (item != my_data->commandPoolMap[commandPool].pCommandBuffers.end()) {
2118 auto del_item = item++;
2119 delete_cmd_buf_info(my_data, commandPool, *del_item);
2120 }
2121 my_data->commandPoolMap.erase(commandPool);
Mark Lobodzinski13b66742015-11-20 14:33:48 -07002122 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002123}
2124
2125VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002126 VkDevice device,
2127 VkCommandPool commandPool,
2128 VkCommandPoolResetFlags flags)
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002129{
2130 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2131 VkBool32 commandBufferComplete = VK_FALSE;
2132 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07002133 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002134
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002135 auto it = my_data->commandPoolMap[commandPool].pCommandBuffers.begin();
2136 // Verify that CB's in pool are complete (not in-flight)
2137 while (it != my_data->commandPoolMap[commandPool].pCommandBuffers.end()) {
2138 skipCall = checkCBCompleted(my_data, (*it), &commandBufferComplete);
2139 if (VK_FALSE == commandBufferComplete) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002140 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)(*it), 0,
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002141 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", "Resetting CB %p before it has completed. You must check CB "
2142 "flag before calling vkResetCommandBuffer().", (*it));
2143 } else {
Mark Lobodzinski13b66742015-11-20 14:33:48 -07002144 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002145 // Clear memory references at this point.
2146 skipCall |= clear_cmd_buf_and_mem_references(my_data, (*it));
Mark Lobodzinski13b66742015-11-20 14:33:48 -07002147 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002148 }
Tobin Ehlis4c8381e2015-12-14 13:46:38 -07002149 ++it;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002150 }
Mark Lobodzinskif2aff492015-11-19 08:31:31 -07002151
2152 if (VK_FALSE == skipCall) {
2153 result = my_data->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
2154 }
2155
2156 return result;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002157}
2158
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002159VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +08002160 VkCommandBuffer commandBuffer,
2161 const VkCommandBufferBeginInfo *pBeginInfo)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002162{
Chia-I Wu1f851912015-10-27 18:04:07 +08002163 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07002164 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002165 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +08002166 VkBool32 commandBufferComplete = VK_FALSE;
Mike Stroyan53430332015-05-19 15:16:08 -06002167 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002168
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07002169 // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references
Chia-I Wu1f851912015-10-27 18:04:07 +08002170 skipCall = checkCBCompleted(my_data, commandBuffer, &commandBufferComplete);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002171
Chia-I Wu1f851912015-10-27 18:04:07 +08002172 if (VK_FALSE == commandBufferComplete) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002173 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, 0,
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06002174 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", "Calling vkBeginCommandBuffer() on active CB %p before it has completed. "
Chia-I Wu1f851912015-10-27 18:04:07 +08002175 "You must check CB flag before this call.", commandBuffer);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07002176 }
Mike Stroyan53430332015-05-19 15:16:08 -06002177 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002178 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002179 result = my_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002180 }
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002181 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wu1f851912015-10-27 18:04:07 +08002182 clear_cmd_buf_and_mem_references(my_data, commandBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002183 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002184 return result;
2185}
2186
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002187VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +08002188 VkCommandBuffer commandBuffer)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002189{
Chia-I Wu1f851912015-10-27 18:04:07 +08002190 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002191 // TODO : Anything to do here?
Chia-I Wu1f851912015-10-27 18:04:07 +08002192 VkResult result = my_data->device_dispatch_table->EndCommandBuffer(commandBuffer);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002193 return result;
2194}
2195
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002196VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002197 VkCommandBuffer commandBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +08002198 VkCommandBufferResetFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002199{
Chia-I Wu1f851912015-10-27 18:04:07 +08002200 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07002201 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002202 VkBool32 skipCall = VK_FALSE;
Chia-I Wu1f851912015-10-27 18:04:07 +08002203 VkBool32 commandBufferComplete = VK_FALSE;
Mike Stroyan53430332015-05-19 15:16:08 -06002204 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002205
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07002206 // Verify that CB is complete (not in-flight)
Chia-I Wu1f851912015-10-27 18:04:07 +08002207 skipCall = checkCBCompleted(my_data, commandBuffer, &commandBufferComplete);
2208 if (VK_FALSE == commandBufferComplete) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002209 skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)commandBuffer, 0,
Mark Lobodzinski9d30cb12015-09-15 16:10:17 -06002210 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM", "Resetting CB %p before it has completed. You must check CB "
Chia-I Wu1f851912015-10-27 18:04:07 +08002211 "flag before calling vkResetCommandBuffer().", commandBuffer);
Tobin Ehlis77b3abb2015-03-04 08:38:22 -07002212 }
2213 // Clear memory references as this point.
Chia-I Wu1f851912015-10-27 18:04:07 +08002214 skipCall |= clear_cmd_buf_and_mem_references(my_data, commandBuffer);
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002215 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002216 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002217 result = my_data->device_dispatch_table->ResetCommandBuffer(commandBuffer, flags);
Courtney Goeltzenleuchter0d6857f2015-09-04 13:52:24 -06002218 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002219 return result;
2220}
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07002221
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002222// TODO : For any vkCmdBind* calls that include an object which has mem bound to it,
Chia-I Wu1f851912015-10-27 18:04:07 +08002223// need to account for that mem now having binding to given commandBuffer
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002224VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(
Chia-I Wuc51b1212015-10-27 19:25:11 +08002225 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002226 VkPipelineBindPoint pipelineBindPoint,
2227 VkPipeline pipeline)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002228{
Chia-I Wu1f851912015-10-27 18:04:07 +08002229 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07002230#if 0
Chia-I Wu1f851912015-10-27 18:04:07 +08002231 // TODO : If memory bound to pipeline, then need to tie that mem to commandBuffer
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07002232 if (getPipeline(pipeline)) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002233 MT_CB_INFO *pCBInfo = get_cmd_buf_info(my_data, commandBuffer);
Mark Lobodzinski7a428ce2015-03-31 16:05:35 -05002234 if (pCBInfo) {
2235 pCBInfo->pipelines[pipelineBindPoint] = pipeline;
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07002236 }
2237 }
2238 else {
Courtney Goeltzenleuchter3e19bf62015-06-14 09:50:18 -06002239 "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002240 layerCbMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, pipeline, 0, MEMTRACK_INVALID_OBJECT, (char *) "DS", (char *) str);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07002241 }
2242#endif
Chia-I Wu1f851912015-10-27 18:04:07 +08002243 my_data->device_dispatch_table->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002244}
2245
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002246VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(
Chia-I Wuc51b1212015-10-27 19:25:11 +08002247 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002248 VkPipelineBindPoint pipelineBindPoint,
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06002249 VkPipelineLayout layout,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002250 uint32_t firstSet,
2251 uint32_t setCount,
2252 const VkDescriptorSet *pDescriptorSets,
2253 uint32_t dynamicOffsetCount,
2254 const uint32_t *pDynamicOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002255{
Chia-I Wu1f851912015-10-27 18:04:07 +08002256 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Tobin Ehlis2836a7d2015-01-08 15:22:32 -07002257 // TODO : Somewhere need to verify that all textures referenced by shaders in DS are in some type of *SHADER_READ* state
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002258 my_data->device_dispatch_table->CmdBindDescriptorSets(
Chia-I Wu1f851912015-10-27 18:04:07 +08002259 commandBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002260}
2261
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002262VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(
Chia-I Wuc51b1212015-10-27 19:25:11 +08002263 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002264 uint32_t startBinding,
2265 uint32_t bindingCount,
2266 const VkBuffer *pBuffers,
2267 const VkDeviceSize *pOffsets)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002268{
Chia-I Wu1f851912015-10-27 18:04:07 +08002269 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002270 bool skip_call = false;
2271 for (int i = 0; i < bindingCount; ++i) {
2272 VkDeviceMemory mem;
2273 skip_call |= get_mem_binding_from_object(my_data, commandBuffer, reinterpret_cast<uint64_t>(pBuffers[i]),
2274 VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
2275 skip_call |= validate_memory_is_valid(my_data, mem);
2276 }
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002277 // TODO : Somewhere need to verify that VBs have correct usage state flagged
Michael Lentine6306a5a2015-11-24 17:55:33 -06002278 if (!skip_call)
2279 my_data->device_dispatch_table->CmdBindVertexBuffers(commandBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Chia-I Wufb5062e2015-01-05 13:42:56 +08002280}
2281
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002282VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002283 VkCommandBuffer commandBuffer,
2284 VkBuffer buffer,
2285 VkDeviceSize offset,
2286 VkIndexType indexType)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002287{
Chia-I Wu1f851912015-10-27 18:04:07 +08002288 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002289 VkDeviceMemory mem;
2290 bool skip_call = get_mem_binding_from_object(my_data, commandBuffer, reinterpret_cast<uint64_t>(buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
2291 skip_call |= validate_memory_is_valid(my_data, mem);
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002292 // TODO : Somewhere need to verify that IBs have correct usage state flagged
Michael Lentine6306a5a2015-11-24 17:55:33 -06002293 if (!skip_call)
2294 my_data->device_dispatch_table->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002295}
2296
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002297VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002298 VkCommandBuffer commandBuffer,
2299 VkBuffer buffer,
2300 VkDeviceSize offset,
2301 uint32_t count,
2302 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002303{
Chia-I Wu1f851912015-10-27 18:04:07 +08002304 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002305 VkDeviceMemory mem;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002306 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002307 VkBool32 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Chia-I Wu1f851912015-10-27 18:04:07 +08002308 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdDrawIndirect");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002309 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002310 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002311 my_data->device_dispatch_table->CmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002312 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002313}
2314
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002315VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002316 VkCommandBuffer commandBuffer,
2317 VkBuffer buffer,
2318 VkDeviceSize offset,
2319 uint32_t count,
2320 uint32_t stride)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002321{
Chia-I Wu1f851912015-10-27 18:04:07 +08002322 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002323 VkDeviceMemory mem;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002324 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002325 VkBool32 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Chia-I Wu1f851912015-10-27 18:04:07 +08002326 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdDrawIndexedIndirect");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002327 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002328 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002329 my_data->device_dispatch_table->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002330 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002331}
2332
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002333VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002334 VkCommandBuffer commandBuffer,
2335 VkBuffer buffer,
2336 VkDeviceSize offset)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002337{
Chia-I Wu1f851912015-10-27 18:04:07 +08002338 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002339 VkDeviceMemory mem;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002340 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002341 VkBool32 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Chia-I Wu1f851912015-10-27 18:04:07 +08002342 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdDispatchIndirect");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002343 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002344 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002345 my_data->device_dispatch_table->CmdDispatchIndirect(commandBuffer, buffer, offset);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002346 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002347}
2348
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002349VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +08002350 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002351 VkBuffer srcBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +08002352 VkBuffer dstBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002353 uint32_t regionCount,
2354 const VkBufferCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002355{
Chia-I Wu1f851912015-10-27 18:04:07 +08002356 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002357 VkDeviceMemory mem;
2358 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002359 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002360 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002361 skipCall |= validate_memory_is_valid(my_data, mem);
Chia-I Wu1f851912015-10-27 18:04:07 +08002362 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyBuffer");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002363 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002364 set_memory_valid(my_data, mem, true);
Chia-I Wu1f851912015-10-27 18:04:07 +08002365 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002366 // Validate that SRC & DST buffers have correct usage flags set
Chia-I Wu1f851912015-10-27 18:04:07 +08002367 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
2368 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002369 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002370 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002371 my_data->device_dispatch_table->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002372 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002373}
2374
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002375VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002376 VkCommandBuffer commandBuffer,
2377 VkQueryPool queryPool,
2378 uint32_t startQuery,
2379 uint32_t queryCount,
2380 VkBuffer dstBuffer,
2381 VkDeviceSize dstOffset,
2382 VkDeviceSize destStride,
2383 VkQueryResultFlags flags)
Mike Stroyan4081bdc2015-10-15 08:42:32 -06002384{
Chia-I Wu1f851912015-10-27 18:04:07 +08002385 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mike Stroyan4081bdc2015-10-15 08:42:32 -06002386 VkDeviceMemory mem;
2387 VkBool32 skipCall = VK_FALSE;
2388 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002389 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002390 set_memory_valid(my_data, mem, true);
Chia-I Wu1f851912015-10-27 18:04:07 +08002391 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyQueryPoolResults");
Mike Stroyan4081bdc2015-10-15 08:42:32 -06002392 // Validate that DST buffer has correct usage flags set
Chia-I Wu1f851912015-10-27 18:04:07 +08002393 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyQueryPoolResults()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mike Stroyan4081bdc2015-10-15 08:42:32 -06002394 loader_platform_thread_unlock_mutex(&globalLock);
2395 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002396 my_data->device_dispatch_table->CmdCopyQueryPoolResults(commandBuffer, queryPool, startQuery, queryCount, dstBuffer, dstOffset, destStride, flags);
Mike Stroyan4081bdc2015-10-15 08:42:32 -06002397 }
2398}
2399
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002400VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(
Chia-I Wu1f851912015-10-27 18:04:07 +08002401 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002402 VkImage srcImage,
2403 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +08002404 VkImage dstImage,
2405 VkImageLayout dstImageLayout,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002406 uint32_t regionCount,
2407 const VkImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002408{
Chia-I Wu1f851912015-10-27 18:04:07 +08002409 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002410 VkDeviceMemory mem;
2411 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002412 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002413 // Validate that src & dst images have correct usage flags set
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002414 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002415 skipCall |= validate_memory_is_valid(my_data, mem, srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002416 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyImage");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002417 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002418 set_memory_valid(my_data, mem, true, dstImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002419 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyImage");
2420 skipCall |= validate_image_usage_flags(my_data, commandBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
2421 skipCall |= validate_image_usage_flags(my_data, commandBuffer, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002422 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002423 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002424 my_data->device_dispatch_table->CmdCopyImage(
Chia-I Wu1f851912015-10-27 18:04:07 +08002425 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002426 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002427}
2428
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002429VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002430 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002431 VkImage srcImage,
2432 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +08002433 VkImage dstImage,
2434 VkImageLayout dstImageLayout,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002435 uint32_t regionCount,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002436 const VkImageBlit *pRegions,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002437 VkFilter filter)
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06002438{
Chia-I Wu1f851912015-10-27 18:04:07 +08002439 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002440 VkDeviceMemory mem;
2441 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002442 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002443 // Validate that src & dst images have correct usage flags set
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002444 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002445 skipCall |= validate_memory_is_valid(my_data, mem, srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002446 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdBlitImage");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002447 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002448 set_memory_valid(my_data, mem, true, dstImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002449 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdBlitImage");
2450 skipCall |= validate_image_usage_flags(my_data, commandBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
2451 skipCall |= validate_image_usage_flags(my_data, commandBuffer, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdBlitImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002452 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002453 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002454 my_data->device_dispatch_table->CmdBlitImage(
Chia-I Wu1f851912015-10-27 18:04:07 +08002455 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002456 }
Courtney Goeltzenleuchterb787a1e2015-03-08 17:02:18 -06002457}
2458
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002459VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002460 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002461 VkBuffer srcBuffer,
Chia-I Wu1f851912015-10-27 18:04:07 +08002462 VkImage dstImage,
2463 VkImageLayout dstImageLayout,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002464 uint32_t regionCount,
2465 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002466{
Chia-I Wu1f851912015-10-27 18:04:07 +08002467 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002468 VkDeviceMemory mem;
2469 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002470 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002471 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002472 set_memory_valid(my_data, mem, true, dstImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002473 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyBufferToImage");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002474 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002475 skipCall |= validate_memory_is_valid(my_data, mem);
Chia-I Wu1f851912015-10-27 18:04:07 +08002476 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyBufferToImage");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002477 // Validate that src buff & dst image have correct usage flags set
Chia-I Wu1f851912015-10-27 18:04:07 +08002478 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, srcBuffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
2479 skipCall |= validate_image_usage_flags(my_data, commandBuffer, dstImage, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002480 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002481 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002482 my_data->device_dispatch_table->CmdCopyBufferToImage(
Chia-I Wu1f851912015-10-27 18:04:07 +08002483 commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002484 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002485}
2486
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002487VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002488 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002489 VkImage srcImage,
2490 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +08002491 VkBuffer dstBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002492 uint32_t regionCount,
2493 const VkBufferImageCopy *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002494{
Chia-I Wu1f851912015-10-27 18:04:07 +08002495 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002496 VkDeviceMemory mem;
2497 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002498 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002499 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002500 skipCall |= validate_memory_is_valid(my_data, mem, srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002501 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyImageToBuffer");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002502 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002503 set_memory_valid(my_data, mem, true);
Chia-I Wu1f851912015-10-27 18:04:07 +08002504 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdCopyImageToBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002505 // Validate that dst buff & src image have correct usage flags set
Chia-I Wu1f851912015-10-27 18:04:07 +08002506 skipCall |= validate_image_usage_flags(my_data, commandBuffer, srcImage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
2507 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002508 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002509 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002510 my_data->device_dispatch_table->CmdCopyImageToBuffer(
Chia-I Wu1f851912015-10-27 18:04:07 +08002511 commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002512 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002513}
2514
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002515VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002516 VkCommandBuffer commandBuffer,
2517 VkBuffer dstBuffer,
2518 VkDeviceSize dstOffset,
2519 VkDeviceSize dataSize,
2520 const uint32_t *pData)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002521{
Chia-I Wu1f851912015-10-27 18:04:07 +08002522 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002523 VkDeviceMemory mem;
2524 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002525 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002526 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002527 set_memory_valid(my_data, mem, true);
Chia-I Wu1f851912015-10-27 18:04:07 +08002528 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdUpdateBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002529 // Validate that dst buff has correct usage flags set
Chia-I Wu1f851912015-10-27 18:04:07 +08002530 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdUpdateBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002531 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002532 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002533 my_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002534 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002535}
2536
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002537VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002538 VkCommandBuffer commandBuffer,
2539 VkBuffer dstBuffer,
2540 VkDeviceSize dstOffset,
2541 VkDeviceSize size,
2542 uint32_t data)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002543{
Chia-I Wu1f851912015-10-27 18:04:07 +08002544 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002545 VkDeviceMemory mem;
2546 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002547 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002548 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002549 set_memory_valid(my_data, mem, true);
Chia-I Wu1f851912015-10-27 18:04:07 +08002550 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdFillBuffer");
Tobin Ehlisd94ba722015-07-03 08:45:14 -06002551 // Validate that dst buff has correct usage flags set
Chia-I Wu1f851912015-10-27 18:04:07 +08002552 skipCall |= validate_buffer_usage_flags(my_data, commandBuffer, dstBuffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, "vkCmdFillBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002553 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002554 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002555 my_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002556 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002557}
2558
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002559VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002560 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002561 VkImage image,
2562 VkImageLayout imageLayout,
Chris Forbese3105972015-06-24 14:34:53 +12002563 const VkClearColorValue *pColor,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002564 uint32_t rangeCount,
2565 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002566{
Chia-I Wu1f851912015-10-27 18:04:07 +08002567 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002568 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002569 VkDeviceMemory mem;
2570 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002571 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002572 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002573 set_memory_valid(my_data, mem, true, image);
Chia-I Wu1f851912015-10-27 18:04:07 +08002574 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdClearColorImage");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002575 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002576 if (VK_FALSE == skipCall) {
Chia-I Wu1f851912015-10-27 18:04:07 +08002577 my_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002578 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002579}
2580
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002581VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002582 VkCommandBuffer commandBuffer,
2583 VkImage image,
2584 VkImageLayout imageLayout,
2585 const VkClearDepthStencilValue *pDepthStencil,
2586 uint32_t rangeCount,
2587 const VkImageSubresourceRange *pRanges)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002588{
Chia-I Wu1f851912015-10-27 18:04:07 +08002589 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002590 // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002591 VkDeviceMemory mem;
2592 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002593 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002594 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002595 set_memory_valid(my_data, mem, true, image);
Chia-I Wu1f851912015-10-27 18:04:07 +08002596 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdClearDepthStencilImage");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002597 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002598 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002599 my_data->device_dispatch_table->CmdClearDepthStencilImage(
Chia-I Wu1f851912015-10-27 18:04:07 +08002600 commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002601 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002602}
2603
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002604VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002605 VkCommandBuffer commandBuffer,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002606 VkImage srcImage,
2607 VkImageLayout srcImageLayout,
Chia-I Wu1f851912015-10-27 18:04:07 +08002608 VkImage dstImage,
2609 VkImageLayout dstImageLayout,
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002610 uint32_t regionCount,
2611 const VkImageResolve *pRegions)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002612{
Chia-I Wu1f851912015-10-27 18:04:07 +08002613 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002614 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002615 loader_platform_thread_lock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002616 VkDeviceMemory mem;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002617 skipCall = get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002618 skipCall |= validate_memory_is_valid(my_data, mem, srcImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002619 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdResolveImage");
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002620 skipCall |= get_mem_binding_from_object(my_data, commandBuffer, (uint64_t)dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
Michael Lentine6306a5a2015-11-24 17:55:33 -06002621 set_memory_valid(my_data, mem, true, dstImage);
Chia-I Wu1f851912015-10-27 18:04:07 +08002622 skipCall |= update_cmd_buf_and_mem_references(my_data, commandBuffer, mem, "vkCmdResolveImage");
Mark Lobodzinski0c0d6a02015-03-02 20:23:52 -06002623 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002624 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002625 my_data->device_dispatch_table->CmdResolveImage(
Chia-I Wu1f851912015-10-27 18:04:07 +08002626 commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002627 }
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002628}
2629
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002630VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(
Chia-I Wu1f851912015-10-27 18:04:07 +08002631 VkCommandBuffer commandBuffer,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002632 VkQueryPool queryPool,
2633 uint32_t slot,
2634 VkFlags flags)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002635{
Chia-I Wu1f851912015-10-27 18:04:07 +08002636 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
2637 my_data->device_dispatch_table->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002638}
2639
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002640VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(
Chia-I Wu1f851912015-10-27 18:04:07 +08002641 VkCommandBuffer commandBuffer,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002642 VkQueryPool queryPool,
2643 uint32_t slot)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002644{
Chia-I Wu1f851912015-10-27 18:04:07 +08002645 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
2646 my_data->device_dispatch_table->CmdEndQuery(commandBuffer, queryPool, slot);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002647}
2648
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002649VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(
Chia-I Wu1f851912015-10-27 18:04:07 +08002650 VkCommandBuffer commandBuffer,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002651 VkQueryPool queryPool,
2652 uint32_t startQuery,
2653 uint32_t queryCount)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002654{
Chia-I Wu1f851912015-10-27 18:04:07 +08002655 layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
2656 my_data->device_dispatch_table->CmdResetQueryPool(commandBuffer, queryPool, startQuery, queryCount);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002657}
2658
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002659VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
2660 VkInstance instance,
2661 const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
2662 const VkAllocationCallbacks* pAllocator,
2663 VkDebugReportCallbackEXT* pMsgCallback)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002664{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002665 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2666 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002667 VkResult res = pTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002668 if (res == VK_SUCCESS) {
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07002669 res = layer_create_msg_callback(my_data->report_data, pCreateInfo, pAllocator, pMsgCallback);
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002670 }
2671 return res;
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002672}
2673
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002674VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07002675 VkInstance instance,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002676 VkDebugReportCallbackEXT msgCallback,
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07002677 const VkAllocationCallbacks* pAllocator)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002678{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06002679 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002680 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002681 pTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -07002682 layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002683}
2684
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002685VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
Courtney Goeltzenleuchter5a424ce2015-12-01 14:10:55 -07002686 VkInstance instance,
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002687 VkDebugReportFlagsEXT flags,
2688 VkDebugReportObjectTypeEXT objType,
Courtney Goeltzenleuchter5a424ce2015-12-01 14:10:55 -07002689 uint64_t object,
2690 size_t location,
2691 int32_t msgCode,
2692 const char* pLayerPrefix,
2693 const char* pMsg)
2694{
2695 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002696 my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter5a424ce2015-12-01 14:10:55 -07002697}
2698
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002699VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
Mark Lobodzinskia908b162015-04-21 15:33:04 -06002700 VkDevice device,
Ian Elliott338dedb2015-08-21 15:09:33 -06002701 const VkSwapchainCreateInfoKHR *pCreateInfo,
Ian Elliottc623ba52015-11-20 14:13:17 -07002702 const VkAllocationCallbacks *pAllocator,
Ian Elliott338dedb2015-08-21 15:09:33 -06002703 VkSwapchainKHR *pSwapchain)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002704{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002705 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Ian Elliottc623ba52015-11-20 14:13:17 -07002706 VkResult result = my_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002707
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002708 if (VK_SUCCESS == result) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002709 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002710 add_swap_chain_info(my_data, *pSwapchain, pCreateInfo);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002711 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis62086412014-11-19 16:19:28 -07002712 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002713
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002714 return result;
2715}
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002716
Ian Elliottc623ba52015-11-20 14:13:17 -07002717VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(
2718 VkDevice device,
2719 VkSwapchainKHR swapchain,
2720 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002721{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002722 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002723 VkBool32 skipCall = VK_FALSE;
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002724 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002725 if (my_data->swapchainMap.find(swapchain) != my_data->swapchainMap.end()) {
2726 MT_SWAP_CHAIN_INFO* pInfo = my_data->swapchainMap[swapchain];
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002727
David Pinedof5997ab2015-04-27 16:36:17 -06002728 if (pInfo->images.size() > 0) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002729 for (auto it = pInfo->images.begin(); it != pInfo->images.end(); it++) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002730 skipCall = clear_object_binding(my_data, device, (uint64_t)*it, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002731 auto image_item = my_data->imageMap.find((uint64_t)*it);
2732 if (image_item != my_data->imageMap.end())
2733 my_data->imageMap.erase(image_item);
David Pinedof5997ab2015-04-27 16:36:17 -06002734 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002735 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002736 delete pInfo;
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002737 my_data->swapchainMap.erase(swapchain);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002738 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002739 loader_platform_thread_unlock_mutex(&globalLock);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002740 if (VK_FALSE == skipCall) {
Ian Elliottc623ba52015-11-20 14:13:17 -07002741 my_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
Mark Lobodzinski87db5012015-09-14 17:43:42 -06002742 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002743}
2744
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002745VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002746 VkDevice device,
2747 VkSwapchainKHR swapchain,
2748 uint32_t *pCount,
2749 VkImage *pSwapchainImages)
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002750{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002751 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2752 VkResult result = my_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002753
Ian Elliott338dedb2015-08-21 15:09:33 -06002754 if (result == VK_SUCCESS && pSwapchainImages != NULL) {
Ian Elliottccac0232015-08-07 14:11:14 -06002755 const size_t count = *pCount;
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002756 MT_SWAP_CHAIN_INFO *pInfo = my_data->swapchainMap[swapchain];
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002757
2758 if (pInfo->images.empty()) {
2759 pInfo->images.resize(count);
Ian Elliott338dedb2015-08-21 15:09:33 -06002760 memcpy(&pInfo->images[0], pSwapchainImages, sizeof(pInfo->images[0]) * count);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002761
David Pinedof5997ab2015-04-27 16:36:17 -06002762 if (pInfo->images.size() > 0) {
Ian Elliottccac0232015-08-07 14:11:14 -06002763 for (std::vector<VkImage>::const_iterator it = pInfo->images.begin();
David Pinedof5997ab2015-04-27 16:36:17 -06002764 it != pInfo->images.end(); it++) {
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06002765 // Add image object binding, then insert the new Mem Object and then bind it to created image
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002766 add_object_create_info(my_data, (uint64_t)*it, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, &pInfo->createInfo);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002767 }
2768 }
2769 } else {
Ian Elliottccac0232015-08-07 14:11:14 -06002770 const size_t count = *pCount;
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002771 MT_SWAP_CHAIN_INFO *pInfo = my_data->swapchainMap[swapchain];
Michael Lentine62c60c32015-10-29 10:41:47 -07002772 const VkBool32 mismatch = (pInfo->images.size() != count ||
Ian Elliott338dedb2015-08-21 15:09:33 -06002773 memcmp(&pInfo->images[0], pSwapchainImages, sizeof(pInfo->images[0]) * count));
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002774
2775 if (mismatch) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002776 // TODO: Verify against Valid Usage section of extension
2777 log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, (uint64_t) swapchain, 0, MEMTRACK_NONE, "SWAP_CHAIN",
Michael Lentinecbc4a5e2015-11-03 16:19:46 -08002778 "vkGetSwapchainInfoKHR(%" PRIu64 ", VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_KHR) returned mismatching data", reinterpret_cast<uint64_t>(swapchain));
Chia-I Wu5b66aa52015-04-16 22:02:10 +08002779 }
2780 }
2781 }
Mark Lobodzinski4aad3642015-03-17 10:53:12 -05002782 return result;
2783}
Tobin Ehlis791a49c2014-11-10 12:29:12 -07002784
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002785VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002786 VkDevice device,
2787 VkSwapchainKHR swapchain,
2788 uint64_t timeout,
2789 VkSemaphore semaphore,
Ian Elliottc623ba52015-11-20 14:13:17 -07002790 VkFence fence,
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002791 uint32_t *pImageIndex)
2792{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002793 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Courtney Goeltzenleuchter48605a52015-12-10 16:41:22 -07002794 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002795 VkBool32 skipCall = VK_FALSE;
2796
2797 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002798 if (my_data->semaphoreMap.find(semaphore) != my_data->semaphoreMap.end()) {
2799 if (my_data->semaphoreMap[semaphore] != MEMTRACK_SEMAPHORE_STATE_UNSET) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -07002800 skipCall = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, (uint64_t)semaphore,
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002801 0, MEMTRACK_NONE, "SEMAPHORE",
2802 "vkAcquireNextImageKHR: Semaphore must not be currently signaled or in a wait state");
2803 }
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002804 my_data->semaphoreMap[semaphore] = MEMTRACK_SEMAPHORE_STATE_SIGNALLED;
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002805 }
2806 loader_platform_thread_unlock_mutex(&globalLock);
2807 if (VK_FALSE == skipCall) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002808 result = my_data->device_dispatch_table->AcquireNextImageKHR(device,
Ian Elliottc623ba52015-11-20 14:13:17 -07002809 swapchain, timeout, semaphore, fence, pImageIndex);
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002810 }
2811 return result;
2812}
2813
Michael Lentine6306a5a2015-11-24 17:55:33 -06002814VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
2815 VkQueue queue,
2816 const VkPresentInfoKHR* pPresentInfo)
2817{
Mark Lobodzinski75fae592015-12-18 09:24:52 -07002818 VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
Michael Lentine6306a5a2015-11-24 17:55:33 -06002819 layer_data *my_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
2820 bool skip_call = false;
2821 VkDeviceMemory mem;
2822 for (int i = 0; i < pPresentInfo->swapchainCount; ++i) {
2823 MT_SWAP_CHAIN_INFO *pInfo = my_data->swapchainMap[pPresentInfo->pSwapchains[i]];
2824 VkImage image = pInfo->images[pPresentInfo->pImageIndices[i]];
2825 skip_call |= get_mem_binding_from_object(my_data, queue, reinterpret_cast<uint64_t>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &mem);
2826 skip_call |= validate_memory_is_valid(my_data, mem, image);
2827 }
Mark Lobodzinski75fae592015-12-18 09:24:52 -07002828 if (!skip_call) {
2829 result = my_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
2830 }
2831 return result;
Michael Lentine6306a5a2015-11-24 17:55:33 -06002832}
2833
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002834VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002835 VkDevice device,
2836 const VkSemaphoreCreateInfo *pCreateInfo,
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002837 const VkAllocationCallbacks *pAllocator,
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002838 VkSemaphore *pSemaphore)
2839{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002840 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Chia-I Wu69f40122015-10-26 21:10:41 +08002841 VkResult result = my_data->device_dispatch_table->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002842 loader_platform_thread_lock_mutex(&globalLock);
Chia-I Wue420a332015-10-26 20:04:44 +08002843 if (*pSemaphore != VK_NULL_HANDLE) {
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002844 my_data->semaphoreMap[*pSemaphore] = MEMTRACK_SEMAPHORE_STATE_UNSET;
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002845 }
2846 loader_platform_thread_unlock_mutex(&globalLock);
2847 return result;
2848}
2849
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08002850VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07002851 VkDevice device,
2852 VkSemaphore semaphore,
2853 const VkAllocationCallbacks *pAllocator)
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002854{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06002855 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002856 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis96310ff2015-10-29 09:03:52 -06002857 auto item = my_data->semaphoreMap.find(semaphore);
2858 if (item != my_data->semaphoreMap.end()) {
2859 my_data->semaphoreMap.erase(item);
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002860 }
2861 loader_platform_thread_unlock_mutex(&globalLock);
Chia-I Wu69f40122015-10-26 21:10:41 +08002862 my_data->device_dispatch_table->DestroySemaphore(device, semaphore, pAllocator);
Mark Lobodzinski2a253072015-10-08 10:44:07 -06002863}
2864
Michael Lentine6306a5a2015-11-24 17:55:33 -06002865VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(
2866 VkDevice device,
2867 const VkFramebufferCreateInfo* pCreateInfo,
2868 const VkAllocationCallbacks* pAllocator,
2869 VkFramebuffer* pFramebuffer)
2870{
2871 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2872 VkResult result = my_data->device_dispatch_table->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
2873 for (int i = 0; i < pCreateInfo->attachmentCount; ++i) {
2874 VkImageView view = pCreateInfo->pAttachments[i];
2875 loader_platform_thread_lock_mutex(&globalLock);
2876 auto view_data = my_data->imageViewMap.find(view);
2877 if (view_data == my_data->imageViewMap.end()) {
2878 loader_platform_thread_unlock_mutex(&globalLock);
2879 continue;
2880 }
2881 MT_FB_ATTACHMENT_INFO fb_info;
2882 get_mem_binding_from_object(my_data, device, reinterpret_cast<uint64_t>(view_data->second.image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, &fb_info.mem);
2883 fb_info.image = view_data->second.image;
2884 my_data->fbMap[*pFramebuffer].attachments.push_back(fb_info);
2885 loader_platform_thread_unlock_mutex(&globalLock);
2886 }
2887 return result;
2888}
2889
Mark Lobodzinski75fae592015-12-18 09:24:52 -07002890VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(
2891 VkDevice device,
2892 VkFramebuffer framebuffer,
2893 const VkAllocationCallbacks* pAllocator)
2894{
2895 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2896
2897 auto item = my_data->fbMap.find(framebuffer);
2898 loader_platform_thread_lock_mutex(&globalLock);
2899 if (item != my_data->fbMap.end()) {
2900 my_data->fbMap.erase(framebuffer);
2901 }
2902 loader_platform_thread_unlock_mutex(&globalLock);
2903
2904 my_data->device_dispatch_table->DestroyFramebuffer(device, framebuffer, pAllocator);
2905}
2906
Michael Lentine6306a5a2015-11-24 17:55:33 -06002907VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(
2908 VkDevice device,
2909 const VkRenderPassCreateInfo* pCreateInfo,
2910 const VkAllocationCallbacks* pAllocator,
2911 VkRenderPass* pRenderPass)
2912{
2913 layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2914 VkResult result = my_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
2915 for (int i = 0; i < pCreateInfo->attachmentCount; ++i) {
2916 VkAttachmentDescription desc = pCreateInfo->pAttachments[i];
2917 MT_PASS_ATTACHMENT_INFO pass_info;
2918 pass_info.load_op = desc.loadOp;
2919 pass_info.store_op = desc.storeOp;
Michael Lentinea3c1c002015-12-22 11:36:14 -06002920 pass_info.attachment = i;
Michael Lentine6306a5a2015-11-24 17:55:33 -06002921 loader_platform_thread_lock_mutex(&globalLock);
2922 my_data->passMap[*pRenderPass].attachments.push_back(pass_info);
2923 loader_platform_thread_unlock_mutex(&globalLock);
2924 }
Michael Lentinea3c1c002015-12-22 11:36:14 -06002925 //TODO: Maybe fill list and then copy instead of locking
2926 loader_platform_thread_lock_mutex(&globalLock);
2927 std::unordered_map<uint32_t, bool>& attachment_first_read = my_data->passMap[*pRenderPass].attachment_first_read;
2928 for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
2929 const VkSubpassDescription& subpass = pCreateInfo->pSubpasses[i];
2930 for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
2931 uint32_t attachment = subpass.pInputAttachments[j].attachment;
2932 if (attachment_first_read.count(attachment)) continue;
2933 attachment_first_read.insert(std::make_pair(attachment, true));
2934 }
2935 for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
2936 uint32_t attachment = subpass.pColorAttachments[j].attachment;
2937 if (attachment_first_read.count(attachment)) continue;
2938 attachment_first_read.insert(std::make_pair(attachment, false));
2939 }
2940 if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
2941 uint32_t attachment = subpass.pDepthStencilAttachment->attachment;
2942 if (attachment_first_read.count(attachment)) continue;
2943 attachment_first_read.insert(std::make_pair(attachment, false));
2944 }
2945 }
2946 loader_platform_thread_unlock_mutex(&globalLock);
2947
Michael Lentine6306a5a2015-11-24 17:55:33 -06002948 return result;
2949}
2950
2951VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(
2952 VkCommandBuffer cmdBuffer,
2953 const VkRenderPassBeginInfo *pRenderPassBegin,
2954 VkSubpassContents contents)
2955{
2956 layer_data *my_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
2957 bool skip_call = false;
Mark Lobodzinski75fae592015-12-18 09:24:52 -07002958 if (pRenderPassBegin) {
2959 loader_platform_thread_lock_mutex(&globalLock);
2960 auto pass_data = my_data->passMap.find(pRenderPassBegin->renderPass);
2961 if (pass_data != my_data->passMap.end()) {
2962 MT_PASS_INFO& pass_info = pass_data->second;
2963 pass_info.fb = pRenderPassBegin->framebuffer;
2964 for (int i = 0; i < pass_info.attachments.size(); ++i) {
2965 MT_FB_ATTACHMENT_INFO& fb_info = my_data->fbMap[pass_info.fb].attachments[i];
2966 if (pass_info.attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
2967 set_memory_valid(my_data, fb_info.mem, true, fb_info.image);
Michael Lentinea3c1c002015-12-22 11:36:14 -06002968 } else if (pass_info.attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) {
2969 set_memory_valid(my_data, fb_info.mem, false, fb_info.image);
Mark Lobodzinski75fae592015-12-18 09:24:52 -07002970 } else if (pass_info.attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_LOAD) {
2971 skip_call |= validate_memory_is_valid(my_data, fb_info.mem, fb_info.image);
2972 }
Michael Lentinea3c1c002015-12-22 11:36:14 -06002973 if (pass_info.attachment_first_read[pass_info.attachments[i].attachment]) {
2974 skip_call |= validate_memory_is_valid(my_data, fb_info.mem, fb_info.image);
2975 }
Michael Lentine6306a5a2015-11-24 17:55:33 -06002976 }
Mark Lobodzinski75fae592015-12-18 09:24:52 -07002977 auto cb_data = my_data->cbMap.find(cmdBuffer);
2978 if (cb_data != my_data->cbMap.end()) {
2979 cb_data->second.pass = pRenderPassBegin->renderPass;
2980 }
Michael Lentine6306a5a2015-11-24 17:55:33 -06002981 }
2982 loader_platform_thread_unlock_mutex(&globalLock);
2983 }
2984 if (!skip_call)
2985 return my_data->device_dispatch_table->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin, contents);
2986}
2987
2988VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(
2989 VkCommandBuffer cmdBuffer)
2990{
2991 layer_data *my_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
2992 auto cb_data = my_data->cbMap.find(cmdBuffer);
2993 if (cb_data != my_data->cbMap.end()) {
2994 auto pass_data = my_data->passMap.find(cb_data->second.pass);
2995 if (pass_data != my_data->passMap.end()) {
2996 MT_PASS_INFO& pass_info = pass_data->second;
2997 for (int i = 0; i < pass_info.attachments.size(); ++i) {
2998 MT_FB_ATTACHMENT_INFO& fb_info = my_data->fbMap[pass_info.fb].attachments[i];
2999 if (pass_info.attachments[i].store_op == VK_ATTACHMENT_STORE_OP_STORE) {
3000 set_memory_valid(my_data, fb_info.mem, true, fb_info.image);
3001 } else if (pass_info.attachments[i].store_op == VK_ATTACHMENT_STORE_OP_DONT_CARE) {
3002 set_memory_valid(my_data, fb_info.mem, false, fb_info.image);
3003 }
3004 }
3005 }
3006 }
3007 my_data->device_dispatch_table->CmdEndRenderPass(cmdBuffer);
3008}
3009
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08003010VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07003011 VkDevice dev,
3012 const char *funcName)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07003013{
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003014 if (dev == NULL)
Tobin Ehlis791a49c2014-11-10 12:29:12 -07003015 return NULL;
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05003016
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003017 layer_data *my_data;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003018 /* loader uses this to force layer initialization; device object is wrapped */
3019 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003020 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev;
3021 my_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
3022 my_data->device_dispatch_table = new VkLayerDispatchTable;
3023 layer_initialize_dispatch_table(my_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003024 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003025 }
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06003026 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003027 return (PFN_vkVoidFunction) vkCreateDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003028 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003029 return (PFN_vkVoidFunction) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003030 if (!strcmp(funcName, "vkQueueSubmit"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003031 return (PFN_vkVoidFunction) vkQueueSubmit;
Chia-I Wu1f851912015-10-27 18:04:07 +08003032 if (!strcmp(funcName, "vkAllocateMemory"))
3033 return (PFN_vkVoidFunction) vkAllocateMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003034 if (!strcmp(funcName, "vkFreeMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003035 return (PFN_vkVoidFunction) vkFreeMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003036 if (!strcmp(funcName, "vkMapMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003037 return (PFN_vkVoidFunction) vkMapMemory;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003038 if (!strcmp(funcName, "vkUnmapMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003039 return (PFN_vkVoidFunction) vkUnmapMemory;
Michael Lentine62c60c32015-10-29 10:41:47 -07003040 if (!strcmp(funcName, "vkFlushMappedMemoryRanges"))
3041 return (PFN_vkVoidFunction) vkFlushMappedMemoryRanges;
3042 if (!strcmp(funcName, "vkInvalidateMappedMemoryRanges"))
3043 return (PFN_vkVoidFunction) vkInvalidateMappedMemoryRanges;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003044 if (!strcmp(funcName, "vkDestroyFence"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003045 return (PFN_vkVoidFunction) vkDestroyFence;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003046 if (!strcmp(funcName, "vkDestroyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003047 return (PFN_vkVoidFunction) vkDestroyBuffer;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003048 if (!strcmp(funcName, "vkDestroyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003049 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003050 if (!strcmp(funcName, "vkBindBufferMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003051 return (PFN_vkVoidFunction) vkBindBufferMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003052 if (!strcmp(funcName, "vkBindImageMemory"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003053 return (PFN_vkVoidFunction) vkBindImageMemory;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003054 if (!strcmp(funcName, "vkGetBufferMemoryRequirements"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003055 return (PFN_vkVoidFunction) vkGetBufferMemoryRequirements;
Tobin Ehlis92f12cd2015-07-08 17:08:02 -06003056 if (!strcmp(funcName, "vkGetImageMemoryRequirements"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003057 return (PFN_vkVoidFunction) vkGetImageMemoryRequirements;
Chia-I Wu06809d52015-10-26 16:55:27 +08003058 if (!strcmp(funcName, "vkQueueBindSparse"))
3059 return (PFN_vkVoidFunction) vkQueueBindSparse;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003060 if (!strcmp(funcName, "vkCreateFence"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003061 return (PFN_vkVoidFunction) vkCreateFence;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003062 if (!strcmp(funcName, "vkGetFenceStatus"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003063 return (PFN_vkVoidFunction) vkGetFenceStatus;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003064 if (!strcmp(funcName, "vkResetFences"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003065 return (PFN_vkVoidFunction) vkResetFences;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003066 if (!strcmp(funcName, "vkWaitForFences"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003067 return (PFN_vkVoidFunction) vkWaitForFences;
Mark Lobodzinski2a253072015-10-08 10:44:07 -06003068 if (!strcmp(funcName, "vkCreateSemaphore"))
3069 return (PFN_vkVoidFunction) vkCreateSemaphore;
3070 if (!strcmp(funcName, "vkDestroySemaphore"))
3071 return (PFN_vkVoidFunction) vkDestroySemaphore;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003072 if (!strcmp(funcName, "vkQueueWaitIdle"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003073 return (PFN_vkVoidFunction) vkQueueWaitIdle;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003074 if (!strcmp(funcName, "vkDeviceWaitIdle"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003075 return (PFN_vkVoidFunction) vkDeviceWaitIdle;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003076 if (!strcmp(funcName, "vkCreateBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003077 return (PFN_vkVoidFunction) vkCreateBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003078 if (!strcmp(funcName, "vkCreateImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003079 return (PFN_vkVoidFunction) vkCreateImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003080 if (!strcmp(funcName, "vkCreateImageView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003081 return (PFN_vkVoidFunction) vkCreateImageView;
Mark Lobodzinskiab5c3d52015-10-27 09:53:00 -06003082 if (!strcmp(funcName, "vkCreateBufferView"))
3083 return (PFN_vkVoidFunction) vkCreateBufferView;
Chia-I Wu1f851912015-10-27 18:04:07 +08003084 if (!strcmp(funcName, "vkAllocateCommandBuffers"))
3085 return (PFN_vkVoidFunction) vkAllocateCommandBuffers;
Mark Lobodzinskic0e316f2015-11-13 13:47:01 -07003086 if (!strcmp(funcName, "vkFreeCommandBuffers"))
3087 return (PFN_vkVoidFunction) vkFreeCommandBuffers;
3088 if (!strcmp(funcName, "vkCreateCommandPool"))
3089 return (PFN_vkVoidFunction) vkCreateCommandPool;
3090 if (!strcmp(funcName, "vkDestroyCommandPool"))
3091 return (PFN_vkVoidFunction) vkDestroyCommandPool;
3092 if (!strcmp(funcName, "vkResetCommandPool"))
3093 return (PFN_vkVoidFunction) vkResetCommandPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003094 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003095 return (PFN_vkVoidFunction) vkBeginCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003096 if (!strcmp(funcName, "vkEndCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003097 return (PFN_vkVoidFunction) vkEndCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003098 if (!strcmp(funcName, "vkResetCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003099 return (PFN_vkVoidFunction) vkResetCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003100 if (!strcmp(funcName, "vkCmdBindPipeline"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003101 return (PFN_vkVoidFunction) vkCmdBindPipeline;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003102 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003103 return (PFN_vkVoidFunction) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06003104 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003105 return (PFN_vkVoidFunction) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003106 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003107 return (PFN_vkVoidFunction) vkCmdBindIndexBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003108 if (!strcmp(funcName, "vkCmdDrawIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003109 return (PFN_vkVoidFunction) vkCmdDrawIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003110 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003111 return (PFN_vkVoidFunction) vkCmdDrawIndexedIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003112 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
Mike Stroyan4081bdc2015-10-15 08:42:32 -06003113 return (PFN_vkVoidFunction)vkCmdDispatchIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003114 if (!strcmp(funcName, "vkCmdCopyBuffer"))
Mike Stroyan4081bdc2015-10-15 08:42:32 -06003115 return (PFN_vkVoidFunction)vkCmdCopyBuffer;
3116 if (!strcmp(funcName, "vkCmdCopyQueryPoolResults"))
3117 return (PFN_vkVoidFunction)vkCmdCopyQueryPoolResults;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003118 if (!strcmp(funcName, "vkCmdCopyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003119 return (PFN_vkVoidFunction) vkCmdCopyImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003120 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003121 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003122 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003123 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003124 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003125 return (PFN_vkVoidFunction) vkCmdUpdateBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003126 if (!strcmp(funcName, "vkCmdFillBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003127 return (PFN_vkVoidFunction) vkCmdFillBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003128 if (!strcmp(funcName, "vkCmdClearColorImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003129 return (PFN_vkVoidFunction) vkCmdClearColorImage;
Chris Forbes2951d7d2015-06-22 17:21:59 +12003130 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003131 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003132 if (!strcmp(funcName, "vkCmdResolveImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003133 return (PFN_vkVoidFunction) vkCmdResolveImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003134 if (!strcmp(funcName, "vkCmdBeginQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003135 return (PFN_vkVoidFunction) vkCmdBeginQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003136 if (!strcmp(funcName, "vkCmdEndQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003137 return (PFN_vkVoidFunction) vkCmdEndQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003138 if (!strcmp(funcName, "vkCmdResetQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003139 return (PFN_vkVoidFunction) vkCmdResetQueryPool;
Michael Lentine6306a5a2015-11-24 17:55:33 -06003140 if (!strcmp(funcName, "vkCreateRenderPass"))
3141 return (PFN_vkVoidFunction) vkCreateRenderPass;
3142 if (!strcmp(funcName, "vkCmdBeginRenderPass"))
3143 return (PFN_vkVoidFunction) vkCmdBeginRenderPass;
3144 if (!strcmp(funcName, "vkCmdEndRenderPass"))
3145 return (PFN_vkVoidFunction) vkCmdEndRenderPass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003146 if (!strcmp(funcName, "vkGetDeviceQueue"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003147 return (PFN_vkVoidFunction) vkGetDeviceQueue;
Michael Lentine6306a5a2015-11-24 17:55:33 -06003148 if (!strcmp(funcName, "vkCreateFramebuffer"))
3149 return (PFN_vkVoidFunction) vkCreateFramebuffer;
Mark Lobodzinski75fae592015-12-18 09:24:52 -07003150 if (!strcmp(funcName, "vkDestroyFramebuffer"))
3151 return (PFN_vkVoidFunction) vkDestroyFramebuffer;
3152
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003153
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003154 my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
3155 if (my_data->wsi_enabled)
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003156 {
Ian Elliott338dedb2015-08-21 15:09:33 -06003157 if (!strcmp(funcName, "vkCreateSwapchainKHR"))
3158 return (PFN_vkVoidFunction) vkCreateSwapchainKHR;
3159 if (!strcmp(funcName, "vkDestroySwapchainKHR"))
3160 return (PFN_vkVoidFunction) vkDestroySwapchainKHR;
3161 if (!strcmp(funcName, "vkGetSwapchainImagesKHR"))
3162 return (PFN_vkVoidFunction) vkGetSwapchainImagesKHR;
Mark Lobodzinski2a253072015-10-08 10:44:07 -06003163 if (!strcmp(funcName, "vkAcquireNextImageKHR"))
3164 return (PFN_vkVoidFunction)vkAcquireNextImageKHR;
Michael Lentine6306a5a2015-11-24 17:55:33 -06003165 if (!strcmp(funcName, "vkQueuePresentKHR"))
3166 return (PFN_vkVoidFunction)vkQueuePresentKHR;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003167 }
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06003168
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003169 VkLayerDispatchTable *pDisp = my_data->device_dispatch_table;
Courtney Goeltzenleuchter9419f322015-07-05 11:17:01 -06003170 if (pDisp->GetDeviceProcAddr == NULL)
3171 return NULL;
3172 return pDisp->GetDeviceProcAddr(dev, funcName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003173}
3174
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +08003175VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(
Mark Lobodzinskie90aca12015-11-19 15:45:36 -07003176 VkInstance instance,
3177 const char *funcName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003178{
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003179 PFN_vkVoidFunction fptr;
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003180 if (instance == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003181 return NULL;
Jon Ashburnd9564002015-05-07 10:27:37 -06003182
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003183 layer_data *my_data;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003184 /* loader uses this to force layer initialization; instance object is wrapped */
3185 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003186 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
3187 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
3188 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
3189 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003190 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003191 }
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003192 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Mark Lobodzinski5176d3d2015-05-20 16:16:37 -05003193 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003194 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06003195 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003196 return (PFN_vkVoidFunction) vkCreateInstance;
Mark Lobodzinski72346292015-07-02 16:49:40 -06003197 if (!strcmp(funcName, "vkGetPhysicalDeviceMemoryProperties"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003198 return (PFN_vkVoidFunction) vkGetPhysicalDeviceMemoryProperties;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06003199 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
3200 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
3201 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
3202 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
3203 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
3204 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
3205 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
3206 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06003207
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -06003208 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Courtney Goeltzenleuchter23b5f8d2015-06-17 20:51:59 -06003209 if (fptr)
3210 return fptr;
3211
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003212 {
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003213 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
3214 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003215 return NULL;
Tobin Ehlis94680ea2015-10-28 16:25:11 -06003216 return pTable->GetInstanceProcAddr(instance, funcName);
Tobin Ehlis791a49c2014-11-10 12:29:12 -07003217 }
3218}