blob: c465768b0f0fea0cbd8d73a5eb4488cd422a1287 [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
Tobin Ehlis7a51d902015-07-03 10:34:49 -060030#include "vk_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
Tony Barboura938abb2015-04-22 11:36:22 -060036#if defined(__GNUC__)
Tobin Ehlis63bb9482015-03-17 16:24:32 -060037#pragma GCC diagnostic warning "-Wwrite-strings"
Tony Barboura938abb2015-04-22 11:36:22 -060038#endif
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060039#include "vk_struct_size_helper.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060040#include "draw_state.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060041#include "vk_layer_config.h"
Jon Ashburnf0615e22015-05-25 14:11:37 -060042#include "vk_debug_marker_layer.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060043// The following is #included again to catch certain OS-specific functions
44// being used:
Tobin Ehlis7a51d902015-07-03 10:34:49 -060045#include "vk_loader_platform.h"
Tobin Ehlis56d204a2015-07-03 10:15:26 -060046#include "vk_layer_msg.h"
47#include "vk_layer_table.h"
48#include "vk_layer_debug_marker_table.h"
49#include "vk_layer_data.h"
50#include "vk_layer_logging.h"
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -060051#include "vk_layer_extension_utils.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060052
Tobin Ehlisc91330b2015-06-16 09:04:30 -060053typedef struct _layer_data {
54 debug_report_data *report_data;
55 // TODO: put instance data here
56 VkDbgMsgCallback logging_callback;
57} layer_data;
58
59static std::unordered_map<void *, layer_data *> layer_data_map;
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -060060static device_table_map draw_state_device_table_map;
61static instance_table_map draw_state_instance_table_map;
62
Tobin Ehlis1dce5f12015-07-07 10:42:20 -060063unordered_map<uint64_t, SAMPLER_NODE*> sampleMap;
64unordered_map<uint64_t, VkImageViewCreateInfo> imageMap;
65unordered_map<uint64_t, VkAttachmentViewCreateInfo> viewMap;
66unordered_map<uint64_t, BUFFER_NODE*> bufferMap;
67unordered_map<uint64_t, VkDynamicViewportStateCreateInfo> dynamicVpStateMap;
Cody Northropf5bd2252015-08-17 11:10:49 -060068unordered_map<uint64_t, VkDynamicRasterLineStateCreateInfo> dynamicRasterLineStateMap;
69unordered_map<uint64_t, VkDynamicRasterDepthBiasStateCreateInfo> dynamicRasterDepthBiasStateMap;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -060070unordered_map<uint64_t, VkDynamicColorBlendStateCreateInfo> dynamicCbStateMap;
71unordered_map<uint64_t, VkDynamicDepthStencilStateCreateInfo> dynamicDsStateMap;
72unordered_map<uint64_t, PIPELINE_NODE*> pipelineMap;
73unordered_map<uint64_t, POOL_NODE*> poolMap;
74unordered_map<uint64_t, SET_NODE*> setMap;
75unordered_map<uint64_t, LAYOUT_NODE*> layoutMap;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -060076// Map for layout chains
Tobin Ehlis1dce5f12015-07-07 10:42:20 -060077unordered_map<void*, GLOBAL_CB_NODE*> cmdBufferMap;
78unordered_map<uint64_t, VkRenderPassCreateInfo*> renderPassMap;
79unordered_map<uint64_t, VkFramebufferCreateInfo*> frameBufferMap;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060080
Jon Ashburn6f8cd632015-06-01 09:37:38 -060081struct devExts {
82 bool debug_marker_enabled;
83};
84
Jon Ashburn6f8cd632015-06-01 09:37:38 -060085static std::unordered_map<void *, struct devExts> deviceExtMap;
Jon Ashburne0fa2282015-05-20 09:00:28 -060086
Tobin Ehlis63bb9482015-03-17 16:24:32 -060087static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Jon Ashburnd9564002015-05-07 10:27:37 -060088
Tobin Ehlis63bb9482015-03-17 16:24:32 -060089// TODO : This can be much smarter, using separate locks for separate global data
90static int globalLockInitialized = 0;
91static loader_platform_thread_mutex globalLock;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060092#define MAX_TID 513
93static loader_platform_thread_id g_tidMapping[MAX_TID] = {0};
94static uint32_t g_maxTID = 0;
Tobin Ehlisfde4dce2015-06-16 15:50:44 -060095
96template layer_data *get_my_data_ptr<layer_data>(
97 void *data_key,
98 std::unordered_map<void *, layer_data *> &data_map);
99
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600100debug_report_data *mdd(void* object)
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600101{
102 dispatch_key key = get_dispatch_key(object);
103 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
104#if DISPATCH_MAP_DEBUG
105 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
106#endif
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600107 return my_data->report_data;
108}
109
110debug_report_data *mid(VkInstance object)
111{
112 dispatch_key key = get_dispatch_key(object);
113 layer_data *my_data = get_my_data_ptr(get_dispatch_key(object), layer_data_map);
114#if DISPATCH_MAP_DEBUG
115 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
116#endif
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600117 return my_data->report_data;
118}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600119// Map actual TID to an index value and return that index
120// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs
121static uint32_t getTIDIndex() {
122 loader_platform_thread_id tid = loader_platform_get_thread_id();
123 for (uint32_t i = 0; i < g_maxTID; i++) {
124 if (tid == g_tidMapping[i])
125 return i;
126 }
127 // Don't yet have mapping, set it and return newly set index
128 uint32_t retVal = (uint32_t) g_maxTID;
129 g_tidMapping[g_maxTID++] = tid;
130 assert(g_maxTID < MAX_TID);
131 return retVal;
132}
133// Return a string representation of CMD_TYPE enum
134static string cmdTypeToString(CMD_TYPE cmd)
135{
136 switch (cmd)
137 {
138 case CMD_BINDPIPELINE:
139 return "CMD_BINDPIPELINE";
140 case CMD_BINDPIPELINEDELTA:
141 return "CMD_BINDPIPELINEDELTA";
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600142 case CMD_BINDDYNAMICVIEWPORTSTATE:
143 return "CMD_BINDDYNAMICVIEWPORTSTATE";
Cody Northropf5bd2252015-08-17 11:10:49 -0600144 case CMD_BINDDYNAMICRASTERLINESTATE:
145 return "CMD_BINDDYNAMICRASTERLINESTATE";
146 case CMD_BINDDYNAMICRASTERDEPTHBIASSTATE:
147 return "CMD_BINDDYNAMICRASTERDEPTHBIASSTATE";
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600148 case CMD_BINDDYNAMICCOLORBLENDSTATE:
149 return "CMD_BINDDYNAMICCOLORBLENDSTATE";
150 case CMD_BINDDYNAMICDEPTHSTENCILSTATE:
151 return "CMD_BINDDYNAMICDEPTHSTENCILSTATE";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600152 case CMD_BINDDESCRIPTORSETS:
153 return "CMD_BINDDESCRIPTORSETS";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600154 case CMD_BINDINDEXBUFFER:
155 return "CMD_BINDINDEXBUFFER";
156 case CMD_BINDVERTEXBUFFER:
157 return "CMD_BINDVERTEXBUFFER";
158 case CMD_DRAW:
159 return "CMD_DRAW";
160 case CMD_DRAWINDEXED:
161 return "CMD_DRAWINDEXED";
162 case CMD_DRAWINDIRECT:
163 return "CMD_DRAWINDIRECT";
164 case CMD_DRAWINDEXEDINDIRECT:
165 return "CMD_DRAWINDEXEDINDIRECT";
166 case CMD_DISPATCH:
167 return "CMD_DISPATCH";
168 case CMD_DISPATCHINDIRECT:
169 return "CMD_DISPATCHINDIRECT";
170 case CMD_COPYBUFFER:
171 return "CMD_COPYBUFFER";
172 case CMD_COPYIMAGE:
173 return "CMD_COPYIMAGE";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600174 case CMD_BLITIMAGE:
175 return "CMD_BLITIMAGE";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600176 case CMD_COPYBUFFERTOIMAGE:
177 return "CMD_COPYBUFFERTOIMAGE";
178 case CMD_COPYIMAGETOBUFFER:
179 return "CMD_COPYIMAGETOBUFFER";
180 case CMD_CLONEIMAGEDATA:
181 return "CMD_CLONEIMAGEDATA";
182 case CMD_UPDATEBUFFER:
183 return "CMD_UPDATEBUFFER";
184 case CMD_FILLBUFFER:
185 return "CMD_FILLBUFFER";
186 case CMD_CLEARCOLORIMAGE:
187 return "CMD_CLEARCOLORIMAGE";
Tobin Ehlis8cd650e2015-07-01 16:46:13 -0600188 case CMD_CLEARCOLORATTACHMENT:
189 return "CMD_CLEARCOLORATTACHMENT";
190 case CMD_CLEARDEPTHSTENCILIMAGE:
191 return "CMD_CLEARDEPTHSTENCILIMAGE";
192 case CMD_CLEARDEPTHSTENCILATTACHMENT:
193 return "CMD_CLEARDEPTHSTENCILATTACHMENT";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600194 case CMD_RESOLVEIMAGE:
195 return "CMD_RESOLVEIMAGE";
196 case CMD_SETEVENT:
197 return "CMD_SETEVENT";
198 case CMD_RESETEVENT:
199 return "CMD_RESETEVENT";
200 case CMD_WAITEVENTS:
201 return "CMD_WAITEVENTS";
202 case CMD_PIPELINEBARRIER:
203 return "CMD_PIPELINEBARRIER";
204 case CMD_BEGINQUERY:
205 return "CMD_BEGINQUERY";
206 case CMD_ENDQUERY:
207 return "CMD_ENDQUERY";
208 case CMD_RESETQUERYPOOL:
209 return "CMD_RESETQUERYPOOL";
210 case CMD_WRITETIMESTAMP:
211 return "CMD_WRITETIMESTAMP";
212 case CMD_INITATOMICCOUNTERS:
213 return "CMD_INITATOMICCOUNTERS";
214 case CMD_LOADATOMICCOUNTERS:
215 return "CMD_LOADATOMICCOUNTERS";
216 case CMD_SAVEATOMICCOUNTERS:
217 return "CMD_SAVEATOMICCOUNTERS";
218 case CMD_BEGINRENDERPASS:
219 return "CMD_BEGINRENDERPASS";
220 case CMD_ENDRENDERPASS:
221 return "CMD_ENDRENDERPASS";
222 case CMD_DBGMARKERBEGIN:
223 return "CMD_DBGMARKERBEGIN";
224 case CMD_DBGMARKEREND:
225 return "CMD_DBGMARKEREND";
226 default:
227 return "UNKNOWN";
228 }
229}
230// Block of code at start here for managing/tracking Pipeline state that this layer cares about
231// Just track 2 shaders for now
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600232#define VK_NUM_GRAPHICS_SHADERS VK_SHADER_STAGE_COMPUTE
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600233#define MAX_SLOTS 2048
234#define NUM_COMMAND_BUFFERS_TO_DISPLAY 10
235
236static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0};
237
238// TODO : Should be tracking lastBound per cmdBuffer and when draws occur, report based on that cmd buffer lastBound
239// Then need to synchronize the accesses based on cmd buffer so that if I'm reading state on one cmd buffer, updates
240// to that same cmd buffer by separate thread are not changing state from underneath us
241// Track the last cmd buffer touched by this thread
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600242static VkCmdBuffer g_lastCmdBuffer[MAX_TID] = {NULL};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600243// Track the last group of CBs touched for displaying to dot file
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600244static GLOBAL_CB_NODE* g_pLastTouchedCB[NUM_COMMAND_BUFFERS_TO_DISPLAY] = {NULL};
245static uint32_t g_lastTouchedCBIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600246// Track the last global DrawState of interest touched by any thread
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600247static GLOBAL_CB_NODE* g_lastGlobalCB = NULL;
248static PIPELINE_NODE* g_lastBoundPipeline = NULL;
249static uint64_t g_lastBoundDynamicState[VK_NUM_STATE_BIND_POINT] = {0};
Dana Jansens4a3e0862015-07-30 13:22:15 -0700250static VkDescriptorSet g_lastBoundDescriptorSet = VK_NULL_HANDLE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600251#define MAX_BINDING 0xFFFFFFFF // Default vtxBinding value in CB Node to identify if no vtxBinding set
252
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600253//static DYNAMIC_STATE_NODE* g_pDynamicStateHead[VK_NUM_STATE_BIND_POINT] = {0};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600254
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600255// Free all allocated nodes for Dynamic State objs
Tobin Ehliseaf28662015-04-08 10:58:37 -0600256static void deleteDynamicState()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600257{
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600258 for (auto ii=dynamicVpStateMap.begin(); ii!=dynamicVpStateMap.end(); ++ii) {
259 delete[] (*ii).second.pScissors;
260 delete[] (*ii).second.pViewports;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600261 }
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600262 dynamicVpStateMap.clear();
Cody Northropf5bd2252015-08-17 11:10:49 -0600263 dynamicRasterLineStateMap.clear();
264 dynamicRasterDepthBiasStateMap.clear();
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600265 dynamicCbStateMap.clear();
266 dynamicDsStateMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600267}
268// Free all sampler nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600269static void deleteSamplers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600270{
David Pinedof5997ab2015-04-27 16:36:17 -0600271 if (sampleMap.size() <= 0)
272 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600273 for (auto ii=sampleMap.begin(); ii!=sampleMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600274 delete (*ii).second;
275 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600276 sampleMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600277}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600278static VkImageViewCreateInfo* getImageViewCreateInfo(VkImageView view)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600279{
280 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600281 if (imageMap.find(view.handle) == imageMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600282 loader_platform_thread_unlock_mutex(&globalLock);
283 return NULL;
Tobin Ehlise42007c2015-06-19 13:00:59 -0600284 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600285 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600286 return &imageMap[view.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600287 }
288}
289// Free all image nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600290static void deleteImages()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600291{
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600292 if (imageMap.size() <= 0)
David Pinedof5997ab2015-04-27 16:36:17 -0600293 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600294 imageMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600295}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600296static VkBufferViewCreateInfo* getBufferViewCreateInfo(VkBufferView view)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600297{
298 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600299 if (bufferMap.find(view.handle) == bufferMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600300 loader_platform_thread_unlock_mutex(&globalLock);
301 return NULL;
Tobin Ehlise42007c2015-06-19 13:00:59 -0600302 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600303 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600304 return &bufferMap[view.handle]->createInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600305 }
306}
307// Free all buffer nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600308static void deleteBuffers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600309{
David Pinedof5997ab2015-04-27 16:36:17 -0600310 if (bufferMap.size() <= 0)
311 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600312 for (auto ii=bufferMap.begin(); ii!=bufferMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600313 delete (*ii).second;
314 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600315 bufferMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600316}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600317static GLOBAL_CB_NODE* getCBNode(VkCmdBuffer cb);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -0600318// Update global ptrs to reflect that specified cmdBuffer has been used
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600319static void updateCBTracking(VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600320{
321 g_lastCmdBuffer[getTIDIndex()] = cb;
322 GLOBAL_CB_NODE* pCB = getCBNode(cb);
323 loader_platform_thread_lock_mutex(&globalLock);
324 g_lastGlobalCB = pCB;
325 // TODO : This is a dumb algorithm. Need smart LRU that drops off oldest
326 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
327 if (g_pLastTouchedCB[i] == pCB) {
328 loader_platform_thread_unlock_mutex(&globalLock);
329 return;
330 }
331 }
332 g_pLastTouchedCB[g_lastTouchedCBIndex++] = pCB;
333 g_lastTouchedCBIndex = g_lastTouchedCBIndex % NUM_COMMAND_BUFFERS_TO_DISPLAY;
334 loader_platform_thread_unlock_mutex(&globalLock);
335}
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600336static VkBool32 hasDrawCmd(GLOBAL_CB_NODE* pCB)
Tobin Ehlis8cd650e2015-07-01 16:46:13 -0600337{
338 for (uint32_t i=0; i<NUM_DRAW_TYPES; i++) {
339 if (pCB->drawCount[i])
340 return VK_TRUE;
341 }
342 return VK_FALSE;
343}
Tobin Ehlis97866202015-06-10 12:57:07 -0600344// Check object status for selected flag state
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600345static VkBool32 validate_status(GLOBAL_CB_NODE* pNode, CBStatusFlags enable_mask, CBStatusFlags status_mask, CBStatusFlags status_flag, VkFlags msg_flags, DRAW_STATE_ERROR error_code, const char* fail_msg)
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600346{
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600347 // If non-zero enable mask is present, check it against status but if enable_mask
348 // is 0 then no enable required so we should always just check status
349 if ((!enable_mask) || (enable_mask & pNode->status)) {
350 if ((pNode->status & status_mask) != status_flag) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600351 // TODO : How to pass dispatchable objects as srcObject? Here src obj should be cmd buffer
352 log_msg(mdd(pNode->cmdBuffer), msg_flags, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, error_code, "DS",
353 "CB object %#" PRIxLEAST64 ": %s", reinterpret_cast<VkUintPtrLeast64>(pNode->cmdBuffer), fail_msg);
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600354 return VK_FALSE;
Tobin Ehlis97866202015-06-10 12:57:07 -0600355 }
Tobin Ehlis97866202015-06-10 12:57:07 -0600356 }
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600357 return VK_TRUE;
Tobin Ehlis97866202015-06-10 12:57:07 -0600358}
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600359// For given dynamic state handle and type, return CreateInfo for that Dynamic State
360static void* getDynamicStateCreateInfo(const uint64_t handle, const DYNAMIC_STATE_BIND_POINT type)
361{
362 switch (type) {
363 case VK_STATE_BIND_POINT_VIEWPORT:
364 return (void*)&dynamicVpStateMap[handle];
Cody Northropf5bd2252015-08-17 11:10:49 -0600365 case VK_STATE_BIND_POINT_RASTER_LINE:
366 return (void*)&dynamicRasterLineStateMap[handle];
367 case VK_STATE_BIND_POINT_RASTER_DEPTH_BIAS:
368 return (void*)&dynamicRasterDepthBiasStateMap[handle];
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600369 case VK_STATE_BIND_POINT_COLOR_BLEND:
370 return (void*)&dynamicCbStateMap[handle];
371 case VK_STATE_BIND_POINT_DEPTH_STENCIL:
372 return (void*)&dynamicDsStateMap[handle];
373 default:
374 return NULL;
375 }
376}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600377// Print the last bound dynamic state
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600378static void printDynamicState(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600379{
380 GLOBAL_CB_NODE* pCB = getCBNode(cb);
381 if (pCB) {
382 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600383 for (uint32_t i = 0; i < VK_NUM_STATE_BIND_POINT; i++) {
Mark Lobodzinski563d1bb2015-08-11 15:44:15 -0600384 if (pCB->lastBoundDynamicState[i]) {
385 void* pDynStateCI = getDynamicStateCreateInfo(pCB->lastBoundDynamicState[i], (DYNAMIC_STATE_BIND_POINT)i);
386 if (pDynStateCI) {
387 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, dynamicStateBindPointToObjType((DYNAMIC_STATE_BIND_POINT)i), pCB->lastBoundDynamicState[i], 0, DRAWSTATE_NONE, "DS",
388 "Reporting CreateInfo for currently bound %s object %#" PRIxLEAST64, string_DYNAMIC_STATE_BIND_POINT((DYNAMIC_STATE_BIND_POINT)i).c_str(), pCB->lastBoundDynamicState[i]);
389 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, dynamicStateBindPointToObjType((DYNAMIC_STATE_BIND_POINT)i), pCB->lastBoundDynamicState[i], 0, DRAWSTATE_NONE, "DS",
390 dynamic_display(pDynStateCI, " ").c_str());
391 } else {
392 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
393 "No dynamic state of type %s bound", string_DYNAMIC_STATE_BIND_POINT((DYNAMIC_STATE_BIND_POINT)i).c_str());
394 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600395 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600396 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
397 "No dynamic state of type %s bound", string_DYNAMIC_STATE_BIND_POINT((DYNAMIC_STATE_BIND_POINT)i).c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600398 }
399 }
400 loader_platform_thread_unlock_mutex(&globalLock);
401 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600402}
403// Retrieve pipeline node ptr for given pipeline object
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600404static PIPELINE_NODE* getPipeline(VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600405{
406 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600407 if (pipelineMap.find(pipeline.handle) == pipelineMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600408 loader_platform_thread_unlock_mutex(&globalLock);
409 return NULL;
410 }
411 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600412 return pipelineMap[pipeline.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600413}
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600414// Validate state stored as flags at time of draw call
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600415static VkBool32 validate_draw_state_flags(GLOBAL_CB_NODE* pCB, VkBool32 indexedDraw) {
416 VkBool32 result;
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600417 result = validate_status(pCB, CBSTATUS_NONE, CBSTATUS_VIEWPORT_BOUND, CBSTATUS_VIEWPORT_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Viewport object not bound to this command buffer");
Cody Northropf5bd2252015-08-17 11:10:49 -0600418 result &= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_RASTER_LINE_BOUND, CBSTATUS_RASTER_LINE_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_RASTER_LINE_NOT_BOUND, "Raster line object not bound to this command buffer");
419 result &= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_RASTER_DEPTH_BIAS_BOUND, CBSTATUS_RASTER_DEPTH_BIAS_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_RASTER_DEPTH_BIAS_NOT_BOUND, "Raster depth bias object not bound to this command buffer");
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600420 result &= validate_status(pCB, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_COLOR_BLEND_BOUND, CBSTATUS_COLOR_BLEND_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_COLOR_BLEND_NOT_BOUND, "Color-blend object not bound to this command buffer");
421 result &= validate_status(pCB, CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE, CBSTATUS_DEPTH_STENCIL_BOUND, CBSTATUS_DEPTH_STENCIL_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_STENCIL_NOT_BOUND, "Depth-stencil object not bound to this command buffer");
422 if (indexedDraw)
423 result &= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_INDEX_BUFFER_BOUND, CBSTATUS_INDEX_BUFFER_BOUND, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_INDEX_BUFFER_NOT_BOUND, "Index buffer object not bound to this command buffer when Index Draw attempted");
424 return result;
425}
426// Validate overall state at the time of a draw call
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600427static VkBool32 validate_draw_state(GLOBAL_CB_NODE* pCB, VkBool32 indexedDraw) {
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600428 // First check flag states
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600429 VkBool32 result = validate_draw_state_flags(pCB, indexedDraw);
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600430 PIPELINE_NODE* pPipe = getPipeline(pCB->lastBoundPipeline);
431 // Now complete other state checks
Tobin Ehlise4076782015-06-24 15:53:07 -0600432 if (pPipe && (pCB->lastBoundPipelineLayout != pPipe->graphicsPipelineCI.layout)) {
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600433 result = VK_FALSE;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600434 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE_LAYOUT, pCB->lastBoundPipelineLayout.handle, 0, DRAWSTATE_PIPELINE_LAYOUT_MISMATCH, "DS",
Mark Lobodzinskia98cf9b2015-08-04 10:54:43 -0600435 "Pipeline layout from last vkCmdBindDescriptorSets() (%#" PRIxLEAST64 ") does not match PSO Pipeline layout (%#" PRIxLEAST64 ") ", pCB->lastBoundPipelineLayout.handle, pPipe->graphicsPipelineCI.layout.handle);
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600436 }
Tobin Ehlis451efca2015-06-23 11:22:55 -0600437 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600438 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Tobin Ehlis451efca2015-06-23 11:22:55 -0600439 "Draw cmd issued without an active RenderPass. vkCmdDraw*() must only be called within a RenderPass.");
440 }
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600441 return result;
442}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600443// For given sampler, return a ptr to its Create Info struct, or NULL if sampler not found
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600444static VkSamplerCreateInfo* getSamplerCreateInfo(const VkSampler sampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600445{
446 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600447 if (sampleMap.find(sampler.handle) == sampleMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600448 loader_platform_thread_unlock_mutex(&globalLock);
449 return NULL;
450 }
451 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600452 return &sampleMap[sampler.handle]->createInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600453}
Tobin Ehlisde63c532015-06-18 15:59:33 -0600454// Verify that create state for a pipeline is valid
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600455static VkBool32 verifyPipelineCreateState(const VkDevice device, const PIPELINE_NODE* pPipeline)
Tobin Ehlisde63c532015-06-18 15:59:33 -0600456{
457 // VS is required
458 if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600459 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600460 "Invalid Pipeline CreateInfo State: Vtx Shader required");
461 return VK_FALSE;
462 }
463 // Either both or neither TC/TE shaders should be defined
464 if (((pPipeline->active_shaders & VK_SHADER_STAGE_TESS_CONTROL_BIT) == 0) !=
465 ((pPipeline->active_shaders & VK_SHADER_STAGE_TESS_EVALUATION_BIT) == 0) ) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600466 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600467 "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair");
468 return VK_FALSE;
469 }
470 // Compute shaders should be specified independent of Gfx shaders
471 if ((pPipeline->active_shaders & VK_SHADER_STAGE_COMPUTE_BIT) &&
472 (pPipeline->active_shaders & (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESS_CONTROL_BIT |
473 VK_SHADER_STAGE_TESS_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_BIT |
474 VK_SHADER_STAGE_FRAGMENT_BIT))) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600475 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600476 "Invalid Pipeline CreateInfo State: Do not specify Compute Shader for Gfx Pipeline");
477 return VK_FALSE;
478 }
479 // VK_PRIMITIVE_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
480 // Mismatching primitive topology and tessellation fails graphics pipeline creation.
481 if (pPipeline->active_shaders & (VK_SHADER_STAGE_TESS_CONTROL_BIT | VK_SHADER_STAGE_TESS_EVALUATION_BIT) &&
482 (pPipeline->iaStateCI.topology != VK_PRIMITIVE_TOPOLOGY_PATCH)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600483 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600484 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH must be set as IA topology for tessellation pipelines");
485 return VK_FALSE;
486 }
487 if ((pPipeline->iaStateCI.topology == VK_PRIMITIVE_TOPOLOGY_PATCH) &&
488 (~pPipeline->active_shaders & VK_SHADER_STAGE_TESS_CONTROL_BIT)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600489 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600490 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines");
491 return VK_FALSE;
492 }
493 return VK_TRUE;
494}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600495// Init the pipeline mapping info based on pipeline create info LL tree
496// Threading note : Calls to this function should wrapped in mutex
Tobin Ehlisde63c532015-06-18 15:59:33 -0600497static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, PIPELINE_NODE* pBasePipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600498{
Tobin Ehlisde63c532015-06-18 15:59:33 -0600499 PIPELINE_NODE* pPipeline = new PIPELINE_NODE;
500 if (pBasePipeline) {
501 memcpy((void*)pPipeline, (void*)pBasePipeline, sizeof(PIPELINE_NODE));
Tobin Ehlise42007c2015-06-19 13:00:59 -0600502 } else {
Tobin Ehlisde63c532015-06-18 15:59:33 -0600503 memset((void*)pPipeline, 0, sizeof(PIPELINE_NODE));
504 }
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600505 // First init create info
Tobin Ehlis2464b882015-04-01 08:40:34 -0600506 // TODO : Validate that no create info is incorrectly replicated
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600507 memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo));
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600508
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600509 size_t bufferSize = 0;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600510 const VkPipelineVertexInputStateCreateInfo* pVICI = NULL;
Tobin Ehlis59db5712015-07-13 13:14:24 -0600511 const VkPipelineColorBlendStateCreateInfo* pCBCI = NULL;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600512
513 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
514 const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
515
516 switch (pPSSCI->stage) {
517 case VK_SHADER_STAGE_VERTEX:
518 memcpy(&pPipeline->vsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
519 pPipeline->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600520 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600521 case VK_SHADER_STAGE_TESS_CONTROL:
522 memcpy(&pPipeline->tcsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
523 pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_CONTROL_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600524 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600525 case VK_SHADER_STAGE_TESS_EVALUATION:
526 memcpy(&pPipeline->tesCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
527 pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_EVALUATION_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600528 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600529 case VK_SHADER_STAGE_GEOMETRY:
530 memcpy(&pPipeline->gsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
531 pPipeline->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600532 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600533 case VK_SHADER_STAGE_FRAGMENT:
534 memcpy(&pPipeline->fsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
535 pPipeline->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600536 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600537 case VK_SHADER_STAGE_COMPUTE:
538 // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
539 pPipeline->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600540 break;
541 default:
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600542 // TODO : Flag error
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600543 break;
544 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600545 }
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600546
547 if (pCreateInfo->pVertexInputState != NULL) {
548 memcpy((void*)&pPipeline->vertexInputCI, pCreateInfo->pVertexInputState , sizeof(VkPipelineVertexInputStateCreateInfo));
549 // Copy embedded ptrs
550 pVICI = pCreateInfo->pVertexInputState;
551 pPipeline->vtxBindingCount = pVICI->bindingCount;
552 if (pPipeline->vtxBindingCount) {
553 pPipeline->pVertexBindingDescriptions = new VkVertexInputBindingDescription[pPipeline->vtxBindingCount];
554 bufferSize = pPipeline->vtxBindingCount * sizeof(VkVertexInputBindingDescription);
555 memcpy((void*)pPipeline->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions, bufferSize);
556 }
557 pPipeline->vtxAttributeCount = pVICI->attributeCount;
558 if (pPipeline->vtxAttributeCount) {
559 pPipeline->pVertexAttributeDescriptions = new VkVertexInputAttributeDescription[pPipeline->vtxAttributeCount];
560 bufferSize = pPipeline->vtxAttributeCount * sizeof(VkVertexInputAttributeDescription);
561 memcpy((void*)pPipeline->pVertexAttributeDescriptions, pVICI->pVertexAttributeDescriptions, bufferSize);
562 }
563 pPipeline->graphicsPipelineCI.pVertexInputState = &pPipeline->vertexInputCI;
564 }
Tony Barboure307f582015-07-10 15:29:03 -0600565 if (pCreateInfo->pInputAssemblyState != NULL) {
566 memcpy((void*)&pPipeline->iaStateCI, pCreateInfo->pInputAssemblyState, sizeof(VkPipelineInputAssemblyStateCreateInfo));
567 pPipeline->graphicsPipelineCI.pInputAssemblyState = &pPipeline->iaStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600568 }
Tony Barboure307f582015-07-10 15:29:03 -0600569 if (pCreateInfo->pTessellationState != NULL) {
570 memcpy((void*)&pPipeline->tessStateCI, pCreateInfo->pTessellationState, sizeof(VkPipelineTessellationStateCreateInfo));
571 pPipeline->graphicsPipelineCI.pTessellationState = &pPipeline->tessStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600572 }
Tony Barboure307f582015-07-10 15:29:03 -0600573 if (pCreateInfo->pViewportState != NULL) {
574 memcpy((void*)&pPipeline->vpStateCI, pCreateInfo->pViewportState, sizeof(VkPipelineViewportStateCreateInfo));
575 pPipeline->graphicsPipelineCI.pViewportState = &pPipeline->vpStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600576 }
Tony Barboure307f582015-07-10 15:29:03 -0600577 if (pCreateInfo->pRasterState != NULL) {
578 memcpy((void*)&pPipeline->rsStateCI, pCreateInfo->pRasterState, sizeof(VkPipelineRasterStateCreateInfo));
579 pPipeline->graphicsPipelineCI.pRasterState = &pPipeline->rsStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600580 }
Tony Barboure307f582015-07-10 15:29:03 -0600581 if (pCreateInfo->pMultisampleState != NULL) {
582 memcpy((void*)&pPipeline->msStateCI, pCreateInfo->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo));
583 pPipeline->graphicsPipelineCI.pMultisampleState = &pPipeline->msStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600584 }
Tony Barboure307f582015-07-10 15:29:03 -0600585 if (pCreateInfo->pColorBlendState != NULL) {
586 memcpy((void*)&pPipeline->cbStateCI, pCreateInfo->pColorBlendState, sizeof(VkPipelineColorBlendStateCreateInfo));
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600587 // Copy embedded ptrs
Tony Barboure307f582015-07-10 15:29:03 -0600588 pCBCI = pCreateInfo->pColorBlendState;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600589 pPipeline->attachmentCount = pCBCI->attachmentCount;
590 if (pPipeline->attachmentCount) {
Tony Barboure307f582015-07-10 15:29:03 -0600591 pPipeline->pAttachments = new VkPipelineColorBlendAttachmentState[pPipeline->attachmentCount];
592 bufferSize = pPipeline->attachmentCount * sizeof(VkPipelineColorBlendAttachmentState);
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600593 memcpy((void*)pPipeline->pAttachments, pCBCI->pAttachments, bufferSize);
594 }
Tony Barboure307f582015-07-10 15:29:03 -0600595 pPipeline->graphicsPipelineCI.pColorBlendState = &pPipeline->cbStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600596 }
Tony Barboure307f582015-07-10 15:29:03 -0600597 if (pCreateInfo->pDepthStencilState != NULL) {
598 memcpy((void*)&pPipeline->dsStateCI, pCreateInfo->pDepthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo));
599 pPipeline->graphicsPipelineCI.pDepthStencilState = &pPipeline->dsStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600600 }
601
602 // Copy over GraphicsPipelineCreateInfo structure embedded pointers
603 if (pCreateInfo->stageCount != 0) {
604 pPipeline->graphicsPipelineCI.pStages = new VkPipelineShaderStageCreateInfo[pCreateInfo->stageCount];
605 bufferSize = pCreateInfo->stageCount * sizeof(VkPipelineShaderStageCreateInfo);
606 memcpy((void*)pPipeline->graphicsPipelineCI.pStages, pCreateInfo->pStages, bufferSize);
607 }
608
Tobin Ehlisde63c532015-06-18 15:59:33 -0600609 return pPipeline;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600610}
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600611
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600612// Free the Pipeline nodes
Tobin Ehliseaf28662015-04-08 10:58:37 -0600613static void deletePipelines()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600614{
David Pinedof5997ab2015-04-27 16:36:17 -0600615 if (pipelineMap.size() <= 0)
616 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600617 for (auto ii=pipelineMap.begin(); ii!=pipelineMap.end(); ++ii) {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600618 if ((*ii).second->graphicsPipelineCI.stageCount != 0) {
619 delete[] (*ii).second->graphicsPipelineCI.pStages;
620 }
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600621 if ((*ii).second->pVertexBindingDescriptions) {
622 delete[] (*ii).second->pVertexBindingDescriptions;
623 }
624 if ((*ii).second->pVertexAttributeDescriptions) {
625 delete[] (*ii).second->pVertexAttributeDescriptions;
626 }
627 if ((*ii).second->pAttachments) {
628 delete[] (*ii).second->pAttachments;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600629 }
630 delete (*ii).second;
631 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -0600632 pipelineMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600633}
Tobin Ehlis2464b882015-04-01 08:40:34 -0600634// For given pipeline, return number of MSAA samples, or one if MSAA disabled
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600635static uint32_t getNumSamples(const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600636{
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600637 PIPELINE_NODE* pPipe = pipelineMap[pipeline.handle];
Tobin Ehlisb3a506f2015-07-13 14:51:15 -0600638 if (VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pPipe->msStateCI.sType) {
639 return pPipe->msStateCI.rasterSamples;
640 }
Tobin Ehlis2464b882015-04-01 08:40:34 -0600641 return 1;
642}
643// Validate state related to the PSO
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600644static void validatePipelineState(const GLOBAL_CB_NODE* pCB, const VkPipelineBindPoint pipelineBindPoint, const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600645{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600646 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
Tobin Ehlis2464b882015-04-01 08:40:34 -0600647 // Verify that any MSAA request in PSO matches sample# in bound FB
648 uint32_t psoNumSamples = getNumSamples(pipeline);
649 if (pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600650 const VkRenderPassCreateInfo* pRPCI = renderPassMap[pCB->activeRenderPass.handle];
Chia-I Wuc278df82015-07-07 11:50:03 +0800651 const VkSubpassDescription* pSD = &pRPCI->pSubpasses[pCB->activeSubpass];
652 int subpassNumSamples = 0;
653 uint32_t i;
654
655 for (i = 0; i < pSD->colorCount; i++) {
656 uint32_t samples;
657
Cody Northrop6de6b0b2015-08-04 11:16:41 -0600658 if (pSD->pColorAttachments[i].attachment == VK_ATTACHMENT_UNUSED)
Chia-I Wuc278df82015-07-07 11:50:03 +0800659 continue;
660
Cody Northrop6de6b0b2015-08-04 11:16:41 -0600661 samples = pRPCI->pAttachments[pSD->pColorAttachments[i].attachment].samples;
Chia-I Wuc278df82015-07-07 11:50:03 +0800662 if (subpassNumSamples == 0) {
663 subpassNumSamples = samples;
664 } else if (subpassNumSamples != samples) {
665 subpassNumSamples = -1;
666 break;
667 }
668 }
669 if (pSD->depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
670 const uint32_t samples = pRPCI->pAttachments[pSD->depthStencilAttachment.attachment].samples;
671 if (subpassNumSamples == 0)
672 subpassNumSamples = samples;
673 else if (subpassNumSamples != samples)
674 subpassNumSamples = -1;
675 }
676
677 if (psoNumSamples != subpassNumSamples) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600678 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
679 "Num samples mismatch! Binding PSO (%#" PRIxLEAST64 ") with %u samples while current RenderPass (%#" PRIxLEAST64 ") w/ %u samples!", pipeline.handle, psoNumSamples, pCB->activeRenderPass.handle, subpassNumSamples);
Tobin Ehlis2464b882015-04-01 08:40:34 -0600680 }
681 } else {
682 // TODO : I believe it's an error if we reach this point and don't have an activeRenderPass
683 // Verify and flag error as appropriate
684 }
685 // TODO : Add more checks here
686 } else {
687 // TODO : Validate non-gfx pipeline updates
688 }
689}
690
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600691// Block of code at start here specifically for managing/tracking DSs
692
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600693// Return Pool node ptr for specified pool or else NULL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600694static POOL_NODE* getPoolNode(VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600695{
696 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600697 if (poolMap.find(pool.handle) == poolMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600698 loader_platform_thread_unlock_mutex(&globalLock);
699 return NULL;
700 }
701 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600702 return poolMap[pool.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600703}
704// Return Set node ptr for specified set or else NULL
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600705static SET_NODE* getSetNode(VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600706{
707 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600708 if (setMap.find(set.handle) == setMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600709 loader_platform_thread_unlock_mutex(&globalLock);
710 return NULL;
711 }
712 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600713 return setMap[set.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600714}
715
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600716static LAYOUT_NODE* getLayoutNode(const VkDescriptorSetLayout layout) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600717 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600718 if (layoutMap.find(layout.handle) == layoutMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600719 loader_platform_thread_unlock_mutex(&globalLock);
720 return NULL;
721 }
722 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600723 return layoutMap[layout.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600724}
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600725// Return 1 if update struct is of valid type, 0 otherwise
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600726static VkBool32 validUpdateStruct(const VkDevice device, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600727{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600728 switch (pUpdateStruct->sType)
729 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800730 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
731 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600732 return 1;
733 default:
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600734 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600735 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600736 return 0;
737 }
738}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600739// For given update struct, return binding
Tobin Ehlisde63c532015-06-18 15:59:33 -0600740static uint32_t getUpdateBinding(const VkDevice device, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600741{
742 switch (pUpdateStruct->sType)
743 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800744 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
745 return ((VkWriteDescriptorSet*)pUpdateStruct)->destBinding;
746 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
747 return ((VkCopyDescriptorSet*)pUpdateStruct)->destBinding;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600748 default:
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600749 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600750 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600751 return 0xFFFFFFFF;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600752 }
753}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600754// Return count for given update struct
Tobin Ehlisde63c532015-06-18 15:59:33 -0600755static uint32_t getUpdateArrayIndex(const VkDevice device, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600756{
757 switch (pUpdateStruct->sType)
758 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800759 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
760 return ((VkWriteDescriptorSet*)pUpdateStruct)->destArrayElement;
761 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600762 // TODO : Need to understand this case better and make sure code is correct
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800763 return ((VkCopyDescriptorSet*)pUpdateStruct)->destArrayElement;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600764 default:
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600765 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600766 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600767 return 0;
768 }
769}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600770// Return count for given update struct
Tobin Ehlisde63c532015-06-18 15:59:33 -0600771static uint32_t getUpdateCount(const VkDevice device, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600772{
773 switch (pUpdateStruct->sType)
774 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800775 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
776 return ((VkWriteDescriptorSet*)pUpdateStruct)->count;
777 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600778 // TODO : Need to understand this case better and make sure code is correct
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800779 return ((VkCopyDescriptorSet*)pUpdateStruct)->count;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600780 default:
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600781 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600782 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600783 return 0;
784 }
785}
786// For given Layout Node and binding, return index where that binding begins
787static uint32_t getBindingStartIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
788{
789 uint32_t offsetIndex = 0;
790 for (uint32_t i = 0; i<binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800791 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600792 }
793 return offsetIndex;
794}
795// For given layout node and binding, return last index that is updated
796static uint32_t getBindingEndIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
797{
798 uint32_t offsetIndex = 0;
799 for (uint32_t i = 0; i<=binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800800 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600801 }
802 return offsetIndex-1;
803}
804// For given layout and update, return the first overall index of the layout that is update
Tobin Ehlisde63c532015-06-18 15:59:33 -0600805static uint32_t getUpdateStartIndex(const VkDevice device, const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600806{
Tobin Ehlisde63c532015-06-18 15:59:33 -0600807 return (getBindingStartIndex(pLayout, getUpdateBinding(device, pUpdateStruct))+getUpdateArrayIndex(device, pUpdateStruct));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600808}
809// For given layout and update, return the last overall index of the layout that is update
Tobin Ehlisde63c532015-06-18 15:59:33 -0600810static uint32_t getUpdateEndIndex(const VkDevice device, const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600811{
Tobin Ehlisde63c532015-06-18 15:59:33 -0600812 return (getBindingStartIndex(pLayout, getUpdateBinding(device, pUpdateStruct))+getUpdateArrayIndex(device, pUpdateStruct)+getUpdateCount(device, pUpdateStruct)-1);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600813}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600814// Verify that the descriptor type in the update struct matches what's expected by the layout
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600815static VkBool32 validateUpdateType(const VkDevice device, const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600816{
817 // First get actual type of update
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600818 VkDescriptorType actualType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600819 uint32_t i = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600820 switch (pUpdateStruct->sType)
821 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800822 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
823 actualType = ((VkWriteDescriptorSet*)pUpdateStruct)->descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600824 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800825 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
826 /* no need to validate */
827 return 1;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600828 break;
829 default:
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600830 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600831 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600832 return 0;
833 }
Tobin Ehlisde63c532015-06-18 15:59:33 -0600834 for (i = getUpdateStartIndex(device, pLayout, pUpdateStruct); i <= getUpdateEndIndex(device, pLayout, pUpdateStruct); i++) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600835 if (pLayout->pTypes[i] != actualType)
836 return 0;
837 }
838 return 1;
839}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600840// Determine the update type, allocate a new struct of that type, shadow the given pUpdate
841// struct into the new struct and return ptr to shadow struct cast as GENERIC_HEADER
842// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisde63c532015-06-18 15:59:33 -0600843static GENERIC_HEADER* shadowUpdateNode(const VkDevice device, GENERIC_HEADER* pUpdate)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600844{
845 GENERIC_HEADER* pNewNode = NULL;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800846 VkWriteDescriptorSet* pWDS = NULL;
847 VkCopyDescriptorSet* pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600848 size_t array_size = 0;
849 size_t base_array_size = 0;
850 size_t total_array_size = 0;
851 size_t baseBuffAddr = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600852 switch (pUpdate->sType)
853 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800854 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
855 pWDS = new VkWriteDescriptorSet;
856 pNewNode = (GENERIC_HEADER*)pWDS;
857 memcpy(pWDS, pUpdate, sizeof(VkWriteDescriptorSet));
858 pWDS->pDescriptors = new VkDescriptorInfo[pWDS->count];
859 array_size = sizeof(VkDescriptorInfo) * pWDS->count;
860 memcpy((void*)pWDS->pDescriptors, ((VkWriteDescriptorSet*)pUpdate)->pDescriptors, array_size);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600861 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800862 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
863 pCDS = new VkCopyDescriptorSet;
864 pUpdate = (GENERIC_HEADER*)pCDS;
865 memcpy(pCDS, pUpdate, sizeof(VkCopyDescriptorSet));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600866 break;
867 default:
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600868 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600869 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdate->sType), pUpdate->sType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600870 return NULL;
871 }
872 // Make sure that pNext for the end of shadow copy is NULL
873 pNewNode->pNext = NULL;
874 return pNewNode;
875}
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800876// update DS mappings based on ppUpdateArray
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600877static VkBool32 dsUpdate(VkDevice device, VkStructureType type, uint32_t updateCount, const void* pUpdateArray)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600878{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800879 const VkWriteDescriptorSet *pWDS = NULL;
880 const VkCopyDescriptorSet *pCDS = NULL;
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600881 VkBool32 result = 1;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800882
883 if (type == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
884 pWDS = (const VkWriteDescriptorSet *) pUpdateArray;
885 else
886 pCDS = (const VkCopyDescriptorSet *) pUpdateArray;
887
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600888 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600889 LAYOUT_NODE* pLayout = NULL;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600890 VkDescriptorSetLayoutCreateInfo* pLayoutCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600891 // TODO : If pCIList is NULL, flag error
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600892 // Perform all updates
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600893 for (uint32_t i = 0; i < updateCount; i++) {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800894 VkDescriptorSet ds = (pWDS) ? pWDS->destSet : pCDS->destSet;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600895 SET_NODE* pSet = setMap[ds.handle]; // getSetNode() without locking
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800896 g_lastBoundDescriptorSet = pSet->set;
897 GENERIC_HEADER* pUpdate = (pWDS) ? (GENERIC_HEADER*) &pWDS[i] : (GENERIC_HEADER*) &pCDS[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600898 pLayout = pSet->pLayout;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600899 // First verify valid update struct
Tobin Ehlisde63c532015-06-18 15:59:33 -0600900 if (!validUpdateStruct(device, pUpdate)) {
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600901 result = 0;
902 break;
903 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600904 // Make sure that binding is within bounds
Tobin Ehlisde63c532015-06-18 15:59:33 -0600905 if (pLayout->createInfo.count < getUpdateBinding(device, pUpdate)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600906 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds.handle, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600907 "Descriptor Set %p does not have binding to match update binding %u for update type %s!", ds, getUpdateBinding(device, pUpdate), string_VkStructureType(pUpdate->sType));
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600908 result = 0;
Tobin Ehlise42007c2015-06-19 13:00:59 -0600909 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600910 // Next verify that update falls within size of given binding
Tobin Ehlisde63c532015-06-18 15:59:33 -0600911 if (getBindingEndIndex(pLayout, getUpdateBinding(device, pUpdate)) < getUpdateEndIndex(device, pLayout, pUpdate)) {
Tony Barbour29b12062015-07-13 13:37:24 -0600912 // TODO : Keep count of layout CI structs and size this string dynamically based on that count
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600913 pLayoutCI = &pLayout->createInfo;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600914 string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo(pLayoutCI, "{DS} ");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600915 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds.handle, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600916 "Descriptor update type of %s is out of bounds for matching binding %u in Layout w/ CI:\n%s!", string_VkStructureType(pUpdate->sType), getUpdateBinding(device, pUpdate), DSstr.c_str());
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600917 result = 0;
Tobin Ehlise42007c2015-06-19 13:00:59 -0600918 } else { // TODO : should we skip update on a type mismatch or force it?
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600919 // Layout bindings match w/ update ok, now verify that update is of the right type
Tobin Ehlisde63c532015-06-18 15:59:33 -0600920 if (!validateUpdateType(device, pLayout, pUpdate)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600921 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds.handle, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600922 "Descriptor update type of %s does not match overlapping binding type!", string_VkStructureType(pUpdate->sType));
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600923 result = 0;
Tobin Ehlise42007c2015-06-19 13:00:59 -0600924 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600925 // Save the update info
926 // TODO : Info message that update successful
927 // Create new update struct for this set's shadow copy
Tobin Ehlisde63c532015-06-18 15:59:33 -0600928 GENERIC_HEADER* pNewNode = shadowUpdateNode(device, pUpdate);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600929 if (NULL == pNewNode) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600930 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds.handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600931 "Out of memory while attempting to allocate UPDATE struct in vkUpdateDescriptors()");
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600932 result = 0;
Tobin Ehlise42007c2015-06-19 13:00:59 -0600933 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600934 // Insert shadow node into LL of updates for this set
935 pNewNode->pNext = pSet->pUpdateStructs;
936 pSet->pUpdateStructs = pNewNode;
937 // Now update appropriate descriptor(s) to point to new Update node
Tobin Ehlisde63c532015-06-18 15:59:33 -0600938 for (uint32_t j = getUpdateStartIndex(device, pLayout, pUpdate); j <= getUpdateEndIndex(device, pLayout, pUpdate); j++) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600939 assert(j<pSet->descriptorCount);
940 pSet->ppDescriptors[j] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600941 }
942 }
943 }
944 }
945 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600946 }
947 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600948 return result;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600949}
950// Free the shadowed update node for this Set
951// NOTE : Calls to this function should be wrapped in mutex
952static void freeShadowUpdateTree(SET_NODE* pSet)
953{
954 GENERIC_HEADER* pShadowUpdate = pSet->pUpdateStructs;
955 pSet->pUpdateStructs = NULL;
956 GENERIC_HEADER* pFreeUpdate = pShadowUpdate;
957 // Clear the descriptor mappings as they will now be invalid
958 memset(pSet->ppDescriptors, 0, pSet->descriptorCount*sizeof(GENERIC_HEADER*));
959 while(pShadowUpdate) {
960 pFreeUpdate = pShadowUpdate;
961 pShadowUpdate = (GENERIC_HEADER*)pShadowUpdate->pNext;
962 uint32_t index = 0;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800963 VkWriteDescriptorSet * pWDS = NULL;
964 VkCopyDescriptorSet * pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600965 void** ppToFree = NULL;
966 switch (pFreeUpdate->sType)
967 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800968 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
969 pWDS = (VkWriteDescriptorSet*)pFreeUpdate;
970 if (pWDS->pDescriptors)
971 delete[] pWDS->pDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600972 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800973 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600974 break;
975 default:
976 assert(0);
977 break;
978 }
Tobin Ehliseaf28662015-04-08 10:58:37 -0600979 delete pFreeUpdate;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600980 }
981}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600982// Free all DS Pools including their Sets & related sub-structs
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600983// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -0600984static void deletePools()
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600985{
David Pinedof5997ab2015-04-27 16:36:17 -0600986 if (poolMap.size() <= 0)
987 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600988 for (auto ii=poolMap.begin(); ii!=poolMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600989 SET_NODE* pSet = (*ii).second->pSets;
990 SET_NODE* pFreeSet = pSet;
991 while (pSet) {
992 pFreeSet = pSet;
993 pSet = pSet->pNext;
Tobin Ehliseaf28662015-04-08 10:58:37 -0600994 // Freeing layouts handled in deleteLayouts() function
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600995 // Free Update shadow struct tree
996 freeShadowUpdateTree(pFreeSet);
997 if (pFreeSet->ppDescriptors) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200998 delete[] pFreeSet->ppDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600999 }
1000 delete pFreeSet;
1001 }
1002 if ((*ii).second->createInfo.pTypeCount) {
Chris Forbes4506d3f2015-06-04 10:49:27 +12001003 delete[] (*ii).second->createInfo.pTypeCount;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001004 }
1005 delete (*ii).second;
1006 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -06001007 poolMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001008}
Tobin Ehliseaf28662015-04-08 10:58:37 -06001009// WARN : Once deleteLayouts() called, any layout ptrs in Pool/Set data structure will be invalid
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001010// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -06001011static void deleteLayouts()
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001012{
David Pinedof5997ab2015-04-27 16:36:17 -06001013 if (layoutMap.size() <= 0)
1014 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001015 for (auto ii=layoutMap.begin(); ii!=layoutMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001016 LAYOUT_NODE* pLayout = (*ii).second;
Tobin Ehliseaf28662015-04-08 10:58:37 -06001017 if (pLayout->createInfo.pBinding) {
1018 for (uint32_t i=0; i<pLayout->createInfo.count; i++) {
1019 if (pLayout->createInfo.pBinding[i].pImmutableSamplers)
1020 delete[] pLayout->createInfo.pBinding[i].pImmutableSamplers;
1021 }
1022 delete[] pLayout->createInfo.pBinding;
1023 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001024 if (pLayout->pTypes) {
Chris Forbes4506d3f2015-06-04 10:49:27 +12001025 delete[] pLayout->pTypes;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001026 }
1027 delete pLayout;
1028 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -06001029 layoutMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001030}
1031// Currently clearing a set is removing all previous updates to that set
1032// TODO : Validate if this is correct clearing behavior
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001033static void clearDescriptorSet(VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001034{
1035 SET_NODE* pSet = getSetNode(set);
1036 if (!pSet) {
1037 // TODO : Return error
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001038 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001039 loader_platform_thread_lock_mutex(&globalLock);
1040 freeShadowUpdateTree(pSet);
1041 loader_platform_thread_unlock_mutex(&globalLock);
1042 }
1043}
1044
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001045static void clearDescriptorPool(VkDevice device, VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001046{
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001047 POOL_NODE* pPool = getPoolNode(pool);
1048 if (!pPool) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001049 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, pool.handle, 0, DRAWSTATE_INVALID_POOL, "DS",
1050 "Unable to find pool node for pool %#" PRIxLEAST64 " specified in vkResetDescriptorPool() call", pool.handle);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001051 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001052 // For every set off of this pool, clear it
1053 SET_NODE* pSet = pPool->pSets;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001054 while (pSet) {
1055 clearDescriptorSet(pSet->set);
1056 }
1057 }
1058}
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001059// For given CB object, fetch associated CB Node from map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001060static GLOBAL_CB_NODE* getCBNode(VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001061{
1062 loader_platform_thread_lock_mutex(&globalLock);
1063 if (cmdBufferMap.find(cb) == cmdBufferMap.end()) {
1064 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001065 // TODO : How to pass cb as srcObj here?
1066 log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS",
1067 "Attempt to use CmdBuffer %#" PRIxLEAST64 " that doesn't exist!", reinterpret_cast<VkUintPtrLeast64>(cb));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001068 return NULL;
1069 }
1070 loader_platform_thread_unlock_mutex(&globalLock);
1071 return cmdBufferMap[cb];
1072}
1073// Free all CB Nodes
1074// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehliseaf28662015-04-08 10:58:37 -06001075static void deleteCmdBuffers()
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001076{
David Pinedof5997ab2015-04-27 16:36:17 -06001077 if (cmdBufferMap.size() <= 0)
1078 return;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001079 for (auto ii=cmdBufferMap.begin(); ii!=cmdBufferMap.end(); ++ii) {
Courtney Goeltzenleuchter09098a72015-04-27 15:04:43 -06001080 vector<CMD_NODE*> cmd_node_list = (*ii).second->pCmds;
1081 while (!cmd_node_list.empty()) {
1082 CMD_NODE* cmd_node = cmd_node_list.back();
1083 delete cmd_node;
1084 cmd_node_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001085 }
1086 delete (*ii).second;
1087 }
Jon Ashburnd0cb7cd2015-06-15 10:58:28 -06001088 cmdBufferMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001089}
Tobin Ehlise42007c2015-06-19 13:00:59 -06001090static void report_error_no_cb_begin(const VkCmdBuffer cb, const char* caller_name)
1091{
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001092 // TODO : How to pass cb as srcObj here?
1093 log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NO_BEGIN_CMD_BUFFER, "DS",
Tobin Ehlise42007c2015-06-19 13:00:59 -06001094 "You must call vkBeginCommandBuffer() before this call to %s", (void*)caller_name);
1095}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001096static void addCmd(GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
1097{
1098 CMD_NODE* pCmd = new CMD_NODE;
1099 if (pCmd) {
1100 // init cmd node and append to end of cmd LL
1101 memset(pCmd, 0, sizeof(CMD_NODE));
1102 pCmd->cmdNumber = ++pCB->numCmds;
1103 pCmd->type = cmd;
1104 pCB->pCmds.push_back(pCmd);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001105 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001106 // TODO : How to pass cb as srcObj here?
1107 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
1108 "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %#" PRIxLEAST64, reinterpret_cast<VkUintPtrLeast64>(pCB->cmdBuffer));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001109 }
1110}
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001111static void resetCB(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001112{
1113 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1114 if (pCB) {
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001115 vector<CMD_NODE*> cmd_list = pCB->pCmds;
1116 while (!cmd_list.empty()) {
1117 delete cmd_list.back();
1118 cmd_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001119 }
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001120 pCB->pCmds.clear();
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001121 // Reset CB state (need to save createInfo)
1122 VkCmdBufferCreateInfo saveCBCI = pCB->createInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001123 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1124 pCB->cmdBuffer = cb;
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001125 pCB->createInfo = saveCBCI;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001126 pCB->lastVtxBinding = MAX_BINDING;
1127 }
1128}
Tobin Ehlis97866202015-06-10 12:57:07 -06001129// Set PSO-related status bits for CB
1130static void set_cb_pso_status(GLOBAL_CB_NODE* pCB, const PIPELINE_NODE* pPipe)
1131{
1132 for (uint32_t i = 0; i < pPipe->cbStateCI.attachmentCount; i++) {
1133 if (0 != pPipe->pAttachments[i].channelWriteMask) {
1134 pCB->status |= CBSTATUS_COLOR_BLEND_WRITE_ENABLE;
1135 }
1136 }
1137 if (pPipe->dsStateCI.depthWriteEnable) {
1138 pCB->status |= CBSTATUS_DEPTH_STENCIL_WRITE_ENABLE;
1139 }
1140}
1141// Set dyn-state related status bits for an object node
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001142static void set_cb_dyn_status(GLOBAL_CB_NODE* pNode, DYNAMIC_STATE_BIND_POINT stateBindPoint) {
Tobin Ehlis97866202015-06-10 12:57:07 -06001143 if (stateBindPoint == VK_STATE_BIND_POINT_VIEWPORT) {
1144 pNode->status |= CBSTATUS_VIEWPORT_BOUND;
Cody Northropf5bd2252015-08-17 11:10:49 -06001145 } else if (stateBindPoint == VK_STATE_BIND_POINT_RASTER_LINE) {
1146 pNode->status |= CBSTATUS_RASTER_LINE_BOUND;
1147 } else if (stateBindPoint == VK_STATE_BIND_POINT_RASTER_DEPTH_BIAS) {
1148 pNode->status |= CBSTATUS_RASTER_DEPTH_BIAS_BOUND;
Tobin Ehlis97866202015-06-10 12:57:07 -06001149 } else if (stateBindPoint == VK_STATE_BIND_POINT_COLOR_BLEND) {
1150 pNode->status |= CBSTATUS_COLOR_BLEND_BOUND;
1151 } else if (stateBindPoint == VK_STATE_BIND_POINT_DEPTH_STENCIL) {
1152 pNode->status |= CBSTATUS_DEPTH_STENCIL_BOUND;
1153 }
1154}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001155// Print the last bound Gfx Pipeline
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001156static void printPipeline(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001157{
1158 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1159 if (pCB) {
1160 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
1161 if (!pPipeTrav) {
1162 // nothing to print
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001163 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001164 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001165 vk_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001166 }
1167 }
1168}
Tobin Ehlise90b1712015-05-27 14:30:06 -06001169// Verify bound Pipeline State Object
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001170static bool validateBoundPipeline(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001171{
1172 GLOBAL_CB_NODE* pCB = getCBNode(cb);
1173 if (pCB && pCB->lastBoundPipeline) {
1174 // First verify that we have a Node for bound pipeline
1175 PIPELINE_NODE *pPipeTrav = getPipeline(pCB->lastBoundPipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001176 if (!pPipeTrav) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001177 log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_PIPELINE_BOUND, "DS",
1178 "Can't find last bound Pipeline %#" PRIxLEAST64 "!", pCB->lastBoundPipeline.handle);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001179 return false;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001180 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001181 // Verify Vtx binding
1182 if (MAX_BINDING != pCB->lastVtxBinding) {
1183 if (pCB->lastVtxBinding >= pPipeTrav->vtxBindingCount) {
1184 if (0 == pPipeTrav->vtxBindingCount) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001185 log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001186 "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001187 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001188 }
1189 else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001190 log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001191 "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipeTrav->vtxBindingCount - 1));
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001192 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001193 }
1194 }
1195 else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001196 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001197 vk_print_vkvertexinputbindingdescription(&pPipeTrav->pVertexBindingDescriptions[pCB->lastVtxBinding], "{DS}INFO : ").c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001198 }
1199 }
1200 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001201 return true;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001202 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06001203 return false;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001204}
1205// Print details of DS config to stdout
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001206static void printDSConfig(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001207{
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001208 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.
1209 GLOBAL_CB_NODE* pCB = getCBNode(cb);
Tobin Ehlis7297f192015-06-09 08:39:32 -06001210 if (pCB && pCB->lastBoundDescriptorSet) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001211 SET_NODE* pSet = getSetNode(pCB->lastBoundDescriptorSet);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001212 POOL_NODE* pPool = getPoolNode(pSet->pool);
1213 // Print out pool details
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001214 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
1215 "Details for pool %#" PRIxLEAST64 ".", pPool->pool.handle);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001216 string poolStr = vk_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, " ");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001217 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001218 "%s", poolStr.c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001219 // Print out set details
1220 char prefix[10];
1221 uint32_t index = 0;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001222 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
1223 "Details for descriptor set %#" PRIxLEAST64 ".", pSet->set.handle);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001224 LAYOUT_NODE* pLayout = pSet->pLayout;
1225 // Print layout details
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001226 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
1227 "Layout #%u, (object %#" PRIxLEAST64 ") for DS %#" PRIxLEAST64 ".", index+1, (void*)pLayout->layout.handle, (void*)pSet->set.handle);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001228 sprintf(prefix, " [L%u] ", index);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001229 string DSLstr = vk_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, prefix).c_str();
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001230 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001231 "%s", DSLstr.c_str());
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001232 index++;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001233 GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
1234 if (pUpdate) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001235 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
1236 "Update Chain [UC] for descriptor set %#" PRIxLEAST64 ":", pSet->set.handle);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001237 sprintf(prefix, " [UC] ");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001238 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001239 dynamic_display(pUpdate, prefix).c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001240 // TODO : If there is a "view" associated with this update, print CI for that view
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001241 } else {
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001242 if (0 != pSet->descriptorCount) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001243 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
1244 "No Update Chain for descriptor set %#" PRIxLEAST64 " which has %u descriptors (vkUpdateDescriptors has not been called)", pSet->set.handle, pSet->descriptorCount);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001245 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001246 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
1247 "FYI: No descriptors in descriptor set %#" PRIxLEAST64 ".", pSet->set.handle);
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001248 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001249 }
1250 }
1251}
1252
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001253static void printCB(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001254{
1255 GLOBAL_CB_NODE* pCB = getCBNode(cb);
David Pinedof5997ab2015-04-27 16:36:17 -06001256 if (pCB && pCB->pCmds.size() > 0) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001257 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001258 "Cmds in CB %p", (void*)cb);
Courtney Goeltzenleuchtercf2a5362015-04-27 11:16:35 -06001259 vector<CMD_NODE*> pCmds = pCB->pCmds;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001260 for (auto ii=pCmds.begin(); ii!=pCmds.end(); ++ii) {
1261 // TODO : Need to pass cb as srcObj here
1262 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001263 " CMD#%lu: %s", (*ii)->cmdNumber, cmdTypeToString((*ii)->type).c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001264 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001265 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001266 // Nothing to print
1267 }
1268}
1269
1270
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001271static void synchAndPrintDSConfig(const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001272{
Mike Stroyanfa2f2222015-08-12 17:11:28 -06001273 if (!(mdd(cb)->active_flags & VK_DBG_REPORT_INFO_BIT)) {
1274 return;
1275 }
Mark Lobodzinskifdb20cf2015-08-07 17:11:09 -06001276 printDSConfig(cb);
1277 printPipeline(cb);
1278 printDynamicState(cb);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001279}
1280
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001281static void init_draw_state(layer_data *my_data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001282{
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001283 uint32_t report_flags = 0;
1284 uint32_t debug_action = 0;
1285 FILE *log_output = NULL;
1286 const char *option_str;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001287 // initialize DrawState options
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001288 report_flags = getLayerOptionFlags("DrawStateReportFlags", 0);
1289 getLayerOptionEnum("DrawStateDebugAction", (uint32_t *) &debug_action);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001290
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001291 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001292 {
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001293 option_str = getLayerOption("DrawStateLogFilename");
1294 if (option_str)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001295 {
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001296 log_output = fopen(option_str, "w");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001297 }
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001298 if (log_output == NULL)
1299 log_output = stdout;
1300
1301 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001302 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001303
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001304 if (!globalLockInitialized)
1305 {
1306 // TODO/TBD: Need to delete this mutex sometime. How??? One
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001307 // suggestion is to call this during vkCreateInstance(), and then we
1308 // can clean it up during vkDestroyInstance(). However, that requires
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001309 // that the layer have per-instance locks. We need to come back and
1310 // address this soon.
1311 loader_platform_thread_create_mutex(&globalLock);
1312 globalLockInitialized = 1;
1313 }
1314}
1315
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001316VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
1317{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001318 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map,*pInstance);
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001319 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
1320
1321 if (result == VK_SUCCESS) {
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001322 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
1323 my_data->report_data = debug_report_create_instance(
1324 pTable,
1325 *pInstance,
1326 pCreateInfo->extensionCount,
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001327 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchterf4a2eba2015-06-08 14:58:39 -06001328
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001329 init_draw_state(my_data);
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001330 }
1331 return result;
1332}
1333
Jon Ashburne0fa2282015-05-20 09:00:28 -06001334/* hook DestroyInstance to remove tableInstanceMap entry */
1335VK_LAYER_EXPORT VkResult VKAPI vkDestroyInstance(VkInstance instance)
1336{
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001337 dispatch_key key = get_dispatch_key(instance);
1338 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map, instance);
1339 VkResult res = pTable->DestroyInstance(instance);
1340
1341 // Clean up logging callback, if any
1342 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
1343 if (my_data->logging_callback) {
1344 layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback);
1345 }
1346
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001347 layer_debug_report_destroy_instance(my_data->report_data);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001348 layer_data_map.erase(pTable);
1349
1350 draw_state_instance_table_map.erase(key);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001351 return res;
1352}
1353
Jon Ashburnf0615e22015-05-25 14:11:37 -06001354static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
1355{
Tony Barbour29b12062015-07-13 13:37:24 -06001356 uint32_t i;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001357 VkLayerDispatchTable *pDisp = get_dispatch_table(draw_state_device_table_map, device);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001358 deviceExtMap[pDisp].debug_marker_enabled = false;
Jon Ashburnf0615e22015-05-25 14:11:37 -06001359
1360 for (i = 0; i < pCreateInfo->extensionCount; i++) {
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001361 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], DEBUG_MARKER_EXTENSION_NAME) == 0) {
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001362 /* Found a matching extension name, mark it enabled and init dispatch table*/
1363 initDebugMarkerTable(device);
1364 deviceExtMap[pDisp].debug_marker_enabled = true;
Jon Ashburnf0615e22015-05-25 14:11:37 -06001365 }
1366
1367 }
1368}
1369
Tony Barbour8205d902015-04-16 15:59:00 -06001370VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001371{
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06001372 VkLayerDispatchTable *pDeviceTable = get_dispatch_table(draw_state_device_table_map, *pDevice);
1373 VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001374 if (result == VK_SUCCESS) {
1375 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
1376 VkLayerDispatchTable *pTable = get_dispatch_table(draw_state_device_table_map, *pDevice);
1377 layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
1378 my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001379 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001380 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001381 return result;
1382}
1383
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001384VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001385{
1386 // Free all the memory
1387 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehliseaf28662015-04-08 10:58:37 -06001388 deletePipelines();
1389 deleteSamplers();
1390 deleteImages();
1391 deleteBuffers();
1392 deleteCmdBuffers();
1393 deleteDynamicState();
1394 deletePools();
1395 deleteLayouts();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001396 loader_platform_thread_unlock_mutex(&globalLock);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001397
Jeremy Hayesea1fef52015-06-19 11:37:38 -06001398 dispatch_key key = get_dispatch_key(device);
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001399 VkLayerDispatchTable *pDisp = get_dispatch_table(draw_state_device_table_map, device);
1400 VkResult result = pDisp->DestroyDevice(device);
1401 deviceExtMap.erase(pDisp);
Jeremy Hayesea1fef52015-06-19 11:37:38 -06001402 draw_state_device_table_map.erase(key);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001403 tableDebugMarkerMap.erase(pDisp);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001404 return result;
1405}
1406
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001407static const VkLayerProperties ds_global_layers[] = {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001408 {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001409 "DrawState",
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001410 VK_API_VERSION,
1411 VK_MAKE_VERSION(0, 1, 0),
1412 "Validation layer: DrawState",
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001413 }
Jon Ashburneb2728b2015-04-10 14:33:07 -06001414};
1415
Tony Barbour426b9052015-06-24 16:06:58 -06001416VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties(
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001417 const char *pLayerName,
1418 uint32_t *pCount,
1419 VkExtensionProperties* pProperties)
Jon Ashburneb2728b2015-04-10 14:33:07 -06001420{
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001421 /* DrawState does not have any global extensions */
1422 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
1423}
Jon Ashburneb2728b2015-04-10 14:33:07 -06001424
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001425VK_LAYER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties(
1426 uint32_t *pCount,
1427 VkLayerProperties* pProperties)
1428{
1429 return util_GetLayerProperties(ARRAY_SIZE(ds_global_layers),
1430 ds_global_layers,
1431 pCount, pProperties);
1432}
Jon Ashburneb2728b2015-04-10 14:33:07 -06001433
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001434static const VkExtensionProperties ds_device_extensions[] = {
1435 {
1436 DEBUG_MARKER_EXTENSION_NAME,
1437 VK_MAKE_VERSION(0, 1, 0),
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001438 }
1439};
1440
1441static const VkLayerProperties ds_device_layers[] = {
1442 {
1443 "DrawState",
1444 VK_API_VERSION,
1445 VK_MAKE_VERSION(0, 1, 0),
1446 "Validation layer: DrawState",
1447 }
1448};
1449
1450VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceExtensionProperties(
1451 VkPhysicalDevice physicalDevice,
1452 const char* pLayerName,
1453 uint32_t* pCount,
1454 VkExtensionProperties* pProperties)
1455{
1456 /* Mem tracker does not have any physical device extensions */
1457 return util_GetExtensionProperties(ARRAY_SIZE(ds_device_extensions), ds_device_extensions,
1458 pCount, pProperties);
1459}
1460
1461VK_LAYER_EXPORT VkResult VKAPI vkGetPhysicalDeviceLayerProperties(
1462 VkPhysicalDevice physicalDevice,
1463 uint32_t* pCount,
1464 VkLayerProperties* pProperties)
1465{
1466 /* Mem tracker's physical device layers are the same as global */
1467 return util_GetLayerProperties(ARRAY_SIZE(ds_device_layers), ds_device_layers,
1468 pCount, pProperties);
Jon Ashburneb2728b2015-04-10 14:33:07 -06001469}
1470
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001471VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001472{
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001473 GLOBAL_CB_NODE* pCB = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001474 for (uint32_t i=0; i < cmdBufferCount; i++) {
1475 // Validate that cmd buffers have been updated
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001476 pCB = getCBNode(pCmdBuffers[i]);
1477 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001478 pCB->submitCount++; // increment submit count
1479 if ((pCB->beginInfo.flags & VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT) && (pCB->submitCount > 1)) {
1480 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_CMD_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
Tobin Ehlis7f7b4422015-08-18 14:24:32 -06001481 "CB %#" PRIxLEAST64 " was begun w/ VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT set, but has been submitted %#" PRIxLEAST64 " times.", reinterpret_cast<VkUintPtrLeast64>(pCB->cmdBuffer), pCB->submitCount);
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001482 }
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001483 if (CB_UPDATE_COMPLETE != pCB->state) {
1484 // Flag error for using CB w/o vkEndCommandBuffer() called
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001485 // TODO : How to pass cb as srcObj?
1486 log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS",
1487 "You must call vkEndCommandBuffer() on CB %#" PRIxLEAST64 " before this call to vkQueueSubmit()!", reinterpret_cast<VkUintPtrLeast64>(pCB->cmdBuffer));
Tobin Ehlise90b1712015-05-27 14:30:06 -06001488 loader_platform_thread_unlock_mutex(&globalLock);
1489 return VK_ERROR_UNKNOWN;
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001490 }
Tobin Ehlise9b700e2015-05-26 16:06:50 -06001491 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001492 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06001493
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001494 VkResult result = get_dispatch_table(draw_state_device_table_map, queue)->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001495 return result;
1496}
1497
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001498VK_LAYER_EXPORT VkResult VKAPI vkDestroyFence(VkDevice device, VkFence fence)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001499{
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001500 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyFence(device, fence);
1501 // TODO : Clean up any internal data structures using this obj.
1502 return result;
1503}
1504
1505VK_LAYER_EXPORT VkResult VKAPI vkDestroySemaphore(VkDevice device, VkSemaphore semaphore)
1506{
1507 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroySemaphore(device, semaphore);
1508 // TODO : Clean up any internal data structures using this obj.
1509 return result;
1510}
1511
1512VK_LAYER_EXPORT VkResult VKAPI vkDestroyEvent(VkDevice device, VkEvent event)
1513{
1514 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyEvent(device, event);
1515 // TODO : Clean up any internal data structures using this obj.
1516 return result;
1517}
1518
1519VK_LAYER_EXPORT VkResult VKAPI vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool)
1520{
1521 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyQueryPool(device, queryPool);
1522 // TODO : Clean up any internal data structures using this obj.
1523 return result;
1524}
1525
1526VK_LAYER_EXPORT VkResult VKAPI vkDestroyBuffer(VkDevice device, VkBuffer buffer)
1527{
1528 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyBuffer(device, buffer);
1529 // TODO : Clean up any internal data structures using this obj.
1530 return result;
1531}
1532
1533VK_LAYER_EXPORT VkResult VKAPI vkDestroyBufferView(VkDevice device, VkBufferView bufferView)
1534{
1535 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyBufferView(device, bufferView);
1536 // TODO : Clean up any internal data structures using this obj.
1537 return result;
1538}
1539
1540VK_LAYER_EXPORT VkResult VKAPI vkDestroyImage(VkDevice device, VkImage image)
1541{
1542 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyImage(device, image);
1543 // TODO : Clean up any internal data structures using this obj.
1544 return result;
1545}
1546
1547VK_LAYER_EXPORT VkResult VKAPI vkDestroyImageView(VkDevice device, VkImageView imageView)
1548{
1549 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyImageView(device, imageView);
1550 // TODO : Clean up any internal data structures using this obj.
1551 return result;
1552}
1553
1554VK_LAYER_EXPORT VkResult VKAPI vkDestroyAttachmentView(VkDevice device, VkAttachmentView attachmentView)
1555{
1556 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyAttachmentView(device, attachmentView);
1557 // TODO : Clean up any internal data structures using this obj.
1558 return result;
1559}
1560
1561VK_LAYER_EXPORT VkResult VKAPI vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule)
1562{
1563 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyShaderModule(device, shaderModule);
1564 // TODO : Clean up any internal data structures using this obj.
1565 return result;
1566}
1567
1568VK_LAYER_EXPORT VkResult VKAPI vkDestroyShader(VkDevice device, VkShader shader)
1569{
1570 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyShader(device, shader);
1571 // TODO : Clean up any internal data structures using this obj.
1572 return result;
1573}
1574
1575VK_LAYER_EXPORT VkResult VKAPI vkDestroyPipeline(VkDevice device, VkPipeline pipeline)
1576{
1577 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyPipeline(device, pipeline);
1578 // TODO : Clean up any internal data structures using this obj.
1579 return result;
1580}
1581
1582VK_LAYER_EXPORT VkResult VKAPI vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout)
1583{
1584 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyPipelineLayout(device, pipelineLayout);
1585 // TODO : Clean up any internal data structures using this obj.
1586 return result;
1587}
1588
1589VK_LAYER_EXPORT VkResult VKAPI vkDestroySampler(VkDevice device, VkSampler sampler)
1590{
1591 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroySampler(device, sampler);
1592 // TODO : Clean up any internal data structures using this obj.
1593 return result;
1594}
1595
1596VK_LAYER_EXPORT VkResult VKAPI vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout)
1597{
1598 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDescriptorSetLayout(device, descriptorSetLayout);
1599 // TODO : Clean up any internal data structures using this obj.
1600 return result;
1601}
1602
1603VK_LAYER_EXPORT VkResult VKAPI vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
1604{
1605 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool);
1606 // TODO : Clean up any internal data structures using this obj.
1607 return result;
1608}
1609
1610VK_LAYER_EXPORT VkResult VKAPI vkDestroyDynamicViewportState(VkDevice device, VkDynamicViewportState dynamicViewportState)
1611{
1612 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDynamicViewportState(device, dynamicViewportState);
1613 // TODO : Clean up any internal data structures using this obj.
1614 return result;
1615}
1616
Cody Northropf5bd2252015-08-17 11:10:49 -06001617VK_LAYER_EXPORT VkResult VKAPI vkDestroyDynamicRasterLineState(VkDevice device, VkDynamicRasterLineState dynamicRasterLineState)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001618{
Cody Northropf5bd2252015-08-17 11:10:49 -06001619 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDynamicRasterLineState(device, dynamicRasterLineState);
1620 // TODO : Clean up any internal data structures using this obj.
1621 return result;
1622}
1623
1624VK_LAYER_EXPORT VkResult VKAPI vkDestroyDynamicRasterDepthBiasState(VkDevice device, VkDynamicRasterDepthBiasState dynamicRasterDepthBiasState)
1625{
1626 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDynamicRasterDepthBiasState(device, dynamicRasterDepthBiasState);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001627 // TODO : Clean up any internal data structures using this obj.
1628 return result;
1629}
1630
1631VK_LAYER_EXPORT VkResult VKAPI vkDestroyDynamicColorBlendState(VkDevice device, VkDynamicColorBlendState dynamicColorBlendState)
1632{
1633 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDynamicColorBlendState(device, dynamicColorBlendState);
1634 // TODO : Clean up any internal data structures using this obj.
1635 return result;
1636}
1637
1638VK_LAYER_EXPORT VkResult VKAPI vkDestroyDynamicDepthStencilState(VkDevice device, VkDynamicDepthStencilState dynamicDepthStencilState)
1639{
1640 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyDynamicDepthStencilState(device, dynamicDepthStencilState);
1641 // TODO : Clean up any internal data structures using this obj.
1642 return result;
1643}
1644
1645VK_LAYER_EXPORT VkResult VKAPI vkDestroyCommandBuffer(VkDevice device, VkCmdBuffer commandBuffer)
1646{
1647 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyCommandBuffer(device, commandBuffer);
1648 // TODO : Clean up any internal data structures using this obj.
1649 return result;
1650}
1651
1652VK_LAYER_EXPORT VkResult VKAPI vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer)
1653{
1654 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyFramebuffer(device, framebuffer);
1655 // TODO : Clean up any internal data structures using this obj.
1656 return result;
1657}
1658
1659VK_LAYER_EXPORT VkResult VKAPI vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass)
1660{
1661 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyRenderPass(device, renderPass);
1662 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001663 return result;
1664}
1665
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001666VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001667{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001668 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001669 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001670 loader_platform_thread_lock_mutex(&globalLock);
1671 BUFFER_NODE* pNewNode = new BUFFER_NODE;
1672 pNewNode->buffer = *pView;
1673 pNewNode->createInfo = *pCreateInfo;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001674 bufferMap[pView->handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001675 loader_platform_thread_unlock_mutex(&globalLock);
1676 }
1677 return result;
1678}
1679
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001680VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001681{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001682 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001683 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001684 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001685 imageMap[pView->handle] = *pCreateInfo;
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06001686 loader_platform_thread_unlock_mutex(&globalLock);
1687 }
1688 return result;
1689}
1690
Tobin Ehlis44c757d2015-07-10 12:15:19 -06001691VkResult VKAPI vkCreateAttachmentView(
1692 VkDevice device,
1693 const VkAttachmentViewCreateInfo* pCreateInfo,
1694 VkAttachmentView* pView)
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06001695{
Tobin Ehlis44c757d2015-07-10 12:15:19 -06001696 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateAttachmentView(device, pCreateInfo, pView);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06001697 if (VK_SUCCESS == result) {
1698 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001699 viewMap[pView->handle] = *pCreateInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001700 loader_platform_thread_unlock_mutex(&globalLock);
1701 }
1702 return result;
1703}
1704
Jon Ashburn0d60d272015-07-09 15:02:25 -06001705//TODO handle pipeline caches
1706VkResult VKAPI vkCreatePipelineCache(
1707 VkDevice device,
1708 const VkPipelineCacheCreateInfo* pCreateInfo,
1709 VkPipelineCache* pPipelineCache)
1710{
1711 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreatePipelineCache(device, pCreateInfo, pPipelineCache);
1712 return result;
1713}
1714
1715VkResult VKAPI vkDestroyPipelineCache(
1716 VkDevice device,
1717 VkPipelineCache pipelineCache)
1718{
1719 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->DestroyPipelineCache(device, pipelineCache);
1720 return result;
1721}
1722
1723size_t VKAPI vkGetPipelineCacheSize(
1724 VkDevice device,
1725 VkPipelineCache pipelineCache)
1726{
1727 size_t size = get_dispatch_table(draw_state_device_table_map, device)->GetPipelineCacheSize(device, pipelineCache);
1728 return size;
1729}
1730
1731VkResult VKAPI vkGetPipelineCacheData(
1732 VkDevice device,
1733 VkPipelineCache pipelineCache,
1734 void* pData)
1735{
1736 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->GetPipelineCacheData(device, pipelineCache, pData);
1737 return result;
1738}
1739
1740VkResult VKAPI vkMergePipelineCaches(
1741 VkDevice device,
1742 VkPipelineCache destCache,
1743 uint32_t srcCacheCount,
1744 const VkPipelineCache* pSrcCaches)
1745{
1746 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->MergePipelineCaches(device, destCache, srcCacheCount, pSrcCaches);
1747 return result;
1748}
1749
1750VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001751{
Tobin Ehlisde63c532015-06-18 15:59:33 -06001752 VkResult result = VK_ERROR_BAD_PIPELINE_DATA;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001753 //TODO handle count > 1 and handle pipelineCache
Tobin Ehlisde63c532015-06-18 15:59:33 -06001754 // The order of operations here is a little convoluted but gets the job done
1755 // 1. Pipeline create state is first shadowed into PIPELINE_NODE struct
1756 // 2. Create state is then validated (which uses flags setup during shadowing)
1757 // 3. If everything looks good, we'll then create the pipeline and add NODE to pipelineMap
1758 loader_platform_thread_lock_mutex(&globalLock);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001759 PIPELINE_NODE* pPipeNode = initPipeline(pCreateInfos, NULL);
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06001760 VkBool32 valid = verifyPipelineCreateState(device, pPipeNode);
Tobin Ehlisde63c532015-06-18 15:59:33 -06001761 loader_platform_thread_unlock_mutex(&globalLock);
1762 if (VK_TRUE == valid) {
Jon Ashburn0d60d272015-07-09 15:02:25 -06001763 result = get_dispatch_table(draw_state_device_table_map, device)->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001764 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_PIPELINE, (*pPipelines).handle, 0, DRAWSTATE_NONE, "DS",
1765 "Created Gfx Pipeline %#" PRIxLEAST64, (*pPipelines).handle);
Tobin Ehlisde63c532015-06-18 15:59:33 -06001766 loader_platform_thread_lock_mutex(&globalLock);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001767 pPipeNode->pipeline = *pPipelines;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001768 pipelineMap[pPipeNode->pipeline.handle] = pPipeNode;
Tobin Ehlisde63c532015-06-18 15:59:33 -06001769 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001770 } else {
Tobin Ehlisde63c532015-06-18 15:59:33 -06001771 if (pPipeNode) {
1772 // If we allocated a pipeNode, need to clean it up here
1773 delete[] pPipeNode->pVertexBindingDescriptions;
1774 delete[] pPipeNode->pVertexAttributeDescriptions;
1775 delete[] pPipeNode->pAttachments;
1776 delete pPipeNode;
1777 }
1778 }
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001779 return result;
1780}
1781
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001782VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001783{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001784 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001785 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001786 loader_platform_thread_lock_mutex(&globalLock);
1787 SAMPLER_NODE* pNewNode = new SAMPLER_NODE;
1788 pNewNode->sampler = *pSampler;
1789 pNewNode->createInfo = *pCreateInfo;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001790 sampleMap[pSampler->handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001791 loader_platform_thread_unlock_mutex(&globalLock);
1792 }
1793 return result;
1794}
1795
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001796VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001797{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001798 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001799 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001800 LAYOUT_NODE* pNewNode = new LAYOUT_NODE;
1801 if (NULL == pNewNode) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001802 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (*pSetLayout).handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001803 "Out of memory while attempting to allocate LAYOUT_NODE in vkCreateDescriptorSetLayout()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001804 }
1805 memset(pNewNode, 0, sizeof(LAYOUT_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001806 memcpy((void*)&pNewNode->createInfo, pCreateInfo, sizeof(VkDescriptorSetLayoutCreateInfo));
1807 pNewNode->createInfo.pBinding = new VkDescriptorSetLayoutBinding[pCreateInfo->count];
1808 memcpy((void*)pNewNode->createInfo.pBinding, pCreateInfo->pBinding, sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->count);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001809 uint32_t totalCount = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001810 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001811 totalCount += pCreateInfo->pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001812 if (pCreateInfo->pBinding[i].pImmutableSamplers) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001813 VkSampler** ppIS = (VkSampler**)&pNewNode->createInfo.pBinding[i].pImmutableSamplers;
Chia-I Wud3114a22015-05-25 16:22:52 +08001814 *ppIS = new VkSampler[pCreateInfo->pBinding[i].arraySize];
1815 memcpy(*ppIS, pCreateInfo->pBinding[i].pImmutableSamplers, pCreateInfo->pBinding[i].arraySize*sizeof(VkSampler));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001816 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001817 }
1818 if (totalCount > 0) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001819 pNewNode->pTypes = new VkDescriptorType[totalCount];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001820 uint32_t offset = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001821 uint32_t j = 0;
1822 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001823 for (j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001824 pNewNode->pTypes[offset + j] = pCreateInfo->pBinding[i].descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001825 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001826 offset += j;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001827 }
1828 }
1829 pNewNode->layout = *pSetLayout;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001830 pNewNode->startIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001831 pNewNode->endIndex = pNewNode->startIndex + totalCount - 1;
1832 assert(pNewNode->endIndex >= pNewNode->startIndex);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001833 // Put new node at Head of global Layer list
1834 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001835 layoutMap[pSetLayout->handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001836 loader_platform_thread_unlock_mutex(&globalLock);
1837 }
1838 return result;
1839}
1840
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001841VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001842{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001843 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001844 if (VK_SUCCESS == result) {
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001845 // TODO : Need to capture the pipeline layout
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001846 }
1847 return result;
1848}
1849
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001850VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001851{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001852 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDescriptorPool(device, poolUsage, maxSets, pCreateInfo, pDescriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001853 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001854 // Insert this pool into Global Pool LL at head
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001855 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (*pDescriptorPool).handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
1856 "Created Descriptor Pool %#" PRIxLEAST64, (*pDescriptorPool).handle);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001857 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001858 POOL_NODE* pNewNode = new POOL_NODE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001859 if (NULL == pNewNode) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001860 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (*pDescriptorPool).handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001861 "Out of memory while attempting to allocate POOL_NODE in vkCreateDescriptorPool()");
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001862 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001863 memset(pNewNode, 0, sizeof(POOL_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001864 VkDescriptorPoolCreateInfo* pCI = (VkDescriptorPoolCreateInfo*)&pNewNode->createInfo;
1865 memcpy((void*)pCI, pCreateInfo, sizeof(VkDescriptorPoolCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001866 if (pNewNode->createInfo.count) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001867 size_t typeCountSize = pNewNode->createInfo.count * sizeof(VkDescriptorTypeCount);
1868 pNewNode->createInfo.pTypeCount = new VkDescriptorTypeCount[typeCountSize];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001869 memcpy((void*)pNewNode->createInfo.pTypeCount, pCreateInfo->pTypeCount, typeCountSize);
1870 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001871 pNewNode->poolUsage = poolUsage;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001872 pNewNode->maxSets = maxSets;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001873 pNewNode->pool = *pDescriptorPool;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001874 poolMap[pDescriptorPool->handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001875 }
1876 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001877 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001878 // Need to do anything if pool create fails?
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001879 }
1880 return result;
1881}
1882
Mike Stroyan230e6252015-04-17 12:36:38 -06001883VK_LAYER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001884{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001885 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->ResetDescriptorPool(device, descriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001886 if (VK_SUCCESS == result) {
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001887 clearDescriptorPool(device, descriptorPool);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001888 }
1889 return result;
1890}
1891
Cody Northropc8aa4a52015-08-03 12:47:29 -06001892VK_LAYER_EXPORT VkResult VKAPI vkAllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001893{
Cody Northropc8aa4a52015-08-03 12:47:29 -06001894 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets);
1895 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001896 POOL_NODE *pPoolNode = getPoolNode(descriptorPool);
1897 if (!pPoolNode) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001898 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, descriptorPool.handle, 0, DRAWSTATE_INVALID_POOL, "DS",
1899 "Unable to find pool node for pool %#" PRIxLEAST64 " specified in vkAllocDescriptorSets() call", descriptorPool.handle);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001900 } else {
Cody Northropc8aa4a52015-08-03 12:47:29 -06001901 if (count == 0) {
1902 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, count, 0, DRAWSTATE_NONE, "DS",
1903 "AllocDescriptorSets called with 0 count");
1904 }
1905 for (uint32_t i = 0; i < count; i++) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001906 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_NONE, "DS",
1907 "Created Descriptor Set %#" PRIxLEAST64, pDescriptorSets[i].handle);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001908 // Create new set node and add to head of pool nodes
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001909 SET_NODE* pNewNode = new SET_NODE;
1910 if (NULL == pNewNode) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001911 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001912 "Out of memory while attempting to allocate SET_NODE in vkAllocDescriptorSets()");
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001913 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001914 memset(pNewNode, 0, sizeof(SET_NODE));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001915 // Insert set at head of Set LL for this pool
1916 pNewNode->pNext = pPoolNode->pSets;
1917 pPoolNode->pSets = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001918 LAYOUT_NODE* pLayout = getLayoutNode(pSetLayouts[i]);
1919 if (NULL == pLayout) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001920 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, pSetLayouts[i].handle, 0, DRAWSTATE_INVALID_LAYOUT, "DS",
1921 "Unable to find set layout node for layout %#" PRIxLEAST64 " specified in vkAllocDescriptorSets() call", pSetLayouts[i].handle);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001922 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001923 pNewNode->pLayout = pLayout;
1924 pNewNode->pool = descriptorPool;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001925 pNewNode->set = pDescriptorSets[i];
1926 pNewNode->setUsage = setUsage;
1927 pNewNode->descriptorCount = pLayout->endIndex + 1;
1928 if (pNewNode->descriptorCount) {
1929 size_t descriptorArraySize = sizeof(GENERIC_HEADER*)*pNewNode->descriptorCount;
1930 pNewNode->ppDescriptors = new GENERIC_HEADER*[descriptorArraySize];
1931 memset(pNewNode->ppDescriptors, 0, descriptorArraySize);
1932 }
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001933 setMap[pDescriptorSets[i].handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001934 }
1935 }
1936 }
1937 }
1938 return result;
1939}
1940
Tony Barbourb857d312015-07-10 10:50:45 -06001941VK_LAYER_EXPORT VkResult VKAPI vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
1942{
1943 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
1944 // TODO : Clean up any internal data structures using this obj.
1945 return result;
1946}
1947
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001948VK_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 -06001949{
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001950 if (dsUpdate(device, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, writeCount, pDescriptorWrites) &&
1951 dsUpdate(device, VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, copyCount, pDescriptorCopies)) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001952 return get_dispatch_table(draw_state_device_table_map, device)->UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001953 }
1954 return VK_ERROR_UNKNOWN;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001955}
1956
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001957VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicViewportState(VkDevice device, const VkDynamicViewportStateCreateInfo* pCreateInfo, VkDynamicViewportState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001958{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001959 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicViewportState(device, pCreateInfo, pState);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001960 VkDynamicViewportStateCreateInfo local_ci;
1961 memcpy(&local_ci, pCreateInfo, sizeof(VkDynamicViewportStateCreateInfo));
1962 local_ci.pViewports = new VkViewport[pCreateInfo->viewportAndScissorCount];
1963 local_ci.pScissors = new VkRect2D[pCreateInfo->viewportAndScissorCount];
1964 loader_platform_thread_lock_mutex(&globalLock);
1965 dynamicVpStateMap[pState->handle] = local_ci;
1966 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001967 return result;
1968}
1969
Cody Northropf5bd2252015-08-17 11:10:49 -06001970VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterLineState(VkDevice device, const VkDynamicRasterLineStateCreateInfo* pCreateInfo, VkDynamicRasterLineState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001971{
Cody Northropf5bd2252015-08-17 11:10:49 -06001972 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicRasterLineState(device, pCreateInfo, pState);
1973 //insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_RASTER_LINE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001974 loader_platform_thread_lock_mutex(&globalLock);
Cody Northropf5bd2252015-08-17 11:10:49 -06001975 dynamicRasterLineStateMap[pState->handle] = *pCreateInfo;
1976 loader_platform_thread_unlock_mutex(&globalLock);
1977 return result;
1978}
1979
1980VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicRasterDepthBiasState(VkDevice device, const VkDynamicRasterDepthBiasStateCreateInfo* pCreateInfo, VkDynamicRasterDepthBiasState* pState)
1981{
1982 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicRasterDepthBiasState(device, pCreateInfo, pState);
1983 //insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_RASTER_DEPTH_BIAS);
1984 loader_platform_thread_lock_mutex(&globalLock);
1985 dynamicRasterDepthBiasStateMap[pState->handle] = *pCreateInfo;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001986 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001987 return result;
1988}
1989
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001990VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicColorBlendState(VkDevice device, const VkDynamicColorBlendStateCreateInfo* pCreateInfo, VkDynamicColorBlendState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001991{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06001992 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicColorBlendState(device, pCreateInfo, pState);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001993 //insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_COLOR_BLEND);
1994 loader_platform_thread_lock_mutex(&globalLock);
1995 dynamicCbStateMap[pState->handle] = *pCreateInfo;
1996 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001997 return result;
1998}
1999
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002000VK_LAYER_EXPORT VkResult VKAPI vkCreateDynamicDepthStencilState(VkDevice device, const VkDynamicDepthStencilStateCreateInfo* pCreateInfo, VkDynamicDepthStencilState* pState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002001{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002002 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateDynamicDepthStencilState(device, pCreateInfo, pState);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002003 //insertDynamicState(*pState, (GENERIC_HEADER*)pCreateInfo, VK_STATE_BIND_POINT_DEPTH_STENCIL);
2004 loader_platform_thread_lock_mutex(&globalLock);
2005 dynamicDsStateMap[pState->handle] = *pCreateInfo;
2006 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002007 return result;
2008}
2009
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002010VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002011{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002012 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002013 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002014 loader_platform_thread_lock_mutex(&globalLock);
2015 GLOBAL_CB_NODE* pCB = new GLOBAL_CB_NODE;
2016 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
2017 pCB->cmdBuffer = *pCmdBuffer;
Tobin Ehlis0cea4082015-08-18 07:10:58 -06002018 pCB->createInfo = *pCreateInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002019 pCB->lastVtxBinding = MAX_BINDING;
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06002020 pCB->level = pCreateInfo->level;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002021 cmdBufferMap[*pCmdBuffer] = pCB;
2022 loader_platform_thread_unlock_mutex(&globalLock);
2023 updateCBTracking(*pCmdBuffer);
2024 }
2025 return result;
2026}
2027
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002028VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002029{
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06002030 // Validate command buffer level
2031 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2032 if (pCB) {
2033 if (pCB->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
2034 if (pBeginInfo->renderPass.handle || pBeginInfo->framebuffer.handle) {
2035 // These should be NULL for a Primary CB
2036 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
2037 "vkCreateCommandBuffer(): Primary Command Buffer (%p) may not specify framebuffer or renderpass parameters", (void*)cmdBuffer);
2038 }
2039 } else {
2040 if (!pBeginInfo->renderPass.handle || !pBeginInfo->framebuffer.handle) {
2041 // These should NOT be null for an Secondary CB
2042 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
2043 "vkCreateCommandBuffer(): Secondary Command Buffers (%p) must specify framebuffer and renderpass parameters", (void*)cmdBuffer);
2044 }
2045 }
Tobin Ehlis0cea4082015-08-18 07:10:58 -06002046 pCB->beginInfo = *pBeginInfo;
2047 } else {
2048 // TODO : Need to pass cmdBuffer as objType here
2049 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS",
2050 "In vkBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06002051 }
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002052 VkResult result = get_dispatch_table(draw_state_device_table_map, cmdBuffer)->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002053 if (VK_SUCCESS == result) {
Tobin Ehlis0cea4082015-08-18 07:10:58 -06002054 if (CB_NEW != pCB->state)
2055 resetCB(cmdBuffer);
2056 pCB->state = CB_UPDATE_ACTIVE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002057 updateCBTracking(cmdBuffer);
2058 }
2059 return result;
2060}
2061
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002062VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002063{
Tobin Ehlise42007c2015-06-19 13:00:59 -06002064 VkResult result = VK_ERROR_BUILDING_COMMAND_BUFFER;
2065 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2066 if (pCB) {
2067 if (pCB->state == CB_UPDATE_ACTIVE) {
2068 result = get_dispatch_table(draw_state_device_table_map, cmdBuffer)->EndCommandBuffer(cmdBuffer);
2069 if (VK_SUCCESS == result) {
2070 updateCBTracking(cmdBuffer);
2071 pCB->state = CB_UPDATE_COMPLETE;
2072 // Reset CB status flags
2073 pCB->status = 0;
2074 printCB(cmdBuffer);
2075 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002076 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002077 report_error_no_cb_begin(cmdBuffer, "vkEndCommandBuffer()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002078 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002079 }
2080 return result;
2081}
2082
Cody Northropf02f9f82015-07-09 18:08:05 -06002083VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer, VkCmdBufferResetFlags flags)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002084{
Cody Northropf02f9f82015-07-09 18:08:05 -06002085 VkResult result = get_dispatch_table(draw_state_device_table_map, cmdBuffer)->ResetCommandBuffer(cmdBuffer, flags);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002086 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002087 resetCB(cmdBuffer);
2088 updateCBTracking(cmdBuffer);
2089 }
2090 return result;
2091}
2092
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002093VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002094{
2095 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2096 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002097 if (pCB->state == CB_UPDATE_ACTIVE) {
2098 updateCBTracking(cmdBuffer);
2099 addCmd(pCB, CMD_BINDPIPELINE);
Tobin Ehlis642d5a52015-06-23 08:46:18 -06002100 if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (pCB->activeRenderPass)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002101 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
2102 "Incorrectly binding compute pipeline (%#" PRIxLEAST64 ") during active RenderPass (%#" PRIxLEAST64 ")", pipeline.handle, pCB->activeRenderPass.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002103 } else if ((VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) && (!pCB->activeRenderPass)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002104 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
2105 "Incorrectly binding graphics pipeline (%#" PRIxLEAST64 ") without an active RenderPass", pipeline.handle);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002106 } else {
Tobin Ehlise4076782015-06-24 15:53:07 -06002107 PIPELINE_NODE* pPN = getPipeline(pipeline);
2108 if (pPN) {
2109 pCB->lastBoundPipeline = pipeline;
2110 loader_platform_thread_lock_mutex(&globalLock);
2111 set_cb_pso_status(pCB, pPN);
2112 g_lastBoundPipeline = pPN;
2113 loader_platform_thread_unlock_mutex(&globalLock);
2114 validatePipelineState(pCB, pipelineBindPoint, pipeline);
2115 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
2116 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002117 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle, 0, DRAWSTATE_INVALID_PIPELINE, "DS",
2118 "Attempt to bind Pipeline %#" PRIxLEAST64 " that doesn't exist!", (void*)pipeline.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002119 }
Tobin Ehlise42007c2015-06-19 13:00:59 -06002120 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002121 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002122 report_error_no_cb_begin(cmdBuffer, "vkCmdBindPipeline()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002123 }
2124 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002125}
2126
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002127VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicViewportState(VkCmdBuffer cmdBuffer, VkDynamicViewportState dynamicViewportState)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002128{
Tobin Ehlise42007c2015-06-19 13:00:59 -06002129 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2130 if (pCB) {
2131 if (pCB->state == CB_UPDATE_ACTIVE) {
2132 updateCBTracking(cmdBuffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002133 addCmd(pCB, CMD_BINDDYNAMICVIEWPORTSTATE);
Tobin Ehlise4076782015-06-24 15:53:07 -06002134 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002135 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
2136 "Incorrect call to vkCmdBindDynamicViewportState() without an active RenderPass.");
Tobin Ehlise4076782015-06-24 15:53:07 -06002137 }
Tobin Ehlise42007c2015-06-19 13:00:59 -06002138 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002139 pCB->status |= CBSTATUS_VIEWPORT_BOUND;
2140 if (dynamicVpStateMap.find(dynamicViewportState.handle) == dynamicVpStateMap.end()) {
Tony Barbour2a199c12015-07-09 17:31:46 -06002141 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DYNAMIC_VIEWPORT_STATE, dynamicViewportState.handle, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002142 "Unable to find VkDynamicViewportState object %#" PRIxLEAST64 ", was it ever created?", dynamicViewportState.handle);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002143 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002144 pCB->lastBoundDynamicState[VK_STATE_BIND_POINT_VIEWPORT] = dynamicViewportState.handle;
2145 g_lastBoundDynamicState[VK_STATE_BIND_POINT_VIEWPORT] = dynamicViewportState.handle;
Tobin Ehlise42007c2015-06-19 13:00:59 -06002146 }
2147 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002148 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDynamicViewportState(cmdBuffer, dynamicViewportState);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002149 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002150 report_error_no_cb_begin(cmdBuffer, "vkCmdBindDynamicViewportState()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002151 }
2152 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002153}
Cody Northropf5bd2252015-08-17 11:10:49 -06002154VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicRasterLineState(VkCmdBuffer cmdBuffer, VkDynamicRasterLineState dynamicRasterLineState)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002155{
2156 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2157 if (pCB) {
2158 if (pCB->state == CB_UPDATE_ACTIVE) {
2159 updateCBTracking(cmdBuffer);
Cody Northropf5bd2252015-08-17 11:10:49 -06002160 addCmd(pCB, CMD_BINDDYNAMICRASTERLINESTATE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002161 if (!pCB->activeRenderPass) {
2162 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Cody Northropf5bd2252015-08-17 11:10:49 -06002163 "Incorrect call to vkCmdBindDynamicRasterLineState() without an active RenderPass.");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002164 }
2165 loader_platform_thread_lock_mutex(&globalLock);
Cody Northropf5bd2252015-08-17 11:10:49 -06002166 pCB->status |= CBSTATUS_RASTER_LINE_BOUND;
2167 if (dynamicRasterLineStateMap.find(dynamicRasterLineState.handle) == dynamicRasterLineStateMap.end()) {
2168 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DYNAMIC_RASTER_LINE_STATE, dynamicRasterLineState.handle, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS",
2169 "Unable to find VkDynamicRasterLineState object %#" PRIxLEAST64 ", was it ever created?", dynamicRasterLineState.handle);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002170 } else {
Cody Northropf5bd2252015-08-17 11:10:49 -06002171 pCB->lastBoundDynamicState[VK_STATE_BIND_POINT_RASTER_LINE] = dynamicRasterLineState.handle;
2172 g_lastBoundDynamicState[VK_STATE_BIND_POINT_RASTER_LINE] = dynamicRasterLineState.handle;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002173 }
2174 loader_platform_thread_unlock_mutex(&globalLock);
Cody Northropf5bd2252015-08-17 11:10:49 -06002175 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDynamicRasterLineState(cmdBuffer, dynamicRasterLineState);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002176 } else {
Cody Northropf5bd2252015-08-17 11:10:49 -06002177 report_error_no_cb_begin(cmdBuffer, "vkCmdBindDynamicRasterLineState()");
2178 }
2179 }
2180}
2181VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicRasterDepthBiasState(VkCmdBuffer cmdBuffer, VkDynamicRasterDepthBiasState dynamicRasterDepthBiasState)
2182{
2183 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2184 if (pCB) {
2185 if (pCB->state == CB_UPDATE_ACTIVE) {
2186 updateCBTracking(cmdBuffer);
2187 addCmd(pCB, CMD_BINDDYNAMICRASTERDEPTHBIASSTATE);
2188 if (!pCB->activeRenderPass) {
2189 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
2190 "Incorrect call to vkCmdBindDynamicRasterDepthBiasState() without an active RenderPass.");
2191 }
2192 loader_platform_thread_lock_mutex(&globalLock);
2193 pCB->status |= CBSTATUS_RASTER_DEPTH_BIAS_BOUND;
2194 if (dynamicRasterDepthBiasStateMap.find(dynamicRasterDepthBiasState.handle) == dynamicRasterDepthBiasStateMap.end()) {
2195 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DYNAMIC_RASTER_DEPTH_BIAS_STATE, dynamicRasterDepthBiasState.handle, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS",
2196 "Unable to find VkDynamicRasterDepthBiasState object %#" PRIxLEAST64 ", was it ever created?", dynamicRasterDepthBiasState.handle);
2197 } else {
2198 pCB->lastBoundDynamicState[VK_STATE_BIND_POINT_RASTER_DEPTH_BIAS] = dynamicRasterDepthBiasState.handle;
2199 g_lastBoundDynamicState[VK_STATE_BIND_POINT_RASTER_DEPTH_BIAS] = dynamicRasterDepthBiasState.handle;
2200 }
2201 loader_platform_thread_unlock_mutex(&globalLock);
2202 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDynamicRasterDepthBiasState(cmdBuffer, dynamicRasterDepthBiasState);
2203 } else {
2204 report_error_no_cb_begin(cmdBuffer, "vkCmdBindDynamicRasterDepthBiasState()");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002205 }
2206 }
2207}
2208VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicColorBlendState(VkCmdBuffer cmdBuffer, VkDynamicColorBlendState dynamicColorBlendState)
2209{
2210 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2211 if (pCB) {
2212 if (pCB->state == CB_UPDATE_ACTIVE) {
2213 updateCBTracking(cmdBuffer);
2214 addCmd(pCB, CMD_BINDDYNAMICCOLORBLENDSTATE);
2215 if (!pCB->activeRenderPass) {
2216 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
2217 "Incorrect call to vkCmdBindDynamicColorBlendState() without an active RenderPass.");
2218 }
2219 loader_platform_thread_lock_mutex(&globalLock);
2220 pCB->status |= CBSTATUS_COLOR_BLEND_BOUND;
2221 if (dynamicCbStateMap.find(dynamicColorBlendState.handle) == dynamicCbStateMap.end()) {
Tony Barbour2a199c12015-07-09 17:31:46 -06002222 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DYNAMIC_COLOR_BLEND_STATE, dynamicColorBlendState.handle, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002223 "Unable to find VkDynamicColorBlendState object %#" PRIxLEAST64 ", was it ever created?", dynamicColorBlendState.handle);
2224 } else {
2225 pCB->lastBoundDynamicState[VK_STATE_BIND_POINT_COLOR_BLEND] = dynamicColorBlendState.handle;
2226 g_lastBoundDynamicState[VK_STATE_BIND_POINT_COLOR_BLEND] = dynamicColorBlendState.handle;
2227 }
2228 loader_platform_thread_unlock_mutex(&globalLock);
2229 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDynamicColorBlendState(cmdBuffer, dynamicColorBlendState);
2230 } else {
2231 report_error_no_cb_begin(cmdBuffer, "vkCmdBindDynamicColorBlendState()");
2232 }
2233 }
2234}
2235VK_LAYER_EXPORT void VKAPI vkCmdBindDynamicDepthStencilState(VkCmdBuffer cmdBuffer, VkDynamicDepthStencilState dynamicDepthStencilState)
2236{
2237 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2238 if (pCB) {
2239 if (pCB->state == CB_UPDATE_ACTIVE) {
2240 updateCBTracking(cmdBuffer);
2241 addCmd(pCB, CMD_BINDDYNAMICDEPTHSTENCILSTATE);
2242 if (!pCB->activeRenderPass) {
2243 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
2244 "Incorrect call to vkCmdBindDynamicDepthStencilState() without an active RenderPass.");
2245 }
2246 loader_platform_thread_lock_mutex(&globalLock);
2247 pCB->status |= CBSTATUS_DEPTH_STENCIL_BOUND;
2248 if (dynamicDsStateMap.find(dynamicDepthStencilState.handle) == dynamicDsStateMap.end()) {
Tony Barbour2a199c12015-07-09 17:31:46 -06002249 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DYNAMIC_DEPTH_STENCIL_STATE, dynamicDepthStencilState.handle, 0, DRAWSTATE_INVALID_DYNAMIC_STATE_OBJECT, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002250 "Unable to find VkDynamicDepthStencilState object %#" PRIxLEAST64 ", was it ever created?", dynamicDepthStencilState.handle);
2251 } else {
2252 pCB->lastBoundDynamicState[VK_STATE_BIND_POINT_DEPTH_STENCIL] = dynamicDepthStencilState.handle;
2253 g_lastBoundDynamicState[VK_STATE_BIND_POINT_DEPTH_STENCIL] = dynamicDepthStencilState.handle;
2254 }
2255 loader_platform_thread_unlock_mutex(&globalLock);
2256 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDynamicDepthStencilState(cmdBuffer, dynamicDepthStencilState);
2257 } else {
2258 report_error_no_cb_begin(cmdBuffer, "vkCmdBindDynamicDepthStencilState()");
2259 }
2260 }
2261}
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06002262VK_LAYER_EXPORT void VKAPI vkCmdBindDescriptorSets(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002263{
2264 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2265 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002266 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise4076782015-06-24 15:53:07 -06002267 if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (pCB->activeRenderPass)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002268 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
2269 "Incorrectly binding compute DescriptorSets during active RenderPass (%#" PRIxLEAST64 ")", pCB->activeRenderPass.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002270 } else if ((VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) && (!pCB->activeRenderPass)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002271 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Tobin Ehlise4076782015-06-24 15:53:07 -06002272 "Incorrectly binding graphics DescriptorSets without an active RenderPass");
2273 } else if (validateBoundPipeline(cmdBuffer)) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002274 for (uint32_t i=0; i<setCount; i++) {
Tobin Ehlis55c1c602015-06-24 17:27:33 -06002275 SET_NODE* pSet = getSetNode(pDescriptorSets[i]);
2276 if (pSet) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002277 loader_platform_thread_lock_mutex(&globalLock);
2278 pCB->lastBoundDescriptorSet = pDescriptorSets[i];
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -06002279 pCB->lastBoundPipelineLayout = layout;
Tobin Ehlise42007c2015-06-19 13:00:59 -06002280 pCB->boundDescriptorSets.push_back(pDescriptorSets[i]);
2281 g_lastBoundDescriptorSet = pDescriptorSets[i];
2282 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002283 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_NONE, "DS",
2284 "DS %#" PRIxLEAST64 " bound on pipeline %s", pDescriptorSets[i].handle, string_VkPipelineBindPoint(pipelineBindPoint));
Tobin Ehlis55c1c602015-06-24 17:27:33 -06002285 if (!pSet->pUpdateStructs)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002286 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
2287 "DS %#" PRIxLEAST64 " bound but it was never updated. You may want to either update it or not bind it.", pDescriptorSets[i].handle);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002288 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002289 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_INVALID_SET, "DS",
2290 "Attempt to bind DS %#" PRIxLEAST64 " that doesn't exist!", pDescriptorSets[i].handle);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002291 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002292 }
Tobin Ehlis59db5712015-07-13 13:14:24 -06002293 updateCBTracking(cmdBuffer);
2294 addCmd(pCB, CMD_BINDDESCRIPTORSETS);
Tobin Ehlis9bde5922015-06-22 18:00:14 -06002295 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002296 }
Tobin Ehlise42007c2015-06-19 13:00:59 -06002297 } else {
2298 report_error_no_cb_begin(cmdBuffer, "vkCmdBindDescriptorSets()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002299 }
2300 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002301}
2302
Tony Barbour8205d902015-04-16 15:59:00 -06002303VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002304{
2305 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2306 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002307 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise4076782015-06-24 15:53:07 -06002308 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002309 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Tobin Ehlise4076782015-06-24 15:53:07 -06002310 "Incorrect call to vkCmdBindIndexBuffer() without an active RenderPass.");
2311 } else {
2312 // TODO : Can be more exact in tracking/validating details for Idx buffer, for now just make sure *something* was bound
2313 pCB->status |= CBSTATUS_INDEX_BUFFER_BOUND;
Tobin Ehlis59db5712015-07-13 13:14:24 -06002314 updateCBTracking(cmdBuffer);
2315 addCmd(pCB, CMD_BINDINDEXBUFFER);
Tobin Ehlise4076782015-06-24 15:53:07 -06002316 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
2317 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002318 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002319 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2320 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002321 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002322}
2323
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002324VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
2325 VkCmdBuffer cmdBuffer,
2326 uint32_t startBinding,
2327 uint32_t bindingCount,
2328 const VkBuffer* pBuffers,
Tony Barbour8205d902015-04-16 15:59:00 -06002329 const VkDeviceSize* pOffsets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002330{
2331 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2332 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002333 if (pCB->state == CB_UPDATE_ACTIVE) {
2334 /* TODO: Need to track all the vertex buffers, not just last one */
Tobin Ehlise4076782015-06-24 15:53:07 -06002335 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002336 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Tobin Ehlise4076782015-06-24 15:53:07 -06002337 "Incorrect call to vkCmdBindVertexBuffers() without an active RenderPass.");
2338 } else {
2339 pCB->lastVtxBinding = startBinding + bindingCount -1;
2340 if (validateBoundPipeline(cmdBuffer)) {
Tobin Ehlis59db5712015-07-13 13:14:24 -06002341 updateCBTracking(cmdBuffer);
2342 addCmd(pCB, CMD_BINDVERTEXBUFFER);
Tobin Ehlise4076782015-06-24 15:53:07 -06002343 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
2344 }
Tobin Ehlise42007c2015-06-19 13:00:59 -06002345 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002346 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002347 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002348 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002349 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002350}
2351
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002352VK_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 -06002353{
2354 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06002355 VkBool32 valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002356 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002357 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002358 pCB->drawCount[DRAW]++;
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -06002359 valid = validate_draw_state(pCB, VK_FALSE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002360 // TODO : Need to pass cmdBuffer as srcObj here
2361 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlise42007c2015-06-19 13:00:59 -06002362 "vkCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
2363 synchAndPrintDSConfig(cmdBuffer);
2364 if (valid) {
Tobin Ehlis59db5712015-07-13 13:14:24 -06002365 updateCBTracking(cmdBuffer);
2366 addCmd(pCB, CMD_DRAW);
2367 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002368 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002369 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002370 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2371 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002372 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002373}
2374
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002375VK_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 -06002376{
2377 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06002378 VkBool32 valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002379 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002380 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002381 pCB->drawCount[DRAW_INDEXED]++;
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -06002382 valid = validate_draw_state(pCB, VK_TRUE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002383 // TODO : Need to pass cmdBuffer as srcObj here
2384 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlise42007c2015-06-19 13:00:59 -06002385 "vkCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
2386 synchAndPrintDSConfig(cmdBuffer);
2387 if (valid) {
Tobin Ehlis59db5712015-07-13 13:14:24 -06002388 updateCBTracking(cmdBuffer);
2389 addCmd(pCB, CMD_DRAWINDEXED);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002390 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
2391 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002392 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002393 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2394 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002395 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002396}
2397
Tony Barbour8205d902015-04-16 15:59:00 -06002398VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002399{
2400 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06002401 VkBool32 valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002402 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002403 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002404 pCB->drawCount[DRAW_INDIRECT]++;
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -06002405 valid = validate_draw_state(pCB, VK_FALSE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002406 // TODO : Need to pass cmdBuffer as srcObj here
2407 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlise42007c2015-06-19 13:00:59 -06002408 "vkCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
2409 synchAndPrintDSConfig(cmdBuffer);
2410 if (valid) {
Tobin Ehlis59db5712015-07-13 13:14:24 -06002411 updateCBTracking(cmdBuffer);
2412 addCmd(pCB, CMD_DRAWINDIRECT);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002413 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
2414 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002415 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002416 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2417 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002418 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002419}
2420
Tony Barbour8205d902015-04-16 15:59:00 -06002421VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002422{
2423 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06002424 VkBool32 valid = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002425 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002426 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002427 pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -06002428 valid = validate_draw_state(pCB, VK_TRUE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002429 // TODO : Need to pass cmdBuffer as srcObj here
2430 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlise42007c2015-06-19 13:00:59 -06002431 "vkCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
2432 synchAndPrintDSConfig(cmdBuffer);
2433 if (valid) {
Tobin Ehlis59db5712015-07-13 13:14:24 -06002434 updateCBTracking(cmdBuffer);
2435 addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
2436 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002437 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002438 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002439 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2440 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06002441 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002442}
2443
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002444VK_LAYER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002445{
2446 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2447 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002448 if (pCB->state == CB_UPDATE_ACTIVE) {
2449 updateCBTracking(cmdBuffer);
2450 addCmd(pCB, CMD_DISPATCH);
2451 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDispatch(cmdBuffer, x, y, z);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002452 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002453 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2454 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002455 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002456}
2457
Tony Barbour8205d902015-04-16 15:59:00 -06002458VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002459{
2460 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2461 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002462 if (pCB->state == CB_UPDATE_ACTIVE) {
2463 updateCBTracking(cmdBuffer);
2464 addCmd(pCB, CMD_DISPATCHINDIRECT);
2465 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002466 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002467 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2468 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002469 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002470}
2471
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002472VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002473{
2474 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2475 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002476 if (pCB->state == CB_UPDATE_ACTIVE) {
2477 updateCBTracking(cmdBuffer);
2478 addCmd(pCB, CMD_COPYBUFFER);
2479 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002480 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002481 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2482 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002483 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002484}
2485
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002486VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer,
2487 VkImage srcImage,
2488 VkImageLayout srcImageLayout,
2489 VkImage destImage,
2490 VkImageLayout destImageLayout,
2491 uint32_t regionCount, const VkImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002492{
2493 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2494 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002495 if (pCB->state == CB_UPDATE_ACTIVE) {
2496 updateCBTracking(cmdBuffer);
2497 addCmd(pCB, CMD_COPYIMAGE);
2498 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002499 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002500 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2501 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002502 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002503}
2504
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002505VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer,
2506 VkImage srcImage, VkImageLayout srcImageLayout,
2507 VkImage destImage, VkImageLayout destImageLayout,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002508 uint32_t regionCount, const VkImageBlit* pRegions,
2509 VkTexFilter filter)
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002510{
2511 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2512 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002513 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlis054bd872015-06-23 10:41:13 -06002514 if (pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002515 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
2516 "Incorrectly issuing CmdBlitImage during active RenderPass (%#" PRIxLEAST64 ")", pCB->activeRenderPass.handle);
Tobin Ehlis59db5712015-07-13 13:14:24 -06002517 } else {
2518 updateCBTracking(cmdBuffer);
2519 addCmd(pCB, CMD_BLITIMAGE);
Tobin Ehlise4076782015-06-24 15:53:07 -06002520 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
Tobin Ehlis59db5712015-07-13 13:14:24 -06002521 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002522 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002523 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2524 }
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002525 }
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002526}
2527
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002528VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer,
2529 VkBuffer srcBuffer,
2530 VkImage destImage, VkImageLayout destImageLayout,
2531 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002532{
2533 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2534 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002535 if (pCB->state == CB_UPDATE_ACTIVE) {
2536 updateCBTracking(cmdBuffer);
2537 addCmd(pCB, CMD_COPYBUFFERTOIMAGE);
2538 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002539 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002540 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2541 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002542 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002543}
2544
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002545VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer,
2546 VkImage srcImage, VkImageLayout srcImageLayout,
2547 VkBuffer destBuffer,
2548 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002549{
2550 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2551 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002552 if (pCB->state == CB_UPDATE_ACTIVE) {
2553 updateCBTracking(cmdBuffer);
2554 addCmd(pCB, CMD_COPYIMAGETOBUFFER);
2555 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002556 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002557 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2558 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002559 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002560}
2561
Tony Barbour8205d902015-04-16 15:59:00 -06002562VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002563{
2564 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2565 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002566 if (pCB->state == CB_UPDATE_ACTIVE) {
2567 updateCBTracking(cmdBuffer);
2568 addCmd(pCB, CMD_UPDATEBUFFER);
2569 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002570 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002571 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2572 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002573 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002574}
2575
Tony Barbour8205d902015-04-16 15:59:00 -06002576VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002577{
2578 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2579 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002580 if (pCB->state == CB_UPDATE_ACTIVE) {
2581 updateCBTracking(cmdBuffer);
2582 addCmd(pCB, CMD_FILLBUFFER);
2583 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002584 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002585 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2586 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002587 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002588}
2589
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002590VK_LAYER_EXPORT void VKAPI vkCmdClearColorAttachment(
2591 VkCmdBuffer cmdBuffer,
2592 uint32_t colorAttachment,
2593 VkImageLayout imageLayout,
2594 const VkClearColorValue* pColor,
2595 uint32_t rectCount,
2596 const VkRect3D* pRects)
2597{
2598 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2599 if (pCB) {
2600 if (pCB->state == CB_UPDATE_ACTIVE) {
2601 // Warn if this is issued prior to Draw Cmd
2602 if (!hasDrawCmd(pCB)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002603 // TODO : cmdBuffer should be srcObj
2604 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS",
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002605 "vkCmdClearColorAttachment() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
2606 " It is recommended you use RenderPass LOAD_OP_CLEAR on Color Attachments prior to any Draw.", reinterpret_cast<VkUintPtrLeast64>(cmdBuffer));
2607 }
Tobin Ehlis92a89912015-06-23 11:34:28 -06002608 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002609 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Tobin Ehlis92a89912015-06-23 11:34:28 -06002610 "Clear*Attachment cmd issued without an active RenderPass. vkCmdClearColorAttachment() must only be called inside of a RenderPass."
2611 " vkCmdClearColorImage() should be used outside of a RenderPass.");
2612 } else {
2613 updateCBTracking(cmdBuffer);
2614 addCmd(pCB, CMD_CLEARCOLORATTACHMENT);
2615 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdClearColorAttachment(cmdBuffer, colorAttachment, imageLayout, pColor, rectCount, pRects);
2616 }
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002617 } else {
2618 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2619 }
2620 }
2621}
2622
2623VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilAttachment(
2624 VkCmdBuffer cmdBuffer,
2625 VkImageAspectFlags imageAspectMask,
2626 VkImageLayout imageLayout,
2627 float depth,
2628 uint32_t stencil,
2629 uint32_t rectCount,
2630 const VkRect3D* pRects)
2631{
2632 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2633 if (pCB) {
2634 if (pCB->state == CB_UPDATE_ACTIVE) {
2635 // Warn if this is issued prior to Draw Cmd
2636 if (!hasDrawCmd(pCB)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002637 // TODO : cmdBuffer should be srcObj
2638 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS",
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002639 "vkCmdClearDepthStencilAttachment() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
2640 " It is recommended you use RenderPass LOAD_OP_CLEAR on DS Attachment prior to any Draw.", reinterpret_cast<VkUintPtrLeast64>(cmdBuffer));
2641 }
Tobin Ehlis92a89912015-06-23 11:34:28 -06002642 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002643 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Tobin Ehlis92a89912015-06-23 11:34:28 -06002644 "Clear*Attachment cmd issued without an active RenderPass. vkCmdClearDepthStencilAttachment() must only be called inside of a RenderPass."
2645 " vkCmdClearDepthStencilImage() should be used outside of a RenderPass.");
2646 } else {
2647 updateCBTracking(cmdBuffer);
2648 addCmd(pCB, CMD_CLEARDEPTHSTENCILATTACHMENT);
2649 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdClearDepthStencilAttachment(cmdBuffer, imageAspectMask, imageLayout, depth, stencil, rectCount, pRects);
2650 }
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002651 } else {
2652 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2653 }
2654 }
2655}
2656
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002657VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2658 VkCmdBuffer cmdBuffer,
2659 VkImage image, VkImageLayout imageLayout,
Chris Forbese3105972015-06-24 14:34:53 +12002660 const VkClearColorValue *pColor,
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002661 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002662{
2663 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2664 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002665 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlis92a89912015-06-23 11:34:28 -06002666 if (pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002667 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
Tobin Ehlis92a89912015-06-23 11:34:28 -06002668 "Clear*Image cmd issued with an active RenderPass. vkCmdClearColorImage() must only be called outside of a RenderPass."
2669 " vkCmdClearColorAttachment() should be used within a RenderPass.");
2670 } else {
2671 updateCBTracking(cmdBuffer);
2672 addCmd(pCB, CMD_CLEARCOLORIMAGE);
2673 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
2674 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002675 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002676 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2677 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002678 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002679}
2680
Chris Forbes2951d7d2015-06-22 17:21:59 +12002681VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(VkCmdBuffer cmdBuffer,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002682 VkImage image, VkImageLayout imageLayout,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002683 float depth, uint32_t stencil,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002684 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002685{
2686 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2687 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002688 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlis92a89912015-06-23 11:34:28 -06002689 if (pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002690 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
Tobin Ehlis92a89912015-06-23 11:34:28 -06002691 "Clear*Image cmd issued with an active RenderPass. vkCmdClearDepthStencilImage() must only be called outside of a RenderPass."
2692 " vkCmdClearDepthStencilAttachment() should be used within a RenderPass.");
2693 } else {
2694 updateCBTracking(cmdBuffer);
2695 addCmd(pCB, CMD_CLEARDEPTHSTENCILIMAGE);
2696 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdClearDepthStencilImage(cmdBuffer, image, imageLayout, depth, stencil, rangeCount, pRanges);
2697 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002698 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002699 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2700 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002701 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002702}
2703
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002704VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer,
2705 VkImage srcImage, VkImageLayout srcImageLayout,
2706 VkImage destImage, VkImageLayout destImageLayout,
Tony Barbour11f74372015-04-13 15:02:52 -06002707 uint32_t regionCount, const VkImageResolve* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002708{
2709 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2710 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002711 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise4076782015-06-24 15:53:07 -06002712 if (pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002713 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
2714 "Cannot call vkCmdResolveImage() during an active RenderPass (%#" PRIxLEAST64 ").", pCB->activeRenderPass.handle);
Tobin Ehlis92a89912015-06-23 11:34:28 -06002715 } else {
2716 updateCBTracking(cmdBuffer);
2717 addCmd(pCB, CMD_RESOLVEIMAGE);
Tobin Ehlise4076782015-06-24 15:53:07 -06002718 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis92a89912015-06-23 11:34:28 -06002719 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002720 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002721 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2722 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002723 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002724}
2725
Tony Barbourc2e987e2015-06-29 16:20:35 -06002726VK_LAYER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002727{
2728 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2729 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002730 if (pCB->state == CB_UPDATE_ACTIVE) {
2731 updateCBTracking(cmdBuffer);
2732 addCmd(pCB, CMD_SETEVENT);
Tony Barbourc2e987e2015-06-29 16:20:35 -06002733 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdSetEvent(cmdBuffer, event, stageMask);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002734 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002735 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2736 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002737 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002738}
2739
Tony Barbourc2e987e2015-06-29 16:20:35 -06002740VK_LAYER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002741{
2742 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2743 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002744 if (pCB->state == CB_UPDATE_ACTIVE) {
2745 updateCBTracking(cmdBuffer);
2746 addCmd(pCB, CMD_RESETEVENT);
Tony Barbourc2e987e2015-06-29 16:20:35 -06002747 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdResetEvent(cmdBuffer, event, stageMask);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002748 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002749 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2750 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002751 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002752}
2753
Courtney Goeltzenleuchterd9ba3422015-07-12 12:58:58 -06002754VK_LAYER_EXPORT void VKAPI vkCmdWaitEvents(VkCmdBuffer cmdBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags destStageMask, uint32_t memBarrierCount, const void* const* ppMemBarriers)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002755{
2756 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2757 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002758 if (pCB->state == CB_UPDATE_ACTIVE) {
2759 updateCBTracking(cmdBuffer);
2760 addCmd(pCB, CMD_WAITEVENTS);
Tony Barbourc2e987e2015-06-29 16:20:35 -06002761 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdWaitEvents(cmdBuffer, eventCount, pEvents, sourceStageMask, destStageMask, memBarrierCount, ppMemBarriers);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002762 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002763 report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
2764 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002765 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002766}
2767
Courtney Goeltzenleuchter82b348f2015-07-12 13:07:46 -06002768VK_LAYER_EXPORT void VKAPI vkCmdPipelineBarrier(VkCmdBuffer cmdBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, VkBool32 byRegion, uint32_t memBarrierCount, const void* const* ppMemBarriers)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002769{
2770 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2771 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002772 if (pCB->state == CB_UPDATE_ACTIVE) {
2773 updateCBTracking(cmdBuffer);
2774 addCmd(pCB, CMD_PIPELINEBARRIER);
Courtney Goeltzenleuchter73a21d32015-07-12 13:20:05 -06002775 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdPipelineBarrier(cmdBuffer, srcStageMask, destStageMask, byRegion, memBarrierCount, ppMemBarriers);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002776 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002777 report_error_no_cb_begin(cmdBuffer, "vkCmdPipelineBarrier()");
2778 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002779 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002780}
2781
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002782VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002783{
2784 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2785 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002786 if (pCB->state == CB_UPDATE_ACTIVE) {
2787 updateCBTracking(cmdBuffer);
2788 addCmd(pCB, CMD_BEGINQUERY);
2789 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002790 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002791 report_error_no_cb_begin(cmdBuffer, "vkCmdBeginQuery()");
2792 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002793 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002794}
2795
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002796VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002797{
2798 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2799 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002800 if (pCB->state == CB_UPDATE_ACTIVE) {
2801 updateCBTracking(cmdBuffer);
2802 addCmd(pCB, CMD_ENDQUERY);
2803 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdEndQuery(cmdBuffer, queryPool, slot);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002804 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002805 report_error_no_cb_begin(cmdBuffer, "vkCmdEndQuery()");
2806 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002807 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002808}
2809
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002810VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002811{
2812 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2813 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002814 if (pCB->state == CB_UPDATE_ACTIVE) {
2815 updateCBTracking(cmdBuffer);
2816 addCmd(pCB, CMD_RESETQUERYPOOL);
2817 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002818 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002819 report_error_no_cb_begin(cmdBuffer, "vkCmdResetQueryPool()");
2820 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002821 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002822}
2823
Tony Barbour8205d902015-04-16 15:59:00 -06002824VK_LAYER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002825{
2826 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2827 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002828 if (pCB->state == CB_UPDATE_ACTIVE) {
2829 updateCBTracking(cmdBuffer);
2830 addCmd(pCB, CMD_WRITETIMESTAMP);
2831 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002832 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002833 report_error_no_cb_begin(cmdBuffer, "vkCmdWriteTimestamp()");
2834 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002835 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002836}
2837
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002838VK_LAYER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002839{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002840 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateFramebuffer(device, pCreateInfo, pFramebuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002841 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002842 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002843 VkFramebufferCreateInfo* localFBCI = new VkFramebufferCreateInfo(*pCreateInfo);
Chia-I Wuc278df82015-07-07 11:50:03 +08002844 if (pCreateInfo->pAttachments) {
Cody Northropf110c6e2015-08-04 10:47:08 -06002845 localFBCI->pAttachments = new VkAttachmentView[localFBCI->attachmentCount];
2846 memcpy((void*)localFBCI->pAttachments, pCreateInfo->pAttachments, localFBCI->attachmentCount*sizeof(VkAttachmentView));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002847 }
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002848 frameBufferMap[pFramebuffer->handle] = localFBCI;
Tobin Ehlis2464b882015-04-01 08:40:34 -06002849 }
2850 return result;
2851}
2852
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002853VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002854{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002855 VkResult result = get_dispatch_table(draw_state_device_table_map, device)->CreateRenderPass(device, pCreateInfo, pRenderPass);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002856 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002857 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002858 VkRenderPassCreateInfo* localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
Chia-I Wuc278df82015-07-07 11:50:03 +08002859 if (pCreateInfo->pAttachments) {
2860 localRPCI->pAttachments = new VkAttachmentDescription[localRPCI->attachmentCount];
2861 memcpy((void*)localRPCI->pAttachments, pCreateInfo->pAttachments, localRPCI->attachmentCount*sizeof(VkAttachmentDescription));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002862 }
Chia-I Wuc278df82015-07-07 11:50:03 +08002863 if (pCreateInfo->pSubpasses) {
2864 localRPCI->pSubpasses = new VkSubpassDescription[localRPCI->subpassCount];
2865 memcpy((void*)localRPCI->pSubpasses, pCreateInfo->pSubpasses, localRPCI->subpassCount*sizeof(VkSubpassDescription));
2866
2867 for (uint32_t i = 0; i < localRPCI->subpassCount; i++) {
2868 VkSubpassDescription *subpass = (VkSubpassDescription *) &localRPCI->pSubpasses[i];
2869 const uint32_t attachmentCount = subpass->inputCount +
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002870 subpass->colorCount * (1 + (subpass->pResolveAttachments?1:0)) +
Chia-I Wuc278df82015-07-07 11:50:03 +08002871 subpass->preserveCount;
2872 VkAttachmentReference *attachments = new VkAttachmentReference[attachmentCount];
2873
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002874 memcpy(attachments, subpass->pInputAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08002875 sizeof(attachments[0]) * subpass->inputCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002876 subpass->pInputAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08002877 attachments += subpass->inputCount;
2878
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002879 memcpy(attachments, subpass->pColorAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08002880 sizeof(attachments[0]) * subpass->colorCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002881 subpass->pColorAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08002882 attachments += subpass->colorCount;
2883
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002884 if (subpass->pResolveAttachments) {
2885 memcpy(attachments, subpass->pResolveAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08002886 sizeof(attachments[0]) * subpass->colorCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002887 subpass->pResolveAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08002888 attachments += subpass->colorCount;
2889 }
2890
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002891 memcpy(attachments, subpass->pPreserveAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08002892 sizeof(attachments[0]) * subpass->preserveCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06002893 subpass->pPreserveAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08002894 }
Tobin Ehlis2464b882015-04-01 08:40:34 -06002895 }
Chia-I Wuc278df82015-07-07 11:50:03 +08002896 if (pCreateInfo->pDependencies) {
2897 localRPCI->pDependencies = new VkSubpassDependency[localRPCI->dependencyCount];
2898 memcpy((void*)localRPCI->pDependencies, pCreateInfo->pDependencies, localRPCI->dependencyCount*sizeof(VkSubpassDependency));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002899 }
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002900 renderPassMap[pRenderPass->handle] = localRPCI;
Tobin Ehlis2464b882015-04-01 08:40:34 -06002901 }
2902 return result;
2903}
2904
Chia-I Wuc278df82015-07-07 11:50:03 +08002905VK_LAYER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkRenderPassContents contents)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002906{
2907 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2908 if (pCB) {
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06002909 if (pRenderPassBegin && pRenderPassBegin->renderPass) {
Tobin Ehlise4076782015-06-24 15:53:07 -06002910 if (pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002911 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
2912 "Cannot call vkCmdBeginRenderPass() during an active RenderPass (%#" PRIxLEAST64 "). You must first call vkCmdEndRenderPass().", pCB->activeRenderPass.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002913 } else {
2914 updateCBTracking(cmdBuffer);
2915 addCmd(pCB, CMD_BEGINRENDERPASS);
2916 pCB->activeRenderPass = pRenderPassBegin->renderPass;
Chia-I Wuc278df82015-07-07 11:50:03 +08002917 pCB->activeSubpass = 0;
Tobin Ehlise4076782015-06-24 15:53:07 -06002918 pCB->framebuffer = pRenderPassBegin->framebuffer;
2919 if (pCB->lastBoundPipeline) {
2920 validatePipelineState(pCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
2921 }
Chia-I Wuc278df82015-07-07 11:50:03 +08002922 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin, contents);
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06002923 }
Tobin Ehlise4076782015-06-24 15:53:07 -06002924 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002925 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS, "DS",
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06002926 "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
Tony Barbourb9f82ba2015-04-06 11:09:26 -06002927 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002928 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002929}
2930
Chia-I Wuc278df82015-07-07 11:50:03 +08002931VK_LAYER_EXPORT void VKAPI vkCmdNextSubpass(VkCmdBuffer cmdBuffer, VkRenderPassContents contents)
2932{
2933 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2934 if (pCB) {
2935 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002936 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Chia-I Wuc278df82015-07-07 11:50:03 +08002937 "Incorrect call to vkCmdNextSubpass() without an active RenderPass.");
2938 } else {
2939 updateCBTracking(cmdBuffer);
2940 addCmd(pCB, CMD_NEXTSUBPASS);
2941 pCB->activeSubpass++;
2942 if (pCB->lastBoundPipeline) {
2943 validatePipelineState(pCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
2944 }
2945 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdNextSubpass(cmdBuffer, contents);
2946 }
2947 }
2948}
2949
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08002950VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002951{
2952 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2953 if (pCB) {
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08002954 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002955 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08002956 "Incorrect call to vkCmdEndRenderPass() without an active RenderPass.");
Tobin Ehlis536cfe42015-06-23 16:13:03 -06002957 } else {
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08002958 updateCBTracking(cmdBuffer);
2959 addCmd(pCB, CMD_ENDRENDERPASS);
2960 pCB->activeRenderPass = 0;
Chia-I Wuc278df82015-07-07 11:50:03 +08002961 pCB->activeSubpass = 0;
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08002962 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdEndRenderPass(cmdBuffer);
2963 }
2964 }
2965}
2966
2967VK_LAYER_EXPORT void VKAPI vkCmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers)
2968{
2969 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
2970 if (pCB) {
2971 if (!pCB->activeRenderPass) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002972 log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08002973 "Incorrect call to vkCmdExecuteCommands() without an active RenderPass.");
2974 } else {
2975 updateCBTracking(cmdBuffer);
2976 addCmd(pCB, CMD_EXECUTECOMMANDS);
2977 get_dispatch_table(draw_state_device_table_map, cmdBuffer)->CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06002978 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002979 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002980}
2981
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002982VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
2983 VkInstance instance,
2984 VkFlags msgFlags,
2985 const PFN_vkDbgMsgCallback pfnMsgCallback,
2986 void* pUserData,
2987 VkDbgMsgCallback* pMsgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002988{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06002989 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map, instance);
Tobin Ehlisc91330b2015-06-16 09:04:30 -06002990 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
2991 if (VK_SUCCESS == res) {
2992 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
2993 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
2994 }
2995 return res;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002996}
2997
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06002998VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
2999 VkInstance instance,
3000 VkDbgMsgCallback msgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003001{
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003002 VkLayerInstanceDispatchTable *pTable = get_dispatch_table(draw_state_instance_table_map, instance);
Tobin Ehlisc91330b2015-06-16 09:04:30 -06003003 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
3004 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
3005 layer_destroy_msg_callback(my_data->report_data, msgCallback);
3006 return res;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003007}
3008
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06003009VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003010{
3011 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003012 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) cmdBuffer;
3013 if (!deviceExtMap[pDisp].debug_marker_enabled) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003014 // TODO : cmdBuffer should be srcObj
3015 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_INVALID_EXTENSION, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06003016 "Attempt to use CmdDbgMarkerBegin but extension disabled!");
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003017 return;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06003018 } else if (pCB) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003019 updateCBTracking(cmdBuffer);
3020 addCmd(pCB, CMD_DBGMARKERBEGIN);
3021 }
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003022 debug_marker_dispatch_table(cmdBuffer)->CmdDbgMarkerBegin(cmdBuffer, pMarker);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003023}
3024
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06003025VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerEnd(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003026{
3027 GLOBAL_CB_NODE* pCB = getCBNode(cmdBuffer);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003028 VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) cmdBuffer;
3029 if (!deviceExtMap[pDisp].debug_marker_enabled) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003030 // TODO : cmdBuffer should be srcObj
3031 log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_INVALID_EXTENSION, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06003032 "Attempt to use CmdDbgMarkerEnd but extension disabled!");
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003033 return;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06003034 } else if (pCB) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003035 updateCBTracking(cmdBuffer);
3036 addCmd(pCB, CMD_DBGMARKEREND);
3037 }
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003038 debug_marker_dispatch_table(cmdBuffer)->CmdDbgMarkerEnd(cmdBuffer);
3039}
3040
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003041//VK_LAYER_EXPORT VkResult VKAPI vkDbgSetObjectTag(VkDevice device, VkObjectType objType, VkObject object, size_t tagSize, const void* pTag)
3042//{
3043// VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
3044// if (!deviceExtMap[pDisp].debug_marker_enabled) {
3045// log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, objType, object, 0, DRAWSTATE_INVALID_EXTENSION, "DS",
3046// "Attempt to use DbgSetObjectTag but extension disabled!");
3047// return VK_ERROR_UNAVAILABLE;
3048// }
3049// debug_marker_dispatch_table(device)->DbgSetObjectTag(device, objType, object, tagSize, pTag);
3050//}
3051//
3052//VK_LAYER_EXPORT VkResult VKAPI vkDbgSetObjectName(VkDevice device, VkObjectType objType, VkObject object, size_t nameSize, const char* pName)
3053//{
3054// VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) device;
3055// if (!deviceExtMap[pDisp].debug_marker_enabled) {
3056// log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, objType, object, 0, DRAWSTATE_INVALID_EXTENSION, "DS",
3057// "Attempt to use DbgSetObjectName but extension disabled!");
3058// return VK_ERROR_UNAVAILABLE;
3059// }
3060// debug_marker_dispatch_table(device)->DbgSetObjectName(device, objType, object, nameSize, pName);
3061//}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003062
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003063VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003064{
Jon Ashburn1245cec2015-05-18 13:20:15 -06003065 if (dev == NULL)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003066 return NULL;
Jon Ashburne0fa2282015-05-20 09:00:28 -06003067
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003068 /* loader uses this to force layer initialization; device object is wrapped */
3069 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003070 initDeviceTable(draw_state_device_table_map, (const VkBaseLayerObject *) dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003071 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003072 }
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06003073 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003074 return (PFN_vkVoidFunction) vkCreateDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003075 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003076 return (PFN_vkVoidFunction) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003077 if (!strcmp(funcName, "vkQueueSubmit"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003078 return (PFN_vkVoidFunction) vkQueueSubmit;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003079 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003080 return (PFN_vkVoidFunction) vkDestroyInstance;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003081 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003082 return (PFN_vkVoidFunction) vkDestroyDevice;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003083 if (!strcmp(funcName, "vkDestroyFence"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003084 return (PFN_vkVoidFunction) vkDestroyFence;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003085 if (!strcmp(funcName, "vkDestroySemaphore"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003086 return (PFN_vkVoidFunction) vkDestroySemaphore;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003087 if (!strcmp(funcName, "vkDestroyEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003088 return (PFN_vkVoidFunction) vkDestroyEvent;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003089 if (!strcmp(funcName, "vkDestroyQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003090 return (PFN_vkVoidFunction) vkDestroyQueryPool;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003091 if (!strcmp(funcName, "vkDestroyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003092 return (PFN_vkVoidFunction) vkDestroyBuffer;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003093 if (!strcmp(funcName, "vkDestroyBufferView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003094 return (PFN_vkVoidFunction) vkDestroyBufferView;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003095 if (!strcmp(funcName, "vkDestroyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003096 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003097 if (!strcmp(funcName, "vkDestroyImageView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003098 return (PFN_vkVoidFunction) vkDestroyImageView;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003099 if (!strcmp(funcName, "vkDestroyAttachmentView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003100 return (PFN_vkVoidFunction) vkDestroyAttachmentView;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003101 if (!strcmp(funcName, "vkDestroyShaderModule"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003102 return (PFN_vkVoidFunction) vkDestroyShaderModule;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003103 if (!strcmp(funcName, "vkDestroyShader"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003104 return (PFN_vkVoidFunction) vkDestroyShader;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003105 if (!strcmp(funcName, "vkDestroyPipeline"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003106 return (PFN_vkVoidFunction) vkDestroyPipeline;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003107 if (!strcmp(funcName, "vkDestroyPipelineLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003108 return (PFN_vkVoidFunction) vkDestroyPipelineLayout;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003109 if (!strcmp(funcName, "vkDestroySampler"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003110 return (PFN_vkVoidFunction) vkDestroySampler;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003111 if (!strcmp(funcName, "vkDestroyDescriptorSetLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003112 return (PFN_vkVoidFunction) vkDestroyDescriptorSetLayout;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003113 if (!strcmp(funcName, "vkDestroyDescriptorPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003114 return (PFN_vkVoidFunction) vkDestroyDescriptorPool;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003115 if (!strcmp(funcName, "vkDestroyDynamicViewportState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003116 return (PFN_vkVoidFunction) vkDestroyDynamicViewportState;
Cody Northropf5bd2252015-08-17 11:10:49 -06003117 if (!strcmp(funcName, "vkDestroyDynamicRasterLineState"))
3118 return (PFN_vkVoidFunction) vkDestroyDynamicRasterLineState;
3119 if (!strcmp(funcName, "vkDestroyDynamicRasterDepthBiasState"))
3120 return (PFN_vkVoidFunction) vkDestroyDynamicRasterDepthBiasState;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003121 if (!strcmp(funcName, "vkDestroyDynamicColorBlendState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003122 return (PFN_vkVoidFunction) vkDestroyDynamicColorBlendState;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003123 if (!strcmp(funcName, "vkDestroyDynamicDepthStencilState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003124 return (PFN_vkVoidFunction) vkDestroyDynamicDepthStencilState;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003125 if (!strcmp(funcName, "vkDestroyCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003126 return (PFN_vkVoidFunction) vkDestroyCommandBuffer;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003127 if (!strcmp(funcName, "vkDestroyFramebuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003128 return (PFN_vkVoidFunction) vkDestroyFramebuffer;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003129 if (!strcmp(funcName, "vkDestroyRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003130 return (PFN_vkVoidFunction) vkDestroyRenderPass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003131 if (!strcmp(funcName, "vkCreateBufferView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003132 return (PFN_vkVoidFunction) vkCreateBufferView;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003133 if (!strcmp(funcName, "vkCreateImageView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003134 return (PFN_vkVoidFunction) vkCreateImageView;
Tobin Ehlis44c757d2015-07-10 12:15:19 -06003135 if (!strcmp(funcName, "vkCreateAttachmentView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003136 return (PFN_vkVoidFunction) vkCreateAttachmentView;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003137 if (!strcmp(funcName, "CreatePipelineCache"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003138 return (PFN_vkVoidFunction) vkCreatePipelineCache;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003139 if (!strcmp(funcName, "DestroyPipelineCache"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003140 return (PFN_vkVoidFunction) vkDestroyPipelineCache;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003141 if (!strcmp(funcName, "GetPipelineCacheSize"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003142 return (PFN_vkVoidFunction) vkGetPipelineCacheSize;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003143 if (!strcmp(funcName, "GetPipelineCacheData"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003144 return (PFN_vkVoidFunction) vkGetPipelineCacheData;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003145 if (!strcmp(funcName, "MergePipelineCaches"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003146 return (PFN_vkVoidFunction) vkMergePipelineCaches;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003147 if (!strcmp(funcName, "vkCreateGraphicsPipelines"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003148 return (PFN_vkVoidFunction) vkCreateGraphicsPipelines;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003149 if (!strcmp(funcName, "vkCreateSampler"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003150 return (PFN_vkVoidFunction) vkCreateSampler;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003151 if (!strcmp(funcName, "vkCreateDescriptorSetLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003152 return (PFN_vkVoidFunction) vkCreateDescriptorSetLayout;
Mark Lobodzinski556f7212015-04-17 14:11:39 -05003153 if (!strcmp(funcName, "vkCreatePipelineLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003154 return (PFN_vkVoidFunction) vkCreatePipelineLayout;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003155 if (!strcmp(funcName, "vkCreateDescriptorPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003156 return (PFN_vkVoidFunction) vkCreateDescriptorPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003157 if (!strcmp(funcName, "vkResetDescriptorPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003158 return (PFN_vkVoidFunction) vkResetDescriptorPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003159 if (!strcmp(funcName, "vkAllocDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003160 return (PFN_vkVoidFunction) vkAllocDescriptorSets;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08003161 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003162 return (PFN_vkVoidFunction) vkUpdateDescriptorSets;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003163 if (!strcmp(funcName, "vkCreateDynamicViewportState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003164 return (PFN_vkVoidFunction) vkCreateDynamicViewportState;
Cody Northropf5bd2252015-08-17 11:10:49 -06003165 if (!strcmp(funcName, "vkCreateDynamicRasterLineState"))
3166 return (PFN_vkVoidFunction) vkCreateDynamicRasterLineState;
3167 if (!strcmp(funcName, "vkCreateDynamicRasterDepthBiasState"))
3168 return (PFN_vkVoidFunction) vkCreateDynamicRasterDepthBiasState;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003169 if (!strcmp(funcName, "vkCreateDynamicColorBlendState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003170 return (PFN_vkVoidFunction) vkCreateDynamicColorBlendState;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003171 if (!strcmp(funcName, "vkCreateDynamicDepthStencilState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003172 return (PFN_vkVoidFunction) vkCreateDynamicDepthStencilState;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003173 if (!strcmp(funcName, "vkCreateCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003174 return (PFN_vkVoidFunction) vkCreateCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003175 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003176 return (PFN_vkVoidFunction) vkBeginCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003177 if (!strcmp(funcName, "vkEndCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003178 return (PFN_vkVoidFunction) vkEndCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003179 if (!strcmp(funcName, "vkResetCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003180 return (PFN_vkVoidFunction) vkResetCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003181 if (!strcmp(funcName, "vkCmdBindPipeline"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003182 return (PFN_vkVoidFunction) vkCmdBindPipeline;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003183 if (!strcmp(funcName, "vkCmdBindDynamicViewportState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003184 return (PFN_vkVoidFunction) vkCmdBindDynamicViewportState;
Cody Northropf5bd2252015-08-17 11:10:49 -06003185 if (!strcmp(funcName, "vkCmdBindDynamicRasterLineState"))
3186 return (PFN_vkVoidFunction) vkCmdBindDynamicRasterLineState;
3187 if (!strcmp(funcName, "vkCmdBindDynamicRasterDepthBiasState"))
3188 return (PFN_vkVoidFunction) vkCmdBindDynamicRasterDepthBiasState;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003189 if (!strcmp(funcName, "vkCmdBindDynamicColorBlendState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003190 return (PFN_vkVoidFunction) vkCmdBindDynamicColorBlendState;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003191 if (!strcmp(funcName, "vkCmdBindDynamicDepthStencilState"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003192 return (PFN_vkVoidFunction) vkCmdBindDynamicDepthStencilState;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003193 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003194 return (PFN_vkVoidFunction) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06003195 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003196 return (PFN_vkVoidFunction) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003197 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003198 return (PFN_vkVoidFunction) vkCmdBindIndexBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003199 if (!strcmp(funcName, "vkCmdDraw"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003200 return (PFN_vkVoidFunction) vkCmdDraw;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003201 if (!strcmp(funcName, "vkCmdDrawIndexed"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003202 return (PFN_vkVoidFunction) vkCmdDrawIndexed;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003203 if (!strcmp(funcName, "vkCmdDrawIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003204 return (PFN_vkVoidFunction) vkCmdDrawIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003205 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003206 return (PFN_vkVoidFunction) vkCmdDrawIndexedIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003207 if (!strcmp(funcName, "vkCmdDispatch"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003208 return (PFN_vkVoidFunction) vkCmdDispatch;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003209 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003210 return (PFN_vkVoidFunction) vkCmdDispatchIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003211 if (!strcmp(funcName, "vkCmdCopyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003212 return (PFN_vkVoidFunction) vkCmdCopyBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003213 if (!strcmp(funcName, "vkCmdCopyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003214 return (PFN_vkVoidFunction) vkCmdCopyImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003215 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003216 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003217 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003218 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003219 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003220 return (PFN_vkVoidFunction) vkCmdUpdateBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003221 if (!strcmp(funcName, "vkCmdFillBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003222 return (PFN_vkVoidFunction) vkCmdFillBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003223 if (!strcmp(funcName, "vkCmdClearColorImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003224 return (PFN_vkVoidFunction) vkCmdClearColorImage;
Chris Forbes2951d7d2015-06-22 17:21:59 +12003225 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003226 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06003227 if (!strcmp(funcName, "vkCmdClearColorAttachment"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003228 return (PFN_vkVoidFunction) vkCmdClearColorAttachment;
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06003229 if (!strcmp(funcName, "vkCmdClearDepthStencilAttachment"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003230 return (PFN_vkVoidFunction) vkCmdClearDepthStencilAttachment;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003231 if (!strcmp(funcName, "vkCmdResolveImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003232 return (PFN_vkVoidFunction) vkCmdResolveImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003233 if (!strcmp(funcName, "vkCmdSetEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003234 return (PFN_vkVoidFunction) vkCmdSetEvent;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003235 if (!strcmp(funcName, "vkCmdResetEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003236 return (PFN_vkVoidFunction) vkCmdResetEvent;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003237 if (!strcmp(funcName, "vkCmdWaitEvents"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003238 return (PFN_vkVoidFunction) vkCmdWaitEvents;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003239 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003240 return (PFN_vkVoidFunction) vkCmdPipelineBarrier;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003241 if (!strcmp(funcName, "vkCmdBeginQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003242 return (PFN_vkVoidFunction) vkCmdBeginQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003243 if (!strcmp(funcName, "vkCmdEndQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003244 return (PFN_vkVoidFunction) vkCmdEndQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003245 if (!strcmp(funcName, "vkCmdResetQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003246 return (PFN_vkVoidFunction) vkCmdResetQueryPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003247 if (!strcmp(funcName, "vkCmdWriteTimestamp"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003248 return (PFN_vkVoidFunction) vkCmdWriteTimestamp;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003249 if (!strcmp(funcName, "vkCreateFramebuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003250 return (PFN_vkVoidFunction) vkCreateFramebuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003251 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003252 return (PFN_vkVoidFunction) vkCreateRenderPass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003253 if (!strcmp(funcName, "vkCmdBeginRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003254 return (PFN_vkVoidFunction) vkCmdBeginRenderPass;
Chia-I Wuc278df82015-07-07 11:50:03 +08003255 if (!strcmp(funcName, "vkCmdNextSubpass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003256 return (PFN_vkVoidFunction) vkCmdNextSubpass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003257 if (!strcmp(funcName, "vkCmdEndRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003258 return (PFN_vkVoidFunction) vkCmdEndRenderPass;
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003259
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003260 VkLayerDispatchTable* pTable = get_dispatch_table(draw_state_device_table_map, dev);
3261 if (deviceExtMap.size() == 0 || deviceExtMap[pTable].debug_marker_enabled)
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003262 {
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003263 if (!strcmp(funcName, "vkCmdDbgMarkerBegin"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003264 return (PFN_vkVoidFunction) vkCmdDbgMarkerBegin;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003265 if (!strcmp(funcName, "vkCmdDbgMarkerEnd"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003266 return (PFN_vkVoidFunction) vkCmdDbgMarkerEnd;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003267// if (!strcmp(funcName, "vkDbgSetObjectTag"))
3268// return (void*) vkDbgSetObjectTag;
3269// if (!strcmp(funcName, "vkDbgSetObjectName"))
3270// return (void*) vkDbgSetObjectName;
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003271 }
3272 {
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003273 if (pTable->GetDeviceProcAddr == NULL)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003274 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003275 return pTable->GetDeviceProcAddr(dev, funcName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003276 }
3277}
3278
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003279VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003280{
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003281 PFN_vkVoidFunction fptr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003282 if (instance == NULL)
3283 return NULL;
3284
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003285 /* loader uses this to force layer initialization; instance object is wrapped */
3286 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003287 initInstanceTable(draw_state_instance_table_map, (const VkBaseLayerObject *) instance);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003288 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003289 }
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06003290 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003291 return (PFN_vkVoidFunction) vkCreateInstance;
Jon Ashburne0fa2282015-05-20 09:00:28 -06003292 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003293 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06003294 if (!strcmp(funcName, "vkGetGlobalLayerProperties"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003295 return (PFN_vkVoidFunction) vkGetGlobalLayerProperties;
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06003296 if (!strcmp(funcName, "vkGetGlobalExtensionProperties"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003297 return (PFN_vkVoidFunction) vkGetGlobalExtensionProperties;
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06003298 if (!strcmp(funcName, "vkGetPhysicalDeviceLayerProperties"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003299 return (PFN_vkVoidFunction) vkGetPhysicalDeviceLayerProperties;
Tony Barbour426b9052015-06-24 16:06:58 -06003300 if (!strcmp(funcName, "vkGetPhysicalDeviceExtensionProperties"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003301 return (PFN_vkVoidFunction) vkGetPhysicalDeviceExtensionProperties;
Courtney Goeltzenleuchtercc899fe2015-06-01 14:33:14 -06003302
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06003303 layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
3304 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Courtney Goeltzenleuchtercc899fe2015-06-01 14:33:14 -06003305 if (fptr)
3306 return fptr;
3307
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003308 {
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -06003309 VkLayerInstanceDispatchTable* pTable = get_dispatch_table(draw_state_instance_table_map, instance);
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003310 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003311 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003312 return pTable->GetInstanceProcAddr(instance, funcName);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003313 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003314}