blob: d338eb7cbab67653d230d448f5fce1c04e6e93e7 [file] [log] [blame]
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
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
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unordered_map>
29
30#include "loader_platform.h"
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060031#include "vk_dispatch_table_helper.h"
32#include "vk_struct_string_helper_cpp.h"
Tony Barboura938abb2015-04-22 11:36:22 -060033#if defined(__GNUC__)
Tobin Ehlis63bb9482015-03-17 16:24:32 -060034#pragma GCC diagnostic ignored "-Wwrite-strings"
Tony Barboura938abb2015-04-22 11:36:22 -060035#endif
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060036#include "vk_struct_graphviz_helper.h"
Tony Barboura938abb2015-04-22 11:36:22 -060037#if defined(__GNUC__)
Tobin Ehlis63bb9482015-03-17 16:24:32 -060038#pragma GCC diagnostic warning "-Wwrite-strings"
Tony Barboura938abb2015-04-22 11:36:22 -060039#endif
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060040#include "vk_struct_size_helper.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060041#include "draw_state.h"
42#include "layers_config.h"
Jon Ashburnf0615e22015-05-25 14:11:37 -060043#include "vk_debug_marker_layer.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060044// The following is #included again to catch certain OS-specific functions
45// being used:
46#include "loader_platform.h"
47#include "layers_msg.h"
Jon Ashburn5a10d212015-06-01 10:02:09 -060048#include "layers_table.h"
Jon Ashburn6f8cd632015-06-01 09:37:38 -060049#include "layers_debug_marker_table.h"
Tobin Ehlisc91330b2015-06-16 09:04:30 -060050#include "layer_logging.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060051
Tobin Ehlisc91330b2015-06-16 09:04:30 -060052typedef struct _layer_data {
53 debug_report_data *report_data;
54 // TODO: put instance data here
55 VkDbgMsgCallback logging_callback;
56} layer_data;
57
58static std::unordered_map<void *, layer_data *> layer_data_map;
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -060059static device_table_map draw_state_device_table_map;
60static instance_table_map draw_state_instance_table_map;
61
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060062unordered_map<VkSampler, SAMPLER_NODE*> sampleMap;
63unordered_map<VkImageView, IMAGE_NODE*> imageMap;
64unordered_map<VkBufferView, BUFFER_NODE*> bufferMap;
65unordered_map<VkDynamicStateObject, DYNAMIC_STATE_NODE*> dynamicStateMap;
66unordered_map<VkPipeline, PIPELINE_NODE*> pipelineMap;
67unordered_map<VkDescriptorPool, POOL_NODE*> poolMap;
68unordered_map<VkDescriptorSet, SET_NODE*> setMap;
69unordered_map<VkDescriptorSetLayout, LAYOUT_NODE*> layoutMap;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -060070// Map for layout chains
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060071unordered_map<VkCmdBuffer, GLOBAL_CB_NODE*> cmdBufferMap;
72unordered_map<VkRenderPass, VkRenderPassCreateInfo*> renderPassMap;
73unordered_map<VkFramebuffer, VkFramebufferCreateInfo*> frameBufferMap;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060074
Jon Ashburn6f8cd632015-06-01 09:37:38 -060075struct devExts {
76 bool debug_marker_enabled;
77};
78
Jon Ashburn6f8cd632015-06-01 09:37:38 -060079static std::unordered_map<void *, struct devExts> deviceExtMap;
Jon Ashburne0fa2282015-05-20 09:00:28 -060080
Tobin Ehlis63bb9482015-03-17 16:24:32 -060081static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Jon Ashburnd9564002015-05-07 10:27:37 -060082
Tobin Ehlis63bb9482015-03-17 16:24:32 -060083// TODO : This can be much smarter, using separate locks for separate global data
84static int globalLockInitialized = 0;
85static loader_platform_thread_mutex globalLock;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060086#define MAX_TID 513
87static loader_platform_thread_id g_tidMapping[MAX_TID] = {0};
88static uint32_t g_maxTID = 0;
89// Map actual TID to an index value and return that index
90// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs
91static uint32_t getTIDIndex() {
92 loader_platform_thread_id tid = loader_platform_get_thread_id();
93 for (uint32_t i = 0; i < g_maxTID; i++) {
94 if (tid == g_tidMapping[i])
95 return i;
96 }
97 // Don't yet have mapping, set it and return newly set index
98 uint32_t retVal = (uint32_t) g_maxTID;
99 g_tidMapping[g_maxTID++] = tid;
100 assert(g_maxTID < MAX_TID);
101 return retVal;
102}
103// Return a string representation of CMD_TYPE enum
104static string cmdTypeToString(CMD_TYPE cmd)
105{
106 switch (cmd)
107 {
108 case CMD_BINDPIPELINE:
109 return "CMD_BINDPIPELINE";
110 case CMD_BINDPIPELINEDELTA:
111 return "CMD_BINDPIPELINEDELTA";
112 case CMD_BINDDYNAMICSTATEOBJECT:
113 return "CMD_BINDDYNAMICSTATEOBJECT";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600114 case CMD_BINDDESCRIPTORSETS:
115 return "CMD_BINDDESCRIPTORSETS";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600116 case CMD_BINDINDEXBUFFER:
117 return "CMD_BINDINDEXBUFFER";
118 case CMD_BINDVERTEXBUFFER:
119 return "CMD_BINDVERTEXBUFFER";
120 case CMD_DRAW:
121 return "CMD_DRAW";
122 case CMD_DRAWINDEXED:
123 return "CMD_DRAWINDEXED";
124 case CMD_DRAWINDIRECT:
125 return "CMD_DRAWINDIRECT";
126 case CMD_DRAWINDEXEDINDIRECT:
127 return "CMD_DRAWINDEXEDINDIRECT";
128 case CMD_DISPATCH:
129 return "CMD_DISPATCH";
130 case CMD_DISPATCHINDIRECT:
131 return "CMD_DISPATCHINDIRECT";
132 case CMD_COPYBUFFER:
133 return "CMD_COPYBUFFER";
134 case CMD_COPYIMAGE:
135 return "CMD_COPYIMAGE";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600136 case CMD_BLITIMAGE:
137 return "CMD_BLITIMAGE";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600138 case CMD_COPYBUFFERTOIMAGE:
139 return "CMD_COPYBUFFERTOIMAGE";
140 case CMD_COPYIMAGETOBUFFER:
141 return "CMD_COPYIMAGETOBUFFER";
142 case CMD_CLONEIMAGEDATA:
143 return "CMD_CLONEIMAGEDATA";
144 case CMD_UPDATEBUFFER:
145 return "CMD_UPDATEBUFFER";
146 case CMD_FILLBUFFER:
147 return "CMD_FILLBUFFER";
148 case CMD_CLEARCOLORIMAGE:
149 return "CMD_CLEARCOLORIMAGE";
150 case CMD_CLEARCOLORIMAGERAW:
151 return "CMD_CLEARCOLORIMAGERAW";
152 case CMD_CLEARDEPTHSTENCIL:
153 return "CMD_CLEARDEPTHSTENCIL";
154 case CMD_RESOLVEIMAGE:
155 return "CMD_RESOLVEIMAGE";
156 case CMD_SETEVENT:
157 return "CMD_SETEVENT";
158 case CMD_RESETEVENT:
159 return "CMD_RESETEVENT";
160 case CMD_WAITEVENTS:
161 return "CMD_WAITEVENTS";
162 case CMD_PIPELINEBARRIER:
163 return "CMD_PIPELINEBARRIER";
164 case CMD_BEGINQUERY:
165 return "CMD_BEGINQUERY";
166 case CMD_ENDQUERY:
167 return "CMD_ENDQUERY";
168 case CMD_RESETQUERYPOOL:
169 return "CMD_RESETQUERYPOOL";
170 case CMD_WRITETIMESTAMP:
171 return "CMD_WRITETIMESTAMP";
172 case CMD_INITATOMICCOUNTERS:
173 return "CMD_INITATOMICCOUNTERS";
174 case CMD_LOADATOMICCOUNTERS:
175 return "CMD_LOADATOMICCOUNTERS";
176 case CMD_SAVEATOMICCOUNTERS:
177 return "CMD_SAVEATOMICCOUNTERS";
178 case CMD_BEGINRENDERPASS:
179 return "CMD_BEGINRENDERPASS";
180 case CMD_ENDRENDERPASS:
181 return "CMD_ENDRENDERPASS";
182 case CMD_DBGMARKERBEGIN:
183 return "CMD_DBGMARKERBEGIN";
184 case CMD_DBGMARKEREND:
185 return "CMD_DBGMARKEREND";
186 default:
187 return "UNKNOWN";
188 }
189}
190// Block of code at start here for managing/tracking Pipeline state that this layer cares about
191// Just track 2 shaders for now
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600192#define VK_NUM_GRAPHICS_SHADERS VK_SHADER_STAGE_COMPUTE
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600193#define MAX_SLOTS 2048
194#define NUM_COMMAND_BUFFERS_TO_DISPLAY 10
195
196static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0};
197
198// TODO : Should be tracking lastBound per cmdBuffer and when draws occur, report based on that cmd buffer lastBound
199// Then need to synchronize the accesses based on cmd buffer so that if I'm reading state on one cmd buffer, updates
200// to that same cmd buffer by separate thread are not changing state from underneath us
201// Track the last cmd buffer touched by this thread
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600202static VkCmdBuffer g_lastCmdBuffer[MAX_TID] = {NULL};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600203// Track the last group of CBs touched for displaying to dot file
204static GLOBAL_CB_NODE* g_pLastTouchedCB[NUM_COMMAND_BUFFERS_TO_DISPLAY] = {NULL};
205static uint32_t g_lastTouchedCBIndex = 0;
206// Track the last global DrawState of interest touched by any thread
207static GLOBAL_CB_NODE* g_lastGlobalCB = NULL;
208static PIPELINE_NODE* g_lastBoundPipeline = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600209static DYNAMIC_STATE_NODE* g_lastBoundDynamicState[VK_NUM_STATE_BIND_POINT] = {NULL};
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600210static VkDescriptorSet g_lastBoundDescriptorSet = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600211#define MAX_BINDING 0xFFFFFFFF // Default vtxBinding value in CB Node to identify if no vtxBinding set
212
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600213//static DYNAMIC_STATE_NODE* g_pDynamicStateHead[VK_NUM_STATE_BIND_POINT] = {0};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600214
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600215static void insertDynamicState(const VkDynamicStateObject state, const GENERIC_HEADER* pCreateInfo, VkStateBindPoint bindPoint)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600216{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600217 VkDynamicVpStateCreateInfo* pVPCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600218 size_t scSize = 0;
219 size_t vpSize = 0;
220 loader_platform_thread_lock_mutex(&globalLock);
221 DYNAMIC_STATE_NODE* pStateNode = new DYNAMIC_STATE_NODE;
222 pStateNode->stateObj = state;
223 switch (pCreateInfo->sType) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600224 case VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600225 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo));
226 pVPCI = (VkDynamicVpStateCreateInfo*)pCreateInfo;
227 pStateNode->create_info.vpci.pScissors = new VkRect[pStateNode->create_info.vpci.viewportAndScissorCount];
228 pStateNode->create_info.vpci.pViewports = new VkViewport[pStateNode->create_info.vpci.viewportAndScissorCount];
229 scSize = pVPCI->viewportAndScissorCount * sizeof(VkRect);
230 vpSize = pVPCI->viewportAndScissorCount * sizeof(VkViewport);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600231 memcpy((void*)pStateNode->create_info.vpci.pScissors, pVPCI->pScissors, scSize);
232 memcpy((void*)pStateNode->create_info.vpci.pViewports, pVPCI->pViewports, vpSize);
233 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600234 case VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600235 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600236 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600237 case VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600238 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600239 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600240 case VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600241 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600242 break;
243 default:
244 assert(0);
245 break;
246 }
247 pStateNode->pCreateInfo = (GENERIC_HEADER*)&pStateNode->create_info.cbci;
248 dynamicStateMap[state] = pStateNode;
249 loader_platform_thread_unlock_mutex(&globalLock);
250}
251// Free all allocated nodes for Dynamic State objs
Tobin Ehliseaf28662015-04-08 10:58:37 -0600252static void deleteDynamicState()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600253{
David Pinedof5997ab2015-04-27 16:36:17 -0600254 if (dynamicStateMap.size() <= 0)
255 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600256 for (unordered_map<VkDynamicStateObject, DYNAMIC_STATE_NODE*>::iterator ii=dynamicStateMap.begin(); ii!=dynamicStateMap.end(); ++ii) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600257 if (VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO == (*ii).second->create_info.vpci.sType) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600258 delete[] (*ii).second->create_info.vpci.pScissors;
259 delete[] (*ii).second->create_info.vpci.pViewports;
260 }
261 delete (*ii).second;
262 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600263 dynamicStateMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600264}
265// Free all sampler nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600266static void deleteSamplers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600267{
David Pinedof5997ab2015-04-27 16:36:17 -0600268 if (sampleMap.size() <= 0)
269 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600270 for (unordered_map<VkSampler, SAMPLER_NODE*>::iterator ii=sampleMap.begin(); ii!=sampleMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600271 delete (*ii).second;
272 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600273 sampleMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600274}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600275static VkImageViewCreateInfo* getImageViewCreateInfo(VkImageView view)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600276{
277 loader_platform_thread_lock_mutex(&globalLock);
278 if (imageMap.find(view) == imageMap.end()) {
279 loader_platform_thread_unlock_mutex(&globalLock);
280 return NULL;
281 }
282 else {
283 loader_platform_thread_unlock_mutex(&globalLock);
284 return &imageMap[view]->createInfo;
285 }
286}
287// Free all image nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600288static void deleteImages()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600289{
David Pinedof5997ab2015-04-27 16:36:17 -0600290 if (imageMap.size() <= 0)
291 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600292 for (unordered_map<VkImageView, IMAGE_NODE*>::iterator ii=imageMap.begin(); ii!=imageMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600293 delete (*ii).second;
294 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600295 imageMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600296}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600297static VkBufferViewCreateInfo* getBufferViewCreateInfo(VkBufferView view)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600298{
299 loader_platform_thread_lock_mutex(&globalLock);
300 if (bufferMap.find(view) == bufferMap.end()) {
301 loader_platform_thread_unlock_mutex(&globalLock);
302 return NULL;
303 }
304 else {
305 loader_platform_thread_unlock_mutex(&globalLock);
306 return &bufferMap[view]->createInfo;
307 }
308}
309// Free all buffer nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600310static void deleteBuffers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600311{
David Pinedof5997ab2015-04-27 16:36:17 -0600312 if (bufferMap.size() <= 0)
313 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600314 for (unordered_map<VkBufferView, BUFFER_NODE*>::iterator ii=bufferMap.begin(); ii!=bufferMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600315 delete (*ii).second;
316 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600317 bufferMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600318}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600319static GLOBAL_CB_NODE* getCBNode(VkCmdBuffer cb);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600320
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600321static void updateCBTracking(VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600322{
323 g_lastCmdBuffer[getTIDIndex()] = cb;
324 GLOBAL_CB_NODE* pCB = getCBNode(cb);
325 loader_platform_thread_lock_mutex(&globalLock);
326 g_lastGlobalCB = pCB;
327 // TODO : This is a dumb algorithm. Need smart LRU that drops off oldest
328 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
329 if (g_pLastTouchedCB[i] == pCB) {
330 loader_platform_thread_unlock_mutex(&globalLock);
331 return;
332 }
333 }
334 g_pLastTouchedCB[g_lastTouchedCBIndex++] = pCB;
335 g_lastTouchedCBIndex = g_lastTouchedCBIndex % NUM_COMMAND_BUFFERS_TO_DISPLAY;
336 loader_platform_thread_unlock_mutex(&globalLock);
337}
Tobin Ehlis97866202015-06-10 12:57:07 -0600338// Check object status for selected flag state
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600339static bool32_t validate_status(VkCmdBuffer cb, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VkFlags msg_flags, DRAW_STATE_ERROR error_code, const char* fail_msg)
340{
Tobin Ehlis97866202015-06-10 12:57:07 -0600341 if (cmdBufferMap.find(cb) != cmdBufferMap.end()) {
342 GLOBAL_CB_NODE* pNode = cmdBufferMap[cb];
343 // If non-zero enable mask is present, check it against status but if enable_mask
344 // is 0 then no enable required so we should always just check status
345 if ((!enable_mask) || (enable_mask & pNode->status)) {
346 if ((pNode->status & status_mask) != status_flag) {
347 char str[1024];
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600348 sprintf(str, "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(cb), str);
349 layerCbMsg(msg_flags, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, error_code, "DS", str);
Tobin Ehlis97866202015-06-10 12:57:07 -0600350 return VK_FALSE;
351 }
352 }
353 return VK_TRUE;
354 }
355 else {
356 // If we do not find it print an error
357 char str[1024];
358 sprintf(str, "Unable to obtain status for non-existent CB object 0x%" PRIxLEAST64, reinterpret_cast<VkUintPtrLeast64>(cb));
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600359 layerCbMsg(msg_flags, (VkObjectType) 0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis97866202015-06-10 12:57:07 -0600360 return VK_FALSE;
361 }
362}
363static bool32_t validate_draw_state_flags(VkCmdBuffer cb) {
364 bool32_t result1, result2, result3, result4;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600365 result1 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
366 result2 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_RASTER_BOUND, CBSTATUS_RASTER_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_RASTER_NOT_BOUND, "Raster object not bound to this command buffer");
367 result3 = validate_status(cb, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND, CBSTATUS_COLOR_BLEND_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_COLOR_BLEND_NOT_BOUND, "Color-blend object not bound to this command buffer");
368 result4 = validate_status(cb, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
Tobin Ehlis97866202015-06-10 12:57:07 -0600369 return ((result1 == VK_TRUE) && (result2 == VK_TRUE) && (result3 == VK_TRUE) && (result4 == VK_TRUE));
370}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600371// Print the last bound dynamic state
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600372static void printDynamicState(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600373{
374 GLOBAL_CB_NODE* pCB = getCBNode(cb);
375 if (pCB) {
376 loader_platform_thread_lock_mutex(&globalLock);
377 char str[4*1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600378 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600379 if (pCB->lastBoundDynamicState[i]) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600380 sprintf(str, "Reporting CreateInfo for currently bound %s object %p", string_VkStateBindPoint((VkStateBindPoint)i), pCB->lastBoundDynamicState[i]->stateObj);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600381 layerCbMsg(VK_DBG_REPORT_INFO_BIT, pCB->lastBoundDynamicState[i]->objType, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", str);
382 layerCbMsg(VK_DBG_REPORT_INFO_BIT, pCB->lastBoundDynamicState[i]->objType, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", dynamic_display(pCB->lastBoundDynamicState[i]->pCreateInfo, " ").c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600383 break;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600384 } else {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600385 sprintf(str, "No dynamic state of type %s bound", string_VkStateBindPoint((VkStateBindPoint)i));
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600386 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600387 }
388 }
389 loader_platform_thread_unlock_mutex(&globalLock);
390 }
391 else {
392 char str[1024];
393 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cb);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600394 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600395 }
396}
397// Retrieve pipeline node ptr for given pipeline object
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600398static PIPELINE_NODE* getPipeline(VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600399{
400 loader_platform_thread_lock_mutex(&globalLock);
401 if (pipelineMap.find(pipeline) == pipelineMap.end()) {
402 loader_platform_thread_unlock_mutex(&globalLock);
403 return NULL;
404 }
405 loader_platform_thread_unlock_mutex(&globalLock);
406 return pipelineMap[pipeline];
407}
408
409// For given sampler, return a ptr to its Create Info struct, or NULL if sampler not found
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600410static VkSamplerCreateInfo* getSamplerCreateInfo(const VkSampler sampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600411{
412 loader_platform_thread_lock_mutex(&globalLock);
413 if (sampleMap.find(sampler) == sampleMap.end()) {
414 loader_platform_thread_unlock_mutex(&globalLock);
415 return NULL;
416 }
417 loader_platform_thread_unlock_mutex(&globalLock);
418 return &sampleMap[sampler]->createInfo;
419}
420
421// Init the pipeline mapping info based on pipeline create info LL tree
422// Threading note : Calls to this function should wrapped in mutex
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600423static void initPipeline(PIPELINE_NODE* pPipeline, const VkGraphicsPipelineCreateInfo* pCreateInfo)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600424{
425 // First init create info, we'll shadow the structs as we go down the tree
Tobin Ehlis2464b882015-04-01 08:40:34 -0600426 // TODO : Validate that no create info is incorrectly replicated
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600427 memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600428 GENERIC_HEADER* pTrav = (GENERIC_HEADER*)pCreateInfo->pNext;
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600429 GENERIC_HEADER* pPrev = (GENERIC_HEADER*)&pPipeline->graphicsPipelineCI; // Hold prev ptr to tie chain of structs together
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600430 size_t bufferSize = 0;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600431 VkPipelineVertexInputCreateInfo* pVICI = NULL;
432 VkPipelineCbStateCreateInfo* pCBCI = NULL;
433 VkPipelineShaderStageCreateInfo* pTmpPSSCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600434 while (pTrav) {
435 switch (pTrav->sType) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600436 case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600437 pTmpPSSCI = (VkPipelineShaderStageCreateInfo*)pTrav;
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600438 switch (pTmpPSSCI->shader.stage) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600439 case VK_SHADER_STAGE_VERTEX:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600440 pPrev->pNext = &pPipeline->vsCI;
441 pPrev = (GENERIC_HEADER*)&pPipeline->vsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600442 memcpy(&pPipeline->vsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600443 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600444 case VK_SHADER_STAGE_TESS_CONTROL:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600445 pPrev->pNext = &pPipeline->tcsCI;
446 pPrev = (GENERIC_HEADER*)&pPipeline->tcsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600447 memcpy(&pPipeline->tcsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600448 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600449 case VK_SHADER_STAGE_TESS_EVALUATION:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600450 pPrev->pNext = &pPipeline->tesCI;
451 pPrev = (GENERIC_HEADER*)&pPipeline->tesCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600452 memcpy(&pPipeline->tesCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600453 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600454 case VK_SHADER_STAGE_GEOMETRY:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600455 pPrev->pNext = &pPipeline->gsCI;
456 pPrev = (GENERIC_HEADER*)&pPipeline->gsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600457 memcpy(&pPipeline->gsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600458 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600459 case VK_SHADER_STAGE_FRAGMENT:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600460 pPrev->pNext = &pPipeline->fsCI;
461 pPrev = (GENERIC_HEADER*)&pPipeline->fsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600462 memcpy(&pPipeline->fsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600463 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600464 case VK_SHADER_STAGE_COMPUTE:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600465 // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600466 break;
467 default:
468 // TODO : Flag error
469 break;
470 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600471 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600472 case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600473 pPrev->pNext = &pPipeline->vertexInputCI;
474 pPrev = (GENERIC_HEADER*)&pPipeline->vertexInputCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600475 memcpy((void*)&pPipeline->vertexInputCI, pTrav, sizeof(VkPipelineVertexInputCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600476 // Copy embedded ptrs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600477 pVICI = (VkPipelineVertexInputCreateInfo*)pTrav;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600478 pPipeline->vtxBindingCount = pVICI->bindingCount;
479 if (pPipeline->vtxBindingCount) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600480 pPipeline->pVertexBindingDescriptions = new VkVertexInputBindingDescription[pPipeline->vtxBindingCount];
481 bufferSize = pPipeline->vtxBindingCount * sizeof(VkVertexInputBindingDescription);
Tobin Ehlis9a70e5d2015-06-09 10:48:55 -0600482 memcpy((void*)pPipeline->pVertexBindingDescriptions, ((VkPipelineVertexInputCreateInfo*)pTrav)->pVertexBindingDescriptions, bufferSize);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600483 }
484 pPipeline->vtxAttributeCount = pVICI->attributeCount;
485 if (pPipeline->vtxAttributeCount) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600486 pPipeline->pVertexAttributeDescriptions = new VkVertexInputAttributeDescription[pPipeline->vtxAttributeCount];
487 bufferSize = pPipeline->vtxAttributeCount * sizeof(VkVertexInputAttributeDescription);
488 memcpy((void*)pPipeline->pVertexAttributeDescriptions, ((VkPipelineVertexInputCreateInfo*)pTrav)->pVertexAttributeDescriptions, bufferSize);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600489 }
490 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600491 case VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600492 pPrev->pNext = &pPipeline->iaStateCI;
493 pPrev = (GENERIC_HEADER*)&pPipeline->iaStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600494 memcpy((void*)&pPipeline->iaStateCI, pTrav, sizeof(VkPipelineIaStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600495 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600496 case VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600497 pPrev->pNext = &pPipeline->tessStateCI;
498 pPrev = (GENERIC_HEADER*)&pPipeline->tessStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600499 memcpy((void*)&pPipeline->tessStateCI, pTrav, sizeof(VkPipelineTessStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600500 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600501 case VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600502 pPrev->pNext = &pPipeline->vpStateCI;
503 pPrev = (GENERIC_HEADER*)&pPipeline->vpStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600504 memcpy((void*)&pPipeline->vpStateCI, pTrav, sizeof(VkPipelineVpStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600505 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600506 case VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600507 pPrev->pNext = &pPipeline->rsStateCI;
508 pPrev = (GENERIC_HEADER*)&pPipeline->rsStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600509 memcpy((void*)&pPipeline->rsStateCI, pTrav, sizeof(VkPipelineRsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600510 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600511 case VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600512 pPrev->pNext = &pPipeline->msStateCI;
513 pPrev = (GENERIC_HEADER*)&pPipeline->msStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600514 memcpy((void*)&pPipeline->msStateCI, pTrav, sizeof(VkPipelineMsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600515 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600516 case VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600517 pPrev->pNext = &pPipeline->cbStateCI;
518 pPrev = (GENERIC_HEADER*)&pPipeline->cbStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600519 memcpy((void*)&pPipeline->cbStateCI, pTrav, sizeof(VkPipelineCbStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600520 // Copy embedded ptrs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600521 pCBCI = (VkPipelineCbStateCreateInfo*)pTrav;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600522 pPipeline->attachmentCount = pCBCI->attachmentCount;
523 if (pPipeline->attachmentCount) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600524 pPipeline->pAttachments = new VkPipelineCbAttachmentState[pPipeline->attachmentCount];
525 bufferSize = pPipeline->attachmentCount * sizeof(VkPipelineCbAttachmentState);
526 memcpy((void*)pPipeline->pAttachments, ((VkPipelineCbStateCreateInfo*)pTrav)->pAttachments, bufferSize);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600527 }
528 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600529 case VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600530 pPrev->pNext = &pPipeline->dsStateCI;
531 pPrev = (GENERIC_HEADER*)&pPipeline->dsStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600532 memcpy((void*)&pPipeline->dsStateCI, pTrav, sizeof(VkPipelineDsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600533 break;
534 default:
535 assert(0);
536 break;
537 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600538 pTrav = (GENERIC_HEADER*)pTrav->pNext;
539 }
540 pipelineMap[pPipeline->pipeline] = pPipeline;
541}
542// Free the Pipeline nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600543static void deletePipelines()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600544{
David Pinedof5997ab2015-04-27 16:36:17 -0600545 if (pipelineMap.size() <= 0)
546 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600547 for (unordered_map<VkPipeline, PIPELINE_NODE*>::iterator ii=pipelineMap.begin(); ii!=pipelineMap.end(); ++ii) {
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600548 if ((*ii).second->pVertexBindingDescriptions) {
549 delete[] (*ii).second->pVertexBindingDescriptions;
550 }
551 if ((*ii).second->pVertexAttributeDescriptions) {
552 delete[] (*ii).second->pVertexAttributeDescriptions;
553 }
554 if ((*ii).second->pAttachments) {
555 delete[] (*ii).second->pAttachments;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600556 }
557 delete (*ii).second;
558 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600559 pipelineMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600560}
Tobin Ehlis2464b882015-04-01 08:40:34 -0600561// For given pipeline, return number of MSAA samples, or one if MSAA disabled
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600562static uint32_t getNumSamples(const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600563{
564 PIPELINE_NODE* pPipe = pipelineMap[pipeline];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600565 if (VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO == pPipe->msStateCI.sType) {
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600566 if (pPipe->msStateCI.multisampleEnable)
567 return pPipe->msStateCI.samples;
Tobin Ehlis2464b882015-04-01 08:40:34 -0600568 }
569 return 1;
570}
571// Validate state related to the PSO
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600572static void validatePipelineState(const GLOBAL_CB_NODE* pCB, const VkPipelineBindPoint pipelineBindPoint, const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600573{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600574 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
Tobin Ehlis2464b882015-04-01 08:40:34 -0600575 // Verify that any MSAA request in PSO matches sample# in bound FB
576 uint32_t psoNumSamples = getNumSamples(pipeline);
577 if (pCB->activeRenderPass) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600578 VkRenderPassCreateInfo* pRPCI = renderPassMap[pCB->activeRenderPass];
579 VkFramebufferCreateInfo* pFBCI = frameBufferMap[pCB->framebuffer];
Tobin Ehlis63826ec2015-05-21 09:06:56 -0600580 if ((psoNumSamples != pFBCI->sampleCount) || (psoNumSamples != pRPCI->sampleCount)) {
Tobin Ehlis2464b882015-04-01 08:40:34 -0600581 char str[1024];
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600582 sprintf(str, "Num samples mismatch! Binding PSO (%p) with %u samples while current RenderPass (%p) w/ %u samples uses FB (%p) with %u samples!", (void*)pipeline, psoNumSamples, (void*)pCB->activeRenderPass, pRPCI->sampleCount, (void*)pCB->framebuffer, pFBCI->sampleCount);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600583 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", str);
Tobin Ehlis2464b882015-04-01 08:40:34 -0600584 }
585 } else {
586 // TODO : I believe it's an error if we reach this point and don't have an activeRenderPass
587 // Verify and flag error as appropriate
588 }
589 // TODO : Add more checks here
590 } else {
591 // TODO : Validate non-gfx pipeline updates
592 }
593}
594
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600595// Block of code at start here specifically for managing/tracking DSs
596
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600597// Return Pool node ptr for specified pool or else NULL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600598static POOL_NODE* getPoolNode(VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600599{
600 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600601 if (poolMap.find(pool) == poolMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600602 loader_platform_thread_unlock_mutex(&globalLock);
603 return NULL;
604 }
605 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600606 return poolMap[pool];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600607}
608// Return Set node ptr for specified set or else NULL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600609static SET_NODE* getSetNode(VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600610{
611 loader_platform_thread_lock_mutex(&globalLock);
612 if (setMap.find(set) == setMap.end()) {
613 loader_platform_thread_unlock_mutex(&globalLock);
614 return NULL;
615 }
616 loader_platform_thread_unlock_mutex(&globalLock);
617 return setMap[set];
618}
619
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600620static LAYOUT_NODE* getLayoutNode(const VkDescriptorSetLayout layout) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600621 loader_platform_thread_lock_mutex(&globalLock);
622 if (layoutMap.find(layout) == layoutMap.end()) {
623 loader_platform_thread_unlock_mutex(&globalLock);
624 return NULL;
625 }
626 loader_platform_thread_unlock_mutex(&globalLock);
627 return layoutMap[layout];
628}
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600629// Return 1 if update struct is of valid type, 0 otherwise
630static bool32_t validUpdateStruct(const GENERIC_HEADER* pUpdateStruct)
631{
632 char str[1024];
633 switch (pUpdateStruct->sType)
634 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800635 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
636 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600637 return 1;
638 default:
639 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600640 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600641 return 0;
642 }
643}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600644// For given update struct, return binding
645static uint32_t getUpdateBinding(const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600646{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600647 char str[1024];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600648 switch (pUpdateStruct->sType)
649 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800650 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
651 return ((VkWriteDescriptorSet*)pUpdateStruct)->destBinding;
652 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
653 return ((VkCopyDescriptorSet*)pUpdateStruct)->destBinding;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600654 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600655 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600656 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600657 return 0xFFFFFFFF;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600658 }
659}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600660// Return count for given update struct
661static uint32_t getUpdateArrayIndex(const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600662{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600663 char str[1024];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600664 switch (pUpdateStruct->sType)
665 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800666 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
667 return ((VkWriteDescriptorSet*)pUpdateStruct)->destArrayElement;
668 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600669 // TODO : Need to understand this case better and make sure code is correct
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800670 return ((VkCopyDescriptorSet*)pUpdateStruct)->destArrayElement;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600671 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600672 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600673 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600674 return 0;
675 }
676}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600677// Return count for given update struct
678static uint32_t getUpdateCount(const GENERIC_HEADER* pUpdateStruct)
679{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600680 char str[1024];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600681 switch (pUpdateStruct->sType)
682 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800683 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
684 return ((VkWriteDescriptorSet*)pUpdateStruct)->count;
685 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600686 // TODO : Need to understand this case better and make sure code is correct
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800687 return ((VkCopyDescriptorSet*)pUpdateStruct)->count;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600688 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600689 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600690 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600691 return 0;
692 }
693}
694// For given Layout Node and binding, return index where that binding begins
695static uint32_t getBindingStartIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
696{
697 uint32_t offsetIndex = 0;
698 for (uint32_t i = 0; i<binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800699 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600700 }
701 return offsetIndex;
702}
703// For given layout node and binding, return last index that is updated
704static uint32_t getBindingEndIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
705{
706 uint32_t offsetIndex = 0;
707 for (uint32_t i = 0; i<=binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800708 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600709 }
710 return offsetIndex-1;
711}
712// For given layout and update, return the first overall index of the layout that is update
713static uint32_t getUpdateStartIndex(const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
714{
715 return (getBindingStartIndex(pLayout, getUpdateBinding(pUpdateStruct))+getUpdateArrayIndex(pUpdateStruct));
716}
717// For given layout and update, return the last overall index of the layout that is update
718static uint32_t getUpdateEndIndex(const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
719{
720 return (getBindingStartIndex(pLayout, getUpdateBinding(pUpdateStruct))+getUpdateArrayIndex(pUpdateStruct)+getUpdateCount(pUpdateStruct)-1);
721}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600722// Verify that the descriptor type in the update struct matches what's expected by the layout
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600723static bool32_t validateUpdateType(const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600724{
725 // First get actual type of update
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600726 VkDescriptorType actualType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600727 uint32_t i = 0;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600728 char str[1024];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600729 switch (pUpdateStruct->sType)
730 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800731 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
732 actualType = ((VkWriteDescriptorSet*)pUpdateStruct)->descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600733 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800734 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
735 /* no need to validate */
736 return 1;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600737 break;
738 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600739 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600740 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, VK_NULL_HANDLE, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600741 return 0;
742 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600743 for (i = getUpdateStartIndex(pLayout, pUpdateStruct); i <= getUpdateEndIndex(pLayout, pUpdateStruct); i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600744 if (pLayout->pTypes[i] != actualType)
745 return 0;
746 }
747 return 1;
748}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600749// Determine the update type, allocate a new struct of that type, shadow the given pUpdate
750// struct into the new struct and return ptr to shadow struct cast as GENERIC_HEADER
751// NOTE : Calls to this function should be wrapped in mutex
752static GENERIC_HEADER* shadowUpdateNode(GENERIC_HEADER* pUpdate)
753{
754 GENERIC_HEADER* pNewNode = NULL;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800755 VkWriteDescriptorSet* pWDS = NULL;
756 VkCopyDescriptorSet* pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600757 size_t array_size = 0;
758 size_t base_array_size = 0;
759 size_t total_array_size = 0;
760 size_t baseBuffAddr = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600761 char str[1024];
762 switch (pUpdate->sType)
763 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800764 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
765 pWDS = new VkWriteDescriptorSet;
766 pNewNode = (GENERIC_HEADER*)pWDS;
767 memcpy(pWDS, pUpdate, sizeof(VkWriteDescriptorSet));
768 pWDS->pDescriptors = new VkDescriptorInfo[pWDS->count];
769 array_size = sizeof(VkDescriptorInfo) * pWDS->count;
770 memcpy((void*)pWDS->pDescriptors, ((VkWriteDescriptorSet*)pUpdate)->pDescriptors, array_size);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600771 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800772 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
773 pCDS = new VkCopyDescriptorSet;
774 pUpdate = (GENERIC_HEADER*)pCDS;
775 memcpy(pCDS, pUpdate, sizeof(VkCopyDescriptorSet));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600776 break;
777 default:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600778 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdate->sType), pUpdate->sType);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600779 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600780 return NULL;
781 }
782 // Make sure that pNext for the end of shadow copy is NULL
783 pNewNode->pNext = NULL;
784 return pNewNode;
785}
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800786// update DS mappings based on ppUpdateArray
787static bool32_t dsUpdate(VkStructureType type, uint32_t updateCount, const void* pUpdateArray)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600788{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800789 const VkWriteDescriptorSet *pWDS = NULL;
790 const VkCopyDescriptorSet *pCDS = NULL;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600791 bool32_t result = 1;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800792
793 if (type == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
794 pWDS = (const VkWriteDescriptorSet *) pUpdateArray;
795 else
796 pCDS = (const VkCopyDescriptorSet *) pUpdateArray;
797
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600798 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600799 LAYOUT_NODE* pLayout = NULL;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600800 VkDescriptorSetLayoutCreateInfo* pLayoutCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600801 // TODO : If pCIList is NULL, flag error
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600802 // Perform all updates
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600803 for (uint32_t i = 0; i < updateCount; i++) {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800804 VkDescriptorSet ds = (pWDS) ? pWDS->destSet : pCDS->destSet;
805 SET_NODE* pSet = setMap[ds]; // getSetNode() without locking
806 g_lastBoundDescriptorSet = pSet->set;
807 GENERIC_HEADER* pUpdate = (pWDS) ? (GENERIC_HEADER*) &pWDS[i] : (GENERIC_HEADER*) &pCDS[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600808 pLayout = pSet->pLayout;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600809 // First verify valid update struct
810 if (!validUpdateStruct(pUpdate)) {
811 result = 0;
812 break;
813 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600814 // Make sure that binding is within bounds
815 if (pLayout->createInfo.count < getUpdateBinding(pUpdate)) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600816 char str[1024];
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600817 sprintf(str, "Descriptor Set %p does not have binding to match update binding %u for update type %s!", ds, getUpdateBinding(pUpdate), string_VkStructureType(pUpdate->sType));
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600818 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600819 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600820 }
821 else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600822 // Next verify that update falls within size of given binding
823 if (getBindingEndIndex(pLayout, getUpdateBinding(pUpdate)) < getUpdateEndIndex(pLayout, pUpdate)) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600824 char str[48*1024]; // TODO : Keep count of layout CI structs and size this string dynamically based on that count
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600825 pLayoutCI = &pLayout->createInfo;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600826 string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo(pLayoutCI, "{DS} ");
827 sprintf(str, "Descriptor update type of %s is out of bounds for matching binding %u in Layout w/ CI:\n%s!", string_VkStructureType(pUpdate->sType), getUpdateBinding(pUpdate), DSstr.c_str());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600828 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600829 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600830 }
831 else { // TODO : should we skip update on a type mismatch or force it?
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600832 // Layout bindings match w/ update ok, now verify that update is of the right type
833 if (!validateUpdateType(pLayout, pUpdate)) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600834 char str[1024];
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600835 sprintf(str, "Descriptor update type of %s does not match overlapping binding type!", string_VkStructureType(pUpdate->sType));
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600836 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600837 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600838 }
839 else {
840 // Save the update info
841 // TODO : Info message that update successful
842 // Create new update struct for this set's shadow copy
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600843 GENERIC_HEADER* pNewNode = shadowUpdateNode(pUpdate);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600844 if (NULL == pNewNode) {
845 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600846 sprintf(str, "Out of memory while attempting to allocate UPDATE struct in vkUpdateDescriptors()");
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600847 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600848 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600849 }
850 else {
851 // Insert shadow node into LL of updates for this set
852 pNewNode->pNext = pSet->pUpdateStructs;
853 pSet->pUpdateStructs = pNewNode;
854 // Now update appropriate descriptor(s) to point to new Update node
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600855 for (uint32_t j = getUpdateStartIndex(pLayout, pUpdate); j <= getUpdateEndIndex(pLayout, pUpdate); j++) {
856 assert(j<pSet->descriptorCount);
857 pSet->ppDescriptors[j] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600858 }
859 }
860 }
861 }
862 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600863 }
864 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600865 return result;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600866}
867// Free the shadowed update node for this Set
868// NOTE : Calls to this function should be wrapped in mutex
869static void freeShadowUpdateTree(SET_NODE* pSet)
870{
871 GENERIC_HEADER* pShadowUpdate = pSet->pUpdateStructs;
872 pSet->pUpdateStructs = NULL;
873 GENERIC_HEADER* pFreeUpdate = pShadowUpdate;
874 // Clear the descriptor mappings as they will now be invalid
875 memset(pSet->ppDescriptors, 0, pSet->descriptorCount*sizeof(GENERIC_HEADER*));
876 while(pShadowUpdate) {
877 pFreeUpdate = pShadowUpdate;
878 pShadowUpdate = (GENERIC_HEADER*)pShadowUpdate->pNext;
879 uint32_t index = 0;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800880 VkWriteDescriptorSet * pWDS = NULL;
881 VkCopyDescriptorSet * pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600882 void** ppToFree = NULL;
883 switch (pFreeUpdate->sType)
884 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800885 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
886 pWDS = (VkWriteDescriptorSet*)pFreeUpdate;
887 if (pWDS->pDescriptors)
888 delete[] pWDS->pDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600889 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800890 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600891 break;
892 default:
893 assert(0);
894 break;
895 }
Tobin Ehliseaf28662015-04-08 10:58:37 -0600896 delete pFreeUpdate;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600897 }
898}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600899// Free all DS Pools including their Sets & related sub-structs
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600900// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600901static void deletePools()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600902{
David Pinedof5997ab2015-04-27 16:36:17 -0600903 if (poolMap.size() <= 0)
904 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600905 for (unordered_map<VkDescriptorPool, POOL_NODE*>::iterator ii=poolMap.begin(); ii!=poolMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600906 SET_NODE* pSet = (*ii).second->pSets;
907 SET_NODE* pFreeSet = pSet;
908 while (pSet) {
909 pFreeSet = pSet;
910 pSet = pSet->pNext;
Tobin Ehliseaf28662015-04-08 10:58:37 -0600911 // Freeing layouts handled in deleteLayouts() function
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600912 // Free Update shadow struct tree
913 freeShadowUpdateTree(pFreeSet);
914 if (pFreeSet->ppDescriptors) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200915 delete[] pFreeSet->ppDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600916 }
917 delete pFreeSet;
918 }
919 if ((*ii).second->createInfo.pTypeCount) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200920 delete[] (*ii).second->createInfo.pTypeCount;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600921 }
922 delete (*ii).second;
923 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600924 poolMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600925}
Tobin Ehliseaf28662015-04-08 10:58:37 -0600926// WARN : Once deleteLayouts() called, any layout ptrs in Pool/Set data structure will be invalid
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600927// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600928static void deleteLayouts()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600929{
David Pinedof5997ab2015-04-27 16:36:17 -0600930 if (layoutMap.size() <= 0)
931 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600932 for (unordered_map<VkDescriptorSetLayout, LAYOUT_NODE*>::iterator ii=layoutMap.begin(); ii!=layoutMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600933 LAYOUT_NODE* pLayout = (*ii).second;
Tobin Ehliseaf28662015-04-08 10:58:37 -0600934 if (pLayout->createInfo.pBinding) {
935 for (uint32_t i=0; i<pLayout->createInfo.count; i++) {
936 if (pLayout->createInfo.pBinding[i].pImmutableSamplers)
937 delete[] pLayout->createInfo.pBinding[i].pImmutableSamplers;
938 }
939 delete[] pLayout->createInfo.pBinding;
940 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600941 if (pLayout->pTypes) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200942 delete[] pLayout->pTypes;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600943 }
944 delete pLayout;
945 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600946 layoutMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600947}
948// Currently clearing a set is removing all previous updates to that set
949// TODO : Validate if this is correct clearing behavior
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600950static void clearDescriptorSet(VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600951{
952 SET_NODE* pSet = getSetNode(set);
953 if (!pSet) {
954 // TODO : Return error
955 }
956 else {
957 loader_platform_thread_lock_mutex(&globalLock);
958 freeShadowUpdateTree(pSet);
959 loader_platform_thread_unlock_mutex(&globalLock);
960 }
961}
962
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600963static void clearDescriptorPool(VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600964{
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600965 POOL_NODE* pPool = getPoolNode(pool);
966 if (!pPool) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600967 char str[1024];
Tobin Ehlis28be0be2015-05-22 12:38:16 -0600968 sprintf(str, "Unable to find pool node for pool %p specified in vkResetDescriptorPool() call", (void*)pool);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600969 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, pool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600970 }
971 else
972 {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600973 // For every set off of this pool, clear it
974 SET_NODE* pSet = pPool->pSets;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600975 while (pSet) {
976 clearDescriptorSet(pSet->set);
977 }
978 }
979}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600980// Code here to manage the Cmd buffer LL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600981static GLOBAL_CB_NODE* getCBNode(VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600982{
983 loader_platform_thread_lock_mutex(&globalLock);
984 if (cmdBufferMap.find(cb) == cmdBufferMap.end()) {
985 loader_platform_thread_unlock_mutex(&globalLock);
986 return NULL;
987 }
988 loader_platform_thread_unlock_mutex(&globalLock);
989 return cmdBufferMap[cb];
990}
991// Free all CB Nodes
992// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600993static void deleteCmdBuffers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600994{
David Pinedof5997ab2015-04-27 16:36:17 -0600995 if (cmdBufferMap.size() <= 0)
996 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600997 for (unordered_map<VkCmdBuffer, GLOBAL_CB_NODE*>::iterator ii=cmdBufferMap.begin(); ii!=cmdBufferMap.end(); ++ii) {
Courtney Goeltzenleuchter09098a72015-04-27 15:04:43 -0600998 vector<CMD_NODE*> cmd_node_list = (*ii).second->pCmds;
999 while (!cmd_node_list.empty()) {
1000 CMD_NODE* cmd_node = cmd_node_list.back();
1001 delete cmd_node;
1002 cmd_node_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001003 }
1004 delete (*ii).second;
1005 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -06001006 cmdBufferMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001007}
1008static void addCmd(GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
1009{
1010 CMD_NODE* pCmd = new CMD_NODE;
1011 if (pCmd) {
1012 // init cmd node and append to end of cmd LL
1013 memset(pCmd, 0, sizeof(CMD_NODE));
1014 pCmd->cmdNumber = ++pCB->numCmds;
1015 pCmd->type = cmd;
1016 pCB->pCmds.push_back(pCmd);
1017 }
1018 else {
1019 char str[1024];
1020 sprintf(str, "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %p", (void*)pCB->cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001021 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, pCB->cmdBuffer, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001022 }
1023}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001024static void resetCB(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001025{
1026 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1027 if (pCB) {
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001028 vector<CMD_NODE*> cmd_list = pCB->pCmds;
1029 while (!cmd_list.empty()) {
1030 delete cmd_list.back();
1031 cmd_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001032 }
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001033 pCB->pCmds.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001034 // Reset CB state
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001035 VkFlags saveFlags = pCB->flags;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001036 uint32_t saveQueueNodeIndex = pCB->queueNodeIndex;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001037 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1038 pCB->cmdBuffer = cb;
1039 pCB->flags = saveFlags;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001040 pCB->queueNodeIndex = saveQueueNodeIndex;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001041 pCB->lastVtxBinding = MAX_BINDING;
1042 }
1043}
Tobin Ehlis97866202015-06-10 12:57:07 -06001044// Set PSO-related status bits for CB
1045static void set_cb_pso_status(GLOBAL_CB_NODE* pCB, const PIPELINE_NODE* pPipe)
1046{
1047 for (uint32_t i = 0; i < pPipe->cbStateCI.attachmentCount; i++) {
1048 if (0 != pPipe->pAttachments[i].channelWriteMask) {
1049 pCB->status |= CBSTATUS_COLOR_BLEND_WRITE_ENABLE;
1050 }
1051 }
1052 if (pPipe->dsStateCI.depthWriteEnable) {
1053 pCB->status |= CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE;
1054 }
1055}
1056// Set dyn-state related status bits for an object node
1057static void set_cb_dyn_status(GLOBAL_CB_NODE* pNode, VkStateBindPoint stateBindPoint) {
1058 if (stateBindPoint == VK_STATE_BIND_POINT_VIEWPORT) {
1059 pNode->status |= CBSTATUS_VIEWPORT_BOUND;
1060 } else if (stateBindPoint == VK_STATE_BIND_POINT_RASTER) {
1061 pNode->status |= CBSTATUS_RASTER_BOUND;
1062 } else if (stateBindPoint == VK_STATE_BIND_POINT_COLOR_BLEND) {
1063 pNode->status |= CBSTATUS_COLOR_BLEND_BOUND;
1064 } else if (stateBindPoint == VK_STATE_BIND_POINT_DEPTH_STENCIL) {
1065 pNode->status |= CBSTATUS_DEPTH_STENCIL_BOUND;
1066 }
1067}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001068// Set the last bound dynamic state of given type
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001069static void setLastBoundDynamicState(const VkCmdBuffer cmdBuffer, const VkDynamicStateObject state, const VkStateBindPoint sType)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001070{
1071 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1072 if (pCB) {
1073 updateCBTracking(cmdBuffer);
1074 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis97866202015-06-10 12:57:07 -06001075 set_cb_dyn_status(pCB, sType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001076 addCmd(pCB, CMD_BINDDYNAMICSTATEOBJECT);
1077 if (dynamicStateMap.find(state) == dynamicStateMap.end()) {
1078 char str[1024];
1079 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001080 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, state, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001081 }
1082 else {
1083 pCB->lastBoundDynamicState[sType] = dynamicStateMap[state];
1084 g_lastBoundDynamicState[sType] = dynamicStateMap[state];
1085 }
1086 loader_platform_thread_unlock_mutex(&globalLock);
1087 }
1088 else {
1089 char str[1024];
1090 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001091 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001092 }
1093}
1094// Print the last bound Gfx Pipeline
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001095static void printPipeline(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001096{
1097 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1098 if (pCB) {
1099 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1100 if (!pPipeTrav) {
1101 // nothing to print
1102 }
1103 else {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001104 string pipeStr = vk_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str();
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001105 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr.c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001106 }
1107 }
1108}
1109// Common Dot dumping code
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001110static void dsCoreDumpDot(const VkDescriptorSet ds, FILE* pOutFile)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001111{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001112#if 0
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001113 SET_NODE* pSet = getSetNode(ds);
1114 if (pSet) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001115 POOL_NODE* pPool = getPoolNode(pSet->pool);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001116 char tmp_str[4*1024];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001117 fprintf(pOutFile, "subgraph cluster_DescriptorPool\n{\nlabel=\"Descriptor Pool\"\n");
1118 sprintf(tmp_str, "Pool (%p)", pPool->pool);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001119 char* pGVstr = vk_gv_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, tmp_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001120 fprintf(pOutFile, "%s", pGVstr);
1121 free(pGVstr);
1122 fprintf(pOutFile, "subgraph cluster_DescriptorSet\n{\nlabel=\"Descriptor Set (%p)\"\n", pSet->set);
1123 sprintf(tmp_str, "Descriptor Set (%p)", pSet->set);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001124 LAYOUT_NODE* pLayout = pSet->pLayout;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001125 uint32_t layout_index = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001126 ++layout_index;
1127 sprintf(tmp_str, "LAYOUT%u", layout_index);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001128 pGVstr = vk_gv_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, tmp_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001129 fprintf(pOutFile, "%s", pGVstr);
1130 free(pGVstr);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001131 if (pSet->pUpdateStructs) {
1132 pGVstr = dynamic_gv_display(pSet->pUpdateStructs, "Descriptor Updates");
1133 fprintf(pOutFile, "%s", pGVstr);
1134 free(pGVstr);
1135 }
1136 if (pSet->ppDescriptors) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001137 fprintf(pOutFile, "\"DESCRIPTORS\" [\nlabel=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD COLSPAN=\"2\" PORT=\"desc\">DESCRIPTORS</TD></TR>");
1138 uint32_t i = 0;
1139 for (i=0; i < pSet->descriptorCount; i++) {
1140 if (pSet->ppDescriptors[i]) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001141 fprintf(pOutFile, "<TR><TD PORT=\"slot%u\">slot%u</TD><TD>%s</TD></TR>", i, i, string_VkStructureType(pSet->ppDescriptors[i]->sType));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001142 }
1143 }
1144#define NUM_COLORS 7
1145 vector<string> edgeColors;
1146 edgeColors.push_back("0000ff");
1147 edgeColors.push_back("ff00ff");
1148 edgeColors.push_back("ffff00");
1149 edgeColors.push_back("00ff00");
1150 edgeColors.push_back("000000");
1151 edgeColors.push_back("00ffff");
1152 edgeColors.push_back("ff0000");
1153 uint32_t colorIdx = 0;
1154 fprintf(pOutFile, "</TABLE>>\n];\n");
1155 // Now add the views that are mapped to active descriptors
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001156 VkUpdateSamplers* pUS = NULL;
1157 VkUpdateSamplerTextures* pUST = NULL;
1158 VkUpdateImages* pUI = NULL;
1159 VkUpdateBuffers* pUB = NULL;
1160 VkUpdateAsCopy* pUAC = NULL;
1161 VkSamplerCreateInfo* pSCI = NULL;
1162 VkImageViewCreateInfo* pIVCI = NULL;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001163 VkBufferViewCreateInfo* pBVCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001164 void** ppNextPtr = NULL;
1165 void* pSaveNext = NULL;
1166 for (i=0; i < pSet->descriptorCount; i++) {
1167 if (pSet->ppDescriptors[i]) {
1168 switch (pSet->ppDescriptors[i]->sType)
1169 {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001170 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001171 pUS = (VkUpdateSamplers*)pSet->ppDescriptors[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001172 pSCI = getSamplerCreateInfo(pUS->pSamplers[i-pUS->arrayIndex]);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001173 if (pSCI) {
1174 sprintf(tmp_str, "SAMPLER%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001175 fprintf(pOutFile, "%s", vk_gv_print_vksamplercreateinfo(pSCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001176 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1177 }
1178 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001179 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001180 pUST = (VkUpdateSamplerTextures*)pSet->ppDescriptors[i];
Courtney Goeltzenleuchterd38dcc92015-04-09 11:43:10 -06001181 pSCI = getSamplerCreateInfo(pUST->pSamplerImageViews[i-pUST->arrayIndex].sampler);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001182 if (pSCI) {
1183 sprintf(tmp_str, "SAMPLER%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001184 fprintf(pOutFile, "%s", vk_gv_print_vksamplercreateinfo(pSCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001185 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1186 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001187 pIVCI = getImageViewCreateInfo(pUST->pSamplerImageViews[i-pUST->arrayIndex].pImageView->view);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001188 if (pIVCI) {
1189 sprintf(tmp_str, "IMAGE_VIEW%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001190 fprintf(pOutFile, "%s", vk_gv_print_vkimageviewcreateinfo(pIVCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001191 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1192 }
1193 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001194 case VK_STRUCTURE_TYPE_UPDATE_IMAGES:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001195 pUI = (VkUpdateImages*)pSet->ppDescriptors[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001196 pIVCI = getImageViewCreateInfo(pUI->pImageViews[i-pUI->arrayIndex].view);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001197 if (pIVCI) {
1198 sprintf(tmp_str, "IMAGE_VIEW%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001199 fprintf(pOutFile, "%s", vk_gv_print_vkimageviewcreateinfo(pIVCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001200 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1201 }
1202 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001203 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001204 pUB = (VkUpdateBuffers*)pSet->ppDescriptors[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001205 pBVCI = getBufferViewCreateInfo(pUB->pBufferViews[i-pUB->arrayIndex].view);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001206 if (pBVCI) {
1207 sprintf(tmp_str, "BUFFER_VIEW%u", i);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001208 fprintf(pOutFile, "%s", vk_gv_print_vkbufferviewcreateinfo(pBVCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001209 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1210 }
1211 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001212 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001213 pUAC = (VkUpdateAsCopy*)pSet->ppDescriptors[i];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001214 // TODO : Need to validate this code
1215 // Save off pNext and set to NULL while printing this struct, then restore it
1216 ppNextPtr = (void**)&pUAC->pNext;
1217 pSaveNext = *ppNextPtr;
1218 *ppNextPtr = NULL;
1219 sprintf(tmp_str, "UPDATE_AS_COPY%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001220 fprintf(pOutFile, "%s", vk_gv_print_vkupdateascopy(pUAC, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001221 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1222 // Restore next ptr
1223 *ppNextPtr = pSaveNext;
1224 break;
1225 default:
1226 break;
1227 }
1228 colorIdx = (colorIdx+1) % NUM_COLORS;
1229 }
1230 }
1231 }
1232 fprintf(pOutFile, "}\n");
1233 fprintf(pOutFile, "}\n");
1234 }
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001235#endif
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001236}
1237// Dump subgraph w/ DS info
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001238static void dsDumpDot(const VkCmdBuffer cb, FILE* pOutFile)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001239{
1240 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1241 if (pCB && pCB->lastBoundDescriptorSet) {
1242 dsCoreDumpDot(pCB->lastBoundDescriptorSet, pOutFile);
1243 }
1244}
1245// Dump a GraphViz dot file showing the Cmd Buffers
1246static void cbDumpDotFile(string outFileName)
1247{
1248 // Print CB Chain for each CB
1249 FILE* pOutFile;
1250 pOutFile = fopen(outFileName.c_str(), "w");
1251 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1252 fprintf(pOutFile, "subgraph cluster_cmdBuffers\n{\nlabel=\"Command Buffers\"\n");
1253 GLOBAL_CB_NODE* pCB = NULL;
1254 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
1255 pCB = g_pLastTouchedCB[i];
David Pinedof5997ab2015-04-27 16:36:17 -06001256 if (pCB && pCB->pCmds.size() > 0) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001257 fprintf(pOutFile, "subgraph cluster_cmdBuffer%u\n{\nlabel=\"Command Buffer #%u\"\n", i, i);
1258 uint32_t instNum = 0;
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001259 vector<CMD_NODE*> cmd_list = pCB->pCmds;
1260 for (vector<CMD_NODE*>::iterator ii= cmd_list.begin(); ii!= cmd_list.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001261 if (instNum) {
1262 fprintf(pOutFile, "\"CB%pCMD%u\" -> \"CB%pCMD%u\" [];\n", (void*)pCB->cmdBuffer, instNum-1, (void*)pCB->cmdBuffer, instNum);
1263 }
1264 if (pCB == g_lastGlobalCB) {
1265 fprintf(pOutFile, "\"CB%pCMD%u\" [\nlabel=<<TABLE BGCOLOR=\"#00FF00\" BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD>CMD#</TD><TD>%u</TD></TR><TR><TD>CMD Type</TD><TD>%s</TD></TR></TABLE>>\n];\n", (void*)pCB->cmdBuffer, instNum, instNum, cmdTypeToString((*ii)->type).c_str());
1266 }
1267 else {
1268 fprintf(pOutFile, "\"CB%pCMD%u\" [\nlabel=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD>CMD#</TD><TD>%u</TD></TR><TR><TD>CMD Type</TD><TD>%s</TD></TR></TABLE>>\n];\n", (void*)pCB->cmdBuffer, instNum, instNum, cmdTypeToString((*ii)->type).c_str());
1269 }
1270 ++instNum;
1271 }
1272 fprintf(pOutFile, "}\n");
1273 }
1274 }
1275 fprintf(pOutFile, "}\n");
1276 fprintf(pOutFile, "}\n"); // close main graph "g"
1277 fclose(pOutFile);
1278}
1279// Dump a GraphViz dot file showing the pipeline for last bound global state
1280static void dumpGlobalDotFile(char *outFileName)
1281{
1282 PIPELINE_NODE *pPipeTrav = g_lastBoundPipeline;
1283 if (pPipeTrav) {
1284 FILE* pOutFile;
1285 pOutFile = fopen(outFileName, "w");
1286 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1287 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
1288 char* pGVstr = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001289 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001290 if (g_lastBoundDynamicState[i] && g_lastBoundDynamicState[i]->pCreateInfo) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001291 pGVstr = dynamic_gv_display(g_lastBoundDynamicState[i]->pCreateInfo, string_VkStateBindPoint((VkStateBindPoint)i));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001292 fprintf(pOutFile, "%s", pGVstr);
1293 free(pGVstr);
1294 }
1295 }
1296 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1297 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001298 pGVstr = vk_gv_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "PSO HEAD");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001299 fprintf(pOutFile, "%s", pGVstr);
1300 free(pGVstr);
1301 fprintf(pOutFile, "}\n");
1302 dsCoreDumpDot(g_lastBoundDescriptorSet, pOutFile);
1303 fprintf(pOutFile, "}\n"); // close main graph "g"
1304 fclose(pOutFile);
1305 }
1306}
1307// Dump a GraphViz dot file showing the pipeline for a given CB
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001308static void dumpDotFile(const VkCmdBuffer cb, string outFileName)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001309{
1310 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1311 if (pCB) {
1312 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1313 if (pPipeTrav) {
1314 FILE* pOutFile;
1315 pOutFile = fopen(outFileName.c_str(), "w");
1316 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1317 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
1318 char* pGVstr = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001319 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001320 if (pCB->lastBoundDynamicState[i] && pCB->lastBoundDynamicState[i]->pCreateInfo) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001321 pGVstr = dynamic_gv_display(pCB->lastBoundDynamicState[i]->pCreateInfo, string_VkStateBindPoint((VkStateBindPoint)i));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001322 fprintf(pOutFile, "%s", pGVstr);
1323 free(pGVstr);
1324 }
1325 }
1326 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1327 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001328 pGVstr = vk_gv_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "PSO HEAD");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001329 fprintf(pOutFile, "%s", pGVstr);
1330 free(pGVstr);
1331 fprintf(pOutFile, "}\n");
1332 dsDumpDot(cb, pOutFile);
1333 fprintf(pOutFile, "}\n"); // close main graph "g"
1334 fclose(pOutFile);
1335 }
1336 }
1337}
Tobin Ehlise90b1712015-05-27 14:30:06 -06001338// Verify bound Pipeline State Object
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001339static bool validateBoundPipeline(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001340{
1341 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1342 if (pCB && pCB->lastBoundPipeline) {
1343 // First verify that we have a Node for bound pipeline
1344 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1345 char str[1024];
1346 if (!pPipeTrav) {
1347 sprintf(str, "Can't find last bound Pipeline %p!", (void*)pCB->lastBoundPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001348 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001349 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001350 }
1351 else {
1352 // Verify Vtx binding
1353 if (MAX_BINDING != pCB->lastVtxBinding) {
1354 if (pCB->lastVtxBinding >= pPipeTrav->vtxBindingCount) {
1355 if (0 == pPipeTrav->vtxBindingCount) {
1356 sprintf(str, "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001357 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001358 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001359 }
1360 else {
1361 sprintf(str, "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001362 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001363 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001364 }
1365 }
1366 else {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001367 string tmpStr = vk_print_vkvertexinputbindingdescription(&pPipeTrav->pVertexBindingDescriptions[pCB->lastVtxBinding], "{DS}INFO : ").c_str();
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001368 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr.c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001369 }
1370 }
1371 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001372 return true;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001373 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001374 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001375}
1376// Print details of DS config to stdout
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001377static void printDSConfig(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001378{
1379 char tmp_str[1024];
1380 char ds_config_str[1024*256] = {0}; // TODO : Currently making this buffer HUGE w/o overrun protection. Need to be smarter, start smaller, and grow as needed.
1381 GLOBAL_CB_NODE* pCB = getCBNode(cb);
Tobin Ehlis7297f192015-06-09 08:39:32 -06001382 if (pCB && pCB->lastBoundDescriptorSet) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001383 SET_NODE* pSet = getSetNode(pCB->lastBoundDescriptorSet);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001384 POOL_NODE* pPool = getPoolNode(pSet->pool);
1385 // Print out pool details
1386 sprintf(tmp_str, "Details for pool %p.", (void*)pPool->pool);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001387 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001388 string poolStr = vk_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, " ");
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001389 sprintf(ds_config_str, "%s", poolStr.c_str());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001390 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001391 // Print out set details
1392 char prefix[10];
1393 uint32_t index = 0;
1394 sprintf(tmp_str, "Details for descriptor set %p.", (void*)pSet->set);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001395 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001396 LAYOUT_NODE* pLayout = pSet->pLayout;
1397 // Print layout details
1398 sprintf(tmp_str, "Layout #%u, (object %p) for DS %p.", index+1, (void*)pLayout->layout, (void*)pSet->set);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001399 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001400 sprintf(prefix, " [L%u] ", index);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001401 string DSLstr = vk_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, prefix).c_str();
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001402 sprintf(ds_config_str, "%s", DSLstr.c_str());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001403 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001404 index++;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001405 GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
1406 if (pUpdate) {
1407 sprintf(tmp_str, "Update Chain [UC] for descriptor set %p:", (void*)pSet->set);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001408 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001409 sprintf(prefix, " [UC] ");
1410 sprintf(ds_config_str, "%s", dynamic_display(pUpdate, prefix).c_str());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001411 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001412 // TODO : If there is a "view" associated with this update, print CI for that view
1413 }
1414 else {
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001415 if (0 != pSet->descriptorCount) {
1416 sprintf(tmp_str, "No Update Chain for descriptor set %p which has %u descriptors (vkUpdateDescriptors has not been called)", (void*)pSet->set, pSet->descriptorCount);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001417 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001418 }
1419 else {
1420 sprintf(tmp_str, "FYI: No descriptors in descriptor set %p.", (void*)pSet->set);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001421 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001422 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001423 }
1424 }
1425}
1426
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001427static void printCB(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001428{
1429 GLOBAL_CB_NODE* pCB = getCBNode(cb);
David Pinedof5997ab2015-04-27 16:36:17 -06001430 if (pCB && pCB->pCmds.size() > 0) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001431 char str[1024];
1432 sprintf(str, "Cmds in CB %p", (void*)cb);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001433 layerCbMsg(VK_DBG_REPORT_INFO_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_NONE, "DS", str);
Courtney Goeltzenleuchtercf2a5362015-04-27 11:16:35 -06001434 vector<CMD_NODE*> pCmds = pCB->pCmds;
1435 for (vector<CMD_NODE*>::iterator ii=pCmds.begin(); ii!=pCmds.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001436 sprintf(str, " CMD#%lu: %s", (*ii)->cmdNumber, cmdTypeToString((*ii)->type).c_str());
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001437 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cb, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001438 }
1439 }
1440 else {
1441 // Nothing to print
1442 }
1443}
1444
1445
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001446static void synchAndPrintDSConfig(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001447{
1448 printDSConfig(cb);
1449 printPipeline(cb);
1450 printDynamicState(cb);
1451 static int autoDumpOnce = 0;
1452 if (autoDumpOnce) {
1453 autoDumpOnce = 0;
1454 dumpDotFile(cb, "pipeline_dump.dot");
1455 cbDumpDotFile("cb_dump.dot");
1456#if defined(_WIN32)
1457// FIXME: NEED WINDOWS EQUIVALENT
1458#else // WIN32
1459 // Convert dot to svg if dot available
1460 if(access( "/usr/bin/dot", X_OK) != -1) {
Tony Barbour22a30862015-04-22 09:02:32 -06001461 int retval = system("/usr/bin/dot pipeline_dump.dot -Tsvg -o pipeline_dump.svg");
1462 assert(retval != -1);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001463 }
1464#endif // WIN32
1465 }
1466}
1467
1468static void initDrawState(void)
1469{
1470 const char *strOpt;
1471 // initialize DrawState options
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001472 getLayerOptionEnum("DrawStateReportLevel", (uint32_t *) &g_reportFlags);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001473 g_actionIsDefault = getLayerOptionEnum("DrawStateDebugAction", (uint32_t *) &g_debugAction);
1474
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001475 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001476 {
1477 strOpt = getLayerOption("DrawStateLogFilename");
1478 if (strOpt)
1479 {
1480 g_logFile = fopen(strOpt, "w");
1481 }
1482 if (g_logFile == NULL)
1483 g_logFile = stdout;
1484 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001485
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001486 if (!globalLockInitialized)
1487 {
1488 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001489 // suggestion is to call this during vkCreateInstance(), and then we
1490 // can clean it up during vkDestroyInstance(). However, that requires
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001491 // that the layer have per-instance locks. We need to come back and
1492 // address this soon.
1493 loader_platform_thread_create_mutex(&globalLock);
1494 globalLockInitialized = 1;
1495 }
1496}
1497
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001498VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
1499{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001500 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map,*pInstance);
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001501
1502 loader_platform_thread_once(&g_initOnce, initDrawState);
1503
1504 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
1505
1506 if (result == VK_SUCCESS) {
1507 enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->pEnabledExtensions);
Courtney Goeltzenleuchterf4a2eba2015-06-08 14:58:39 -06001508
1509 debug_report_init_instance_extension_dispatch_table(
1510 pTable,
1511 pTable->GetInstanceProcAddr,
1512 *pInstance);
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001513 }
1514 return result;
1515}
1516
Jon Ashburne0fa2282015-05-20 09:00:28 -06001517/* hook DestroyInstance to remove tableInstanceMap entry */
1518VK_LAYER_EXPORT VkResult VKAPI vkDestroyInstance(VkInstance instance)
1519{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001520 VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) instance;
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001521 VkResult res = get_dispatch_table(draw_state_instance_table_map, instance)->DestroyInstance(instance);
1522 draw_state_instance_table_map.erase(pDisp);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001523 return res;
1524}
1525
Jon Ashburnf0615e22015-05-25 14:11:37 -06001526static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
1527{
1528 uint32_t i, ext_idx;
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001529 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
1530 deviceExtMap[pDisp].debug_marker_enabled = false;
Jon Ashburnf0615e22015-05-25 14:11:37 -06001531
1532 for (i = 0; i < pCreateInfo->extensionCount; i++) {
1533 if (strcmp(pCreateInfo->pEnabledExtensions[i].name, DEBUG_MARKER_EXTENSION_NAME) == 0) {
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001534 /* Found a matching extension name, mark it enabled and init dispatch table*/
1535 initDebugMarkerTable(device);
1536 deviceExtMap[pDisp].debug_marker_enabled = true;
Jon Ashburnf0615e22015-05-25 14:11:37 -06001537 }
1538
1539 }
1540}
1541
Tony Barbour8205d902015-04-16 15:59:00 -06001542VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001543{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001544 VkResult result = get_dispatch_table(draw_state_instance_table_map, gpu)->CreateDevice(gpu, pCreateInfo, pDevice);
Jon Ashburnf0615e22015-05-25 14:11:37 -06001545 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001546 return result;
1547}
1548
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001549VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001550{
1551 // Free all the memory
1552 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliseaf28662015-04-08 10:58:37 -06001553 deletePipelines();
1554 deleteSamplers();
1555 deleteImages();
1556 deleteBuffers();
1557 deleteCmdBuffers();
1558 deleteDynamicState();
1559 deletePools();
1560 deleteLayouts();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001561 loader_platform_thread_unlock_mutex(&globalLock);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001562
1563 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001564 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDevice(device);
1565 draw_state_device_table_map.erase(pDisp);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001566 tableDebugMarkerMap.erase(pDisp);
1567 deviceExtMap.erase(pDisp);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001568 return result;
1569}
1570
Jon Ashburneb2728b2015-04-10 14:33:07 -06001571struct extProps {
1572 uint32_t version;
1573 const char * const name;
1574};
Jon Ashburn0b2ec1d2015-06-15 16:08:39 -06001575#define DRAW_STATE_LAYER_DEV_EXT_ARRAY_SIZE 3
1576static const VkExtensionProperties dsDevExts[DRAW_STATE_LAYER_DEV_EXT_ARRAY_SIZE] = {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001577 {
1578 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
1579 "DrawState",
1580 0x10,
1581 "Sample layer: DrawState",
Courtney Goeltzenleuchter47461fb2015-06-01 14:34:25 -06001582 },
1583 {
1584 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
1585 "Validation",
1586 0x10,
1587 "Sample layer: DrawState",
Jon Ashburn0b2ec1d2015-06-15 16:08:39 -06001588 },
1589 {
1590 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
1591 DEBUG_MARKER_EXTENSION_NAME,
1592 0x10,
1593 "Sample layer: DrawState",
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001594 }
Jon Ashburneb2728b2015-04-10 14:33:07 -06001595};
1596
Jon Ashburnf0615e22015-05-25 14:11:37 -06001597//TODO add DEBUG_MARKER to device extension list
Jon Ashburn64716542015-06-15 12:21:02 -06001598VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionInfo(
1599 VkPhysicalDevice physical_device,
1600 VkExtensionInfoType infoType,
1601 uint32_t extensionIndex,
1602 size_t *pDataSize,
1603 void *pData)
1604{
1605 uint32_t *count;
1606
1607 if (pDataSize == NULL) {
1608 return VK_ERROR_INVALID_POINTER;
1609 }
1610
1611 switch (infoType) {
1612 case VK_EXTENSION_INFO_TYPE_COUNT:
1613 *pDataSize = sizeof(uint32_t);
1614 if (pData == NULL) {
1615 return VK_SUCCESS;
1616 }
1617 count = (uint32_t *) pData;
Jon Ashburn0b2ec1d2015-06-15 16:08:39 -06001618 *count = DRAW_STATE_LAYER_DEV_EXT_ARRAY_SIZE;
Jon Ashburn64716542015-06-15 12:21:02 -06001619 break;
1620 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
1621 *pDataSize = sizeof(VkExtensionProperties);
1622 if (pData == NULL) {
1623 return VK_SUCCESS;
1624 }
Jon Ashburn0b2ec1d2015-06-15 16:08:39 -06001625 if (extensionIndex >= DRAW_STATE_LAYER_DEV_EXT_ARRAY_SIZE) {
Jon Ashburn64716542015-06-15 12:21:02 -06001626 return VK_ERROR_INVALID_VALUE;
1627 }
Jon Ashburn0b2ec1d2015-06-15 16:08:39 -06001628 memcpy((VkExtensionProperties *) pData, &dsDevExts[extensionIndex], sizeof(VkExtensionProperties));
Jon Ashburn64716542015-06-15 12:21:02 -06001629 break;
1630 default:
1631 return VK_ERROR_INVALID_VALUE;
1632 }
1633
1634 return VK_SUCCESS;
1635}
1636
Jon Ashburn0b2ec1d2015-06-15 16:08:39 -06001637#define DRAW_STATE_LAYER_EXT_ARRAY_SIZE 2
1638static const VkExtensionProperties dsExts[DRAW_STATE_LAYER_EXT_ARRAY_SIZE] = {
1639 {
1640 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
1641 "DrawState",
1642 0x10,
1643 "Sample layer: DrawState",
1644 },
1645 {
1646 VK_STRUCTURE_TYPE_EXTENSION_PROPERTIES,
1647 "Validation",
1648 0x10,
1649 "Sample layer: DrawState",
1650 }
1651};
1652
Jon Ashburneb2728b2015-04-10 14:33:07 -06001653VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001654 VkExtensionInfoType infoType,
1655 uint32_t extensionIndex,
1656 size_t* pDataSize,
1657 void* pData)
Jon Ashburneb2728b2015-04-10 14:33:07 -06001658{
Jon Ashburneb2728b2015-04-10 14:33:07 -06001659 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
Jon Ashburneb2728b2015-04-10 14:33:07 -06001660 uint32_t *count;
1661
1662 if (pDataSize == NULL)
1663 return VK_ERROR_INVALID_POINTER;
1664
1665 switch (infoType) {
1666 case VK_EXTENSION_INFO_TYPE_COUNT:
1667 *pDataSize = sizeof(uint32_t);
1668 if (pData == NULL)
1669 return VK_SUCCESS;
1670 count = (uint32_t *) pData;
1671 *count = DRAW_STATE_LAYER_EXT_ARRAY_SIZE;
1672 break;
1673 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
1674 *pDataSize = sizeof(VkExtensionProperties);
1675 if (pData == NULL)
1676 return VK_SUCCESS;
1677 if (extensionIndex >= DRAW_STATE_LAYER_EXT_ARRAY_SIZE)
1678 return VK_ERROR_INVALID_VALUE;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001679 memcpy((VkExtensionProperties *) pData, &dsExts[extensionIndex], sizeof(VkExtensionProperties));
Jon Ashburneb2728b2015-04-10 14:33:07 -06001680 break;
1681 default:
1682 return VK_ERROR_INVALID_VALUE;
1683 };
1684
1685 return VK_SUCCESS;
1686}
1687
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001688VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001689{
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001690 GLOBAL_CB_NODE* pCB = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001691 for (uint32_t i=0; i < cmdBufferCount; i++) {
1692 // Validate that cmd buffers have been updated
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001693 pCB = getCBNode(pCmdBuffers[i]);
1694 loader_platform_thread_lock_mutex(&globalLock);
1695 if (CB_UPDATE_COMPLETE != pCB->state) {
1696 // Flag error for using CB w/o vkEndCommandBuffer() called
1697 char str[1024];
1698 sprintf(str, "You must call vkEndCommandBuffer() on CB %p before this call to vkQueueSubmit()!", pCB->cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001699 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, pCB->cmdBuffer, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS", str);
Tobin Ehlise90b1712015-05-27 14:30:06 -06001700 loader_platform_thread_unlock_mutex(&globalLock);
1701 return VK_ERROR_UNKNOWN;
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001702 }
Tobin Ehlise9b700e2015-05-26 16:06:50 -06001703 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001704 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06001705
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001706 VkResult result = get_dispatch_table(draw_state_device_table_map, queue)->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001707 return result;
1708}
1709
Mike Stroyan230e6252015-04-17 12:36:38 -06001710VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(VkDevice device, VkObjectType objType, VkObject object)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001711{
1712 // TODO : When wrapped objects (such as dynamic state) are destroyed, need to clean up memory
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001713 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyObject(device, objType, object);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001714 return result;
1715}
1716
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001717VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001718{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001719 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001720 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001721 loader_platform_thread_lock_mutex(&globalLock);
1722 BUFFER_NODE* pNewNode = new BUFFER_NODE;
1723 pNewNode->buffer = *pView;
1724 pNewNode->createInfo = *pCreateInfo;
1725 bufferMap[*pView] = pNewNode;
1726 loader_platform_thread_unlock_mutex(&globalLock);
1727 }
1728 return result;
1729}
1730
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001731VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001732{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001733 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001734 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001735 loader_platform_thread_lock_mutex(&globalLock);
1736 IMAGE_NODE *pNewNode = new IMAGE_NODE;
1737 pNewNode->image = *pView;
1738 pNewNode->createInfo = *pCreateInfo;
1739 imageMap[*pView] = pNewNode;
1740 loader_platform_thread_unlock_mutex(&globalLock);
1741 }
1742 return result;
1743}
1744
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001745static void track_pipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline)
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001746{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001747 // Create LL HEAD for this Pipeline
1748 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001749 PIPELINE_NODE* pPipeNode = new PIPELINE_NODE;
1750 memset((void*)pPipeNode, 0, sizeof(PIPELINE_NODE));
1751 pPipeNode->pipeline = *pPipeline;
1752 initPipeline(pPipeNode, pCreateInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001753 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001754}
1755
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001756VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001757{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001758 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001759 // Create LL HEAD for this Pipeline
1760 char str[1024];
1761 sprintf(str, "Created Gfx Pipeline %p", (void*)*pPipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001762 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_PIPELINE, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001763
1764 track_pipeline(pCreateInfo, pPipeline);
1765
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001766 return result;
1767}
1768
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001769VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
1770 VkDevice device,
1771 const VkGraphicsPipelineCreateInfo* pCreateInfo,
1772 VkPipeline basePipeline,
1773 VkPipeline* pPipeline)
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001774{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001775 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001776 // Create LL HEAD for this Pipeline
1777 char str[1024];
1778 sprintf(str, "Created Gfx Pipeline %p (derived from pipeline %p)", (void*)*pPipeline, basePipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001779 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_PIPELINE, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001780
1781 track_pipeline(pCreateInfo, pPipeline);
1782
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001783 loader_platform_thread_unlock_mutex(&globalLock);
Jon Ashburnbdcd7562015-04-14 14:12:59 -06001784
1785 return result;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001786}
1787
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001788VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001789{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001790 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001791 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001792 loader_platform_thread_lock_mutex(&globalLock);
1793 SAMPLER_NODE* pNewNode = new SAMPLER_NODE;
1794 pNewNode->sampler = *pSampler;
1795 pNewNode->createInfo = *pCreateInfo;
1796 sampleMap[*pSampler] = pNewNode;
1797 loader_platform_thread_unlock_mutex(&globalLock);
1798 }
1799 return result;
1800}
1801
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001802VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001803{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001804 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001805 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001806 LAYOUT_NODE* pNewNode = new LAYOUT_NODE;
1807 if (NULL == pNewNode) {
1808 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001809 sprintf(str, "Out of memory while attempting to allocate LAYOUT_NODE in vkCreateDescriptorSetLayout()");
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001810 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, *pSetLayout, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001811 }
1812 memset(pNewNode, 0, sizeof(LAYOUT_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001813 memcpy((void*)&pNewNode->createInfo, pCreateInfo, sizeof(VkDescriptorSetLayoutCreateInfo));
1814 pNewNode->createInfo.pBinding = new VkDescriptorSetLayoutBinding[pCreateInfo->count];
1815 memcpy((void*)pNewNode->createInfo.pBinding, pCreateInfo->pBinding, sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->count);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001816 uint32_t totalCount = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001817 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001818 totalCount += pCreateInfo->pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001819 if (pCreateInfo->pBinding[i].pImmutableSamplers) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001820 VkSampler** ppIS = (VkSampler**)&pNewNode->createInfo.pBinding[i].pImmutableSamplers;
Chia-I Wud3114a22015-05-25 16:22:52 +08001821 *ppIS = new VkSampler[pCreateInfo->pBinding[i].arraySize];
1822 memcpy(*ppIS, pCreateInfo->pBinding[i].pImmutableSamplers, pCreateInfo->pBinding[i].arraySize*sizeof(VkSampler));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001823 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001824 }
1825 if (totalCount > 0) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001826 pNewNode->pTypes = new VkDescriptorType[totalCount];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001827 uint32_t offset = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001828 uint32_t j = 0;
1829 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001830 for (j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001831 pNewNode->pTypes[offset + j] = pCreateInfo->pBinding[i].descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001832 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001833 offset += j;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001834 }
1835 }
1836 pNewNode->layout = *pSetLayout;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001837 pNewNode->startIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001838 pNewNode->endIndex = pNewNode->startIndex + totalCount - 1;
1839 assert(pNewNode->endIndex >= pNewNode->startIndex);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001840 // Put new node at Head of global Layer list
1841 loader_platform_thread_lock_mutex(&globalLock);
1842 layoutMap[*pSetLayout] = pNewNode;
1843 loader_platform_thread_unlock_mutex(&globalLock);
1844 }
1845 return result;
1846}
1847
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001848VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001849{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001850 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001851 if (VK_SUCCESS == result) {
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001852 // TODO : Need to capture the pipeline layout
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001853 }
1854 return result;
1855}
1856
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001857VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001858{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001859 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001860 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001861 // Insert this pool into Global Pool LL at head
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001862 char str[1024];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001863 sprintf(str, "Created Descriptor Pool %p", (void*)*pDescriptorPool);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001864 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (VkObject)pDescriptorPool, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001865 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001866 POOL_NODE* pNewNode = new POOL_NODE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001867 if (NULL == pNewNode) {
1868 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001869 sprintf(str, "Out of memory while attempting to allocate POOL_NODE in vkCreateDescriptorPool()");
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001870 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (VkObject)*pDescriptorPool, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001871 }
1872 else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001873 memset(pNewNode, 0, sizeof(POOL_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001874 VkDescriptorPoolCreateInfo* pCI = (VkDescriptorPoolCreateInfo*)&pNewNode->createInfo;
1875 memcpy((void*)pCI, pCreateInfo, sizeof(VkDescriptorPoolCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001876 if (pNewNode->createInfo.count) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001877 size_t typeCountSize = pNewNode->createInfo.count * sizeof(VkDescriptorTypeCount);
1878 pNewNode->createInfo.pTypeCount = new VkDescriptorTypeCount[typeCountSize];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001879 memcpy((void*)pNewNode->createInfo.pTypeCount, pCreateInfo->pTypeCount, typeCountSize);
1880 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001881 pNewNode->poolUsage = poolUsage;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001882 pNewNode->maxSets = maxSets;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001883 pNewNode->pool = *pDescriptorPool;
1884 poolMap[*pDescriptorPool] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001885 }
1886 loader_platform_thread_unlock_mutex(&globalLock);
1887 }
1888 else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001889 // Need to do anything if pool create fails?
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001890 }
1891 return result;
1892}
1893
Mike Stroyan230e6252015-04-17 12:36:38 -06001894VK_LAYER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001895{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001896 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->ResetDescriptorPool(device, descriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001897 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001898 clearDescriptorPool(descriptorPool);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001899 }
1900 return result;
1901}
1902
Mike Stroyan230e6252015-04-17 12:36:38 -06001903VK_LAYER_EXPORT VkResult VKAPI vkAllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets, uint32_t* pCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001904{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001905 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001906 if ((VK_SUCCESS == result) || (*pCount > 0)) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001907 POOL_NODE *pPoolNode = getPoolNode(descriptorPool);
1908 if (!pPoolNode) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001909 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001910 sprintf(str, "Unable to find pool node for pool %p specified in vkAllocDescriptorSets() call", (void*)descriptorPool);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001911 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, descriptorPool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001912 }
1913 else {
1914 for (uint32_t i = 0; i < *pCount; i++) {
1915 char str[1024];
1916 sprintf(str, "Created Descriptor Set %p", (void*)pDescriptorSets[i]);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001917 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001918 // Create new set node and add to head of pool nodes
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001919 SET_NODE* pNewNode = new SET_NODE;
1920 if (NULL == pNewNode) {
1921 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001922 sprintf(str, "Out of memory while attempting to allocate SET_NODE in vkAllocDescriptorSets()");
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001923 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001924 }
1925 else {
1926 memset(pNewNode, 0, sizeof(SET_NODE));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001927 // Insert set at head of Set LL for this pool
1928 pNewNode->pNext = pPoolNode->pSets;
1929 pPoolNode->pSets = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001930 LAYOUT_NODE* pLayout = getLayoutNode(pSetLayouts[i]);
1931 if (NULL == pLayout) {
1932 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001933 sprintf(str, "Unable to find set layout node for layout %p specified in vkAllocDescriptorSets() call", (void*)pSetLayouts[i]);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001934 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, pSetLayouts[i], 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001935 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001936 pNewNode->pLayout = pLayout;
1937 pNewNode->pool = descriptorPool;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001938 pNewNode->set = pDescriptorSets[i];
1939 pNewNode->setUsage = setUsage;
1940 pNewNode->descriptorCount = pLayout->endIndex + 1;
1941 if (pNewNode->descriptorCount) {
1942 size_t descriptorArraySize = sizeof(GENERIC_HEADER*)*pNewNode->descriptorCount;
1943 pNewNode->ppDescriptors = new GENERIC_HEADER*[descriptorArraySize];
1944 memset(pNewNode->ppDescriptors, 0, descriptorArraySize);
1945 }
1946 setMap[pDescriptorSets[i]] = pNewNode;
1947 }
1948 }
1949 }
1950 }
1951 return result;
1952}
1953
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001954VK_LAYER_EXPORT VkResult VKAPI vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001955{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001956 if (dsUpdate(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, writeCount, pDescriptorWrites) &&
Jon Ashburne0fa2282015-05-20 09:00:28 -06001957 dsUpdate(VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, copyCount, pDescriptorCopies)) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001958 return get_dispatch_table(draw_state_device_table_map, device)->UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001959 }
1960 return VK_ERROR_UNKNOWN;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001961}
1962
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001963VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(VkDevice device, const VkDynamicVpStateCreateInfo* pCreateInfo, VkDynamicVpState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001964{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001965 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicViewportState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001966 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_VIEWPORT);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001967 return result;
1968}
1969
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001970VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(VkDevice device, const VkDynamicRsStateCreateInfo* pCreateInfo, VkDynamicRsState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001971{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001972 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicRasterState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001973 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_RASTER);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001974 return result;
1975}
1976
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001977VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(VkDevice device, const VkDynamicCbStateCreateInfo* pCreateInfo, VkDynamicCbState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001978{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001979 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001980 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_COLOR_BLEND);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001981 return result;
1982}
1983
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001984VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(VkDevice device, const VkDynamicDsStateCreateInfo* pCreateInfo, VkDynamicDsState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001985{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001986 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001987 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_DEPTH_STENCIL);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001988 return result;
1989}
1990
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001991VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001992{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001993 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001994 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001995 loader_platform_thread_lock_mutex(&globalLock);
1996 GLOBAL_CB_NODE* pCB = new GLOBAL_CB_NODE;
1997 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1998 pCB->cmdBuffer = *pCmdBuffer;
1999 pCB->flags = pCreateInfo->flags;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07002000 pCB->queueNodeIndex = pCreateInfo->queueNodeIndex;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002001 pCB->lastVtxBinding = MAX_BINDING;
2002 cmdBufferMap[*pCmdBuffer] = pCB;
2003 loader_platform_thread_unlock_mutex(&globalLock);
2004 updateCBTracking(*pCmdBuffer);
2005 }
2006 return result;
2007}
2008
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002009VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002010{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002011 VkResult result = get_dispatch_table(draw_state_device_table_map, cmdBuffer)->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002012 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002013 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2014 if (pCB) {
2015 if (CB_NEW != pCB->state)
2016 resetCB(cmdBuffer);
2017 pCB->state = CB_UPDATE_ACTIVE;
Tobin Ehlis2464b882015-04-01 08:40:34 -06002018 if (pBeginInfo->pNext) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002019 VkCmdBufferGraphicsBeginInfo* pCbGfxBI = (VkCmdBufferGraphicsBeginInfo*)pBeginInfo->pNext;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002020 if (VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO == pCbGfxBI->sType) {
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06002021 pCB->activeRenderPass = pCbGfxBI->renderPassContinue.renderPass;
Tobin Ehlis2464b882015-04-01 08:40:34 -06002022 }
2023 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002024 }
2025 else {
2026 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002027 sprintf(str, "In vkBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002028 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002029 }
2030 updateCBTracking(cmdBuffer);
2031 }
2032 return result;
2033}
2034
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002035VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002036{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002037 VkResult result = get_dispatch_table(draw_state_device_table_map, cmdBuffer)->EndCommandBuffer(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002038 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002039 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2040 if (pCB) {
2041 pCB->state = CB_UPDATE_COMPLETE;
Tobin Ehlis97866202015-06-10 12:57:07 -06002042 // Reset CB status flags
2043 pCB->status = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002044 printCB(cmdBuffer);
2045 }
2046 else {
2047 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002048 sprintf(str, "In vkEndCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002049 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002050 }
2051 updateCBTracking(cmdBuffer);
2052 //cbDumpDotFile("cb_dump.dot");
2053 }
2054 return result;
2055}
2056
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002057VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002058{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002059 VkResult result = get_dispatch_table(draw_state_device_table_map, cmdBuffer)->ResetCommandBuffer(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002060 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002061 resetCB(cmdBuffer);
2062 updateCBTracking(cmdBuffer);
2063 }
2064 return result;
2065}
2066
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002067VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002068{
2069 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2070 if (pCB) {
2071 updateCBTracking(cmdBuffer);
2072 addCmd(pCB, CMD_BINDPIPELINE);
2073 PIPELINE_NODE* pPN = getPipeline(pipeline);
2074 if (pPN) {
2075 pCB->lastBoundPipeline = pipeline;
2076 loader_platform_thread_lock_mutex(&globalLock);
2077 g_lastBoundPipeline = pPN;
2078 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002079 validatePipelineState(pCB, pipelineBindPoint, pipeline);
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002080 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002081 }
2082 else {
2083 char str[1024];
2084 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002085 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline, 0, DRAWSTATE_INVALID_PIPELINE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002086 }
2087 }
2088 else {
2089 char str[1024];
2090 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002091 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002092 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002093}
2094
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002095VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(VkCmdBuffer cmdBuffer, VkStateBindPoint stateBindPoint, VkDynamicStateObject state)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002096{
2097 setLastBoundDynamicState(cmdBuffer, state, stateBindPoint);
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002098 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002099}
2100
Cody Northrop1a01b1d2015-04-16 13:41:56 -06002101VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002102{
2103 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2104 if (pCB) {
2105 updateCBTracking(cmdBuffer);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06002106 addCmd(pCB, CMD_BINDDESCRIPTORSETS);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002107 if (validateBoundPipeline(cmdBuffer)) {
2108 for (uint32_t i=0; i<setCount; i++) {
2109 if (getSetNode(pDescriptorSets[i])) {
2110 loader_platform_thread_lock_mutex(&globalLock);
2111 pCB->lastBoundDescriptorSet = pDescriptorSets[i];
2112 pCB->boundDescriptorSets.push_back(pDescriptorSets[i]);
2113 g_lastBoundDescriptorSet = pDescriptorSets[i];
2114 loader_platform_thread_unlock_mutex(&globalLock);
2115 char str[1024];
2116 sprintf(str, "DS %p bound on pipeline %s", (void*)pDescriptorSets[i], string_VkPipelineBindPoint(pipelineBindPoint));
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002117 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002118 }
2119 else {
2120 char str[1024];
2121 sprintf(str, "Attempt to bind DS %p that doesn't exist!", (void*)pDescriptorSets[i]);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002122 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i], 0, DRAWSTATE_INVALID_SET, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002123 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002124 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002125 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002126 }
2127 }
2128 else {
2129 char str[1024];
2130 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002131 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002132 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002133}
2134
Tony Barbour8205d902015-04-16 15:59:00 -06002135VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002136{
2137 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2138 if (pCB) {
2139 updateCBTracking(cmdBuffer);
2140 addCmd(pCB, CMD_BINDINDEXBUFFER);
2141 // TODO : Track idxBuffer binding
2142 }
2143 else {
2144 char str[1024];
2145 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002146 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002147 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002148 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002149}
2150
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002151VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
2152 VkCmdBuffer cmdBuffer,
2153 uint32_t startBinding,
2154 uint32_t bindingCount,
2155 const VkBuffer* pBuffers,
Tony Barbour8205d902015-04-16 15:59:00 -06002156 const VkDeviceSize* pOffsets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002157{
2158 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2159 if (pCB) {
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002160 /* TODO: Need to track all the vertex buffers, not just last one */
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002161 updateCBTracking(cmdBuffer);
2162 addCmd(pCB, CMD_BINDVERTEXBUFFER);
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002163 pCB->lastVtxBinding = startBinding + bindingCount -1;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002164 if (validateBoundPipeline(cmdBuffer)) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002165 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002166 }
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002167 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002168 char str[1024];
2169 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002170 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002171 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002172}
2173
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002174VK_LAYER_EXPORT void VKAPI vkCmdDraw(VkCmdBuffer cmdBuffer, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002175{
2176 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002177 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002178 if (pCB) {
2179 updateCBTracking(cmdBuffer);
2180 addCmd(pCB, CMD_DRAW);
2181 pCB->drawCount[DRAW]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002182 loader_platform_thread_lock_mutex(&globalLock);
2183 valid = validate_draw_state_flags(cmdBuffer);
2184 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002185 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002186 sprintf(str, "vkCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002187 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002188 synchAndPrintDSConfig(cmdBuffer);
2189 }
2190 else {
2191 char str[1024];
2192 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002193 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002194 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002195 if (valid) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002196 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
Jon Ashburne0fa2282015-05-20 09:00:28 -06002197 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002198}
2199
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002200VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexed(VkCmdBuffer cmdBuffer, uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002201{
2202 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002203 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002204 if (pCB) {
2205 updateCBTracking(cmdBuffer);
2206 addCmd(pCB, CMD_DRAWINDEXED);
2207 pCB->drawCount[DRAW_INDEXED]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002208 loader_platform_thread_lock_mutex(&globalLock);
2209 valid = validate_draw_state_flags(cmdBuffer);
2210 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002211 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002212 sprintf(str, "vkCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002213 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002214 synchAndPrintDSConfig(cmdBuffer);
2215 }
2216 else {
2217 char str[1024];
2218 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002219 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002220 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002221 if (valid) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002222 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
Jon Ashburne0fa2282015-05-20 09:00:28 -06002223 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002224}
2225
Tony Barbour8205d902015-04-16 15:59:00 -06002226VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002227{
2228 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002229 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002230 if (pCB) {
2231 updateCBTracking(cmdBuffer);
2232 addCmd(pCB, CMD_DRAWINDIRECT);
2233 pCB->drawCount[DRAW_INDIRECT]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002234 loader_platform_thread_lock_mutex(&globalLock);
2235 valid = validate_draw_state_flags(cmdBuffer);
2236 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002237 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002238 sprintf(str, "vkCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002239 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002240 synchAndPrintDSConfig(cmdBuffer);
2241 }
2242 else {
2243 char str[1024];
2244 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002245 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002246 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002247 if (valid) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002248 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Jon Ashburne0fa2282015-05-20 09:00:28 -06002249 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002250}
2251
Tony Barbour8205d902015-04-16 15:59:00 -06002252VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002253{
2254 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002255 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002256 if (pCB) {
2257 updateCBTracking(cmdBuffer);
2258 addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
2259 pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002260 loader_platform_thread_lock_mutex(&globalLock);
2261 valid = validate_draw_state_flags(cmdBuffer);
2262 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002263 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002264 sprintf(str, "vkCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002265 layerCbMsg(VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002266 synchAndPrintDSConfig(cmdBuffer);
2267 }
2268 else {
2269 char str[1024];
2270 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002271 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002272 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002273 if (valid) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002274 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Jon Ashburne0fa2282015-05-20 09:00:28 -06002275 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002276}
2277
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002278VK_LAYER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002279{
2280 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2281 if (pCB) {
2282 updateCBTracking(cmdBuffer);
2283 addCmd(pCB, CMD_DISPATCH);
2284 }
2285 else {
2286 char str[1024];
2287 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002288 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002289 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002290 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDispatch(cmdBuffer, x, y, z);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002291}
2292
Tony Barbour8205d902015-04-16 15:59:00 -06002293VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002294{
2295 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2296 if (pCB) {
2297 updateCBTracking(cmdBuffer);
2298 addCmd(pCB, CMD_DISPATCHINDIRECT);
2299 }
2300 else {
2301 char str[1024];
2302 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002303 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002304 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002305 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002306}
2307
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002308VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002309{
2310 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2311 if (pCB) {
2312 updateCBTracking(cmdBuffer);
2313 addCmd(pCB, CMD_COPYBUFFER);
2314 }
2315 else {
2316 char str[1024];
2317 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002318 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002319 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002320 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002321}
2322
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002323VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer,
2324 VkImage srcImage,
2325 VkImageLayout srcImageLayout,
2326 VkImage destImage,
2327 VkImageLayout destImageLayout,
2328 uint32_t regionCount, const VkImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002329{
2330 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2331 if (pCB) {
2332 updateCBTracking(cmdBuffer);
2333 addCmd(pCB, CMD_COPYIMAGE);
2334 }
2335 else {
2336 char str[1024];
2337 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002338 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002339 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002340 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002341}
2342
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002343VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer,
2344 VkImage srcImage, VkImageLayout srcImageLayout,
2345 VkImage destImage, VkImageLayout destImageLayout,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002346 uint32_t regionCount, const VkImageBlit* pRegions,
2347 VkTexFilter filter)
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002348{
2349 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2350 if (pCB) {
2351 updateCBTracking(cmdBuffer);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06002352 addCmd(pCB, CMD_BLITIMAGE);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002353 }
2354 else {
2355 char str[1024];
2356 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002357 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002358 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002359 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002360}
2361
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002362VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer,
2363 VkBuffer srcBuffer,
2364 VkImage destImage, VkImageLayout destImageLayout,
2365 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002366{
2367 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2368 if (pCB) {
2369 updateCBTracking(cmdBuffer);
2370 addCmd(pCB, CMD_COPYBUFFERTOIMAGE);
2371 }
2372 else {
2373 char str[1024];
2374 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002375 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002376 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002377 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002378}
2379
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002380VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer,
2381 VkImage srcImage, VkImageLayout srcImageLayout,
2382 VkBuffer destBuffer,
2383 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002384{
2385 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2386 if (pCB) {
2387 updateCBTracking(cmdBuffer);
2388 addCmd(pCB, CMD_COPYIMAGETOBUFFER);
2389 }
2390 else {
2391 char str[1024];
2392 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002393 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002394 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002395 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002396}
2397
Tony Barbour8205d902015-04-16 15:59:00 -06002398VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002399{
2400 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2401 if (pCB) {
2402 updateCBTracking(cmdBuffer);
2403 addCmd(pCB, CMD_UPDATEBUFFER);
2404 }
2405 else {
2406 char str[1024];
2407 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002408 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002409 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002410 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002411}
2412
Tony Barbour8205d902015-04-16 15:59:00 -06002413VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002414{
2415 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2416 if (pCB) {
2417 updateCBTracking(cmdBuffer);
2418 addCmd(pCB, CMD_FILLBUFFER);
2419 }
2420 else {
2421 char str[1024];
2422 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002423 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002424 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002425 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002426}
2427
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002428VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2429 VkCmdBuffer cmdBuffer,
2430 VkImage image, VkImageLayout imageLayout,
2431 const VkClearColor *pColor,
2432 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002433{
2434 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2435 if (pCB) {
2436 updateCBTracking(cmdBuffer);
2437 addCmd(pCB, CMD_CLEARCOLORIMAGE);
2438 }
2439 else {
2440 char str[1024];
2441 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002442 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002443 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002444 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002445}
2446
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002447VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(VkCmdBuffer cmdBuffer,
2448 VkImage image, VkImageLayout imageLayout,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002449 float depth, uint32_t stencil,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002450 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002451{
2452 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2453 if (pCB) {
2454 updateCBTracking(cmdBuffer);
2455 addCmd(pCB, CMD_CLEARDEPTHSTENCIL);
2456 }
2457 else {
2458 char str[1024];
2459 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002460 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002461 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002462 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002463}
2464
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002465VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer,
2466 VkImage srcImage, VkImageLayout srcImageLayout,
2467 VkImage destImage, VkImageLayout destImageLayout,
Tony Barbour11f74372015-04-13 15:02:52 -06002468 uint32_t regionCount, const VkImageResolve* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002469{
2470 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2471 if (pCB) {
2472 updateCBTracking(cmdBuffer);
2473 addCmd(pCB, CMD_RESOLVEIMAGE);
2474 }
2475 else {
2476 char str[1024];
2477 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002478 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002479 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002480 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002481}
2482
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002483VK_LAYER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002484{
2485 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2486 if (pCB) {
2487 updateCBTracking(cmdBuffer);
2488 addCmd(pCB, CMD_SETEVENT);
2489 }
2490 else {
2491 char str[1024];
2492 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002493 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002494 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002495 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdSetEvent(cmdBuffer, event, pipeEvent);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002496}
2497
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002498VK_LAYER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002499{
2500 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2501 if (pCB) {
2502 updateCBTracking(cmdBuffer);
2503 addCmd(pCB, CMD_RESETEVENT);
2504 }
2505 else {
2506 char str[1024];
2507 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002508 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002509 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002510 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdResetEvent(cmdBuffer, event, pipeEvent);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002511}
2512
Tony Barbour8205d902015-04-16 15:59:00 -06002513VK_LAYER_EXPORT void VKAPI vkCmdWaitEvents(VkCmdBuffer cmdBuffer, VkWaitEvent waitEvent, uint32_t eventCount, const VkEvent* pEvents, uint32_t memBarrierCount, const void** ppMemBarriers)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002514{
2515 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2516 if (pCB) {
2517 updateCBTracking(cmdBuffer);
2518 addCmd(pCB, CMD_WAITEVENTS);
2519 }
2520 else {
2521 char str[1024];
2522 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002523 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002524 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002525 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdWaitEvents(cmdBuffer, waitEvent, eventCount, pEvents, memBarrierCount, ppMemBarriers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002526}
2527
Tony Barbour8205d902015-04-16 15:59:00 -06002528VK_LAYER_EXPORT void VKAPI vkCmdPipelineBarrier(VkCmdBuffer cmdBuffer, VkWaitEvent waitEvent, uint32_t pipeEventCount, const VkPipeEvent* pPipeEvents, uint32_t memBarrierCount, const void** ppMemBarriers)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002529{
2530 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2531 if (pCB) {
2532 updateCBTracking(cmdBuffer);
2533 addCmd(pCB, CMD_PIPELINEBARRIER);
2534 }
2535 else {
2536 char str[1024];
2537 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002538 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002539 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002540 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdPipelineBarrier(cmdBuffer, waitEvent, pipeEventCount, pPipeEvents, memBarrierCount, ppMemBarriers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002541}
2542
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002543VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002544{
2545 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2546 if (pCB) {
2547 updateCBTracking(cmdBuffer);
2548 addCmd(pCB, CMD_BEGINQUERY);
2549 }
2550 else {
2551 char str[1024];
2552 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002553 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002554 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002555 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002556}
2557
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002558VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002559{
2560 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2561 if (pCB) {
2562 updateCBTracking(cmdBuffer);
2563 addCmd(pCB, CMD_ENDQUERY);
2564 }
2565 else {
2566 char str[1024];
2567 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002568 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002569 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002570 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdEndQuery(cmdBuffer, queryPool, slot);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002571}
2572
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002573VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002574{
2575 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2576 if (pCB) {
2577 updateCBTracking(cmdBuffer);
2578 addCmd(pCB, CMD_RESETQUERYPOOL);
2579 }
2580 else {
2581 char str[1024];
2582 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002583 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002584 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002585 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002586}
2587
Tony Barbour8205d902015-04-16 15:59:00 -06002588VK_LAYER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002589{
2590 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2591 if (pCB) {
2592 updateCBTracking(cmdBuffer);
2593 addCmd(pCB, CMD_WRITETIMESTAMP);
2594 }
2595 else {
2596 char str[1024];
2597 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002598 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002599 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002600 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002601}
2602
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002603VK_LAYER_EXPORT void VKAPI vkCmdInitAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, const uint32_t* pData)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002604{
2605 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2606 if (pCB) {
2607 updateCBTracking(cmdBuffer);
2608 addCmd(pCB, CMD_INITATOMICCOUNTERS);
2609 }
2610 else {
2611 char str[1024];
2612 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002613 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002614 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002615 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002616}
2617
Tony Barbour8205d902015-04-16 15:59:00 -06002618VK_LAYER_EXPORT void VKAPI vkCmdLoadAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, VkBuffer srcBuffer, VkDeviceSize srcOffset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002619{
2620 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2621 if (pCB) {
2622 updateCBTracking(cmdBuffer);
2623 addCmd(pCB, CMD_LOADATOMICCOUNTERS);
2624 }
2625 else {
2626 char str[1024];
2627 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002628 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002629 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002630 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002631}
2632
Tony Barbour8205d902015-04-16 15:59:00 -06002633VK_LAYER_EXPORT void VKAPI vkCmdSaveAtomicCounters(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t startCounter, uint32_t counterCount, VkBuffer destBuffer, VkDeviceSize destOffset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002634{
2635 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2636 if (pCB) {
2637 updateCBTracking(cmdBuffer);
2638 addCmd(pCB, CMD_SAVEATOMICCOUNTERS);
2639 }
2640 else {
2641 char str[1024];
2642 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002643 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002644 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002645 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002646}
2647
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002648VK_LAYER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002649{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002650 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateFramebuffer(device, pCreateInfo, pFramebuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002651 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002652 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002653 VkFramebufferCreateInfo* localFBCI = new VkFramebufferCreateInfo(*pCreateInfo);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002654 if (pCreateInfo->pColorAttachments) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002655 localFBCI->pColorAttachments = new VkColorAttachmentBindInfo[localFBCI->colorAttachmentCount];
2656 memcpy((void*)localFBCI->pColorAttachments, pCreateInfo->pColorAttachments, localFBCI->colorAttachmentCount*sizeof(VkColorAttachmentBindInfo));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002657 }
2658 if (pCreateInfo->pDepthStencilAttachment) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002659 localFBCI->pDepthStencilAttachment = new VkDepthStencilBindInfo[localFBCI->colorAttachmentCount];
2660 memcpy((void*)localFBCI->pDepthStencilAttachment, pCreateInfo->pDepthStencilAttachment, localFBCI->colorAttachmentCount*sizeof(VkDepthStencilBindInfo));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002661 }
2662 frameBufferMap[*pFramebuffer] = localFBCI;
2663 }
2664 return result;
2665}
2666
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002667VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002668{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002669 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002670 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002671 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002672 VkRenderPassCreateInfo* localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002673 if (pCreateInfo->pColorLoadOps) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002674 localRPCI->pColorLoadOps = new VkAttachmentLoadOp[localRPCI->colorAttachmentCount];
2675 memcpy((void*)localRPCI->pColorLoadOps, pCreateInfo->pColorLoadOps, localRPCI->colorAttachmentCount*sizeof(VkAttachmentLoadOp));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002676 }
2677 if (pCreateInfo->pColorStoreOps) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002678 localRPCI->pColorStoreOps = new VkAttachmentStoreOp[localRPCI->colorAttachmentCount];
2679 memcpy((void*)localRPCI->pColorStoreOps, pCreateInfo->pColorStoreOps, localRPCI->colorAttachmentCount*sizeof(VkAttachmentStoreOp));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002680 }
2681 if (pCreateInfo->pColorLoadClearValues) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002682 localRPCI->pColorLoadClearValues = new VkClearColor[localRPCI->colorAttachmentCount];
2683 memcpy((void*)localRPCI->pColorLoadClearValues, pCreateInfo->pColorLoadClearValues, localRPCI->colorAttachmentCount*sizeof(VkClearColor));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002684 }
2685 renderPassMap[*pRenderPass] = localRPCI;
2686 }
2687 return result;
2688}
2689
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002690VK_LAYER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBegin *pRenderPassBegin)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002691{
2692 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2693 if (pCB) {
2694 updateCBTracking(cmdBuffer);
2695 addCmd(pCB, CMD_BEGINRENDERPASS);
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06002696 pCB->activeRenderPass = pRenderPassBegin->renderPass;
2697 pCB->framebuffer = pRenderPassBegin->framebuffer;
Tony Barbourb9f82ba2015-04-06 11:09:26 -06002698 if (pCB->lastBoundPipeline) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002699 validatePipelineState(pCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
Tony Barbourb9f82ba2015-04-06 11:09:26 -06002700 }
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06002701 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002702 char str[1024];
2703 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002704 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002705 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002706 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002707}
2708
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002709VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer, VkRenderPass renderPass)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002710{
2711 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2712 if (pCB) {
2713 updateCBTracking(cmdBuffer);
2714 addCmd(pCB, CMD_ENDRENDERPASS);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002715 pCB->activeRenderPass = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002716 }
2717 else {
2718 char str[1024];
2719 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002720 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002721 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002722 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdEndRenderPass(cmdBuffer, renderPass);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002723}
2724
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002725VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
2726 VkInstance instance,
2727 VkFlags msgFlags,
2728 const PFN_vkDbgMsgCallback pfnMsgCallback,
2729 void* pUserData,
2730 VkDbgMsgCallback* pMsgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002731{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002732 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map, instance);
Tobin Ehlisc91330b2015-06-16 09:04:30 -06002733 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
2734 if (VK_SUCCESS == res) {
2735 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2736 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
2737 }
2738 return res;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002739}
2740
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002741VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
2742 VkInstance instance,
2743 VkDbgMsgCallback msgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002744{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002745 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map, instance);
Tobin Ehlisc91330b2015-06-16 09:04:30 -06002746 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
2747 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2748 layer_destroy_msg_callback(my_data->report_data, msgCallback);
2749 return res;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002750}
2751
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002752VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002753{
2754 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002755 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) cmdBuffer;
2756 if (!deviceExtMap[pDisp].debug_marker_enabled) {
Jon Ashburnf0615e22015-05-25 14:11:37 -06002757 char str[1024];
2758 sprintf(str, "Attempt to use CmdDbgMarkerBegin but extension disabled!");
2759 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_EXTENSION, "DS", str);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002760 return;
Jon Ashburnf0615e22015-05-25 14:11:37 -06002761 }
2762 else if (pCB) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002763 updateCBTracking(cmdBuffer);
2764 addCmd(pCB, CMD_DBGMARKERBEGIN);
2765 }
2766 else {
2767 char str[1024];
2768 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002769 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002770 }
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002771 debug_marker_dispatch_table(cmdBuffer)->CmdDbgMarkerBegin(cmdBuffer, pMarker);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002772}
2773
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002774VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerEnd(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002775{
2776 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002777 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) cmdBuffer;
2778 if (!deviceExtMap[pDisp].debug_marker_enabled) {
Jon Ashburnf0615e22015-05-25 14:11:37 -06002779 char str[1024];
2780 sprintf(str, "Attempt to use CmdDbgMarkerEnd but extension disabled!");
2781 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_EXTENSION, "DS", str);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002782 return;
Jon Ashburnf0615e22015-05-25 14:11:37 -06002783 }
2784 else if (pCB) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002785 updateCBTracking(cmdBuffer);
2786 addCmd(pCB, CMD_DBGMARKEREND);
2787 }
2788 else {
2789 char str[1024];
2790 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002791 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002792 }
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002793 debug_marker_dispatch_table(cmdBuffer)->CmdDbgMarkerEnd(cmdBuffer);
2794}
2795
2796VK_LAYER_EXPORT VkResult VKAPI vkDbgSetObjectTag(VkDevice device, VkObjectType objType, VkObject object, size_t tagSize, const void* pTag)
2797{
2798 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
2799 if (!deviceExtMap[pDisp].debug_marker_enabled) {
2800 char const str[] = "Attempt to use DbgSetObjectTag but extension disabled!";
2801 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, objType, object, 0, DRAWSTATE_INVALID_EXTENSION, "DS", str);
2802 return VK_ERROR_UNAVAILABLE;
2803 }
2804 debug_marker_dispatch_table(device)->DbgSetObjectTag(device, objType, object, tagSize, pTag);
2805}
2806
2807VK_LAYER_EXPORT VkResult VKAPI vkDbgSetObjectName(VkDevice device, VkObjectType objType, VkObject object, size_t nameSize, const char* pName)
2808{
2809 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
2810 if (!deviceExtMap[pDisp].debug_marker_enabled) {
2811 char const str[] = "Attempt to use DbgSetObjectName but extension disabled!";
2812 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, objType, object, 0, DRAWSTATE_INVALID_EXTENSION, "DS", str);
2813 return VK_ERROR_UNAVAILABLE;
2814 }
2815 debug_marker_dispatch_table(device)->DbgSetObjectName(device, objType, object, nameSize, pName);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002816}
2817
2818// TODO : Want to pass in a cmdBuffer here based on which state to display
2819void drawStateDumpDotFile(char* outFileName)
2820{
2821 // TODO : Currently just setting cmdBuffer based on global var
2822 //dumpDotFile(g_lastDrawStateCmdBuffer, outFileName);
2823 dumpGlobalDotFile(outFileName);
2824}
2825
2826void drawStateDumpCommandBufferDotFile(char* outFileName)
2827{
2828 cbDumpDotFile(outFileName);
2829}
2830
2831void drawStateDumpPngFile(char* outFileName)
2832{
2833#if defined(_WIN32)
2834// FIXME: NEED WINDOWS EQUIVALENT
2835 char str[1024];
2836 sprintf(str, "Cannot execute dot program yet on Windows.");
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002837 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002838#else // WIN32
2839 char dotExe[32] = "/usr/bin/dot";
2840 if( access(dotExe, X_OK) != -1) {
2841 dumpDotFile(g_lastCmdBuffer[getTIDIndex()], "/tmp/tmp.dot");
2842 char dotCmd[1024];
2843 sprintf(dotCmd, "%s /tmp/tmp.dot -Tpng -o %s", dotExe, outFileName);
Tony Barbour22a30862015-04-22 09:02:32 -06002844 int retval = system(dotCmd);
2845 assert(retval != -1);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002846 remove("/tmp/tmp.dot");
2847 }
2848 else {
2849 char str[1024];
2850 sprintf(str, "Cannot execute dot program at (%s) to dump requested %s file.", dotExe, outFileName);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002851 layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002852 }
2853#endif // WIN32
2854}
2855
Jon Ashburn1245cec2015-05-18 13:20:15 -06002856VK_LAYER_EXPORT void* VKAPI vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002857{
Jon Ashburn1245cec2015-05-18 13:20:15 -06002858 if (dev == NULL)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002859 return NULL;
Jon Ashburne0fa2282015-05-20 09:00:28 -06002860
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002861 loader_platform_thread_once(&g_initOnce, initDrawState);
2862
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002863 /* loader uses this to force layer initialization; device object is wrapped */
2864 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002865 initDeviceTable(draw_state_device_table_map, (const VkBaseLayerObject *) dev);
Jon Ashburn1245cec2015-05-18 13:20:15 -06002866 return (void *) vkGetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002867 }
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002868 if (!strcmp(funcName, "vkDestroyDevice"))
2869 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002870 if (!strcmp(funcName, "vkQueueSubmit"))
2871 return (void*) vkQueueSubmit;
2872 if (!strcmp(funcName, "vkDestroyObject"))
2873 return (void*) vkDestroyObject;
2874 if (!strcmp(funcName, "vkCreateBufferView"))
2875 return (void*) vkCreateBufferView;
2876 if (!strcmp(funcName, "vkCreateImageView"))
2877 return (void*) vkCreateImageView;
2878 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2879 return (void*) vkCreateGraphicsPipeline;
2880 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2881 return (void*) vkCreateGraphicsPipelineDerivative;
2882 if (!strcmp(funcName, "vkCreateSampler"))
2883 return (void*) vkCreateSampler;
2884 if (!strcmp(funcName, "vkCreateDescriptorSetLayout"))
2885 return (void*) vkCreateDescriptorSetLayout;
Mark Lobodzinski556f7212015-04-17 14:11:39 -05002886 if (!strcmp(funcName, "vkCreatePipelineLayout"))
2887 return (void*) vkCreatePipelineLayout;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002888 if (!strcmp(funcName, "vkCreateDescriptorPool"))
2889 return (void*) vkCreateDescriptorPool;
2890 if (!strcmp(funcName, "vkResetDescriptorPool"))
2891 return (void*) vkResetDescriptorPool;
2892 if (!strcmp(funcName, "vkAllocDescriptorSets"))
2893 return (void*) vkAllocDescriptorSets;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08002894 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
2895 return (void*) vkUpdateDescriptorSets;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002896 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2897 return (void*) vkCreateDynamicViewportState;
2898 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2899 return (void*) vkCreateDynamicRasterState;
2900 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2901 return (void*) vkCreateDynamicColorBlendState;
2902 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2903 return (void*) vkCreateDynamicDepthStencilState;
2904 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2905 return (void*) vkCreateCommandBuffer;
2906 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2907 return (void*) vkBeginCommandBuffer;
2908 if (!strcmp(funcName, "vkEndCommandBuffer"))
2909 return (void*) vkEndCommandBuffer;
2910 if (!strcmp(funcName, "vkResetCommandBuffer"))
2911 return (void*) vkResetCommandBuffer;
2912 if (!strcmp(funcName, "vkCmdBindPipeline"))
2913 return (void*) vkCmdBindPipeline;
2914 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2915 return (void*) vkCmdBindDynamicStateObject;
2916 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2917 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002918 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2919 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002920 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2921 return (void*) vkCmdBindIndexBuffer;
2922 if (!strcmp(funcName, "vkCmdDraw"))
2923 return (void*) vkCmdDraw;
2924 if (!strcmp(funcName, "vkCmdDrawIndexed"))
2925 return (void*) vkCmdDrawIndexed;
2926 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2927 return (void*) vkCmdDrawIndirect;
2928 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2929 return (void*) vkCmdDrawIndexedIndirect;
2930 if (!strcmp(funcName, "vkCmdDispatch"))
2931 return (void*) vkCmdDispatch;
2932 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2933 return (void*) vkCmdDispatchIndirect;
2934 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2935 return (void*) vkCmdCopyBuffer;
2936 if (!strcmp(funcName, "vkCmdCopyImage"))
2937 return (void*) vkCmdCopyImage;
2938 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2939 return (void*) vkCmdCopyBufferToImage;
2940 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2941 return (void*) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002942 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2943 return (void*) vkCmdUpdateBuffer;
2944 if (!strcmp(funcName, "vkCmdFillBuffer"))
2945 return (void*) vkCmdFillBuffer;
2946 if (!strcmp(funcName, "vkCmdClearColorImage"))
2947 return (void*) vkCmdClearColorImage;
2948 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2949 return (void*) vkCmdClearDepthStencil;
2950 if (!strcmp(funcName, "vkCmdResolveImage"))
2951 return (void*) vkCmdResolveImage;
2952 if (!strcmp(funcName, "vkCmdSetEvent"))
2953 return (void*) vkCmdSetEvent;
2954 if (!strcmp(funcName, "vkCmdResetEvent"))
2955 return (void*) vkCmdResetEvent;
2956 if (!strcmp(funcName, "vkCmdWaitEvents"))
2957 return (void*) vkCmdWaitEvents;
2958 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
2959 return (void*) vkCmdPipelineBarrier;
2960 if (!strcmp(funcName, "vkCmdBeginQuery"))
2961 return (void*) vkCmdBeginQuery;
2962 if (!strcmp(funcName, "vkCmdEndQuery"))
2963 return (void*) vkCmdEndQuery;
2964 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2965 return (void*) vkCmdResetQueryPool;
2966 if (!strcmp(funcName, "vkCmdWriteTimestamp"))
2967 return (void*) vkCmdWriteTimestamp;
2968 if (!strcmp(funcName, "vkCmdInitAtomicCounters"))
2969 return (void*) vkCmdInitAtomicCounters;
2970 if (!strcmp(funcName, "vkCmdLoadAtomicCounters"))
2971 return (void*) vkCmdLoadAtomicCounters;
2972 if (!strcmp(funcName, "vkCmdSaveAtomicCounters"))
2973 return (void*) vkCmdSaveAtomicCounters;
2974 if (!strcmp(funcName, "vkCreateFramebuffer"))
2975 return (void*) vkCreateFramebuffer;
2976 if (!strcmp(funcName, "vkCreateRenderPass"))
2977 return (void*) vkCreateRenderPass;
2978 if (!strcmp(funcName, "vkCmdBeginRenderPass"))
2979 return (void*) vkCmdBeginRenderPass;
2980 if (!strcmp(funcName, "vkCmdEndRenderPass"))
2981 return (void*) vkCmdEndRenderPass;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002982 if (!strcmp("drawStateDumpDotFile", funcName))
2983 return (void*) drawStateDumpDotFile;
2984 if (!strcmp("drawStateDumpCommandBufferDotFile", funcName))
2985 return (void*) drawStateDumpCommandBufferDotFile;
2986 if (!strcmp("drawStateDumpPngFile", funcName))
2987 return (void*) drawStateDumpPngFile;
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002988
2989 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) dev;
2990 if (!deviceExtMap[pDisp].debug_marker_enabled)
Jon Ashburn4f2575f2015-05-28 16:25:02 -06002991 {
Jon Ashburn6f8cd632015-06-01 09:37:38 -06002992 if (!strcmp(funcName, "CmdDbgMarkerBegin"))
2993 return (void*) vkCmdDbgMarkerBegin;
2994 if (!strcmp(funcName, "CmdDbgMarkerEnd"))
2995 return (void*) vkCmdDbgMarkerEnd;
2996 if (!strcmp(funcName, "DbgSetObjectTag"))
2997 return (void*) vkDbgSetObjectTag;
2998 if (!strcmp(funcName, "DbgSetObjectName"))
2999 return (void*) vkDbgSetObjectName;
3000 }
3001 {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003002 VkLayerDispatchTable* pTable = get_dispatch_table(draw_state_device_table_map, dev);
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003003 if (pTable->GetDeviceProcAddr == NULL)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003004 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003005 return pTable->GetDeviceProcAddr(dev, funcName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003006 }
3007}
3008
3009VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
3010{
Courtney Goeltzenleuchtercc899fe2015-06-01 14:33:14 -06003011 void *fptr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003012 if (instance == NULL)
3013 return NULL;
3014
Jon Ashburnd9564002015-05-07 10:27:37 -06003015 loader_platform_thread_once(&g_initOnce, initDrawState);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003016
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003017 /* loader uses this to force layer initialization; instance object is wrapped */
3018 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003019 initInstanceTable(draw_state_instance_table_map, (const VkBaseLayerObject *) instance);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003020 return (void *) vkGetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003021 }
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06003022 if (!strcmp(funcName, "vkCreateInstance"))
3023 return (void *) vkCreateInstance;
Jon Ashburne0fa2282015-05-20 09:00:28 -06003024 if (!strcmp(funcName, "vkDestroyInstance"))
3025 return (void *) vkDestroyInstance;
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003026 if (!strcmp(funcName, "vkCreateDevice"))
3027 return (void*) vkCreateDevice;
Courtney Goeltzenleuchtercc899fe2015-06-01 14:33:14 -06003028
3029 fptr = msg_callback_get_proc_addr(funcName);
3030 if (fptr)
3031 return fptr;
3032
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003033 {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003034 VkLayerInstanceDispatchTable* pTable = get_dispatch_table(draw_state_instance_table_map, instance);
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003035 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003036 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003037 return pTable->GetInstanceProcAddr(instance, funcName);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003038 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003039}