blob: 398393d44e6d0038650e2c55f4bab81f7146fbd1 [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_table.h"
47#include "vk_layer_debug_marker_table.h"
48#include "vk_layer_data.h"
49#include "vk_layer_logging.h"
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -060050#include "vk_layer_extension_utils.h"
Tobin Ehlis63bb9482015-03-17 16:24:32 -060051
Tobin Ehlise6ab55a2015-10-07 09:38:40 -060052struct devExts {
53 bool debug_marker_enabled;
54};
55
Cody Northrop73bb6572015-09-28 15:09:32 -060056struct layer_data {
Tobin Ehlisc91330b2015-06-16 09:04:30 -060057 debug_report_data *report_data;
58 // TODO: put instance data here
Courtney Goeltzenleuchter1781b1c2015-10-05 15:58:38 -060059 std::vector<VkDbgMsgCallback> logging_callback;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -060060 VkLayerDispatchTable* device_dispatch_table;
61 VkLayerInstanceDispatchTable* instance_dispatch_table;
62 devExts device_extensions;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -060063 // Layer specific data
64 unordered_map<uint64_t, unique_ptr<SAMPLER_NODE>> sampleMap;
65 unordered_map<uint64_t, unique_ptr<VkImageViewCreateInfo>> imageViewMap;
66 unordered_map<uint64_t, unique_ptr<BUFFER_NODE>> bufferViewMap;
67 unordered_map<uint64_t, PIPELINE_NODE*> pipelineMap;
68 unordered_map<uint64_t, POOL_NODE*> poolMap;
69 unordered_map<uint64_t, SET_NODE*> setMap;
70 unordered_map<uint64_t, LAYOUT_NODE*> layoutMap;
71 // Map for layout chains
72 unordered_map<void*, GLOBAL_CB_NODE*> cmdBufferMap;
73 unordered_map<uint64_t, VkRenderPassCreateInfo*> renderPassMap;
74 unordered_map<uint64_t, VkFramebufferCreateInfo*> frameBufferMap;
Cody Northrop73bb6572015-09-28 15:09:32 -060075
76 layer_data() :
77 report_data(nullptr),
Tobin Ehlise6ab55a2015-10-07 09:38:40 -060078 device_dispatch_table(nullptr),
79 instance_dispatch_table(nullptr),
80 device_extensions()
Cody Northrop73bb6572015-09-28 15:09:32 -060081 {};
82};
Tobin Ehlisd04ccab2015-10-07 15:40:22 -060083// TODO : Do we need to guard access to layer_data_map w/ lock?
Tobin Ehlisc91330b2015-06-16 09:04:30 -060084static std::unordered_map<void *, layer_data *> layer_data_map;
Courtney Goeltzenleuchterc280adc2015-06-13 21:23:09 -060085
Tobin Ehlis63bb9482015-03-17 16:24:32 -060086static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
Jon Ashburnd9564002015-05-07 10:27:37 -060087
Tobin Ehlis63bb9482015-03-17 16:24:32 -060088// TODO : This can be much smarter, using separate locks for separate global data
89static int globalLockInitialized = 0;
90static loader_platform_thread_mutex globalLock;
Tobin Ehlis63bb9482015-03-17 16:24:32 -060091#define MAX_TID 513
92static loader_platform_thread_id g_tidMapping[MAX_TID] = {0};
93static uint32_t g_maxTID = 0;
Tobin Ehlisfde4dce2015-06-16 15:50:44 -060094
95template layer_data *get_my_data_ptr<layer_data>(
96 void *data_key,
97 std::unordered_map<void *, layer_data *> &data_map);
98
Tobin Ehlis1dce5f12015-07-07 10:42:20 -060099debug_report_data *mdd(void* object)
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600100{
101 dispatch_key key = get_dispatch_key(object);
102 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
103#if DISPATCH_MAP_DEBUG
104 fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
105#endif
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600106 return my_data->report_data;
107}
108
109debug_report_data *mid(VkInstance object)
110{
111 dispatch_key key = get_dispatch_key(object);
Tobin Ehlis8354e022015-09-01 11:46:36 -0600112 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600113#if DISPATCH_MAP_DEBUG
114 fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
115#endif
Tobin Ehlisfde4dce2015-06-16 15:50:44 -0600116 return my_data->report_data;
117}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600118// Map actual TID to an index value and return that index
119// This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs
120static uint32_t getTIDIndex() {
121 loader_platform_thread_id tid = loader_platform_get_thread_id();
122 for (uint32_t i = 0; i < g_maxTID; i++) {
123 if (tid == g_tidMapping[i])
124 return i;
125 }
126 // Don't yet have mapping, set it and return newly set index
127 uint32_t retVal = (uint32_t) g_maxTID;
128 g_tidMapping[g_maxTID++] = tid;
129 assert(g_maxTID < MAX_TID);
130 return retVal;
131}
132// Return a string representation of CMD_TYPE enum
133static string cmdTypeToString(CMD_TYPE cmd)
134{
135 switch (cmd)
136 {
137 case CMD_BINDPIPELINE:
138 return "CMD_BINDPIPELINE";
139 case CMD_BINDPIPELINEDELTA:
140 return "CMD_BINDPIPELINEDELTA";
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -0600141 case CMD_SETVIEWPORTSTATE:
142 return "CMD_SETVIEWPORTSTATE";
143 case CMD_SETLINEWIDTHSTATE:
144 return "CMD_SETLINEWIDTHSTATE";
145 case CMD_SETDEPTHBIASSTATE:
146 return "CMD_SETDEPTHBIASSTATE";
147 case CMD_SETBLENDSTATE:
148 return "CMD_SETBLENDSTATE";
149 case CMD_SETDEPTHBOUNDSSTATE:
150 return "CMD_SETDEPTHBOUNDSSTATE";
151 case CMD_SETSTENCILREADMASKSTATE:
152 return "CMD_SETSTENCILREADMASKSTATE";
153 case CMD_SETSTENCILWRITEMASKSTATE:
154 return "CMD_SETSTENCILWRITEMASKSTATE";
155 case CMD_SETSTENCILREFERENCESTATE:
156 return "CMD_SETSTENCILREFERENCESTATE";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600157 case CMD_BINDDESCRIPTORSETS:
158 return "CMD_BINDDESCRIPTORSETS";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600159 case CMD_BINDINDEXBUFFER:
160 return "CMD_BINDINDEXBUFFER";
161 case CMD_BINDVERTEXBUFFER:
162 return "CMD_BINDVERTEXBUFFER";
163 case CMD_DRAW:
164 return "CMD_DRAW";
165 case CMD_DRAWINDEXED:
166 return "CMD_DRAWINDEXED";
167 case CMD_DRAWINDIRECT:
168 return "CMD_DRAWINDIRECT";
169 case CMD_DRAWINDEXEDINDIRECT:
170 return "CMD_DRAWINDEXEDINDIRECT";
171 case CMD_DISPATCH:
172 return "CMD_DISPATCH";
173 case CMD_DISPATCHINDIRECT:
174 return "CMD_DISPATCHINDIRECT";
175 case CMD_COPYBUFFER:
176 return "CMD_COPYBUFFER";
177 case CMD_COPYIMAGE:
178 return "CMD_COPYIMAGE";
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600179 case CMD_BLITIMAGE:
180 return "CMD_BLITIMAGE";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600181 case CMD_COPYBUFFERTOIMAGE:
182 return "CMD_COPYBUFFERTOIMAGE";
183 case CMD_COPYIMAGETOBUFFER:
184 return "CMD_COPYIMAGETOBUFFER";
185 case CMD_CLONEIMAGEDATA:
186 return "CMD_CLONEIMAGEDATA";
187 case CMD_UPDATEBUFFER:
188 return "CMD_UPDATEBUFFER";
189 case CMD_FILLBUFFER:
190 return "CMD_FILLBUFFER";
191 case CMD_CLEARCOLORIMAGE:
192 return "CMD_CLEARCOLORIMAGE";
Tobin Ehlis8cd650e2015-07-01 16:46:13 -0600193 case CMD_CLEARCOLORATTACHMENT:
194 return "CMD_CLEARCOLORATTACHMENT";
195 case CMD_CLEARDEPTHSTENCILIMAGE:
196 return "CMD_CLEARDEPTHSTENCILIMAGE";
197 case CMD_CLEARDEPTHSTENCILATTACHMENT:
198 return "CMD_CLEARDEPTHSTENCILATTACHMENT";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600199 case CMD_RESOLVEIMAGE:
200 return "CMD_RESOLVEIMAGE";
201 case CMD_SETEVENT:
202 return "CMD_SETEVENT";
203 case CMD_RESETEVENT:
204 return "CMD_RESETEVENT";
205 case CMD_WAITEVENTS:
206 return "CMD_WAITEVENTS";
207 case CMD_PIPELINEBARRIER:
208 return "CMD_PIPELINEBARRIER";
209 case CMD_BEGINQUERY:
210 return "CMD_BEGINQUERY";
211 case CMD_ENDQUERY:
212 return "CMD_ENDQUERY";
213 case CMD_RESETQUERYPOOL:
214 return "CMD_RESETQUERYPOOL";
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -0600215 case CMD_COPYQUERYPOOLRESULTS:
216 return "CMD_COPYQUERYPOOLRESULTS";
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600217 case CMD_WRITETIMESTAMP:
218 return "CMD_WRITETIMESTAMP";
219 case CMD_INITATOMICCOUNTERS:
220 return "CMD_INITATOMICCOUNTERS";
221 case CMD_LOADATOMICCOUNTERS:
222 return "CMD_LOADATOMICCOUNTERS";
223 case CMD_SAVEATOMICCOUNTERS:
224 return "CMD_SAVEATOMICCOUNTERS";
225 case CMD_BEGINRENDERPASS:
226 return "CMD_BEGINRENDERPASS";
227 case CMD_ENDRENDERPASS:
228 return "CMD_ENDRENDERPASS";
229 case CMD_DBGMARKERBEGIN:
230 return "CMD_DBGMARKERBEGIN";
231 case CMD_DBGMARKEREND:
232 return "CMD_DBGMARKEREND";
233 default:
234 return "UNKNOWN";
235 }
236}
237// Block of code at start here for managing/tracking Pipeline state that this layer cares about
238// Just track 2 shaders for now
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600239#define VK_NUM_GRAPHICS_SHADERS VK_SHADER_STAGE_COMPUTE
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600240#define MAX_SLOTS 2048
241#define NUM_COMMAND_BUFFERS_TO_DISPLAY 10
242
243static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0};
244
245// TODO : Should be tracking lastBound per cmdBuffer and when draws occur, report based on that cmd buffer lastBound
246// Then need to synchronize the accesses based on cmd buffer so that if I'm reading state on one cmd buffer, updates
247// to that same cmd buffer by separate thread are not changing state from underneath us
248// Track the last cmd buffer touched by this thread
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600249static VkCmdBuffer g_lastCmdBuffer[MAX_TID] = {NULL};
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600250// Track the last group of CBs touched for displaying to dot file
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600251static GLOBAL_CB_NODE* g_pLastTouchedCB[NUM_COMMAND_BUFFERS_TO_DISPLAY] = {NULL};
252static uint32_t g_lastTouchedCBIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600253// Track the last global DrawState of interest touched by any thread
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600254static GLOBAL_CB_NODE* g_lastGlobalCB = NULL;
255static PIPELINE_NODE* g_lastBoundPipeline = NULL;
Dana Jansens4a3e0862015-07-30 13:22:15 -0700256static VkDescriptorSet g_lastBoundDescriptorSet = VK_NULL_HANDLE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600257#define MAX_BINDING 0xFFFFFFFF // Default vtxBinding value in CB Node to identify if no vtxBinding set
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600258// prototype
259static GLOBAL_CB_NODE* getCBNode(layer_data*, const VkCmdBuffer);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -0600260// Update global ptrs to reflect that specified cmdBuffer has been used
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600261static void updateCBTracking(GLOBAL_CB_NODE* pCB)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600262{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600263 g_lastCmdBuffer[getTIDIndex()] = pCB->cmdBuffer;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600264 loader_platform_thread_lock_mutex(&globalLock);
265 g_lastGlobalCB = pCB;
266 // TODO : This is a dumb algorithm. Need smart LRU that drops off oldest
267 for (uint32_t i = 0; i < NUM_COMMAND_BUFFERS_TO_DISPLAY; i++) {
268 if (g_pLastTouchedCB[i] == pCB) {
269 loader_platform_thread_unlock_mutex(&globalLock);
270 return;
271 }
272 }
273 g_pLastTouchedCB[g_lastTouchedCBIndex++] = pCB;
274 g_lastTouchedCBIndex = g_lastTouchedCBIndex % NUM_COMMAND_BUFFERS_TO_DISPLAY;
275 loader_platform_thread_unlock_mutex(&globalLock);
276}
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600277static VkBool32 hasDrawCmd(GLOBAL_CB_NODE* pCB)
Tobin Ehlis8cd650e2015-07-01 16:46:13 -0600278{
279 for (uint32_t i=0; i<NUM_DRAW_TYPES; i++) {
280 if (pCB->drawCount[i])
281 return VK_TRUE;
282 }
283 return VK_FALSE;
284}
Tobin Ehlis97866202015-06-10 12:57:07 -0600285// Check object status for selected flag state
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600286static 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 -0600287{
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600288 // If non-zero enable mask is present, check it against status but if enable_mask
289 // is 0 then no enable required so we should always just check status
290 if ((!enable_mask) || (enable_mask & pNode->status)) {
291 if ((pNode->status & status_mask) != status_flag) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -0600292 // TODO : How to pass dispatchable objects as srcObject? Here src obj should be cmd buffer
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600293 return log_msg(mdd(pNode->cmdBuffer), msg_flags, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, error_code, "DS",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -0600294 "CB object %#" PRIxLEAST64 ": %s", reinterpret_cast<uint64_t>(pNode->cmdBuffer), fail_msg);
Tobin Ehlis97866202015-06-10 12:57:07 -0600295 }
Tobin Ehlis97866202015-06-10 12:57:07 -0600296 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600297 return VK_FALSE;
Tobin Ehlis97866202015-06-10 12:57:07 -0600298}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600299// Retrieve pipeline node ptr for given pipeline object
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600300static PIPELINE_NODE* getPipeline(layer_data* my_data, const VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600301{
302 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600303 if (my_data->pipelineMap.find(pipeline.handle) == my_data->pipelineMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600304 loader_platform_thread_unlock_mutex(&globalLock);
305 return NULL;
306 }
307 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600308 return my_data->pipelineMap[pipeline.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600309}
Tobin Ehlisa88e2f52015-10-02 11:00:56 -0600310// Return VK_TRUE if for a given PSO, the given state enum is dynamic, else return VK_FALSE
311static VkBool32 isDynamic(const PIPELINE_NODE* pPipeline, const VkDynamicState state)
312{
313 if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) {
314 for (uint32_t i=0; i<pPipeline->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) {
315 if (state == pPipeline->graphicsPipelineCI.pDynamicState->pDynamicStates[i])
316 return VK_TRUE;
317 }
318 }
319 return VK_FALSE;
320}
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600321// Validate state stored as flags at time of draw call
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600322static VkBool32 validate_draw_state_flags(GLOBAL_CB_NODE* pCB, VkBool32 indexedDraw) {
323 VkBool32 result;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -0600324 result = validate_status(pCB, CBSTATUS_NONE, CBSTATUS_VIEWPORT_SET, CBSTATUS_VIEWPORT_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_VIEWPORT_NOT_BOUND, "Dynamic viewport state not set for this command buffer");
325 result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_SCISSOR_SET, CBSTATUS_SCISSOR_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic scissor state not set for this command buffer");
326 result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_LINE_WIDTH_SET, CBSTATUS_LINE_WIDTH_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_LINE_WIDTH_NOT_BOUND, "Dynamic line width state not set for this command buffer");
327 result |= validate_status(pCB, CBSTATUS_NONE, CBSTATUS_DEPTH_BIAS_SET, CBSTATUS_DEPTH_BIAS_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_BIAS_NOT_BOUND, "Dynamic depth bias state not set for this command buffer");
328 result |= validate_status(pCB, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_BLEND_SET, CBSTATUS_BLEND_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_BLEND_NOT_BOUND, "Dynamic blend object state not set for this command buffer");
329 result |= validate_status(pCB, CBSTATUS_DEPTH_WRITE_ENABLE, CBSTATUS_DEPTH_BOUNDS_SET, CBSTATUS_DEPTH_BOUNDS_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, "Dynamic depth bounds state not set for this command buffer");
330 result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_READ_MASK_SET, CBSTATUS_STENCIL_READ_MASK_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil read mask state not set for this command buffer");
331 result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_WRITE_MASK_SET, CBSTATUS_STENCIL_WRITE_MASK_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil write mask state not set for this command buffer");
332 result |= validate_status(pCB, CBSTATUS_STENCIL_TEST_ENABLE, CBSTATUS_STENCIL_REFERENCE_SET, CBSTATUS_STENCIL_REFERENCE_SET, VK_DBG_REPORT_ERROR_BIT, DRAWSTATE_STENCIL_NOT_BOUND, "Dynamic stencil reference state not set for this command buffer");
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600333 if (indexedDraw)
Tobin Ehlisf6cb4672015-09-29 08:18:34 -0600334 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 Indexed Draw attempted");
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600335 return result;
336}
337// Validate overall state at the time of a draw call
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600338static VkBool32 validate_draw_state(layer_data* my_data, GLOBAL_CB_NODE* pCB, VkBool32 indexedDraw) {
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600339 // First check flag states
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600340 VkBool32 result = validate_draw_state_flags(pCB, indexedDraw);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600341 PIPELINE_NODE* pPipe = getPipeline(my_data, pCB->lastBoundPipeline);
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600342 // Now complete other state checks
Tobin Ehlis12ab7dc2015-09-09 13:31:01 -0600343 // TODO : Currently only performing next check if *something* was bound (non-zero last bound)
344 // There is probably a better way to gate when this check happens, and to know if something *should* have been bound
345 // We should have that check separately and then gate this check based on that check
346 if (pPipe && (pCB->lastBoundPipelineLayout) && (pCB->lastBoundPipelineLayout != pPipe->graphicsPipelineCI.layout)) {
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600347 result = VK_FALSE;
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600348 result |= 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 -0600349 "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 -0600350 }
Tobin Ehlisd28acef2015-09-09 15:12:35 -0600351 // Verify Vtx binding
352 if (MAX_BINDING != pCB->lastVtxBinding) {
353 if (pCB->lastVtxBinding >= pPipe->vtxBindingCount) {
354 if (0 == pPipe->vtxBindingCount) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600355 result |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
Tobin Ehlisd28acef2015-09-09 15:12:35 -0600356 "Vtx Buffer Index %u was bound, but no vtx buffers are attached to PSO.", pCB->lastVtxBinding);
Tobin Ehlisd28acef2015-09-09 15:12:35 -0600357 }
358 else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600359 result |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
Tobin Ehlisd28acef2015-09-09 15:12:35 -0600360 "Vtx binding Index of %u exceeds PSO pVertexBindingDescriptions max array index of %u.", pCB->lastVtxBinding, (pPipe->vtxBindingCount - 1));
Tobin Ehlisd28acef2015-09-09 15:12:35 -0600361 }
362 }
363 }
Tobin Ehlisa88e2f52015-10-02 11:00:56 -0600364 // If Viewport or scissors are dynamic, verify that dynamic count matches PSO count
365 VkBool32 dynViewport = isDynamic(pPipe, VK_DYNAMIC_STATE_VIEWPORT);
366 VkBool32 dynScissor = isDynamic(pPipe, VK_DYNAMIC_STATE_SCISSOR);
367 if (dynViewport) {
368 if (pCB->viewports.size() != pPipe->graphicsPipelineCI.pViewportState->viewportCount) {
369 result |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
370 "Dynamic viewportCount from vkCmdSetViewport() is %u, but PSO viewportCount is %u. These counts must match.", pCB->viewports.size(), pPipe->graphicsPipelineCI.pViewportState->viewportCount);
371 }
372 }
373 if (dynScissor) {
374 if (pCB->scissors.size() != pPipe->graphicsPipelineCI.pViewportState->scissorCount) {
375 result |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
376 "Dynamic scissorCount from vkCmdSetScissor() is %u, but PSO scissorCount is %u. These counts must match.", pCB->scissors.size(), pPipe->graphicsPipelineCI.pViewportState->scissorCount);
377 }
378 }
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -0600379 return result;
380}
Tobin Ehlisde63c532015-06-18 15:59:33 -0600381// Verify that create state for a pipeline is valid
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600382static VkBool32 verifyPipelineCreateState(const VkDevice device, const PIPELINE_NODE* pPipeline)
Tobin Ehlisde63c532015-06-18 15:59:33 -0600383{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600384 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisde63c532015-06-18 15:59:33 -0600385 // VS is required
386 if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600387 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600388 "Invalid Pipeline CreateInfo State: Vtx Shader required");
Tobin Ehlisde63c532015-06-18 15:59:33 -0600389 }
390 // Either both or neither TC/TE shaders should be defined
391 if (((pPipeline->active_shaders & VK_SHADER_STAGE_TESS_CONTROL_BIT) == 0) !=
392 ((pPipeline->active_shaders & VK_SHADER_STAGE_TESS_EVALUATION_BIT) == 0) ) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600393 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600394 "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair");
Tobin Ehlisde63c532015-06-18 15:59:33 -0600395 }
396 // Compute shaders should be specified independent of Gfx shaders
397 if ((pPipeline->active_shaders & VK_SHADER_STAGE_COMPUTE_BIT) &&
398 (pPipeline->active_shaders & (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESS_CONTROL_BIT |
399 VK_SHADER_STAGE_TESS_EVALUATION_BIT | VK_SHADER_STAGE_GEOMETRY_BIT |
400 VK_SHADER_STAGE_FRAGMENT_BIT))) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600401 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600402 "Invalid Pipeline CreateInfo State: Do not specify Compute Shader for Gfx Pipeline");
Tobin Ehlisde63c532015-06-18 15:59:33 -0600403 }
404 // VK_PRIMITIVE_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines.
405 // Mismatching primitive topology and tessellation fails graphics pipeline creation.
406 if (pPipeline->active_shaders & (VK_SHADER_STAGE_TESS_CONTROL_BIT | VK_SHADER_STAGE_TESS_EVALUATION_BIT) &&
407 (pPipeline->iaStateCI.topology != VK_PRIMITIVE_TOPOLOGY_PATCH)) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600408 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600409 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH must be set as IA topology for tessellation pipelines");
Tobin Ehlisde63c532015-06-18 15:59:33 -0600410 }
Tobin Ehlis20693172015-09-17 08:46:18 -0600411 if (pPipeline->iaStateCI.topology == VK_PRIMITIVE_TOPOLOGY_PATCH) {
412 if (~pPipeline->active_shaders & VK_SHADER_STAGE_TESS_CONTROL_BIT) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600413 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlisde63c532015-06-18 15:59:33 -0600414 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH primitive topology is only valid for tessellation pipelines");
Tobin Ehlis20693172015-09-17 08:46:18 -0600415 }
416 if (!pPipeline->tessStateCI.patchControlPoints || (pPipeline->tessStateCI.patchControlPoints > 32)) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600417 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS",
Tobin Ehlis20693172015-09-17 08:46:18 -0600418 "Invalid Pipeline CreateInfo State: VK_PRIMITIVE_TOPOLOGY_PATCH primitive topology used with patchControlPoints value %u."
419 " patchControlPoints should be >0 and <=32.", pPipeline->tessStateCI.patchControlPoints);
420 }
Tobin Ehlisde63c532015-06-18 15:59:33 -0600421 }
Tobin Ehlisa88e2f52015-10-02 11:00:56 -0600422 // Viewport state must be included and viewport and scissor counts should always match
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600423 // NOTE : Even if these are flagged as dynamic, counts need to be set correctly for shader compiler
Tobin Ehlisa88e2f52015-10-02 11:00:56 -0600424 if (!pPipeline->graphicsPipelineCI.pViewportState) {
425 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
426 "Gfx Pipeline pViewportState is null. Even if viewport and scissors are dynamic PSO must include viewportCount and scissorCount in pViewportState.");
427 } else if (pPipeline->graphicsPipelineCI.pViewportState->scissorCount != pPipeline->graphicsPipelineCI.pViewportState->viewportCount) {
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600428 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
429 "Gfx Pipeline viewport count (%u) must match scissor count (%u).", pPipeline->vpStateCI.viewportCount, pPipeline->vpStateCI.scissorCount);
Tobin Ehlisa88e2f52015-10-02 11:00:56 -0600430 } else {
431 // If viewport or scissor are not dynamic, then verify that data is appropriate for count
432 VkBool32 dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT);
433 VkBool32 dynScissor = isDynamic(pPipeline, VK_DYNAMIC_STATE_SCISSOR);
434 if (!dynViewport) {
435 if (pPipeline->graphicsPipelineCI.pViewportState->viewportCount && !pPipeline->graphicsPipelineCI.pViewportState->pViewports) {
436 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
437 "Gfx Pipeline viewportCount is %u, but pViewports is NULL. For non-zero viewportCount, you must either include pViewports data, or include viewport in pDynamicState and set it with vkCmdSetViewport().", pPipeline->graphicsPipelineCI.pViewportState->viewportCount);
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600438 }
439 }
Tobin Ehlisa88e2f52015-10-02 11:00:56 -0600440 if (!dynScissor) {
441 if (pPipeline->graphicsPipelineCI.pViewportState->scissorCount && !pPipeline->graphicsPipelineCI.pViewportState->pScissors) {
442 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
443 "Gfx Pipeline scissorCount is %u, but pScissors is NULL. For non-zero scissorCount, you must either include pScissors data, or include scissor in pDynamicState and set it with vkCmdSetScissor().", pPipeline->graphicsPipelineCI.pViewportState->scissorCount);
444 }
Tobin Ehlis9e839e52015-10-01 11:15:13 -0600445 }
446 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600447 return skipCall;
Tobin Ehlisde63c532015-06-18 15:59:33 -0600448}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600449// Init the pipeline mapping info based on pipeline create info LL tree
450// Threading note : Calls to this function should wrapped in mutex
Tobin Ehlisde63c532015-06-18 15:59:33 -0600451static PIPELINE_NODE* initPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, PIPELINE_NODE* pBasePipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600452{
Tobin Ehlisde63c532015-06-18 15:59:33 -0600453 PIPELINE_NODE* pPipeline = new PIPELINE_NODE;
454 if (pBasePipeline) {
455 memcpy((void*)pPipeline, (void*)pBasePipeline, sizeof(PIPELINE_NODE));
Tobin Ehlise42007c2015-06-19 13:00:59 -0600456 } else {
Tobin Ehlisde63c532015-06-18 15:59:33 -0600457 memset((void*)pPipeline, 0, sizeof(PIPELINE_NODE));
458 }
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600459 // First init create info
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600460 memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, sizeof(VkGraphicsPipelineCreateInfo));
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600461
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600462 size_t bufferSize = 0;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600463 const VkPipelineVertexInputStateCreateInfo* pVICI = NULL;
Tobin Ehlis59db5712015-07-13 13:14:24 -0600464 const VkPipelineColorBlendStateCreateInfo* pCBCI = NULL;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600465
466 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
467 const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
468
469 switch (pPSSCI->stage) {
470 case VK_SHADER_STAGE_VERTEX:
471 memcpy(&pPipeline->vsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
472 pPipeline->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600473 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600474 case VK_SHADER_STAGE_TESS_CONTROL:
475 memcpy(&pPipeline->tcsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
476 pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_CONTROL_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600477 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600478 case VK_SHADER_STAGE_TESS_EVALUATION:
479 memcpy(&pPipeline->tesCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
480 pPipeline->active_shaders |= VK_SHADER_STAGE_TESS_EVALUATION_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600481 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600482 case VK_SHADER_STAGE_GEOMETRY:
483 memcpy(&pPipeline->gsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
484 pPipeline->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600485 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600486 case VK_SHADER_STAGE_FRAGMENT:
487 memcpy(&pPipeline->fsCI, pPSSCI, sizeof(VkPipelineShaderStageCreateInfo));
488 pPipeline->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600489 break;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600490 case VK_SHADER_STAGE_COMPUTE:
491 // TODO : Flag error, CS is specified through VkComputePipelineCreateInfo
492 pPipeline->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600493 break;
494 default:
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600495 // TODO : Flag error
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600496 break;
497 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600498 }
Tobin Ehlisf6cb4672015-09-29 08:18:34 -0600499 // Copy over GraphicsPipelineCreateInfo structure embedded pointers
500 if (pCreateInfo->stageCount != 0) {
501 pPipeline->graphicsPipelineCI.pStages = new VkPipelineShaderStageCreateInfo[pCreateInfo->stageCount];
502 bufferSize = pCreateInfo->stageCount * sizeof(VkPipelineShaderStageCreateInfo);
503 memcpy((void*)pPipeline->graphicsPipelineCI.pStages, pCreateInfo->pStages, bufferSize);
504 }
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600505 if (pCreateInfo->pVertexInputState != NULL) {
506 memcpy((void*)&pPipeline->vertexInputCI, pCreateInfo->pVertexInputState , sizeof(VkPipelineVertexInputStateCreateInfo));
507 // Copy embedded ptrs
508 pVICI = pCreateInfo->pVertexInputState;
509 pPipeline->vtxBindingCount = pVICI->bindingCount;
510 if (pPipeline->vtxBindingCount) {
511 pPipeline->pVertexBindingDescriptions = new VkVertexInputBindingDescription[pPipeline->vtxBindingCount];
512 bufferSize = pPipeline->vtxBindingCount * sizeof(VkVertexInputBindingDescription);
513 memcpy((void*)pPipeline->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions, bufferSize);
514 }
515 pPipeline->vtxAttributeCount = pVICI->attributeCount;
516 if (pPipeline->vtxAttributeCount) {
517 pPipeline->pVertexAttributeDescriptions = new VkVertexInputAttributeDescription[pPipeline->vtxAttributeCount];
518 bufferSize = pPipeline->vtxAttributeCount * sizeof(VkVertexInputAttributeDescription);
519 memcpy((void*)pPipeline->pVertexAttributeDescriptions, pVICI->pVertexAttributeDescriptions, bufferSize);
520 }
521 pPipeline->graphicsPipelineCI.pVertexInputState = &pPipeline->vertexInputCI;
522 }
Tony Barboure307f582015-07-10 15:29:03 -0600523 if (pCreateInfo->pInputAssemblyState != NULL) {
524 memcpy((void*)&pPipeline->iaStateCI, pCreateInfo->pInputAssemblyState, sizeof(VkPipelineInputAssemblyStateCreateInfo));
525 pPipeline->graphicsPipelineCI.pInputAssemblyState = &pPipeline->iaStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600526 }
Tony Barboure307f582015-07-10 15:29:03 -0600527 if (pCreateInfo->pTessellationState != NULL) {
528 memcpy((void*)&pPipeline->tessStateCI, pCreateInfo->pTessellationState, sizeof(VkPipelineTessellationStateCreateInfo));
529 pPipeline->graphicsPipelineCI.pTessellationState = &pPipeline->tessStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600530 }
Tony Barboure307f582015-07-10 15:29:03 -0600531 if (pCreateInfo->pViewportState != NULL) {
532 memcpy((void*)&pPipeline->vpStateCI, pCreateInfo->pViewportState, sizeof(VkPipelineViewportStateCreateInfo));
533 pPipeline->graphicsPipelineCI.pViewportState = &pPipeline->vpStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600534 }
Tony Barboure307f582015-07-10 15:29:03 -0600535 if (pCreateInfo->pRasterState != NULL) {
536 memcpy((void*)&pPipeline->rsStateCI, pCreateInfo->pRasterState, sizeof(VkPipelineRasterStateCreateInfo));
537 pPipeline->graphicsPipelineCI.pRasterState = &pPipeline->rsStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600538 }
Tony Barboure307f582015-07-10 15:29:03 -0600539 if (pCreateInfo->pMultisampleState != NULL) {
540 memcpy((void*)&pPipeline->msStateCI, pCreateInfo->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo));
541 pPipeline->graphicsPipelineCI.pMultisampleState = &pPipeline->msStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600542 }
Tobin Ehlisf6cb4672015-09-29 08:18:34 -0600543 if (pCreateInfo->pDepthStencilState != NULL) {
544 memcpy((void*)&pPipeline->dsStateCI, pCreateInfo->pDepthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo));
545 pPipeline->graphicsPipelineCI.pDepthStencilState = &pPipeline->dsStateCI;
546 }
Tony Barboure307f582015-07-10 15:29:03 -0600547 if (pCreateInfo->pColorBlendState != NULL) {
548 memcpy((void*)&pPipeline->cbStateCI, pCreateInfo->pColorBlendState, sizeof(VkPipelineColorBlendStateCreateInfo));
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600549 // Copy embedded ptrs
Tony Barboure307f582015-07-10 15:29:03 -0600550 pCBCI = pCreateInfo->pColorBlendState;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600551 pPipeline->attachmentCount = pCBCI->attachmentCount;
552 if (pPipeline->attachmentCount) {
Tony Barboure307f582015-07-10 15:29:03 -0600553 pPipeline->pAttachments = new VkPipelineColorBlendAttachmentState[pPipeline->attachmentCount];
554 bufferSize = pPipeline->attachmentCount * sizeof(VkPipelineColorBlendAttachmentState);
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600555 memcpy((void*)pPipeline->pAttachments, pCBCI->pAttachments, bufferSize);
556 }
Tony Barboure307f582015-07-10 15:29:03 -0600557 pPipeline->graphicsPipelineCI.pColorBlendState = &pPipeline->cbStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600558 }
Tobin Ehlisf6cb4672015-09-29 08:18:34 -0600559 if (pCreateInfo->pDynamicState != NULL) {
560 memcpy((void*)&pPipeline->dynStateCI, pCreateInfo->pDynamicState, sizeof(VkPipelineDynamicStateCreateInfo));
561 if (pPipeline->dynStateCI.dynamicStateCount) {
562 pPipeline->dynStateCI.pDynamicStates = new VkDynamicState[pPipeline->dynStateCI.dynamicStateCount];
563 bufferSize = pPipeline->dynStateCI.dynamicStateCount * sizeof(VkDynamicState);
564 memcpy((void*)pPipeline->dynStateCI.pDynamicStates, pCreateInfo->pDynamicState->pDynamicStates, bufferSize);
565 }
566 pPipeline->graphicsPipelineCI.pDynamicState = &pPipeline->dynStateCI;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600567 }
568
Tobin Ehlisde63c532015-06-18 15:59:33 -0600569 return pPipeline;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600570}
571// Free the Pipeline nodes
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600572static void deletePipelines(layer_data* my_data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600573{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600574 if (my_data->pipelineMap.size() <= 0)
David Pinedof5997ab2015-04-27 16:36:17 -0600575 return;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600576 for (auto ii=my_data->pipelineMap.begin(); ii!=my_data->pipelineMap.end(); ++ii) {
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600577 if ((*ii).second->graphicsPipelineCI.stageCount != 0) {
578 delete[] (*ii).second->graphicsPipelineCI.pStages;
579 }
Tobin Ehliscd3109e2015-04-01 11:59:08 -0600580 if ((*ii).second->pVertexBindingDescriptions) {
581 delete[] (*ii).second->pVertexBindingDescriptions;
582 }
583 if ((*ii).second->pVertexAttributeDescriptions) {
584 delete[] (*ii).second->pVertexAttributeDescriptions;
585 }
586 if ((*ii).second->pAttachments) {
587 delete[] (*ii).second->pAttachments;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600588 }
Tobin Ehlisf6cb4672015-09-29 08:18:34 -0600589 if ((*ii).second->dynStateCI.dynamicStateCount != 0) {
590 delete[] (*ii).second->dynStateCI.pDynamicStates;
591 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600592 delete (*ii).second;
593 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600594 my_data->pipelineMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600595}
Tobin Ehlis2464b882015-04-01 08:40:34 -0600596// For given pipeline, return number of MSAA samples, or one if MSAA disabled
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600597static uint32_t getNumSamples(layer_data* my_data, const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600598{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600599 PIPELINE_NODE* pPipe = my_data->pipelineMap[pipeline.handle];
Tobin Ehlisb3a506f2015-07-13 14:51:15 -0600600 if (VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pPipe->msStateCI.sType) {
601 return pPipe->msStateCI.rasterSamples;
602 }
Tobin Ehlis2464b882015-04-01 08:40:34 -0600603 return 1;
604}
605// Validate state related to the PSO
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600606static VkBool32 validatePipelineState(layer_data* my_data, const GLOBAL_CB_NODE* pCB, const VkPipelineBindPoint pipelineBindPoint, const VkPipeline pipeline)
Tobin Ehlis2464b882015-04-01 08:40:34 -0600607{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600608 if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) {
Tobin Ehlis2464b882015-04-01 08:40:34 -0600609 // Verify that any MSAA request in PSO matches sample# in bound FB
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600610 uint32_t psoNumSamples = getNumSamples(my_data, pipeline);
Tobin Ehlis2464b882015-04-01 08:40:34 -0600611 if (pCB->activeRenderPass) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600612 const VkRenderPassCreateInfo* pRPCI = my_data->renderPassMap[pCB->activeRenderPass.handle];
Chia-I Wuc278df82015-07-07 11:50:03 +0800613 const VkSubpassDescription* pSD = &pRPCI->pSubpasses[pCB->activeSubpass];
614 int subpassNumSamples = 0;
615 uint32_t i;
616
617 for (i = 0; i < pSD->colorCount; i++) {
618 uint32_t samples;
619
Cody Northrop6de6b0b2015-08-04 11:16:41 -0600620 if (pSD->pColorAttachments[i].attachment == VK_ATTACHMENT_UNUSED)
Chia-I Wuc278df82015-07-07 11:50:03 +0800621 continue;
622
Cody Northrop6de6b0b2015-08-04 11:16:41 -0600623 samples = pRPCI->pAttachments[pSD->pColorAttachments[i].attachment].samples;
Chia-I Wuc278df82015-07-07 11:50:03 +0800624 if (subpassNumSamples == 0) {
625 subpassNumSamples = samples;
626 } else if (subpassNumSamples != samples) {
627 subpassNumSamples = -1;
628 break;
629 }
630 }
631 if (pSD->depthStencilAttachment.attachment != VK_ATTACHMENT_UNUSED) {
632 const uint32_t samples = pRPCI->pAttachments[pSD->depthStencilAttachment.attachment].samples;
633 if (subpassNumSamples == 0)
634 subpassNumSamples = samples;
635 else if (subpassNumSamples != samples)
636 subpassNumSamples = -1;
637 }
638
639 if (psoNumSamples != subpassNumSamples) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600640 return log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle, 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -0600641 "Num samples mismatch! Binding PSO (%#" PRIxLEAST64 ") with %u samples while current RenderPass (%#" PRIxLEAST64 ") w/ %u samples!",
642 pipeline.handle, psoNumSamples, pCB->activeRenderPass.handle, subpassNumSamples);
Tobin Ehlis2464b882015-04-01 08:40:34 -0600643 }
644 } else {
645 // TODO : I believe it's an error if we reach this point and don't have an activeRenderPass
646 // Verify and flag error as appropriate
647 }
648 // TODO : Add more checks here
649 } else {
650 // TODO : Validate non-gfx pipeline updates
651 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600652 return VK_FALSE;
Tobin Ehlis2464b882015-04-01 08:40:34 -0600653}
654
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600655// Block of code at start here specifically for managing/tracking DSs
656
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600657// Return Pool node ptr for specified pool or else NULL
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600658static POOL_NODE* getPoolNode(layer_data* my_data, const VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600659{
660 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600661 if (my_data->poolMap.find(pool.handle) == my_data->poolMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600662 loader_platform_thread_unlock_mutex(&globalLock);
663 return NULL;
664 }
665 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600666 return my_data->poolMap[pool.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600667}
668// Return Set node ptr for specified set or else NULL
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600669static SET_NODE* getSetNode(layer_data* my_data, const VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600670{
671 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600672 if (my_data->setMap.find(set.handle) == my_data->setMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600673 loader_platform_thread_unlock_mutex(&globalLock);
674 return NULL;
675 }
676 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600677 return my_data->setMap[set.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600678}
679
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600680static LAYOUT_NODE* getLayoutNode(layer_data* my_data, const VkDescriptorSetLayout layout) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600681 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600682 if (my_data->layoutMap.find(layout.handle) == my_data->layoutMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600683 loader_platform_thread_unlock_mutex(&globalLock);
684 return NULL;
685 }
686 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600687 return my_data->layoutMap[layout.handle];
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600688}
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600689// Return VK_FALSE if update struct is of valid type, otherwise flag error and return code from callback
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600690static VkBool32 validUpdateStruct(const VkDevice device, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600691{
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600692 switch (pUpdateStruct->sType)
693 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800694 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
695 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600696 return VK_FALSE;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600697 default:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600698 return 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 -0600699 "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 -0600700 }
701}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600702// For given update struct, return binding
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600703static VkBool32 getUpdateBinding(const VkDevice device, const GENERIC_HEADER* pUpdateStruct, uint32_t* binding)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600704{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600705 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600706 switch (pUpdateStruct->sType)
707 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800708 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600709 *binding = ((VkWriteDescriptorSet*)pUpdateStruct)->destBinding;
710 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800711 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600712 *binding = ((VkCopyDescriptorSet*)pUpdateStruct)->destBinding;
713 break;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600714 default:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600715 skipCall |= 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 -0600716 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600717 *binding = 0xFFFFFFFF;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600718 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600719 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600720}
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600721// Set arrayIndex for given update struct in the last parameter
722// Return value of skipCall, which is only VK_TRUE is error occurs and callback signals execution to cease
723static uint32_t getUpdateArrayIndex(const VkDevice device, const GENERIC_HEADER* pUpdateStruct, uint32_t* arrayIndex)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600724{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600725 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600726 switch (pUpdateStruct->sType)
727 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800728 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600729 *arrayIndex = ((VkWriteDescriptorSet*)pUpdateStruct)->destArrayElement;
730 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800731 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600732 // TODO : Need to understand this case better and make sure code is correct
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600733 *arrayIndex = ((VkCopyDescriptorSet*)pUpdateStruct)->destArrayElement;
734 break;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600735 default:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600736 skipCall |= 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 -0600737 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600738 *arrayIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600739 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600740 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600741}
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600742// Set count for given update struct in the last parameter
743// Return value of skipCall, which is only VK_TRUE is error occurs and callback signals execution to cease
744static uint32_t getUpdateCount(const VkDevice device, const GENERIC_HEADER* pUpdateStruct, uint32_t* count)
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600745{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600746 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600747 switch (pUpdateStruct->sType)
748 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800749 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600750 *count = ((VkWriteDescriptorSet*)pUpdateStruct)->count;
751 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800752 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600753 // TODO : Need to understand this case better and make sure code is correct
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600754 *count = ((VkCopyDescriptorSet*)pUpdateStruct)->count;
755 break;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600756 default:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600757 skipCall |= 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 -0600758 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdateStruct->sType), pUpdateStruct->sType);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600759 *count = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600760 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600761 return skipCall;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600762}
763// For given Layout Node and binding, return index where that binding begins
764static uint32_t getBindingStartIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
765{
766 uint32_t offsetIndex = 0;
767 for (uint32_t i = 0; i<binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800768 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600769 }
770 return offsetIndex;
771}
772// For given layout node and binding, return last index that is updated
773static uint32_t getBindingEndIndex(const LAYOUT_NODE* pLayout, const uint32_t binding)
774{
775 uint32_t offsetIndex = 0;
776 for (uint32_t i = 0; i<=binding; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +0800777 offsetIndex += pLayout->createInfo.pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600778 }
779 return offsetIndex-1;
780}
781// For given layout and update, return the first overall index of the layout that is update
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600782static VkBool32 getUpdateStartIndex(const VkDevice device, const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct, uint32_t* startIndex)
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600783{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600784 uint32_t binding = 0, arrayIndex = 0;
785 VkBool32 skipCall = getUpdateBinding(device, pUpdateStruct, &binding);
786 skipCall |= getUpdateArrayIndex(device, pUpdateStruct, &arrayIndex);
787 if (VK_FALSE == skipCall)
788 *startIndex = getBindingStartIndex(pLayout, binding)+arrayIndex;
789 return skipCall;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600790}
791// For given layout and update, return the last overall index of the layout that is update
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600792static VkBool32 getUpdateEndIndex(const VkDevice device, const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct, uint32_t* endIndex)
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600793{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600794 uint32_t binding = 0, arrayIndex = 0, count = 0;
795 VkBool32 skipCall = getUpdateBinding(device, pUpdateStruct, &binding);
796 skipCall |= getUpdateArrayIndex(device, pUpdateStruct, &arrayIndex);
797 skipCall |= getUpdateCount(device, pUpdateStruct, &count);
798 if (VK_FALSE == skipCall)
799 *endIndex = getBindingStartIndex(pLayout, binding)+arrayIndex+count-1;
800 return skipCall;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600801}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600802// Verify that the descriptor type in the update struct matches what's expected by the layout
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -0600803static VkBool32 validateUpdateType(const VkDevice device, const LAYOUT_NODE* pLayout, const GENERIC_HEADER* pUpdateStruct)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600804{
805 // First get actual type of update
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600806 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600807 VkDescriptorType actualType;
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600808 uint32_t i = 0, startIndex = 0, endIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600809 switch (pUpdateStruct->sType)
810 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800811 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
812 actualType = ((VkWriteDescriptorSet*)pUpdateStruct)->descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600813 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800814 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
815 /* no need to validate */
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600816 return VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600817 break;
818 default:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600819 skipCall |= 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 -0600820 "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 -0600821 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600822 skipCall |= getUpdateStartIndex(device, pLayout, pUpdateStruct, &startIndex);
823 skipCall |= getUpdateEndIndex(device, pLayout, pUpdateStruct, &endIndex);
824 if (VK_FALSE == skipCall) {
825 for (i = startIndex; i <= endIndex; i++) {
Tobin Ehlis3b341092015-09-30 08:30:20 -0600826 if (pLayout->pTypes[i] != actualType) {
827 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS",
828 "Descriptor update type of %s has descriptor type %s that does not match overlapping binding descriptor type of %s!",
829 string_VkStructureType(pUpdateStruct->sType), string_VkDescriptorType(actualType), string_VkDescriptorType(pLayout->pTypes[i]));
830 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600831 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600832 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600833 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600834}
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600835// Determine the update type, allocate a new struct of that type, shadow the given pUpdate
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600836// struct into the pNewNode param. Return VK_TRUE if error condition encountered and callback signals early exit.
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600837// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600838static VkBool32 shadowUpdateNode(const VkDevice device, GENERIC_HEADER* pUpdate, GENERIC_HEADER** pNewNode)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600839{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600840 VkBool32 skipCall = VK_FALSE;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800841 VkWriteDescriptorSet* pWDS = NULL;
842 VkCopyDescriptorSet* pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600843 size_t array_size = 0;
844 size_t base_array_size = 0;
845 size_t total_array_size = 0;
846 size_t baseBuffAddr = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600847 switch (pUpdate->sType)
848 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800849 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
850 pWDS = new VkWriteDescriptorSet;
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600851 *pNewNode = (GENERIC_HEADER*)pWDS;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800852 memcpy(pWDS, pUpdate, sizeof(VkWriteDescriptorSet));
853 pWDS->pDescriptors = new VkDescriptorInfo[pWDS->count];
854 array_size = sizeof(VkDescriptorInfo) * pWDS->count;
855 memcpy((void*)pWDS->pDescriptors, ((VkWriteDescriptorSet*)pUpdate)->pDescriptors, array_size);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600856 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800857 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
858 pCDS = new VkCopyDescriptorSet;
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600859 *pNewNode = (GENERIC_HEADER*)pCDS;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800860 memcpy(pCDS, pUpdate, sizeof(VkCopyDescriptorSet));
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600861 break;
862 default:
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600863 if (log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_UPDATE_STRUCT, "DS",
864 "Unexpected UPDATE struct of type %s (value %u) in vkUpdateDescriptors() struct tree", string_VkStructureType(pUpdate->sType), pUpdate->sType))
865 return VK_TRUE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600866 }
867 // Make sure that pNext for the end of shadow copy is NULL
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600868 (*pNewNode)->pNext = NULL;
869 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600870}
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800871// update DS mappings based on ppUpdateArray
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600872static VkBool32 dsUpdate(layer_data* my_data, VkDevice device, VkStructureType type, uint32_t updateCount, const void* pUpdateArray)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600873{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800874 const VkWriteDescriptorSet *pWDS = NULL;
875 const VkCopyDescriptorSet *pCDS = NULL;
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600876 VkBool32 skipCall = VK_FALSE;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800877
878 if (type == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET)
879 pWDS = (const VkWriteDescriptorSet *) pUpdateArray;
880 else
881 pCDS = (const VkCopyDescriptorSet *) pUpdateArray;
882
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600883 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600884 LAYOUT_NODE* pLayout = NULL;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600885 VkDescriptorSetLayoutCreateInfo* pLayoutCI = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600886 // TODO : If pCIList is NULL, flag error
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600887 // Perform all updates
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600888 for (uint32_t i = 0; i < updateCount; i++) {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800889 VkDescriptorSet ds = (pWDS) ? pWDS->destSet : pCDS->destSet;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600890 SET_NODE* pSet = my_data->setMap[ds.handle]; // getSetNode() without locking
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800891 g_lastBoundDescriptorSet = pSet->set;
892 GENERIC_HEADER* pUpdate = (pWDS) ? (GENERIC_HEADER*) &pWDS[i] : (GENERIC_HEADER*) &pCDS[i];
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600893 pLayout = pSet->pLayout;
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600894 // First verify valid update struct
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600895 if ((skipCall = validUpdateStruct(device, pUpdate)) == VK_TRUE) {
Tobin Ehlis0b551cd2015-05-28 12:10:17 -0600896 break;
897 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600898 // Make sure that binding is within bounds
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600899 uint32_t binding = 0, endIndex = 0;
900 skipCall |= getUpdateBinding(device, pUpdate, &binding);
901 if (pLayout->createInfo.count < binding) {
902 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds.handle, 0, DRAWSTATE_INVALID_UPDATE_INDEX, "DS",
903 "Descriptor Set %p does not have binding to match update binding %u for update type %s!", ds, binding, string_VkStructureType(pUpdate->sType));
Tobin Ehlise42007c2015-06-19 13:00:59 -0600904 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600905 // Next verify that update falls within size of given binding
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600906 skipCall |= getUpdateBinding(device, pUpdate, &binding);
907 skipCall |= getUpdateEndIndex(device, pLayout, pUpdate, &endIndex);
908 if (getBindingEndIndex(pLayout, binding) < endIndex) {
Tony Barbour29b12062015-07-13 13:37:24 -0600909 // TODO : Keep count of layout CI structs and size this string dynamically based on that count
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600910 pLayoutCI = &pLayout->createInfo;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600911 string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo(pLayoutCI, "{DS} ");
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600912 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, ds.handle, 0, DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS",
913 "Descriptor update type of %s is out of bounds for matching binding %u in Layout w/ CI:\n%s!", string_VkStructureType(pUpdate->sType), binding, DSstr.c_str());
Tobin Ehlise42007c2015-06-19 13:00:59 -0600914 } else { // TODO : should we skip update on a type mismatch or force it?
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600915 // Layout bindings match w/ update ok, now verify that update is of the right type
Tobin Ehlis3b341092015-09-30 08:30:20 -0600916 if ((skipCall = validateUpdateType(device, pLayout, pUpdate)) == VK_FALSE) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600917 // Save the update info
918 // TODO : Info message that update successful
919 // Create new update struct for this set's shadow copy
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600920 GENERIC_HEADER* pNewNode = NULL;
921 skipCall |= shadowUpdateNode(device, pUpdate, &pNewNode);
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600922 if (NULL == pNewNode) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600923 skipCall |= 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 -0600924 "Out of memory while attempting to allocate UPDATE struct in vkUpdateDescriptors()");
Tobin Ehlise42007c2015-06-19 13:00:59 -0600925 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600926 // Insert shadow node into LL of updates for this set
927 pNewNode->pNext = pSet->pUpdateStructs;
928 pSet->pUpdateStructs = pNewNode;
929 // Now update appropriate descriptor(s) to point to new Update node
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600930 skipCall |= getUpdateEndIndex(device, pLayout, pUpdate, &endIndex);
931 uint32_t startIndex;
932 skipCall |= getUpdateStartIndex(device, pLayout, pUpdate, &startIndex);
933 for (uint32_t j = startIndex; j <= endIndex; j++) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600934 assert(j<pSet->descriptorCount);
935 pSet->ppDescriptors[j] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600936 }
937 }
938 }
939 }
940 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600941 }
942 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -0600943 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600944}
945// Free the shadowed update node for this Set
946// NOTE : Calls to this function should be wrapped in mutex
947static void freeShadowUpdateTree(SET_NODE* pSet)
948{
949 GENERIC_HEADER* pShadowUpdate = pSet->pUpdateStructs;
950 pSet->pUpdateStructs = NULL;
951 GENERIC_HEADER* pFreeUpdate = pShadowUpdate;
952 // Clear the descriptor mappings as they will now be invalid
953 memset(pSet->ppDescriptors, 0, pSet->descriptorCount*sizeof(GENERIC_HEADER*));
954 while(pShadowUpdate) {
955 pFreeUpdate = pShadowUpdate;
956 pShadowUpdate = (GENERIC_HEADER*)pShadowUpdate->pNext;
957 uint32_t index = 0;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800958 VkWriteDescriptorSet * pWDS = NULL;
959 VkCopyDescriptorSet * pCDS = NULL;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600960 void** ppToFree = NULL;
961 switch (pFreeUpdate->sType)
962 {
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800963 case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET:
964 pWDS = (VkWriteDescriptorSet*)pFreeUpdate;
965 if (pWDS->pDescriptors)
966 delete[] pWDS->pDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600967 break;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800968 case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET:
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600969 break;
970 default:
971 assert(0);
972 break;
973 }
Tobin Ehliseaf28662015-04-08 10:58:37 -0600974 delete pFreeUpdate;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600975 }
976}
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -0600977// Free all DS Pools including their Sets & related sub-structs
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600978// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600979static void deletePools(layer_data* my_data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600980{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600981 if (my_data->poolMap.size() <= 0)
David Pinedof5997ab2015-04-27 16:36:17 -0600982 return;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -0600983 for (auto ii=my_data->poolMap.begin(); ii!=my_data->poolMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600984 SET_NODE* pSet = (*ii).second->pSets;
985 SET_NODE* pFreeSet = pSet;
986 while (pSet) {
987 pFreeSet = pSet;
988 pSet = pSet->pNext;
Tobin Ehliseaf28662015-04-08 10:58:37 -0600989 // Freeing layouts handled in deleteLayouts() function
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600990 // Free Update shadow struct tree
991 freeShadowUpdateTree(pFreeSet);
992 if (pFreeSet->ppDescriptors) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200993 delete[] pFreeSet->ppDescriptors;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600994 }
995 delete pFreeSet;
996 }
997 if ((*ii).second->createInfo.pTypeCount) {
Chris Forbes4506d3f2015-06-04 10:49:27 +1200998 delete[] (*ii).second->createInfo.pTypeCount;
Tobin Ehlis63bb9482015-03-17 16:24:32 -0600999 }
1000 delete (*ii).second;
1001 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001002 my_data->poolMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001003}
Tobin Ehliseaf28662015-04-08 10:58:37 -06001004// WARN : Once deleteLayouts() called, any layout ptrs in Pool/Set data structure will be invalid
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001005// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001006static void deleteLayouts(layer_data* my_data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001007{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001008 if (my_data->layoutMap.size() <= 0)
David Pinedof5997ab2015-04-27 16:36:17 -06001009 return;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001010 for (auto ii=my_data->layoutMap.begin(); ii!=my_data->layoutMap.end(); ++ii) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001011 LAYOUT_NODE* pLayout = (*ii).second;
Tobin Ehliseaf28662015-04-08 10:58:37 -06001012 if (pLayout->createInfo.pBinding) {
1013 for (uint32_t i=0; i<pLayout->createInfo.count; i++) {
1014 if (pLayout->createInfo.pBinding[i].pImmutableSamplers)
1015 delete[] pLayout->createInfo.pBinding[i].pImmutableSamplers;
1016 }
1017 delete[] pLayout->createInfo.pBinding;
1018 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001019 if (pLayout->pTypes) {
Chris Forbes4506d3f2015-06-04 10:49:27 +12001020 delete[] pLayout->pTypes;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001021 }
1022 delete pLayout;
1023 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001024 my_data->layoutMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001025}
1026// Currently clearing a set is removing all previous updates to that set
1027// TODO : Validate if this is correct clearing behavior
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001028static void clearDescriptorSet(layer_data* my_data, VkDescriptorSet set)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001029{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001030 SET_NODE* pSet = getSetNode(my_data, set);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001031 if (!pSet) {
1032 // TODO : Return error
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001033 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001034 loader_platform_thread_lock_mutex(&globalLock);
1035 freeShadowUpdateTree(pSet);
1036 loader_platform_thread_unlock_mutex(&globalLock);
1037 }
1038}
1039
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001040static void clearDescriptorPool(layer_data* my_data, const VkDevice device, const VkDescriptorPool pool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001041{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001042 POOL_NODE* pPool = getPoolNode(my_data, pool);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001043 if (!pPool) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001044 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, pool.handle, 0, DRAWSTATE_INVALID_POOL, "DS",
1045 "Unable to find pool node for pool %#" PRIxLEAST64 " specified in vkResetDescriptorPool() call", pool.handle);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001046 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001047 // For every set off of this pool, clear it
1048 SET_NODE* pSet = pPool->pSets;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001049 while (pSet) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001050 clearDescriptorSet(my_data, pSet->set);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001051 }
1052 }
1053}
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001054// For given CB object, fetch associated CB Node from map
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001055static GLOBAL_CB_NODE* getCBNode(layer_data* my_data, const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001056{
1057 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001058 if (my_data->cmdBufferMap.find(cb) == my_data->cmdBufferMap.end()) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001059 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001060 // TODO : How to pass cb as srcObj here?
1061 log_msg(mdd(cb), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -06001062 "Attempt to use CmdBuffer %#" PRIxLEAST64 " that doesn't exist!", reinterpret_cast<uint64_t>(cb));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001063 return NULL;
1064 }
1065 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001066 return my_data->cmdBufferMap[cb];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001067}
1068// Free all CB Nodes
1069// NOTE : Calls to this function should be wrapped in mutex
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001070static void deleteCmdBuffers(layer_data* my_data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001071{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001072 if (my_data->cmdBufferMap.size() <= 0)
David Pinedof5997ab2015-04-27 16:36:17 -06001073 return;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001074 for (auto ii=my_data->cmdBufferMap.begin(); ii!=my_data->cmdBufferMap.end(); ++ii) {
Courtney Goeltzenleuchter09098a72015-04-27 15:04:43 -06001075 vector<CMD_NODE*> cmd_node_list = (*ii).second->pCmds;
1076 while (!cmd_node_list.empty()) {
1077 CMD_NODE* cmd_node = cmd_node_list.back();
1078 delete cmd_node;
1079 cmd_node_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001080 }
1081 delete (*ii).second;
1082 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001083 my_data->cmdBufferMap.clear();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001084}
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001085static VkBool32 report_error_no_cb_begin(const VkCmdBuffer cb, const char* caller_name)
Tobin Ehlise42007c2015-06-19 13:00:59 -06001086{
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001087 // TODO : How to pass cb as srcObj here?
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001088 return 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 -06001089 "You must call vkBeginCommandBuffer() before this call to %s", (void*)caller_name);
1090}
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001091static VkBool32 addCmd(GLOBAL_CB_NODE* pCB, const CMD_TYPE cmd)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001092{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001093 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001094 CMD_NODE* pCmd = new CMD_NODE;
1095 if (pCmd) {
1096 // init cmd node and append to end of cmd LL
1097 memset(pCmd, 0, sizeof(CMD_NODE));
1098 pCmd->cmdNumber = ++pCB->numCmds;
1099 pCmd->type = cmd;
1100 pCB->pCmds.push_back(pCmd);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001101 } else {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001102 // TODO : How to pass cb as srcObj here?
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001103 skipCall |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -06001104 "Out of memory while attempting to allocate new CMD_NODE for cmdBuffer %#" PRIxLEAST64, reinterpret_cast<uint64_t>(pCB->cmdBuffer));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001105 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001106 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001107}
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001108static void resetCB(layer_data* my_data, const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001109{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001110 GLOBAL_CB_NODE* pCB = getCBNode(my_data, cb);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001111 if (pCB) {
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001112 vector<CMD_NODE*> cmd_list = pCB->pCmds;
1113 while (!cmd_list.empty()) {
1114 delete cmd_list.back();
1115 cmd_list.pop_back();
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001116 }
Courtney Goeltzenleuchterf03711e2015-04-27 17:16:56 -06001117 pCB->pCmds.clear();
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001118 // Reset CB state (need to save createInfo)
1119 VkCmdBufferCreateInfo saveCBCI = pCB->createInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001120 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1121 pCB->cmdBuffer = cb;
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001122 pCB->createInfo = saveCBCI;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001123 pCB->lastVtxBinding = MAX_BINDING;
1124 }
1125}
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001126// Set PSO-related status bits for CB, including dynamic state set via PSO
Tobin Ehlis97866202015-06-10 12:57:07 -06001127static void set_cb_pso_status(GLOBAL_CB_NODE* pCB, const PIPELINE_NODE* pPipe)
1128{
1129 for (uint32_t i = 0; i < pPipe->cbStateCI.attachmentCount; i++) {
1130 if (0 != pPipe->pAttachments[i].channelWriteMask) {
1131 pCB->status |= CBSTATUS_COLOR_BLEND_WRITE_ENABLE;
1132 }
1133 }
1134 if (pPipe->dsStateCI.depthWriteEnable) {
Cody Northrop2605cb02015-08-18 15:21:16 -06001135 pCB->status |= CBSTATUS_DEPTH_WRITE_ENABLE;
1136 }
Cody Northrop2605cb02015-08-18 15:21:16 -06001137 if (pPipe->dsStateCI.stencilTestEnable) {
1138 pCB->status |= CBSTATUS_STENCIL_TEST_ENABLE;
Tobin Ehlis97866202015-06-10 12:57:07 -06001139 }
Tobin Ehlisa88e2f52015-10-02 11:00:56 -06001140 // Account for any dynamic state not set via this PSO
1141 if (!pPipe->dynStateCI.dynamicStateCount) { // All state is static
1142 pCB->status = CBSTATUS_ALL;
1143 } else {
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001144 // First consider all state on
1145 // Then unset any state that's noted as dynamic in PSO
1146 // Finally OR that into CB statemask
1147 CBStatusFlags psoDynStateMask = CBSTATUS_ALL;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001148 for (uint32_t i=0; i < pPipe->dynStateCI.dynamicStateCount; i++) {
1149 switch (pPipe->dynStateCI.pDynamicStates[i]) {
1150 case VK_DYNAMIC_STATE_VIEWPORT:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001151 psoDynStateMask &= ~CBSTATUS_VIEWPORT_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001152 break;
1153 case VK_DYNAMIC_STATE_SCISSOR:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001154 psoDynStateMask &= ~CBSTATUS_SCISSOR_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001155 break;
1156 case VK_DYNAMIC_STATE_LINE_WIDTH:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001157 psoDynStateMask &= ~CBSTATUS_LINE_WIDTH_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001158 break;
1159 case VK_DYNAMIC_STATE_DEPTH_BIAS:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001160 psoDynStateMask &= ~CBSTATUS_DEPTH_BIAS_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001161 break;
1162 case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001163 psoDynStateMask &= ~CBSTATUS_BLEND_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001164 break;
1165 case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001166 psoDynStateMask &= ~CBSTATUS_DEPTH_BOUNDS_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001167 break;
1168 case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001169 psoDynStateMask &= ~CBSTATUS_STENCIL_READ_MASK_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001170 break;
1171 case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001172 psoDynStateMask &= ~CBSTATUS_STENCIL_WRITE_MASK_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001173 break;
1174 case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001175 psoDynStateMask &= ~CBSTATUS_STENCIL_REFERENCE_SET;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001176 break;
1177 default:
1178 // TODO : Flag error here
1179 break;
1180 }
1181 }
Tobin Ehlis3dec46c2015-10-01 09:24:40 -06001182 pCB->status |= psoDynStateMask;
Tobin Ehlisf6cb4672015-09-29 08:18:34 -06001183 }
Tobin Ehlis97866202015-06-10 12:57:07 -06001184}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001185// Print the last bound Gfx Pipeline
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001186static VkBool32 printPipeline(layer_data* my_data, const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001187{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001188 VkBool32 skipCall = VK_FALSE;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001189 GLOBAL_CB_NODE* pCB = getCBNode(my_data, cb);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001190 if (pCB) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001191 PIPELINE_NODE *pPipeTrav = getPipeline(my_data, pCB->lastBoundPipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001192 if (!pPipeTrav) {
1193 // nothing to print
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001194 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001195 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001196 vk_print_vkgraphicspipelinecreateinfo(&pPipeTrav->graphicsPipelineCI, "{DS}").c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001197 }
1198 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001199 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001200}
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001201// Print details of DS config to stdout
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001202static VkBool32 printDSConfig(layer_data* my_data, const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001203{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001204 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001205 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.
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001206 GLOBAL_CB_NODE* pCB = getCBNode(my_data, cb);
Tobin Ehlis7297f192015-06-09 08:39:32 -06001207 if (pCB && pCB->lastBoundDescriptorSet) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001208 SET_NODE* pSet = getSetNode(my_data, pCB->lastBoundDescriptorSet);
1209 POOL_NODE* pPool = getPoolNode(my_data, pSet->pool);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001210 // Print out pool details
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001211 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001212 "Details for pool %#" PRIxLEAST64 ".", pPool->pool.handle);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001213 string poolStr = vk_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, " ");
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001214 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001215 "%s", poolStr.c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001216 // Print out set details
1217 char prefix[10];
1218 uint32_t index = 0;
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001219 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001220 "Details for descriptor set %#" PRIxLEAST64 ".", pSet->set.handle);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001221 LAYOUT_NODE* pLayout = pSet->pLayout;
1222 // Print layout details
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001223 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001224 "Layout #%u, (object %#" PRIxLEAST64 ") for DS %#" PRIxLEAST64 ".", index+1, (void*)pLayout->layout.handle, (void*)pSet->set.handle);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001225 sprintf(prefix, " [L%u] ", index);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001226 string DSLstr = vk_print_vkdescriptorsetlayoutcreateinfo(&pLayout->createInfo, prefix).c_str();
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001227 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001228 "%s", DSLstr.c_str());
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001229 index++;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001230 GENERIC_HEADER* pUpdate = pSet->pUpdateStructs;
1231 if (pUpdate) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001232 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001233 "Update Chain [UC] for descriptor set %#" PRIxLEAST64 ":", pSet->set.handle);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001234 sprintf(prefix, " [UC] ");
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001235 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001236 dynamic_display(pUpdate, prefix).c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001237 // TODO : If there is a "view" associated with this update, print CI for that view
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001238 } else {
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001239 if (0 != pSet->descriptorCount) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001240 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001241 "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 -06001242 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001243 skipCall |= log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001244 "FYI: No descriptors in descriptor set %#" PRIxLEAST64 ".", pSet->set.handle);
Tobin Ehlis2bca8b02015-06-15 08:41:17 -06001245 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001246 }
1247 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001248 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001249}
1250
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001251static void printCB(layer_data* my_data, const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001252{
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001253 GLOBAL_CB_NODE* pCB = getCBNode(my_data, cb);
David Pinedof5997ab2015-04-27 16:36:17 -06001254 if (pCB && pCB->pCmds.size() > 0) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001255 log_msg(mdd(cb), VK_DBG_REPORT_INFO_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001256 "Cmds in CB %p", (void*)cb);
Courtney Goeltzenleuchtercf2a5362015-04-27 11:16:35 -06001257 vector<CMD_NODE*> pCmds = pCB->pCmds;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001258 for (auto ii=pCmds.begin(); ii!=pCmds.end(); ++ii) {
1259 // TODO : Need to pass cb as srcObj here
1260 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 -06001261 " CMD#%lu: %s", (*ii)->cmdNumber, cmdTypeToString((*ii)->type).c_str());
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001262 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001263 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001264 // Nothing to print
1265 }
1266}
1267
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001268static VkBool32 synchAndPrintDSConfig(layer_data* my_data, const VkCmdBuffer cb)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001269{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001270 VkBool32 skipCall = VK_FALSE;
Mike Stroyanfa2f2222015-08-12 17:11:28 -06001271 if (!(mdd(cb)->active_flags & VK_DBG_REPORT_INFO_BIT)) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001272 return skipCall;
Mike Stroyanfa2f2222015-08-12 17:11:28 -06001273 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001274 skipCall |= printDSConfig(my_data, cb);
1275 skipCall |= printPipeline(my_data, cb);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001276 return skipCall;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001277}
1278
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06001279// Flags validation error if the associated call is made inside a render pass. The apiName
1280// routine should ONLY be called outside a render pass.
1281static VkBool32 insideRenderPass(GLOBAL_CB_NODE *pCB, const char *apiName)
1282{
1283 VkBool32 inside = VK_FALSE;
1284 if (pCB->activeRenderPass) {
1285 inside = log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
1286 (uint64_t)pCB->cmdBuffer, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
1287 "%s: It is invalid to issue this call inside an active render pass (%#" PRIxLEAST64 ")",
1288 apiName, pCB->activeRenderPass.handle);
1289 }
1290 return inside;
1291}
1292
1293// Flags validation error if the associated call is made outside a render pass. The apiName
1294// routine should ONLY be called inside a render pass.
1295static VkBool32 outsideRenderPass(GLOBAL_CB_NODE *pCB, const char *apiName)
1296{
1297 VkBool32 outside = VK_FALSE;
1298 if (!pCB->activeRenderPass) {
1299 outside = log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER,
Mark Lobodzinski70244842015-10-01 17:00:47 -06001300 (uint64_t)pCB->cmdBuffer, 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS",
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06001301 "%s: This call must be issued inside an active render pass.", apiName);
1302 }
1303 return outside;
1304}
1305
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001306static void init_draw_state(layer_data *my_data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001307{
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001308 uint32_t report_flags = 0;
1309 uint32_t debug_action = 0;
1310 FILE *log_output = NULL;
1311 const char *option_str;
Courtney Goeltzenleuchter1781b1c2015-10-05 15:58:38 -06001312 VkDbgMsgCallback callback;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001313 // initialize DrawState options
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001314 report_flags = getLayerOptionFlags("DrawStateReportFlags", 0);
1315 getLayerOptionEnum("DrawStateDebugAction", (uint32_t *) &debug_action);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001316
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001317 if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001318 {
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001319 option_str = getLayerOption("DrawStateLogFilename");
Tobin Ehlisb4b6e7c2015-09-15 09:55:54 -06001320 log_output = getLayerLogOutput(option_str, "DrawState");
Courtney Goeltzenleuchter1781b1c2015-10-05 15:58:38 -06001321 layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &callback);
1322 my_data->logging_callback.push_back(callback);
1323 }
1324
1325 if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
1326 layer_create_msg_callback(my_data->report_data, report_flags, win32_debug_output_msg, NULL, &callback);
1327 my_data->logging_callback.push_back(callback);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001328 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001329
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001330 if (!globalLockInitialized)
1331 {
Mike Stroyand9dd0072015-08-18 15:56:18 -06001332 // This mutex may be deleted by vkDestroyInstance of last instance.
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001333 loader_platform_thread_create_mutex(&globalLock);
1334 globalLockInitialized = 1;
1335 }
1336}
1337
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001338VK_LAYER_EXPORT VkResult VKAPI vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance)
1339{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001340 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
1341 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001342 VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
1343
1344 if (result == VK_SUCCESS) {
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001345 layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
1346 my_data->report_data = debug_report_create_instance(
1347 pTable,
1348 *pInstance,
1349 pCreateInfo->extensionCount,
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001350 pCreateInfo->ppEnabledExtensionNames);
Courtney Goeltzenleuchterf4a2eba2015-06-08 14:58:39 -06001351
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001352 init_draw_state(my_data);
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06001353 }
1354 return result;
1355}
1356
Jon Ashburne0fa2282015-05-20 09:00:28 -06001357/* hook DestroyInstance to remove tableInstanceMap entry */
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001358VK_LAYER_EXPORT void VKAPI vkDestroyInstance(VkInstance instance)
Jon Ashburne0fa2282015-05-20 09:00:28 -06001359{
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001360 dispatch_key key = get_dispatch_key(instance);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001361 layer_data *my_data = get_my_data_ptr(key, layer_data_map);
1362 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001363 pTable->DestroyInstance(instance);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001364
1365 // Clean up logging callback, if any
Courtney Goeltzenleuchter1781b1c2015-10-05 15:58:38 -06001366 while (my_data->logging_callback.size() > 0) {
1367 VkDbgMsgCallback callback = my_data->logging_callback.back();
1368 layer_destroy_msg_callback(my_data->report_data, callback);
1369 my_data->logging_callback.pop_back();
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001370 }
1371
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -06001372 layer_debug_report_destroy_instance(my_data->report_data);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001373 delete my_data->instance_dispatch_table;
1374 layer_data_map.erase(key);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001375 // TODO : Potential race here with separate threads creating/destroying instance
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001376 if (layer_data_map.empty()) {
Mike Stroyand9dd0072015-08-18 15:56:18 -06001377 // Release mutex when destroying last instance.
1378 loader_platform_thread_delete_mutex(&globalLock);
1379 globalLockInitialized = 0;
1380 }
Jon Ashburne0fa2282015-05-20 09:00:28 -06001381}
1382
Jon Ashburnf0615e22015-05-25 14:11:37 -06001383static void createDeviceRegisterExtensions(const VkDeviceCreateInfo* pCreateInfo, VkDevice device)
1384{
Tony Barbour29b12062015-07-13 13:37:24 -06001385 uint32_t i;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001386 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1387 dev_data->device_extensions.debug_marker_enabled = false;
Jon Ashburnf0615e22015-05-25 14:11:37 -06001388
1389 for (i = 0; i < pCreateInfo->extensionCount; i++) {
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001390 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], DEBUG_MARKER_EXTENSION_NAME) == 0) {
Jon Ashburn6f8cd632015-06-01 09:37:38 -06001391 /* Found a matching extension name, mark it enabled and init dispatch table*/
1392 initDebugMarkerTable(device);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001393 dev_data->device_extensions.debug_marker_enabled = true;
Jon Ashburnf0615e22015-05-25 14:11:37 -06001394 }
Jon Ashburnf0615e22015-05-25 14:11:37 -06001395 }
1396}
1397
Tony Barbour8205d902015-04-16 15:59:00 -06001398VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001399{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001400 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
1401 VkResult result = dev_data->device_dispatch_table->CreateDevice(gpu, pCreateInfo, pDevice);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001402 if (result == VK_SUCCESS) {
1403 layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001404 dev_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
Jon Ashburn7e07faf2015-06-18 15:02:58 -06001405 createDeviceRegisterExtensions(pCreateInfo, *pDevice);
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06001406 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001407 return result;
1408}
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001409// prototype
1410static void deleteRenderPasses(layer_data*);
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001411VK_LAYER_EXPORT void VKAPI vkDestroyDevice(VkDevice device)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001412{
Jeremy Hayesea1fef52015-06-19 11:37:38 -06001413 dispatch_key key = get_dispatch_key(device);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001414 layer_data* dev_data = get_my_data_ptr(key, layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001415 // Free all the memory
1416 loader_platform_thread_lock_mutex(&globalLock);
1417 deletePipelines(dev_data);
1418 deleteRenderPasses(dev_data);
1419 deleteCmdBuffers(dev_data);
1420 deletePools(dev_data);
1421 deleteLayouts(dev_data);
1422 loader_platform_thread_unlock_mutex(&globalLock);
1423
1424 dev_data->device_dispatch_table->DestroyDevice(device);
1425 tableDebugMarkerMap.erase(key);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001426 delete dev_data->device_dispatch_table;
1427 layer_data_map.erase(key);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001428}
1429
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001430static const VkLayerProperties ds_global_layers[] = {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001431 {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001432 "DrawState",
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001433 VK_API_VERSION,
1434 VK_MAKE_VERSION(0, 1, 0),
1435 "Validation layer: DrawState",
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001436 }
Jon Ashburneb2728b2015-04-10 14:33:07 -06001437};
1438
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001439VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001440 const char *pLayerName,
1441 uint32_t *pCount,
1442 VkExtensionProperties* pProperties)
Jon Ashburneb2728b2015-04-10 14:33:07 -06001443{
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001444 /* DrawState does not have any global extensions */
1445 return util_GetExtensionProperties(0, NULL, pCount, pProperties);
1446}
Jon Ashburneb2728b2015-04-10 14:33:07 -06001447
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001448VK_LAYER_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001449 uint32_t *pCount,
1450 VkLayerProperties* pProperties)
1451{
1452 return util_GetLayerProperties(ARRAY_SIZE(ds_global_layers),
1453 ds_global_layers,
1454 pCount, pProperties);
1455}
Jon Ashburneb2728b2015-04-10 14:33:07 -06001456
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001457static const VkExtensionProperties ds_device_extensions[] = {
1458 {
1459 DEBUG_MARKER_EXTENSION_NAME,
1460 VK_MAKE_VERSION(0, 1, 0),
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001461 }
1462};
1463
1464static const VkLayerProperties ds_device_layers[] = {
1465 {
1466 "DrawState",
1467 VK_API_VERSION,
1468 VK_MAKE_VERSION(0, 1, 0),
1469 "Validation layer: DrawState",
1470 }
1471};
1472
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001473VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceExtensionProperties(
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001474 VkPhysicalDevice physicalDevice,
1475 const char* pLayerName,
1476 uint32_t* pCount,
1477 VkExtensionProperties* pProperties)
1478{
1479 /* Mem tracker does not have any physical device extensions */
1480 return util_GetExtensionProperties(ARRAY_SIZE(ds_device_extensions), ds_device_extensions,
1481 pCount, pProperties);
1482}
1483
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06001484VK_LAYER_EXPORT VkResult VKAPI vkEnumerateDeviceLayerProperties(
Courtney Goeltzenleuchter73e8bd42015-07-06 22:31:52 -06001485 VkPhysicalDevice physicalDevice,
1486 uint32_t* pCount,
1487 VkLayerProperties* pProperties)
1488{
1489 /* Mem tracker's physical device layers are the same as global */
1490 return util_GetLayerProperties(ARRAY_SIZE(ds_device_layers), ds_device_layers,
1491 pCount, pProperties);
Jon Ashburneb2728b2015-04-10 14:33:07 -06001492}
1493
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001494VK_LAYER_EXPORT VkResult VKAPI vkQueueSubmit(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001495{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001496 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001497 GLOBAL_CB_NODE* pCB = NULL;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001498 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(queue), layer_data_map);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001499 for (uint32_t i=0; i < cmdBufferCount; i++) {
1500 // Validate that cmd buffers have been updated
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001501 pCB = getCBNode(dev_data, pCmdBuffers[i]);
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001502 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001503 pCB->submitCount++; // increment submit count
1504 if ((pCB->beginInfo.flags & VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT) && (pCB->submitCount > 1)) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001505 skipCall |= log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_CMD_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -06001506 "CB %#" PRIxLEAST64 " was begun w/ VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT set, but has been submitted %#" PRIxLEAST64 " times.", reinterpret_cast<uint64_t>(pCB->cmdBuffer), pCB->submitCount);
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001507 }
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001508 if (CB_UPDATE_COMPLETE != pCB->state) {
1509 // Flag error for using CB w/o vkEndCommandBuffer() called
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001510 // TODO : How to pass cb as srcObj?
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001511 skipCall |= log_msg(mdd(queue), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_NO_END_CMD_BUFFER, "DS",
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -06001512 "You must call vkEndCommandBuffer() on CB %#" PRIxLEAST64 " before this call to vkQueueSubmit()!", reinterpret_cast<uint64_t>(pCB->cmdBuffer));
Tobin Ehlise90b1712015-05-27 14:30:06 -06001513 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001514 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis28be0be2015-05-22 12:38:16 -06001515 }
Tobin Ehlise9b700e2015-05-26 16:06:50 -06001516 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001517 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001518 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001519 return dev_data->device_dispatch_table->QueueSubmit(queue, cmdBufferCount, pCmdBuffers, fence);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001520 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001521}
1522
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001523VK_LAYER_EXPORT void VKAPI vkDestroyFence(VkDevice device, VkFence fence)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001524{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001525 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyFence(device, fence);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001526 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001527}
1528
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001529VK_LAYER_EXPORT void VKAPI vkDestroySemaphore(VkDevice device, VkSemaphore semaphore)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001530{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001531 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroySemaphore(device, semaphore);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001532 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001533}
1534
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001535VK_LAYER_EXPORT void VKAPI vkDestroyEvent(VkDevice device, VkEvent event)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001536{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001537 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyEvent(device, event);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001538 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001539}
1540
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001541VK_LAYER_EXPORT void VKAPI vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001542{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001543 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyQueryPool(device, queryPool);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001544 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001545}
1546
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001547VK_LAYER_EXPORT void VKAPI vkDestroyBuffer(VkDevice device, VkBuffer buffer)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001548{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001549 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyBuffer(device, buffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001550 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001551}
1552
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001553VK_LAYER_EXPORT void VKAPI vkDestroyBufferView(VkDevice device, VkBufferView bufferView)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001554{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001555 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyBufferView(device, bufferView);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001556 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001557}
1558
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001559VK_LAYER_EXPORT void VKAPI vkDestroyImage(VkDevice device, VkImage image)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001560{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001561 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyImage(device, image);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001562 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001563}
1564
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001565VK_LAYER_EXPORT void VKAPI vkDestroyImageView(VkDevice device, VkImageView imageView)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001566{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001567 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyImageView(device, imageView);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001568 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001569}
1570
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001571VK_LAYER_EXPORT void VKAPI vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001572{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001573 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyShaderModule(device, shaderModule);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001574 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001575}
1576
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001577VK_LAYER_EXPORT void VKAPI vkDestroyShader(VkDevice device, VkShader shader)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001578{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001579 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyShader(device, shader);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001580 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001581}
1582
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001583VK_LAYER_EXPORT void VKAPI vkDestroyPipeline(VkDevice device, VkPipeline pipeline)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001584{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001585 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyPipeline(device, pipeline);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001586 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001587}
1588
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001589VK_LAYER_EXPORT void VKAPI vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001590{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001591 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyPipelineLayout(device, pipelineLayout);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001592 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001593}
1594
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001595VK_LAYER_EXPORT void VKAPI vkDestroySampler(VkDevice device, VkSampler sampler)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001596{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001597 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroySampler(device, sampler);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001598 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001599}
1600
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001601VK_LAYER_EXPORT void VKAPI vkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001602{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001603 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyDescriptorSetLayout(device, descriptorSetLayout);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001604 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001605}
1606
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001607VK_LAYER_EXPORT void VKAPI vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001608{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001609 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyDescriptorPool(device, descriptorPool);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001610 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001611}
1612
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001613VK_LAYER_EXPORT void VKAPI vkDestroyCommandBuffer(VkDevice device, VkCmdBuffer commandBuffer)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001614{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001615 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyCommandBuffer(device, commandBuffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001616 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001617}
1618
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001619VK_LAYER_EXPORT void VKAPI vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001620{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001621 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyFramebuffer(device, framebuffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001622 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001623}
1624
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001625VK_LAYER_EXPORT void VKAPI vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001626{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001627 get_my_data_ptr(get_dispatch_key(device), layer_data_map)->device_dispatch_table->DestroyRenderPass(device, renderPass);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001628 // TODO : Clean up any internal data structures using this obj.
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001629}
1630
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001631VK_LAYER_EXPORT VkResult VKAPI vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001632{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001633 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1634 VkResult result = dev_data->device_dispatch_table->CreateBufferView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001635 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001636 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001637 dev_data->bufferViewMap[pView->handle] = unique_ptr<BUFFER_NODE>(new BUFFER_NODE(pView, pCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001638 loader_platform_thread_unlock_mutex(&globalLock);
1639 }
1640 return result;
1641}
1642
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001643VK_LAYER_EXPORT VkResult VKAPI vkCreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001644{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001645 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1646 VkResult result = dev_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pView);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001647 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001648 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001649 dev_data->imageViewMap[pView->handle] = unique_ptr<VkImageViewCreateInfo>(new VkImageViewCreateInfo(*pCreateInfo));
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06001650 loader_platform_thread_unlock_mutex(&globalLock);
1651 }
1652 return result;
1653}
1654
Jon Ashburn0d60d272015-07-09 15:02:25 -06001655//TODO handle pipeline caches
1656VkResult VKAPI vkCreatePipelineCache(
1657 VkDevice device,
1658 const VkPipelineCacheCreateInfo* pCreateInfo,
1659 VkPipelineCache* pPipelineCache)
1660{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001661 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1662 VkResult result = dev_data->device_dispatch_table->CreatePipelineCache(device, pCreateInfo, pPipelineCache);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001663 return result;
1664}
1665
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001666void VKAPI vkDestroyPipelineCache(
Jon Ashburn0d60d272015-07-09 15:02:25 -06001667 VkDevice device,
1668 VkPipelineCache pipelineCache)
1669{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001670 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1671 dev_data->device_dispatch_table->DestroyPipelineCache(device, pipelineCache);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001672}
1673
1674size_t VKAPI vkGetPipelineCacheSize(
1675 VkDevice device,
1676 VkPipelineCache pipelineCache)
1677{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001678 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1679 size_t size = dev_data->device_dispatch_table->GetPipelineCacheSize(device, pipelineCache);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001680 return size;
1681}
1682
1683VkResult VKAPI vkGetPipelineCacheData(
1684 VkDevice device,
1685 VkPipelineCache pipelineCache,
1686 void* pData)
1687{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001688 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1689 VkResult result = dev_data->device_dispatch_table->GetPipelineCacheData(device, pipelineCache, pData);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001690 return result;
1691}
1692
1693VkResult VKAPI vkMergePipelineCaches(
1694 VkDevice device,
1695 VkPipelineCache destCache,
1696 uint32_t srcCacheCount,
1697 const VkPipelineCache* pSrcCaches)
1698{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001699 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1700 VkResult result = dev_data->device_dispatch_table->MergePipelineCaches(device, destCache, srcCacheCount, pSrcCaches);
Jon Ashburn0d60d272015-07-09 15:02:25 -06001701 return result;
1702}
1703
1704VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001705{
Courtney Goeltzenleuchtera54b76a2015-09-04 13:39:59 -06001706 VkResult result = VK_SUCCESS;
Tobin Ehlise48be202015-09-16 10:33:53 -06001707 //TODO What to do with pipelineCache?
Tobin Ehlisde63c532015-06-18 15:59:33 -06001708 // The order of operations here is a little convoluted but gets the job done
1709 // 1. Pipeline create state is first shadowed into PIPELINE_NODE struct
1710 // 2. Create state is then validated (which uses flags setup during shadowing)
1711 // 3. If everything looks good, we'll then create the pipeline and add NODE to pipelineMap
Tobin Ehlise48be202015-09-16 10:33:53 -06001712 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis76c18852015-09-17 16:33:58 -06001713 // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic
1714 vector<PIPELINE_NODE*> pPipeNode(count);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001715 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlise48be202015-09-16 10:33:53 -06001716 uint32_t i=0;
Tobin Ehlisde63c532015-06-18 15:59:33 -06001717 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlise48be202015-09-16 10:33:53 -06001718 for (i=0; i<count; i++) {
1719 pPipeNode[i] = initPipeline(&pCreateInfos[i], NULL);
1720 skipCall |= verifyPipelineCreateState(device, pPipeNode[i]);
1721 }
Tobin Ehlisde63c532015-06-18 15:59:33 -06001722 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001723 if (VK_FALSE == skipCall) {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001724 result = dev_data->device_dispatch_table->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pPipelines);
Tobin Ehlisde63c532015-06-18 15:59:33 -06001725 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlise48be202015-09-16 10:33:53 -06001726 for (i=0; i<count; i++) {
1727 pPipeNode[i]->pipeline = pPipelines[i];
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001728 dev_data->pipelineMap[pPipeNode[i]->pipeline.handle] = pPipeNode[i];
Tobin Ehlise48be202015-09-16 10:33:53 -06001729 }
Tobin Ehlisde63c532015-06-18 15:59:33 -06001730 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001731 } else {
Tobin Ehlise48be202015-09-16 10:33:53 -06001732 for (i=0; i<count; i++) {
1733 if (pPipeNode[i]) {
1734 // If we allocated a pipeNode, need to clean it up here
1735 delete[] pPipeNode[i]->pVertexBindingDescriptions;
1736 delete[] pPipeNode[i]->pVertexAttributeDescriptions;
1737 delete[] pPipeNode[i]->pAttachments;
1738 delete pPipeNode[i];
1739 }
Tobin Ehlisde63c532015-06-18 15:59:33 -06001740 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001741 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlisde63c532015-06-18 15:59:33 -06001742 }
Courtney Goeltzenleuchter9452ac22015-04-13 16:16:04 -06001743 return result;
1744}
1745
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001746VK_LAYER_EXPORT VkResult VKAPI vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001747{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001748 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1749 VkResult result = dev_data->device_dispatch_table->CreateSampler(device, pCreateInfo, pSampler);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001750 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001751 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001752 dev_data->sampleMap[pSampler->handle] = unique_ptr<SAMPLER_NODE>(new SAMPLER_NODE(pSampler, pCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001753 loader_platform_thread_unlock_mutex(&globalLock);
1754 }
1755 return result;
1756}
1757
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001758VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001759{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001760 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1761 VkResult result = dev_data->device_dispatch_table->CreateDescriptorSetLayout(device, pCreateInfo, pSetLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001762 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001763 LAYOUT_NODE* pNewNode = new LAYOUT_NODE;
1764 if (NULL == pNewNode) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001765 if (log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (*pSetLayout).handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
1766 "Out of memory while attempting to allocate LAYOUT_NODE in vkCreateDescriptorSetLayout()"))
1767 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001768 }
1769 memset(pNewNode, 0, sizeof(LAYOUT_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001770 memcpy((void*)&pNewNode->createInfo, pCreateInfo, sizeof(VkDescriptorSetLayoutCreateInfo));
1771 pNewNode->createInfo.pBinding = new VkDescriptorSetLayoutBinding[pCreateInfo->count];
1772 memcpy((void*)pNewNode->createInfo.pBinding, pCreateInfo->pBinding, sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->count);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001773 uint32_t totalCount = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001774 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001775 totalCount += pCreateInfo->pBinding[i].arraySize;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001776 if (pCreateInfo->pBinding[i].pImmutableSamplers) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001777 VkSampler** ppIS = (VkSampler**)&pNewNode->createInfo.pBinding[i].pImmutableSamplers;
Chia-I Wud3114a22015-05-25 16:22:52 +08001778 *ppIS = new VkSampler[pCreateInfo->pBinding[i].arraySize];
1779 memcpy(*ppIS, pCreateInfo->pBinding[i].pImmutableSamplers, pCreateInfo->pBinding[i].arraySize*sizeof(VkSampler));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001780 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001781 }
1782 if (totalCount > 0) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001783 pNewNode->pTypes = new VkDescriptorType[totalCount];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001784 uint32_t offset = 0;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001785 uint32_t j = 0;
1786 for (uint32_t i=0; i<pCreateInfo->count; i++) {
Chia-I Wud3114a22015-05-25 16:22:52 +08001787 for (j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001788 pNewNode->pTypes[offset + j] = pCreateInfo->pBinding[i].descriptorType;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001789 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001790 offset += j;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001791 }
1792 }
1793 pNewNode->layout = *pSetLayout;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001794 pNewNode->startIndex = 0;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001795 pNewNode->endIndex = pNewNode->startIndex + totalCount - 1;
1796 assert(pNewNode->endIndex >= pNewNode->startIndex);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001797 // Put new node at Head of global Layer list
1798 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001799 dev_data->layoutMap[pSetLayout->handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001800 loader_platform_thread_unlock_mutex(&globalLock);
1801 }
1802 return result;
1803}
1804
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001805VkResult VKAPI vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001806{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001807 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1808 VkResult result = dev_data->device_dispatch_table->CreatePipelineLayout(device, pCreateInfo, pPipelineLayout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001809 if (VK_SUCCESS == result) {
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001810 // TODO : Need to capture the pipeline layout
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001811 }
1812 return result;
1813}
1814
Courtney Goeltzenleuchterd9e966a2015-09-16 16:12:45 -06001815VK_LAYER_EXPORT VkResult VKAPI vkCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001816{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001817 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1818 VkResult result = dev_data->device_dispatch_table->CreateDescriptorPool(device, pCreateInfo, pDescriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001819 if (VK_SUCCESS == result) {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001820 // Insert this pool into Global Pool LL at head
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001821 if (log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (*pDescriptorPool).handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
1822 "Created Descriptor Pool %#" PRIxLEAST64, (*pDescriptorPool).handle))
1823 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001824 loader_platform_thread_lock_mutex(&globalLock);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001825 POOL_NODE* pNewNode = new POOL_NODE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001826 if (NULL == pNewNode) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001827 if (log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (*pDescriptorPool).handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
1828 "Out of memory while attempting to allocate POOL_NODE in vkCreateDescriptorPool()"))
1829 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001830 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001831 memset(pNewNode, 0, sizeof(POOL_NODE));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001832 VkDescriptorPoolCreateInfo* pCI = (VkDescriptorPoolCreateInfo*)&pNewNode->createInfo;
1833 memcpy((void*)pCI, pCreateInfo, sizeof(VkDescriptorPoolCreateInfo));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001834 if (pNewNode->createInfo.count) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001835 size_t typeCountSize = pNewNode->createInfo.count * sizeof(VkDescriptorTypeCount);
1836 pNewNode->createInfo.pTypeCount = new VkDescriptorTypeCount[typeCountSize];
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001837 memcpy((void*)pNewNode->createInfo.pTypeCount, pCreateInfo->pTypeCount, typeCountSize);
1838 }
Courtney Goeltzenleuchterd9e966a2015-09-16 16:12:45 -06001839 pNewNode->poolUsage = pCreateInfo->poolUsage;
Tobin Ehlis3c543112015-10-08 13:13:50 -06001840 pNewNode->maxSets = pCreateInfo->maxSets;
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001841 pNewNode->pool = *pDescriptorPool;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001842 dev_data->poolMap[pDescriptorPool->handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001843 }
1844 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001845 } else {
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001846 // Need to do anything if pool create fails?
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001847 }
1848 return result;
1849}
1850
Mike Stroyan230e6252015-04-17 12:36:38 -06001851VK_LAYER_EXPORT VkResult VKAPI vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001852{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001853 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1854 VkResult result = dev_data->device_dispatch_table->ResetDescriptorPool(device, descriptorPool);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001855 if (VK_SUCCESS == result) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001856 clearDescriptorPool(dev_data, device, descriptorPool);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001857 }
1858 return result;
1859}
1860
Cody Northropc8aa4a52015-08-03 12:47:29 -06001861VK_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 -06001862{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001863 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1864 VkResult result = dev_data->device_dispatch_table->AllocDescriptorSets(device, descriptorPool, setUsage, count, pSetLayouts, pDescriptorSets);
Cody Northropc8aa4a52015-08-03 12:47:29 -06001865 if (VK_SUCCESS == result) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001866 POOL_NODE *pPoolNode = getPoolNode(dev_data, descriptorPool);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001867 if (!pPoolNode) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001868 log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_POOL, descriptorPool.handle, 0, DRAWSTATE_INVALID_POOL, "DS",
1869 "Unable to find pool node for pool %#" PRIxLEAST64 " specified in vkAllocDescriptorSets() call", descriptorPool.handle);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001870 } else {
Cody Northropc8aa4a52015-08-03 12:47:29 -06001871 if (count == 0) {
1872 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, count, 0, DRAWSTATE_NONE, "DS",
1873 "AllocDescriptorSets called with 0 count");
1874 }
1875 for (uint32_t i = 0; i < count; i++) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06001876 log_msg(mdd(device), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_NONE, "DS",
1877 "Created Descriptor Set %#" PRIxLEAST64, pDescriptorSets[i].handle);
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001878 // Create new set node and add to head of pool nodes
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001879 SET_NODE* pNewNode = new SET_NODE;
1880 if (NULL == pNewNode) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001881 if (log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_OUT_OF_MEMORY, "DS",
1882 "Out of memory while attempting to allocate SET_NODE in vkAllocDescriptorSets()"))
1883 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06001884 } else {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001885 memset(pNewNode, 0, sizeof(SET_NODE));
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001886 // Insert set at head of Set LL for this pool
1887 pNewNode->pNext = pPoolNode->pSets;
1888 pPoolNode->pSets = pNewNode;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001889 LAYOUT_NODE* pLayout = getLayoutNode(dev_data, pSetLayouts[i]);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001890 if (NULL == pLayout) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001891 if (log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, pSetLayouts[i].handle, 0, DRAWSTATE_INVALID_LAYOUT, "DS",
1892 "Unable to find set layout node for layout %#" PRIxLEAST64 " specified in vkAllocDescriptorSets() call", pSetLayouts[i].handle))
1893 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001894 }
Tobin Ehlisdd82f6b2015-04-03 12:01:11 -06001895 pNewNode->pLayout = pLayout;
1896 pNewNode->pool = descriptorPool;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001897 pNewNode->set = pDescriptorSets[i];
1898 pNewNode->setUsage = setUsage;
1899 pNewNode->descriptorCount = pLayout->endIndex + 1;
1900 if (pNewNode->descriptorCount) {
1901 size_t descriptorArraySize = sizeof(GENERIC_HEADER*)*pNewNode->descriptorCount;
1902 pNewNode->ppDescriptors = new GENERIC_HEADER*[descriptorArraySize];
1903 memset(pNewNode->ppDescriptors, 0, descriptorArraySize);
1904 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001905 dev_data->setMap[pDescriptorSets[i].handle] = pNewNode;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001906 }
1907 }
1908 }
1909 }
1910 return result;
1911}
1912
Tony Barbourb857d312015-07-10 10:50:45 -06001913VK_LAYER_EXPORT VkResult VKAPI vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets)
1914{
Tobin Ehlis3c543112015-10-08 13:13:50 -06001915 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001916 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
Tobin Ehlis3c543112015-10-08 13:13:50 -06001917 POOL_NODE *pPoolNode = getPoolNode(dev_data, descriptorPool);
1918 if (pPoolNode && (VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT == pPoolNode->poolUsage)) {
1919 // Can't Free from a ONE_SHOT pool
1920 skipCall |= log_msg(mdd(device), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DEVICE, (uint64_t)device, 0, DRAWSTATE_CANT_FREE_FROM_ONE_SHOT_POOL, "DS",
1921 "It is invalid to call vkFreeDescriptorSets() with a pool created with usage type VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT.");
1922 }
1923 if (skipCall)
1924 return VK_ERROR_VALIDATION_FAILED;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001925 VkResult result = dev_data->device_dispatch_table->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
Tony Barbourb857d312015-07-10 10:50:45 -06001926 // TODO : Clean up any internal data structures using this obj.
1927 return result;
1928}
1929
Mark Lobodzinski67b42b72015-09-07 13:59:43 -06001930VK_LAYER_EXPORT void VKAPI vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001931{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001932 // dsUpdate will return VK_TRUE only if a bailout error occurs, so we want to call down tree when both updates return VK_FALSE
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001933 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1934 if (!dsUpdate(dev_data, device, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, writeCount, pDescriptorWrites) &&
1935 !dsUpdate(dev_data, device, VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, copyCount, pDescriptorCopies)) {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001936 dev_data->device_dispatch_table->UpdateDescriptorSets(device, writeCount, pDescriptorWrites, copyCount, pDescriptorCopies);
Jon Ashburne0fa2282015-05-20 09:00:28 -06001937 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001938}
1939
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001940VK_LAYER_EXPORT VkResult VKAPI vkCreateCommandBuffer(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001941{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001942 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
1943 VkResult result = dev_data->device_dispatch_table->CreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001944 if (VK_SUCCESS == result) {
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001945 loader_platform_thread_lock_mutex(&globalLock);
1946 GLOBAL_CB_NODE* pCB = new GLOBAL_CB_NODE;
1947 memset(pCB, 0, sizeof(GLOBAL_CB_NODE));
1948 pCB->cmdBuffer = *pCmdBuffer;
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001949 pCB->createInfo = *pCreateInfo;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001950 pCB->lastVtxBinding = MAX_BINDING;
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06001951 pCB->level = pCreateInfo->level;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001952 dev_data->cmdBufferMap[*pCmdBuffer] = pCB;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001953 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001954 updateCBTracking(pCB);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001955 }
1956 return result;
1957}
1958
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001959VK_LAYER_EXPORT VkResult VKAPI vkBeginCommandBuffer(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001960{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001961 VkBool32 skipCall = false;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001962 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06001963 // Validate command buffer level
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001964 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06001965 if (pCB) {
1966 if (pCB->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
1967 if (pBeginInfo->renderPass.handle || pBeginInfo->framebuffer.handle) {
1968 // These should be NULL for a Primary CB
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001969 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06001970 "vkCreateCommandBuffer(): Primary Command Buffer (%p) may not specify framebuffer or renderpass parameters", (void*)cmdBuffer);
1971 }
1972 } else {
1973 if (!pBeginInfo->renderPass.handle || !pBeginInfo->framebuffer.handle) {
1974 // These should NOT be null for an Secondary CB
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001975 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06001976 "vkCreateCommandBuffer(): Secondary Command Buffers (%p) must specify framebuffer and renderpass parameters", (void*)cmdBuffer);
1977 }
1978 }
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001979 pCB->beginInfo = *pBeginInfo;
1980 } else {
1981 // TODO : Need to pass cmdBuffer as objType here
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001982 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, 0, 0, DRAWSTATE_INVALID_CMD_BUFFER, "DS",
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001983 "In vkBeginCommandBuffer() and unable to find CmdBuffer Node for CB %p!", (void*)cmdBuffer);
Mark Lobodzinski90bf5b02015-08-04 16:24:20 -06001984 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06001985 if (skipCall) {
1986 return VK_ERROR_VALIDATION_FAILED;
Courtney Goeltzenleuchter3abd86e2015-09-04 15:03:52 -06001987 }
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06001988 VkResult result = dev_data->device_dispatch_table->BeginCommandBuffer(cmdBuffer, pBeginInfo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001989 if (VK_SUCCESS == result) {
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001990 if (CB_NEW != pCB->state)
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001991 resetCB(dev_data, cmdBuffer);
Tobin Ehlis0cea4082015-08-18 07:10:58 -06001992 pCB->state = CB_UPDATE_ACTIVE;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06001993 updateCBTracking(pCB);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001994 }
1995 return result;
1996}
1997
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001998VK_LAYER_EXPORT VkResult VKAPI vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06001999{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002000 VkBool32 skipCall = VK_FALSE;
Courtney Goeltzenleuchtera54b76a2015-09-04 13:39:59 -06002001 VkResult result = VK_SUCCESS;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002002 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
2003 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Courtney Goeltzenleuchtera54b76a2015-09-04 13:39:59 -06002004 /* TODO: preference is to always call API function after reporting any validation errors */
Tobin Ehlise42007c2015-06-19 13:00:59 -06002005 if (pCB) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002006 if (pCB->state != CB_UPDATE_ACTIVE) {
2007 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkEndCommandBuffer()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002008 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002009 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002010 if (VK_FALSE == skipCall) {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002011 result = dev_data->device_dispatch_table->EndCommandBuffer(cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002012 if (VK_SUCCESS == result) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002013 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002014 pCB->state = CB_UPDATE_COMPLETE;
2015 // Reset CB status flags
2016 pCB->status = 0;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002017 printCB(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002018 }
2019 } else {
2020 result = VK_ERROR_VALIDATION_FAILED;
2021 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002022 return result;
2023}
2024
Cody Northropf02f9f82015-07-09 18:08:05 -06002025VK_LAYER_EXPORT VkResult VKAPI vkResetCommandBuffer(VkCmdBuffer cmdBuffer, VkCmdBufferResetFlags flags)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002026{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002027 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
2028 VkResult result = dev_data->device_dispatch_table->ResetCommandBuffer(cmdBuffer, flags);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002029 if (VK_SUCCESS == result) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002030 resetCB(dev_data, cmdBuffer);
2031 updateCBTracking(getCBNode(dev_data, cmdBuffer));
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002032 }
2033 return result;
2034}
2035
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002036VK_LAYER_EXPORT void VKAPI vkCmdBindPipeline(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002037{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002038 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002039 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002040 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002041 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002042 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002043 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002044 skipCall |= addCmd(pCB, CMD_BINDPIPELINE);
Tobin Ehlis642d5a52015-06-23 08:46:18 -06002045 if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (pCB->activeRenderPass)) {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002046 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle,
2047 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
2048 "Incorrectly binding compute pipeline (%#" PRIxLEAST64 ") during active RenderPass (%#" PRIxLEAST64 ")",
2049 pipeline.handle, pCB->activeRenderPass.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002050 } else if ((VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) && (!pCB->activeRenderPass)) {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002051 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle,
2052 0, DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS", "Incorrectly binding graphics pipeline "
2053 " (%#" PRIxLEAST64 ") without an active RenderPass", pipeline.handle);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002054 } else {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002055 PIPELINE_NODE* pPN = getPipeline(dev_data, pipeline);
Tobin Ehlise4076782015-06-24 15:53:07 -06002056 if (pPN) {
2057 pCB->lastBoundPipeline = pipeline;
2058 loader_platform_thread_lock_mutex(&globalLock);
2059 set_cb_pso_status(pCB, pPN);
2060 g_lastBoundPipeline = pPN;
2061 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002062 skipCall |= validatePipelineState(dev_data, pCB, pipelineBindPoint, pipeline);
Tobin Ehlise4076782015-06-24 15:53:07 -06002063 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002064 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_PIPELINE, pipeline.handle,
2065 0, DRAWSTATE_INVALID_PIPELINE, "DS",
2066 "Attempt to bind Pipeline %#" PRIxLEAST64 " that doesn't exist!", (void*)pipeline.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002067 }
Tobin Ehlise42007c2015-06-19 13:00:59 -06002068 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002069 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002070 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBindPipeline()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002071 }
2072 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002073 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002074 dev_data->device_dispatch_table->CmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002075}
2076
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002077VK_LAYER_EXPORT void VKAPI vkCmdSetViewport(
2078 VkCmdBuffer cmdBuffer,
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002079 uint32_t viewportCount,
2080 const VkViewport* pViewports)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002081{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002082 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002083 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002084 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002085 if (pCB) {
2086 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002087 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002088 skipCall |= addCmd(pCB, CMD_SETVIEWPORTSTATE);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002089 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002090 pCB->status |= CBSTATUS_VIEWPORT_SET;
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002091 pCB->viewports.resize(viewportCount);
Tobin Ehlis9e839e52015-10-01 11:15:13 -06002092 memcpy(pCB->viewports.data(), pViewports, viewportCount * sizeof(VkViewport));
Tobin Ehlise42007c2015-06-19 13:00:59 -06002093 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002094 } else {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002095 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetViewport()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002096 }
2097 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002098 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002099 dev_data->device_dispatch_table->CmdSetViewport(cmdBuffer, viewportCount, pViewports);
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002100}
2101
2102VK_LAYER_EXPORT void VKAPI vkCmdSetScissor(
2103 VkCmdBuffer cmdBuffer,
2104 uint32_t scissorCount,
2105 const VkRect2D* pScissors)
2106{
2107 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002108 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002109 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002110 if (pCB) {
2111 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002112 updateCBTracking(pCB);
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002113 skipCall |= addCmd(pCB, CMD_SETSCISSORSTATE);
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002114 loader_platform_thread_lock_mutex(&globalLock);
2115 pCB->status |= CBSTATUS_SCISSOR_SET;
2116 pCB->scissors.resize(scissorCount);
Tobin Ehlis9e839e52015-10-01 11:15:13 -06002117 memcpy(pCB->scissors.data(), pScissors, scissorCount * sizeof(VkRect2D));
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06002118 loader_platform_thread_unlock_mutex(&globalLock);
2119 } else {
2120 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetScissor()");
2121 }
2122 }
2123 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002124 dev_data->device_dispatch_table->CmdSetScissor(cmdBuffer, scissorCount, pScissors);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002125}
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002126
2127VK_LAYER_EXPORT void VKAPI vkCmdSetLineWidth(VkCmdBuffer cmdBuffer, float lineWidth)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002128{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002129 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002130 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002131 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002132 if (pCB) {
2133 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002134 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002135 skipCall |= addCmd(pCB, CMD_SETLINEWIDTHSTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002136 /* TODO: Do we still need this lock? */
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002137 loader_platform_thread_lock_mutex(&globalLock);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002138 pCB->status |= CBSTATUS_LINE_WIDTH_SET;
2139 pCB->lineWidth = lineWidth;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002140 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002141 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002142 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBindDynamicLineWidthState()");
Cody Northropf5bd2252015-08-17 11:10:49 -06002143 }
2144 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002145 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002146 dev_data->device_dispatch_table->CmdSetLineWidth(cmdBuffer, lineWidth);
Cody Northropf5bd2252015-08-17 11:10:49 -06002147}
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002148
2149VK_LAYER_EXPORT void VKAPI vkCmdSetDepthBias(
2150 VkCmdBuffer cmdBuffer,
2151 float depthBias,
2152 float depthBiasClamp,
2153 float slopeScaledDepthBias)
Cody Northropf5bd2252015-08-17 11:10:49 -06002154{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002155 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002156 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002157 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Cody Northropf5bd2252015-08-17 11:10:49 -06002158 if (pCB) {
2159 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002160 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002161 skipCall |= addCmd(pCB, CMD_SETDEPTHBIASSTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002162 pCB->status |= CBSTATUS_DEPTH_BIAS_SET;
2163 pCB->depthBias = depthBias;
2164 pCB->depthBiasClamp = depthBiasClamp;
2165 pCB->slopeScaledDepthBias = slopeScaledDepthBias;
Cody Northropf5bd2252015-08-17 11:10:49 -06002166 } else {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002167 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetDepthBias()");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002168 }
2169 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002170 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002171 dev_data->device_dispatch_table->CmdSetDepthBias(cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002172}
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002173
2174VK_LAYER_EXPORT void VKAPI vkCmdSetBlendConstants(VkCmdBuffer cmdBuffer, const float blendConst[4])
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002175{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002176 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002177 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002178 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002179 if (pCB) {
2180 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002181 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002182 skipCall |= addCmd(pCB, CMD_SETBLENDSTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002183 pCB->status |= CBSTATUS_BLEND_SET;
2184 memcpy(pCB->blendConst, blendConst, 4 * sizeof(float));
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002185 } else {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002186 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetBlendConstants()");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002187 }
2188 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002189 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002190 dev_data->device_dispatch_table->CmdSetBlendConstants(cmdBuffer, blendConst);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002191}
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002192
2193VK_LAYER_EXPORT void VKAPI vkCmdSetDepthBounds(
2194 VkCmdBuffer cmdBuffer,
2195 float minDepthBounds,
2196 float maxDepthBounds)
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002197{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002198 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002199 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002200 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002201 if (pCB) {
2202 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002203 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002204 skipCall |= addCmd(pCB, CMD_SETDEPTHBOUNDSSTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002205 pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET;
2206 pCB->minDepthBounds = minDepthBounds;
2207 pCB->maxDepthBounds = maxDepthBounds;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002208 } else {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002209 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetDepthBounds()");
Cody Northrop2605cb02015-08-18 15:21:16 -06002210 }
2211 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002212 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002213 dev_data->device_dispatch_table->CmdSetDepthBounds(cmdBuffer, minDepthBounds, maxDepthBounds);
Cody Northrop2605cb02015-08-18 15:21:16 -06002214}
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002215
2216VK_LAYER_EXPORT void VKAPI vkCmdSetStencilCompareMask(
2217 VkCmdBuffer cmdBuffer,
2218 VkStencilFaceFlags faceMask,
2219 uint32_t stencilCompareMask)
Cody Northrop2605cb02015-08-18 15:21:16 -06002220{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002221 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002222 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002223 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Cody Northrop2605cb02015-08-18 15:21:16 -06002224 if (pCB) {
2225 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002226 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002227 skipCall |= addCmd(pCB, CMD_SETSTENCILREADMASKSTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002228 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2229 pCB->front.stencilCompareMask = stencilCompareMask;
Cody Northrop2605cb02015-08-18 15:21:16 -06002230 }
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002231 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2232 pCB->back.stencilCompareMask = stencilCompareMask;
2233 }
2234 /* TODO: Do we need to track front and back separately? */
2235 /* TODO: We aren't capturing the faceMask, do we need to? */
2236 pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET;
Cody Northrop2605cb02015-08-18 15:21:16 -06002237 } else {
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002238 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetStencilCompareMask()");
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002239 }
2240 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002241 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002242 dev_data->device_dispatch_table->CmdSetStencilCompareMask(cmdBuffer, faceMask, stencilCompareMask);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002243}
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002244
2245VK_LAYER_EXPORT void VKAPI vkCmdSetStencilWriteMask(
2246 VkCmdBuffer cmdBuffer,
2247 VkStencilFaceFlags faceMask,
2248 uint32_t stencilWriteMask)
2249{
2250 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002251 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002252 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002253 if (pCB) {
2254 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002255 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002256 skipCall |= addCmd(pCB, CMD_SETSTENCILWRITEMASKSTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002257 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2258 pCB->front.stencilWriteMask = stencilWriteMask;
2259 }
2260 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2261 pCB->back.stencilWriteMask = stencilWriteMask;
2262 }
2263 pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET;
2264 } else {
2265 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetStencilWriteMask()");
2266 }
2267 }
2268 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002269 dev_data->device_dispatch_table->CmdSetStencilWriteMask(cmdBuffer, faceMask, stencilWriteMask);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002270}
2271
2272VK_LAYER_EXPORT void VKAPI vkCmdSetStencilReference(
2273 VkCmdBuffer cmdBuffer,
2274 VkStencilFaceFlags faceMask,
2275 uint32_t stencilReference)
2276{
2277 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002278 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002279 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002280 if (pCB) {
2281 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002282 updateCBTracking(pCB);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002283 skipCall |= addCmd(pCB, CMD_SETSTENCILREFERENCESTATE);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002284 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
2285 pCB->front.stencilReference = stencilReference;
2286 }
2287 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
2288 pCB->back.stencilReference = stencilReference;
2289 }
2290 pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET;
2291 } else {
2292 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetStencilReference()");
2293 }
2294 }
2295 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002296 dev_data->device_dispatch_table->CmdSetStencilReference(cmdBuffer, faceMask, stencilReference);
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06002297}
2298
Mark Lobodzinskia65c4632015-06-15 13:21:21 -06002299VK_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 -06002300{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002301 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002302 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002303 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002304 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002305 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise4076782015-06-24 15:53:07 -06002306 if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (pCB->activeRenderPass)) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002307 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002308 "Incorrectly binding compute DescriptorSets during active RenderPass (%#" PRIxLEAST64 ")", pCB->activeRenderPass.handle);
Tobin Ehlise4076782015-06-24 15:53:07 -06002309 } else if ((VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) && (!pCB->activeRenderPass)) {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002310 skipCall |= 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 -06002311 "Incorrectly binding graphics DescriptorSets without an active RenderPass");
Tobin Ehlisd28acef2015-09-09 15:12:35 -06002312 } else {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002313 for (uint32_t i=0; i<setCount; i++) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002314 SET_NODE* pSet = getSetNode(dev_data, pDescriptorSets[i]);
Tobin Ehlis55c1c602015-06-24 17:27:33 -06002315 if (pSet) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002316 loader_platform_thread_lock_mutex(&globalLock);
2317 pCB->lastBoundDescriptorSet = pDescriptorSets[i];
Tobin Ehlisc6c3d6d2015-06-22 17:20:50 -06002318 pCB->lastBoundPipelineLayout = layout;
Tobin Ehlise42007c2015-06-19 13:00:59 -06002319 pCB->boundDescriptorSets.push_back(pDescriptorSets[i]);
2320 g_lastBoundDescriptorSet = pDescriptorSets[i];
2321 loader_platform_thread_unlock_mutex(&globalLock);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002322 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_INFO_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_NONE, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002323 "DS %#" PRIxLEAST64 " bound on pipeline %s", pDescriptorSets[i].handle, string_VkPipelineBindPoint(pipelineBindPoint));
Tobin Ehlis55c1c602015-06-24 17:27:33 -06002324 if (!pSet->pUpdateStructs)
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002325 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_WARN_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002326 "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 -06002327 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002328 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_DESCRIPTOR_SET, pDescriptorSets[i].handle, 0, DRAWSTATE_INVALID_SET, "DS",
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002329 "Attempt to bind DS %#" PRIxLEAST64 " that doesn't exist!", pDescriptorSets[i].handle);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002330 }
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002331 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002332 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002333 skipCall |= addCmd(pCB, CMD_BINDDESCRIPTORSETS);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002334 }
Tobin Ehlise42007c2015-06-19 13:00:59 -06002335 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002336 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBindDescriptorSets()");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002337 }
2338 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002339 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002340 dev_data->device_dispatch_table->CmdBindDescriptorSets(cmdBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002341}
2342
Tony Barbour8205d902015-04-16 15:59:00 -06002343VK_LAYER_EXPORT void VKAPI vkCmdBindIndexBuffer(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002344{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002345 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002346 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002347 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002348 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002349 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlis8d199e52015-09-17 12:24:13 -06002350 VkDeviceSize offset_align = 0;
2351 switch (indexType) {
2352 case VK_INDEX_TYPE_UINT16:
2353 offset_align = 2;
2354 break;
2355 case VK_INDEX_TYPE_UINT32:
2356 offset_align = 4;
2357 break;
2358 default:
2359 // ParamChecker should catch bad enum, we'll also throw alignment error below if offset_align stays 0
2360 break;
2361 }
2362 if (!offset_align || (offset % offset_align)) {
2363 skipCall |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, "DS",
2364 "vkCmdBindIndexBuffer() offset (%#" PRIxLEAST64 ") does not fall on alignment (%s) boundary.", offset, string_VkIndexType(indexType));
Tobin Ehlise4076782015-06-24 15:53:07 -06002365 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002366 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002367 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBindIndexBuffer()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002368 }
Tobin Ehlis8d199e52015-09-17 12:24:13 -06002369 pCB->status |= CBSTATUS_INDEX_BUFFER_BOUND;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002370 updateCBTracking(pCB);
Tobin Ehlis8d199e52015-09-17 12:24:13 -06002371 skipCall |= addCmd(pCB, CMD_BINDINDEXBUFFER);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002372 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002373 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002374 dev_data->device_dispatch_table->CmdBindIndexBuffer(cmdBuffer, buffer, offset, indexType);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002375}
2376
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06002377VK_LAYER_EXPORT void VKAPI vkCmdBindVertexBuffers(
2378 VkCmdBuffer cmdBuffer,
2379 uint32_t startBinding,
2380 uint32_t bindingCount,
2381 const VkBuffer* pBuffers,
Tony Barbour8205d902015-04-16 15:59:00 -06002382 const VkDeviceSize* pOffsets)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002383{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002384 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002385 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002386 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002387 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002388 if (pCB->state == CB_UPDATE_ACTIVE) {
2389 /* TODO: Need to track all the vertex buffers, not just last one */
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002390 pCB->lastVtxBinding = startBinding + bindingCount -1;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002391 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002392 addCmd(pCB, CMD_BINDVERTEXBUFFER);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002393 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002394 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBindVertexBuffer()");
Tobin Ehlis0b551cd2015-05-28 12:10:17 -06002395 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002396 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002397 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002398 dev_data->device_dispatch_table->CmdBindVertexBuffers(cmdBuffer, startBinding, bindingCount, pBuffers, pOffsets);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002399}
2400
Courtney Goeltzenleuchter4ff11cc2015-09-23 12:31:50 -06002401VK_LAYER_EXPORT void VKAPI vkCmdDraw(VkCmdBuffer cmdBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002402{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002403 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002404 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002405 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002406 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002407 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002408 pCB->drawCount[DRAW]++;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002409 skipCall |= validate_draw_state(dev_data, pCB, VK_FALSE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002410 // TODO : Need to pass cmdBuffer as srcObj here
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002411 skipCall |= 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 -06002412 "vkCmdDraw() call #%lu, reporting DS state:", g_drawCount[DRAW]++);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002413 skipCall |= synchAndPrintDSConfig(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002414 if (VK_FALSE == skipCall) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002415 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002416 skipCall |= addCmd(pCB, CMD_DRAW);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002417 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002418 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002419 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdDraw()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002420 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002421 skipCall |= outsideRenderPass(pCB, "vkCmdDraw");
Jon Ashburne0fa2282015-05-20 09:00:28 -06002422 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002423 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002424 dev_data->device_dispatch_table->CmdDraw(cmdBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002425}
2426
Courtney Goeltzenleuchter4ff11cc2015-09-23 12:31:50 -06002427VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexed(VkCmdBuffer cmdBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002428{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002429 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002430 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002431 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002432 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002433 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002434 pCB->drawCount[DRAW_INDEXED]++;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002435 skipCall |= validate_draw_state(dev_data, pCB, VK_TRUE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002436 // TODO : Need to pass cmdBuffer as srcObj here
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002437 skipCall |= 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 -06002438 "vkCmdDrawIndexed() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED]++);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002439 skipCall |= synchAndPrintDSConfig(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002440 if (VK_FALSE == skipCall) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002441 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002442 skipCall |= addCmd(pCB, CMD_DRAWINDEXED);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002443 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002444 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002445 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdDrawIndexed()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002446 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002447 skipCall |= outsideRenderPass(pCB, "vkCmdDrawIndexed");
Jon Ashburne0fa2282015-05-20 09:00:28 -06002448 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002449 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002450 dev_data->device_dispatch_table->CmdDrawIndexed(cmdBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002451}
2452
Tony Barbour8205d902015-04-16 15:59:00 -06002453VK_LAYER_EXPORT void VKAPI vkCmdDrawIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002454{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002455 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002456 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002457 VkBool32 skipCall = VK_FALSE;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002458 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002459 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002460 pCB->drawCount[DRAW_INDIRECT]++;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002461 skipCall |= validate_draw_state(dev_data, pCB, VK_FALSE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002462 // TODO : Need to pass cmdBuffer as srcObj here
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002463 skipCall |= 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 -06002464 "vkCmdDrawIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002465 skipCall |= synchAndPrintDSConfig(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002466 if (VK_FALSE == skipCall) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002467 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002468 skipCall |= addCmd(pCB, CMD_DRAWINDIRECT);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002469 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002470 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002471 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdDrawIndirect()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002472 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002473 skipCall |= outsideRenderPass(pCB, "vkCmdDrawIndirect");
Jon Ashburne0fa2282015-05-20 09:00:28 -06002474 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002475 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002476 dev_data->device_dispatch_table->CmdDrawIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002477}
2478
Tony Barbour8205d902015-04-16 15:59:00 -06002479VK_LAYER_EXPORT void VKAPI vkCmdDrawIndexedIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002480{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002481 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002482 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002483 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002484 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002485 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002486 pCB->drawCount[DRAW_INDEXED_INDIRECT]++;
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002487 skipCall |= validate_draw_state(dev_data, pCB, VK_TRUE);
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002488 // TODO : Need to pass cmdBuffer as srcObj here
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002489 skipCall |= 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 -06002490 "vkCmdDrawIndexedIndirect() call #%lu, reporting DS state:", g_drawCount[DRAW_INDEXED_INDIRECT]++);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002491 skipCall |= synchAndPrintDSConfig(dev_data, cmdBuffer);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002492 if (VK_FALSE == skipCall) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002493 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002494 skipCall |= addCmd(pCB, CMD_DRAWINDEXEDINDIRECT);
Tobin Ehlise42007c2015-06-19 13:00:59 -06002495 }
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002496 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002497 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdDrawIndexedIndirect()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002498 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002499 skipCall |= outsideRenderPass(pCB, "vkCmdDrawIndexedIndirect");
Jon Ashburne0fa2282015-05-20 09:00:28 -06002500 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002501 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002502 dev_data->device_dispatch_table->CmdDrawIndexedIndirect(cmdBuffer, buffer, offset, count, stride);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002503}
2504
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002505VK_LAYER_EXPORT void VKAPI vkCmdDispatch(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002506{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002507 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002508 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002509 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002510 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002511 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002512 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002513 skipCall |= addCmd(pCB, CMD_DISPATCH);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002514 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002515 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdDispatch()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002516 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002517 skipCall |= insideRenderPass(pCB, "vkCmdDispatch");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002518 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002519 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002520 dev_data->device_dispatch_table->CmdDispatch(cmdBuffer, x, y, z);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002521}
2522
Tony Barbour8205d902015-04-16 15:59:00 -06002523VK_LAYER_EXPORT void VKAPI vkCmdDispatchIndirect(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002524{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002525 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002526 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002527 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002528 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002529 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002530 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002531 skipCall |= addCmd(pCB, CMD_DISPATCHINDIRECT);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002532 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002533 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdDispatchIndirect()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002534 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002535 skipCall |= insideRenderPass(pCB, "vkCmdDispatchIndirect");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002536 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002537 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002538 dev_data->device_dispatch_table->CmdDispatchIndirect(cmdBuffer, buffer, offset);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002539}
2540
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002541VK_LAYER_EXPORT void VKAPI vkCmdCopyBuffer(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002542{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002543 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002544 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002545 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002546 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002547 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002548 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002549 skipCall |= addCmd(pCB, CMD_COPYBUFFER);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002550 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002551 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdCopyBuffer()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002552 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002553 skipCall |= insideRenderPass(pCB, "vkCmdCopyBuffer");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002554 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002555 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002556 dev_data->device_dispatch_table->CmdCopyBuffer(cmdBuffer, srcBuffer, destBuffer, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002557}
2558
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002559VK_LAYER_EXPORT void VKAPI vkCmdCopyImage(VkCmdBuffer cmdBuffer,
2560 VkImage srcImage,
2561 VkImageLayout srcImageLayout,
2562 VkImage destImage,
2563 VkImageLayout destImageLayout,
2564 uint32_t regionCount, const VkImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002565{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002566 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002567 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002568 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002569 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002570 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002571 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002572 skipCall |= addCmd(pCB, CMD_COPYIMAGE);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002573 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002574 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdCopyImage()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002575 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002576 skipCall |= insideRenderPass(pCB, "vkCmdCopyImage");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002577 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002578 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002579 dev_data->device_dispatch_table->CmdCopyImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002580}
2581
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002582VK_LAYER_EXPORT void VKAPI vkCmdBlitImage(VkCmdBuffer cmdBuffer,
2583 VkImage srcImage, VkImageLayout srcImageLayout,
2584 VkImage destImage, VkImageLayout destImageLayout,
Mark Lobodzinski20f68592015-05-22 14:43:25 -05002585 uint32_t regionCount, const VkImageBlit* pRegions,
2586 VkTexFilter filter)
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002587{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002588 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002589 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002590 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002591 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002592 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002593 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002594 skipCall |= addCmd(pCB, CMD_BLITIMAGE);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002595 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002596 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBlitImage()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002597 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002598 skipCall |= insideRenderPass(pCB, "vkCmdBlitImage");
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002599 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002600 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002601 dev_data->device_dispatch_table->CmdBlitImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter);
Courtney Goeltzenleuchter6ff8ebc2015-04-03 14:42:51 -06002602}
2603
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002604VK_LAYER_EXPORT void VKAPI vkCmdCopyBufferToImage(VkCmdBuffer cmdBuffer,
2605 VkBuffer srcBuffer,
2606 VkImage destImage, VkImageLayout destImageLayout,
2607 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002608{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002609 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002610 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002611 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002612 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002613 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002614 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002615 skipCall |= addCmd(pCB, CMD_COPYBUFFERTOIMAGE);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002616 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002617 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdCopyBufferToImage()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002618 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002619 skipCall |= insideRenderPass(pCB, "vkCmdCopyBufferToImage");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002620 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002621 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002622 dev_data->device_dispatch_table->CmdCopyBufferToImage(cmdBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002623}
2624
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002625VK_LAYER_EXPORT void VKAPI vkCmdCopyImageToBuffer(VkCmdBuffer cmdBuffer,
2626 VkImage srcImage, VkImageLayout srcImageLayout,
2627 VkBuffer destBuffer,
2628 uint32_t regionCount, const VkBufferImageCopy* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002629{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002630 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002631 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002632 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002633 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002634 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002635 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002636 skipCall |= addCmd(pCB, CMD_COPYIMAGETOBUFFER);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002637 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002638 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdCopyImageToBuffer()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002639 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002640 skipCall |= insideRenderPass(pCB, "vkCmdCopyImageToBuffer");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002641 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002642 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002643 dev_data->device_dispatch_table->CmdCopyImageToBuffer(cmdBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002644}
2645
Tony Barbour8205d902015-04-16 15:59:00 -06002646VK_LAYER_EXPORT void VKAPI vkCmdUpdateBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002647{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002648 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002649 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002650 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002651 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002652 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002653 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002654 skipCall |= addCmd(pCB, CMD_UPDATEBUFFER);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002655 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002656 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdUpdateBuffer()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002657 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002658 skipCall |= insideRenderPass(pCB, "vkCmdCopyUpdateBuffer");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002659 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002660 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002661 dev_data->device_dispatch_table->CmdUpdateBuffer(cmdBuffer, destBuffer, destOffset, dataSize, pData);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002662}
2663
Tony Barbour8205d902015-04-16 15:59:00 -06002664VK_LAYER_EXPORT void VKAPI vkCmdFillBuffer(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002665{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002666 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002667 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002668 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002669 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002670 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002671 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002672 skipCall |= addCmd(pCB, CMD_FILLBUFFER);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002673 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002674 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdFillBuffer()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002675 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002676 skipCall |= insideRenderPass(pCB, "vkCmdCopyFillBuffer");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002677 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002678 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002679 dev_data->device_dispatch_table->CmdFillBuffer(cmdBuffer, destBuffer, destOffset, fillSize, data);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002680}
2681
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002682VK_LAYER_EXPORT void VKAPI vkCmdClearColorAttachment(
2683 VkCmdBuffer cmdBuffer,
2684 uint32_t colorAttachment,
2685 VkImageLayout imageLayout,
2686 const VkClearColorValue* pColor,
2687 uint32_t rectCount,
2688 const VkRect3D* pRects)
2689{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002690 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002691 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002692 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002693 if (pCB) {
2694 if (pCB->state == CB_UPDATE_ACTIVE) {
2695 // Warn if this is issued prior to Draw Cmd
2696 if (!hasDrawCmd(pCB)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002697 // TODO : cmdBuffer should be srcObj
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002698 skipCall |= 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 -06002699 "vkCmdClearColorAttachment() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -06002700 " It is recommended you use RenderPass LOAD_OP_CLEAR on Color Attachments prior to any Draw.", reinterpret_cast<uint64_t>(cmdBuffer));
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002701 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002702 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002703 skipCall |= addCmd(pCB, CMD_CLEARCOLORATTACHMENT);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002704 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002705 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdClearColorAttachment()");
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002706 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002707 skipCall |= outsideRenderPass(pCB, "vkCmdClearColorAttachment");
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002708 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002709 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002710 dev_data->device_dispatch_table->CmdClearColorAttachment(cmdBuffer, colorAttachment, imageLayout, pColor, rectCount, pRects);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002711}
2712
2713VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilAttachment(
2714 VkCmdBuffer cmdBuffer,
2715 VkImageAspectFlags imageAspectMask,
2716 VkImageLayout imageLayout,
Courtney Goeltzenleuchter315ad992015-09-15 18:03:22 -06002717 const VkClearDepthStencilValue* pDepthStencil,
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002718 uint32_t rectCount,
2719 const VkRect3D* pRects)
2720{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002721 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002722 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002723 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002724 if (pCB) {
2725 if (pCB->state == CB_UPDATE_ACTIVE) {
2726 // Warn if this is issued prior to Draw Cmd
2727 if (!hasDrawCmd(pCB)) {
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06002728 // TODO : cmdBuffer should be srcObj
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002729 skipCall |= 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 -06002730 "vkCmdClearDepthStencilAttachment() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
Courtney Goeltzenleuchter0f2b9e22015-08-26 15:09:25 -06002731 " It is recommended you use RenderPass LOAD_OP_CLEAR on DS Attachment prior to any Draw.", reinterpret_cast<uint64_t>(cmdBuffer));
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002732 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002733 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002734 skipCall |= addCmd(pCB, CMD_CLEARDEPTHSTENCILATTACHMENT);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002735 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002736 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdClearDepthStencilAttachment()");
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002737 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002738 skipCall |= outsideRenderPass(pCB, "vkCmdClearDepthStencilAttachment");
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002739 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002740 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002741 dev_data->device_dispatch_table->CmdClearDepthStencilAttachment(cmdBuffer, imageAspectMask, imageLayout, pDepthStencil, rectCount, pRects);
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06002742}
2743
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002744VK_LAYER_EXPORT void VKAPI vkCmdClearColorImage(
2745 VkCmdBuffer cmdBuffer,
2746 VkImage image, VkImageLayout imageLayout,
Chris Forbese3105972015-06-24 14:34:53 +12002747 const VkClearColorValue *pColor,
Courtney Goeltzenleuchterda4a99e2015-04-23 17:49:22 -06002748 uint32_t rangeCount, const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002749{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002750 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002751 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002752 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002753 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002754 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002755 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002756 skipCall |= addCmd(pCB, CMD_CLEARCOLORIMAGE);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002757 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002758 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdClearColorImage()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002759 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002760 skipCall |= insideRenderPass(pCB, "vkCmdClearColorImage");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002761 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002762 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002763 dev_data->device_dispatch_table->CmdClearColorImage(cmdBuffer, image, imageLayout, pColor, rangeCount, pRanges);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002764}
2765
Courtney Goeltzenleuchter315ad992015-09-15 18:03:22 -06002766VK_LAYER_EXPORT void VKAPI vkCmdClearDepthStencilImage(
2767 VkCmdBuffer cmdBuffer,
2768 VkImage image, VkImageLayout imageLayout,
2769 const VkClearDepthStencilValue *pDepthStencil,
2770 uint32_t rangeCount,
2771 const VkImageSubresourceRange* pRanges)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002772{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002773 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002774 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002775 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002776 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002777 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002778 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002779 skipCall |= addCmd(pCB, CMD_CLEARDEPTHSTENCILIMAGE);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002780 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002781 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdClearDepthStencilImage()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002782 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002783 skipCall |= insideRenderPass(pCB, "vkCmdClearDepthStencilImage");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002784 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002785 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002786 dev_data->device_dispatch_table->CmdClearDepthStencilImage(cmdBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002787}
2788
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002789VK_LAYER_EXPORT void VKAPI vkCmdResolveImage(VkCmdBuffer cmdBuffer,
2790 VkImage srcImage, VkImageLayout srcImageLayout,
2791 VkImage destImage, VkImageLayout destImageLayout,
Tony Barbour11f74372015-04-13 15:02:52 -06002792 uint32_t regionCount, const VkImageResolve* pRegions)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002793{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002794 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002795 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002796 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002797 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002798 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002799 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002800 skipCall |= addCmd(pCB, CMD_RESOLVEIMAGE);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002801 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002802 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdResolveImage()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002803 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002804 skipCall |= insideRenderPass(pCB, "vkCmdResolveImage");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002805 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002806 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002807 dev_data->device_dispatch_table->CmdResolveImage(cmdBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002808}
2809
Tony Barbourc2e987e2015-06-29 16:20:35 -06002810VK_LAYER_EXPORT void VKAPI vkCmdSetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002811{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002812 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002813 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002814 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002815 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002816 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002817 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002818 skipCall |= addCmd(pCB, CMD_SETEVENT);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002819 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002820 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdSetEvent()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002821 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002822 skipCall |= insideRenderPass(pCB, "vkCmdSetEvent");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002823 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002824 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002825 dev_data->device_dispatch_table->CmdSetEvent(cmdBuffer, event, stageMask);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002826}
2827
Tony Barbourc2e987e2015-06-29 16:20:35 -06002828VK_LAYER_EXPORT void VKAPI vkCmdResetEvent(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002829{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002830 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002831 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002832 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002833 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002834 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002835 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002836 skipCall |= addCmd(pCB, CMD_RESETEVENT);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002837 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002838 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdResetEvent()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002839 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002840 skipCall |= insideRenderPass(pCB, "vkCmdResetEvent");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002841 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002842 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002843 dev_data->device_dispatch_table->CmdResetEvent(cmdBuffer, event, stageMask);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002844}
2845
Courtney Goeltzenleuchterd9ba3422015-07-12 12:58:58 -06002846VK_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 -06002847{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002848 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002849 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002850 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002851 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002852 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002853 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002854 skipCall |= addCmd(pCB, CMD_WAITEVENTS);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002855 } else {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002856 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdWaitEvents()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002857 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002858 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002859 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002860 dev_data->device_dispatch_table->CmdWaitEvents(cmdBuffer, eventCount, pEvents, sourceStageMask, destStageMask, memBarrierCount, ppMemBarriers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002861}
2862
Courtney Goeltzenleuchter82b348f2015-07-12 13:07:46 -06002863VK_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 -06002864{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002865 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002866 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002867 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002868 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002869 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002870 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002871 skipCall |= addCmd(pCB, CMD_PIPELINEBARRIER);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002872 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002873 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdPipelineBarrier()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002874 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002875 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002876 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002877 dev_data->device_dispatch_table->CmdPipelineBarrier(cmdBuffer, srcStageMask, destStageMask, byRegion, memBarrierCount, ppMemBarriers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002878}
2879
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002880VK_LAYER_EXPORT void VKAPI vkCmdBeginQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002881{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002882 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002883 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002884 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002885 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002886 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002887 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002888 skipCall |= addCmd(pCB, CMD_BEGINQUERY);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002889 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002890 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdBeginQuery()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002891 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002892 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002893 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002894 dev_data->device_dispatch_table->CmdBeginQuery(cmdBuffer, queryPool, slot, flags);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002895}
2896
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002897VK_LAYER_EXPORT void VKAPI vkCmdEndQuery(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002898{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002899 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002900 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002901 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002902 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002903 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002904 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002905 skipCall |= addCmd(pCB, CMD_ENDQUERY);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002906 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002907 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdEndQuery()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002908 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002909 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002910 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002911 dev_data->device_dispatch_table->CmdEndQuery(cmdBuffer, queryPool, slot);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002912}
2913
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002914VK_LAYER_EXPORT void VKAPI vkCmdResetQueryPool(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002915{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002916 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002917 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002918 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002919 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002920 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002921 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002922 skipCall |= addCmd(pCB, CMD_RESETQUERYPOOL);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002923 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002924 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdResetQueryPool()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002925 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002926 skipCall |= insideRenderPass(pCB, "vkCmdQueryPool");
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002927 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002928 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002929 dev_data->device_dispatch_table->CmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002930}
2931
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002932VK_LAYER_EXPORT void VKAPI vkCmdCopyQueryPoolResults(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery,
2933 uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset,
2934 VkDeviceSize destStride, VkQueryResultFlags flags)
2935{
2936 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002937 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002938 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002939 if (pCB) {
2940 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002941 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002942 skipCall |= addCmd(pCB, CMD_COPYQUERYPOOLRESULTS);
2943 } else {
2944 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdCopyQueryPoolResults()");
2945 }
2946 skipCall |= insideRenderPass(pCB, "vkCmdCopyQueryPoolResults");
2947 }
2948 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002949 dev_data->device_dispatch_table->CmdCopyQueryPoolResults(cmdBuffer, queryPool,
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06002950 startQuery, queryCount, destBuffer, destOffset, destStride, flags);
2951}
2952
Tony Barbour8205d902015-04-16 15:59:00 -06002953VK_LAYER_EXPORT void VKAPI vkCmdWriteTimestamp(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002954{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002955 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002956 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002957 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002958 if (pCB) {
Tobin Ehlise42007c2015-06-19 13:00:59 -06002959 if (pCB->state == CB_UPDATE_ACTIVE) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002960 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002961 skipCall |= addCmd(pCB, CMD_WRITETIMESTAMP);
Tobin Ehlisa366ca22015-06-19 15:07:05 -06002962 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002963 skipCall |= report_error_no_cb_begin(cmdBuffer, "vkCmdWriteTimestamp()");
Tobin Ehlise42007c2015-06-19 13:00:59 -06002964 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002965 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06002966 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002967 dev_data->device_dispatch_table->CmdWriteTimestamp(cmdBuffer, timestampType, destBuffer, destOffset);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06002968}
2969
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002970VK_LAYER_EXPORT VkResult VKAPI vkCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002971{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002972 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2973 VkResult result = dev_data->device_dispatch_table->CreateFramebuffer(device, pCreateInfo, pFramebuffer);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002974 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002975 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002976 VkFramebufferCreateInfo* localFBCI = new VkFramebufferCreateInfo(*pCreateInfo);
Chia-I Wuc278df82015-07-07 11:50:03 +08002977 if (pCreateInfo->pAttachments) {
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -06002978 localFBCI->pAttachments = new VkImageView[localFBCI->attachmentCount];
2979 memcpy((void*)localFBCI->pAttachments, pCreateInfo->pAttachments, localFBCI->attachmentCount*sizeof(VkImageView));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002980 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06002981 dev_data->frameBufferMap[pFramebuffer->handle] = localFBCI;
Tobin Ehlis2464b882015-04-01 08:40:34 -06002982 }
2983 return result;
2984}
2985
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002986VK_LAYER_EXPORT VkResult VKAPI vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass)
Tobin Ehlis2464b882015-04-01 08:40:34 -06002987{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06002988 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
2989 VkResult result = dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pRenderPass);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002990 if (VK_SUCCESS == result) {
Tobin Ehlis2464b882015-04-01 08:40:34 -06002991 // Shadow create info and store in map
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06002992 VkRenderPassCreateInfo* localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
Chia-I Wuc278df82015-07-07 11:50:03 +08002993 if (pCreateInfo->pAttachments) {
2994 localRPCI->pAttachments = new VkAttachmentDescription[localRPCI->attachmentCount];
2995 memcpy((void*)localRPCI->pAttachments, pCreateInfo->pAttachments, localRPCI->attachmentCount*sizeof(VkAttachmentDescription));
Tobin Ehlis2464b882015-04-01 08:40:34 -06002996 }
Chia-I Wuc278df82015-07-07 11:50:03 +08002997 if (pCreateInfo->pSubpasses) {
2998 localRPCI->pSubpasses = new VkSubpassDescription[localRPCI->subpassCount];
2999 memcpy((void*)localRPCI->pSubpasses, pCreateInfo->pSubpasses, localRPCI->subpassCount*sizeof(VkSubpassDescription));
3000
3001 for (uint32_t i = 0; i < localRPCI->subpassCount; i++) {
3002 VkSubpassDescription *subpass = (VkSubpassDescription *) &localRPCI->pSubpasses[i];
3003 const uint32_t attachmentCount = subpass->inputCount +
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003004 subpass->colorCount * (1 + (subpass->pResolveAttachments?1:0)) +
Chia-I Wuc278df82015-07-07 11:50:03 +08003005 subpass->preserveCount;
3006 VkAttachmentReference *attachments = new VkAttachmentReference[attachmentCount];
3007
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003008 memcpy(attachments, subpass->pInputAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08003009 sizeof(attachments[0]) * subpass->inputCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003010 subpass->pInputAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08003011 attachments += subpass->inputCount;
3012
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003013 memcpy(attachments, subpass->pColorAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08003014 sizeof(attachments[0]) * subpass->colorCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003015 subpass->pColorAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08003016 attachments += subpass->colorCount;
3017
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003018 if (subpass->pResolveAttachments) {
3019 memcpy(attachments, subpass->pResolveAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08003020 sizeof(attachments[0]) * subpass->colorCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003021 subpass->pResolveAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08003022 attachments += subpass->colorCount;
3023 }
3024
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003025 memcpy(attachments, subpass->pPreserveAttachments,
Chia-I Wuc278df82015-07-07 11:50:03 +08003026 sizeof(attachments[0]) * subpass->preserveCount);
Cody Northrop6de6b0b2015-08-04 11:16:41 -06003027 subpass->pPreserveAttachments = attachments;
Chia-I Wuc278df82015-07-07 11:50:03 +08003028 }
Tobin Ehlis2464b882015-04-01 08:40:34 -06003029 }
Chia-I Wuc278df82015-07-07 11:50:03 +08003030 if (pCreateInfo->pDependencies) {
3031 localRPCI->pDependencies = new VkSubpassDependency[localRPCI->dependencyCount];
3032 memcpy((void*)localRPCI->pDependencies, pCreateInfo->pDependencies, localRPCI->dependencyCount*sizeof(VkSubpassDependency));
Tobin Ehlis2464b882015-04-01 08:40:34 -06003033 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003034 dev_data->renderPassMap[pRenderPass->handle] = localRPCI;
Tobin Ehlis2464b882015-04-01 08:40:34 -06003035 }
3036 return result;
3037}
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003038// Free the renderpass shadow
3039static void deleteRenderPasses(layer_data* my_data)
3040{
3041 if (my_data->renderPassMap.size() <= 0)
3042 return;
3043 for (auto ii=my_data->renderPassMap.begin(); ii!=my_data->renderPassMap.end(); ++ii) {
3044 if ((*ii).second->pAttachments) {
3045 delete[] (*ii).second->pAttachments;
3046 }
3047 if ((*ii).second->pSubpasses) {
3048 for (uint32_t i=0; i<(*ii).second->subpassCount; ++i) {
3049 // Attachements are all allocated in a block, so just need to
3050 // find the first non-null one to delete
3051 if ((*ii).second->pSubpasses[i].pInputAttachments) {
3052 delete[] (*ii).second->pSubpasses[i].pInputAttachments;
3053 } else if ((*ii).second->pSubpasses[i].pColorAttachments) {
3054 delete[] (*ii).second->pSubpasses[i].pColorAttachments;
3055 } else if ((*ii).second->pSubpasses[i].pResolveAttachments) {
3056 delete[] (*ii).second->pSubpasses[i].pResolveAttachments;
3057 } else if ((*ii).second->pSubpasses[i].pPreserveAttachments) {
3058 delete[] (*ii).second->pSubpasses[i].pPreserveAttachments;
3059 }
3060 }
3061 delete[] (*ii).second->pSubpasses;
3062 }
3063 if ((*ii).second->pDependencies) {
3064 delete[] (*ii).second->pDependencies;
3065 }
3066 }
3067 my_data->renderPassMap.clear();
3068}
Chia-I Wuc278df82015-07-07 11:50:03 +08003069VK_LAYER_EXPORT void VKAPI vkCmdBeginRenderPass(VkCmdBuffer cmdBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkRenderPassContents contents)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003070{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003071 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003072 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003073 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003074 if (pCB) {
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06003075 if (pRenderPassBegin && pRenderPassBegin->renderPass) {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06003076 skipCall |= insideRenderPass(pCB, "vkCmdBeginRenderPass");
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003077 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06003078 skipCall |= addCmd(pCB, CMD_BEGINRENDERPASS);
3079 pCB->activeRenderPass = pRenderPassBegin->renderPass;
3080 pCB->activeSubpass = 0;
3081 pCB->framebuffer = pRenderPassBegin->framebuffer;
3082 if (pCB->lastBoundPipeline) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003083 skipCall |= validatePipelineState(dev_data, pCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06003084 }
Tobin Ehlise4076782015-06-24 15:53:07 -06003085 } else {
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003086 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_RENDERPASS, "DS",
Tobin Ehlis8b6c2352015-06-23 16:13:03 -06003087 "You cannot use a NULL RenderPass object in vkCmdBeginRenderPass()");
Tony Barbourb9f82ba2015-04-06 11:09:26 -06003088 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003089 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003090 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003091 dev_data->device_dispatch_table->CmdBeginRenderPass(cmdBuffer, pRenderPassBegin, contents);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003092}
3093
Chia-I Wuc278df82015-07-07 11:50:03 +08003094VK_LAYER_EXPORT void VKAPI vkCmdNextSubpass(VkCmdBuffer cmdBuffer, VkRenderPassContents contents)
3095{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003096 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003097 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003098 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Chia-I Wuc278df82015-07-07 11:50:03 +08003099 if (pCB) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003100 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06003101 skipCall |= addCmd(pCB, CMD_NEXTSUBPASS);
3102 pCB->activeSubpass++;
3103 if (pCB->lastBoundPipeline) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003104 skipCall |= validatePipelineState(dev_data, pCB, VK_PIPELINE_BIND_POINT_GRAPHICS, pCB->lastBoundPipeline);
Chia-I Wuc278df82015-07-07 11:50:03 +08003105 }
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06003106 skipCall |= outsideRenderPass(pCB, "vkCmdNextSubpass");
Chia-I Wuc278df82015-07-07 11:50:03 +08003107 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003108 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003109 dev_data->device_dispatch_table->CmdNextSubpass(cmdBuffer, contents);
Chia-I Wuc278df82015-07-07 11:50:03 +08003110}
3111
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08003112VK_LAYER_EXPORT void VKAPI vkCmdEndRenderPass(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003113{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003114 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003115 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003116 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003117 if (pCB) {
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06003118 skipCall |= outsideRenderPass(pCB, "vkEndRenderpass");
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003119 updateCBTracking(pCB);
Mark Lobodzinskia0f061c2015-09-30 16:19:16 -06003120 skipCall |= addCmd(pCB, CMD_ENDRENDERPASS);
3121 pCB->activeRenderPass = 0;
3122 pCB->activeSubpass = 0;
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08003123 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003124 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003125 dev_data->device_dispatch_table->CmdEndRenderPass(cmdBuffer);
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08003126}
3127
3128VK_LAYER_EXPORT void VKAPI vkCmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers)
3129{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003130 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003131 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003132 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08003133 if (pCB) {
Tobin Ehlis5f728d32015-09-17 14:18:16 -06003134 GLOBAL_CB_NODE* pSubCB = NULL;
3135 for (uint32_t i=0; i<cmdBuffersCount; i++) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003136 pSubCB = getCBNode(dev_data, pCmdBuffers[i]);
Tobin Ehlis5f728d32015-09-17 14:18:16 -06003137 if (!pSubCB) {
3138 skipCall |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_SECONDARY_CMD_BUFFER, "DS",
3139 "vkCmdExecuteCommands() called w/ invalid Cmd Buffer %p in element %u of pCmdBuffers array.", (void*)pCmdBuffers[i], i);
3140 } else if (VK_CMD_BUFFER_LEVEL_PRIMARY == pSubCB->createInfo.level) {
3141 skipCall |= log_msg(mdd(pCB->cmdBuffer), VK_DBG_REPORT_ERROR_BIT, (VkDbgObjectType) 0, 0, 0, DRAWSTATE_INVALID_SECONDARY_CMD_BUFFER, "DS",
3142 "vkCmdExecuteCommands() called w/ Primary Cmd Buffer %p in element %u of pCmdBuffers array. All cmd buffers in pCmdBuffers array must be secondary.", (void*)pCmdBuffers[i], i);
3143 }
3144 }
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003145 updateCBTracking(pCB);
Tobin Ehlis5f728d32015-09-17 14:18:16 -06003146 skipCall |= addCmd(pCB, CMD_EXECUTECOMMANDS);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003147 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003148 if (VK_FALSE == skipCall)
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003149 dev_data->device_dispatch_table->CmdExecuteCommands(cmdBuffer, cmdBuffersCount, pCmdBuffers);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003150}
3151
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06003152VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
3153 VkInstance instance,
3154 VkFlags msgFlags,
3155 const PFN_vkDbgMsgCallback pfnMsgCallback,
3156 void* pUserData,
3157 VkDbgMsgCallback* pMsgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003158{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003159 layer_data* my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
3160 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Tobin Ehlisc91330b2015-06-16 09:04:30 -06003161 VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
3162 if (VK_SUCCESS == res) {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003163 //layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Tobin Ehlisc91330b2015-06-16 09:04:30 -06003164 res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
3165 }
3166 return res;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003167}
3168
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06003169VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
3170 VkInstance instance,
3171 VkDbgMsgCallback msgCallback)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003172{
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003173 layer_data* my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
3174 VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
Tobin Ehlisc91330b2015-06-16 09:04:30 -06003175 VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
Tobin Ehlisc91330b2015-06-16 09:04:30 -06003176 layer_destroy_msg_callback(my_data->report_data, msgCallback);
3177 return res;
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003178}
3179
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06003180VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerBegin(VkCmdBuffer cmdBuffer, const char* pMarker)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003181{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003182 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003183 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003184 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003185 if (!dev_data->device_extensions.debug_marker_enabled) {
3186 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0, DRAWSTATE_INVALID_EXTENSION, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06003187 "Attempt to use CmdDbgMarkerBegin but extension disabled!");
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003188 return;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06003189 } else if (pCB) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003190 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003191 skipCall |= addCmd(pCB, CMD_DBGMARKERBEGIN);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003192 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003193 if (VK_FALSE == skipCall)
3194 debug_marker_dispatch_table(cmdBuffer)->CmdDbgMarkerBegin(cmdBuffer, pMarker);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003195}
3196
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06003197VK_LAYER_EXPORT void VKAPI vkCmdDbgMarkerEnd(VkCmdBuffer cmdBuffer)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003198{
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003199 VkBool32 skipCall = VK_FALSE;
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003200 layer_data* dev_data = get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003201 GLOBAL_CB_NODE* pCB = getCBNode(dev_data, cmdBuffer);
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003202 if (!dev_data->device_extensions.debug_marker_enabled) {
3203 skipCall |= log_msg(mdd(cmdBuffer), VK_DBG_REPORT_ERROR_BIT, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)cmdBuffer, 0, DRAWSTATE_INVALID_EXTENSION, "DS",
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06003204 "Attempt to use CmdDbgMarkerEnd but extension disabled!");
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003205 return;
Tobin Ehlisa366ca22015-06-19 15:07:05 -06003206 } else if (pCB) {
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003207 updateCBTracking(pCB);
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003208 skipCall |= addCmd(pCB, CMD_DBGMARKEREND);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003209 }
Tobin Ehlis48ddcb82015-09-09 11:31:10 -06003210 if (VK_FALSE == skipCall)
3211 debug_marker_dispatch_table(cmdBuffer)->CmdDbgMarkerEnd(cmdBuffer);
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003212}
3213
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003214VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003215{
Jon Ashburn1245cec2015-05-18 13:20:15 -06003216 if (dev == NULL)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003217 return NULL;
Jon Ashburne0fa2282015-05-20 09:00:28 -06003218
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003219 layer_data *dev_data;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003220 /* loader uses this to force layer initialization; device object is wrapped */
3221 if (!strcmp(funcName, "vkGetDeviceProcAddr")) {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003222 VkBaseLayerObject* wrapped_dev = (VkBaseLayerObject*) dev;
3223 dev_data = get_my_data_ptr(get_dispatch_key(wrapped_dev->baseObject), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003224 dev_data->device_dispatch_table = new VkLayerDispatchTable;
3225 layer_initialize_dispatch_table(dev_data->device_dispatch_table, wrapped_dev);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003226 return (PFN_vkVoidFunction) vkGetDeviceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003227 }
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003228 dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
Courtney Goeltzenleuchterbe637992015-06-25 18:01:43 -06003229 if (!strcmp(funcName, "vkCreateDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003230 return (PFN_vkVoidFunction) vkCreateDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003231 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003232 return (PFN_vkVoidFunction) vkDestroyDevice;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003233 if (!strcmp(funcName, "vkQueueSubmit"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003234 return (PFN_vkVoidFunction) vkQueueSubmit;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003235 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003236 return (PFN_vkVoidFunction) vkDestroyInstance;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003237 if (!strcmp(funcName, "vkDestroyDevice"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003238 return (PFN_vkVoidFunction) vkDestroyDevice;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003239 if (!strcmp(funcName, "vkDestroyFence"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003240 return (PFN_vkVoidFunction) vkDestroyFence;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003241 if (!strcmp(funcName, "vkDestroySemaphore"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003242 return (PFN_vkVoidFunction) vkDestroySemaphore;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003243 if (!strcmp(funcName, "vkDestroyEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003244 return (PFN_vkVoidFunction) vkDestroyEvent;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003245 if (!strcmp(funcName, "vkDestroyQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003246 return (PFN_vkVoidFunction) vkDestroyQueryPool;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003247 if (!strcmp(funcName, "vkDestroyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003248 return (PFN_vkVoidFunction) vkDestroyBuffer;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003249 if (!strcmp(funcName, "vkDestroyBufferView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003250 return (PFN_vkVoidFunction) vkDestroyBufferView;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003251 if (!strcmp(funcName, "vkDestroyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003252 return (PFN_vkVoidFunction) vkDestroyImage;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003253 if (!strcmp(funcName, "vkDestroyImageView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003254 return (PFN_vkVoidFunction) vkDestroyImageView;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003255 if (!strcmp(funcName, "vkDestroyShaderModule"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003256 return (PFN_vkVoidFunction) vkDestroyShaderModule;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003257 if (!strcmp(funcName, "vkDestroyShader"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003258 return (PFN_vkVoidFunction) vkDestroyShader;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003259 if (!strcmp(funcName, "vkDestroyPipeline"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003260 return (PFN_vkVoidFunction) vkDestroyPipeline;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003261 if (!strcmp(funcName, "vkDestroyPipelineLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003262 return (PFN_vkVoidFunction) vkDestroyPipelineLayout;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003263 if (!strcmp(funcName, "vkDestroySampler"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003264 return (PFN_vkVoidFunction) vkDestroySampler;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003265 if (!strcmp(funcName, "vkDestroyDescriptorSetLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003266 return (PFN_vkVoidFunction) vkDestroyDescriptorSetLayout;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003267 if (!strcmp(funcName, "vkDestroyDescriptorPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003268 return (PFN_vkVoidFunction) vkDestroyDescriptorPool;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003269 if (!strcmp(funcName, "vkDestroyCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003270 return (PFN_vkVoidFunction) vkDestroyCommandBuffer;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003271 if (!strcmp(funcName, "vkDestroyFramebuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003272 return (PFN_vkVoidFunction) vkDestroyFramebuffer;
Tobin Ehlis1dce5f12015-07-07 10:42:20 -06003273 if (!strcmp(funcName, "vkDestroyRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003274 return (PFN_vkVoidFunction) vkDestroyRenderPass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003275 if (!strcmp(funcName, "vkCreateBufferView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003276 return (PFN_vkVoidFunction) vkCreateBufferView;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003277 if (!strcmp(funcName, "vkCreateImageView"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003278 return (PFN_vkVoidFunction) vkCreateImageView;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003279 if (!strcmp(funcName, "CreatePipelineCache"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003280 return (PFN_vkVoidFunction) vkCreatePipelineCache;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003281 if (!strcmp(funcName, "DestroyPipelineCache"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003282 return (PFN_vkVoidFunction) vkDestroyPipelineCache;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003283 if (!strcmp(funcName, "GetPipelineCacheSize"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003284 return (PFN_vkVoidFunction) vkGetPipelineCacheSize;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003285 if (!strcmp(funcName, "GetPipelineCacheData"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003286 return (PFN_vkVoidFunction) vkGetPipelineCacheData;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003287 if (!strcmp(funcName, "MergePipelineCaches"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003288 return (PFN_vkVoidFunction) vkMergePipelineCaches;
Jon Ashburn0d60d272015-07-09 15:02:25 -06003289 if (!strcmp(funcName, "vkCreateGraphicsPipelines"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003290 return (PFN_vkVoidFunction) vkCreateGraphicsPipelines;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003291 if (!strcmp(funcName, "vkCreateSampler"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003292 return (PFN_vkVoidFunction) vkCreateSampler;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003293 if (!strcmp(funcName, "vkCreateDescriptorSetLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003294 return (PFN_vkVoidFunction) vkCreateDescriptorSetLayout;
Mark Lobodzinski556f7212015-04-17 14:11:39 -05003295 if (!strcmp(funcName, "vkCreatePipelineLayout"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003296 return (PFN_vkVoidFunction) vkCreatePipelineLayout;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003297 if (!strcmp(funcName, "vkCreateDescriptorPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003298 return (PFN_vkVoidFunction) vkCreateDescriptorPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003299 if (!strcmp(funcName, "vkResetDescriptorPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003300 return (PFN_vkVoidFunction) vkResetDescriptorPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003301 if (!strcmp(funcName, "vkAllocDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003302 return (PFN_vkVoidFunction) vkAllocDescriptorSets;
Tobin Ehlis3c543112015-10-08 13:13:50 -06003303 if (!strcmp(funcName, "vkFreeDescriptorSets"))
3304 return (PFN_vkVoidFunction) vkFreeDescriptorSets;
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08003305 if (!strcmp(funcName, "vkUpdateDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003306 return (PFN_vkVoidFunction) vkUpdateDescriptorSets;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003307 if (!strcmp(funcName, "vkCreateCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003308 return (PFN_vkVoidFunction) vkCreateCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003309 if (!strcmp(funcName, "vkBeginCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003310 return (PFN_vkVoidFunction) vkBeginCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003311 if (!strcmp(funcName, "vkEndCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003312 return (PFN_vkVoidFunction) vkEndCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003313 if (!strcmp(funcName, "vkResetCommandBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003314 return (PFN_vkVoidFunction) vkResetCommandBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003315 if (!strcmp(funcName, "vkCmdBindPipeline"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003316 return (PFN_vkVoidFunction) vkCmdBindPipeline;
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06003317 if (!strcmp(funcName, "vkCmdSetViewport"))
3318 return (PFN_vkVoidFunction) vkCmdSetViewport;
Courtney Goeltzenleuchter932cdb52015-09-21 11:44:06 -06003319 if (!strcmp(funcName, "vkCmdSetScissor"))
3320 return (PFN_vkVoidFunction) vkCmdSetScissor;
Courtney Goeltzenleuchter09772bb2015-09-17 15:06:17 -06003321 if (!strcmp(funcName, "vkCmdSetLineWidth"))
3322 return (PFN_vkVoidFunction) vkCmdSetLineWidth;
3323 if (!strcmp(funcName, "vkCmdSetDepthBias"))
3324 return (PFN_vkVoidFunction) vkCmdSetDepthBias;
3325 if (!strcmp(funcName, "vkCmdSetBlendConstants"))
3326 return (PFN_vkVoidFunction) vkCmdSetBlendConstants;
3327 if (!strcmp(funcName, "vkCmdSetDepthBounds"))
3328 return (PFN_vkVoidFunction) vkCmdSetDepthBounds;
3329 if (!strcmp(funcName, "vkCmdSetStencilCompareMask"))
3330 return (PFN_vkVoidFunction) vkCmdSetStencilCompareMask;
3331 if (!strcmp(funcName, "vkCmdSetStencilWriteMask"))
3332 return (PFN_vkVoidFunction) vkCmdSetStencilWriteMask;
3333 if (!strcmp(funcName, "vkCmdSetStencilReference"))
3334 return (PFN_vkVoidFunction) vkCmdSetStencilReference;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003335 if (!strcmp(funcName, "vkCmdBindDescriptorSets"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003336 return (PFN_vkVoidFunction) vkCmdBindDescriptorSets;
Courtney Goeltzenleuchter46962942015-04-16 13:38:46 -06003337 if (!strcmp(funcName, "vkCmdBindVertexBuffers"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003338 return (PFN_vkVoidFunction) vkCmdBindVertexBuffers;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003339 if (!strcmp(funcName, "vkCmdBindIndexBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003340 return (PFN_vkVoidFunction) vkCmdBindIndexBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003341 if (!strcmp(funcName, "vkCmdDraw"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003342 return (PFN_vkVoidFunction) vkCmdDraw;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003343 if (!strcmp(funcName, "vkCmdDrawIndexed"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003344 return (PFN_vkVoidFunction) vkCmdDrawIndexed;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003345 if (!strcmp(funcName, "vkCmdDrawIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003346 return (PFN_vkVoidFunction) vkCmdDrawIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003347 if (!strcmp(funcName, "vkCmdDrawIndexedIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003348 return (PFN_vkVoidFunction) vkCmdDrawIndexedIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003349 if (!strcmp(funcName, "vkCmdDispatch"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003350 return (PFN_vkVoidFunction) vkCmdDispatch;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003351 if (!strcmp(funcName, "vkCmdDispatchIndirect"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003352 return (PFN_vkVoidFunction) vkCmdDispatchIndirect;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003353 if (!strcmp(funcName, "vkCmdCopyBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003354 return (PFN_vkVoidFunction) vkCmdCopyBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003355 if (!strcmp(funcName, "vkCmdCopyImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003356 return (PFN_vkVoidFunction) vkCmdCopyImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003357 if (!strcmp(funcName, "vkCmdCopyBufferToImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003358 return (PFN_vkVoidFunction) vkCmdCopyBufferToImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003359 if (!strcmp(funcName, "vkCmdCopyImageToBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003360 return (PFN_vkVoidFunction) vkCmdCopyImageToBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003361 if (!strcmp(funcName, "vkCmdUpdateBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003362 return (PFN_vkVoidFunction) vkCmdUpdateBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003363 if (!strcmp(funcName, "vkCmdFillBuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003364 return (PFN_vkVoidFunction) vkCmdFillBuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003365 if (!strcmp(funcName, "vkCmdClearColorImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003366 return (PFN_vkVoidFunction) vkCmdClearColorImage;
Chris Forbes2951d7d2015-06-22 17:21:59 +12003367 if (!strcmp(funcName, "vkCmdClearDepthStencilImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003368 return (PFN_vkVoidFunction) vkCmdClearDepthStencilImage;
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06003369 if (!strcmp(funcName, "vkCmdClearColorAttachment"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003370 return (PFN_vkVoidFunction) vkCmdClearColorAttachment;
Tobin Ehlis8cd650e2015-07-01 16:46:13 -06003371 if (!strcmp(funcName, "vkCmdClearDepthStencilAttachment"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003372 return (PFN_vkVoidFunction) vkCmdClearDepthStencilAttachment;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003373 if (!strcmp(funcName, "vkCmdResolveImage"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003374 return (PFN_vkVoidFunction) vkCmdResolveImage;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003375 if (!strcmp(funcName, "vkCmdSetEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003376 return (PFN_vkVoidFunction) vkCmdSetEvent;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003377 if (!strcmp(funcName, "vkCmdResetEvent"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003378 return (PFN_vkVoidFunction) vkCmdResetEvent;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003379 if (!strcmp(funcName, "vkCmdWaitEvents"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003380 return (PFN_vkVoidFunction) vkCmdWaitEvents;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003381 if (!strcmp(funcName, "vkCmdPipelineBarrier"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003382 return (PFN_vkVoidFunction) vkCmdPipelineBarrier;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003383 if (!strcmp(funcName, "vkCmdBeginQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003384 return (PFN_vkVoidFunction) vkCmdBeginQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003385 if (!strcmp(funcName, "vkCmdEndQuery"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003386 return (PFN_vkVoidFunction) vkCmdEndQuery;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003387 if (!strcmp(funcName, "vkCmdResetQueryPool"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003388 return (PFN_vkVoidFunction) vkCmdResetQueryPool;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003389 if (!strcmp(funcName, "vkCmdWriteTimestamp"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003390 return (PFN_vkVoidFunction) vkCmdWriteTimestamp;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003391 if (!strcmp(funcName, "vkCreateFramebuffer"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003392 return (PFN_vkVoidFunction) vkCreateFramebuffer;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003393 if (!strcmp(funcName, "vkCreateRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003394 return (PFN_vkVoidFunction) vkCreateRenderPass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003395 if (!strcmp(funcName, "vkCmdBeginRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003396 return (PFN_vkVoidFunction) vkCmdBeginRenderPass;
Chia-I Wuc278df82015-07-07 11:50:03 +08003397 if (!strcmp(funcName, "vkCmdNextSubpass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003398 return (PFN_vkVoidFunction) vkCmdNextSubpass;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06003399 if (!strcmp(funcName, "vkCmdEndRenderPass"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003400 return (PFN_vkVoidFunction) vkCmdEndRenderPass;
Tobin Ehlis5f728d32015-09-17 14:18:16 -06003401 if (!strcmp(funcName, "vkCmdExecuteCommands"))
3402 return (PFN_vkVoidFunction) vkCmdExecuteCommands;
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003403
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003404 VkLayerDispatchTable* pTable = dev_data->device_dispatch_table;
3405 if (dev_data->device_extensions.debug_marker_enabled)
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003406 {
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003407 if (!strcmp(funcName, "vkCmdDbgMarkerBegin"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003408 return (PFN_vkVoidFunction) vkCmdDbgMarkerBegin;
Jon Ashburn7e07faf2015-06-18 15:02:58 -06003409 if (!strcmp(funcName, "vkCmdDbgMarkerEnd"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003410 return (PFN_vkVoidFunction) vkCmdDbgMarkerEnd;
Jon Ashburn6f8cd632015-06-01 09:37:38 -06003411 }
3412 {
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003413 if (pTable->GetDeviceProcAddr == NULL)
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003414 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003415 return pTable->GetDeviceProcAddr(dev, funcName);
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003416 }
3417}
3418
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003419VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003420{
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003421 PFN_vkVoidFunction fptr;
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003422 if (instance == NULL)
3423 return NULL;
3424
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003425 layer_data* my_data;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003426 /* loader uses this to force layer initialization; instance object is wrapped */
3427 if (!strcmp(funcName, "vkGetInstanceProcAddr")) {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003428 VkBaseLayerObject* wrapped_inst = (VkBaseLayerObject*) instance;
3429 my_data = get_my_data_ptr(get_dispatch_key(wrapped_inst->baseObject), layer_data_map);
Tobin Ehlisd04ccab2015-10-07 15:40:22 -06003430 my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
3431 layer_init_instance_dispatch_table(my_data->instance_dispatch_table, wrapped_inst);
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003432 return (PFN_vkVoidFunction) vkGetInstanceProcAddr;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003433 }
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003434 my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
Courtney Goeltzenleuchter3c9f6ec2015-06-01 14:29:58 -06003435 if (!strcmp(funcName, "vkCreateInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003436 return (PFN_vkVoidFunction) vkCreateInstance;
Jon Ashburne0fa2282015-05-20 09:00:28 -06003437 if (!strcmp(funcName, "vkDestroyInstance"))
Courtney Goeltzenleuchtera4c8c712015-07-12 14:35:22 -06003438 return (PFN_vkVoidFunction) vkDestroyInstance;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -06003439 if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties"))
3440 return (PFN_vkVoidFunction) vkEnumerateInstanceLayerProperties;
3441 if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties"))
3442 return (PFN_vkVoidFunction) vkEnumerateInstanceExtensionProperties;
3443 if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties"))
3444 return (PFN_vkVoidFunction) vkEnumerateDeviceLayerProperties;
3445 if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties"))
3446 return (PFN_vkVoidFunction) vkEnumerateDeviceExtensionProperties;
Courtney Goeltzenleuchtercc899fe2015-06-01 14:33:14 -06003447
Tobin Ehlisfde4dce2015-06-16 15:50:44 -06003448 fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
Courtney Goeltzenleuchtercc899fe2015-06-01 14:33:14 -06003449 if (fptr)
3450 return fptr;
3451
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003452 {
Tobin Ehlise6ab55a2015-10-07 09:38:40 -06003453 VkLayerInstanceDispatchTable* pTable = my_data->instance_dispatch_table;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003454 if (pTable->GetInstanceProcAddr == NULL)
Jon Ashburn79b78ac2015-05-05 14:22:52 -06003455 return NULL;
Jon Ashburn4f2575f2015-05-28 16:25:02 -06003456 return pTable->GetInstanceProcAddr(instance, funcName);
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003457 }
Tobin Ehlis63bb9482015-03-17 16:24:32 -06003458}