blob: 4415f72e1821e7cbebb010b3b10b25bb5d1ec85f [file] [log] [blame]
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -07001/* Copyright (c) 2015-2016 The Khronos Group Inc.
2 * Copyright (c) 2015-2016 Valve Corporation
3 * Copyright (c) 2015-2016 LunarG, Inc.
4 * Copyright (C) 2015-2016 Google Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials
11 * are furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice(s) and this permission notice shall be included
14 * in all copies or substantial portions of the Materials.
15 *
16 * THE MATERIALS ARE 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.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS
24 *
25 * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
26 * Author: Tobin Ehlis <tobine@google.com>
27 * Author: Chris Forbes <chrisf@ijw.co.nz>
28 * Author: Mark Lobodzinski <mark@lunarg.com>
29 */
30
Dustin Gravesc23e9b12016-04-01 15:00:09 -060031// Check for noexcept support
32#if defined(__clang__)
33#if __has_feature(cxx_noexcept)
34#define HAS_NOEXCEPT
35#endif
36#else
Jamie Madill98b56762016-04-04 14:42:21 -040037#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46
Dustin Gravesc23e9b12016-04-01 15:00:09 -060038#define HAS_NOEXCEPT
Jamie Madill98b56762016-04-04 14:42:21 -040039#else
40#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS
41#define HAS_NOEXCEPT
42#endif
Dustin Gravesc23e9b12016-04-01 15:00:09 -060043#endif
44#endif
45
46#ifdef HAS_NOEXCEPT
47#define NOEXCEPT noexcept
48#else
49#define NOEXCEPT
50#endif
51
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070052// Enable mem_tracker merged code
53#define MTMERGE 1
54
55#pragma once
Tobin Ehlisca546212016-04-01 13:51:33 -060056#include "vk_safe_struct.h"
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070057#include "vulkan/vk_layer.h"
58#include <atomic>
59#include <vector>
60#include <unordered_map>
Chris Forbes896fc322016-03-31 17:37:36 +130061#include <unordered_set>
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070062#include <memory>
Mark Lobodzinski68df55c2016-03-15 09:19:59 -060063#include <functional>
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070064
65using std::vector;
Chris Forbes896fc322016-03-31 17:37:36 +130066using std::unordered_set;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070067
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070068#if MTMERGE
69// Mem Tracker ERROR codes
70typedef enum _MEM_TRACK_ERROR {
71 MEMTRACK_NONE, // Used for INFO & other non-error messages
72 MEMTRACK_INVALID_CB, // Cmd Buffer invalid
73 MEMTRACK_INVALID_MEM_OBJ, // Invalid Memory Object
74 MEMTRACK_INVALID_ALIASING, // Invalid Memory Aliasing
75 MEMTRACK_INVALID_LAYOUT, // Invalid Layout
76 MEMTRACK_INTERNAL_ERROR, // Bug in Mem Track Layer internal data structures
77 MEMTRACK_FREED_MEM_REF, // MEM Obj freed while it still has obj and/or CB refs
78 MEMTRACK_MEM_OBJ_CLEAR_EMPTY_BINDINGS, // Clearing bindings on mem obj that doesn't have any bindings
79 MEMTRACK_MISSING_MEM_BINDINGS, // Trying to retrieve mem bindings, but none found (may be internal error)
80 MEMTRACK_INVALID_OBJECT, // Attempting to reference generic VK Object that is invalid
81 MEMTRACK_MEMORY_BINDING_ERROR, // Error during one of many calls that bind memory to object or CB
82 MEMTRACK_MEMORY_LEAK, // Failure to call vkFreeMemory on Mem Obj prior to DestroyDevice
83 MEMTRACK_INVALID_STATE, // Memory not in the correct state
84 MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, // vkResetCommandBuffer() called on a CB that hasn't completed
85 MEMTRACK_INVALID_FENCE_STATE, // Invalid Fence State signaled or used
86 MEMTRACK_REBIND_OBJECT, // Non-sparse object bindings are immutable
87 MEMTRACK_INVALID_USAGE_FLAG, // Usage flags specified at image/buffer create conflict w/ use of object
88 MEMTRACK_INVALID_MAP, // Size flag specified at alloc is too small for mapping range
89} MEM_TRACK_ERROR;
90
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070091struct MemRange {
92 VkDeviceSize offset;
93 VkDeviceSize size;
94};
95
96/*
Tobin Ehlis58070a62016-03-16 16:00:36 -060097 * MTMTODO : Update this comment
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -070098 * Data Structure overview
99 * There are 4 global STL(' maps
100 * cbMap -- map of command Buffer (CB) objects to MT_CB_INFO structures
101 * Each MT_CB_INFO struct has an stl list container with
102 * memory objects that are referenced by this CB
103 * memObjMap -- map of Memory Objects to MT_MEM_OBJ_INFO structures
104 * Each MT_MEM_OBJ_INFO has two stl list containers with:
105 * -- all CBs referencing this mem obj
106 * -- all VK Objects that are bound to this memory
107 * objectMap -- map of objects to MT_OBJ_INFO structures
108 *
109 * Algorithm overview
110 * These are the primary events that should happen related to different objects
111 * 1. Command buffers
112 * CREATION - Add object,structure to map
113 * CMD BIND - If mem associated, add mem reference to list container
114 * DESTROY - Remove from map, decrement (and report) mem references
115 * 2. Mem Objects
116 * CREATION - Add object,structure to map
117 * OBJ BIND - Add obj structure to list container for that mem node
118 * CMB BIND - If mem-related add CB structure to list container for that mem node
119 * DESTROY - Flag as errors any remaining refs and remove from map
120 * 3. Generic Objects
121 * MEM BIND - DESTROY any previous binding, Add obj node w/ ref to map, add obj ref to list container for that mem node
122 * DESTROY - If mem bound, remove reference list container for that memInfo, remove object ref from map
123 */
124// TODO : Is there a way to track when Cmd Buffer finishes & remove mem references at that point?
125// TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used
126
127// Simple struct to hold handle and type of object so they can be uniquely identified and looked up in appropriate map
128struct MT_OBJ_HANDLE_TYPE {
129 uint64_t handle;
130 VkDebugReportObjectTypeEXT type;
131};
132
Dustin Gravesc23e9b12016-04-01 15:00:09 -0600133bool operator==(MT_OBJ_HANDLE_TYPE a, MT_OBJ_HANDLE_TYPE b) NOEXCEPT{
Chris Forbes896fc322016-03-31 17:37:36 +1300134 return a.handle == b.handle && a.type == b.type;
135}
136
137namespace std {
138 template<>
139 struct hash<MT_OBJ_HANDLE_TYPE> {
Dustin Gravesc23e9b12016-04-01 15:00:09 -0600140 size_t operator()(MT_OBJ_HANDLE_TYPE obj) const NOEXCEPT{
Chris Forbes896fc322016-03-31 17:37:36 +1300141 return hash<uint64_t>()(obj.handle) ^
142 hash<uint32_t>()(obj.type);
143 }
144 };
145}
146
Tobin Ehlis58070a62016-03-16 16:00:36 -0600147struct MEMORY_RANGE {
148 uint64_t handle;
149 VkDeviceMemory memory;
150 VkDeviceSize start;
151 VkDeviceSize end;
152};
153
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700154// Data struct for tracking memory object
Tobin Ehlis58070a62016-03-16 16:00:36 -0600155struct DEVICE_MEM_INFO {
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700156 void *object; // Dispatchable object used to create this memory (device of swapchain)
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700157 bool valid; // Stores if the memory has valid data or not
158 VkDeviceMemory mem;
159 VkMemoryAllocateInfo allocInfo;
Chris Forbes896fc322016-03-31 17:37:36 +1300160 unordered_set<MT_OBJ_HANDLE_TYPE> objBindings; // objects bound to this memory
Chris Forbesde886ba2016-03-31 17:58:13 +1300161 unordered_set<VkCommandBuffer> commandBufferBindings; // cmd buffers referencing this memory
Tobin Ehlis58070a62016-03-16 16:00:36 -0600162 vector<MEMORY_RANGE> bufferRanges;
163 vector<MEMORY_RANGE> imageRanges;
164 VkImage image; // If memory is bound to image, this will have VkImage handle, else VK_NULL_HANDLE
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700165 MemRange memRange;
166 void *pData, *pDriverData;
167};
168
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700169struct MT_FB_ATTACHMENT_INFO {
170 VkImage image;
171 VkDeviceMemory mem;
172};
173
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700174struct MT_PASS_ATTACHMENT_INFO {
175 uint32_t attachment;
176 VkAttachmentLoadOp load_op;
177 VkAttachmentStoreOp store_op;
178};
179
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700180// Associate fenceId with a fence object
181struct MT_FENCE_INFO {
182 uint64_t fenceId; // Sequence number for fence at last submit
183 VkQueue queue; // Queue that this fence is submitted against or NULL
184 VkSwapchainKHR swapchain; // Swapchain that this fence is submitted against or NULL
Dustin Gravese3319182016-04-05 09:41:17 -0600185 bool firstTimeFlag; // Fence was created in signaled state, avoid warnings for first use
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700186 VkFenceCreateInfo createInfo;
187};
188
189// Track Queue information
190struct MT_QUEUE_INFO {
191 uint64_t lastRetiredId;
192 uint64_t lastSubmittedId;
193 list<VkCommandBuffer> pQueueCommandBuffers;
194 list<VkDeviceMemory> pMemRefList;
195};
196
197struct MT_DESCRIPTOR_SET_INFO {
198 std::vector<VkImageView> images;
199 std::vector<VkBuffer> buffers;
200};
201
202// Track Swapchain Information
203struct MT_SWAP_CHAIN_INFO {
204 VkSwapchainCreateInfoKHR createInfo;
205 std::vector<VkImage> images;
206};
207
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700208#endif
209// Draw State ERROR codes
210typedef enum _DRAW_STATE_ERROR {
Michael Lentine885537d2016-03-24 20:48:59 -0500211 // TODO: Remove the comments here or expand them. There isn't any additional information in the
212 // comments than in the name in almost all cases.
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700213 DRAWSTATE_NONE, // Used for INFO & other non-error messages
214 DRAWSTATE_INTERNAL_ERROR, // Error with DrawState internal data structures
215 DRAWSTATE_NO_PIPELINE_BOUND, // Unable to identify a bound pipeline
216 DRAWSTATE_INVALID_POOL, // Invalid DS pool
217 DRAWSTATE_INVALID_SET, // Invalid DS
Michael Lentine885537d2016-03-24 20:48:59 -0500218 DRAWSTATE_INVALID_RENDER_AREA, // Invalid renderArea
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700219 DRAWSTATE_INVALID_LAYOUT, // Invalid DS layout
220 DRAWSTATE_INVALID_IMAGE_LAYOUT, // Invalid Image layout
221 DRAWSTATE_INVALID_PIPELINE, // Invalid Pipeline handle referenced
222 DRAWSTATE_INVALID_PIPELINE_LAYOUT, // Invalid PipelineLayout
223 DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, // Attempt to create a pipeline
224 // with invalid state
225 DRAWSTATE_INVALID_COMMAND_BUFFER, // Invalid CommandBuffer referenced
226 DRAWSTATE_INVALID_BARRIER, // Invalid Barrier
227 DRAWSTATE_INVALID_BUFFER, // Invalid Buffer
228 DRAWSTATE_INVALID_QUERY, // Invalid Query
229 DRAWSTATE_INVALID_FENCE, // Invalid Fence
230 DRAWSTATE_INVALID_SEMAPHORE, // Invalid Semaphore
231 DRAWSTATE_INVALID_EVENT, // Invalid Event
232 DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, // binding in vkCmdBindVertexData() too
233 // large for PSO's
234 // pVertexBindingDescriptions array
235 DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, // binding offset in
236 // vkCmdBindIndexBuffer() out of
237 // alignment based on indexType
238 // DRAWSTATE_MISSING_DOT_PROGRAM, // No "dot" program in order
239 // to generate png image
240 DRAWSTATE_OUT_OF_MEMORY, // malloc failed
241 DRAWSTATE_INVALID_DESCRIPTOR_SET, // Descriptor Set handle is unknown
242 DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, // Type in layout vs. update are not the
243 // same
244 DRAWSTATE_DESCRIPTOR_STAGEFLAGS_MISMATCH, // StageFlags in layout are not
245 // the same throughout a single
246 // VkWriteDescriptorSet update
247 DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, // Descriptors set for update out
248 // of bounds for corresponding
249 // layout section
250 DRAWSTATE_DESCRIPTOR_POOL_EMPTY, // Attempt to allocate descriptor from a
251 // pool with no more descriptors of that
252 // type available
253 DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, // Invalid to call
254 // vkFreeDescriptorSets on Sets
255 // allocated from a NON_FREE Pool
256 DRAWSTATE_INVALID_UPDATE_INDEX, // Index of requested update is invalid for
257 // specified descriptors set
258 DRAWSTATE_INVALID_UPDATE_STRUCT, // Struct in DS Update tree is of invalid
259 // type
260 DRAWSTATE_NUM_SAMPLES_MISMATCH, // Number of samples in bound PSO does not
261 // match number in FB of current RenderPass
262 DRAWSTATE_NO_END_COMMAND_BUFFER, // Must call vkEndCommandBuffer() before
263 // QueueSubmit on that commandBuffer
264 DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, // Binding cmds or calling End on CB that
265 // never had vkBeginCommandBuffer()
266 // called on it
267 DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, // Cmd Buffer created with
268 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
269 // flag is submitted
270 // multiple times
271 DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, // vkCmdExecuteCommands() called
272 // with a primary commandBuffer
273 // in pCommandBuffers array
274 DRAWSTATE_VIEWPORT_NOT_BOUND, // Draw submitted with no viewport state bound
275 DRAWSTATE_SCISSOR_NOT_BOUND, // Draw submitted with no scissor state bound
276 DRAWSTATE_LINE_WIDTH_NOT_BOUND, // Draw submitted with no line width state
277 // bound
278 DRAWSTATE_DEPTH_BIAS_NOT_BOUND, // Draw submitted with no depth bias state
279 // bound
280 DRAWSTATE_BLEND_NOT_BOUND, // Draw submitted with no blend state bound when
281 // color write enabled
282 DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, // Draw submitted with no depth bounds
283 // state bound when depth enabled
284 DRAWSTATE_STENCIL_NOT_BOUND, // Draw submitted with no stencil state bound
285 // when stencil enabled
286 DRAWSTATE_INDEX_BUFFER_NOT_BOUND, // Draw submitted with no depth-stencil
287 // state bound when depth write enabled
288 DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, // Draw submitted PSO Pipeline
289 // layout that's not compatible
290 // with layout from
291 // BindDescriptorSets
292 DRAWSTATE_RENDERPASS_INCOMPATIBLE, // Incompatible renderpasses between
293 // secondary cmdBuffer and primary
294 // cmdBuffer or framebuffer
295 DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, // Incompatible framebuffer between
296 // secondary cmdBuffer and active
297 // renderPass
298 DRAWSTATE_INVALID_RENDERPASS, // Use of a NULL or otherwise invalid
299 // RenderPass object
300 DRAWSTATE_INVALID_RENDERPASS_CMD, // Invalid cmd submitted while a
301 // RenderPass is active
302 DRAWSTATE_NO_ACTIVE_RENDERPASS, // Rendering cmd submitted without an active
303 // RenderPass
304 DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, // DescriptorSet bound but it was
305 // never updated. This is a warning
306 // code.
307 DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, // DescriptorSet used by pipeline at
308 // draw time is not bound, or has been
309 // disturbed (which would have flagged
310 // previous warning)
311 DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, // DescriptorSets bound with
312 // different number of dynamic
313 // descriptors that were included in
314 // dynamicOffsetCount
315 DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, // Clear cmd issued before any Draw in
316 // CommandBuffer, should use RenderPass Ops
317 // instead
318 DRAWSTATE_BEGIN_CB_INVALID_STATE, // CB state at Begin call is bad. Can be
319 // Primary/Secondary CB created with
320 // mismatched FB/RP information or CB in
321 // RECORDING state
322 DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, // CmdBuffer is being used in
323 // violation of
324 // VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT
325 // rules (i.e. simultaneous use w/o
326 // that bit set)
327 DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, // Attempting to call Reset (or
328 // Begin on recorded cmdBuffer) that
329 // was allocated from Pool w/o
330 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
331 // bit set
332 DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, // Count for viewports and scissors
333 // mismatch and/or state doesn't match
334 // count
335 DRAWSTATE_INVALID_IMAGE_ASPECT, // Image aspect is invalid for the current
336 // operation
337 DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, // Attachment reference must be
338 // present in active subpass
339 DRAWSTATE_SAMPLER_DESCRIPTOR_ERROR, // A Descriptor of *_SAMPLER type is
340 // being updated with an invalid or bad
341 // Sampler
342 DRAWSTATE_INCONSISTENT_IMMUTABLE_SAMPLER_UPDATE, // Descriptors of
343 // *COMBINED_IMAGE_SAMPLER
344 // type are being updated
345 // where some, but not all,
346 // of the updates use
347 // immutable samplers
348 DRAWSTATE_IMAGEVIEW_DESCRIPTOR_ERROR, // A Descriptor of *_IMAGE or
349 // *_ATTACHMENT type is being updated
350 // with an invalid or bad ImageView
351 DRAWSTATE_BUFFERVIEW_DESCRIPTOR_ERROR, // A Descriptor of *_TEXEL_BUFFER
352 // type is being updated with an
353 // invalid or bad BufferView
354 DRAWSTATE_BUFFERINFO_DESCRIPTOR_ERROR, // A Descriptor of
355 // *_[UNIFORM|STORAGE]_BUFFER_[DYNAMIC]
356 // type is being updated with an
357 // invalid or bad BufferView
358 DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, // At draw time the dynamic offset
359 // combined with buffer offset and range
360 // oversteps size of buffer
361 DRAWSTATE_DOUBLE_DESTROY, // Destroying an object twice
362 DRAWSTATE_OBJECT_INUSE, // Destroying or modifying an object in use by a
363 // command buffer
364 DRAWSTATE_QUEUE_FORWARD_PROGRESS, // Queue cannot guarantee forward progress
Dustin Graves2c905c82016-03-31 18:01:37 -0600365 DRAWSTATE_INVALID_BUFFER_MEMORY_OFFSET, // Dynamic Buffer Offset
366 // violates memory requirements limit
367 DRAWSTATE_INVALID_TEXEL_BUFFER_OFFSET, // Dynamic Texel Buffer Offsets
368 // violate device limit
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700369 DRAWSTATE_INVALID_UNIFORM_BUFFER_OFFSET, // Dynamic Uniform Buffer Offsets
370 // violate device limit
371 DRAWSTATE_INVALID_STORAGE_BUFFER_OFFSET, // Dynamic Storage Buffer Offsets
372 // violate device limit
373 DRAWSTATE_INDEPENDENT_BLEND, // If independent blending is not enabled, all
374 // elements of pAttachmentsMustBeIdentical
375 DRAWSTATE_DISABLED_LOGIC_OP, // If logic operations is not enabled, logicOpEnable
376 // must be VK_FALSE
377 DRAWSTATE_INVALID_LOGIC_OP, // If logicOpEnable is VK_TRUE, logicOp must
378 // must be a valid VkLogicOp value
379 DRAWSTATE_INVALID_QUEUE_INDEX, // Specified queue index exceeds number
380 // of queried queue families
381 DRAWSTATE_PUSH_CONSTANTS_ERROR, // Push constants exceed maxPushConstantSize
382} DRAW_STATE_ERROR;
383
384typedef enum _SHADER_CHECKER_ERROR {
385 SHADER_CHECKER_NONE,
386 SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, // Type mismatch between shader stages or shader and pipeline
387 SHADER_CHECKER_OUTPUT_NOT_CONSUMED, // Entry appears in output interface, but missing in input
388 SHADER_CHECKER_INPUT_NOT_PRODUCED, // Entry appears in input interface, but missing in output
389 SHADER_CHECKER_NON_SPIRV_SHADER, // Shader image is not SPIR-V
390 SHADER_CHECKER_INCONSISTENT_SPIRV, // General inconsistency within a SPIR-V module
391 SHADER_CHECKER_UNKNOWN_STAGE, // Stage is not supported by analysis
392 SHADER_CHECKER_INCONSISTENT_VI, // VI state contains conflicting binding or attrib descriptions
393 SHADER_CHECKER_MISSING_DESCRIPTOR, // Shader attempts to use a descriptor binding not declared in the layout
394 SHADER_CHECKER_BAD_SPECIALIZATION, // Specialization map entry points outside specialization data block
395 SHADER_CHECKER_MISSING_ENTRYPOINT, // Shader module does not contain the requested entrypoint
396 SHADER_CHECKER_PUSH_CONSTANT_OUT_OF_RANGE, // Push constant variable is not in a push constant range
397 SHADER_CHECKER_PUSH_CONSTANT_NOT_ACCESSIBLE_FROM_STAGE, // Push constant range exists, but not accessible from stage
398 SHADER_CHECKER_DESCRIPTOR_TYPE_MISMATCH, // Descriptor type does not match shader resource type
399 SHADER_CHECKER_DESCRIPTOR_NOT_ACCESSIBLE_FROM_STAGE, // Descriptor used by shader, but not accessible from stage
Chris Forbesa3c20a22016-03-15 10:12:48 +1300400 SHADER_CHECKER_FEATURE_NOT_ENABLED, // Shader uses capability requiring a feature not enabled on device
401 SHADER_CHECKER_BAD_CAPABILITY, // Shader uses capability not supported by Vulkan (OpenCL features)
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700402} SHADER_CHECKER_ERROR;
403
404typedef enum _DRAW_TYPE {
405 DRAW = 0,
406 DRAW_INDEXED = 1,
407 DRAW_INDIRECT = 2,
408 DRAW_INDEXED_INDIRECT = 3,
409 DRAW_BEGIN_RANGE = DRAW,
410 DRAW_END_RANGE = DRAW_INDEXED_INDIRECT,
411 NUM_DRAW_TYPES = (DRAW_END_RANGE - DRAW_BEGIN_RANGE + 1),
412} DRAW_TYPE;
413
414typedef struct _SHADER_DS_MAPPING {
415 uint32_t slotCount;
416 VkDescriptorSetLayoutCreateInfo *pShaderMappingSlot;
417} SHADER_DS_MAPPING;
418
419typedef struct _GENERIC_HEADER {
420 VkStructureType sType;
421 const void *pNext;
422} GENERIC_HEADER;
423
Tobin Ehlisca546212016-04-01 13:51:33 -0600424class PIPELINE_NODE {
425 public:
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700426 VkPipeline pipeline;
Tobin Ehlisca546212016-04-01 13:51:33 -0600427 safe_VkGraphicsPipelineCreateInfo graphicsPipelineCI;
428 safe_VkComputePipelineCreateInfo computePipelineCI;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700429 // Flag of which shader stages are active for this pipeline
430 uint32_t active_shaders;
Chris Forbes52156ec2016-04-06 11:21:28 +1200431 uint32_t duplicate_shaders;
Tobin Ehlisa61b5372016-03-24 09:17:25 -0600432 // Capture which slots (set#->bindings) are actually used by the shaders of this pipeline
433 unordered_map<uint32_t, unordered_set<uint32_t>> active_slots;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700434 // Vtx input info (if any)
Chris Forbes5188e312016-03-18 11:07:59 +1300435 std::vector<VkVertexInputBindingDescription> vertexBindingDescriptions;
436 std::vector<VkVertexInputAttributeDescription> vertexAttributeDescriptions;
437 std::vector<VkPipelineColorBlendAttachmentState> attachments;
Tobin Ehlis3d3e06b2016-03-28 11:18:19 -0600438 bool blendConstantsEnabled; // Blend constants enabled for any attachments
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700439 // Default constructor
Tobin Ehlisca546212016-04-01 13:51:33 -0600440 PIPELINE_NODE()
Chris Forbes52156ec2016-04-06 11:21:28 +1200441 : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), duplicate_shaders(0), active_slots(), vertexBindingDescriptions(),
Tobin Ehlisca546212016-04-01 13:51:33 -0600442 vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false) {}
443
444 void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo) {
445 graphicsPipelineCI.initialize(pCreateInfo);
446 // Make sure compute pipeline is null
447 VkComputePipelineCreateInfo emptyComputeCI = {};
448 computePipelineCI.initialize(&emptyComputeCI);
449 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
450 const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
Chris Forbes52156ec2016-04-06 11:21:28 +1200451 this->duplicate_shaders |= this->active_shaders & pPSSCI->stage;
452 this->active_shaders |= pPSSCI->stage;
Tobin Ehlisca546212016-04-01 13:51:33 -0600453 }
454 if (pCreateInfo->pVertexInputState) {
455 const VkPipelineVertexInputStateCreateInfo *pVICI = pCreateInfo->pVertexInputState;
456 if (pVICI->vertexBindingDescriptionCount) {
457 this->vertexBindingDescriptions = std::vector<VkVertexInputBindingDescription>(
458 pVICI->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions + pVICI->vertexBindingDescriptionCount);
459 }
460 if (pVICI->vertexAttributeDescriptionCount) {
461 this->vertexAttributeDescriptions = std::vector<VkVertexInputAttributeDescription>(
462 pVICI->pVertexAttributeDescriptions,
463 pVICI->pVertexAttributeDescriptions + pVICI->vertexAttributeDescriptionCount);
464 }
465 }
466 if (pCreateInfo->pColorBlendState) {
467 const VkPipelineColorBlendStateCreateInfo *pCBCI = pCreateInfo->pColorBlendState;
468 if (pCBCI->attachmentCount) {
469 this->attachments = std::vector<VkPipelineColorBlendAttachmentState>(pCBCI->pAttachments,
470 pCBCI->pAttachments + pCBCI->attachmentCount);
471 }
472 }
473 }
474 void initComputePipeline(const VkComputePipelineCreateInfo *pCreateInfo) {
475 computePipelineCI.initialize(pCreateInfo);
476 // Make sure gfx pipeline is null
477 VkGraphicsPipelineCreateInfo emptyGraphicsCI = {};
478 graphicsPipelineCI.initialize(&emptyGraphicsCI);
479 switch (computePipelineCI.stage.stage) {
480 case VK_SHADER_STAGE_COMPUTE_BIT:
481 this->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
482 break;
483 default:
484 // TODO : Flag error
485 break;
486 }
487 }
488};
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700489
490class BASE_NODE {
491 public:
492 std::atomic_int in_use;
493};
494
495typedef struct _SAMPLER_NODE {
496 VkSampler sampler;
497 VkSamplerCreateInfo createInfo;
498
499 _SAMPLER_NODE(const VkSampler *ps, const VkSamplerCreateInfo *pci) : sampler(*ps), createInfo(*pci){};
500} SAMPLER_NODE;
501
502class IMAGE_NODE : public BASE_NODE {
503 public:
504 VkImageCreateInfo createInfo;
505 VkDeviceMemory mem;
Tobin Ehlis94c53c02016-04-05 13:33:00 -0600506 bool valid; // If this is a swapchain image backing memory track valid here as it doesn't have DEVICE_MEM_INFO
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700507 VkDeviceSize memOffset;
508 VkDeviceSize memSize;
509};
510
511typedef struct _IMAGE_LAYOUT_NODE {
512 VkImageLayout layout;
513 VkFormat format;
514} IMAGE_LAYOUT_NODE;
515
Michael Lentine08682cd2016-03-24 15:36:27 -0500516class IMAGE_CMD_BUF_LAYOUT_NODE {
517 public:
518 IMAGE_CMD_BUF_LAYOUT_NODE() {}
519 IMAGE_CMD_BUF_LAYOUT_NODE(VkImageLayout initialLayoutInput, VkImageLayout layoutInput)
520 : initialLayout(initialLayoutInput), layout(layoutInput) {}
521
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700522 VkImageLayout initialLayout;
523 VkImageLayout layout;
Michael Lentine08682cd2016-03-24 15:36:27 -0500524};
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700525
526class BUFFER_NODE : public BASE_NODE {
527 public:
528 using BASE_NODE::in_use;
Tobin Ehlis94c53c02016-04-05 13:33:00 -0600529 VkDeviceMemory mem;
530 VkBufferCreateInfo createInfo;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700531};
532
533// Store the DAG.
534struct DAGNode {
535 uint32_t pass;
536 std::vector<uint32_t> prev;
537 std::vector<uint32_t> next;
538};
539
540struct RENDER_PASS_NODE {
541 VkRenderPassCreateInfo const *pCreateInfo;
Tobin Ehlis87e0afc2016-03-22 13:50:21 -0600542 VkFramebuffer fb;
543 vector<bool> hasSelfDependency;
544 vector<DAGNode> subpassToNode;
545 vector<vector<VkFormat>> subpassColorFormats;
546 vector<MT_PASS_ATTACHMENT_INFO> attachments;
547 unordered_map<uint32_t, bool> attachment_first_read;
548 unordered_map<uint32_t, VkImageLayout> attachment_first_layout;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700549
Tobin Ehlis87e0afc2016-03-22 13:50:21 -0600550 RENDER_PASS_NODE(VkRenderPassCreateInfo const *pCreateInfo) : pCreateInfo(pCreateInfo), fb(VK_NULL_HANDLE) {
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700551 uint32_t i;
552
553 subpassColorFormats.reserve(pCreateInfo->subpassCount);
554 for (i = 0; i < pCreateInfo->subpassCount; i++) {
555 const VkSubpassDescription *subpass = &pCreateInfo->pSubpasses[i];
556 vector<VkFormat> color_formats;
557 uint32_t j;
558
559 color_formats.reserve(subpass->colorAttachmentCount);
560 for (j = 0; j < subpass->colorAttachmentCount; j++) {
561 const uint32_t att = subpass->pColorAttachments[j].attachment;
562 const VkFormat format = pCreateInfo->pAttachments[att].format;
563
564 color_formats.push_back(format);
565 }
566
567 subpassColorFormats.push_back(color_formats);
568 }
569 }
570};
571
572class PHYS_DEV_PROPERTIES_NODE {
573 public:
574 VkPhysicalDeviceProperties properties;
575 VkPhysicalDeviceFeatures features;
576 vector<VkQueueFamilyProperties> queue_family_properties;
577};
578
579class FENCE_NODE : public BASE_NODE {
580 public:
581 using BASE_NODE::in_use;
582#if MTMERGE
583 uint64_t fenceId; // Sequence number for fence at last submit
584 VkSwapchainKHR swapchain; // Swapchain that this fence is submitted against or NULL
Dustin Gravese3319182016-04-05 09:41:17 -0600585 bool firstTimeFlag; // Fence was created in signaled state, avoid warnings for first use
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700586 VkFenceCreateInfo createInfo;
587#endif
588 VkQueue queue;
589 vector<VkCommandBuffer> cmdBuffers;
590 bool needsSignaled;
Michael Lentine0a32ed72016-03-17 16:34:32 -0500591 vector<VkFence> priorFences;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700592
593 // Default constructor
Michael Lentine0a32ed72016-03-17 16:34:32 -0500594 FENCE_NODE() : queue(NULL), needsSignaled(VK_FALSE){};
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700595};
596
597class SEMAPHORE_NODE : public BASE_NODE {
598 public:
599 using BASE_NODE::in_use;
Tobin Ehlis13443022016-04-12 10:49:41 -0600600 bool signaled;
Michael Lentine0a32ed72016-03-17 16:34:32 -0500601 VkQueue queue;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700602};
603
604class EVENT_NODE : public BASE_NODE {
605 public:
606 using BASE_NODE::in_use;
607 bool needsSignaled;
608 VkPipelineStageFlags stageMask;
609};
610
611class QUEUE_NODE {
612 public:
613 VkDevice device;
Michael Lentine0a32ed72016-03-17 16:34:32 -0500614 vector<VkFence> lastFences;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700615#if MTMERGE
616 uint64_t lastRetiredId;
617 uint64_t lastSubmittedId;
618 // MTMTODO : merge cmd_buffer data structs here
619 list<VkCommandBuffer> pQueueCommandBuffers;
620 list<VkDeviceMemory> pMemRefList;
621#endif
622 vector<VkCommandBuffer> untrackedCmdBuffers;
623 unordered_set<VkCommandBuffer> inFlightCmdBuffers;
Michael Lentineb4cc5212016-03-18 14:11:44 -0500624 unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700625};
626
627class QUERY_POOL_NODE : public BASE_NODE {
628 public:
629 VkQueryPoolCreateInfo createInfo;
630};
631
632class FRAMEBUFFER_NODE {
633 public:
634 VkFramebufferCreateInfo createInfo;
635 unordered_set<VkCommandBuffer> referencingCmdBuffers;
Tobin Ehlis5b813662016-03-22 13:38:08 -0600636 vector<MT_FB_ATTACHMENT_INFO> attachments;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700637};
638
639// Descriptor Data structures
640// Layout Node has the core layout data
641typedef struct _LAYOUT_NODE {
642 VkDescriptorSetLayout layout;
643 VkDescriptorSetLayoutCreateInfo createInfo;
644 uint32_t startIndex; // 1st index of this layout
645 uint32_t endIndex; // last index of this layout
646 uint32_t dynamicDescriptorCount; // Total count of dynamic descriptors used
647 // by this layout
648 vector<VkDescriptorType> descriptorTypes; // Type per descriptor in this
649 // layout to verify correct
650 // updates
651 vector<VkShaderStageFlags> stageFlags; // stageFlags per descriptor in this
652 // layout to verify correct updates
653 unordered_map<uint32_t, uint32_t> bindingToIndexMap; // map set binding # to
Tobin Ehlisa61b5372016-03-24 09:17:25 -0600654 // createInfo.pBindings index
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700655 // Default constructor
656 _LAYOUT_NODE() : layout{}, createInfo{}, startIndex(0), endIndex(0), dynamicDescriptorCount(0){};
657} LAYOUT_NODE;
658
659// Store layouts and pushconstants for PipelineLayout
660struct PIPELINE_LAYOUT_NODE {
661 vector<VkDescriptorSetLayout> descriptorSetLayouts;
662 vector<VkPushConstantRange> pushConstantRanges;
663};
664
665class SET_NODE : public BASE_NODE {
666 public:
667 using BASE_NODE::in_use;
668 VkDescriptorSet set;
669 VkDescriptorPool pool;
670 // Head of LL of all Update structs for this set
671 GENERIC_HEADER *pUpdateStructs;
672 // Total num of descriptors in this set (count of its layout plus all prior layouts)
673 uint32_t descriptorCount;
Tobin Ehlis3a417a52016-03-24 10:16:09 -0600674 vector<GENERIC_HEADER*> pDescriptorUpdates; // Vector where each index points to update node for its slot
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700675 LAYOUT_NODE *pLayout; // Layout for this set
676 SET_NODE *pNext;
677 unordered_set<VkCommandBuffer> boundCmdBuffers; // Cmd buffers that this set has been bound to
Tobin Ehlis3a417a52016-03-24 10:16:09 -0600678 SET_NODE() : set(VK_NULL_HANDLE), pool(VK_NULL_HANDLE), pUpdateStructs(nullptr), pLayout(nullptr), pNext(nullptr){};
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700679};
680
681typedef struct _DESCRIPTOR_POOL_NODE {
682 VkDescriptorPool pool;
Mark Lobodzinskia2d5d612016-03-21 16:32:53 -0600683 uint32_t maxSets; // Max descriptor sets allowed in this pool
Tobin Ehlise9fc72c2016-03-30 12:20:53 -0600684 uint32_t availableSets; // Available descriptor sets in this pool
Mark Lobodzinskia2d5d612016-03-21 16:32:53 -0600685
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700686 VkDescriptorPoolCreateInfo createInfo;
687 SET_NODE *pSets; // Head of LL of sets for this Pool
Mark Lobodzinskia2d5d612016-03-21 16:32:53 -0600688 vector<uint32_t> maxDescriptorTypeCount; // Max # of descriptors of each type in this pool
689 vector<uint32_t> availableDescriptorTypeCount; // Available # of descriptors of each type in this pool
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700690
691 _DESCRIPTOR_POOL_NODE(const VkDescriptorPool pool, const VkDescriptorPoolCreateInfo *pCreateInfo)
Mark Lobodzinskia2d5d612016-03-21 16:32:53 -0600692 : pool(pool), maxSets(pCreateInfo->maxSets), availableSets(pCreateInfo->maxSets), createInfo(*pCreateInfo), pSets(NULL),
Norbert Nopper962c59b2016-04-13 01:08:36 +0200693 maxDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0), availableDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0) {
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700694 if (createInfo.poolSizeCount) { // Shadow type struct from ptr into local struct
695 size_t poolSizeCountSize = createInfo.poolSizeCount * sizeof(VkDescriptorPoolSize);
696 createInfo.pPoolSizes = new VkDescriptorPoolSize[poolSizeCountSize];
697 memcpy((void *)createInfo.pPoolSizes, pCreateInfo->pPoolSizes, poolSizeCountSize);
698 // Now set max counts for each descriptor type based on count of that type times maxSets
699 uint32_t i = 0;
700 for (i = 0; i < createInfo.poolSizeCount; ++i) {
701 uint32_t typeIndex = static_cast<uint32_t>(createInfo.pPoolSizes[i].type);
Tobin Ehlisbcde12d2016-04-13 15:15:09 -0600702 // Same descriptor types can appear several times
Norbert Nopper962c59b2016-04-13 01:08:36 +0200703 maxDescriptorTypeCount[typeIndex] += createInfo.pPoolSizes[i].descriptorCount;
Mark Lobodzinskia2d5d612016-03-21 16:32:53 -0600704 availableDescriptorTypeCount[typeIndex] = maxDescriptorTypeCount[typeIndex];
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700705 }
706 } else {
707 createInfo.pPoolSizes = NULL; // Make sure this is NULL so we don't try to clean it up
708 }
709 }
710 ~_DESCRIPTOR_POOL_NODE() {
711 delete[] createInfo.pPoolSizes;
712 // TODO : pSets are currently freed in deletePools function which uses freeShadowUpdateTree function
713 // need to migrate that struct to smart ptrs for auto-cleanup
714 }
715} DESCRIPTOR_POOL_NODE;
716
717// Cmd Buffer Tracking
718typedef enum _CMD_TYPE {
719 CMD_BINDPIPELINE,
720 CMD_BINDPIPELINEDELTA,
721 CMD_SETVIEWPORTSTATE,
722 CMD_SETSCISSORSTATE,
723 CMD_SETLINEWIDTHSTATE,
724 CMD_SETDEPTHBIASSTATE,
725 CMD_SETBLENDSTATE,
726 CMD_SETDEPTHBOUNDSSTATE,
727 CMD_SETSTENCILREADMASKSTATE,
728 CMD_SETSTENCILWRITEMASKSTATE,
729 CMD_SETSTENCILREFERENCESTATE,
730 CMD_BINDDESCRIPTORSETS,
731 CMD_BINDINDEXBUFFER,
732 CMD_BINDVERTEXBUFFER,
733 CMD_DRAW,
734 CMD_DRAWINDEXED,
735 CMD_DRAWINDIRECT,
736 CMD_DRAWINDEXEDINDIRECT,
737 CMD_DISPATCH,
738 CMD_DISPATCHINDIRECT,
739 CMD_COPYBUFFER,
740 CMD_COPYIMAGE,
741 CMD_BLITIMAGE,
742 CMD_COPYBUFFERTOIMAGE,
743 CMD_COPYIMAGETOBUFFER,
744 CMD_CLONEIMAGEDATA,
745 CMD_UPDATEBUFFER,
746 CMD_FILLBUFFER,
747 CMD_CLEARCOLORIMAGE,
748 CMD_CLEARATTACHMENTS,
749 CMD_CLEARDEPTHSTENCILIMAGE,
750 CMD_RESOLVEIMAGE,
751 CMD_SETEVENT,
752 CMD_RESETEVENT,
753 CMD_WAITEVENTS,
754 CMD_PIPELINEBARRIER,
755 CMD_BEGINQUERY,
756 CMD_ENDQUERY,
757 CMD_RESETQUERYPOOL,
758 CMD_COPYQUERYPOOLRESULTS,
759 CMD_WRITETIMESTAMP,
760 CMD_PUSHCONSTANTS,
761 CMD_INITATOMICCOUNTERS,
762 CMD_LOADATOMICCOUNTERS,
763 CMD_SAVEATOMICCOUNTERS,
764 CMD_BEGINRENDERPASS,
765 CMD_NEXTSUBPASS,
766 CMD_ENDRENDERPASS,
767 CMD_EXECUTECOMMANDS,
768} CMD_TYPE;
769// Data structure for holding sequence of cmds in cmd buffer
770typedef struct _CMD_NODE {
771 CMD_TYPE type;
772 uint64_t cmdNumber;
773} CMD_NODE;
774
775typedef enum _CB_STATE {
776 CB_NEW, // Newly created CB w/o any cmds
777 CB_RECORDING, // BeginCB has been called on this CB
778 CB_RECORDED, // EndCB has been called on this CB
779 CB_INVALID // CB had a bound descriptor set destroyed or updated
780} CB_STATE;
781// CB Status -- used to track status of various bindings on cmd buffer objects
782typedef VkFlags CBStatusFlags;
783typedef enum _CBStatusFlagBits {
Tobin Ehlis3d3e06b2016-03-28 11:18:19 -0600784 // clang-format off
785 CBSTATUS_NONE = 0x00000000, // No status is set
786 CBSTATUS_VIEWPORT_SET = 0x00000001, // Viewport has been set
787 CBSTATUS_LINE_WIDTH_SET = 0x00000002, // Line width has been set
788 CBSTATUS_DEPTH_BIAS_SET = 0x00000004, // Depth bias has been set
789 CBSTATUS_BLEND_CONSTANTS_SET = 0x00000008, // Blend constants state has been set
790 CBSTATUS_DEPTH_BOUNDS_SET = 0x00000010, // Depth bounds state object has been set
791 CBSTATUS_STENCIL_READ_MASK_SET = 0x00000020, // Stencil read mask has been set
792 CBSTATUS_STENCIL_WRITE_MASK_SET = 0x00000040, // Stencil write mask has been set
793 CBSTATUS_STENCIL_REFERENCE_SET = 0x00000080, // Stencil reference has been set
794 CBSTATUS_INDEX_BUFFER_BOUND = 0x00000100, // Index buffer has been set
795 CBSTATUS_SCISSOR_SET = 0x00000200, // Scissor has been set
796 CBSTATUS_ALL = 0x000003FF, // All dynamic state set
797 // clang-format on
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700798} CBStatusFlagBits;
799
800typedef struct stencil_data {
801 uint32_t compareMask;
802 uint32_t writeMask;
803 uint32_t reference;
804} CBStencilData;
805
806typedef struct _DRAW_DATA { vector<VkBuffer> buffers; } DRAW_DATA;
807
808struct ImageSubresourcePair {
809 VkImage image;
810 bool hasSubresource;
811 VkImageSubresource subresource;
812};
813
814bool operator==(const ImageSubresourcePair &img1, const ImageSubresourcePair &img2) {
815 if (img1.image != img2.image || img1.hasSubresource != img2.hasSubresource)
816 return false;
817 return !img1.hasSubresource ||
818 (img1.subresource.aspectMask == img2.subresource.aspectMask && img1.subresource.mipLevel == img2.subresource.mipLevel &&
819 img1.subresource.arrayLayer == img2.subresource.arrayLayer);
820}
821
822namespace std {
823template <> struct hash<ImageSubresourcePair> {
824 size_t operator()(ImageSubresourcePair img) const throw() {
825 size_t hashVal = hash<uint64_t>()(reinterpret_cast<uint64_t &>(img.image));
826 hashVal ^= hash<bool>()(img.hasSubresource);
827 if (img.hasSubresource) {
828 hashVal ^= hash<uint32_t>()(reinterpret_cast<uint32_t &>(img.subresource.aspectMask));
829 hashVal ^= hash<uint32_t>()(img.subresource.mipLevel);
830 hashVal ^= hash<uint32_t>()(img.subresource.arrayLayer);
831 }
832 return hashVal;
833 }
834};
835}
836
837struct QueryObject {
838 VkQueryPool pool;
839 uint32_t index;
840};
841
842bool operator==(const QueryObject &query1, const QueryObject &query2) {
843 return (query1.pool == query2.pool && query1.index == query2.index);
844}
845
846namespace std {
847template <> struct hash<QueryObject> {
848 size_t operator()(QueryObject query) const throw() {
849 return hash<uint64_t>()((uint64_t)(query.pool)) ^ hash<uint32_t>()(query.index);
850 }
851};
852}
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600853// Track last states that are bound per pipeline bind point (Gfx & Compute)
854struct LAST_BOUND_STATE {
855 VkPipeline pipeline;
856 VkPipelineLayout pipelineLayout;
857 // Track each set that has been bound
858 // TODO : can unique be global per CB? (do we care about Gfx vs. Compute?)
859 unordered_set<VkDescriptorSet> uniqueBoundSets;
860 // Ordered bound set tracking where index is set# that given set is bound to
861 vector<VkDescriptorSet> boundDescriptorSets;
862 // one dynamic offset per dynamic descriptor bound to this CB
863 vector<uint32_t> dynamicOffsets;
864 void reset() {
865 pipeline = VK_NULL_HANDLE;
866 pipelineLayout = VK_NULL_HANDLE;
867 uniqueBoundSets.clear();
868 boundDescriptorSets.clear();
869 dynamicOffsets.clear();
870 }
871};
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700872// Cmd Buffer Wrapper Struct
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600873struct GLOBAL_CB_NODE {
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700874 VkCommandBuffer commandBuffer;
875 VkCommandBufferAllocateInfo createInfo;
876 VkCommandBufferBeginInfo beginInfo;
877 VkCommandBufferInheritanceInfo inheritanceInfo;
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600878 // VkFence fence; // fence tracking this cmd buffer
879 VkDevice device; // device this CB belongs to
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700880 uint64_t numCmds; // number of cmds in this CB
881 uint64_t drawCount[NUM_DRAW_TYPES]; // Count of each type of draw in this CB
882 CB_STATE state; // Track cmd buffer update state
883 uint64_t submitCount; // Number of times CB has been submitted
884 CBStatusFlags status; // Track status of various bindings on cmd buffer
885 vector<CMD_NODE> cmds; // vector of commands bound to this command buffer
886 // Currently storing "lastBound" objects on per-CB basis
887 // long-term may want to create caches of "lastBound" states and could have
888 // each individual CMD_NODE referencing its own "lastBound" state
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600889 // VkPipeline lastBoundPipeline;
890 // VkPipelineLayout lastBoundPipelineLayout;
891 // // Capture unique std::set of descriptorSets that are bound to this CB.
892 // std::set<VkDescriptorSet> uniqueBoundSets;
893 // vector<VkDescriptorSet> boundDescriptorSets; // Index is set# that given set is bound to
894 // Store last bound state for Gfx & Compute pipeline bind points
895 LAST_BOUND_STATE lastBound[VK_PIPELINE_BIND_POINT_RANGE_SIZE];
896
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700897 vector<VkViewport> viewports;
898 vector<VkRect2D> scissors;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700899 VkRenderPassBeginInfo activeRenderPassBeginInfo;
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600900 uint64_t fenceId;
901 VkFence lastSubmittedFence;
902 VkQueue lastSubmittedQueue;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700903 VkRenderPass activeRenderPass;
904 VkSubpassContents activeSubpassContents;
905 uint32_t activeSubpass;
Mark Lobodzinski93c396d2016-04-12 10:41:59 -0600906 std::unordered_set<VkFramebuffer> framebuffers;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700907 // Track descriptor sets that are destroyed or updated while bound to CB
908 // TODO : These data structures relate to tracking resources that invalidate
909 // a cmd buffer that references them. Need to unify how we handle these
910 // cases so we don't have different tracking data for each type.
Chris Forbes31cb3e82016-04-14 10:34:17 +1200911 unordered_set<VkDescriptorSet> destroyedSets;
912 unordered_set<VkDescriptorSet> updatedSets;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700913 unordered_set<VkFramebuffer> destroyedFramebuffers;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700914 vector<VkEvent> waitedEvents;
915 vector<VkSemaphore> semaphores;
916 vector<VkEvent> events;
917 unordered_map<QueryObject, vector<VkEvent>> waitedEventsBeforeQueryReset;
918 unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available
919 unordered_set<QueryObject> activeQueries;
920 unordered_set<QueryObject> startedQueries;
921 unordered_map<ImageSubresourcePair, IMAGE_CMD_BUF_LAYOUT_NODE> imageLayoutMap;
922 unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
923 unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
924 vector<DRAW_DATA> drawData;
925 DRAW_DATA currentDrawData;
926 VkCommandBuffer primaryCommandBuffer;
Tobin Ehlis7a3985a2016-03-25 11:49:51 -0600927 // Track images and buffers that are updated by this CB at the point of a draw
928 unordered_set<VkImageView> updateImages;
929 unordered_set<VkBuffer> updateBuffers;
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700930 // If cmd buffer is primary, track secondary command buffers pending
931 // execution
932 std::unordered_set<VkCommandBuffer> secondaryCommandBuffers;
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600933 // MTMTODO : Scrub these data fields and merge active sets w/ lastBound as appropriate
Dustin Gravese3319182016-04-05 09:41:17 -0600934 vector<std::function<bool()>> validate_functions;
Chris Forbesc7196ad2016-03-31 18:11:28 +1300935 std::unordered_set<VkDeviceMemory> memObjs;
Michael Lentineb4cc5212016-03-18 14:11:44 -0500936 vector<std::function<bool(VkQueue)>> eventUpdates;
Tobin Ehlis72d66f02016-03-21 14:14:44 -0600937};
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700938
Tobin Ehlis08017632016-03-16 13:52:20 -0600939class SWAPCHAIN_NODE {
940 public:
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700941 VkSwapchainCreateInfoKHR createInfo;
942 uint32_t *pQueueFamilyIndices;
943 std::vector<VkImage> images;
Tobin Ehlis08017632016-03-16 13:52:20 -0600944 SWAPCHAIN_NODE(const VkSwapchainCreateInfoKHR *pCreateInfo) : createInfo(*pCreateInfo), pQueueFamilyIndices(NULL) {
Tobin Ehlis5b5e7bc2016-03-09 16:12:48 -0700945 if (pCreateInfo->queueFamilyIndexCount && pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
946 pQueueFamilyIndices = new uint32_t[pCreateInfo->queueFamilyIndexCount];
947 memcpy(pQueueFamilyIndices, pCreateInfo->pQueueFamilyIndices, pCreateInfo->queueFamilyIndexCount * sizeof(uint32_t));
948 createInfo.pQueueFamilyIndices = pQueueFamilyIndices;
949 }
950 }
Tobin Ehlis08017632016-03-16 13:52:20 -0600951 ~SWAPCHAIN_NODE() { delete[] pQueueFamilyIndices; }
952};