111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Copyright (c) 2015-2016 The Khronos Group Inc.
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 Valve Corporation
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (c) 2015-2016 LunarG, Inc.
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (C) 2015-2016 Google Inc.
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Licensed under the Apache License, Version 2.0 (the "License");
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * you may not use this file except in compliance with the License.
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * You may obtain a copy of the License at
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *     http://www.apache.org/licenses/LICENSE-2.0
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Unless required by applicable law or agreed to in writing, software
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * distributed under the License is distributed on an "AS IS" BASIS,
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * See the License for the specific language governing permissions and
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * limitations under the License.
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Courtney Goeltzenleuchter <courtneygo@google.com>
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Tobin Ehlis <tobine@google.com>
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Chris Forbes <chrisf@ijw.co.nz>
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Author: Mark Lobodzinski <mark@lunarg.com>
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Check for noexcept support
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__clang__)
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __has_feature(cxx_noexcept)
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define HAS_NOEXCEPT
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define HAS_NOEXCEPT
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define HAS_NOEXCEPT
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef HAS_NOEXCEPT
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define NOEXCEPT noexcept
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define NOEXCEPT
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Enable mem_tracker merged code
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define MTMERGE 1
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#pragma once
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "core_validation_error_enums.h"
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "core_validation_types.h"
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "descriptor_sets.h"
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_layer_logging.h"
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vk_safe_struct.h"
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "vulkan/vk_layer.h"
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <atomic>
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <functional>
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <memory>
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <unordered_map>
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <unordered_set>
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <vector>
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <list>
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if MTMERGE
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * MTMTODO : Update this comment
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Data Structure overview
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  There are 4 global STL(' maps
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  cbMap -- map of command Buffer (CB) objects to MT_CB_INFO structures
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    Each MT_CB_INFO struct has an stl list container with
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    memory objects that are referenced by this CB
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  memObjMap -- map of Memory Objects to MT_MEM_OBJ_INFO structures
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    Each MT_MEM_OBJ_INFO has two stl list containers with:
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *      -- all CBs referencing this mem obj
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *      -- all VK Objects that are bound to this memory
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  objectMap -- map of objects to MT_OBJ_INFO structures
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Algorithm overview
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * These are the primary events that should happen related to different objects
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 1. Command buffers
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   CREATION - Add object,structure to map
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   CMD BIND - If mem associated, add mem reference to list container
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   DESTROY  - Remove from map, decrement (and report) mem references
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 2. Mem Objects
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   CREATION - Add object,structure to map
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   OBJ BIND - Add obj structure to list container for that mem node
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   CMB BIND - If mem-related add CB structure to list container for that mem node
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   DESTROY  - Flag as errors any remaining refs and remove from map
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 3. Generic Objects
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   MEM BIND - DESTROY any previous binding, Add obj node w/ ref to map, add obj ref to list container for that mem node
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *   DESTROY - If mem bound, remove reference list container for that memInfo, remove object ref from map
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// TODO : Is there a way to track when Cmd Buffer finishes & remove mem references at that point?
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct MT_FB_ATTACHMENT_INFO {
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkImage image;
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkDeviceMemory mem;
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct MT_DESCRIPTOR_SET_INFO {
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkImageView> images;
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkBuffer> buffers;
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Track Swapchain Information
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct MT_SWAP_CHAIN_INFO {
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkSwapchainCreateInfoKHR createInfo;
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkImage> images;
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct SHADER_DS_MAPPING {
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t slotCount;
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkDescriptorSetLayoutCreateInfo *pShaderMappingSlot;
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct GENERIC_HEADER {
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkStructureType sType;
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const void *pNext;
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct IMAGE_LAYOUT_NODE {
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkImageLayout layout;
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkFormat format;
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Store layouts and pushconstants for PipelineLayout
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct PIPELINE_LAYOUT_NODE {
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<cvdescriptorset::DescriptorSetLayout const *> setLayouts;
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkPushConstantRange> pushConstantRanges;
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass PIPELINE_NODE {
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkPipeline pipeline;
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    safe_VkGraphicsPipelineCreateInfo graphicsPipelineCI;
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    safe_VkComputePipelineCreateInfo computePipelineCI;
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Flag of which shader stages are active for this pipeline
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t active_shaders;
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t duplicate_shaders;
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Capture which slots (set#->bindings) are actually used by the shaders of this pipeline
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::unordered_map<uint32_t, std::unordered_set<uint32_t>> active_slots;
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Vtx input info (if any)
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkVertexInputBindingDescription> vertexBindingDescriptions;
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkVertexInputAttributeDescription> vertexAttributeDescriptions;
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkPipelineColorBlendAttachmentState> attachments;
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool blendConstantsEnabled; // Blend constants enabled for any attachments
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    RENDER_PASS_NODE *renderPass;
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    PIPELINE_LAYOUT_NODE const *pipelineLayout;
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Default constructor
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    PIPELINE_NODE()
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), duplicate_shaders(0), active_slots(), vertexBindingDescriptions(),
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false), renderPass(nullptr), pipelineLayout(nullptr) {}
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void initGraphicsPipeline(const VkGraphicsPipelineCreateInfo *pCreateInfo) {
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        graphicsPipelineCI.initialize(pCreateInfo);
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // Make sure compute pipeline is null
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        VkComputePipelineCreateInfo emptyComputeCI = {};
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        computePipelineCI.initialize(&emptyComputeCI);
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            const VkPipelineShaderStageCreateInfo *pPSSCI = &pCreateInfo->pStages[i];
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            this->duplicate_shaders |= this->active_shaders & pPSSCI->stage;
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            this->active_shaders |= pPSSCI->stage;
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        if (pCreateInfo->pVertexInputState) {
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            const VkPipelineVertexInputStateCreateInfo *pVICI = pCreateInfo->pVertexInputState;
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            if (pVICI->vertexBindingDescriptionCount) {
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                this->vertexBindingDescriptions = std::vector<VkVertexInputBindingDescription>(
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                    pVICI->pVertexBindingDescriptions, pVICI->pVertexBindingDescriptions + pVICI->vertexBindingDescriptionCount);
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            }
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            if (pVICI->vertexAttributeDescriptionCount) {
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                this->vertexAttributeDescriptions = std::vector<VkVertexInputAttributeDescription>(
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                    pVICI->pVertexAttributeDescriptions,
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                    pVICI->pVertexAttributeDescriptions + pVICI->vertexAttributeDescriptionCount);
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            }
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        if (pCreateInfo->pColorBlendState) {
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            const VkPipelineColorBlendStateCreateInfo *pCBCI = pCreateInfo->pColorBlendState;
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            if (pCBCI->attachmentCount) {
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                this->attachments = std::vector<VkPipelineColorBlendAttachmentState>(pCBCI->pAttachments,
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                                                                     pCBCI->pAttachments + pCBCI->attachmentCount);
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            }
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void initComputePipeline(const VkComputePipelineCreateInfo *pCreateInfo) {
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        computePipelineCI.initialize(pCreateInfo);
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // Make sure gfx pipeline is null
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        VkGraphicsPipelineCreateInfo emptyGraphicsCI = {};
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        graphicsPipelineCI.initialize(&emptyGraphicsCI);
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        switch (computePipelineCI.stage.stage) {
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        case VK_SHADER_STAGE_COMPUTE_BIT:
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            this->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT;
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            break;
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        default:
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            // TODO : Flag error
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            break;
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass PHYS_DEV_PROPERTIES_NODE {
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkPhysicalDeviceProperties properties;
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkPhysicalDeviceFeatures features;
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkQueueFamilyProperties> queue_family_properties;
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass FENCE_NODE : public BASE_NODE {
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    using BASE_NODE::in_use;
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkSwapchainKHR swapchain; // Swapchain that this fence is submitted against or NULL
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool firstTimeFlag;       // Fence was created in signaled state, avoid warnings for first use
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkFenceCreateInfo createInfo;
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::unordered_set<VkQueue> queues;
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkCommandBuffer> cmdBuffers;
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool needsSignaled;
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkFence> priorFences;
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Default constructor
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    FENCE_NODE() : swapchain(VK_NULL_HANDLE), firstTimeFlag(false), needsSignaled(false){};
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass SEMAPHORE_NODE : public BASE_NODE {
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    using BASE_NODE::in_use;
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool signaled;
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkQueue queue;
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass EVENT_NODE : public BASE_NODE {
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    using BASE_NODE::in_use;
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int write_in_use;
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool needsSignaled;
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkPipelineStageFlags stageMask;
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass QUEUE_NODE {
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkDevice device;
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkFence> lastFences;
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if MTMERGE
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // MTMTODO : merge cmd_buffer data structs here
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::list<VkCommandBuffer> pQueueCommandBuffers;
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::list<VkDeviceMemory> pMemRefList;
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<VkCommandBuffer> untrackedCmdBuffers;
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::unordered_map<VkEvent, VkPipelineStageFlags> eventToStageMap;
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::unordered_map<QueryObject, bool> queryToStateMap; // 0 is unavailable, 1 is available
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass QUERY_POOL_NODE : public BASE_NODE {
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkQueryPoolCreateInfo createInfo;
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass FRAMEBUFFER_NODE {
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkFramebufferCreateInfo createInfo;
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::unordered_set<VkCommandBuffer> referencingCmdBuffers;
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<MT_FB_ATTACHMENT_INFO> attachments;
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct DESCRIPTOR_POOL_NODE {
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkDescriptorPool pool;
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t maxSets;                              // Max descriptor sets allowed in this pool
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t availableSets;                        // Available descriptor sets in this pool
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    VkDescriptorPoolCreateInfo createInfo;
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::unordered_set<cvdescriptorset::DescriptorSet *> sets; // Collection of all sets in this pool
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<uint32_t> maxDescriptorTypeCount;       // Max # of descriptors of each type in this pool
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::vector<uint32_t> availableDescriptorTypeCount; // Available # of descriptors of each type in this pool
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    DESCRIPTOR_POOL_NODE(const VkDescriptorPool pool, const VkDescriptorPoolCreateInfo *pCreateInfo)
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        : pool(pool), maxSets(pCreateInfo->maxSets), availableSets(pCreateInfo->maxSets), createInfo(*pCreateInfo),
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          maxDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0), availableDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0) {
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        if (createInfo.poolSizeCount) { // Shadow type struct from ptr into local struct
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            size_t poolSizeCountSize = createInfo.poolSizeCount * sizeof(VkDescriptorPoolSize);
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            createInfo.pPoolSizes = new VkDescriptorPoolSize[poolSizeCountSize];
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            memcpy((void *)createInfo.pPoolSizes, pCreateInfo->pPoolSizes, poolSizeCountSize);
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            // Now set max counts for each descriptor type based on count of that type times maxSets
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            uint32_t i = 0;
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            for (i = 0; i < createInfo.poolSizeCount; ++i) {
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                uint32_t typeIndex = static_cast<uint32_t>(createInfo.pPoolSizes[i].type);
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                // Same descriptor types can appear several times
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                maxDescriptorTypeCount[typeIndex] += createInfo.pPoolSizes[i].descriptorCount;
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                availableDescriptorTypeCount[typeIndex] = maxDescriptorTypeCount[typeIndex];
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            }
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        } else {
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            createInfo.pPoolSizes = NULL; // Make sure this is NULL so we don't try to clean it up
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ~DESCRIPTOR_POOL_NODE() {
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        delete[] createInfo.pPoolSizes;
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        // TODO : pSets are currently freed in deletePools function which uses freeShadowUpdateTree function
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        //  need to migrate that struct to smart ptrs for auto-cleanup
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Alberttypedef struct stencil_data {
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t compareMask;
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t writeMask;
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    uint32_t reference;
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} CBStencilData;
309