blob: c47ad889e33ee2d931e5bd1a3488984f431d780b [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"
43// The following is #included again to catch certain OS-specific functions
44// being used:
45#include "loader_platform.h"
46#include "layers_msg.h"
47
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060048unordered_map<VkSampler, SAMPLER_NODE*> sampleMap;
49unordered_map<VkImageView, IMAGE_NODE*> imageMap;
50unordered_map<VkBufferView, BUFFER_NODE*> bufferMap;
51unordered_map<VkDynamicStateObject, DYNAMIC_STATE_NODE*> dynamicStateMap;
52unordered_map<VkPipeline, PIPELINE_NODE*> pipelineMap;
53unordered_map<VkDescriptorPool, POOL_NODE*> poolMap;
54unordered_map<VkDescriptorSet, SET_NODE*> setMap;
55unordered_map<VkDescriptorSetLayout, LAYOUT_NODE*> layoutMap;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -060056// Map for layout chains
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060057unordered_map<VkCmdBuffer, GLOBAL_CB_NODE*> cmdBufferMap;
58unordered_map<VkRenderPass, VkRenderPassCreateInfo*> renderPassMap;
59unordered_map<VkFramebuffer, VkFramebufferCreateInfo*> frameBufferMap;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060060
Jon Ashburn301c5f02015-04-06 10:58:22 -060061static VkLayerDispatchTable nextTable;
62static VkBaseLayerObject *pCurObj;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060063static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
64// TODO : This can be much smarter, using separate locks for separate global data
65static int globalLockInitialized = 0;
66static loader_platform_thread_mutex globalLock;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060067#define MAX_TID 513
68static loader_platform_thread_id g_tidMapping[MAX_TID] = {0};
69static uint32_t g_maxTID = 0;
70// Map actual TID to an index value and return that index
71// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs
72static uint32_t getTIDIndex() {
73 loader_platform_thread_id tid = loader_platform_get_thread_id();
74 for (uint32_t i = 0; i < g_maxTID; i++) {
75 if (tid == g_tidMapping[i])
76 return i;
77 }
78 // Don't yet have mapping, set it and return newly set index
79 uint32_t retVal = (uint32_t) g_maxTID;
80 g_tidMapping[g_maxTID++] = tid;
81 assert(g_maxTID < MAX_TID);
82 return retVal;
83}
84// Return a string representation of CMD_TYPE enum
85static string cmdTypeToString(CMD_TYPE cmd)
86{
87 switch (cmd)
88 {
89 case CMD_BINDPIPELINE:
90 return "CMD_BINDPIPELINE";
91 case CMD_BINDPIPELINEDELTA:
92 return "CMD_BINDPIPELINEDELTA";
93 case CMD_BINDDYNAMICSTATEOBJECT:
94 return "CMD_BINDDYNAMICSTATEOBJECT";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -060095 case CMD_BINDDESCRIPTORSETS:
96 return "CMD_BINDDESCRIPTORSETS";
Tobin Ehlis63bb9482015-03-17 16:24:32 -060097 case CMD_BINDINDEXBUFFER:
98 return "CMD_BINDINDEXBUFFER";
99 case CMD_BINDVERTEXBUFFER:
100 return "CMD_BINDVERTEXBUFFER";
101 case CMD_DRAW:
102 return "CMD_DRAW";
103 case CMD_DRAWINDEXED:
104 return "CMD_DRAWINDEXED";
105 case CMD_DRAWINDIRECT:
106 return "CMD_DRAWINDIRECT";
107 case CMD_DRAWINDEXEDINDIRECT:
108 return "CMD_DRAWINDEXEDINDIRECT";
109 case CMD_DISPATCH:
110 return "CMD_DISPATCH";
111 case CMD_DISPATCHINDIRECT:
112 return "CMD_DISPATCHINDIRECT";
113 case CMD_COPYBUFFER:
114 return "CMD_COPYBUFFER";
115 case CMD_COPYIMAGE:
116 return "CMD_COPYIMAGE";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600117 case CMD_BLITIMAGE:
118 return "CMD_BLITIMAGE";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600119 case CMD_COPYBUFFERTOIMAGE:
120 return "CMD_COPYBUFFERTOIMAGE";
121 case CMD_COPYIMAGETOBUFFER:
122 return "CMD_COPYIMAGETOBUFFER";
123 case CMD_CLONEIMAGEDATA:
124 return "CMD_CLONEIMAGEDATA";
125 case CMD_UPDATEBUFFER:
126 return "CMD_UPDATEBUFFER";
127 case CMD_FILLBUFFER:
128 return "CMD_FILLBUFFER";
129 case CMD_CLEARCOLORIMAGE:
130 return "CMD_CLEARCOLORIMAGE";
131 case CMD_CLEARCOLORIMAGERAW:
132 return "CMD_CLEARCOLORIMAGERAW";
133 case CMD_CLEARDEPTHSTENCIL:
134 return "CMD_CLEARDEPTHSTENCIL";
135 case CMD_RESOLVEIMAGE:
136 return "CMD_RESOLVEIMAGE";
137 case CMD_SETEVENT:
138 return "CMD_SETEVENT";
139 case CMD_RESETEVENT:
140 return "CMD_RESETEVENT";
141 case CMD_WAITEVENTS:
142 return "CMD_WAITEVENTS";
143 case CMD_PIPELINEBARRIER:
144 return "CMD_PIPELINEBARRIER";
145 case CMD_BEGINQUERY:
146 return "CMD_BEGINQUERY";
147 case CMD_ENDQUERY:
148 return "CMD_ENDQUERY";
149 case CMD_RESETQUERYPOOL:
150 return "CMD_RESETQUERYPOOL";
151 case CMD_WRITETIMESTAMP:
152 return "CMD_WRITETIMESTAMP";
153 case CMD_INITATOMICCOUNTERS:
154 return "CMD_INITATOMICCOUNTERS";
155 case CMD_LOADATOMICCOUNTERS:
156 return "CMD_LOADATOMICCOUNTERS";
157 case CMD_SAVEATOMICCOUNTERS:
158 return "CMD_SAVEATOMICCOUNTERS";
159 case CMD_BEGINRENDERPASS:
160 return "CMD_BEGINRENDERPASS";
161 case CMD_ENDRENDERPASS:
162 return "CMD_ENDRENDERPASS";
163 case CMD_DBGMARKERBEGIN:
164 return "CMD_DBGMARKERBEGIN";
165 case CMD_DBGMARKEREND:
166 return "CMD_DBGMARKEREND";
167 default:
168 return "UNKNOWN";
169 }
170}
171// Block of code at start here for managing/tracking Pipeline state that this layer cares about
172// Just track 2 shaders for now
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600173#define VK_NUM_GRAPHICS_SHADERS VK_SHADER_STAGE_COMPUTE
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600174#define MAX_SLOTS 2048
175#define NUM_COMMAND_BUFFERS_TO_DISPLAY 10
176
177static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0};
178
179// TODO : Should be tracking lastBound per cmdBuffer and when draws occur, report based on that cmd buffer lastBound
180// Then need to synchronize the accesses based on cmd buffer so that if I'm reading state on one cmd buffer, updates
181// to that same cmd buffer by separate thread are not changing state from underneath us
182// Track the last cmd buffer touched by this thread
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600183static VkCmdBuffer g_lastCmdBuffer[MAX_TID] = {NULL};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600184// Track the last group of CBs touched for displaying to dot file
185static GLOBAL_CB_NODE* g_pLastTouchedCB[NUM_COMMAND_BUFFERS_TO_DISPLAY] = {NULL};
186static uint32_t g_lastTouchedCBIndex = 0;
187// Track the last global DrawState of interest touched by any thread
188static GLOBAL_CB_NODE* g_lastGlobalCB = NULL;
189static PIPELINE_NODE* g_lastBoundPipeline = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600190static DYNAMIC_STATE_NODE* g_lastBoundDynamicState[VK_NUM_STATE_BIND_POINT] = {NULL};
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600191static VkDescriptorSet g_lastBoundDescriptorSet = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600192#define MAX_BINDING 0xFFFFFFFF // Default vtxBinding value in CB Node to identify if no vtxBinding set
193
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600194//static DYNAMIC_STATE_NODE* g_pDynamicStateHead[VK_NUM_STATE_BIND_POINT] = {0};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600195
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600196static void insertDynamicState(const VkDynamicStateObject state, const GENERIC_HEADER* pCreateInfo, VkStateBindPoint bindPoint)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600197{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600198 VkDynamicVpStateCreateInfo* pVPCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600199 size_t scSize = 0;
200 size_t vpSize = 0;
201 loader_platform_thread_lock_mutex(&globalLock);
202 DYNAMIC_STATE_NODE* pStateNode = new DYNAMIC_STATE_NODE;
203 pStateNode->stateObj = state;
204 switch (pCreateInfo->sType) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600205 case VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600206 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicVpStateCreateInfo));
207 pVPCI = (VkDynamicVpStateCreateInfo*)pCreateInfo;
208 pStateNode->create_info.vpci.pScissors = new VkRect[pStateNode->create_info.vpci.viewportAndScissorCount];
209 pStateNode->create_info.vpci.pViewports = new VkViewport[pStateNode->create_info.vpci.viewportAndScissorCount];
210 scSize = pVPCI->viewportAndScissorCount * sizeof(VkRect);
211 vpSize = pVPCI->viewportAndScissorCount * sizeof(VkViewport);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600212 memcpy((void*)pStateNode->create_info.vpci.pScissors, pVPCI->pScissors, scSize);
213 memcpy((void*)pStateNode->create_info.vpci.pViewports, pVPCI->pViewports, vpSize);
214 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600215 case VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600216 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicRsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600217 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600218 case VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600219 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicCbStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600220 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600221 case VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600222 memcpy(&pStateNode->create_info, pCreateInfo, sizeof(VkDynamicDsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600223 break;
224 default:
225 assert(0);
226 break;
227 }
228 pStateNode->pCreateInfo = (GENERIC_HEADER*)&pStateNode->create_info.cbci;
229 dynamicStateMap[state] = pStateNode;
230 loader_platform_thread_unlock_mutex(&globalLock);
231}
232// Free all allocated nodes for Dynamic State objs
Tobin Ehliseaf28662015-04-08 10:58:37 -0600233static void deleteDynamicState()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600234{
David Pinedof5997ab2015-04-27 16:36:17 -0600235 if (dynamicStateMap.size() <= 0)
236 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600237 for (unordered_map<VkDynamicStateObject, DYNAMIC_STATE_NODE*>::iterator ii=dynamicStateMap.begin(); ii!=dynamicStateMap.end(); ++ii) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600238 if (VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO == (*ii).second->create_info.vpci.sType) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600239 delete[] (*ii).second->create_info.vpci.pScissors;
240 delete[] (*ii).second->create_info.vpci.pViewports;
241 }
242 delete (*ii).second;
243 }
244}
245// Free all sampler nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600246static void deleteSamplers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600247{
David Pinedof5997ab2015-04-27 16:36:17 -0600248 if (sampleMap.size() <= 0)
249 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600250 for (unordered_map<VkSampler, SAMPLER_NODE*>::iterator ii=sampleMap.begin(); ii!=sampleMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600251 delete (*ii).second;
252 }
253}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600254static VkImageViewCreateInfo* getImageViewCreateInfo(VkImageView view)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600255{
256 loader_platform_thread_lock_mutex(&globalLock);
257 if (imageMap.find(view) == imageMap.end()) {
258 loader_platform_thread_unlock_mutex(&globalLock);
259 return NULL;
260 }
261 else {
262 loader_platform_thread_unlock_mutex(&globalLock);
263 return &imageMap[view]->createInfo;
264 }
265}
266// Free all image nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600267static void deleteImages()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600268{
David Pinedof5997ab2015-04-27 16:36:17 -0600269 if (imageMap.size() <= 0)
270 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600271 for (unordered_map<VkImageView, IMAGE_NODE*>::iterator ii=imageMap.begin(); ii!=imageMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600272 delete (*ii).second;
273 }
274}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600275static VkBufferViewCreateInfo* getBufferViewCreateInfo(VkBufferView view)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600276{
277 loader_platform_thread_lock_mutex(&globalLock);
278 if (bufferMap.find(view) == bufferMap.end()) {
279 loader_platform_thread_unlock_mutex(&globalLock);
280 return NULL;
281 }
282 else {
283 loader_platform_thread_unlock_mutex(&globalLock);
284 return &bufferMap[view]->createInfo;
285 }
286}
287// Free all buffer nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600288static void deleteBuffers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600289{
David Pinedof5997ab2015-04-27 16:36:17 -0600290 if (bufferMap.size() <= 0)
291 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600292 for (unordered_map<VkBufferView, BUFFER_NODE*>::iterator ii=bufferMap.begin(); ii!=bufferMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600293 delete (*ii).second;
294 }
295}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600296static GLOBAL_CB_NODE* getCBNode(VkCmdBuffer cb);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600297
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600298static void updateCBTracking(VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600299{
300 g_lastCmdBuffer[getTIDIndex()] = cb;
301 GLOBAL_CB_NODE* pCB = getCBNode(cb);
302 loader_platform_thread_lock_mutex(&globalLock);
303 g_lastGlobalCB = pCB;
304 // TODO : This is a dumb algorithm. Need smart LRU that drops off oldest
305 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
306 if (g_pLastTouchedCB[i] == pCB) {
307 loader_platform_thread_unlock_mutex(&globalLock);
308 return;
309 }
310 }
311 g_pLastTouchedCB[g_lastTouchedCBIndex++] = pCB;
312 g_lastTouchedCBIndex = g_lastTouchedCBIndex % NUM_COMMAND_BUFFERS_TO_DISPLAY;
313 loader_platform_thread_unlock_mutex(&globalLock);
314}
Tobin Ehlis97866202015-06-10 12:57:07 -0600315// Check object status for selected flag state
316static bool32_t validate_status(VkCmdBuffer cb, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VK_DBG_MSG_TYPE error_level, DRAW_STATE_ERROR error_code, const char* fail_msg) {
317 if (cmdBufferMap.find(cb) != cmdBufferMap.end()) {
318 GLOBAL_CB_NODE* pNode = cmdBufferMap[cb];
319 // If non-zero enable mask is present, check it against status but if enable_mask
320 // is 0 then no enable required so we should always just check status
321 if ((!enable_mask) || (enable_mask & pNode->status)) {
322 if ((pNode->status & status_mask) != status_flag) {
323 char str[1024];
324 sprintf(str, "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(cb), fail_msg);
325 layerCbMsg(error_level, VK_VALIDATION_LEVEL_0, cb, 0, error_code, "DS", str);
326 return VK_FALSE;
327 }
328 }
329 return VK_TRUE;
330 }
331 else {
332 // If we do not find it print an error
333 char str[1024];
334 sprintf(str, "Unable to obtain status for non-existent CB object 0x%" PRIxLEAST64, reinterpret_cast<VkUintPtrLeast64>(cb));
335 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
336 return VK_FALSE;
337 }
338}
339static bool32_t validate_draw_state_flags(VkCmdBuffer cb) {
340 bool32_t result1, result2, result3, result4;
341 result1 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_MSG_ERROR, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
342 result2 = validate_status(cb, CBSTATUS_NONE, CBSTATUS_RASTER_BOUND, CBSTATUS_RASTER_BOUND, VK_DBG_MSG_ERROR, DRAWSTATE_RASTER_NOT_BOUND, "Raster object not bound to this command buffer");
343 result3 = validate_status(cb, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND, CBSTATUS_COLOR_BLEND_BOUND, VK_DBG_MSG_ERROR, DRAWSTATE_COLOR_BLEND_NOT_BOUND, "Color-blend object not bound to this command buffer");
344 result4 = validate_status(cb, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_MSG_ERROR, DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
345 return ((result1 == VK_TRUE) && (result2 == VK_TRUE) && (result3 == VK_TRUE) && (result4 == VK_TRUE));
346}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600347// Print the last bound dynamic state
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600348static void printDynamicState(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600349{
350 GLOBAL_CB_NODE* pCB = getCBNode(cb);
351 if (pCB) {
352 loader_platform_thread_lock_mutex(&globalLock);
353 char str[4*1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600354 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600355 if (pCB->lastBoundDynamicState[i]) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600356 sprintf(str, "Reporting CreateInfo for currently bound %s object %p", string_VkStateBindPoint((VkStateBindPoint)i), pCB->lastBoundDynamicState[i]->stateObj);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600357 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", str);
358 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pCB->lastBoundDynamicState[i]->stateObj, 0, DRAWSTATE_NONE, "DS", dynamic_display(pCB->lastBoundDynamicState[i]->pCreateInfo, " ").c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600359 break;
360 }
361 else {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600362 sprintf(str, "No dynamic state of type %s bound", string_VkStateBindPoint((VkStateBindPoint)i));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600363 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600364 }
365 }
366 loader_platform_thread_unlock_mutex(&globalLock);
367 }
368 else {
369 char str[1024];
370 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600371 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600372 }
373}
374// Retrieve pipeline node ptr for given pipeline object
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600375static PIPELINE_NODE* getPipeline(VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600376{
377 loader_platform_thread_lock_mutex(&globalLock);
378 if (pipelineMap.find(pipeline) == pipelineMap.end()) {
379 loader_platform_thread_unlock_mutex(&globalLock);
380 return NULL;
381 }
382 loader_platform_thread_unlock_mutex(&globalLock);
383 return pipelineMap[pipeline];
384}
385
386// For given sampler, return a ptr to its Create Info struct, or NULL if sampler not found
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600387static VkSamplerCreateInfo* getSamplerCreateInfo(const VkSampler sampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600388{
389 loader_platform_thread_lock_mutex(&globalLock);
390 if (sampleMap.find(sampler) == sampleMap.end()) {
391 loader_platform_thread_unlock_mutex(&globalLock);
392 return NULL;
393 }
394 loader_platform_thread_unlock_mutex(&globalLock);
395 return &sampleMap[sampler]->createInfo;
396}
397
398// Init the pipeline mapping info based on pipeline create info LL tree
399// Threading note : Calls to this function should wrapped in mutex
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600400static void initPipeline(PIPELINE_NODE* pPipeline, const VkGraphicsPipelineCreateInfo* pCreateInfo)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600401{
402 // First init create info, we'll shadow the structs as we go down the tree
Tobin Ehlis2464b882015-04-01 08:40:34 -0600403 // TODO : Validate that no create info is incorrectly replicated
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600404 memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600405 GENERIC_HEADER* pTrav = (GENERIC_HEADER*)pCreateInfo->pNext;
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600406 GENERIC_HEADER* pPrev = (GENERIC_HEADER*)&pPipeline->graphicsPipelineCI; // Hold prev ptr to tie chain of structs together
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600407 size_t bufferSize = 0;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600408 VkPipelineVertexInputCreateInfo* pVICI = NULL;
409 VkPipelineCbStateCreateInfo* pCBCI = NULL;
410 VkPipelineShaderStageCreateInfo* pTmpPSSCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600411 while (pTrav) {
412 switch (pTrav->sType) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600413 case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600414 pTmpPSSCI = (VkPipelineShaderStageCreateInfo*)pTrav;
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600415 switch (pTmpPSSCI->shader.stage) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600416 case VK_SHADER_STAGE_VERTEX:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600417 pPrev->pNext = &pPipeline->vsCI;
418 pPrev = (GENERIC_HEADER*)&pPipeline->vsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600419 memcpy(&pPipeline->vsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600420 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600421 case VK_SHADER_STAGE_TESS_CONTROL:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600422 pPrev->pNext = &pPipeline->tcsCI;
423 pPrev = (GENERIC_HEADER*)&pPipeline->tcsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600424 memcpy(&pPipeline->tcsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600425 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600426 case VK_SHADER_STAGE_TESS_EVALUATION:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600427 pPrev->pNext = &pPipeline->tesCI;
428 pPrev = (GENERIC_HEADER*)&pPipeline->tesCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600429 memcpy(&pPipeline->tesCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600430 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600431 case VK_SHADER_STAGE_GEOMETRY:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600432 pPrev->pNext = &pPipeline->gsCI;
433 pPrev = (GENERIC_HEADER*)&pPipeline->gsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600434 memcpy(&pPipeline->gsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600435 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600436 case VK_SHADER_STAGE_FRAGMENT:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600437 pPrev->pNext = &pPipeline->fsCI;
438 pPrev = (GENERIC_HEADER*)&pPipeline->fsCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600439 memcpy(&pPipeline->fsCI, pTmpPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600440 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600441 case VK_SHADER_STAGE_COMPUTE:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600442 // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600443 break;
444 default:
445 // TODO : Flag error
446 break;
447 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600448 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600449 case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600450 pPrev->pNext = &pPipeline->vertexInputCI;
451 pPrev = (GENERIC_HEADER*)&pPipeline->vertexInputCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600452 memcpy((void*)&pPipeline->vertexInputCI, pTrav, sizeof(VkPipelineVertexInputCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600453 // Copy embedded ptrs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600454 pVICI = (VkPipelineVertexInputCreateInfo*)pTrav;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600455 pPipeline->vtxBindingCount = pVICI->bindingCount;
456 if (pPipeline->vtxBindingCount) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600457 pPipeline->pVertexBindingDescriptions = new VkVertexInputBindingDescription[pPipeline->vtxBindingCount];
458 bufferSize = pPipeline->vtxBindingCount * sizeof(VkVertexInputBindingDescription);
Tobin Ehlis9a70e5d2015-06-09 10:48:55 -0600459 memcpy((void*)pPipeline->pVertexBindingDescriptions, ((VkPipelineVertexInputCreateInfo*)pTrav)->pVertexBindingDescriptions, bufferSize);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600460 }
461 pPipeline->vtxAttributeCount = pVICI->attributeCount;
462 if (pPipeline->vtxAttributeCount) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600463 pPipeline->pVertexAttributeDescriptions = new VkVertexInputAttributeDescription[pPipeline->vtxAttributeCount];
464 bufferSize = pPipeline->vtxAttributeCount * sizeof(VkVertexInputAttributeDescription);
465 memcpy((void*)pPipeline->pVertexAttributeDescriptions, ((VkPipelineVertexInputCreateInfo*)pTrav)->pVertexAttributeDescriptions, bufferSize);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600466 }
467 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600468 case VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600469 pPrev->pNext = &pPipeline->iaStateCI;
470 pPrev = (GENERIC_HEADER*)&pPipeline->iaStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600471 memcpy((void*)&pPipeline->iaStateCI, pTrav, sizeof(VkPipelineIaStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600472 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600473 case VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600474 pPrev->pNext = &pPipeline->tessStateCI;
475 pPrev = (GENERIC_HEADER*)&pPipeline->tessStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600476 memcpy((void*)&pPipeline->tessStateCI, pTrav, sizeof(VkPipelineTessStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600477 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600478 case VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600479 pPrev->pNext = &pPipeline->vpStateCI;
480 pPrev = (GENERIC_HEADER*)&pPipeline->vpStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600481 memcpy((void*)&pPipeline->vpStateCI, pTrav, sizeof(VkPipelineVpStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600482 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600483 case VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600484 pPrev->pNext = &pPipeline->rsStateCI;
485 pPrev = (GENERIC_HEADER*)&pPipeline->rsStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600486 memcpy((void*)&pPipeline->rsStateCI, pTrav, sizeof(VkPipelineRsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600487 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600488 case VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600489 pPrev->pNext = &pPipeline->msStateCI;
490 pPrev = (GENERIC_HEADER*)&pPipeline->msStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600491 memcpy((void*)&pPipeline->msStateCI, pTrav, sizeof(VkPipelineMsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600492 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600493 case VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600494 pPrev->pNext = &pPipeline->cbStateCI;
495 pPrev = (GENERIC_HEADER*)&pPipeline->cbStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600496 memcpy((void*)&pPipeline->cbStateCI, pTrav, sizeof(VkPipelineCbStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600497 // Copy embedded ptrs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600498 pCBCI = (VkPipelineCbStateCreateInfo*)pTrav;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600499 pPipeline->attachmentCount = pCBCI->attachmentCount;
500 if (pPipeline->attachmentCount) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600501 pPipeline->pAttachments = new VkPipelineCbAttachmentState[pPipeline->attachmentCount];
502 bufferSize = pPipeline->attachmentCount * sizeof(VkPipelineCbAttachmentState);
503 memcpy((void*)pPipeline->pAttachments, ((VkPipelineCbStateCreateInfo*)pTrav)->pAttachments, bufferSize);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600504 }
505 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600506 case VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600507 pPrev->pNext = &pPipeline->dsStateCI;
508 pPrev = (GENERIC_HEADER*)&pPipeline->dsStateCI;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600509 memcpy((void*)&pPipeline->dsStateCI, pTrav, sizeof(VkPipelineDsStateCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600510 break;
511 default:
512 assert(0);
513 break;
514 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600515 pTrav = (GENERIC_HEADER*)pTrav->pNext;
516 }
517 pipelineMap[pPipeline->pipeline] = pPipeline;
518}
519// Free the Pipeline nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600520static void deletePipelines()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600521{
David Pinedof5997ab2015-04-27 16:36:17 -0600522 if (pipelineMap.size() <= 0)
523 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600524 for (unordered_map<VkPipeline, PIPELINE_NODE*>::iterator ii=pipelineMap.begin(); ii!=pipelineMap.end(); ++ii) {
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600525 if ((*ii).second->pVertexBindingDescriptions) {
526 delete[] (*ii).second->pVertexBindingDescriptions;
527 }
528 if ((*ii).second->pVertexAttributeDescriptions) {
529 delete[] (*ii).second->pVertexAttributeDescriptions;
530 }
531 if ((*ii).second->pAttachments) {
532 delete[] (*ii).second->pAttachments;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600533 }
534 delete (*ii).second;
535 }
536}
Tobin Ehlis2464b882015-04-01 08:40:34 -0600537// For given pipeline, return number of MSAA samples, or one if MSAA disabled
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600538static uint32_t getNumSamples(const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600539{
540 PIPELINE_NODE* pPipe = pipelineMap[pipeline];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600541 if (VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO == pPipe->msStateCI.sType) {
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600542 if (pPipe->msStateCI.multisampleEnable)
543 return pPipe->msStateCI.samples;
Tobin Ehlis2464b882015-04-01 08:40:34 -0600544 }
545 return 1;
546}
547// Validate state related to the PSO
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600548static void validatePipelineState(const GLOBAL_CB_NODE* pCB, const VkPipelineBindPoint pipelineBindPoint, const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600549{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600550 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
Tobin Ehlis2464b882015-04-01 08:40:34 -0600551 // Verify that any MSAA request in PSO matches sample# in bound FB
552 uint32_t psoNumSamples = getNumSamples(pipeline);
553 if (pCB->activeRenderPass) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600554 VkRenderPassCreateInfo* pRPCI = renderPassMap[pCB->activeRenderPass];
555 VkFramebufferCreateInfo* pFBCI = frameBufferMap[pCB->framebuffer];
Tobin Ehlis63826ec2015-05-21 09:06:56 -0600556 if ((psoNumSamples != pFBCI->sampleCount) || (psoNumSamples != pRPCI->sampleCount)) {
Tobin Ehlis2464b882015-04-01 08:40:34 -0600557 char str[1024];
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600558 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 Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600559 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", str);
Tobin Ehlis2464b882015-04-01 08:40:34 -0600560 }
561 } else {
562 // TODO : I believe it's an error if we reach this point and don't have an activeRenderPass
563 // Verify and flag error as appropriate
564 }
565 // TODO : Add more checks here
566 } else {
567 // TODO : Validate non-gfx pipeline updates
568 }
569}
570
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600571// Block of code at start here specifically for managing/tracking DSs
572
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600573// Return Pool node ptr for specified pool or else NULL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600574static POOL_NODE* getPoolNode(VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600575{
576 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600577 if (poolMap.find(pool) == poolMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600578 loader_platform_thread_unlock_mutex(&globalLock);
579 return NULL;
580 }
581 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600582 return poolMap[pool];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600583}
584// Return Set node ptr for specified set or else NULL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600585static SET_NODE* getSetNode(VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600586{
587 loader_platform_thread_lock_mutex(&globalLock);
588 if (setMap.find(set) == setMap.end()) {
589 loader_platform_thread_unlock_mutex(&globalLock);
590 return NULL;
591 }
592 loader_platform_thread_unlock_mutex(&globalLock);
593 return setMap[set];
594}
595
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600596static LAYOUT_NODE* getLayoutNode(const VkDescriptorSetLayout layout) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600597 loader_platform_thread_lock_mutex(&globalLock);
598 if (layoutMap.find(layout) == layoutMap.end()) {
599 loader_platform_thread_unlock_mutex(&globalLock);
600 return NULL;
601 }
602 loader_platform_thread_unlock_mutex(&globalLock);
603 return layoutMap[layout];
604}
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600605// Return 1 if update struct is of valid type, 0 otherwise
606static bool32_t validUpdateStruct(const GENERIC_HEADER* pUpdateStruct)
607{
608 char str[1024];
609 switch (pUpdateStruct->sType)
610 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800611 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
612 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600613 return 1;
614 default:
615 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
616 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
617 return 0;
618 }
619}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600620// For given update struct, return binding
621static uint32_t getUpdateBinding(const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600622{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600623 char str[1024];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600624 switch (pUpdateStruct->sType)
625 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800626 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
627 return ((VkWriteDescriptorSet*)pUpdateStruct)->destBinding;
628 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
629 return ((VkCopyDescriptorSet*)pUpdateStruct)->destBinding;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600630 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600631 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
632 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
633 return 0xFFFFFFFF;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600634 }
635}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600636// Return count for given update struct
637static uint32_t getUpdateArrayIndex(const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600638{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600639 char str[1024];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600640 switch (pUpdateStruct->sType)
641 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800642 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
643 return ((VkWriteDescriptorSet*)pUpdateStruct)->destArrayElement;
644 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600645 // TODO : Need to understand this case better and make sure code is correct
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800646 return ((VkCopyDescriptorSet*)pUpdateStruct)->destArrayElement;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600647 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600648 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
649 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600650 return 0;
651 }
652}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600653// Return count for given update struct
654static uint32_t getUpdateCount(const GENERIC_HEADER* pUpdateStruct)
655{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600656 char str[1024];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600657 switch (pUpdateStruct->sType)
658 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800659 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
660 return ((VkWriteDescriptorSet*)pUpdateStruct)->count;
661 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600662 // TODO : Need to understand this case better and make sure code is correct
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800663 return ((VkCopyDescriptorSet*)pUpdateStruct)->count;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600664 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600665 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
666 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600667 return 0;
668 }
669}
670// For given Layout Node and binding, return index where that binding begins
671static uint32_t getBindingStartIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
672{
673 uint32_t offsetIndex = 0;
674 for (uint32_t i = 0; i<binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800675 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600676 }
677 return offsetIndex;
678}
679// For given layout node and binding, return last index that is updated
680static uint32_t getBindingEndIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
681{
682 uint32_t offsetIndex = 0;
683 for (uint32_t i = 0; i<=binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800684 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600685 }
686 return offsetIndex-1;
687}
688// For given layout and update, return the first overall index of the layout that is update
689static uint32_t getUpdateStartIndex(const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
690{
691 return (getBindingStartIndex(pLayout, getUpdateBinding(pUpdateStruct))+getUpdateArrayIndex(pUpdateStruct));
692}
693// For given layout and update, return the last overall index of the layout that is update
694static uint32_t getUpdateEndIndex(const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
695{
696 return (getBindingStartIndex(pLayout, getUpdateBinding(pUpdateStruct))+getUpdateArrayIndex(pUpdateStruct)+getUpdateCount(pUpdateStruct)-1);
697}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600698// Verify that the descriptor type in the update struct matches what's expected by the layout
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600699static bool32_t validateUpdateType(const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600700{
701 // First get actual type of update
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600702 VkDescriptorType actualType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600703 uint32_t i = 0;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600704 char str[1024];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600705 switch (pUpdateStruct->sType)
706 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800707 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
708 actualType = ((VkWriteDescriptorSet*)pUpdateStruct)->descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600709 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800710 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
711 /* no need to validate */
712 return 1;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600713 break;
714 default:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600715 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
716 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600717 return 0;
718 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600719 for (i = getUpdateStartIndex(pLayout, pUpdateStruct); i <= getUpdateEndIndex(pLayout, pUpdateStruct); i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600720 if (pLayout->pTypes[i] != actualType)
721 return 0;
722 }
723 return 1;
724}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600725// Determine the update type, allocate a new struct of that type, shadow the given pUpdate
726// struct into the new struct and return ptr to shadow struct cast as GENERIC_HEADER
727// NOTE : Calls to this function should be wrapped in mutex
728static GENERIC_HEADER* shadowUpdateNode(GENERIC_HEADER* pUpdate)
729{
730 GENERIC_HEADER* pNewNode = NULL;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800731 VkWriteDescriptorSet* pWDS = NULL;
732 VkCopyDescriptorSet* pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600733 size_t array_size = 0;
734 size_t base_array_size = 0;
735 size_t total_array_size = 0;
736 size_t baseBuffAddr = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600737 char str[1024];
738 switch (pUpdate->sType)
739 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800740 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
741 pWDS = new VkWriteDescriptorSet;
742 pNewNode = (GENERIC_HEADER*)pWDS;
743 memcpy(pWDS, pUpdate, sizeof(VkWriteDescriptorSet));
744 pWDS->pDescriptors = new VkDescriptorInfo[pWDS->count];
745 array_size = sizeof(VkDescriptorInfo) * pWDS->count;
746 memcpy((void*)pWDS->pDescriptors, ((VkWriteDescriptorSet*)pUpdate)->pDescriptors, array_size);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600747 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800748 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
749 pCDS = new VkCopyDescriptorSet;
750 pUpdate = (GENERIC_HEADER*)pCDS;
751 memcpy(pCDS, pUpdate, sizeof(VkCopyDescriptorSet));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600752 break;
753 default:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600754 sprintf(str, "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdate->sType), pUpdate->sType);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600755 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600756 return NULL;
757 }
758 // Make sure that pNext for the end of shadow copy is NULL
759 pNewNode->pNext = NULL;
760 return pNewNode;
761}
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800762// update DS mappings based on ppUpdateArray
763static bool32_t dsUpdate(VkStructureType type, uint32_t updateCount, const void* pUpdateArray)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600764{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800765 const VkWriteDescriptorSet *pWDS = NULL;
766 const VkCopyDescriptorSet *pCDS = NULL;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600767 bool32_t result = 1;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800768
769 if (type == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
770 pWDS = (const VkWriteDescriptorSet *) pUpdateArray;
771 else
772 pCDS = (const VkCopyDescriptorSet *) pUpdateArray;
773
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600774 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600775 LAYOUT_NODE* pLayout = NULL;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600776 VkDescriptorSetLayoutCreateInfo* pLayoutCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600777 // TODO : If pCIList is NULL, flag error
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600778 // Perform all updates
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600779 for (uint32_t i = 0; i < updateCount; i++) {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800780 VkDescriptorSet ds = (pWDS) ? pWDS->destSet : pCDS->destSet;
781 SET_NODE* pSet = setMap[ds]; // getSetNode() without locking
782 g_lastBoundDescriptorSet = pSet->set;
783 GENERIC_HEADER* pUpdate = (pWDS) ? (GENERIC_HEADER*) &pWDS[i] : (GENERIC_HEADER*) &pCDS[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600784 pLayout = pSet->pLayout;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600785 // First verify valid update struct
786 if (!validUpdateStruct(pUpdate)) {
787 result = 0;
788 break;
789 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600790 // Make sure that binding is within bounds
791 if (pLayout->createInfo.count < getUpdateBinding(pUpdate)) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600792 char str[1024];
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600793 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 Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600794 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600795 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600796 }
797 else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600798 // Next verify that update falls within size of given binding
799 if (getBindingEndIndex(pLayout, getUpdateBinding(pUpdate)) < getUpdateEndIndex(pLayout, pUpdate)) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600800 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 -0600801 pLayoutCI = &pLayout->createInfo;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600802 string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo(pLayoutCI, "{DS} ");
803 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 Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600804 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600805 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600806 }
807 else { // TODO : should we skip update on a type mismatch or force it?
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600808 // Layout bindings match w/ update ok, now verify that update is of the right type
809 if (!validateUpdateType(pLayout, pUpdate)) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600810 char str[1024];
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600811 sprintf(str, "Descriptor update type of %s does not match overlapping binding type!", string_VkStructureType(pUpdate->sType));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600812 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600813 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600814 }
815 else {
816 // Save the update info
817 // TODO : Info message that update successful
818 // Create new update struct for this set's shadow copy
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600819 GENERIC_HEADER* pNewNode = shadowUpdateNode(pUpdate);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600820 if (NULL == pNewNode) {
821 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600822 sprintf(str, "Out of memory while attempting to allocate UPDATE struct in vkUpdateDescriptors()");
823 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, ds, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600824 result = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600825 }
826 else {
827 // Insert shadow node into LL of updates for this set
828 pNewNode->pNext = pSet->pUpdateStructs;
829 pSet->pUpdateStructs = pNewNode;
830 // Now update appropriate descriptor(s) to point to new Update node
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600831 for (uint32_t j = getUpdateStartIndex(pLayout, pUpdate); j <= getUpdateEndIndex(pLayout, pUpdate); j++) {
832 assert(j<pSet->descriptorCount);
833 pSet->ppDescriptors[j] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600834 }
835 }
836 }
837 }
838 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600839 }
840 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600841 return result;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600842}
843// Free the shadowed update node for this Set
844// NOTE : Calls to this function should be wrapped in mutex
845static void freeShadowUpdateTree(SET_NODE* pSet)
846{
847 GENERIC_HEADER* pShadowUpdate = pSet->pUpdateStructs;
848 pSet->pUpdateStructs = NULL;
849 GENERIC_HEADER* pFreeUpdate = pShadowUpdate;
850 // Clear the descriptor mappings as they will now be invalid
851 memset(pSet->ppDescriptors, 0, pSet->descriptorCount*sizeof(GENERIC_HEADER*));
852 while(pShadowUpdate) {
853 pFreeUpdate = pShadowUpdate;
854 pShadowUpdate = (GENERIC_HEADER*)pShadowUpdate->pNext;
855 uint32_t index = 0;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800856 VkWriteDescriptorSet * pWDS = NULL;
857 VkCopyDescriptorSet * pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600858 void** ppToFree = NULL;
859 switch (pFreeUpdate->sType)
860 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800861 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
862 pWDS = (VkWriteDescriptorSet*)pFreeUpdate;
863 if (pWDS->pDescriptors)
864 delete[] pWDS->pDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600865 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800866 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600867 break;
868 default:
869 assert(0);
870 break;
871 }
Tobin Ehliseaf28662015-04-08 10:58:37 -0600872 delete pFreeUpdate;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600873 }
874}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600875// Free all DS Pools including their Sets & related sub-structs
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600876// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600877static void deletePools()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600878{
David Pinedof5997ab2015-04-27 16:36:17 -0600879 if (poolMap.size() <= 0)
880 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600881 for (unordered_map<VkDescriptorPool, POOL_NODE*>::iterator ii=poolMap.begin(); ii!=poolMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600882 SET_NODE* pSet = (*ii).second->pSets;
883 SET_NODE* pFreeSet = pSet;
884 while (pSet) {
885 pFreeSet = pSet;
886 pSet = pSet->pNext;
Tobin Ehliseaf28662015-04-08 10:58:37 -0600887 // Freeing layouts handled in deleteLayouts() function
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600888 // Free Update shadow struct tree
889 freeShadowUpdateTree(pFreeSet);
890 if (pFreeSet->ppDescriptors) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200891 delete[] pFreeSet->ppDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600892 }
893 delete pFreeSet;
894 }
895 if ((*ii).second->createInfo.pTypeCount) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200896 delete[] (*ii).second->createInfo.pTypeCount;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600897 }
898 delete (*ii).second;
899 }
900}
Tobin Ehliseaf28662015-04-08 10:58:37 -0600901// WARN : Once deleteLayouts() called, any layout ptrs in Pool/Set data structure will be invalid
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600902// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600903static void deleteLayouts()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600904{
David Pinedof5997ab2015-04-27 16:36:17 -0600905 if (layoutMap.size() <= 0)
906 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600907 for (unordered_map<VkDescriptorSetLayout, LAYOUT_NODE*>::iterator ii=layoutMap.begin(); ii!=layoutMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600908 LAYOUT_NODE* pLayout = (*ii).second;
Tobin Ehliseaf28662015-04-08 10:58:37 -0600909 if (pLayout->createInfo.pBinding) {
910 for (uint32_t i=0; i<pLayout->createInfo.count; i++) {
911 if (pLayout->createInfo.pBinding[i].pImmutableSamplers)
912 delete[] pLayout->createInfo.pBinding[i].pImmutableSamplers;
913 }
914 delete[] pLayout->createInfo.pBinding;
915 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600916 if (pLayout->pTypes) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200917 delete[] pLayout->pTypes;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600918 }
919 delete pLayout;
920 }
921}
922// Currently clearing a set is removing all previous updates to that set
923// TODO : Validate if this is correct clearing behavior
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600924static void clearDescriptorSet(VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600925{
926 SET_NODE* pSet = getSetNode(set);
927 if (!pSet) {
928 // TODO : Return error
929 }
930 else {
931 loader_platform_thread_lock_mutex(&globalLock);
932 freeShadowUpdateTree(pSet);
933 loader_platform_thread_unlock_mutex(&globalLock);
934 }
935}
936
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600937static void clearDescriptorPool(VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600938{
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600939 POOL_NODE* pPool = getPoolNode(pool);
940 if (!pPool) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600941 char str[1024];
Tobin Ehlis28be0be2015-05-22 12:38:16 -0600942 sprintf(str, "Unable to find pool node for pool %p specified in vkResetDescriptorPool() call", (void*)pool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600943 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600944 }
945 else
946 {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600947 // For every set off of this pool, clear it
948 SET_NODE* pSet = pPool->pSets;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600949 while (pSet) {
950 clearDescriptorSet(pSet->set);
951 }
952 }
953}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600954// Code here to manage the Cmd buffer LL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600955static GLOBAL_CB_NODE* getCBNode(VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600956{
957 loader_platform_thread_lock_mutex(&globalLock);
958 if (cmdBufferMap.find(cb) == cmdBufferMap.end()) {
959 loader_platform_thread_unlock_mutex(&globalLock);
960 return NULL;
961 }
962 loader_platform_thread_unlock_mutex(&globalLock);
963 return cmdBufferMap[cb];
964}
965// Free all CB Nodes
966// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600967static void deleteCmdBuffers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600968{
David Pinedof5997ab2015-04-27 16:36:17 -0600969 if (cmdBufferMap.size() <= 0)
970 return;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600971 for (unordered_map<VkCmdBuffer, GLOBAL_CB_NODE*>::iterator ii=cmdBufferMap.begin(); ii!=cmdBufferMap.end(); ++ii) {
Courtney Goeltzenleuchter09098a72015-04-27 15:04:43 -0600972 vector<CMD_NODE*> cmd_node_list = (*ii).second->pCmds;
973 while (!cmd_node_list.empty()) {
974 CMD_NODE* cmd_node = cmd_node_list.back();
975 delete cmd_node;
976 cmd_node_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600977 }
978 delete (*ii).second;
979 }
980}
981static void addCmd(GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
982{
983 CMD_NODE* pCmd = new CMD_NODE;
984 if (pCmd) {
985 // init cmd node and append to end of cmd LL
986 memset(pCmd, 0, sizeof(CMD_NODE));
987 pCmd->cmdNumber = ++pCB->numCmds;
988 pCmd->type = cmd;
989 pCB->pCmds.push_back(pCmd);
990 }
991 else {
992 char str[1024];
993 sprintf(str, "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %p", (void*)pCB->cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600994 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600995 }
996}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600997static void resetCB(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600998{
999 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1000 if (pCB) {
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001001 vector<CMD_NODE*> cmd_list = pCB->pCmds;
1002 while (!cmd_list.empty()) {
1003 delete cmd_list.back();
1004 cmd_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001005 }
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001006 pCB->pCmds.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001007 // Reset CB state
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001008 VkFlags saveFlags = pCB->flags;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001009 uint32_t saveQueueNodeIndex = pCB->queueNodeIndex;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001010 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1011 pCB->cmdBuffer = cb;
1012 pCB->flags = saveFlags;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001013 pCB->queueNodeIndex = saveQueueNodeIndex;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001014 pCB->lastVtxBinding = MAX_BINDING;
1015 }
1016}
Tobin Ehlis97866202015-06-10 12:57:07 -06001017// Set PSO-related status bits for CB
1018static void set_cb_pso_status(GLOBAL_CB_NODE* pCB, const PIPELINE_NODE* pPipe)
1019{
1020 for (uint32_t i = 0; i < pPipe->cbStateCI.attachmentCount; i++) {
1021 if (0 != pPipe->pAttachments[i].channelWriteMask) {
1022 pCB->status |= CBSTATUS_COLOR_BLEND_WRITE_ENABLE;
1023 }
1024 }
1025 if (pPipe->dsStateCI.depthWriteEnable) {
1026 pCB->status |= CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE;
1027 }
1028}
1029// Set dyn-state related status bits for an object node
1030static void set_cb_dyn_status(GLOBAL_CB_NODE* pNode, VkStateBindPoint stateBindPoint) {
1031 if (stateBindPoint == VK_STATE_BIND_POINT_VIEWPORT) {
1032 pNode->status |= CBSTATUS_VIEWPORT_BOUND;
1033 } else if (stateBindPoint == VK_STATE_BIND_POINT_RASTER) {
1034 pNode->status |= CBSTATUS_RASTER_BOUND;
1035 } else if (stateBindPoint == VK_STATE_BIND_POINT_COLOR_BLEND) {
1036 pNode->status |= CBSTATUS_COLOR_BLEND_BOUND;
1037 } else if (stateBindPoint == VK_STATE_BIND_POINT_DEPTH_STENCIL) {
1038 pNode->status |= CBSTATUS_DEPTH_STENCIL_BOUND;
1039 }
1040}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001041// Set the last bound dynamic state of given type
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001042static void setLastBoundDynamicState(const VkCmdBuffer cmdBuffer, const VkDynamicStateObject state, const VkStateBindPoint sType)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001043{
1044 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1045 if (pCB) {
1046 updateCBTracking(cmdBuffer);
1047 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis97866202015-06-10 12:57:07 -06001048 set_cb_dyn_status(pCB, sType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001049 addCmd(pCB, CMD_BINDDYNAMICSTATEOBJECT);
1050 if (dynamicStateMap.find(state) == dynamicStateMap.end()) {
1051 char str[1024];
1052 sprintf(str, "Unable to find dynamic state object %p, was it ever created?", (void*)state);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001053 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, state, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001054 }
1055 else {
1056 pCB->lastBoundDynamicState[sType] = dynamicStateMap[state];
1057 g_lastBoundDynamicState[sType] = dynamicStateMap[state];
1058 }
1059 loader_platform_thread_unlock_mutex(&globalLock);
1060 }
1061 else {
1062 char str[1024];
1063 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001064 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001065 }
1066}
1067// Print the last bound Gfx Pipeline
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001068static void printPipeline(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001069{
1070 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1071 if (pCB) {
1072 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1073 if (!pPipeTrav) {
1074 // nothing to print
1075 }
1076 else {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001077 string pipeStr = vk_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001078 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", pipeStr.c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001079 }
1080 }
1081}
1082// Common Dot dumping code
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001083static void dsCoreDumpDot(const VkDescriptorSet ds, FILE* pOutFile)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001084{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001085#if 0
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001086 SET_NODE* pSet = getSetNode(ds);
1087 if (pSet) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001088 POOL_NODE* pPool = getPoolNode(pSet->pool);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001089 char tmp_str[4*1024];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001090 fprintf(pOutFile, "subgraph cluster_DescriptorPool\n{\nlabel=\"Descriptor Pool\"\n");
1091 sprintf(tmp_str, "Pool (%p)", pPool->pool);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001092 char* pGVstr = vk_gv_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, tmp_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001093 fprintf(pOutFile, "%s", pGVstr);
1094 free(pGVstr);
1095 fprintf(pOutFile, "subgraph cluster_DescriptorSet\n{\nlabel=\"Descriptor Set (%p)\"\n", pSet->set);
1096 sprintf(tmp_str, "Descriptor Set (%p)", pSet->set);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001097 LAYOUT_NODE* pLayout = pSet->pLayout;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001098 uint32_t layout_index = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001099 ++layout_index;
1100 sprintf(tmp_str, "LAYOUT%u", layout_index);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001101 pGVstr = vk_gv_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, tmp_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001102 fprintf(pOutFile, "%s", pGVstr);
1103 free(pGVstr);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001104 if (pSet->pUpdateStructs) {
1105 pGVstr = dynamic_gv_display(pSet->pUpdateStructs, "Descriptor Updates");
1106 fprintf(pOutFile, "%s", pGVstr);
1107 free(pGVstr);
1108 }
1109 if (pSet->ppDescriptors) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001110 fprintf(pOutFile, "\"DESCRIPTORS\" [\nlabel=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\"> <TR><TD COLSPAN=\"2\" PORT=\"desc\">DESCRIPTORS</TD></TR>");
1111 uint32_t i = 0;
1112 for (i=0; i < pSet->descriptorCount; i++) {
1113 if (pSet->ppDescriptors[i]) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001114 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 -06001115 }
1116 }
1117#define NUM_COLORS 7
1118 vector<string> edgeColors;
1119 edgeColors.push_back("0000ff");
1120 edgeColors.push_back("ff00ff");
1121 edgeColors.push_back("ffff00");
1122 edgeColors.push_back("00ff00");
1123 edgeColors.push_back("000000");
1124 edgeColors.push_back("00ffff");
1125 edgeColors.push_back("ff0000");
1126 uint32_t colorIdx = 0;
1127 fprintf(pOutFile, "</TABLE>>\n];\n");
1128 // Now add the views that are mapped to active descriptors
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001129 VkUpdateSamplers* pUS = NULL;
1130 VkUpdateSamplerTextures* pUST = NULL;
1131 VkUpdateImages* pUI = NULL;
1132 VkUpdateBuffers* pUB = NULL;
1133 VkUpdateAsCopy* pUAC = NULL;
1134 VkSamplerCreateInfo* pSCI = NULL;
1135 VkImageViewCreateInfo* pIVCI = NULL;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001136 VkBufferViewCreateInfo* pBVCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001137 void** ppNextPtr = NULL;
1138 void* pSaveNext = NULL;
1139 for (i=0; i < pSet->descriptorCount; i++) {
1140 if (pSet->ppDescriptors[i]) {
1141 switch (pSet->ppDescriptors[i]->sType)
1142 {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001143 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001144 pUS = (VkUpdateSamplers*)pSet->ppDescriptors[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001145 pSCI = getSamplerCreateInfo(pUS->pSamplers[i-pUS->arrayIndex]);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001146 if (pSCI) {
1147 sprintf(tmp_str, "SAMPLER%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001148 fprintf(pOutFile, "%s", vk_gv_print_vksamplercreateinfo(pSCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001149 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1150 }
1151 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001152 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001153 pUST = (VkUpdateSamplerTextures*)pSet->ppDescriptors[i];
Courtney Goeltzenleuchterd38dcc92015-04-09 11:43:10 -06001154 pSCI = getSamplerCreateInfo(pUST->pSamplerImageViews[i-pUST->arrayIndex].sampler);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001155 if (pSCI) {
1156 sprintf(tmp_str, "SAMPLER%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001157 fprintf(pOutFile, "%s", vk_gv_print_vksamplercreateinfo(pSCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001158 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1159 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001160 pIVCI = getImageViewCreateInfo(pUST->pSamplerImageViews[i-pUST->arrayIndex].pImageView->view);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001161 if (pIVCI) {
1162 sprintf(tmp_str, "IMAGE_VIEW%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001163 fprintf(pOutFile, "%s", vk_gv_print_vkimageviewcreateinfo(pIVCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001164 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1165 }
1166 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001167 case VK_STRUCTURE_TYPE_UPDATE_IMAGES:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001168 pUI = (VkUpdateImages*)pSet->ppDescriptors[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001169 pIVCI = getImageViewCreateInfo(pUI->pImageViews[i-pUI->arrayIndex].view);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001170 if (pIVCI) {
1171 sprintf(tmp_str, "IMAGE_VIEW%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001172 fprintf(pOutFile, "%s", vk_gv_print_vkimageviewcreateinfo(pIVCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001173 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1174 }
1175 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001176 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001177 pUB = (VkUpdateBuffers*)pSet->ppDescriptors[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001178 pBVCI = getBufferViewCreateInfo(pUB->pBufferViews[i-pUB->arrayIndex].view);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001179 if (pBVCI) {
1180 sprintf(tmp_str, "BUFFER_VIEW%u", i);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001181 fprintf(pOutFile, "%s", vk_gv_print_vkbufferviewcreateinfo(pBVCI, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001182 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1183 }
1184 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001185 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY:
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001186 pUAC = (VkUpdateAsCopy*)pSet->ppDescriptors[i];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001187 // TODO : Need to validate this code
1188 // Save off pNext and set to NULL while printing this struct, then restore it
1189 ppNextPtr = (void**)&pUAC->pNext;
1190 pSaveNext = *ppNextPtr;
1191 *ppNextPtr = NULL;
1192 sprintf(tmp_str, "UPDATE_AS_COPY%u", i);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001193 fprintf(pOutFile, "%s", vk_gv_print_vkupdateascopy(pUAC, tmp_str));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001194 fprintf(pOutFile, "\"DESCRIPTORS\":slot%u -> \"%s\" [color=\"#%s\"];\n", i, tmp_str, edgeColors[colorIdx].c_str());
1195 // Restore next ptr
1196 *ppNextPtr = pSaveNext;
1197 break;
1198 default:
1199 break;
1200 }
1201 colorIdx = (colorIdx+1) % NUM_COLORS;
1202 }
1203 }
1204 }
1205 fprintf(pOutFile, "}\n");
1206 fprintf(pOutFile, "}\n");
1207 }
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001208#endif
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001209}
1210// Dump subgraph w/ DS info
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001211static void dsDumpDot(const VkCmdBuffer cb, FILE* pOutFile)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001212{
1213 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1214 if (pCB && pCB->lastBoundDescriptorSet) {
1215 dsCoreDumpDot(pCB->lastBoundDescriptorSet, pOutFile);
1216 }
1217}
1218// Dump a GraphViz dot file showing the Cmd Buffers
1219static void cbDumpDotFile(string outFileName)
1220{
1221 // Print CB Chain for each CB
1222 FILE* pOutFile;
1223 pOutFile = fopen(outFileName.c_str(), "w");
1224 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1225 fprintf(pOutFile, "subgraph cluster_cmdBuffers\n{\nlabel=\"Command Buffers\"\n");
1226 GLOBAL_CB_NODE* pCB = NULL;
1227 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
1228 pCB = g_pLastTouchedCB[i];
David Pinedof5997ab2015-04-27 16:36:17 -06001229 if (pCB && pCB->pCmds.size() > 0) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001230 fprintf(pOutFile, "subgraph cluster_cmdBuffer%u\n{\nlabel=\"Command Buffer #%u\"\n", i, i);
1231 uint32_t instNum = 0;
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001232 vector<CMD_NODE*> cmd_list = pCB->pCmds;
1233 for (vector<CMD_NODE*>::iterator ii= cmd_list.begin(); ii!= cmd_list.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001234 if (instNum) {
1235 fprintf(pOutFile, "\"CB%pCMD%u\" -> \"CB%pCMD%u\" [];\n", (void*)pCB->cmdBuffer, instNum-1, (void*)pCB->cmdBuffer, instNum);
1236 }
1237 if (pCB == g_lastGlobalCB) {
1238 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());
1239 }
1240 else {
1241 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());
1242 }
1243 ++instNum;
1244 }
1245 fprintf(pOutFile, "}\n");
1246 }
1247 }
1248 fprintf(pOutFile, "}\n");
1249 fprintf(pOutFile, "}\n"); // close main graph "g"
1250 fclose(pOutFile);
1251}
1252// Dump a GraphViz dot file showing the pipeline for last bound global state
1253static void dumpGlobalDotFile(char *outFileName)
1254{
1255 PIPELINE_NODE *pPipeTrav = g_lastBoundPipeline;
1256 if (pPipeTrav) {
1257 FILE* pOutFile;
1258 pOutFile = fopen(outFileName, "w");
1259 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1260 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
1261 char* pGVstr = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001262 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001263 if (g_lastBoundDynamicState[i] && g_lastBoundDynamicState[i]->pCreateInfo) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001264 pGVstr = dynamic_gv_display(g_lastBoundDynamicState[i]->pCreateInfo, string_VkStateBindPoint((VkStateBindPoint)i));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001265 fprintf(pOutFile, "%s", pGVstr);
1266 free(pGVstr);
1267 }
1268 }
1269 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1270 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001271 pGVstr = vk_gv_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "PSO HEAD");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001272 fprintf(pOutFile, "%s", pGVstr);
1273 free(pGVstr);
1274 fprintf(pOutFile, "}\n");
1275 dsCoreDumpDot(g_lastBoundDescriptorSet, pOutFile);
1276 fprintf(pOutFile, "}\n"); // close main graph "g"
1277 fclose(pOutFile);
1278 }
1279}
1280// Dump a GraphViz dot file showing the pipeline for a given CB
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001281static void dumpDotFile(const VkCmdBuffer cb, string outFileName)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001282{
1283 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1284 if (pCB) {
1285 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1286 if (pPipeTrav) {
1287 FILE* pOutFile;
1288 pOutFile = fopen(outFileName.c_str(), "w");
1289 fprintf(pOutFile, "digraph g {\ngraph [\nrankdir = \"TB\"\n];\nnode [\nfontsize = \"16\"\nshape = \"plaintext\"\n];\nedge [\n];\n");
1290 fprintf(pOutFile, "subgraph cluster_dynamicState\n{\nlabel=\"Dynamic State\"\n");
1291 char* pGVstr = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001292 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001293 if (pCB->lastBoundDynamicState[i] && pCB->lastBoundDynamicState[i]->pCreateInfo) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001294 pGVstr = dynamic_gv_display(pCB->lastBoundDynamicState[i]->pCreateInfo, string_VkStateBindPoint((VkStateBindPoint)i));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001295 fprintf(pOutFile, "%s", pGVstr);
1296 free(pGVstr);
1297 }
1298 }
1299 fprintf(pOutFile, "}\n"); // close dynamicState subgraph
1300 fprintf(pOutFile, "subgraph cluster_PipelineStateObject\n{\nlabel=\"Pipeline State Object\"\n");
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001301 pGVstr = vk_gv_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "PSO HEAD");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001302 fprintf(pOutFile, "%s", pGVstr);
1303 free(pGVstr);
1304 fprintf(pOutFile, "}\n");
1305 dsDumpDot(cb, pOutFile);
1306 fprintf(pOutFile, "}\n"); // close main graph "g"
1307 fclose(pOutFile);
1308 }
1309 }
1310}
Tobin Ehlise90b1712015-05-27 14:30:06 -06001311// Verify bound Pipeline State Object
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001312static bool validateBoundPipeline(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001313{
1314 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1315 if (pCB && pCB->lastBoundPipeline) {
1316 // First verify that we have a Node for bound pipeline
1317 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1318 char str[1024];
1319 if (!pPipeTrav) {
1320 sprintf(str, "Can't find last bound Pipeline %p!", (void*)pCB->lastBoundPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001321 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001322 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001323 }
1324 else {
1325 // Verify Vtx binding
1326 if (MAX_BINDING != pCB->lastVtxBinding) {
1327 if (pCB->lastVtxBinding >= pPipeTrav->vtxBindingCount) {
1328 if (0 == pPipeTrav->vtxBindingCount) {
1329 sprintf(str, "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001330 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001331 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001332 }
1333 else {
1334 sprintf(str, "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001335 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", str);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001336 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001337 }
1338 }
1339 else {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001340 string tmpStr = vk_print_vkvertexinputbindingdescription(&pPipeTrav->pVertexBindingDescriptions[pCB->lastVtxBinding], "{DS}INFO : ").c_str();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001341 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmpStr.c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001342 }
1343 }
1344 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001345 return true;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001346 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001347 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001348}
1349// Print details of DS config to stdout
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001350static void printDSConfig(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001351{
1352 char tmp_str[1024];
1353 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.
1354 GLOBAL_CB_NODE* pCB = getCBNode(cb);
Tobin Ehlis7297f192015-06-09 08:39:32 -06001355 if (pCB && pCB->lastBoundDescriptorSet) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001356 SET_NODE* pSet = getSetNode(pCB->lastBoundDescriptorSet);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001357 POOL_NODE* pPool = getPoolNode(pSet->pool);
1358 // Print out pool details
1359 sprintf(tmp_str, "Details for pool %p.", (void*)pPool->pool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001360 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001361 string poolStr = vk_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, " ");
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001362 sprintf(ds_config_str, "%s", poolStr.c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001363 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001364 // Print out set details
1365 char prefix[10];
1366 uint32_t index = 0;
1367 sprintf(tmp_str, "Details for descriptor set %p.", (void*)pSet->set);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001368 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001369 LAYOUT_NODE* pLayout = pSet->pLayout;
1370 // Print layout details
1371 sprintf(tmp_str, "Layout #%u, (object %p) for DS %p.", index+1, (void*)pLayout->layout, (void*)pSet->set);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001372 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001373 sprintf(prefix, " [L%u] ", index);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001374 string DSLstr = vk_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, prefix).c_str();
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001375 sprintf(ds_config_str, "%s", DSLstr.c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001376 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001377 index++;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001378 GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
1379 if (pUpdate) {
1380 sprintf(tmp_str, "Update Chain [UC] for descriptor set %p:", (void*)pSet->set);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001381 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001382 sprintf(prefix, " [UC] ");
1383 sprintf(ds_config_str, "%s", dynamic_display(pUpdate, prefix).c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001384 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", ds_config_str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001385 // TODO : If there is a "view" associated with this update, print CI for that view
1386 }
1387 else {
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001388 if (0 != pSet->descriptorCount) {
1389 sprintf(tmp_str, "No Update Chain for descriptor set %p which has %u descriptors (vkUpdateDescriptors has not been called)", (void*)pSet->set, pSet->descriptorCount);
1390 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1391 }
1392 else {
1393 sprintf(tmp_str, "FYI: No descriptors in descriptor set %p.", (void*)pSet->set);
1394 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", tmp_str);
1395 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001396 }
1397 }
1398}
1399
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001400static void printCB(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001401{
1402 GLOBAL_CB_NODE* pCB = getCBNode(cb);
David Pinedof5997ab2015-04-27 16:36:17 -06001403 if (pCB && pCB->pCmds.size() > 0) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001404 char str[1024];
1405 sprintf(str, "Cmds in CB %p", (void*)cb);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001406 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_NONE, "DS", str);
Courtney Goeltzenleuchtercf2a5362015-04-27 11:16:35 -06001407 vector<CMD_NODE*> pCmds = pCB->pCmds;
1408 for (vector<CMD_NODE*>::iterator ii=pCmds.begin(); ii!=pCmds.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001409 sprintf(str, " CMD#%lu: %s", (*ii)->cmdNumber, cmdTypeToString((*ii)->type).c_str());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001410 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cb, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001411 }
1412 }
1413 else {
1414 // Nothing to print
1415 }
1416}
1417
1418
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001419static void synchAndPrintDSConfig(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001420{
1421 printDSConfig(cb);
1422 printPipeline(cb);
1423 printDynamicState(cb);
1424 static int autoDumpOnce = 0;
1425 if (autoDumpOnce) {
1426 autoDumpOnce = 0;
1427 dumpDotFile(cb, "pipeline_dump.dot");
1428 cbDumpDotFile("cb_dump.dot");
1429#if defined(_WIN32)
1430// FIXME: NEED WINDOWS EQUIVALENT
1431#else // WIN32
1432 // Convert dot to svg if dot available
1433 if(access( "/usr/bin/dot", X_OK) != -1) {
Tony Barbour22a30862015-04-22 09:02:32 -06001434 int retval = system("/usr/bin/dot pipeline_dump.dot -Tsvg -o pipeline_dump.svg");
1435 assert(retval != -1);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001436 }
1437#endif // WIN32
1438 }
1439}
1440
1441static void initDrawState(void)
1442{
1443 const char *strOpt;
1444 // initialize DrawState options
1445 getLayerOptionEnum("DrawStateReportLevel", (uint32_t *) &g_reportingLevel);
1446 g_actionIsDefault = getLayerOptionEnum("DrawStateDebugAction", (uint32_t *) &g_debugAction);
1447
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001448 if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001449 {
1450 strOpt = getLayerOption("DrawStateLogFilename");
1451 if (strOpt)
1452 {
1453 g_logFile = fopen(strOpt, "w");
1454 }
1455 if (g_logFile == NULL)
1456 g_logFile = stdout;
1457 }
1458 // initialize Layer dispatch table
1459 // TODO handle multiple GPUs
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001460 PFN_vkGetProcAddr fpNextGPA;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001461 fpNextGPA = pCurObj->pGPA;
1462 assert(fpNextGPA);
1463
Tony Barbour8205d902015-04-16 15:59:00 -06001464 layer_initialize_dispatch_table(&nextTable, fpNextGPA, (VkPhysicalDevice) pCurObj->nextObject);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001465
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001466 if (!globalLockInitialized)
1467 {
1468 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001469 // suggestion is to call this during vkCreateInstance(), and then we
1470 // can clean it up during vkDestroyInstance(). However, that requires
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001471 // that the layer have per-instance locks. We need to come back and
1472 // address this soon.
1473 loader_platform_thread_create_mutex(&globalLock);
1474 globalLockInitialized = 1;
1475 }
1476}
1477
Tony Barbour8205d902015-04-16 15:59:00 -06001478VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001479{
Jon Ashburn630e44f2015-04-08 21:33:34 -06001480 pCurObj = (VkBaseLayerObject *) gpu;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001481 loader_platform_thread_once(&g_initOnce, initDrawState);
Jon Ashburn630e44f2015-04-08 21:33:34 -06001482 VkResult result = nextTable.CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001483 return result;
1484}
1485
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001486VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001487{
1488 // Free all the memory
1489 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliseaf28662015-04-08 10:58:37 -06001490 deletePipelines();
1491 deleteSamplers();
1492 deleteImages();
1493 deleteBuffers();
1494 deleteCmdBuffers();
1495 deleteDynamicState();
1496 deletePools();
1497 deleteLayouts();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001498 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001499 VkResult result = nextTable.DestroyDevice(device);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001500 return result;
1501}
1502
Jon Ashburneb2728b2015-04-10 14:33:07 -06001503struct extProps {
1504 uint32_t version;
1505 const char * const name;
1506};
Jon Ashburnbdcd7562015-04-14 14:12:59 -06001507#define DRAW_STATE_LAYER_EXT_ARRAY_SIZE 5
Jon Ashburneb2728b2015-04-10 14:33:07 -06001508static const struct extProps dsExts[DRAW_STATE_LAYER_EXT_ARRAY_SIZE] = {
1509 // TODO what is the version?
Jon Ashburnbdcd7562015-04-14 14:12:59 -06001510 0x10, "DrawState",
1511 0x10, "Validation",
1512 0x10, "drawStateDumpDotFile",
1513 0x10, "drawStateDumpCommandBufferDotFile",
1514 0x10, "drawStateDumpPngFile"
Jon Ashburneb2728b2015-04-10 14:33:07 -06001515};
1516
1517VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionInfo(
1518 VkExtensionInfoType infoType,
1519 uint32_t extensionIndex,
1520 size_t* pDataSize,
1521 void* pData)
1522{
Jon Ashburneb2728b2015-04-10 14:33:07 -06001523 /* This entrypoint is NOT going to init it's own dispatch table since loader calls here early */
1524 VkExtensionProperties *ext_props;
1525 uint32_t *count;
1526
1527 if (pDataSize == NULL)
1528 return VK_ERROR_INVALID_POINTER;
1529
1530 switch (infoType) {
1531 case VK_EXTENSION_INFO_TYPE_COUNT:
1532 *pDataSize = sizeof(uint32_t);
1533 if (pData == NULL)
1534 return VK_SUCCESS;
1535 count = (uint32_t *) pData;
1536 *count = DRAW_STATE_LAYER_EXT_ARRAY_SIZE;
1537 break;
1538 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
1539 *pDataSize = sizeof(VkExtensionProperties);
1540 if (pData == NULL)
1541 return VK_SUCCESS;
1542 if (extensionIndex >= DRAW_STATE_LAYER_EXT_ARRAY_SIZE)
1543 return VK_ERROR_INVALID_VALUE;
1544 ext_props = (VkExtensionProperties *) pData;
1545 ext_props->version = dsExts[extensionIndex].version;
1546 strncpy(ext_props->extName, dsExts[extensionIndex].name,
1547 VK_MAX_EXTENSION_NAME);
1548 ext_props->extName[VK_MAX_EXTENSION_NAME - 1] = '\0';
1549 break;
1550 default:
1551 return VK_ERROR_INVALID_VALUE;
1552 };
1553
1554 return VK_SUCCESS;
1555}
1556
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001557VK_LAYER_EXPORT VkResult VKAPI vkEnumerateLayers(VkPhysicalDevice gpu, size_t maxStringSize, size_t* pLayerCount, char* const* pOutLayers, void* pReserved)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001558{
1559 if (gpu != NULL)
1560 {
Jon Ashburn630e44f2015-04-08 21:33:34 -06001561 pCurObj = (VkBaseLayerObject *) gpu;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001562 loader_platform_thread_once(&g_initOnce, initDrawState);
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001563 VkResult result = nextTable.EnumerateLayers(gpu, maxStringSize, pLayerCount, pOutLayers, pReserved);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001564 return result;
Jon Ashburn630e44f2015-04-08 21:33:34 -06001565 } else {
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001566 if (pLayerCount == NULL || pOutLayers == NULL || pOutLayers[0] == NULL)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001567 return VK_ERROR_INVALID_POINTER;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001568 // This layer compatible with all GPUs
Courtney Goeltzenleuchterbb1f3602015-04-20 11:04:54 -06001569 *pLayerCount = 1;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001570 strncpy((char *) pOutLayers[0], "DrawState", maxStringSize);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001571 return VK_SUCCESS;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001572 }
1573}
1574
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001575VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001576{
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001577 GLOBAL_CB_NODE* pCB = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001578 for (uint32_t i=0; i < cmdBufferCount; i++) {
1579 // Validate that cmd buffers have been updated
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001580 pCB = getCBNode(pCmdBuffers[i]);
1581 loader_platform_thread_lock_mutex(&globalLock);
1582 if (CB_UPDATE_COMPLETE != pCB->state) {
1583 // Flag error for using CB w/o vkEndCommandBuffer() called
1584 char str[1024];
1585 sprintf(str, "You must call vkEndCommandBuffer() on CB %p before this call to vkQueueSubmit()!", pCB->cmdBuffer);
1586 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pCB->cmdBuffer, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS", str);
Tobin Ehlise90b1712015-05-27 14:30:06 -06001587 loader_platform_thread_unlock_mutex(&globalLock);
1588 return VK_ERROR_UNKNOWN;
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001589 }
Tobin Ehlise9b700e2015-05-26 16:06:50 -06001590 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001591 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001592 VkResult result = nextTable.QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001593 return result;
1594}
1595
Mike Stroyan230e6252015-04-17 12:36:38 -06001596VK_LAYER_EXPORT VkResult VKAPI vkDestroyObject(VkDevice device, VkObjectType objType, VkObject object)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001597{
1598 // TODO : When wrapped objects (such as dynamic state) are destroyed, need to clean up memory
Mike Stroyan230e6252015-04-17 12:36:38 -06001599 VkResult result = nextTable.DestroyObject(device, objType, object);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001600 return result;
1601}
1602
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001603VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001604{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001605 VkResult result = nextTable.CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001606 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001607 loader_platform_thread_lock_mutex(&globalLock);
1608 BUFFER_NODE* pNewNode = new BUFFER_NODE;
1609 pNewNode->buffer = *pView;
1610 pNewNode->createInfo = *pCreateInfo;
1611 bufferMap[*pView] = pNewNode;
1612 loader_platform_thread_unlock_mutex(&globalLock);
1613 }
1614 return result;
1615}
1616
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001617VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001618{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001619 VkResult result = nextTable.CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001620 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001621 loader_platform_thread_lock_mutex(&globalLock);
1622 IMAGE_NODE *pNewNode = new IMAGE_NODE;
1623 pNewNode->image = *pView;
1624 pNewNode->createInfo = *pCreateInfo;
1625 imageMap[*pView] = pNewNode;
1626 loader_platform_thread_unlock_mutex(&globalLock);
1627 }
1628 return result;
1629}
1630
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001631static void track_pipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline)
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001632{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001633 // Create LL HEAD for this Pipeline
1634 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001635 PIPELINE_NODE* pPipeNode = new PIPELINE_NODE;
1636 memset((void*)pPipeNode, 0, sizeof(PIPELINE_NODE));
1637 pPipeNode->pipeline = *pPipeline;
1638 initPipeline(pPipeNode, pCreateInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001639 loader_platform_thread_unlock_mutex(&globalLock);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001640}
1641
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001642VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001643{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001644 VkResult result = nextTable.CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001645 // Create LL HEAD for this Pipeline
1646 char str[1024];
1647 sprintf(str, "Created Gfx Pipeline %p", (void*)*pPipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001648 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001649
1650 track_pipeline(pCreateInfo, pPipeline);
1651
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001652 return result;
1653}
1654
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001655VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelineDerivative(
1656 VkDevice device,
1657 const VkGraphicsPipelineCreateInfo* pCreateInfo,
1658 VkPipeline basePipeline,
1659 VkPipeline* pPipeline)
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001660{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001661 VkResult result = nextTable.CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001662 // Create LL HEAD for this Pipeline
1663 char str[1024];
1664 sprintf(str, "Created Gfx Pipeline %p (derived from pipeline %p)", (void*)*pPipeline, basePipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001665 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, *pPipeline, 0, DRAWSTATE_NONE, "DS", str);
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001666
1667 track_pipeline(pCreateInfo, pPipeline);
1668
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001669 loader_platform_thread_unlock_mutex(&globalLock);
Jon Ashburnbdcd7562015-04-14 14:12:59 -06001670
1671 return result;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001672}
1673
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001674VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001675{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001676 VkResult result = nextTable.CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001677 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001678 loader_platform_thread_lock_mutex(&globalLock);
1679 SAMPLER_NODE* pNewNode = new SAMPLER_NODE;
1680 pNewNode->sampler = *pSampler;
1681 pNewNode->createInfo = *pCreateInfo;
1682 sampleMap[*pSampler] = pNewNode;
1683 loader_platform_thread_unlock_mutex(&globalLock);
1684 }
1685 return result;
1686}
1687
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001688VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001689{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001690 VkResult result = nextTable.CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001691 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001692 LAYOUT_NODE* pNewNode = new LAYOUT_NODE;
1693 if (NULL == pNewNode) {
1694 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001695 sprintf(str, "Out of memory while attempting to allocate LAYOUT_NODE in vkCreateDescriptorSetLayout()");
1696 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, *pSetLayout, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001697 }
1698 memset(pNewNode, 0, sizeof(LAYOUT_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001699 memcpy((void*)&pNewNode->createInfo, pCreateInfo, sizeof(VkDescriptorSetLayoutCreateInfo));
1700 pNewNode->createInfo.pBinding = new VkDescriptorSetLayoutBinding[pCreateInfo->count];
1701 memcpy((void*)pNewNode->createInfo.pBinding, pCreateInfo->pBinding, sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->count);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001702 uint32_t totalCount = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001703 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001704 totalCount += pCreateInfo->pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001705 if (pCreateInfo->pBinding[i].pImmutableSamplers) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001706 VkSampler** ppIS = (VkSampler**)&pNewNode->createInfo.pBinding[i].pImmutableSamplers;
Chia-I Wud3114a22015-05-25 16:22:52 +08001707 *ppIS = new VkSampler[pCreateInfo->pBinding[i].arraySize];
1708 memcpy(*ppIS, pCreateInfo->pBinding[i].pImmutableSamplers, pCreateInfo->pBinding[i].arraySize*sizeof(VkSampler));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001709 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001710 }
1711 if (totalCount > 0) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001712 pNewNode->pTypes = new VkDescriptorType[totalCount];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001713 uint32_t offset = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001714 uint32_t j = 0;
1715 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001716 for (j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001717 pNewNode->pTypes[offset + j] = pCreateInfo->pBinding[i].descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001718 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001719 offset += j;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001720 }
1721 }
1722 pNewNode->layout = *pSetLayout;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001723 pNewNode->startIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001724 pNewNode->endIndex = pNewNode->startIndex + totalCount - 1;
1725 assert(pNewNode->endIndex >= pNewNode->startIndex);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001726 // Put new node at Head of global Layer list
1727 loader_platform_thread_lock_mutex(&globalLock);
1728 layoutMap[*pSetLayout] = pNewNode;
1729 loader_platform_thread_unlock_mutex(&globalLock);
1730 }
1731 return result;
1732}
1733
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001734VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001735{
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001736 VkResult result = nextTable.CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001737 if (VK_SUCCESS == result) {
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001738 // TODO : Need to capture the pipeline layout
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001739 }
1740 return result;
1741}
1742
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001743VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001744{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001745 VkResult result = nextTable.CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001746 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001747 // Insert this pool into Global Pool LL at head
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001748 char str[1024];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001749 sprintf(str, "Created Descriptor Pool %p", (void*)*pDescriptorPool);
Mike Stroyan230e6252015-04-17 12:36:38 -06001750 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, (VkObject)pDescriptorPool, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001751 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001752 POOL_NODE* pNewNode = new POOL_NODE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001753 if (NULL == pNewNode) {
1754 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001755 sprintf(str, "Out of memory while attempting to allocate POOL_NODE in vkCreateDescriptorPool()");
Mike Stroyan230e6252015-04-17 12:36:38 -06001756 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, (VkObject)*pDescriptorPool, 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001757 }
1758 else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001759 memset(pNewNode, 0, sizeof(POOL_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001760 VkDescriptorPoolCreateInfo* pCI = (VkDescriptorPoolCreateInfo*)&pNewNode->createInfo;
1761 memcpy((void*)pCI, pCreateInfo, sizeof(VkDescriptorPoolCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001762 if (pNewNode->createInfo.count) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001763 size_t typeCountSize = pNewNode->createInfo.count * sizeof(VkDescriptorTypeCount);
1764 pNewNode->createInfo.pTypeCount = new VkDescriptorTypeCount[typeCountSize];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001765 memcpy((void*)pNewNode->createInfo.pTypeCount, pCreateInfo->pTypeCount, typeCountSize);
1766 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001767 pNewNode->poolUsage = poolUsage;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001768 pNewNode->maxSets = maxSets;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001769 pNewNode->pool = *pDescriptorPool;
1770 poolMap[*pDescriptorPool] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001771 }
1772 loader_platform_thread_unlock_mutex(&globalLock);
1773 }
1774 else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001775 // Need to do anything if pool create fails?
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001776 }
1777 return result;
1778}
1779
Mike Stroyan230e6252015-04-17 12:36:38 -06001780VK_LAYER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001781{
Mike Stroyan230e6252015-04-17 12:36:38 -06001782 VkResult result = nextTable.ResetDescriptorPool(device, descriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001783 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001784 clearDescriptorPool(descriptorPool);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001785 }
1786 return result;
1787}
1788
Mike Stroyan230e6252015-04-17 12:36:38 -06001789VK_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 -06001790{
Mike Stroyan230e6252015-04-17 12:36:38 -06001791 VkResult result = nextTable.AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets, pCount);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001792 if ((VK_SUCCESS == result) || (*pCount > 0)) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001793 POOL_NODE *pPoolNode = getPoolNode(descriptorPool);
1794 if (!pPoolNode) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001795 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001796 sprintf(str, "Unable to find pool node for pool %p specified in vkAllocDescriptorSets() call", (void*)descriptorPool);
1797 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, descriptorPool, 0, DRAWSTATE_INVALID_POOL, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001798 }
1799 else {
1800 for (uint32_t i = 0; i < *pCount; i++) {
1801 char str[1024];
1802 sprintf(str, "Created Descriptor Set %p", (void*)pDescriptorSets[i]);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001803 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001804 // Create new set node and add to head of pool nodes
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001805 SET_NODE* pNewNode = new SET_NODE;
1806 if (NULL == pNewNode) {
1807 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001808 sprintf(str, "Out of memory while attempting to allocate SET_NODE in vkAllocDescriptorSets()");
1809 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_OUT_OF_MEMORY, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001810 }
1811 else {
1812 memset(pNewNode, 0, sizeof(SET_NODE));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001813 // Insert set at head of Set LL for this pool
1814 pNewNode->pNext = pPoolNode->pSets;
1815 pPoolNode->pSets = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001816 LAYOUT_NODE* pLayout = getLayoutNode(pSetLayouts[i]);
1817 if (NULL == pLayout) {
1818 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001819 sprintf(str, "Unable to find set layout node for layout %p specified in vkAllocDescriptorSets() call", (void*)pSetLayouts[i]);
1820 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pSetLayouts[i], 0, DRAWSTATE_INVALID_LAYOUT, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001821 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001822 pNewNode->pLayout = pLayout;
1823 pNewNode->pool = descriptorPool;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001824 pNewNode->set = pDescriptorSets[i];
1825 pNewNode->setUsage = setUsage;
1826 pNewNode->descriptorCount = pLayout->endIndex + 1;
1827 if (pNewNode->descriptorCount) {
1828 size_t descriptorArraySize = sizeof(GENERIC_HEADER*)*pNewNode->descriptorCount;
1829 pNewNode->ppDescriptors = new GENERIC_HEADER*[descriptorArraySize];
1830 memset(pNewNode->ppDescriptors, 0, descriptorArraySize);
1831 }
1832 setMap[pDescriptorSets[i]] = pNewNode;
1833 }
1834 }
1835 }
1836 }
1837 return result;
1838}
1839
Mike Stroyan230e6252015-04-17 12:36:38 -06001840VK_LAYER_EXPORT void VKAPI vkClearDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001841{
1842 for (uint32_t i = 0; i < count; i++) {
1843 clearDescriptorSet(pDescriptorSets[i]);
1844 }
Mike Stroyan230e6252015-04-17 12:36:38 -06001845 nextTable.ClearDescriptorSets(device, descriptorPool, count, pDescriptorSets);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001846}
1847
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001848VK_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 -06001849{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001850 if (dsUpdate(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, writeCount, pDescriptorWrites) &&
1851 dsUpdate(VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, copyCount, pDescriptorCopies))
1852 return nextTable.UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
1853 else
1854 return VK_ERROR_UNKNOWN;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001855}
1856
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001857VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(VkDevice device, const VkDynamicVpStateCreateInfo* pCreateInfo, VkDynamicVpState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001858{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001859 VkResult result = nextTable.CreateDynamicViewportState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001860 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_VIEWPORT);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001861 return result;
1862}
1863
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001864VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterState(VkDevice device, const VkDynamicRsStateCreateInfo* pCreateInfo, VkDynamicRsState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001865{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001866 VkResult result = nextTable.CreateDynamicRasterState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001867 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_RASTER);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001868 return result;
1869}
1870
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001871VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(VkDevice device, const VkDynamicCbStateCreateInfo* pCreateInfo, VkDynamicCbState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001872{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001873 VkResult result = nextTable.CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001874 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_COLOR_BLEND);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001875 return result;
1876}
1877
Courtney Goeltzenleuchterfcf855f2015-04-10 16:24:50 -06001878VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(VkDevice device, const VkDynamicDsStateCreateInfo* pCreateInfo, VkDynamicDsState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001879{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001880 VkResult result = nextTable.CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tony Barbour8205d902015-04-16 15:59:00 -06001881 insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_DEPTH_STENCIL);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001882 return result;
1883}
1884
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001885VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001886{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001887 VkResult result = nextTable.CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001888 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001889 loader_platform_thread_lock_mutex(&globalLock);
1890 GLOBAL_CB_NODE* pCB = new GLOBAL_CB_NODE;
1891 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1892 pCB->cmdBuffer = *pCmdBuffer;
1893 pCB->flags = pCreateInfo->flags;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001894 pCB->queueNodeIndex = pCreateInfo->queueNodeIndex;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001895 pCB->lastVtxBinding = MAX_BINDING;
1896 cmdBufferMap[*pCmdBuffer] = pCB;
1897 loader_platform_thread_unlock_mutex(&globalLock);
1898 updateCBTracking(*pCmdBuffer);
1899 }
1900 return result;
1901}
1902
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001903VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001904{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001905 VkResult result = nextTable.BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001906 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001907 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1908 if (pCB) {
1909 if (CB_NEW != pCB->state)
1910 resetCB(cmdBuffer);
1911 pCB->state = CB_UPDATE_ACTIVE;
Tobin Ehlis2464b882015-04-01 08:40:34 -06001912 if (pBeginInfo->pNext) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001913 VkCmdBufferGraphicsBeginInfo* pCbGfxBI = (VkCmdBufferGraphicsBeginInfo*)pBeginInfo->pNext;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001914 if (VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO == pCbGfxBI->sType) {
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06001915 pCB->activeRenderPass = pCbGfxBI->renderPassContinue.renderPass;
Tobin Ehlis2464b882015-04-01 08:40:34 -06001916 }
1917 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001918 }
1919 else {
1920 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001921 sprintf(str, "In vkBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
1922 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001923 }
1924 updateCBTracking(cmdBuffer);
1925 }
1926 return result;
1927}
1928
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001929VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001930{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001931 VkResult result = nextTable.EndCommandBuffer(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001932 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001933 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1934 if (pCB) {
1935 pCB->state = CB_UPDATE_COMPLETE;
Tobin Ehlis97866202015-06-10 12:57:07 -06001936 // Reset CB status flags
1937 pCB->status = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001938 printCB(cmdBuffer);
1939 }
1940 else {
1941 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001942 sprintf(str, "In vkEndCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
1943 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001944 }
1945 updateCBTracking(cmdBuffer);
1946 //cbDumpDotFile("cb_dump.dot");
1947 }
1948 return result;
1949}
1950
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001951VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001952{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001953 VkResult result = nextTable.ResetCommandBuffer(cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001954 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001955 resetCB(cmdBuffer);
1956 updateCBTracking(cmdBuffer);
1957 }
1958 return result;
1959}
1960
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001961VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001962{
1963 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1964 if (pCB) {
1965 updateCBTracking(cmdBuffer);
1966 addCmd(pCB, CMD_BINDPIPELINE);
1967 PIPELINE_NODE* pPN = getPipeline(pipeline);
1968 if (pPN) {
1969 pCB->lastBoundPipeline = pipeline;
1970 loader_platform_thread_lock_mutex(&globalLock);
1971 g_lastBoundPipeline = pPN;
1972 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis2464b882015-04-01 08:40:34 -06001973 validatePipelineState(pCB, pipelineBindPoint, pipeline);
Tobin Ehlise9b700e2015-05-26 16:06:50 -06001974 nextTable.CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001975 }
1976 else {
1977 char str[1024];
1978 sprintf(str, "Attempt to bind Pipeline %p that doesn't exist!", (void*)pipeline);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001979 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pipeline, 0, DRAWSTATE_INVALID_PIPELINE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001980 }
1981 }
1982 else {
1983 char str[1024];
1984 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001985 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001986 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001987}
1988
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001989VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicStateObject(VkCmdBuffer cmdBuffer, VkStateBindPoint stateBindPoint, VkDynamicStateObject state)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001990{
1991 setLastBoundDynamicState(cmdBuffer, state, stateBindPoint);
1992 nextTable.CmdBindDynamicStateObject(cmdBuffer, stateBindPoint, state);
1993}
1994
Cody Northrop1a01b1d2015-04-16 13:41:56 -06001995VK_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 -06001996{
1997 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
1998 if (pCB) {
1999 updateCBTracking(cmdBuffer);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06002000 addCmd(pCB, CMD_BINDDESCRIPTORSETS);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002001 if (validateBoundPipeline(cmdBuffer)) {
2002 for (uint32_t i=0; i<setCount; i++) {
2003 if (getSetNode(pDescriptorSets[i])) {
2004 loader_platform_thread_lock_mutex(&globalLock);
2005 pCB->lastBoundDescriptorSet = pDescriptorSets[i];
2006 pCB->boundDescriptorSets.push_back(pDescriptorSets[i]);
2007 g_lastBoundDescriptorSet = pDescriptorSets[i];
2008 loader_platform_thread_unlock_mutex(&globalLock);
2009 char str[1024];
2010 sprintf(str, "DS %p bound on pipeline %s", (void*)pDescriptorSets[i], string_VkPipelineBindPoint(pipelineBindPoint));
2011 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_NONE, "DS", str);
2012 synchAndPrintDSConfig(cmdBuffer);
2013 }
2014 else {
2015 char str[1024];
2016 sprintf(str, "Attempt to bind DS %p that doesn't exist!", (void*)pDescriptorSets[i]);
2017 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, pDescriptorSets[i], 0, DRAWSTATE_INVALID_SET, "DS", str);
2018 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002019 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002020 nextTable.CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002021 }
2022 }
2023 else {
2024 char str[1024];
2025 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002026 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002027 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002028}
2029
Tony Barbour8205d902015-04-16 15:59:00 -06002030VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002031{
2032 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2033 if (pCB) {
2034 updateCBTracking(cmdBuffer);
2035 addCmd(pCB, CMD_BINDINDEXBUFFER);
2036 // TODO : Track idxBuffer binding
2037 }
2038 else {
2039 char str[1024];
2040 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002041 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002042 }
2043 nextTable.CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
2044}
2045
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002046VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
2047 VkCmdBuffer cmdBuffer,
2048 uint32_t startBinding,
2049 uint32_t bindingCount,
2050 const VkBuffer* pBuffers,
Tony Barbour8205d902015-04-16 15:59:00 -06002051 const VkDeviceSize* pOffsets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002052{
2053 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2054 if (pCB) {
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002055 /* TODO: Need to track all the vertex buffers, not just last one */
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002056 updateCBTracking(cmdBuffer);
2057 addCmd(pCB, CMD_BINDVERTEXBUFFER);
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002058 pCB->lastVtxBinding = startBinding + bindingCount -1;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002059 if (validateBoundPipeline(cmdBuffer)) {
2060 nextTable.CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
2061 }
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002062 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002063 char str[1024];
2064 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002065 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002066 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002067}
2068
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002069VK_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 -06002070{
2071 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002072 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002073 if (pCB) {
2074 updateCBTracking(cmdBuffer);
2075 addCmd(pCB, CMD_DRAW);
2076 pCB->drawCount[DRAW]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002077 loader_platform_thread_lock_mutex(&globalLock);
2078 valid = validate_draw_state_flags(cmdBuffer);
2079 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002080 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002081 sprintf(str, "vkCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
2082 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002083 synchAndPrintDSConfig(cmdBuffer);
2084 }
2085 else {
2086 char str[1024];
2087 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002088 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002089 }
Tobin Ehlis97866202015-06-10 12:57:07 -06002090 if (valid)
2091 nextTable.CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002092}
2093
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002094VK_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 -06002095{
2096 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002097 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002098 if (pCB) {
2099 updateCBTracking(cmdBuffer);
2100 addCmd(pCB, CMD_DRAWINDEXED);
2101 pCB->drawCount[DRAW_INDEXED]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002102 loader_platform_thread_lock_mutex(&globalLock);
2103 valid = validate_draw_state_flags(cmdBuffer);
2104 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002105 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002106 sprintf(str, "vkCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
2107 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002108 synchAndPrintDSConfig(cmdBuffer);
2109 }
2110 else {
2111 char str[1024];
2112 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002113 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002114 }
Tobin Ehlis97866202015-06-10 12:57:07 -06002115 if (valid)
2116 nextTable.CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002117}
2118
Tony Barbour8205d902015-04-16 15:59:00 -06002119VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002120{
2121 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002122 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002123 if (pCB) {
2124 updateCBTracking(cmdBuffer);
2125 addCmd(pCB, CMD_DRAWINDIRECT);
2126 pCB->drawCount[DRAW_INDIRECT]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002127 loader_platform_thread_lock_mutex(&globalLock);
2128 valid = validate_draw_state_flags(cmdBuffer);
2129 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002130 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002131 sprintf(str, "vkCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
2132 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002133 synchAndPrintDSConfig(cmdBuffer);
2134 }
2135 else {
2136 char str[1024];
2137 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002138 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002139 }
Tobin Ehlis97866202015-06-10 12:57:07 -06002140 if (valid)
2141 nextTable.CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002142}
2143
Tony Barbour8205d902015-04-16 15:59:00 -06002144VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002145{
2146 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Tobin Ehlis97866202015-06-10 12:57:07 -06002147 bool32_t valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002148 if (pCB) {
2149 updateCBTracking(cmdBuffer);
2150 addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
2151 pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
Tobin Ehlis97866202015-06-10 12:57:07 -06002152 loader_platform_thread_lock_mutex(&globalLock);
2153 valid = validate_draw_state_flags(cmdBuffer);
2154 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002155 char str[1024];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002156 sprintf(str, "vkCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
2157 layerCbMsg(VK_DBG_MSG_UNKNOWN, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_NONE, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002158 synchAndPrintDSConfig(cmdBuffer);
2159 }
2160 else {
2161 char str[1024];
2162 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002163 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002164 }
Tobin Ehlis97866202015-06-10 12:57:07 -06002165 if (valid)
2166 nextTable.CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002167}
2168
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002169VK_LAYER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002170{
2171 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2172 if (pCB) {
2173 updateCBTracking(cmdBuffer);
2174 addCmd(pCB, CMD_DISPATCH);
2175 }
2176 else {
2177 char str[1024];
2178 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002179 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002180 }
2181 nextTable.CmdDispatch(cmdBuffer, x, y, z);
2182}
2183
Tony Barbour8205d902015-04-16 15:59:00 -06002184VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002185{
2186 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2187 if (pCB) {
2188 updateCBTracking(cmdBuffer);
2189 addCmd(pCB, CMD_DISPATCHINDIRECT);
2190 }
2191 else {
2192 char str[1024];
2193 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002194 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002195 }
2196 nextTable.CmdDispatchIndirect(cmdBuffer, buffer, offset);
2197}
2198
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002199VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002200{
2201 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2202 if (pCB) {
2203 updateCBTracking(cmdBuffer);
2204 addCmd(pCB, CMD_COPYBUFFER);
2205 }
2206 else {
2207 char str[1024];
2208 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002209 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002210 }
2211 nextTable.CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
2212}
2213
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002214VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer,
2215 VkImage srcImage,
2216 VkImageLayout srcImageLayout,
2217 VkImage destImage,
2218 VkImageLayout destImageLayout,
2219 uint32_t regionCount, const VkImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002220{
2221 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2222 if (pCB) {
2223 updateCBTracking(cmdBuffer);
2224 addCmd(pCB, CMD_COPYIMAGE);
2225 }
2226 else {
2227 char str[1024];
2228 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002229 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002230 }
Courtney Goeltzenleuchter45334842015-04-13 16:16:56 -06002231 nextTable.CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002232}
2233
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002234VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer,
2235 VkImage srcImage, VkImageLayout srcImageLayout,
2236 VkImage destImage, VkImageLayout destImageLayout,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002237 uint32_t regionCount, const VkImageBlit* pRegions,
2238 VkTexFilter filter)
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002239{
2240 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2241 if (pCB) {
2242 updateCBTracking(cmdBuffer);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06002243 addCmd(pCB, CMD_BLITIMAGE);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002244 }
2245 else {
2246 char str[1024];
2247 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002248 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002249 }
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002250 nextTable.CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002251}
2252
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002253VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer,
2254 VkBuffer srcBuffer,
2255 VkImage destImage, VkImageLayout destImageLayout,
2256 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002257{
2258 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2259 if (pCB) {
2260 updateCBTracking(cmdBuffer);
2261 addCmd(pCB, CMD_COPYBUFFERTOIMAGE);
2262 }
2263 else {
2264 char str[1024];
2265 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002266 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002267 }
Courtney Goeltzenleuchter45334842015-04-13 16:16:56 -06002268 nextTable.CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002269}
2270
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002271VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer,
2272 VkImage srcImage, VkImageLayout srcImageLayout,
2273 VkBuffer destBuffer,
2274 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002275{
2276 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2277 if (pCB) {
2278 updateCBTracking(cmdBuffer);
2279 addCmd(pCB, CMD_COPYIMAGETOBUFFER);
2280 }
2281 else {
2282 char str[1024];
2283 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002284 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002285 }
Courtney Goeltzenleuchter45334842015-04-13 16:16:56 -06002286 nextTable.CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002287}
2288
Tony Barbour8205d902015-04-16 15:59:00 -06002289VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002290{
2291 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2292 if (pCB) {
2293 updateCBTracking(cmdBuffer);
2294 addCmd(pCB, CMD_UPDATEBUFFER);
2295 }
2296 else {
2297 char str[1024];
2298 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002299 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002300 }
2301 nextTable.CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
2302}
2303
Tony Barbour8205d902015-04-16 15:59:00 -06002304VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002305{
2306 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2307 if (pCB) {
2308 updateCBTracking(cmdBuffer);
2309 addCmd(pCB, CMD_FILLBUFFER);
2310 }
2311 else {
2312 char str[1024];
2313 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002314 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002315 }
2316 nextTable.CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
2317}
2318
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002319VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2320 VkCmdBuffer cmdBuffer,
2321 VkImage image, VkImageLayout imageLayout,
2322 const VkClearColor *pColor,
2323 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002324{
2325 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2326 if (pCB) {
2327 updateCBTracking(cmdBuffer);
2328 addCmd(pCB, CMD_CLEARCOLORIMAGE);
2329 }
2330 else {
2331 char str[1024];
2332 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002333 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002334 }
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002335 nextTable.CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002336}
2337
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002338VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencil(VkCmdBuffer cmdBuffer,
2339 VkImage image, VkImageLayout imageLayout,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002340 float depth, uint32_t stencil,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002341 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002342{
2343 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2344 if (pCB) {
2345 updateCBTracking(cmdBuffer);
2346 addCmd(pCB, CMD_CLEARDEPTHSTENCIL);
2347 }
2348 else {
2349 char str[1024];
2350 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002351 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002352 }
Courtney Goeltzenleuchter45334842015-04-13 16:16:56 -06002353 nextTable.CmdClearDepthStencil(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002354}
2355
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002356VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer,
2357 VkImage srcImage, VkImageLayout srcImageLayout,
2358 VkImage destImage, VkImageLayout destImageLayout,
Tony Barbour11f74372015-04-13 15:02:52 -06002359 uint32_t regionCount, const VkImageResolve* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002360{
2361 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2362 if (pCB) {
2363 updateCBTracking(cmdBuffer);
2364 addCmd(pCB, CMD_RESOLVEIMAGE);
2365 }
2366 else {
2367 char str[1024];
2368 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002369 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002370 }
Tony Barbour11f74372015-04-13 15:02:52 -06002371 nextTable.CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002372}
2373
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002374VK_LAYER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002375{
2376 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2377 if (pCB) {
2378 updateCBTracking(cmdBuffer);
2379 addCmd(pCB, CMD_SETEVENT);
2380 }
2381 else {
2382 char str[1024];
2383 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002384 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002385 }
2386 nextTable.CmdSetEvent(cmdBuffer, event, pipeEvent);
2387}
2388
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002389VK_LAYER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipeEvent pipeEvent)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002390{
2391 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2392 if (pCB) {
2393 updateCBTracking(cmdBuffer);
2394 addCmd(pCB, CMD_RESETEVENT);
2395 }
2396 else {
2397 char str[1024];
2398 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002399 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002400 }
Courtney Goeltzenleuchteraa86e0e2015-03-24 18:02:34 -06002401 nextTable.CmdResetEvent(cmdBuffer, event, pipeEvent);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002402}
2403
Tony Barbour8205d902015-04-16 15:59:00 -06002404VK_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 -06002405{
2406 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2407 if (pCB) {
2408 updateCBTracking(cmdBuffer);
2409 addCmd(pCB, CMD_WAITEVENTS);
2410 }
2411 else {
2412 char str[1024];
2413 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002414 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002415 }
Tony Barbour8205d902015-04-16 15:59:00 -06002416 nextTable.CmdWaitEvents(cmdBuffer, waitEvent, eventCount, pEvents, memBarrierCount, ppMemBarriers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002417}
2418
Tony Barbour8205d902015-04-16 15:59:00 -06002419VK_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 -06002420{
2421 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2422 if (pCB) {
2423 updateCBTracking(cmdBuffer);
2424 addCmd(pCB, CMD_PIPELINEBARRIER);
2425 }
2426 else {
2427 char str[1024];
2428 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002429 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002430 }
Tony Barbour8205d902015-04-16 15:59:00 -06002431 nextTable.CmdPipelineBarrier(cmdBuffer, waitEvent, pipeEventCount, pPipeEvents, memBarrierCount, ppMemBarriers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002432}
2433
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002434VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002435{
2436 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2437 if (pCB) {
2438 updateCBTracking(cmdBuffer);
2439 addCmd(pCB, CMD_BEGINQUERY);
2440 }
2441 else {
2442 char str[1024];
2443 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002444 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002445 }
2446 nextTable.CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
2447}
2448
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002449VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002450{
2451 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2452 if (pCB) {
2453 updateCBTracking(cmdBuffer);
2454 addCmd(pCB, CMD_ENDQUERY);
2455 }
2456 else {
2457 char str[1024];
2458 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002459 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002460 }
2461 nextTable.CmdEndQuery(cmdBuffer, queryPool, slot);
2462}
2463
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002464VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002465{
2466 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2467 if (pCB) {
2468 updateCBTracking(cmdBuffer);
2469 addCmd(pCB, CMD_RESETQUERYPOOL);
2470 }
2471 else {
2472 char str[1024];
2473 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002474 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002475 }
2476 nextTable.CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
2477}
2478
Tony Barbour8205d902015-04-16 15:59:00 -06002479VK_LAYER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002480{
2481 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2482 if (pCB) {
2483 updateCBTracking(cmdBuffer);
2484 addCmd(pCB, CMD_WRITETIMESTAMP);
2485 }
2486 else {
2487 char str[1024];
2488 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002489 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002490 }
2491 nextTable.CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
2492}
2493
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002494VK_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 -06002495{
2496 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2497 if (pCB) {
2498 updateCBTracking(cmdBuffer);
2499 addCmd(pCB, CMD_INITATOMICCOUNTERS);
2500 }
2501 else {
2502 char str[1024];
2503 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002504 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002505 }
2506 nextTable.CmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
2507}
2508
Tony Barbour8205d902015-04-16 15:59:00 -06002509VK_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 -06002510{
2511 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2512 if (pCB) {
2513 updateCBTracking(cmdBuffer);
2514 addCmd(pCB, CMD_LOADATOMICCOUNTERS);
2515 }
2516 else {
2517 char str[1024];
2518 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002519 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002520 }
2521 nextTable.CmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcBuffer, srcOffset);
2522}
2523
Tony Barbour8205d902015-04-16 15:59:00 -06002524VK_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 -06002525{
2526 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2527 if (pCB) {
2528 updateCBTracking(cmdBuffer);
2529 addCmd(pCB, CMD_SAVEATOMICCOUNTERS);
2530 }
2531 else {
2532 char str[1024];
2533 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002534 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002535 }
2536 nextTable.CmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destBuffer, destOffset);
2537}
2538
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002539VK_LAYER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002540{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002541 VkResult result = nextTable.CreateFramebuffer(device, pCreateInfo, pFramebuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002542 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002543 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002544 VkFramebufferCreateInfo* localFBCI = new VkFramebufferCreateInfo(*pCreateInfo);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002545 if (pCreateInfo->pColorAttachments) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002546 localFBCI->pColorAttachments = new VkColorAttachmentBindInfo[localFBCI->colorAttachmentCount];
2547 memcpy((void*)localFBCI->pColorAttachments, pCreateInfo->pColorAttachments, localFBCI->colorAttachmentCount*sizeof(VkColorAttachmentBindInfo));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002548 }
2549 if (pCreateInfo->pDepthStencilAttachment) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002550 localFBCI->pDepthStencilAttachment = new VkDepthStencilBindInfo[localFBCI->colorAttachmentCount];
2551 memcpy((void*)localFBCI->pDepthStencilAttachment, pCreateInfo->pDepthStencilAttachment, localFBCI->colorAttachmentCount*sizeof(VkDepthStencilBindInfo));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002552 }
2553 frameBufferMap[*pFramebuffer] = localFBCI;
2554 }
2555 return result;
2556}
2557
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002558VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002559{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002560 VkResult result = nextTable.CreateRenderPass(device, pCreateInfo, pRenderPass);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002561 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002562 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002563 VkRenderPassCreateInfo* localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002564 if (pCreateInfo->pColorLoadOps) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002565 localRPCI->pColorLoadOps = new VkAttachmentLoadOp[localRPCI->colorAttachmentCount];
2566 memcpy((void*)localRPCI->pColorLoadOps, pCreateInfo->pColorLoadOps, localRPCI->colorAttachmentCount*sizeof(VkAttachmentLoadOp));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002567 }
2568 if (pCreateInfo->pColorStoreOps) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002569 localRPCI->pColorStoreOps = new VkAttachmentStoreOp[localRPCI->colorAttachmentCount];
2570 memcpy((void*)localRPCI->pColorStoreOps, pCreateInfo->pColorStoreOps, localRPCI->colorAttachmentCount*sizeof(VkAttachmentStoreOp));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002571 }
2572 if (pCreateInfo->pColorLoadClearValues) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002573 localRPCI->pColorLoadClearValues = new VkClearColor[localRPCI->colorAttachmentCount];
2574 memcpy((void*)localRPCI->pColorLoadClearValues, pCreateInfo->pColorLoadClearValues, localRPCI->colorAttachmentCount*sizeof(VkClearColor));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002575 }
2576 renderPassMap[*pRenderPass] = localRPCI;
2577 }
2578 return result;
2579}
2580
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002581VK_LAYER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBegin *pRenderPassBegin)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002582{
2583 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2584 if (pCB) {
2585 updateCBTracking(cmdBuffer);
2586 addCmd(pCB, CMD_BEGINRENDERPASS);
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06002587 pCB->activeRenderPass = pRenderPassBegin->renderPass;
2588 pCB->framebuffer = pRenderPassBegin->framebuffer;
Tony Barbourb9f82ba2015-04-06 11:09:26 -06002589 if (pCB->lastBoundPipeline) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002590 validatePipelineState(pCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
Tony Barbourb9f82ba2015-04-06 11:09:26 -06002591 }
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06002592 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002593 char str[1024];
2594 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002595 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002596 }
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -06002597 nextTable.CmdBeginRenderPass(cmdBuffer, pRenderPassBegin);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002598}
2599
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002600VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer, VkRenderPass renderPass)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002601{
2602 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2603 if (pCB) {
2604 updateCBTracking(cmdBuffer);
2605 addCmd(pCB, CMD_ENDRENDERPASS);
Tobin Ehlis2464b882015-04-01 08:40:34 -06002606 pCB->activeRenderPass = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002607 }
2608 else {
2609 char str[1024];
2610 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002611 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002612 }
2613 nextTable.CmdEndRenderPass(cmdBuffer, renderPass);
2614}
2615
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002616VK_LAYER_EXPORT VkResult VKAPI vkDbgRegisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback, void* pUserData)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002617{
2618 // This layer intercepts callbacks
Tobin Ehliseaf28662015-04-08 10:58:37 -06002619 VK_LAYER_DBG_FUNCTION_NODE* pNewDbgFuncNode = new VK_LAYER_DBG_FUNCTION_NODE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002620 if (!pNewDbgFuncNode)
Tony Barbour8205d902015-04-16 15:59:00 -06002621 return VK_ERROR_OUT_OF_HOST_MEMORY;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002622 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
2623 pNewDbgFuncNode->pUserData = pUserData;
2624 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
2625 g_pDbgFunctionHead = pNewDbgFuncNode;
2626 // force callbacks if DebugAction hasn't been set already other than initial value
2627 if (g_actionIsDefault) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002628 g_debugAction = VK_DBG_LAYER_ACTION_CALLBACK;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002629 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002630 VkResult result = nextTable.DbgRegisterMsgCallback(instance, pfnMsgCallback, pUserData);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002631 return result;
2632}
2633
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002634VK_LAYER_EXPORT VkResult VKAPI vkDbgUnregisterMsgCallback(VkInstance instance, VK_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002635{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002636 VK_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
2637 VK_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002638 while (pTrav) {
2639 if (pTrav->pfnMsgCallback == pfnMsgCallback) {
2640 pPrev->pNext = pTrav->pNext;
2641 if (g_pDbgFunctionHead == pTrav)
2642 g_pDbgFunctionHead = pTrav->pNext;
Tobin Ehliseaf28662015-04-08 10:58:37 -06002643 delete pTrav;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002644 break;
2645 }
2646 pPrev = pTrav;
2647 pTrav = pTrav->pNext;
2648 }
2649 if (g_pDbgFunctionHead == NULL)
2650 {
2651 if (g_actionIsDefault)
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002652 g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002653 else
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002654 g_debugAction = (VK_LAYER_DBG_ACTION)(g_debugAction & ~((uint32_t)VK_DBG_LAYER_ACTION_CALLBACK));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002655 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002656 VkResult result = nextTable.DbgUnregisterMsgCallback(instance, pfnMsgCallback);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002657 return result;
2658}
2659
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002660VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002661{
2662 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2663 if (pCB) {
2664 updateCBTracking(cmdBuffer);
2665 addCmd(pCB, CMD_DBGMARKERBEGIN);
2666 }
2667 else {
2668 char str[1024];
2669 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002670 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002671 }
2672 nextTable.CmdDbgMarkerBegin(cmdBuffer, pMarker);
2673}
2674
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002675VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerEnd(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002676{
2677 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2678 if (pCB) {
2679 updateCBTracking(cmdBuffer);
2680 addCmd(pCB, CMD_DBGMARKEREND);
2681 }
2682 else {
2683 char str[1024];
2684 sprintf(str, "Attempt to use CmdBuffer %p that doesn't exist!", (void*)cmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002685 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, cmdBuffer, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002686 }
2687 nextTable.CmdDbgMarkerEnd(cmdBuffer);
2688}
2689
2690// TODO : Want to pass in a cmdBuffer here based on which state to display
2691void drawStateDumpDotFile(char* outFileName)
2692{
2693 // TODO : Currently just setting cmdBuffer based on global var
2694 //dumpDotFile(g_lastDrawStateCmdBuffer, outFileName);
2695 dumpGlobalDotFile(outFileName);
2696}
2697
2698void drawStateDumpCommandBufferDotFile(char* outFileName)
2699{
2700 cbDumpDotFile(outFileName);
2701}
2702
2703void drawStateDumpPngFile(char* outFileName)
2704{
2705#if defined(_WIN32)
2706// FIXME: NEED WINDOWS EQUIVALENT
2707 char str[1024];
2708 sprintf(str, "Cannot execute dot program yet on Windows.");
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002709 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002710#else // WIN32
2711 char dotExe[32] = "/usr/bin/dot";
2712 if( access(dotExe, X_OK) != -1) {
2713 dumpDotFile(g_lastCmdBuffer[getTIDIndex()], "/tmp/tmp.dot");
2714 char dotCmd[1024];
2715 sprintf(dotCmd, "%s /tmp/tmp.dot -Tpng -o %s", dotExe, outFileName);
Tony Barbour22a30862015-04-22 09:02:32 -06002716 int retval = system(dotCmd);
2717 assert(retval != -1);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002718 remove("/tmp/tmp.dot");
2719 }
2720 else {
2721 char str[1024];
2722 sprintf(str, "Cannot execute dot program at (%s) to dump requested %s file.", dotExe, outFileName);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002723 layerCbMsg(VK_DBG_MSG_ERROR, VK_VALIDATION_LEVEL_0, NULL, 0, DRAWSTATE_MISSING_DOT_PROGRAM, "DS", str);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002724 }
2725#endif // WIN32
2726}
2727
Tony Barbour8205d902015-04-16 15:59:00 -06002728VK_LAYER_EXPORT void* VKAPI vkGetProcAddr(VkPhysicalDevice gpu, const char* funcName)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002729{
Jon Ashburn301c5f02015-04-06 10:58:22 -06002730 VkBaseLayerObject* gpuw = (VkBaseLayerObject *) gpu;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002731
2732 if (gpu == NULL)
2733 return NULL;
2734 pCurObj = gpuw;
2735 loader_platform_thread_once(&g_initOnce, initDrawState);
2736
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002737 if (!strcmp(funcName, "vkGetProcAddr"))
2738 return (void *) vkGetProcAddr;
2739 if (!strcmp(funcName, "vkCreateDevice"))
2740 return (void*) vkCreateDevice;
2741 if (!strcmp(funcName, "vkDestroyDevice"))
2742 return (void*) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002743 if (!strcmp(funcName, "vkEnumerateLayers"))
2744 return (void*) vkEnumerateLayers;
2745 if (!strcmp(funcName, "vkQueueSubmit"))
2746 return (void*) vkQueueSubmit;
2747 if (!strcmp(funcName, "vkDestroyObject"))
2748 return (void*) vkDestroyObject;
2749 if (!strcmp(funcName, "vkCreateBufferView"))
2750 return (void*) vkCreateBufferView;
2751 if (!strcmp(funcName, "vkCreateImageView"))
2752 return (void*) vkCreateImageView;
2753 if (!strcmp(funcName, "vkCreateGraphicsPipeline"))
2754 return (void*) vkCreateGraphicsPipeline;
2755 if (!strcmp(funcName, "vkCreateGraphicsPipelineDerivative"))
2756 return (void*) vkCreateGraphicsPipelineDerivative;
2757 if (!strcmp(funcName, "vkCreateSampler"))
2758 return (void*) vkCreateSampler;
2759 if (!strcmp(funcName, "vkCreateDescriptorSetLayout"))
2760 return (void*) vkCreateDescriptorSetLayout;
Mark Lobodzinski556f7212015-04-17 14:11:39 -05002761 if (!strcmp(funcName, "vkCreatePipelineLayout"))
2762 return (void*) vkCreatePipelineLayout;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002763 if (!strcmp(funcName, "vkCreateDescriptorPool"))
2764 return (void*) vkCreateDescriptorPool;
2765 if (!strcmp(funcName, "vkResetDescriptorPool"))
2766 return (void*) vkResetDescriptorPool;
2767 if (!strcmp(funcName, "vkAllocDescriptorSets"))
2768 return (void*) vkAllocDescriptorSets;
2769 if (!strcmp(funcName, "vkClearDescriptorSets"))
2770 return (void*) vkClearDescriptorSets;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08002771 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
2772 return (void*) vkUpdateDescriptorSets;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002773 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
2774 return (void*) vkCreateDynamicViewportState;
2775 if (!strcmp(funcName, "vkCreateDynamicRasterState"))
2776 return (void*) vkCreateDynamicRasterState;
2777 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
2778 return (void*) vkCreateDynamicColorBlendState;
2779 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
2780 return (void*) vkCreateDynamicDepthStencilState;
2781 if (!strcmp(funcName, "vkCreateCommandBuffer"))
2782 return (void*) vkCreateCommandBuffer;
2783 if (!strcmp(funcName, "vkBeginCommandBuffer"))
2784 return (void*) vkBeginCommandBuffer;
2785 if (!strcmp(funcName, "vkEndCommandBuffer"))
2786 return (void*) vkEndCommandBuffer;
2787 if (!strcmp(funcName, "vkResetCommandBuffer"))
2788 return (void*) vkResetCommandBuffer;
2789 if (!strcmp(funcName, "vkCmdBindPipeline"))
2790 return (void*) vkCmdBindPipeline;
2791 if (!strcmp(funcName, "vkCmdBindDynamicStateObject"))
2792 return (void*) vkCmdBindDynamicStateObject;
2793 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
2794 return (void*) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002795 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
2796 return (void*) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002797 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
2798 return (void*) vkCmdBindIndexBuffer;
2799 if (!strcmp(funcName, "vkCmdDraw"))
2800 return (void*) vkCmdDraw;
2801 if (!strcmp(funcName, "vkCmdDrawIndexed"))
2802 return (void*) vkCmdDrawIndexed;
2803 if (!strcmp(funcName, "vkCmdDrawIndirect"))
2804 return (void*) vkCmdDrawIndirect;
2805 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
2806 return (void*) vkCmdDrawIndexedIndirect;
2807 if (!strcmp(funcName, "vkCmdDispatch"))
2808 return (void*) vkCmdDispatch;
2809 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
2810 return (void*) vkCmdDispatchIndirect;
2811 if (!strcmp(funcName, "vkCmdCopyBuffer"))
2812 return (void*) vkCmdCopyBuffer;
2813 if (!strcmp(funcName, "vkCmdCopyImage"))
2814 return (void*) vkCmdCopyImage;
2815 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
2816 return (void*) vkCmdCopyBufferToImage;
2817 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
2818 return (void*) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002819 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
2820 return (void*) vkCmdUpdateBuffer;
2821 if (!strcmp(funcName, "vkCmdFillBuffer"))
2822 return (void*) vkCmdFillBuffer;
2823 if (!strcmp(funcName, "vkCmdClearColorImage"))
2824 return (void*) vkCmdClearColorImage;
2825 if (!strcmp(funcName, "vkCmdClearDepthStencil"))
2826 return (void*) vkCmdClearDepthStencil;
2827 if (!strcmp(funcName, "vkCmdResolveImage"))
2828 return (void*) vkCmdResolveImage;
2829 if (!strcmp(funcName, "vkCmdSetEvent"))
2830 return (void*) vkCmdSetEvent;
2831 if (!strcmp(funcName, "vkCmdResetEvent"))
2832 return (void*) vkCmdResetEvent;
2833 if (!strcmp(funcName, "vkCmdWaitEvents"))
2834 return (void*) vkCmdWaitEvents;
2835 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
2836 return (void*) vkCmdPipelineBarrier;
2837 if (!strcmp(funcName, "vkCmdBeginQuery"))
2838 return (void*) vkCmdBeginQuery;
2839 if (!strcmp(funcName, "vkCmdEndQuery"))
2840 return (void*) vkCmdEndQuery;
2841 if (!strcmp(funcName, "vkCmdResetQueryPool"))
2842 return (void*) vkCmdResetQueryPool;
2843 if (!strcmp(funcName, "vkCmdWriteTimestamp"))
2844 return (void*) vkCmdWriteTimestamp;
2845 if (!strcmp(funcName, "vkCmdInitAtomicCounters"))
2846 return (void*) vkCmdInitAtomicCounters;
2847 if (!strcmp(funcName, "vkCmdLoadAtomicCounters"))
2848 return (void*) vkCmdLoadAtomicCounters;
2849 if (!strcmp(funcName, "vkCmdSaveAtomicCounters"))
2850 return (void*) vkCmdSaveAtomicCounters;
2851 if (!strcmp(funcName, "vkCreateFramebuffer"))
2852 return (void*) vkCreateFramebuffer;
2853 if (!strcmp(funcName, "vkCreateRenderPass"))
2854 return (void*) vkCreateRenderPass;
2855 if (!strcmp(funcName, "vkCmdBeginRenderPass"))
2856 return (void*) vkCmdBeginRenderPass;
2857 if (!strcmp(funcName, "vkCmdEndRenderPass"))
2858 return (void*) vkCmdEndRenderPass;
2859 if (!strcmp(funcName, "vkDbgRegisterMsgCallback"))
2860 return (void*) vkDbgRegisterMsgCallback;
2861 if (!strcmp(funcName, "vkDbgUnregisterMsgCallback"))
2862 return (void*) vkDbgUnregisterMsgCallback;
2863 if (!strcmp(funcName, "vkCmdDbgMarkerBegin"))
2864 return (void*) vkCmdDbgMarkerBegin;
2865 if (!strcmp(funcName, "vkCmdDbgMarkerEnd"))
2866 return (void*) vkCmdDbgMarkerEnd;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002867 if (!strcmp("drawStateDumpDotFile", funcName))
2868 return (void*) drawStateDumpDotFile;
2869 if (!strcmp("drawStateDumpCommandBufferDotFile", funcName))
2870 return (void*) drawStateDumpCommandBufferDotFile;
2871 if (!strcmp("drawStateDumpPngFile", funcName))
2872 return (void*) drawStateDumpPngFile;
2873 else {
2874 if (gpuw->pGPA == NULL)
2875 return NULL;
Tony Barbour8205d902015-04-16 15:59:00 -06002876 return gpuw->pGPA((VkPhysicalDevice)gpuw->nextObject, funcName);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002877 }
2878}