Mark Lobodzinski | 6eda00a | 2016-02-02 15:55:36 -0700 | [diff] [blame] | 1 | /* 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. |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5 | * |
Mark Lobodzinski | 6eda00a | 2016-02-02 15:55:36 -0700 | [diff] [blame] | 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: |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 12 | * |
Mark Lobodzinski | 6eda00a | 2016-02-02 15:55:36 -0700 | [diff] [blame] | 13 | * The above copyright notice(s) and this permission notice shall be included |
| 14 | * in all copies or substantial portions of the Materials. |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 15 | * |
Mark Lobodzinski | 6eda00a | 2016-02-02 15:55:36 -0700 | [diff] [blame] | 16 | * The Materials are Confidential Information as defined by the Khronos |
| 17 | * Membership Agreement until designated non-confidential by Khronos, at which |
| 18 | * point this condition clause shall be removed. |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 19 | * |
Mark Lobodzinski | 6eda00a | 2016-02-02 15:55:36 -0700 | [diff] [blame] | 20 | * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
Mark Lobodzinski | 6eda00a | 2016-02-02 15:55:36 -0700 | [diff] [blame] | 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 23 | * |
| 24 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| 25 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| 26 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE |
| 27 | * USE OR OTHER DEALINGS IN THE MATERIALS |
Courtney Goeltzenleuchter | 0555952 | 2015-10-30 11:14:30 -0600 | [diff] [blame] | 28 | * |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 29 | * Author: Cody Northrop <cnorthrop@google.com> |
Courtney Goeltzenleuchter | 0555952 | 2015-10-30 11:14:30 -0600 | [diff] [blame] | 30 | * Author: Michael Lentine <mlentine@google.com> |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 31 | * Author: Tobin Ehlis <tobine@google.com> |
| 32 | * Author: Chia-I Wu <olv@google.com> |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 33 | * Author: Chris Forbes <chrisf@ijw.co.nz> |
Mark Lobodzinski | 78da8cb | 2015-12-28 15:51:07 -0700 | [diff] [blame] | 34 | * Author: Mark Lobodzinski <mark@lunarg.com> |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 35 | */ |
| 36 | |
Mark Lobodzinski | 78da8cb | 2015-12-28 15:51:07 -0700 | [diff] [blame] | 37 | // Allow use of STL min and max functions in Windows |
| 38 | #define NOMINMAX |
| 39 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 40 | #include <stdio.h> |
| 41 | #include <stdlib.h> |
| 42 | #include <string.h> |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 43 | #include <assert.h> |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 44 | #include <unordered_map> |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 45 | #include <unordered_set> |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 46 | #include <map> |
| 47 | #include <string> |
| 48 | #include <iostream> |
| 49 | #include <algorithm> |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 50 | #include <list> |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 51 | #include <spirv.hpp> |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 52 | #include <set> |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 53 | |
Tobin Ehlis | b835d1b | 2015-07-03 10:34:49 -0600 | [diff] [blame] | 54 | #include "vk_loader_platform.h" |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 55 | #include "vk_dispatch_table_helper.h" |
| 56 | #include "vk_struct_string_helper_cpp.h" |
Tony Barbour | 18f7155 | 2015-04-22 11:36:22 -0600 | [diff] [blame] | 57 | #if defined(__GNUC__) |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 58 | #pragma GCC diagnostic ignored "-Wwrite-strings" |
Tony Barbour | 18f7155 | 2015-04-22 11:36:22 -0600 | [diff] [blame] | 59 | #endif |
Tony Barbour | 18f7155 | 2015-04-22 11:36:22 -0600 | [diff] [blame] | 60 | #if defined(__GNUC__) |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 61 | #pragma GCC diagnostic warning "-Wwrite-strings" |
Tony Barbour | 18f7155 | 2015-04-22 11:36:22 -0600 | [diff] [blame] | 62 | #endif |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 63 | #include "vk_struct_size_helper.h" |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 64 | #include "draw_state.h" |
Tobin Ehlis | a0cb02e | 2015-07-03 10:15:26 -0600 | [diff] [blame] | 65 | #include "vk_layer_config.h" |
Michael Lentine | 97eb746 | 2015-11-20 09:48:52 -0800 | [diff] [blame] | 66 | #include "vulkan/vk_debug_marker_layer.h" |
Tobin Ehlis | a0cb02e | 2015-07-03 10:15:26 -0600 | [diff] [blame] | 67 | #include "vk_layer_table.h" |
| 68 | #include "vk_layer_debug_marker_table.h" |
| 69 | #include "vk_layer_data.h" |
| 70 | #include "vk_layer_logging.h" |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 71 | #include "vk_layer_extension_utils.h" |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 72 | #include "vk_layer_utils.h" |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 73 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 74 | // This definition controls whether image layout transitions are |
| 75 | // enabled/disabled. |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 76 | // disable until corner cases are fixed |
| 77 | #define DISABLE_IMAGE_LAYOUT_VALIDATION |
| 78 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 79 | using std::unordered_map; |
| 80 | using std::unordered_set; |
| 81 | |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 82 | // Track command pools and their command buffers |
| 83 | struct CMD_POOL_INFO { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 84 | VkCommandPoolCreateFlags createFlags; |
| 85 | list<VkCommandBuffer> commandBuffers; // list container of cmd buffers |
| 86 | // allocated from this pool |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 87 | }; |
| 88 | |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 89 | struct devExts { |
Courtney Goeltzenleuchter | 6ed5dc2 | 2015-11-03 15:41:43 -0700 | [diff] [blame] | 90 | VkBool32 debug_marker_enabled; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 91 | VkBool32 wsi_enabled; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 92 | unordered_map<VkSwapchainKHR, SWAPCHAIN_NODE *> swapchainMap; |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 93 | }; |
| 94 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 95 | // fwd decls |
| 96 | struct shader_module; |
| 97 | struct render_pass; |
| 98 | |
Cody Northrop | 55443ef | 2015-09-28 15:09:32 -0600 | [diff] [blame] | 99 | struct layer_data { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 100 | debug_report_data *report_data; |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 101 | std::vector<VkDebugReportCallbackEXT> logging_callback; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 102 | VkLayerDispatchTable *device_dispatch_table; |
| 103 | VkLayerInstanceDispatchTable *instance_dispatch_table; |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 104 | devExts device_extensions; |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 105 | vector<VkQueue> queues; // all queues under given device |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 106 | // Global set of all cmdBuffers that are inFlight on this device |
| 107 | unordered_set<VkCommandBuffer> globalInFlightCmdBuffers; |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 108 | // Layer specific data |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 109 | unordered_map<VkSampler, unique_ptr<SAMPLER_NODE>> sampleMap; |
| 110 | unordered_map<VkImageView, unique_ptr<VkImageViewCreateInfo>> imageViewMap; |
| 111 | unordered_map<VkImage, unique_ptr<VkImageCreateInfo>> imageMap; |
| 112 | unordered_map<VkBufferView, unique_ptr<VkBufferViewCreateInfo>> |
| 113 | bufferViewMap; |
| 114 | unordered_map<VkBuffer, BUFFER_NODE> bufferMap; |
| 115 | unordered_map<VkPipeline, PIPELINE_NODE *> pipelineMap; |
| 116 | unordered_map<VkCommandPool, CMD_POOL_INFO> commandPoolMap; |
| 117 | unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> descriptorPoolMap; |
| 118 | unordered_map<VkDescriptorSet, SET_NODE *> setMap; |
| 119 | unordered_map<VkDescriptorSetLayout, LAYOUT_NODE *> descriptorSetLayoutMap; |
| 120 | unordered_map<VkPipelineLayout, PIPELINE_LAYOUT_NODE> pipelineLayoutMap; |
| 121 | unordered_map<VkDeviceMemory, VkImage> memImageMap; |
| 122 | unordered_map<VkFence, FENCE_NODE> fenceMap; |
| 123 | unordered_map<VkQueue, QUEUE_NODE> queueMap; |
| 124 | unordered_map<VkEvent, EVENT_NODE> eventMap; |
| 125 | unordered_map<QueryObject, bool> queryToStateMap; |
| 126 | unordered_map<VkSemaphore, uint32_t> semaphoreSignaledMap; |
| 127 | unordered_map<void *, GLOBAL_CB_NODE *> commandBufferMap; |
| 128 | unordered_map<VkFramebuffer, VkFramebufferCreateInfo *> frameBufferMap; |
| 129 | unordered_map<VkImage, IMAGE_NODE *> imageLayoutMap; |
| 130 | unordered_map<VkRenderPass, RENDER_PASS_NODE *> renderPassMap; |
| 131 | unordered_map<VkShaderModule, shader_module *> shaderModuleMap; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 132 | // Current render pass |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 133 | VkRenderPassBeginInfo renderPassBeginInfo; |
| 134 | uint32_t currentSubpass; |
| 135 | unordered_map<VkDevice, VkPhysicalDeviceProperties> physDevPropertyMap; |
Cody Northrop | 55443ef | 2015-09-28 15:09:32 -0600 | [diff] [blame] | 136 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 137 | layer_data() |
| 138 | : report_data(nullptr), device_dispatch_table(nullptr), |
| 139 | instance_dispatch_table(nullptr), device_extensions(){}; |
Cody Northrop | 55443ef | 2015-09-28 15:09:32 -0600 | [diff] [blame] | 140 | }; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 141 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 142 | // Code imported from ShaderChecker |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 143 | static void build_def_index(shader_module *); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 144 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 145 | // A forward iterator over spirv instructions. Provides easy access to len, |
| 146 | // opcode, and content words |
| 147 | // without the caller needing to care too much about the physical SPIRV module |
| 148 | // layout. |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 149 | struct spirv_inst_iter { |
| 150 | std::vector<uint32_t>::const_iterator zero; |
| 151 | std::vector<uint32_t>::const_iterator it; |
| 152 | |
| 153 | uint32_t len() { return *it >> 16; } |
| 154 | uint32_t opcode() { return *it & 0x0ffffu; } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 155 | uint32_t const &word(unsigned n) { return it[n]; } |
Mark Young | d652d13 | 2016-01-25 13:37:06 -0700 | [diff] [blame] | 156 | uint32_t offset() { return (uint32_t)(it - zero); } |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 157 | |
| 158 | spirv_inst_iter(std::vector<uint32_t>::const_iterator zero, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 159 | std::vector<uint32_t>::const_iterator it) |
| 160 | : zero(zero), it(it) {} |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 161 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 162 | bool operator==(spirv_inst_iter const &other) { return it == other.it; } |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 163 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 164 | bool operator!=(spirv_inst_iter const &other) { return it != other.it; } |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 165 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 166 | spirv_inst_iter operator++(int) { /* x++ */ |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 167 | spirv_inst_iter ii = *this; |
| 168 | it += len(); |
| 169 | return ii; |
| 170 | } |
| 171 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 172 | spirv_inst_iter operator++() { /* ++x; */ |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 173 | it += len(); |
| 174 | return *this; |
| 175 | } |
| 176 | |
| 177 | /* The iterator and the value are the same thing. */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 178 | spirv_inst_iter &operator*() { return *this; } |
| 179 | spirv_inst_iter const &operator*() const { return *this; } |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 180 | }; |
| 181 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 182 | struct shader_module { |
| 183 | /* the spirv image itself */ |
| 184 | vector<uint32_t> words; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 185 | /* a mapping of <id> to the first word of its def. this is useful because |
| 186 | * walking type |
| 187 | * trees, constant expressions, etc requires jumping all over the |
| 188 | * instruction stream. |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 189 | */ |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 190 | unordered_map<unsigned, unsigned> def_index; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 191 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 192 | shader_module(VkShaderModuleCreateInfo const *pCreateInfo) |
| 193 | : words((uint32_t *)pCreateInfo->pCode, |
| 194 | (uint32_t *)pCreateInfo->pCode + |
| 195 | pCreateInfo->codeSize / sizeof(uint32_t)), |
| 196 | def_index() { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 197 | |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 198 | build_def_index(this); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 199 | } |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 200 | |
| 201 | /* expose begin() / end() to enable range-based for */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 202 | spirv_inst_iter begin() const { |
| 203 | return spirv_inst_iter(words.begin(), words.begin() + 5); |
| 204 | } /* first insn */ |
| 205 | spirv_inst_iter end() const { |
| 206 | return spirv_inst_iter(words.begin(), words.end()); |
| 207 | } /* just past last insn */ |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 208 | /* given an offset into the module, produce an iterator there. */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 209 | spirv_inst_iter at(unsigned offset) const { |
| 210 | return spirv_inst_iter(words.begin(), words.begin() + offset); |
| 211 | } |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 212 | |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 213 | /* gets an iterator to the definition of an id */ |
| 214 | spirv_inst_iter get_def(unsigned id) const { |
| 215 | auto it = def_index.find(id); |
| 216 | if (it == def_index.end()) { |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 217 | return end(); |
| 218 | } |
| 219 | return at(it->second); |
| 220 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 221 | }; |
| 222 | |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 223 | // TODO : Do we need to guard access to layer_data_map w/ lock? |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 224 | static unordered_map<void *, layer_data *> layer_data_map; |
Courtney Goeltzenleuchter | 3d0dfad | 2015-06-13 21:23:09 -0600 | [diff] [blame] | 225 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 226 | static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 227 | // TODO : This can be much smarter, using separate locks for separate global |
| 228 | // data |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 229 | static int globalLockInitialized = 0; |
| 230 | static loader_platform_thread_mutex globalLock; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 231 | #define MAX_TID 513 |
| 232 | static loader_platform_thread_id g_tidMapping[MAX_TID] = {0}; |
| 233 | static uint32_t g_maxTID = 0; |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 234 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 235 | template layer_data * |
| 236 | get_my_data_ptr<layer_data>(void *data_key, |
| 237 | std::unordered_map<void *, layer_data *> &data_map); |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 238 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 239 | // Map actual TID to an index value and return that index |
| 240 | // This keeps TIDs in range from 0-MAX_TID and simplifies compares between runs |
| 241 | static uint32_t getTIDIndex() { |
| 242 | loader_platform_thread_id tid = loader_platform_get_thread_id(); |
| 243 | for (uint32_t i = 0; i < g_maxTID; i++) { |
| 244 | if (tid == g_tidMapping[i]) |
| 245 | return i; |
| 246 | } |
| 247 | // Don't yet have mapping, set it and return newly set index |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 248 | uint32_t retVal = (uint32_t)g_maxTID; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 249 | g_tidMapping[g_maxTID++] = tid; |
| 250 | assert(g_maxTID < MAX_TID); |
| 251 | return retVal; |
| 252 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 253 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 254 | // Return a string representation of CMD_TYPE enum |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 255 | static string cmdTypeToString(CMD_TYPE cmd) { |
| 256 | switch (cmd) { |
| 257 | case CMD_BINDPIPELINE: |
| 258 | return "CMD_BINDPIPELINE"; |
| 259 | case CMD_BINDPIPELINEDELTA: |
| 260 | return "CMD_BINDPIPELINEDELTA"; |
| 261 | case CMD_SETVIEWPORTSTATE: |
| 262 | return "CMD_SETVIEWPORTSTATE"; |
| 263 | case CMD_SETLINEWIDTHSTATE: |
| 264 | return "CMD_SETLINEWIDTHSTATE"; |
| 265 | case CMD_SETDEPTHBIASSTATE: |
| 266 | return "CMD_SETDEPTHBIASSTATE"; |
| 267 | case CMD_SETBLENDSTATE: |
| 268 | return "CMD_SETBLENDSTATE"; |
| 269 | case CMD_SETDEPTHBOUNDSSTATE: |
| 270 | return "CMD_SETDEPTHBOUNDSSTATE"; |
| 271 | case CMD_SETSTENCILREADMASKSTATE: |
| 272 | return "CMD_SETSTENCILREADMASKSTATE"; |
| 273 | case CMD_SETSTENCILWRITEMASKSTATE: |
| 274 | return "CMD_SETSTENCILWRITEMASKSTATE"; |
| 275 | case CMD_SETSTENCILREFERENCESTATE: |
| 276 | return "CMD_SETSTENCILREFERENCESTATE"; |
| 277 | case CMD_BINDDESCRIPTORSETS: |
| 278 | return "CMD_BINDDESCRIPTORSETS"; |
| 279 | case CMD_BINDINDEXBUFFER: |
| 280 | return "CMD_BINDINDEXBUFFER"; |
| 281 | case CMD_BINDVERTEXBUFFER: |
| 282 | return "CMD_BINDVERTEXBUFFER"; |
| 283 | case CMD_DRAW: |
| 284 | return "CMD_DRAW"; |
| 285 | case CMD_DRAWINDEXED: |
| 286 | return "CMD_DRAWINDEXED"; |
| 287 | case CMD_DRAWINDIRECT: |
| 288 | return "CMD_DRAWINDIRECT"; |
| 289 | case CMD_DRAWINDEXEDINDIRECT: |
| 290 | return "CMD_DRAWINDEXEDINDIRECT"; |
| 291 | case CMD_DISPATCH: |
| 292 | return "CMD_DISPATCH"; |
| 293 | case CMD_DISPATCHINDIRECT: |
| 294 | return "CMD_DISPATCHINDIRECT"; |
| 295 | case CMD_COPYBUFFER: |
| 296 | return "CMD_COPYBUFFER"; |
| 297 | case CMD_COPYIMAGE: |
| 298 | return "CMD_COPYIMAGE"; |
| 299 | case CMD_BLITIMAGE: |
| 300 | return "CMD_BLITIMAGE"; |
| 301 | case CMD_COPYBUFFERTOIMAGE: |
| 302 | return "CMD_COPYBUFFERTOIMAGE"; |
| 303 | case CMD_COPYIMAGETOBUFFER: |
| 304 | return "CMD_COPYIMAGETOBUFFER"; |
| 305 | case CMD_CLONEIMAGEDATA: |
| 306 | return "CMD_CLONEIMAGEDATA"; |
| 307 | case CMD_UPDATEBUFFER: |
| 308 | return "CMD_UPDATEBUFFER"; |
| 309 | case CMD_FILLBUFFER: |
| 310 | return "CMD_FILLBUFFER"; |
| 311 | case CMD_CLEARCOLORIMAGE: |
| 312 | return "CMD_CLEARCOLORIMAGE"; |
| 313 | case CMD_CLEARATTACHMENTS: |
| 314 | return "CMD_CLEARCOLORATTACHMENT"; |
| 315 | case CMD_CLEARDEPTHSTENCILIMAGE: |
| 316 | return "CMD_CLEARDEPTHSTENCILIMAGE"; |
| 317 | case CMD_RESOLVEIMAGE: |
| 318 | return "CMD_RESOLVEIMAGE"; |
| 319 | case CMD_SETEVENT: |
| 320 | return "CMD_SETEVENT"; |
| 321 | case CMD_RESETEVENT: |
| 322 | return "CMD_RESETEVENT"; |
| 323 | case CMD_WAITEVENTS: |
| 324 | return "CMD_WAITEVENTS"; |
| 325 | case CMD_PIPELINEBARRIER: |
| 326 | return "CMD_PIPELINEBARRIER"; |
| 327 | case CMD_BEGINQUERY: |
| 328 | return "CMD_BEGINQUERY"; |
| 329 | case CMD_ENDQUERY: |
| 330 | return "CMD_ENDQUERY"; |
| 331 | case CMD_RESETQUERYPOOL: |
| 332 | return "CMD_RESETQUERYPOOL"; |
| 333 | case CMD_COPYQUERYPOOLRESULTS: |
| 334 | return "CMD_COPYQUERYPOOLRESULTS"; |
| 335 | case CMD_WRITETIMESTAMP: |
| 336 | return "CMD_WRITETIMESTAMP"; |
| 337 | case CMD_INITATOMICCOUNTERS: |
| 338 | return "CMD_INITATOMICCOUNTERS"; |
| 339 | case CMD_LOADATOMICCOUNTERS: |
| 340 | return "CMD_LOADATOMICCOUNTERS"; |
| 341 | case CMD_SAVEATOMICCOUNTERS: |
| 342 | return "CMD_SAVEATOMICCOUNTERS"; |
| 343 | case CMD_BEGINRENDERPASS: |
| 344 | return "CMD_BEGINRENDERPASS"; |
| 345 | case CMD_ENDRENDERPASS: |
| 346 | return "CMD_ENDRENDERPASS"; |
| 347 | case CMD_DBGMARKERBEGIN: |
| 348 | return "CMD_DBGMARKERBEGIN"; |
| 349 | case CMD_DBGMARKEREND: |
| 350 | return "CMD_DBGMARKEREND"; |
| 351 | default: |
| 352 | return "UNKNOWN"; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 353 | } |
| 354 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 355 | |
| 356 | // SPIRV utility functions |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 357 | static void build_def_index(shader_module *module) { |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 358 | for (auto insn : *module) { |
| 359 | switch (insn.opcode()) { |
Chris Forbes | 92b9ab0 | 2016-01-26 13:49:27 +1300 | [diff] [blame] | 360 | /* Types */ |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 361 | case spv::OpTypeVoid: |
| 362 | case spv::OpTypeBool: |
| 363 | case spv::OpTypeInt: |
| 364 | case spv::OpTypeFloat: |
| 365 | case spv::OpTypeVector: |
| 366 | case spv::OpTypeMatrix: |
| 367 | case spv::OpTypeImage: |
| 368 | case spv::OpTypeSampler: |
| 369 | case spv::OpTypeSampledImage: |
| 370 | case spv::OpTypeArray: |
| 371 | case spv::OpTypeRuntimeArray: |
| 372 | case spv::OpTypeStruct: |
| 373 | case spv::OpTypeOpaque: |
| 374 | case spv::OpTypePointer: |
| 375 | case spv::OpTypeFunction: |
| 376 | case spv::OpTypeEvent: |
| 377 | case spv::OpTypeDeviceEvent: |
| 378 | case spv::OpTypeReserveId: |
| 379 | case spv::OpTypeQueue: |
| 380 | case spv::OpTypePipe: |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 381 | module->def_index[insn.word(1)] = insn.offset(); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 382 | break; |
| 383 | |
Chris Forbes | 92b9ab0 | 2016-01-26 13:49:27 +1300 | [diff] [blame] | 384 | /* Fixed constants */ |
| 385 | case spv::OpConstantTrue: |
| 386 | case spv::OpConstantFalse: |
| 387 | case spv::OpConstant: |
| 388 | case spv::OpConstantComposite: |
| 389 | case spv::OpConstantSampler: |
| 390 | case spv::OpConstantNull: |
| 391 | module->def_index[insn.word(2)] = insn.offset(); |
| 392 | break; |
| 393 | |
| 394 | /* Specialization constants */ |
| 395 | case spv::OpSpecConstantTrue: |
| 396 | case spv::OpSpecConstantFalse: |
| 397 | case spv::OpSpecConstant: |
| 398 | case spv::OpSpecConstantComposite: |
| 399 | case spv::OpSpecConstantOp: |
| 400 | module->def_index[insn.word(2)] = insn.offset(); |
| 401 | break; |
| 402 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 403 | default: |
Chris Forbes | 92b9ab0 | 2016-01-26 13:49:27 +1300 | [diff] [blame] | 404 | /* We don't care about any other defs for now. */ |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 405 | break; |
| 406 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 407 | } |
| 408 | } |
| 409 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 410 | bool shader_is_spirv(VkShaderModuleCreateInfo const *pCreateInfo) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 411 | uint32_t *words = (uint32_t *)pCreateInfo->pCode; |
| 412 | size_t sizeInWords = pCreateInfo->codeSize / sizeof(uint32_t); |
| 413 | |
| 414 | /* Just validate that the header makes sense. */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 415 | return sizeInWords >= 5 && words[0] == spv::MagicNumber && |
| 416 | words[1] == spv::Version; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 417 | } |
| 418 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 419 | static char const *storage_class_name(unsigned sc) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 420 | switch (sc) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 421 | case spv::StorageClassInput: |
| 422 | return "input"; |
| 423 | case spv::StorageClassOutput: |
| 424 | return "output"; |
| 425 | case spv::StorageClassUniformConstant: |
| 426 | return "const uniform"; |
| 427 | case spv::StorageClassUniform: |
| 428 | return "uniform"; |
| 429 | case spv::StorageClassWorkgroup: |
| 430 | return "workgroup local"; |
| 431 | case spv::StorageClassCrossWorkgroup: |
| 432 | return "workgroup global"; |
| 433 | case spv::StorageClassPrivate: |
| 434 | return "private global"; |
| 435 | case spv::StorageClassFunction: |
| 436 | return "function"; |
| 437 | case spv::StorageClassGeneric: |
| 438 | return "generic"; |
| 439 | case spv::StorageClassAtomicCounter: |
| 440 | return "atomic counter"; |
| 441 | case spv::StorageClassImage: |
| 442 | return "image"; |
| 443 | default: |
| 444 | return "unknown"; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 445 | } |
| 446 | } |
| 447 | |
Chris Forbes | 204207a | 2016-01-26 14:07:16 +1300 | [diff] [blame] | 448 | /* get the value of an integral constant */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 449 | unsigned get_constant_value(shader_module const *src, unsigned id) { |
Chris Forbes | 204207a | 2016-01-26 14:07:16 +1300 | [diff] [blame] | 450 | auto value = src->get_def(id); |
| 451 | assert(value != src->end()); |
| 452 | |
| 453 | if (value.opcode() != spv::OpConstant) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 454 | /* TODO: Either ensure that the specialization transform is already |
| 455 | performed on a module we're |
Chris Forbes | 204207a | 2016-01-26 14:07:16 +1300 | [diff] [blame] | 456 | considering here, OR -- specialize on the fly now. |
| 457 | */ |
| 458 | return 1; |
| 459 | } |
| 460 | |
| 461 | return value.word(3); |
| 462 | } |
| 463 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 464 | /* returns ptr to null terminator */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 465 | static char *describe_type(char *dst, shader_module const *src, unsigned type) { |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 466 | auto insn = src->get_def(type); |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 467 | assert(insn != src->end()); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 468 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 469 | switch (insn.opcode()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 470 | case spv::OpTypeBool: |
| 471 | return dst + sprintf(dst, "bool"); |
| 472 | case spv::OpTypeInt: |
| 473 | return dst + |
| 474 | sprintf(dst, "%cint%d", insn.word(3) ? 's' : 'u', insn.word(2)); |
| 475 | case spv::OpTypeFloat: |
| 476 | return dst + sprintf(dst, "float%d", insn.word(2)); |
| 477 | case spv::OpTypeVector: |
| 478 | dst += sprintf(dst, "vec%d of ", insn.word(3)); |
| 479 | return describe_type(dst, src, insn.word(2)); |
| 480 | case spv::OpTypeMatrix: |
| 481 | dst += sprintf(dst, "mat%d of ", insn.word(3)); |
| 482 | return describe_type(dst, src, insn.word(2)); |
| 483 | case spv::OpTypeArray: |
| 484 | dst += |
| 485 | sprintf(dst, "arr[%d] of ", get_constant_value(src, insn.word(3))); |
| 486 | return describe_type(dst, src, insn.word(2)); |
| 487 | case spv::OpTypePointer: |
| 488 | dst += sprintf(dst, "ptr to %s ", storage_class_name(insn.word(2))); |
| 489 | return describe_type(dst, src, insn.word(3)); |
| 490 | case spv::OpTypeStruct: { |
| 491 | dst += sprintf(dst, "struct of ("); |
| 492 | for (unsigned i = 2; i < insn.len(); i++) { |
| 493 | dst = describe_type(dst, src, insn.word(i)); |
| 494 | dst += sprintf(dst, i == insn.len() - 1 ? ")" : ", "); |
| 495 | } |
| 496 | return dst; |
| 497 | } |
| 498 | case spv::OpTypeSampler: |
| 499 | return dst + sprintf(dst, "sampler"); |
| 500 | default: |
| 501 | return dst + sprintf(dst, "oddtype"); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 502 | } |
| 503 | } |
| 504 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 505 | static bool types_match(shader_module const *a, shader_module const *b, |
| 506 | unsigned a_type, unsigned b_type, bool b_arrayed) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 507 | /* walk two type trees together, and complain about differences */ |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 508 | auto a_insn = a->get_def(a_type); |
| 509 | auto b_insn = b->get_def(b_type); |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 510 | assert(a_insn != a->end()); |
| 511 | assert(b_insn != b->end()); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 512 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 513 | if (b_arrayed && b_insn.opcode() == spv::OpTypeArray) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 514 | /* we probably just found the extra level of arrayness in b_type: |
| 515 | * compare the type inside it to a_type */ |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 516 | return types_match(a, b, a_type, b_insn.word(2), false); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 517 | } |
| 518 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 519 | if (a_insn.opcode() != b_insn.opcode()) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 520 | return false; |
| 521 | } |
| 522 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 523 | switch (a_insn.opcode()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 524 | /* if b_arrayed and we hit a leaf type, then we can't match -- there's |
| 525 | * nowhere for the extra OpTypeArray to be! */ |
| 526 | case spv::OpTypeBool: |
| 527 | return true && !b_arrayed; |
| 528 | case spv::OpTypeInt: |
| 529 | /* match on width, signedness */ |
| 530 | return a_insn.word(2) == b_insn.word(2) && |
| 531 | a_insn.word(3) == b_insn.word(3) && !b_arrayed; |
| 532 | case spv::OpTypeFloat: |
| 533 | /* match on width */ |
| 534 | return a_insn.word(2) == b_insn.word(2) && !b_arrayed; |
| 535 | case spv::OpTypeVector: |
| 536 | case spv::OpTypeMatrix: |
| 537 | /* match on element type, count. these all have the same layout. we |
| 538 | * don't get here if |
| 539 | * b_arrayed -- that is handled above. */ |
| 540 | return !b_arrayed && |
| 541 | types_match(a, b, a_insn.word(2), b_insn.word(2), b_arrayed) && |
| 542 | a_insn.word(3) == b_insn.word(3); |
| 543 | case spv::OpTypeArray: |
| 544 | /* match on element type, count. these all have the same layout. we |
| 545 | * don't get here if |
| 546 | * b_arrayed. This differs from vector & matrix types in that the array |
| 547 | * size is the id of a constant instruction, |
| 548 | * not a literal within OpTypeArray */ |
| 549 | return !b_arrayed && |
| 550 | types_match(a, b, a_insn.word(2), b_insn.word(2), b_arrayed) && |
| 551 | get_constant_value(a, a_insn.word(3)) == |
| 552 | get_constant_value(b, b_insn.word(3)); |
| 553 | case spv::OpTypeStruct: |
| 554 | /* match on all element types */ |
| 555 | { |
| 556 | if (b_arrayed) { |
| 557 | /* for the purposes of matching different levels of arrayness, |
| 558 | * structs are leaves. */ |
| 559 | return false; |
| 560 | } |
| 561 | |
| 562 | if (a_insn.len() != b_insn.len()) { |
| 563 | return false; /* structs cannot match if member counts differ */ |
| 564 | } |
| 565 | |
| 566 | for (unsigned i = 2; i < a_insn.len(); i++) { |
| 567 | if (!types_match(a, b, a_insn.word(i), b_insn.word(i), |
| 568 | b_arrayed)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 569 | return false; |
| 570 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 571 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 572 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 573 | return true; |
| 574 | } |
| 575 | case spv::OpTypePointer: |
| 576 | /* match on pointee type. storage class is expected to differ */ |
| 577 | return types_match(a, b, a_insn.word(3), b_insn.word(3), b_arrayed); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 578 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 579 | default: |
| 580 | /* remaining types are CLisms, or may not appear in the interfaces we |
| 581 | * are interested in. Just claim no match. |
| 582 | */ |
| 583 | return false; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 584 | } |
| 585 | } |
| 586 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 587 | static int value_or_default(std::unordered_map<unsigned, unsigned> const &map, |
| 588 | unsigned id, int def) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 589 | auto it = map.find(id); |
| 590 | if (it == map.end()) |
| 591 | return def; |
| 592 | else |
| 593 | return it->second; |
| 594 | } |
| 595 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 596 | static unsigned get_locations_consumed_by_type(shader_module const *src, |
| 597 | unsigned type, |
| 598 | bool strip_array_level) { |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 599 | auto insn = src->get_def(type); |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 600 | assert(insn != src->end()); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 601 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 602 | switch (insn.opcode()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 603 | case spv::OpTypePointer: |
| 604 | /* see through the ptr -- this is only ever at the toplevel for graphics |
| 605 | * shaders; |
| 606 | * we're never actually passing pointers around. */ |
| 607 | return get_locations_consumed_by_type(src, insn.word(3), |
| 608 | strip_array_level); |
| 609 | case spv::OpTypeArray: |
| 610 | if (strip_array_level) { |
| 611 | return get_locations_consumed_by_type(src, insn.word(2), false); |
| 612 | } else { |
| 613 | return get_constant_value(src, insn.word(3)) * |
| 614 | get_locations_consumed_by_type(src, insn.word(2), false); |
| 615 | } |
| 616 | case spv::OpTypeMatrix: |
| 617 | /* num locations is the dimension * element size */ |
| 618 | return insn.word(3) * |
| 619 | get_locations_consumed_by_type(src, insn.word(2), false); |
| 620 | default: |
| 621 | /* everything else is just 1. */ |
| 622 | return 1; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 623 | |
| 624 | /* TODO: extend to handle 64bit scalar types, whose vectors may need |
| 625 | * multiple locations. */ |
| 626 | } |
| 627 | } |
| 628 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 629 | struct interface_var { |
| 630 | uint32_t id; |
| 631 | uint32_t type_id; |
| 632 | uint32_t offset; |
| 633 | /* TODO: collect the name, too? Isn't required to be present. */ |
| 634 | }; |
| 635 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 636 | static void collect_interface_block_members( |
| 637 | layer_data *my_data, VkDevice dev, shader_module const *src, |
| 638 | std::map<uint32_t, interface_var> &out, |
| 639 | std::map<uint32_t, interface_var> &builtins_out, |
| 640 | std::unordered_map<unsigned, unsigned> const &blocks, |
| 641 | bool is_array_of_verts, uint32_t id, uint32_t type_id) { |
| 642 | /* Walk down the type_id presented, trying to determine whether it's |
| 643 | * actually an interface block. */ |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 644 | auto type = src->get_def(type_id); |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 645 | |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 646 | while (true) { |
| 647 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 648 | if (type.opcode() == spv::OpTypePointer) { |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 649 | type = src->get_def(type.word(3)); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 650 | } else if (type.opcode() == spv::OpTypeArray && is_array_of_verts) { |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 651 | type = src->get_def(type.word(2)); |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 652 | is_array_of_verts = false; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 653 | } else if (type.opcode() == spv::OpTypeStruct) { |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 654 | if (blocks.find(type.word(1)) == blocks.end()) { |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 655 | /* This isn't an interface block. */ |
| 656 | return; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 657 | } else { |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 658 | /* We have found the correct type. Walk its members. */ |
| 659 | break; |
| 660 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 661 | } else { |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 662 | /* not an interface block */ |
| 663 | return; |
| 664 | } |
| 665 | } |
| 666 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 667 | /* Walk all the OpMemberDecorate for type's result id. */ |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 668 | for (auto insn : *src) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 669 | if (insn.opcode() == spv::OpMemberDecorate && |
| 670 | insn.word(1) == type.word(1)) { |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 671 | unsigned member_index = insn.word(2); |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 672 | unsigned member_type_id = type.word(2 + member_index); |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 673 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 674 | if (insn.word(3) == spv::DecorationLocation) { |
| 675 | unsigned location = insn.word(4); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 676 | unsigned num_locations = |
| 677 | get_locations_consumed_by_type(src, member_type_id, false); |
| 678 | for (unsigned int offset = 0; offset < num_locations; |
| 679 | offset++) { |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 680 | interface_var v; |
| 681 | v.id = id; |
| 682 | /* TODO: member index in interface_var too? */ |
| 683 | v.type_id = member_type_id; |
| 684 | v.offset = offset; |
| 685 | out[location + offset] = v; |
| 686 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 687 | } else if (insn.word(3) == spv::DecorationBuiltIn) { |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 688 | unsigned builtin = insn.word(4); |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 689 | interface_var v; |
| 690 | v.id = id; |
| 691 | v.type_id = member_type_id; |
| 692 | v.offset = 0; |
| 693 | builtins_out[builtin] = v; |
| 694 | } |
| 695 | } |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 696 | } |
| 697 | } |
| 698 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 699 | static void collect_interface_by_location( |
| 700 | layer_data *my_data, VkDevice dev, shader_module const *src, |
| 701 | spv::StorageClass sinterface, std::map<uint32_t, interface_var> &out, |
| 702 | std::map<uint32_t, interface_var> &builtins_out, bool is_array_of_verts) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 703 | std::unordered_map<unsigned, unsigned> var_locations; |
| 704 | std::unordered_map<unsigned, unsigned> var_builtins; |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 705 | std::unordered_map<unsigned, unsigned> blocks; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 706 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 707 | for (auto insn : *src) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 708 | |
| 709 | /* We consider two interface models: SSO rendezvous-by-location, and |
| 710 | * builtins. Complain about anything that fits neither model. |
| 711 | */ |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 712 | if (insn.opcode() == spv::OpDecorate) { |
| 713 | if (insn.word(2) == spv::DecorationLocation) { |
| 714 | var_locations[insn.word(1)] = insn.word(3); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 715 | } |
| 716 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 717 | if (insn.word(2) == spv::DecorationBuiltIn) { |
| 718 | var_builtins[insn.word(1)] = insn.word(3); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 719 | } |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 720 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 721 | if (insn.word(2) == spv::DecorationBlock) { |
| 722 | blocks[insn.word(1)] = 1; |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 723 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 724 | } |
| 725 | |
| 726 | /* TODO: handle grouped decorations */ |
| 727 | /* TODO: handle index=1 dual source outputs from FS -- two vars will |
| 728 | * have the same location, and we DONT want to clobber. */ |
| 729 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 730 | else if (insn.opcode() == spv::OpVariable && |
| 731 | insn.word(3) == sinterface) { |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 732 | unsigned id = insn.word(2); |
| 733 | unsigned type = insn.word(1); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 734 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 735 | int location = value_or_default(var_locations, id, -1); |
| 736 | int builtin = value_or_default(var_builtins, id, -1); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 737 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 738 | /* All variables and interface block members in the Input or Output |
| 739 | *storage classes |
Chris Forbes | f5020cf | 2016-01-13 09:29:31 +1300 | [diff] [blame] | 740 | * must be decorated with either a builtin or an explicit location. |
| 741 | * |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 742 | * TODO: integrate the interface block support here. For now, don't |
| 743 | *complain -- |
| 744 | * a valid SPIRV module will only hit this path for the interface |
| 745 | *block case, as the |
| 746 | * individual members of the type are decorated, rather than |
| 747 | *variable declarations. |
Chris Forbes | f5020cf | 2016-01-13 09:29:31 +1300 | [diff] [blame] | 748 | */ |
| 749 | |
| 750 | if (location != -1) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 751 | /* A user-defined interface variable, with a location. Where a |
| 752 | * variable |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 753 | * occupied multiple locations, emit one result for each. */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 754 | unsigned num_locations = get_locations_consumed_by_type( |
| 755 | src, type, is_array_of_verts); |
| 756 | for (unsigned int offset = 0; offset < num_locations; |
| 757 | offset++) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 758 | interface_var v; |
| 759 | v.id = id; |
| 760 | v.type_id = type; |
| 761 | v.offset = offset; |
| 762 | out[location + offset] = v; |
| 763 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 764 | } else if (builtin != -1) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 765 | /* A builtin interface variable */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 766 | /* Note that since builtin interface variables do not consume |
| 767 | * numbered |
| 768 | * locations, there is no larger-than-vec4 consideration as |
| 769 | * above |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 770 | */ |
| 771 | interface_var v; |
| 772 | v.id = id; |
| 773 | v.type_id = type; |
| 774 | v.offset = 0; |
| 775 | builtins_out[builtin] = v; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 776 | } else { |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 777 | /* An interface block instance */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 778 | collect_interface_block_members(my_data, dev, src, out, |
| 779 | builtins_out, blocks, |
| 780 | is_array_of_verts, id, type); |
Chris Forbes | a3e85f6 | 2016-01-15 14:53:11 +1300 | [diff] [blame] | 781 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 782 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 783 | } |
| 784 | } |
| 785 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 786 | static void collect_interface_by_descriptor_slot( |
| 787 | layer_data *my_data, VkDevice dev, shader_module const *src, |
| 788 | spv::StorageClass sinterface, |
| 789 | std::map<std::pair<unsigned, unsigned>, interface_var> &out) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 790 | |
| 791 | std::unordered_map<unsigned, unsigned> var_sets; |
| 792 | std::unordered_map<unsigned, unsigned> var_bindings; |
| 793 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 794 | for (auto insn : *src) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 795 | /* All variables in the Uniform or UniformConstant storage classes are |
| 796 | * required to be decorated with both |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 797 | * DecorationDescriptorSet and DecorationBinding. |
| 798 | */ |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 799 | if (insn.opcode() == spv::OpDecorate) { |
| 800 | if (insn.word(2) == spv::DecorationDescriptorSet) { |
| 801 | var_sets[insn.word(1)] = insn.word(3); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 802 | } |
| 803 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 804 | if (insn.word(2) == spv::DecorationBinding) { |
| 805 | var_bindings[insn.word(1)] = insn.word(3); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 806 | } |
| 807 | } |
| 808 | |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 809 | else if (insn.opcode() == spv::OpVariable && |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 810 | (insn.word(3) == spv::StorageClassUniform || |
| 811 | insn.word(3) == spv::StorageClassUniformConstant)) { |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 812 | unsigned set = value_or_default(var_sets, insn.word(2), 0); |
| 813 | unsigned binding = value_or_default(var_bindings, insn.word(2), 0); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 814 | |
| 815 | auto existing_it = out.find(std::make_pair(set, binding)); |
| 816 | if (existing_it != out.end()) { |
| 817 | /* conflict within spv image */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 818 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 819 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 820 | __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC", |
| 821 | "var %d (type %d) in %s interface in descriptor slot " |
| 822 | "(%u,%u) conflicts with existing definition", |
| 823 | insn.word(2), insn.word(1), |
| 824 | storage_class_name(sinterface), |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 825 | existing_it->first.first, existing_it->first.second); |
| 826 | } |
| 827 | |
| 828 | interface_var v; |
Chris Forbes | c7e2e20 | 2016-01-18 08:56:40 +1300 | [diff] [blame] | 829 | v.id = insn.word(2); |
| 830 | v.type_id = insn.word(1); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 831 | out[std::make_pair(set, binding)] = v; |
| 832 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 833 | } |
| 834 | } |
| 835 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 836 | static bool validate_interface_between_stages(layer_data *my_data, VkDevice dev, |
| 837 | shader_module const *producer, |
| 838 | char const *producer_name, |
| 839 | shader_module const *consumer, |
| 840 | char const *consumer_name, |
| 841 | bool consumer_arrayed_input) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 842 | std::map<uint32_t, interface_var> outputs; |
| 843 | std::map<uint32_t, interface_var> inputs; |
| 844 | |
| 845 | std::map<uint32_t, interface_var> builtin_outputs; |
| 846 | std::map<uint32_t, interface_var> builtin_inputs; |
| 847 | |
| 848 | bool pass = true; |
| 849 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 850 | collect_interface_by_location(my_data, dev, producer, |
| 851 | spv::StorageClassOutput, outputs, |
| 852 | builtin_outputs, false); |
| 853 | collect_interface_by_location(my_data, dev, consumer, |
| 854 | spv::StorageClassInput, inputs, |
| 855 | builtin_inputs, consumer_arrayed_input); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 856 | |
| 857 | auto a_it = outputs.begin(); |
| 858 | auto b_it = inputs.begin(); |
| 859 | |
| 860 | /* maps sorted by key (location); walk them together to find mismatches */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 861 | while ((outputs.size() > 0 && a_it != outputs.end()) || |
| 862 | (inputs.size() && b_it != inputs.end())) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 863 | bool a_at_end = outputs.size() == 0 || a_it == outputs.end(); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 864 | bool b_at_end = inputs.size() == 0 || b_it == inputs.end(); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 865 | auto a_first = a_at_end ? 0 : a_it->first; |
| 866 | auto b_first = b_at_end ? 0 : b_it->first; |
| 867 | |
| 868 | if (b_at_end || ((!a_at_end) && (a_first < b_first))) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 869 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 870 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 871 | __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", |
| 872 | "%s writes to output location %d which is not consumed " |
| 873 | "by %s", |
| 874 | producer_name, a_first, consumer_name)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 875 | pass = false; |
| 876 | } |
| 877 | a_it++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 878 | } else if (a_at_end || a_first > b_first) { |
| 879 | if (log_msg( |
| 880 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 881 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, __LINE__, |
| 882 | SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", |
| 883 | "%s consumes input location %d which is not written by %s", |
| 884 | consumer_name, b_first, producer_name)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 885 | pass = false; |
| 886 | } |
| 887 | b_it++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 888 | } else { |
| 889 | if (types_match(producer, consumer, a_it->second.type_id, |
| 890 | b_it->second.type_id, consumer_arrayed_input)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 891 | /* OK! */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 892 | } else { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 893 | char producer_type[1024]; |
| 894 | char consumer_type[1024]; |
| 895 | describe_type(producer_type, producer, a_it->second.type_id); |
| 896 | describe_type(consumer_type, consumer, b_it->second.type_id); |
| 897 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 898 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 899 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 900 | __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, |
| 901 | "SC", "Type mismatch on location %d: '%s' vs '%s'", |
| 902 | a_it->first, producer_type, consumer_type)) { |
| 903 | pass = false; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 904 | } |
| 905 | } |
| 906 | a_it++; |
| 907 | b_it++; |
| 908 | } |
| 909 | } |
| 910 | |
| 911 | return pass; |
| 912 | } |
| 913 | |
| 914 | enum FORMAT_TYPE { |
| 915 | FORMAT_TYPE_UNDEFINED, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 916 | FORMAT_TYPE_FLOAT, /* UNORM, SNORM, FLOAT, USCALED, SSCALED, SRGB -- |
| 917 | anything we consider float in the shader */ |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 918 | FORMAT_TYPE_SINT, |
| 919 | FORMAT_TYPE_UINT, |
| 920 | }; |
| 921 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 922 | static unsigned get_format_type(VkFormat fmt) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 923 | switch (fmt) { |
| 924 | case VK_FORMAT_UNDEFINED: |
| 925 | return FORMAT_TYPE_UNDEFINED; |
| 926 | case VK_FORMAT_R8_SINT: |
| 927 | case VK_FORMAT_R8G8_SINT: |
| 928 | case VK_FORMAT_R8G8B8_SINT: |
| 929 | case VK_FORMAT_R8G8B8A8_SINT: |
| 930 | case VK_FORMAT_R16_SINT: |
| 931 | case VK_FORMAT_R16G16_SINT: |
| 932 | case VK_FORMAT_R16G16B16_SINT: |
| 933 | case VK_FORMAT_R16G16B16A16_SINT: |
| 934 | case VK_FORMAT_R32_SINT: |
| 935 | case VK_FORMAT_R32G32_SINT: |
| 936 | case VK_FORMAT_R32G32B32_SINT: |
| 937 | case VK_FORMAT_R32G32B32A32_SINT: |
| 938 | case VK_FORMAT_B8G8R8_SINT: |
| 939 | case VK_FORMAT_B8G8R8A8_SINT: |
| 940 | case VK_FORMAT_A2B10G10R10_SINT_PACK32: |
| 941 | case VK_FORMAT_A2R10G10B10_SINT_PACK32: |
| 942 | return FORMAT_TYPE_SINT; |
| 943 | case VK_FORMAT_R8_UINT: |
| 944 | case VK_FORMAT_R8G8_UINT: |
| 945 | case VK_FORMAT_R8G8B8_UINT: |
| 946 | case VK_FORMAT_R8G8B8A8_UINT: |
| 947 | case VK_FORMAT_R16_UINT: |
| 948 | case VK_FORMAT_R16G16_UINT: |
| 949 | case VK_FORMAT_R16G16B16_UINT: |
| 950 | case VK_FORMAT_R16G16B16A16_UINT: |
| 951 | case VK_FORMAT_R32_UINT: |
| 952 | case VK_FORMAT_R32G32_UINT: |
| 953 | case VK_FORMAT_R32G32B32_UINT: |
| 954 | case VK_FORMAT_R32G32B32A32_UINT: |
| 955 | case VK_FORMAT_B8G8R8_UINT: |
| 956 | case VK_FORMAT_B8G8R8A8_UINT: |
| 957 | case VK_FORMAT_A2B10G10R10_UINT_PACK32: |
| 958 | case VK_FORMAT_A2R10G10B10_UINT_PACK32: |
| 959 | return FORMAT_TYPE_UINT; |
| 960 | default: |
| 961 | return FORMAT_TYPE_FLOAT; |
| 962 | } |
| 963 | } |
| 964 | |
| 965 | /* characterizes a SPIR-V type appearing in an interface to a FF stage, |
| 966 | * for comparison to a VkFormat's characterization above. */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 967 | static unsigned get_fundamental_type(shader_module const *src, unsigned type) { |
Chris Forbes | 21977d9 | 2016-01-26 13:41:39 +1300 | [diff] [blame] | 968 | auto insn = src->get_def(type); |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 969 | assert(insn != src->end()); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 970 | |
Chris Forbes | 1257f91 | 2016-01-18 12:07:01 +1300 | [diff] [blame] | 971 | switch (insn.opcode()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 972 | case spv::OpTypeInt: |
| 973 | return insn.word(3) ? FORMAT_TYPE_SINT : FORMAT_TYPE_UINT; |
| 974 | case spv::OpTypeFloat: |
| 975 | return FORMAT_TYPE_FLOAT; |
| 976 | case spv::OpTypeVector: |
| 977 | return get_fundamental_type(src, insn.word(2)); |
| 978 | case spv::OpTypeMatrix: |
| 979 | return get_fundamental_type(src, insn.word(2)); |
| 980 | case spv::OpTypeArray: |
| 981 | return get_fundamental_type(src, insn.word(2)); |
| 982 | case spv::OpTypePointer: |
| 983 | return get_fundamental_type(src, insn.word(3)); |
| 984 | default: |
| 985 | return FORMAT_TYPE_UNDEFINED; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 986 | } |
| 987 | } |
| 988 | |
| 989 | static bool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 990 | validate_vi_consistency(layer_data *my_data, VkDevice dev, |
| 991 | VkPipelineVertexInputStateCreateInfo const *vi) { |
| 992 | /* walk the binding descriptions, which describe the step rate and stride of |
| 993 | * each vertex buffer. |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 994 | * each binding should be specified only once. |
| 995 | */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 996 | std::unordered_map<uint32_t, VkVertexInputBindingDescription const *> |
| 997 | bindings; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 998 | bool pass = true; |
| 999 | |
| 1000 | for (unsigned i = 0; i < vi->vertexBindingDescriptionCount; i++) { |
| 1001 | auto desc = &vi->pVertexBindingDescriptions[i]; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1002 | auto &binding = bindings[desc->binding]; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1003 | if (binding) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1004 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1005 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1006 | __LINE__, SHADER_CHECKER_INCONSISTENT_VI, "SC", |
| 1007 | "Duplicate vertex input binding descriptions for " |
| 1008 | "binding %d", |
| 1009 | desc->binding)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1010 | pass = false; |
| 1011 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1012 | } else { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1013 | binding = desc; |
| 1014 | } |
| 1015 | } |
| 1016 | |
| 1017 | return pass; |
| 1018 | } |
| 1019 | |
| 1020 | static bool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1021 | validate_vi_against_vs_inputs(layer_data *my_data, VkDevice dev, |
| 1022 | VkPipelineVertexInputStateCreateInfo const *vi, |
| 1023 | shader_module const *vs) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1024 | std::map<uint32_t, interface_var> inputs; |
| 1025 | /* we collect builtin inputs, but they will never appear in the VI state -- |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1026 | * the vs builtin inputs are generated in the pipeline, not sourced from |
| 1027 | * buffers (VertexID, etc) |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1028 | */ |
| 1029 | std::map<uint32_t, interface_var> builtin_inputs; |
| 1030 | bool pass = true; |
| 1031 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1032 | collect_interface_by_location(my_data, dev, vs, spv::StorageClassInput, |
| 1033 | inputs, builtin_inputs, false); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1034 | |
| 1035 | /* Build index by location */ |
| 1036 | std::map<uint32_t, VkVertexInputAttributeDescription const *> attribs; |
| 1037 | if (vi) { |
| 1038 | for (unsigned i = 0; i < vi->vertexAttributeDescriptionCount; i++) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1039 | attribs[vi->pVertexAttributeDescriptions[i].location] = |
| 1040 | &vi->pVertexAttributeDescriptions[i]; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1041 | } |
| 1042 | |
| 1043 | auto it_a = attribs.begin(); |
| 1044 | auto it_b = inputs.begin(); |
| 1045 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1046 | while ((attribs.size() > 0 && it_a != attribs.end()) || |
| 1047 | (inputs.size() > 0 && it_b != inputs.end())) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1048 | bool a_at_end = attribs.size() == 0 || it_a == attribs.end(); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1049 | bool b_at_end = inputs.size() == 0 || it_b == inputs.end(); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1050 | auto a_first = a_at_end ? 0 : it_a->first; |
| 1051 | auto b_first = b_at_end ? 0 : it_b->first; |
Chris Forbes | 7d83cd5 | 2016-01-15 11:32:03 +1300 | [diff] [blame] | 1052 | if (!a_at_end && (b_at_end || a_first < b_first)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1053 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 1054 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1055 | __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", |
| 1056 | "Vertex attribute at location %d not consumed by VS", |
| 1057 | a_first)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1058 | pass = false; |
| 1059 | } |
| 1060 | it_a++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1061 | } else if (!b_at_end && (a_at_end || b_first < a_first)) { |
| 1062 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1063 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1064 | __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", |
| 1065 | "VS consumes input at location %d but not provided", |
| 1066 | b_first)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1067 | pass = false; |
| 1068 | } |
| 1069 | it_b++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1070 | } else { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1071 | unsigned attrib_type = get_format_type(it_a->second->format); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1072 | unsigned input_type = |
| 1073 | get_fundamental_type(vs, it_b->second.type_id); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1074 | |
| 1075 | /* type checking */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1076 | if (attrib_type != FORMAT_TYPE_UNDEFINED && |
| 1077 | input_type != FORMAT_TYPE_UNDEFINED && |
| 1078 | attrib_type != input_type) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1079 | char vs_type[1024]; |
| 1080 | describe_type(vs_type, vs, it_b->second.type_id); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1081 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1082 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1083 | __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, |
| 1084 | "SC", "Attribute type of `%s` at location %d does " |
| 1085 | "not match VS input type of `%s`", |
| 1086 | string_VkFormat(it_a->second->format), a_first, |
| 1087 | vs_type)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1088 | pass = false; |
| 1089 | } |
| 1090 | } |
| 1091 | |
| 1092 | /* OK! */ |
| 1093 | it_a++; |
| 1094 | it_b++; |
| 1095 | } |
| 1096 | } |
| 1097 | |
| 1098 | return pass; |
| 1099 | } |
| 1100 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1101 | static bool validate_fs_outputs_against_render_pass(layer_data *my_data, |
| 1102 | VkDevice dev, |
| 1103 | shader_module const *fs, |
| 1104 | RENDER_PASS_NODE const *rp, |
| 1105 | uint32_t subpass) { |
| 1106 | const std::vector<VkFormat> &color_formats = |
| 1107 | rp->subpassColorFormats[subpass]; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1108 | std::map<uint32_t, interface_var> outputs; |
| 1109 | std::map<uint32_t, interface_var> builtin_outputs; |
| 1110 | bool pass = true; |
| 1111 | |
| 1112 | /* TODO: dual source blend index (spv::DecIndex, zero if not provided) */ |
| 1113 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1114 | collect_interface_by_location(my_data, dev, fs, spv::StorageClassOutput, |
| 1115 | outputs, builtin_outputs, false); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1116 | |
| 1117 | auto it = outputs.begin(); |
| 1118 | uint32_t attachment = 0; |
| 1119 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1120 | /* Walk attachment list and outputs together -- this is a little overpowered |
| 1121 | * since attachments |
| 1122 | * are currently dense, but the parallel with matching between shader stages |
| 1123 | * is nice. |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1124 | */ |
| 1125 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1126 | while ((outputs.size() > 0 && it != outputs.end()) || |
| 1127 | attachment < color_formats.size()) { |
| 1128 | if (attachment == color_formats.size() || |
| 1129 | (it != outputs.end() && it->first < attachment)) { |
| 1130 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 1131 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1132 | __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", |
| 1133 | "FS writes to output location %d with no matching " |
| 1134 | "attachment", |
| 1135 | it->first)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1136 | pass = false; |
| 1137 | } |
| 1138 | it++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1139 | } else if (it == outputs.end() || it->first > attachment) { |
| 1140 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1141 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1142 | __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", |
| 1143 | "Attachment %d not written by FS", attachment)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1144 | pass = false; |
| 1145 | } |
| 1146 | attachment++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1147 | } else { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1148 | unsigned output_type = get_fundamental_type(fs, it->second.type_id); |
| 1149 | unsigned att_type = get_format_type(color_formats[attachment]); |
| 1150 | |
| 1151 | /* type checking */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1152 | if (att_type != FORMAT_TYPE_UNDEFINED && |
| 1153 | output_type != FORMAT_TYPE_UNDEFINED && |
| 1154 | att_type != output_type) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1155 | char fs_type[1024]; |
| 1156 | describe_type(fs_type, fs, it->second.type_id); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1157 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1158 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1159 | __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, |
| 1160 | "SC", "Attachment %d of type `%s` does not match " |
| 1161 | "FS output type of `%s`", |
| 1162 | attachment, |
| 1163 | string_VkFormat(color_formats[attachment]), |
| 1164 | fs_type)) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1165 | pass = false; |
| 1166 | } |
| 1167 | } |
| 1168 | |
| 1169 | /* OK! */ |
| 1170 | it++; |
| 1171 | attachment++; |
| 1172 | } |
| 1173 | } |
| 1174 | |
| 1175 | return pass; |
| 1176 | } |
| 1177 | |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1178 | struct shader_stage_attributes { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1179 | char const *const name; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1180 | bool arrayed_input; |
| 1181 | }; |
| 1182 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1183 | static shader_stage_attributes shader_stage_attribs[] = { |
| 1184 | {"vertex shader", false}, |
| 1185 | {"tessellation control shader", true}, |
| 1186 | {"tessellation evaluation shader", false}, |
| 1187 | {"geometry shader", true}, |
| 1188 | {"fragment shader", false}, |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1189 | }; |
| 1190 | |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1191 | // For given pipelineLayout verify that the setLayout at slot.first |
| 1192 | // has the requested binding at slot.second |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1193 | static bool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1194 | has_descriptor_binding(layer_data *my_data, |
| 1195 | vector<VkDescriptorSetLayout> *pipelineLayout, |
| 1196 | std::pair<unsigned, unsigned> slot) { |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1197 | if (!pipelineLayout) |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1198 | return false; |
| 1199 | |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1200 | if (slot.first >= pipelineLayout->size()) |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1201 | return false; |
| 1202 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1203 | auto set = my_data->descriptorSetLayoutMap[(*pipelineLayout)[slot.first]] |
| 1204 | ->bindings; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1205 | |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1206 | return (set.find(slot.second) != set.end()); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1207 | } |
| 1208 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1209 | static uint32_t get_shader_stage_id(VkShaderStageFlagBits stage) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1210 | uint32_t bit_pos = u_ffs(stage); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1211 | return bit_pos - 1; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1212 | } |
| 1213 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1214 | // Block of code at start here for managing/tracking Pipeline state that this |
| 1215 | // layer cares about |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 1216 | |
| 1217 | static uint64_t g_drawCount[NUM_DRAW_TYPES] = {0, 0, 0, 0}; |
| 1218 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1219 | // TODO : Should be tracking lastBound per commandBuffer and when draws occur, |
| 1220 | // report based on that cmd buffer lastBound |
| 1221 | // Then need to synchronize the accesses based on cmd buffer so that if I'm |
| 1222 | // reading state on one cmd buffer, updates |
| 1223 | // to that same cmd buffer by separate thread are not changing state from |
| 1224 | // underneath us |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 1225 | // Track the last cmd buffer touched by this thread |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1226 | |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 1227 | // prototype |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1228 | static GLOBAL_CB_NODE *getCBNode(layer_data *, const VkCommandBuffer); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1229 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1230 | static VkBool32 hasDrawCmd(GLOBAL_CB_NODE *pCB) { |
| 1231 | for (uint32_t i = 0; i < NUM_DRAW_TYPES; i++) { |
Tobin Ehlis | 53eddda | 2015-07-01 16:46:13 -0600 | [diff] [blame] | 1232 | if (pCB->drawCount[i]) |
| 1233 | return VK_TRUE; |
| 1234 | } |
| 1235 | return VK_FALSE; |
| 1236 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1237 | |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 1238 | // Check object status for selected flag state |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1239 | static VkBool32 validate_status(layer_data *my_data, GLOBAL_CB_NODE *pNode, |
| 1240 | CBStatusFlags enable_mask, |
| 1241 | CBStatusFlags status_mask, |
| 1242 | CBStatusFlags status_flag, VkFlags msg_flags, |
| 1243 | DRAW_STATE_ERROR error_code, |
| 1244 | const char *fail_msg) { |
| 1245 | // If non-zero enable mask is present, check it against status but if |
| 1246 | // enable_mask |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1247 | // is 0 then no enable required so we should always just check status |
| 1248 | if ((!enable_mask) || (enable_mask & pNode->status)) { |
| 1249 | if ((pNode->status & status_mask) != status_flag) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1250 | // TODO : How to pass dispatchable objects as srcObject? Here src |
| 1251 | // obj should be cmd buffer |
| 1252 | return log_msg(my_data->report_data, msg_flags, |
| 1253 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, |
| 1254 | __LINE__, error_code, "DS", |
| 1255 | "CB object %#" PRIxLEAST64 ": %s", |
| 1256 | (uint64_t)(pNode->commandBuffer), fail_msg); |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 1257 | } |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 1258 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 1259 | return VK_FALSE; |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 1260 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1261 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 1262 | // Retrieve pipeline node ptr for given pipeline object |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1263 | static PIPELINE_NODE *getPipeline(layer_data *my_data, |
| 1264 | const VkPipeline pipeline) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 1265 | loader_platform_thread_lock_mutex(&globalLock); |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 1266 | if (my_data->pipelineMap.find(pipeline) == my_data->pipelineMap.end()) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 1267 | loader_platform_thread_unlock_mutex(&globalLock); |
| 1268 | return NULL; |
| 1269 | } |
| 1270 | loader_platform_thread_unlock_mutex(&globalLock); |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 1271 | return my_data->pipelineMap[pipeline]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 1272 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1273 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1274 | // Return VK_TRUE if for a given PSO, the given state enum is dynamic, else |
| 1275 | // return VK_FALSE |
| 1276 | static VkBool32 isDynamic(const PIPELINE_NODE *pPipeline, |
| 1277 | const VkDynamicState state) { |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 1278 | if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1279 | for (uint32_t i = 0; |
| 1280 | i < pPipeline->graphicsPipelineCI.pDynamicState->dynamicStateCount; |
| 1281 | i++) { |
| 1282 | if (state == |
| 1283 | pPipeline->graphicsPipelineCI.pDynamicState->pDynamicStates[i]) |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 1284 | return VK_TRUE; |
| 1285 | } |
| 1286 | } |
| 1287 | return VK_FALSE; |
| 1288 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1289 | |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1290 | // Validate state stored as flags at time of draw call |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1291 | static VkBool32 validate_draw_state_flags(layer_data *my_data, |
| 1292 | GLOBAL_CB_NODE *pCB, |
| 1293 | VkBool32 indexedDraw) { |
Courtney Goeltzenleuchter | cd2a099 | 2015-07-09 11:44:38 -0600 | [diff] [blame] | 1294 | VkBool32 result; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1295 | result = validate_status( |
| 1296 | my_data, pCB, CBSTATUS_NONE, CBSTATUS_VIEWPORT_SET, |
| 1297 | CBSTATUS_VIEWPORT_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1298 | DRAWSTATE_VIEWPORT_NOT_BOUND, |
| 1299 | "Dynamic viewport state not set for this command buffer"); |
| 1300 | result |= validate_status( |
| 1301 | my_data, pCB, CBSTATUS_NONE, CBSTATUS_SCISSOR_SET, CBSTATUS_SCISSOR_SET, |
| 1302 | VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_SCISSOR_NOT_BOUND, |
| 1303 | "Dynamic scissor state not set for this command buffer"); |
| 1304 | result |= validate_status( |
| 1305 | my_data, pCB, CBSTATUS_NONE, CBSTATUS_LINE_WIDTH_SET, |
| 1306 | CBSTATUS_LINE_WIDTH_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1307 | DRAWSTATE_LINE_WIDTH_NOT_BOUND, |
| 1308 | "Dynamic line width state not set for this command buffer"); |
| 1309 | result |= validate_status( |
| 1310 | my_data, pCB, CBSTATUS_NONE, CBSTATUS_DEPTH_BIAS_SET, |
| 1311 | CBSTATUS_DEPTH_BIAS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1312 | DRAWSTATE_DEPTH_BIAS_NOT_BOUND, |
| 1313 | "Dynamic depth bias state not set for this command buffer"); |
| 1314 | result |= validate_status( |
| 1315 | my_data, pCB, CBSTATUS_COLOR_BLEND_WRITE_ENABLE, CBSTATUS_BLEND_SET, |
| 1316 | CBSTATUS_BLEND_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1317 | DRAWSTATE_BLEND_NOT_BOUND, |
| 1318 | "Dynamic blend object state not set for this command buffer"); |
| 1319 | result |= validate_status( |
| 1320 | my_data, pCB, CBSTATUS_DEPTH_WRITE_ENABLE, CBSTATUS_DEPTH_BOUNDS_SET, |
| 1321 | CBSTATUS_DEPTH_BOUNDS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1322 | DRAWSTATE_DEPTH_BOUNDS_NOT_BOUND, |
| 1323 | "Dynamic depth bounds state not set for this command buffer"); |
| 1324 | result |= validate_status( |
| 1325 | my_data, pCB, CBSTATUS_STENCIL_TEST_ENABLE, |
| 1326 | CBSTATUS_STENCIL_READ_MASK_SET, CBSTATUS_STENCIL_READ_MASK_SET, |
| 1327 | VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_STENCIL_NOT_BOUND, |
| 1328 | "Dynamic stencil read mask state not set for this command buffer"); |
| 1329 | result |= validate_status( |
| 1330 | my_data, pCB, CBSTATUS_STENCIL_TEST_ENABLE, |
| 1331 | CBSTATUS_STENCIL_WRITE_MASK_SET, CBSTATUS_STENCIL_WRITE_MASK_SET, |
| 1332 | VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_STENCIL_NOT_BOUND, |
| 1333 | "Dynamic stencil write mask state not set for this command buffer"); |
| 1334 | result |= validate_status( |
| 1335 | my_data, pCB, CBSTATUS_STENCIL_TEST_ENABLE, |
| 1336 | CBSTATUS_STENCIL_REFERENCE_SET, CBSTATUS_STENCIL_REFERENCE_SET, |
| 1337 | VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_STENCIL_NOT_BOUND, |
| 1338 | "Dynamic stencil reference state not set for this command buffer"); |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1339 | if (indexedDraw) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1340 | result |= validate_status( |
| 1341 | my_data, pCB, CBSTATUS_NONE, CBSTATUS_INDEX_BUFFER_BOUND, |
| 1342 | CBSTATUS_INDEX_BUFFER_BOUND, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1343 | DRAWSTATE_INDEX_BUFFER_NOT_BOUND, "Index buffer object not bound " |
| 1344 | "to this command buffer when " |
| 1345 | "Indexed Draw attempted"); |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1346 | return result; |
| 1347 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1348 | |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1349 | // Verify attachment reference compatibility according to spec |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1350 | // If one array is larger, treat missing elements of shorter array as |
| 1351 | // VK_ATTACHMENT_UNUSED & other array much match this |
| 1352 | // If both AttachmentReference arrays have requested index, check their |
| 1353 | // corresponding AttachementDescriptions |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1354 | // to make sure that format and samples counts match. |
| 1355 | // If not, they are not compatible. |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1356 | static bool attachment_references_compatible( |
| 1357 | const uint32_t index, const VkAttachmentReference *pPrimary, |
| 1358 | const uint32_t primaryCount, |
| 1359 | const VkAttachmentDescription *pPrimaryAttachments, |
| 1360 | const VkAttachmentReference *pSecondary, const uint32_t secondaryCount, |
| 1361 | const VkAttachmentDescription *pSecondaryAttachments) { |
| 1362 | if (index >= |
| 1363 | primaryCount) { // Check secondary as if primary is VK_ATTACHMENT_UNUSED |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1364 | if (VK_ATTACHMENT_UNUSED != pSecondary[index].attachment) |
| 1365 | return false; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1366 | } else if (index >= secondaryCount) { // Check primary as if secondary is |
| 1367 | // VK_ATTACHMENT_UNUSED |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1368 | if (VK_ATTACHMENT_UNUSED != pPrimary[index].attachment) |
| 1369 | return false; |
| 1370 | } else { // format and sample count must match |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1371 | if ((pPrimaryAttachments[pPrimary[index].attachment].format == |
| 1372 | pSecondaryAttachments[pSecondary[index].attachment].format) && |
| 1373 | (pPrimaryAttachments[pPrimary[index].attachment].samples == |
| 1374 | pSecondaryAttachments[pSecondary[index].attachment].samples)) |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1375 | return true; |
| 1376 | } |
| 1377 | // Format and sample counts didn't match |
| 1378 | return false; |
| 1379 | } |
| 1380 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1381 | // For give primary and secondary RenderPass objects, verify that they're |
| 1382 | // compatible |
| 1383 | static bool verify_renderpass_compatibility(layer_data *my_data, |
| 1384 | const VkRenderPass primaryRP, |
| 1385 | const VkRenderPass secondaryRP, |
| 1386 | string &errorMsg) { |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1387 | stringstream errorStr; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1388 | if (my_data->renderPassMap.find(primaryRP) == |
| 1389 | my_data->renderPassMap.end()) { |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1390 | errorStr << "invalid VkRenderPass (" << primaryRP << ")"; |
| 1391 | errorMsg = errorStr.str(); |
| 1392 | return false; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1393 | } else if (my_data->renderPassMap.find(secondaryRP) == |
| 1394 | my_data->renderPassMap.end()) { |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1395 | errorStr << "invalid VkRenderPass (" << secondaryRP << ")"; |
| 1396 | errorMsg = errorStr.str(); |
| 1397 | return false; |
| 1398 | } |
| 1399 | // Trivial pass case is exact same RP |
| 1400 | if (primaryRP == secondaryRP) |
| 1401 | return true; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1402 | const VkRenderPassCreateInfo *primaryRPCI = |
| 1403 | my_data->renderPassMap[primaryRP]->pCreateInfo; |
| 1404 | const VkRenderPassCreateInfo *secondaryRPCI = |
| 1405 | my_data->renderPassMap[secondaryRP]->pCreateInfo; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1406 | if (primaryRPCI->subpassCount != secondaryRPCI->subpassCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1407 | errorStr << "RenderPass for primary cmdBuffer has " |
| 1408 | << primaryRPCI->subpassCount |
| 1409 | << " subpasses but renderPass for secondary cmdBuffer has " |
| 1410 | << secondaryRPCI->subpassCount << " subpasses."; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1411 | errorMsg = errorStr.str(); |
| 1412 | return false; |
| 1413 | } |
| 1414 | uint32_t spIndex = 0; |
| 1415 | for (spIndex = 0; spIndex < primaryRPCI->subpassCount; ++spIndex) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1416 | // For each subpass, verify that corresponding color, input, resolve & |
| 1417 | // depth/stencil attachment references are compatible |
| 1418 | uint32_t primaryColorCount = |
| 1419 | primaryRPCI->pSubpasses[spIndex].colorAttachmentCount; |
| 1420 | uint32_t secondaryColorCount = |
| 1421 | secondaryRPCI->pSubpasses[spIndex].colorAttachmentCount; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1422 | uint32_t colorMax = std::max(primaryColorCount, secondaryColorCount); |
| 1423 | for (uint32_t cIdx = 0; cIdx < colorMax; ++cIdx) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1424 | if (!attachment_references_compatible( |
| 1425 | cIdx, primaryRPCI->pSubpasses[spIndex].pColorAttachments, |
| 1426 | primaryColorCount, primaryRPCI->pAttachments, |
| 1427 | secondaryRPCI->pSubpasses[spIndex].pColorAttachments, |
| 1428 | secondaryColorCount, secondaryRPCI->pAttachments)) { |
| 1429 | errorStr << "color attachments at index " << cIdx |
| 1430 | << " of subpass index " << spIndex |
| 1431 | << " are not compatible."; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1432 | errorMsg = errorStr.str(); |
| 1433 | return false; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1434 | } else if (!attachment_references_compatible( |
| 1435 | cIdx, |
| 1436 | primaryRPCI->pSubpasses[spIndex].pResolveAttachments, |
| 1437 | primaryColorCount, primaryRPCI->pAttachments, |
| 1438 | secondaryRPCI->pSubpasses[spIndex] |
| 1439 | .pResolveAttachments, |
| 1440 | secondaryColorCount, secondaryRPCI->pAttachments)) { |
| 1441 | errorStr << "resolve attachments at index " << cIdx |
| 1442 | << " of subpass index " << spIndex |
| 1443 | << " are not compatible."; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1444 | errorMsg = errorStr.str(); |
| 1445 | return false; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1446 | } else if (!attachment_references_compatible( |
| 1447 | cIdx, primaryRPCI->pSubpasses[spIndex] |
| 1448 | .pDepthStencilAttachment, |
| 1449 | primaryColorCount, primaryRPCI->pAttachments, |
| 1450 | secondaryRPCI->pSubpasses[spIndex] |
| 1451 | .pDepthStencilAttachment, |
| 1452 | secondaryColorCount, secondaryRPCI->pAttachments)) { |
| 1453 | errorStr << "depth/stencil attachments at index " << cIdx |
| 1454 | << " of subpass index " << spIndex |
| 1455 | << " are not compatible."; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1456 | errorMsg = errorStr.str(); |
| 1457 | return false; |
| 1458 | } |
| 1459 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1460 | uint32_t primaryInputCount = |
| 1461 | primaryRPCI->pSubpasses[spIndex].inputAttachmentCount; |
| 1462 | uint32_t secondaryInputCount = |
| 1463 | secondaryRPCI->pSubpasses[spIndex].inputAttachmentCount; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1464 | uint32_t inputMax = std::max(primaryInputCount, secondaryInputCount); |
| 1465 | for (uint32_t i = 0; i < inputMax; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1466 | if (!attachment_references_compatible( |
| 1467 | i, primaryRPCI->pSubpasses[spIndex].pInputAttachments, |
| 1468 | primaryColorCount, primaryRPCI->pAttachments, |
| 1469 | secondaryRPCI->pSubpasses[spIndex].pInputAttachments, |
| 1470 | secondaryColorCount, secondaryRPCI->pAttachments)) { |
| 1471 | errorStr << "input attachments at index " << i |
| 1472 | << " of subpass index " << spIndex |
| 1473 | << " are not compatible."; |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 1474 | errorMsg = errorStr.str(); |
| 1475 | return false; |
| 1476 | } |
| 1477 | } |
| 1478 | } |
| 1479 | return true; |
| 1480 | } |
| 1481 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1482 | // For give SET_NODE, verify that its Set is compatible w/ the setLayout |
| 1483 | // corresponding to pipelineLayout[layoutIndex] |
| 1484 | static bool verify_set_layout_compatibility(layer_data *my_data, |
| 1485 | const SET_NODE *pSet, |
| 1486 | const VkPipelineLayout layout, |
| 1487 | const uint32_t layoutIndex, |
| 1488 | string &errorMsg) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 1489 | stringstream errorStr; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1490 | if (my_data->pipelineLayoutMap.find(layout) == |
| 1491 | my_data->pipelineLayoutMap.end()) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 1492 | errorStr << "invalid VkPipelineLayout (" << layout << ")"; |
| 1493 | errorMsg = errorStr.str(); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1494 | return false; |
| 1495 | } |
| 1496 | PIPELINE_LAYOUT_NODE pl = my_data->pipelineLayoutMap[layout]; |
| 1497 | if (layoutIndex >= pl.descriptorSetLayouts.size()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1498 | errorStr << "VkPipelineLayout (" << layout << ") only contains " |
| 1499 | << pl.descriptorSetLayouts.size() |
| 1500 | << " setLayouts corresponding to sets 0-" |
| 1501 | << pl.descriptorSetLayouts.size() - 1 |
| 1502 | << ", but you're attempting to bind set to index " |
| 1503 | << layoutIndex; |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 1504 | errorMsg = errorStr.str(); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1505 | return false; |
| 1506 | } |
| 1507 | // Get the specific setLayout from PipelineLayout that overlaps this set |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1508 | LAYOUT_NODE *pLayoutNode = |
| 1509 | my_data->descriptorSetLayoutMap[pl.descriptorSetLayouts[layoutIndex]]; |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1510 | if (pLayoutNode->layout == pSet->pLayout->layout) { // trivial pass case |
| 1511 | return true; |
| 1512 | } |
Courtney Goeltzenleuchter | 5123947 | 2015-12-16 16:06:06 -0700 | [diff] [blame] | 1513 | size_t descriptorCount = pLayoutNode->descriptorTypes.size(); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1514 | if (descriptorCount != pSet->pLayout->descriptorTypes.size()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1515 | errorStr << "setLayout " << layoutIndex << " from pipelineLayout " |
| 1516 | << layout << " has " << descriptorCount |
| 1517 | << " descriptors, but corresponding set being bound has " |
| 1518 | << pSet->pLayout->descriptorTypes.size() << " descriptors."; |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 1519 | errorMsg = errorStr.str(); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1520 | return false; // trivial fail case |
| 1521 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1522 | // Now need to check set against corresponding pipelineLayout to verify |
| 1523 | // compatibility |
| 1524 | for (size_t i = 0; i < descriptorCount; ++i) { |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1525 | // Need to verify that layouts are identically defined |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1526 | // TODO : Is below sufficient? Making sure that types & stageFlags |
| 1527 | // match per descriptor |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1528 | // do we also need to check immutable samplers? |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1529 | if (pLayoutNode->descriptorTypes[i] != |
| 1530 | pSet->pLayout->descriptorTypes[i]) { |
| 1531 | errorStr << "descriptor " << i |
| 1532 | << " for descriptorSet being bound is type '" |
| 1533 | << string_VkDescriptorType( |
| 1534 | pSet->pLayout->descriptorTypes[i]) |
| 1535 | << "' but corresponding descriptor from pipelineLayout is " |
| 1536 | "type '" |
| 1537 | << string_VkDescriptorType(pLayoutNode->descriptorTypes[i]) |
| 1538 | << "'"; |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 1539 | errorMsg = errorStr.str(); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1540 | return false; |
| 1541 | } |
| 1542 | if (pLayoutNode->stageFlags[i] != pSet->pLayout->stageFlags[i]) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1543 | errorStr << "stageFlags " << i |
| 1544 | << " for descriptorSet being bound is " |
| 1545 | << pSet->pLayout->stageFlags[i] |
| 1546 | << "' but corresponding descriptor from pipelineLayout " |
| 1547 | "has stageFlags " << pLayoutNode->stageFlags[i]; |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 1548 | errorMsg = errorStr.str(); |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1549 | return false; |
| 1550 | } |
| 1551 | } |
| 1552 | return true; |
| 1553 | } |
| 1554 | |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 1555 | // Validate that the shaders used by the given pipeline |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1556 | // As a side effect this function also records the sets that are actually used |
| 1557 | // by the pipeline |
| 1558 | static VkBool32 validate_pipeline_shaders(layer_data *my_data, VkDevice dev, |
| 1559 | PIPELINE_NODE *pPipeline) { |
| 1560 | VkGraphicsPipelineCreateInfo const *pCreateInfo = |
| 1561 | &pPipeline->graphicsPipelineCI; |
| 1562 | /* We seem to allow pipeline stages to be specified out of order, so collect |
| 1563 | * and identify them |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1564 | * before trying to do anything more: */ |
| 1565 | int vertex_stage = get_shader_stage_id(VK_SHADER_STAGE_VERTEX_BIT); |
| 1566 | int geometry_stage = get_shader_stage_id(VK_SHADER_STAGE_GEOMETRY_BIT); |
| 1567 | int fragment_stage = get_shader_stage_id(VK_SHADER_STAGE_FRAGMENT_BIT); |
| 1568 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1569 | shader_module **shaders = |
| 1570 | new shader_module *[fragment_stage + 1]; /* exclude CS */ |
| 1571 | memset(shaders, 0, sizeof(shader_module *) * (fragment_stage + 1)); |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1572 | RENDER_PASS_NODE const *rp = 0; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1573 | VkPipelineVertexInputStateCreateInfo const *vi = 0; |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 1574 | VkBool32 pass = VK_TRUE; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1575 | |
| 1576 | for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1577 | VkPipelineShaderStageCreateInfo const *pStage = |
| 1578 | &pCreateInfo->pStages[i]; |
| 1579 | if (pStage->sType == |
| 1580 | VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1581 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1582 | if ((pStage->stage & |
| 1583 | (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT | |
| 1584 | VK_SHADER_STAGE_FRAGMENT_BIT | |
| 1585 | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | |
| 1586 | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) == 0) { |
| 1587 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 1588 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0, |
| 1589 | __LINE__, SHADER_CHECKER_UNKNOWN_STAGE, "SC", |
| 1590 | "Unknown shader stage %d", pStage->stage)) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 1591 | pass = VK_FALSE; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1592 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1593 | } else { |
| 1594 | shader_module *module = |
| 1595 | my_data->shaderModuleMap[pStage->module]; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1596 | shaders[get_shader_stage_id(pStage->stage)] = module; |
| 1597 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1598 | /* validate descriptor set layout against what the spirv module |
| 1599 | * actually uses */ |
| 1600 | std::map<std::pair<unsigned, unsigned>, interface_var> |
| 1601 | descriptor_uses; |
| 1602 | collect_interface_by_descriptor_slot(my_data, dev, module, |
| 1603 | spv::StorageClassUniform, |
| 1604 | descriptor_uses); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1605 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1606 | auto layouts = |
| 1607 | pCreateInfo->layout != VK_NULL_HANDLE |
| 1608 | ? &(my_data->pipelineLayoutMap[pCreateInfo->layout] |
| 1609 | .descriptorSetLayouts) |
| 1610 | : nullptr; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1611 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1612 | for (auto it = descriptor_uses.begin(); |
| 1613 | it != descriptor_uses.end(); it++) { |
| 1614 | // As a side-effect of this function, capture which sets are |
| 1615 | // used by the pipeline |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 1616 | pPipeline->active_sets.insert(it->first.first); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1617 | |
| 1618 | /* find the matching binding */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1619 | auto found = |
| 1620 | has_descriptor_binding(my_data, layouts, it->first); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1621 | |
| 1622 | if (!found) { |
| 1623 | char type_name[1024]; |
| 1624 | describe_type(type_name, module, it->second.type_id); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1625 | if (log_msg(my_data->report_data, |
| 1626 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1627 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, |
| 1628 | /*dev*/ 0, __LINE__, |
| 1629 | SHADER_CHECKER_MISSING_DESCRIPTOR, "SC", |
| 1630 | "Shader uses descriptor slot %u.%u (used " |
| 1631 | "as type `%s`) but not declared in " |
| 1632 | "pipeline layout", |
| 1633 | it->first.first, it->first.second, |
| 1634 | type_name)) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 1635 | pass = VK_FALSE; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1636 | } |
| 1637 | } |
| 1638 | } |
| 1639 | } |
| 1640 | } |
| 1641 | } |
| 1642 | |
| 1643 | if (pCreateInfo->renderPass != VK_NULL_HANDLE) |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1644 | rp = my_data->renderPassMap[pCreateInfo->renderPass]; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1645 | |
| 1646 | vi = pCreateInfo->pVertexInputState; |
| 1647 | |
| 1648 | if (vi) { |
| 1649 | pass = validate_vi_consistency(my_data, dev, vi) && pass; |
| 1650 | } |
| 1651 | |
| 1652 | if (shaders[vertex_stage]) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1653 | pass = validate_vi_against_vs_inputs(my_data, dev, vi, |
| 1654 | shaders[vertex_stage]) && |
| 1655 | pass; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1656 | } |
| 1657 | |
| 1658 | /* TODO: enforce rules about present combinations of shaders */ |
| 1659 | int producer = get_shader_stage_id(VK_SHADER_STAGE_VERTEX_BIT); |
| 1660 | int consumer = get_shader_stage_id(VK_SHADER_STAGE_GEOMETRY_BIT); |
| 1661 | |
| 1662 | while (!shaders[producer] && producer != fragment_stage) { |
| 1663 | producer++; |
| 1664 | consumer++; |
| 1665 | } |
| 1666 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1667 | for (; producer != fragment_stage && consumer <= fragment_stage; |
| 1668 | consumer++) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1669 | assert(shaders[producer]); |
| 1670 | if (shaders[consumer]) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1671 | pass = validate_interface_between_stages( |
| 1672 | my_data, dev, shaders[producer], |
| 1673 | shader_stage_attribs[producer].name, shaders[consumer], |
| 1674 | shader_stage_attribs[consumer].name, |
| 1675 | shader_stage_attribs[consumer].arrayed_input) && |
| 1676 | pass; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1677 | |
| 1678 | producer = consumer; |
| 1679 | } |
| 1680 | } |
| 1681 | |
| 1682 | if (shaders[fragment_stage] && rp) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1683 | pass = validate_fs_outputs_against_render_pass( |
| 1684 | my_data, dev, shaders[fragment_stage], rp, |
| 1685 | pCreateInfo->subpass) && |
| 1686 | pass; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1687 | } |
| 1688 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1689 | delete[] shaders; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 1690 | |
| 1691 | return pass; |
| 1692 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1693 | |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1694 | // Return Set node ptr for specified set or else NULL |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1695 | static SET_NODE *getSetNode(layer_data *my_data, const VkDescriptorSet set) { |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1696 | loader_platform_thread_lock_mutex(&globalLock); |
| 1697 | if (my_data->setMap.find(set) == my_data->setMap.end()) { |
| 1698 | loader_platform_thread_unlock_mutex(&globalLock); |
| 1699 | return NULL; |
| 1700 | } |
| 1701 | loader_platform_thread_unlock_mutex(&globalLock); |
| 1702 | return my_data->setMap[set]; |
| 1703 | } |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1704 | // For the given command buffer, verify that for each set set in activeSetNodes |
| 1705 | // that any dynamic descriptor in that set has a valid dynamic offset bound. |
| 1706 | // To be valid, the dynamic offset combined with the offet and range from its |
| 1707 | // descriptor update must not overflow the size of its buffer being updated |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1708 | static VkBool32 |
| 1709 | validate_dynamic_offsets(layer_data *my_data, const GLOBAL_CB_NODE *pCB, |
| 1710 | const vector<SET_NODE *> activeSetNodes) { |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1711 | VkBool32 result = VK_FALSE; |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1712 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1713 | VkWriteDescriptorSet *pWDS = NULL; |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1714 | uint32_t dynOffsetIndex = 0; |
| 1715 | VkDeviceSize bufferSize = 0; |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1716 | for (auto set_node : activeSetNodes) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1717 | for (uint32_t i = 0; i < set_node->descriptorCount; ++i) { |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1718 | switch (set_node->ppDescriptors[i]->sType) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1719 | case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: |
| 1720 | pWDS = (VkWriteDescriptorSet *)set_node->ppDescriptors[i]; |
| 1721 | if ((pWDS->descriptorType == |
| 1722 | VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || |
| 1723 | (pWDS->descriptorType == |
| 1724 | VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { |
| 1725 | for (uint32_t j = 0; j < pWDS->descriptorCount; ++j) { |
| 1726 | bufferSize = |
| 1727 | my_data->bufferMap[pWDS->pBufferInfo[j].buffer] |
| 1728 | .create_info->size; |
| 1729 | if ((pCB->dynamicOffsets[dynOffsetIndex] + |
| 1730 | pWDS->pBufferInfo[j].offset + |
| 1731 | pWDS->pBufferInfo[j].range) > bufferSize) { |
| 1732 | result |= log_msg( |
| 1733 | my_data->report_data, |
| 1734 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1735 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 1736 | (uint64_t)set_node->set, __LINE__, |
| 1737 | DRAWSTATE_DYNAMIC_OFFSET_OVERFLOW, "DS", |
| 1738 | "VkDescriptorSet (%#" PRIxLEAST64 |
| 1739 | ") bound as set #%u has dynamic offset %u. " |
| 1740 | "Combined with offet %#" PRIxLEAST64 |
| 1741 | " and range %#" PRIxLEAST64 |
| 1742 | " from its update, this oversteps its buffer " |
| 1743 | "(%#" PRIxLEAST64 |
| 1744 | ") which has a size of %#" PRIxLEAST64 ".", |
| 1745 | (uint64_t)set_node->set, i, |
| 1746 | pCB->dynamicOffsets[dynOffsetIndex], |
| 1747 | pWDS->pBufferInfo[j].offset, |
| 1748 | pWDS->pBufferInfo[j].range, |
| 1749 | (uint64_t)pWDS->pBufferInfo[j].buffer, |
| 1750 | bufferSize); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1751 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1752 | dynOffsetIndex++; |
| 1753 | i += j; // Advance i to end of this set of descriptors |
| 1754 | // (++i at end of for loop will move 1 index |
| 1755 | // past last of these descriptors) |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1756 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1757 | } |
| 1758 | break; |
| 1759 | default: // Currently only shadowing Write update nodes so shouldn't |
| 1760 | // get here |
| 1761 | assert(0); |
| 1762 | continue; |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1763 | } |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 1764 | } |
| 1765 | } |
| 1766 | return result; |
| 1767 | } |
| 1768 | |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1769 | // Validate overall state at the time of a draw call |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1770 | static VkBool32 validate_draw_state(layer_data *my_data, GLOBAL_CB_NODE *pCB, |
| 1771 | VkBool32 indexedDraw) { |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1772 | // First check flag states |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 1773 | VkBool32 result = validate_draw_state_flags(my_data, pCB, indexedDraw); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1774 | PIPELINE_NODE *pPipe = getPipeline(my_data, pCB->lastBoundPipeline); |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1775 | // Now complete other state checks |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1776 | // TODO : Currently only performing next check if *something* was bound |
| 1777 | // (non-zero last bound) |
| 1778 | // There is probably a better way to gate when this check happens, and to |
| 1779 | // know if something *should* have been bound |
| 1780 | // We should have that check separately and then gate this check based on |
| 1781 | // that check |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1782 | if (pPipe) { |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1783 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1784 | if (pCB->lastBoundPipelineLayout) { |
| 1785 | string errorString; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1786 | // Need a vector (vs. std::set) of active Sets for dynamicOffset |
| 1787 | // validation in case same set bound w/ different offsets |
| 1788 | vector<SET_NODE *> activeSetNodes; |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1789 | for (auto setIndex : pPipe->active_sets) { |
| 1790 | // If valid set is not bound throw an error |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1791 | if ((pCB->boundDescriptorSets.size() <= setIndex) || |
| 1792 | (!pCB->boundDescriptorSets[setIndex])) { |
| 1793 | result |= log_msg( |
| 1794 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1795 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1796 | DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, "DS", |
| 1797 | "VkPipeline %#" PRIxLEAST64 |
| 1798 | " uses set #%u but that set is not bound.", |
| 1799 | (uint64_t)pPipe->pipeline, setIndex); |
| 1800 | } else if (!verify_set_layout_compatibility( |
| 1801 | my_data, |
| 1802 | my_data |
| 1803 | ->setMap[pCB->boundDescriptorSets[setIndex]], |
| 1804 | pPipe->graphicsPipelineCI.layout, setIndex, |
| 1805 | errorString)) { |
| 1806 | // Set is bound but not compatible w/ overlapping |
| 1807 | // pipelineLayout from PSO |
| 1808 | VkDescriptorSet setHandle = |
| 1809 | my_data->setMap[pCB->boundDescriptorSets[setIndex]] |
| 1810 | ->set; |
| 1811 | result |= log_msg( |
| 1812 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1813 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 1814 | (uint64_t)setHandle, __LINE__, |
| 1815 | DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS", |
| 1816 | "VkDescriptorSet (%#" PRIxLEAST64 |
| 1817 | ") bound as set #%u is not compatible with overlapping " |
| 1818 | "VkPipelineLayout %#" PRIxLEAST64 " due to: %s", |
| 1819 | (uint64_t)setHandle, setIndex, |
| 1820 | (uint64_t)pPipe->graphicsPipelineCI.layout, |
| 1821 | errorString.c_str()); |
| 1822 | } else { // Valid set is bound and layout compatible, validate |
| 1823 | // that it's updated and verify any dynamic offsets |
Tobin Ehlis | 43c39c0 | 2016-01-11 13:18:40 -0700 | [diff] [blame] | 1824 | // Pull the set node |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1825 | SET_NODE *pSet = |
| 1826 | my_data->setMap[pCB->boundDescriptorSets[setIndex]]; |
| 1827 | // Save vector of all active sets to verify dynamicOffsets |
| 1828 | // below |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1829 | activeSetNodes.push_back(pSet); |
Tobin Ehlis | 43c39c0 | 2016-01-11 13:18:40 -0700 | [diff] [blame] | 1830 | // Make sure set has been updated |
| 1831 | if (!pSet->pUpdateStructs) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1832 | result |= log_msg( |
| 1833 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1834 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 1835 | (uint64_t)pSet->set, __LINE__, |
| 1836 | DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS", |
| 1837 | "DS %#" PRIxLEAST64 " bound but it was never " |
| 1838 | "updated. It is now being used " |
| 1839 | "to draw so this will result " |
| 1840 | "in undefined behavior.", |
| 1841 | (uint64_t)pSet->set); |
Tobin Ehlis | 43c39c0 | 2016-01-11 13:18:40 -0700 | [diff] [blame] | 1842 | } |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1843 | } |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 1844 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1845 | // For each dynamic descriptor, make sure dynamic offset doesn't |
| 1846 | // overstep buffer |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1847 | if (!pCB->dynamicOffsets.empty()) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1848 | result |= |
| 1849 | validate_dynamic_offsets(my_data, pCB, activeSetNodes); |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 1850 | } |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1851 | // Verify Vtx binding |
| 1852 | if (pPipe->vtxBindingCount > 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1853 | VkPipelineVertexInputStateCreateInfo *vtxInCI = |
| 1854 | &pPipe->vertexInputCI; |
| 1855 | for (uint32_t i = 0; i < vtxInCI->vertexBindingDescriptionCount; |
| 1856 | i++) { |
| 1857 | if ((pCB->currentDrawData.buffers.size() < (i + 1)) || |
| 1858 | (pCB->currentDrawData.buffers[i] == VK_NULL_HANDLE)) { |
| 1859 | result |= log_msg( |
| 1860 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1861 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1862 | DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", |
| 1863 | "The Pipeline State Object (%#" PRIxLEAST64 |
| 1864 | ") expects that this Command Buffer's vertex binding " |
| 1865 | "Index %d should be set via vkCmdBindVertexBuffers.", |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1866 | (uint64_t)pCB->lastBoundPipeline, i); |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1867 | } |
| 1868 | } |
| 1869 | } else { |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 1870 | if (!pCB->currentDrawData.buffers.empty()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1871 | result |= log_msg( |
| 1872 | my_data->report_data, VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 1873 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1874 | DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", |
| 1875 | "Vertex buffers are bound to command buffer (%#" PRIxLEAST64 |
| 1876 | ") but no vertex buffers are attached to this Pipeline " |
| 1877 | "State Object (%#" PRIxLEAST64 ").", |
| 1878 | (uint64_t)pCB->commandBuffer, |
| 1879 | (uint64_t)pCB->lastBoundPipeline); |
Tobin Ehlis | f7bf450 | 2015-09-09 15:12:35 -0600 | [diff] [blame] | 1880 | } |
| 1881 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1882 | // If Viewport or scissors are dynamic, verify that dynamic count |
| 1883 | // matches PSO count |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1884 | VkBool32 dynViewport = isDynamic(pPipe, VK_DYNAMIC_STATE_VIEWPORT); |
| 1885 | VkBool32 dynScissor = isDynamic(pPipe, VK_DYNAMIC_STATE_SCISSOR); |
| 1886 | if (dynViewport) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1887 | if (pCB->viewports.size() != |
| 1888 | pPipe->graphicsPipelineCI.pViewportState->viewportCount) { |
| 1889 | result |= log_msg( |
| 1890 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1891 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1892 | DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", |
| 1893 | "Dynamic viewportCount from vkCmdSetViewport() " |
| 1894 | "is " PRINTF_SIZE_T_SPECIFIER |
| 1895 | ", but PSO viewportCount is %u. These counts must match.", |
| 1896 | pCB->viewports.size(), |
| 1897 | pPipe->graphicsPipelineCI.pViewportState->viewportCount); |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1898 | } |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 1899 | } |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1900 | if (dynScissor) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1901 | if (pCB->scissors.size() != |
| 1902 | pPipe->graphicsPipelineCI.pViewportState->scissorCount) { |
| 1903 | result |= log_msg( |
| 1904 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1905 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1906 | DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", |
| 1907 | "Dynamic scissorCount from vkCmdSetScissor() " |
| 1908 | "is " PRINTF_SIZE_T_SPECIFIER |
| 1909 | ", but PSO scissorCount is %u. These counts must match.", |
| 1910 | pCB->scissors.size(), |
| 1911 | pPipe->graphicsPipelineCI.pViewportState->scissorCount); |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 1912 | } |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 1913 | } |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 1914 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 1915 | } |
Tobin Ehlis | 429b91d | 2015-06-22 17:20:50 -0600 | [diff] [blame] | 1916 | return result; |
| 1917 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 1918 | |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1919 | // Verify that create state for a pipeline is valid |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1920 | static VkBool32 verifyPipelineCreateState(layer_data *my_data, |
| 1921 | const VkDevice device, |
| 1922 | PIPELINE_NODE *pPipeline) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 1923 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | 2fd2d03 | 2015-12-16 14:25:22 -0700 | [diff] [blame] | 1924 | |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 1925 | if (!validate_pipeline_shaders(my_data, device, pPipeline)) { |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 1926 | skipCall = VK_TRUE; |
| 1927 | } |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1928 | // VS is required |
| 1929 | if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1930 | skipCall |= |
| 1931 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1932 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1933 | DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", |
| 1934 | "Invalid Pipeline CreateInfo State: Vtx Shader required"); |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1935 | } |
| 1936 | // Either both or neither TC/TE shaders should be defined |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1937 | if (((pPipeline->active_shaders & |
| 1938 | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) == 0) != |
| 1939 | ((pPipeline->active_shaders & |
| 1940 | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) == 0)) { |
| 1941 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1942 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1943 | DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", |
| 1944 | "Invalid Pipeline CreateInfo State: TE and TC " |
| 1945 | "shaders must be included or excluded as a pair"); |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1946 | } |
| 1947 | // Compute shaders should be specified independent of Gfx shaders |
| 1948 | if ((pPipeline->active_shaders & VK_SHADER_STAGE_COMPUTE_BIT) && |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1949 | (pPipeline->active_shaders & |
| 1950 | (VK_SHADER_STAGE_VERTEX_BIT | |
| 1951 | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | |
| 1952 | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | |
| 1953 | VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT))) { |
| 1954 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1955 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1956 | DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", |
| 1957 | "Invalid Pipeline CreateInfo State: Do not specify " |
| 1958 | "Compute Shader for Gfx Pipeline"); |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1959 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1960 | // VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology is only valid for |
| 1961 | // tessellation pipelines. |
| 1962 | // Mismatching primitive topology and tessellation fails graphics pipeline |
| 1963 | // creation. |
| 1964 | if (pPipeline->active_shaders & |
| 1965 | (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | |
| 1966 | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) && |
Chia-I Wu | 515eb8f | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 1967 | (pPipeline->iaStateCI.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1968 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1969 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1970 | DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", |
| 1971 | "Invalid Pipeline CreateInfo State: " |
| 1972 | "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST must be set as " |
| 1973 | "IA topology for tessellation pipelines"); |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1974 | } |
Chia-I Wu | 515eb8f | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 1975 | if (pPipeline->iaStateCI.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1976 | if (~pPipeline->active_shaders & |
| 1977 | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) { |
| 1978 | skipCall |= |
| 1979 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1980 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1981 | DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", |
| 1982 | "Invalid Pipeline CreateInfo State: " |
| 1983 | "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology " |
| 1984 | "is only valid for tessellation pipelines"); |
Tobin Ehlis | 912df02 | 2015-09-17 08:46:18 -0600 | [diff] [blame] | 1985 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1986 | if (!pPipeline->tessStateCI.patchControlPoints || |
| 1987 | (pPipeline->tessStateCI.patchControlPoints > 32)) { |
| 1988 | skipCall |= |
| 1989 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 1990 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 1991 | DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", |
| 1992 | "Invalid Pipeline CreateInfo State: " |
| 1993 | "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology " |
| 1994 | "used with patchControlPoints value %u." |
| 1995 | " patchControlPoints should be >0 and <=32.", |
| 1996 | pPipeline->tessStateCI.patchControlPoints); |
Tobin Ehlis | 912df02 | 2015-09-17 08:46:18 -0600 | [diff] [blame] | 1997 | } |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 1998 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 1999 | // Viewport state must be included and viewport and scissor counts should |
| 2000 | // always match |
| 2001 | // NOTE : Even if these are flagged as dynamic, counts need to be set |
| 2002 | // correctly for shader compiler |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 2003 | if (!pPipeline->graphicsPipelineCI.pViewportState) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2004 | skipCall |= |
| 2005 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2006 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2007 | DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", |
| 2008 | "Gfx Pipeline pViewportState is null. Even if viewport and " |
| 2009 | "scissors are dynamic PSO must include viewportCount and " |
| 2010 | "scissorCount in pViewportState."); |
| 2011 | } else if (pPipeline->graphicsPipelineCI.pViewportState->scissorCount != |
| 2012 | pPipeline->graphicsPipelineCI.pViewportState->viewportCount) { |
| 2013 | skipCall |= log_msg( |
| 2014 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2015 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2016 | DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", |
| 2017 | "Gfx Pipeline viewport count (%u) must match scissor count (%u).", |
| 2018 | pPipeline->vpStateCI.viewportCount, |
| 2019 | pPipeline->vpStateCI.scissorCount); |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 2020 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2021 | // If viewport or scissor are not dynamic, then verify that data is |
| 2022 | // appropriate for count |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 2023 | VkBool32 dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT); |
| 2024 | VkBool32 dynScissor = isDynamic(pPipeline, VK_DYNAMIC_STATE_SCISSOR); |
| 2025 | if (!dynViewport) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2026 | if (pPipeline->graphicsPipelineCI.pViewportState->viewportCount && |
| 2027 | !pPipeline->graphicsPipelineCI.pViewportState->pViewports) { |
| 2028 | skipCall |= log_msg( |
| 2029 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2030 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2031 | DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", |
| 2032 | "Gfx Pipeline viewportCount is %u, but pViewports is NULL. " |
| 2033 | "For non-zero viewportCount, you must either include " |
| 2034 | "pViewports data, or include viewport in pDynamicState and " |
| 2035 | "set it with vkCmdSetViewport().", |
| 2036 | pPipeline->graphicsPipelineCI.pViewportState |
| 2037 | ->viewportCount); |
Tobin Ehlis | e68360f | 2015-10-01 11:15:13 -0600 | [diff] [blame] | 2038 | } |
| 2039 | } |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 2040 | if (!dynScissor) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2041 | if (pPipeline->graphicsPipelineCI.pViewportState->scissorCount && |
| 2042 | !pPipeline->graphicsPipelineCI.pViewportState->pScissors) { |
| 2043 | skipCall |= log_msg( |
| 2044 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2045 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2046 | DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", |
| 2047 | "Gfx Pipeline scissorCount is %u, but pScissors is NULL. " |
| 2048 | "For non-zero scissorCount, you must either include " |
| 2049 | "pScissors data, or include scissor in pDynamicState and " |
| 2050 | "set it with vkCmdSetScissor().", |
| 2051 | pPipeline->graphicsPipelineCI.pViewportState->scissorCount); |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 2052 | } |
Tobin Ehlis | e68360f | 2015-10-01 11:15:13 -0600 | [diff] [blame] | 2053 | } |
| 2054 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2055 | return skipCall; |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 2056 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2057 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2058 | // Init the pipeline mapping info based on pipeline create info LL tree |
| 2059 | // Threading note : Calls to this function should wrapped in mutex |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 2060 | // TODO : this should really just be in the constructor for PIPELINE_NODE |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2061 | static PIPELINE_NODE * |
| 2062 | initGraphicsPipeline(layer_data *dev_data, |
| 2063 | const VkGraphicsPipelineCreateInfo *pCreateInfo, |
| 2064 | PIPELINE_NODE *pBasePipeline) { |
| 2065 | PIPELINE_NODE *pPipeline = new PIPELINE_NODE; |
Mark Lobodzinski | c44baa5 | 2015-12-11 11:56:07 -0700 | [diff] [blame] | 2066 | |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 2067 | if (pBasePipeline) { |
Mark Lobodzinski | c44baa5 | 2015-12-11 11:56:07 -0700 | [diff] [blame] | 2068 | *pPipeline = *pBasePipeline; |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 2069 | } |
Mark Lobodzinski | c44baa5 | 2015-12-11 11:56:07 -0700 | [diff] [blame] | 2070 | |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2071 | // First init create info |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2072 | memcpy(&pPipeline->graphicsPipelineCI, pCreateInfo, |
| 2073 | sizeof(VkGraphicsPipelineCreateInfo)); |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2074 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2075 | size_t bufferSize = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2076 | const VkPipelineVertexInputStateCreateInfo *pVICI = NULL; |
| 2077 | const VkPipelineColorBlendStateCreateInfo *pCBCI = NULL; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2078 | |
| 2079 | for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2080 | const VkPipelineShaderStageCreateInfo *pPSSCI = |
| 2081 | &pCreateInfo->pStages[i]; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2082 | |
Chia-I Wu | 28e0691 | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2083 | switch (pPSSCI->stage) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2084 | case VK_SHADER_STAGE_VERTEX_BIT: |
| 2085 | memcpy(&pPipeline->vsCI, pPSSCI, |
| 2086 | sizeof(VkPipelineShaderStageCreateInfo)); |
| 2087 | pPipeline->active_shaders |= VK_SHADER_STAGE_VERTEX_BIT; |
| 2088 | break; |
| 2089 | case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: |
| 2090 | memcpy(&pPipeline->tcsCI, pPSSCI, |
| 2091 | sizeof(VkPipelineShaderStageCreateInfo)); |
| 2092 | pPipeline->active_shaders |= |
| 2093 | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; |
| 2094 | break; |
| 2095 | case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: |
| 2096 | memcpy(&pPipeline->tesCI, pPSSCI, |
| 2097 | sizeof(VkPipelineShaderStageCreateInfo)); |
| 2098 | pPipeline->active_shaders |= |
| 2099 | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; |
| 2100 | break; |
| 2101 | case VK_SHADER_STAGE_GEOMETRY_BIT: |
| 2102 | memcpy(&pPipeline->gsCI, pPSSCI, |
| 2103 | sizeof(VkPipelineShaderStageCreateInfo)); |
| 2104 | pPipeline->active_shaders |= VK_SHADER_STAGE_GEOMETRY_BIT; |
| 2105 | break; |
| 2106 | case VK_SHADER_STAGE_FRAGMENT_BIT: |
| 2107 | memcpy(&pPipeline->fsCI, pPSSCI, |
| 2108 | sizeof(VkPipelineShaderStageCreateInfo)); |
| 2109 | pPipeline->active_shaders |= VK_SHADER_STAGE_FRAGMENT_BIT; |
| 2110 | break; |
| 2111 | case VK_SHADER_STAGE_COMPUTE_BIT: |
| 2112 | // TODO : Flag error, CS is specified through |
| 2113 | // VkComputePipelineCreateInfo |
| 2114 | pPipeline->active_shaders |= VK_SHADER_STAGE_COMPUTE_BIT; |
| 2115 | break; |
| 2116 | default: |
| 2117 | // TODO : Flag error |
| 2118 | break; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2119 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2120 | } |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2121 | // Copy over GraphicsPipelineCreateInfo structure embedded pointers |
| 2122 | if (pCreateInfo->stageCount != 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2123 | pPipeline->graphicsPipelineCI.pStages = |
| 2124 | new VkPipelineShaderStageCreateInfo[pCreateInfo->stageCount]; |
| 2125 | bufferSize = |
| 2126 | pCreateInfo->stageCount * sizeof(VkPipelineShaderStageCreateInfo); |
| 2127 | memcpy((void *)pPipeline->graphicsPipelineCI.pStages, |
| 2128 | pCreateInfo->pStages, bufferSize); |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2129 | } |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2130 | if (pCreateInfo->pVertexInputState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2131 | memcpy((void *)&pPipeline->vertexInputCI, |
| 2132 | pCreateInfo->pVertexInputState, |
| 2133 | sizeof(VkPipelineVertexInputStateCreateInfo)); |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2134 | // Copy embedded ptrs |
| 2135 | pVICI = pCreateInfo->pVertexInputState; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 2136 | pPipeline->vtxBindingCount = pVICI->vertexBindingDescriptionCount; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2137 | if (pPipeline->vtxBindingCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2138 | pPipeline->pVertexBindingDescriptions = |
| 2139 | new VkVertexInputBindingDescription[pPipeline->vtxBindingCount]; |
| 2140 | bufferSize = pPipeline->vtxBindingCount * |
| 2141 | sizeof(VkVertexInputBindingDescription); |
| 2142 | memcpy((void *)pPipeline->pVertexBindingDescriptions, |
| 2143 | pVICI->pVertexBindingDescriptions, bufferSize); |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2144 | } |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 2145 | pPipeline->vtxAttributeCount = pVICI->vertexAttributeDescriptionCount; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2146 | if (pPipeline->vtxAttributeCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2147 | pPipeline->pVertexAttributeDescriptions = |
| 2148 | new VkVertexInputAttributeDescription[pPipeline |
| 2149 | ->vtxAttributeCount]; |
| 2150 | bufferSize = pPipeline->vtxAttributeCount * |
| 2151 | sizeof(VkVertexInputAttributeDescription); |
| 2152 | memcpy((void *)pPipeline->pVertexAttributeDescriptions, |
| 2153 | pVICI->pVertexAttributeDescriptions, bufferSize); |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2154 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2155 | pPipeline->graphicsPipelineCI.pVertexInputState = |
| 2156 | &pPipeline->vertexInputCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2157 | } |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2158 | if (pCreateInfo->pInputAssemblyState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2159 | memcpy((void *)&pPipeline->iaStateCI, pCreateInfo->pInputAssemblyState, |
| 2160 | sizeof(VkPipelineInputAssemblyStateCreateInfo)); |
| 2161 | pPipeline->graphicsPipelineCI.pInputAssemblyState = |
| 2162 | &pPipeline->iaStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2163 | } |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2164 | if (pCreateInfo->pTessellationState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2165 | memcpy((void *)&pPipeline->tessStateCI, pCreateInfo->pTessellationState, |
| 2166 | sizeof(VkPipelineTessellationStateCreateInfo)); |
| 2167 | pPipeline->graphicsPipelineCI.pTessellationState = |
| 2168 | &pPipeline->tessStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2169 | } |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2170 | if (pCreateInfo->pViewportState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2171 | memcpy((void *)&pPipeline->vpStateCI, pCreateInfo->pViewportState, |
| 2172 | sizeof(VkPipelineViewportStateCreateInfo)); |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2173 | pPipeline->graphicsPipelineCI.pViewportState = &pPipeline->vpStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2174 | } |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 2175 | if (pCreateInfo->pRasterizationState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2176 | memcpy((void *)&pPipeline->rsStateCI, pCreateInfo->pRasterizationState, |
| 2177 | sizeof(VkPipelineRasterizationStateCreateInfo)); |
| 2178 | pPipeline->graphicsPipelineCI.pRasterizationState = |
| 2179 | &pPipeline->rsStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2180 | } |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2181 | if (pCreateInfo->pMultisampleState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2182 | memcpy((void *)&pPipeline->msStateCI, pCreateInfo->pMultisampleState, |
| 2183 | sizeof(VkPipelineMultisampleStateCreateInfo)); |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2184 | pPipeline->graphicsPipelineCI.pMultisampleState = &pPipeline->msStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2185 | } |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2186 | if (pCreateInfo->pDepthStencilState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2187 | memcpy((void *)&pPipeline->dsStateCI, pCreateInfo->pDepthStencilState, |
| 2188 | sizeof(VkPipelineDepthStencilStateCreateInfo)); |
| 2189 | pPipeline->graphicsPipelineCI.pDepthStencilState = |
| 2190 | &pPipeline->dsStateCI; |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2191 | } |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2192 | if (pCreateInfo->pColorBlendState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2193 | memcpy((void *)&pPipeline->cbStateCI, pCreateInfo->pColorBlendState, |
| 2194 | sizeof(VkPipelineColorBlendStateCreateInfo)); |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2195 | // Copy embedded ptrs |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2196 | pCBCI = pCreateInfo->pColorBlendState; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2197 | pPipeline->attachmentCount = pCBCI->attachmentCount; |
| 2198 | if (pPipeline->attachmentCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2199 | pPipeline->pAttachments = |
| 2200 | new VkPipelineColorBlendAttachmentState[pPipeline |
| 2201 | ->attachmentCount]; |
| 2202 | bufferSize = pPipeline->attachmentCount * |
| 2203 | sizeof(VkPipelineColorBlendAttachmentState); |
| 2204 | memcpy((void *)pPipeline->pAttachments, pCBCI->pAttachments, |
| 2205 | bufferSize); |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2206 | } |
Tony Barbour | dd6e32e | 2015-07-10 15:29:03 -0600 | [diff] [blame] | 2207 | pPipeline->graphicsPipelineCI.pColorBlendState = &pPipeline->cbStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2208 | } |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2209 | if (pCreateInfo->pDynamicState != NULL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2210 | memcpy((void *)&pPipeline->dynStateCI, pCreateInfo->pDynamicState, |
| 2211 | sizeof(VkPipelineDynamicStateCreateInfo)); |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2212 | if (pPipeline->dynStateCI.dynamicStateCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2213 | pPipeline->dynStateCI.pDynamicStates = |
| 2214 | new VkDynamicState[pPipeline->dynStateCI.dynamicStateCount]; |
| 2215 | bufferSize = pPipeline->dynStateCI.dynamicStateCount * |
| 2216 | sizeof(VkDynamicState); |
| 2217 | memcpy((void *)pPipeline->dynStateCI.pDynamicStates, |
| 2218 | pCreateInfo->pDynamicState->pDynamicStates, bufferSize); |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2219 | } |
| 2220 | pPipeline->graphicsPipelineCI.pDynamicState = &pPipeline->dynStateCI; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2221 | } |
Tobin Ehlis | 8845283 | 2015-12-03 09:40:56 -0700 | [diff] [blame] | 2222 | pPipeline->active_sets.clear(); |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 2223 | return pPipeline; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2224 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2225 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2226 | // Free the Pipeline nodes |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2227 | static void deletePipelines(layer_data *my_data) { |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 2228 | if (my_data->pipelineMap.size() <= 0) |
David Pinedo | d8f83d8 | 2015-04-27 16:36:17 -0600 | [diff] [blame] | 2229 | return; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2230 | for (auto ii = my_data->pipelineMap.begin(); |
| 2231 | ii != my_data->pipelineMap.end(); ++ii) { |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2232 | if ((*ii).second->graphicsPipelineCI.stageCount != 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2233 | delete[](*ii).second->graphicsPipelineCI.pStages; |
Mark Lobodzinski | d5732f3 | 2015-06-23 15:11:57 -0600 | [diff] [blame] | 2234 | } |
Tobin Ehlis | f313c8b | 2015-04-01 11:59:08 -0600 | [diff] [blame] | 2235 | if ((*ii).second->pVertexBindingDescriptions) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2236 | delete[](*ii).second->pVertexBindingDescriptions; |
Tobin Ehlis | f313c8b | 2015-04-01 11:59:08 -0600 | [diff] [blame] | 2237 | } |
| 2238 | if ((*ii).second->pVertexAttributeDescriptions) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2239 | delete[](*ii).second->pVertexAttributeDescriptions; |
Tobin Ehlis | f313c8b | 2015-04-01 11:59:08 -0600 | [diff] [blame] | 2240 | } |
| 2241 | if ((*ii).second->pAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2242 | delete[](*ii).second->pAttachments; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2243 | } |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2244 | if ((*ii).second->dynStateCI.dynamicStateCount != 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2245 | delete[](*ii).second->dynStateCI.pDynamicStates; |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 2246 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2247 | delete (*ii).second; |
| 2248 | } |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 2249 | my_data->pipelineMap.clear(); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2250 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2251 | |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2252 | // For given pipeline, return number of MSAA samples, or one if MSAA disabled |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2253 | static VkSampleCountFlagBits getNumSamples(layer_data *my_data, |
| 2254 | const VkPipeline pipeline) { |
| 2255 | PIPELINE_NODE *pPipe = my_data->pipelineMap[pipeline]; |
| 2256 | if (VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == |
| 2257 | pPipe->msStateCI.sType) { |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 2258 | return pPipe->msStateCI.rasterizationSamples; |
Tobin Ehlis | 577188e | 2015-07-13 14:51:15 -0600 | [diff] [blame] | 2259 | } |
Chia-I Wu | 5c17c96 | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2260 | return VK_SAMPLE_COUNT_1_BIT; |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2261 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2262 | |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2263 | // Validate state related to the PSO |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2264 | static VkBool32 |
| 2265 | validatePipelineState(layer_data *my_data, const GLOBAL_CB_NODE *pCB, |
| 2266 | const VkPipelineBindPoint pipelineBindPoint, |
| 2267 | const VkPipeline pipeline) { |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 2268 | if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) { |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2269 | // Verify that any MSAA request in PSO matches sample# in bound FB |
Chia-I Wu | 5c17c96 | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2270 | VkSampleCountFlagBits psoNumSamples = getNumSamples(my_data, pipeline); |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2271 | if (pCB->activeRenderPass) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2272 | const VkRenderPassCreateInfo *pRPCI = |
| 2273 | my_data->renderPassMap[pCB->activeRenderPass]->pCreateInfo; |
| 2274 | const VkSubpassDescription *pSD = |
| 2275 | &pRPCI->pSubpasses[pCB->activeSubpass]; |
| 2276 | VkSampleCountFlagBits subpassNumSamples = (VkSampleCountFlagBits)0; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2277 | uint32_t i; |
| 2278 | |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 2279 | for (i = 0; i < pSD->colorAttachmentCount; i++) { |
Chia-I Wu | 5c17c96 | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2280 | VkSampleCountFlagBits samples; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2281 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2282 | if (pSD->pColorAttachments[i].attachment == |
| 2283 | VK_ATTACHMENT_UNUSED) |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2284 | continue; |
| 2285 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2286 | samples = |
| 2287 | pRPCI->pAttachments[pSD->pColorAttachments[i].attachment] |
| 2288 | .samples; |
| 2289 | if (subpassNumSamples == (VkSampleCountFlagBits)0) { |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2290 | subpassNumSamples = samples; |
| 2291 | } else if (subpassNumSamples != samples) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2292 | subpassNumSamples = (VkSampleCountFlagBits)-1; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2293 | break; |
| 2294 | } |
| 2295 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2296 | if (pSD->pDepthStencilAttachment && |
| 2297 | pSD->pDepthStencilAttachment->attachment != |
| 2298 | VK_ATTACHMENT_UNUSED) { |
| 2299 | const VkSampleCountFlagBits samples = |
| 2300 | pRPCI |
| 2301 | ->pAttachments[pSD->pDepthStencilAttachment->attachment] |
| 2302 | .samples; |
| 2303 | if (subpassNumSamples == (VkSampleCountFlagBits)0) |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2304 | subpassNumSamples = samples; |
| 2305 | else if (subpassNumSamples != samples) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2306 | subpassNumSamples = (VkSampleCountFlagBits)-1; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 2307 | } |
| 2308 | |
| 2309 | if (psoNumSamples != subpassNumSamples) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2310 | return log_msg( |
| 2311 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2312 | VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, |
| 2313 | (uint64_t)pipeline, __LINE__, |
| 2314 | DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", |
| 2315 | "Num samples mismatch! Binding PSO (%#" PRIxLEAST64 |
| 2316 | ") with %u samples while current RenderPass (%#" PRIxLEAST64 |
| 2317 | ") w/ %u samples!", |
| 2318 | (uint64_t)pipeline, psoNumSamples, |
| 2319 | (uint64_t)pCB->activeRenderPass, subpassNumSamples); |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2320 | } |
| 2321 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2322 | // TODO : I believe it's an error if we reach this point and don't |
| 2323 | // have an activeRenderPass |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2324 | // Verify and flag error as appropriate |
| 2325 | } |
| 2326 | // TODO : Add more checks here |
| 2327 | } else { |
| 2328 | // TODO : Validate non-gfx pipeline updates |
| 2329 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2330 | return VK_FALSE; |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 2331 | } |
| 2332 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2333 | // Block of code at start here specifically for managing/tracking DSs |
| 2334 | |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2335 | // Return Pool node ptr for specified pool or else NULL |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2336 | static DESCRIPTOR_POOL_NODE *getPoolNode(layer_data *my_data, |
| 2337 | const VkDescriptorPool pool) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2338 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2339 | if (my_data->descriptorPoolMap.find(pool) == |
| 2340 | my_data->descriptorPoolMap.end()) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2341 | loader_platform_thread_unlock_mutex(&globalLock); |
| 2342 | return NULL; |
| 2343 | } |
| 2344 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 2345 | return my_data->descriptorPoolMap[pool]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2346 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2347 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2348 | static LAYOUT_NODE *getLayoutNode(layer_data *my_data, |
| 2349 | const VkDescriptorSetLayout layout) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2350 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2351 | if (my_data->descriptorSetLayoutMap.find(layout) == |
| 2352 | my_data->descriptorSetLayoutMap.end()) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2353 | loader_platform_thread_unlock_mutex(&globalLock); |
| 2354 | return NULL; |
| 2355 | } |
| 2356 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 2357 | return my_data->descriptorSetLayoutMap[layout]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2358 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2359 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2360 | // Return VK_FALSE if update struct is of valid type, otherwise flag error and |
| 2361 | // return code from callback |
| 2362 | static VkBool32 validUpdateStruct(layer_data *my_data, const VkDevice device, |
| 2363 | const GENERIC_HEADER *pUpdateStruct) { |
| 2364 | switch (pUpdateStruct->sType) { |
| 2365 | case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: |
| 2366 | case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET: |
| 2367 | return VK_FALSE; |
| 2368 | default: |
| 2369 | return log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2370 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2371 | DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", |
| 2372 | "Unexpected UPDATE struct of type %s (value %u) in " |
| 2373 | "vkUpdateDescriptors() struct tree", |
| 2374 | string_VkStructureType(pUpdateStruct->sType), |
| 2375 | pUpdateStruct->sType); |
Tobin Ehlis | 0174fed | 2015-05-28 12:10:17 -0600 | [diff] [blame] | 2376 | } |
| 2377 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2378 | |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2379 | // Set count for given update struct in the last parameter |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2380 | // Return value of skipCall, which is only VK_TRUE if error occurs and callback |
| 2381 | // signals execution to cease |
| 2382 | static uint32_t getUpdateCount(layer_data *my_data, const VkDevice device, |
| 2383 | const GENERIC_HEADER *pUpdateStruct) { |
| 2384 | switch (pUpdateStruct->sType) { |
| 2385 | case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: |
| 2386 | return ((VkWriteDescriptorSet *)pUpdateStruct)->descriptorCount; |
| 2387 | case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET: |
| 2388 | // TODO : Need to understand this case better and make sure code is |
| 2389 | // correct |
| 2390 | return ((VkCopyDescriptorSet *)pUpdateStruct)->descriptorCount; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2391 | } |
Courtney Goeltzenleuchter | 7f47bca | 2015-12-16 16:08:08 -0700 | [diff] [blame] | 2392 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2393 | return 0; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2394 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2395 | |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2396 | // For given Layout Node and binding, return index where that binding begins |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2397 | static uint32_t getBindingStartIndex(const LAYOUT_NODE *pLayout, |
| 2398 | const uint32_t binding) { |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2399 | uint32_t offsetIndex = 0; |
Chia-I Wu | d46e6ae | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2400 | for (uint32_t i = 0; i < pLayout->createInfo.bindingCount; i++) { |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 2401 | if (pLayout->createInfo.pBindings[i].binding == binding) |
Chia-I Wu | d46e6ae | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2402 | break; |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 2403 | offsetIndex += pLayout->createInfo.pBindings[i].descriptorCount; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2404 | } |
| 2405 | return offsetIndex; |
| 2406 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2407 | |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2408 | // For given layout node and binding, return last index that is updated |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2409 | static uint32_t getBindingEndIndex(const LAYOUT_NODE *pLayout, |
| 2410 | const uint32_t binding) { |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2411 | uint32_t offsetIndex = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2412 | for (uint32_t i = 0; i < pLayout->createInfo.bindingCount; i++) { |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 2413 | offsetIndex += pLayout->createInfo.pBindings[i].descriptorCount; |
| 2414 | if (pLayout->createInfo.pBindings[i].binding == binding) |
Chia-I Wu | d46e6ae | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2415 | break; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2416 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2417 | return offsetIndex - 1; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2418 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2419 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2420 | // For given layout and update, return the first overall index of the layout |
| 2421 | // that is updated |
| 2422 | static uint32_t getUpdateStartIndex(layer_data *my_data, const VkDevice device, |
| 2423 | const LAYOUT_NODE *pLayout, |
| 2424 | const uint32_t binding, |
| 2425 | const uint32_t arrayIndex, |
| 2426 | const GENERIC_HEADER *pUpdateStruct) { |
| 2427 | return getBindingStartIndex(pLayout, binding) + arrayIndex; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2428 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2429 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2430 | // For given layout and update, return the last overall index of the layout that |
| 2431 | // is updated |
| 2432 | static uint32_t getUpdateEndIndex(layer_data *my_data, const VkDevice device, |
| 2433 | const LAYOUT_NODE *pLayout, |
| 2434 | const uint32_t binding, |
| 2435 | const uint32_t arrayIndex, |
| 2436 | const GENERIC_HEADER *pUpdateStruct) { |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 2437 | uint32_t count = getUpdateCount(my_data, device, pUpdateStruct); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2438 | return getBindingStartIndex(pLayout, binding) + arrayIndex + count - 1; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2439 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2440 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2441 | // Verify that the descriptor type in the update struct matches what's expected |
| 2442 | // by the layout |
| 2443 | static VkBool32 validateUpdateConsistency(layer_data *my_data, |
| 2444 | const VkDevice device, |
| 2445 | const LAYOUT_NODE *pLayout, |
| 2446 | const GENERIC_HEADER *pUpdateStruct, |
| 2447 | uint32_t startIndex, |
| 2448 | uint32_t endIndex) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2449 | // First get actual type of update |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2450 | VkBool32 skipCall = VK_FALSE; |
Courtney Goeltzenleuchter | fb4efc6 | 2015-04-10 08:34:15 -0600 | [diff] [blame] | 2451 | VkDescriptorType actualType; |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2452 | uint32_t i = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2453 | switch (pUpdateStruct->sType) { |
| 2454 | case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: |
| 2455 | actualType = ((VkWriteDescriptorSet *)pUpdateStruct)->descriptorType; |
| 2456 | break; |
| 2457 | case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET: |
| 2458 | /* no need to validate */ |
| 2459 | return VK_FALSE; |
| 2460 | break; |
| 2461 | default: |
| 2462 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2463 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2464 | DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", |
| 2465 | "Unexpected UPDATE struct of type %s (value %u) in " |
| 2466 | "vkUpdateDescriptors() struct tree", |
| 2467 | string_VkStructureType(pUpdateStruct->sType), |
| 2468 | pUpdateStruct->sType); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2469 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2470 | if (VK_FALSE == skipCall) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2471 | // Set first stageFlags as reference and verify that all other updates |
| 2472 | // match it |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2473 | VkShaderStageFlags refStageFlags = pLayout->stageFlags[startIndex]; |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2474 | for (i = startIndex; i <= endIndex; i++) { |
Tobin Ehlis | 644ff04 | 2015-10-20 10:11:55 -0600 | [diff] [blame] | 2475 | if (pLayout->descriptorTypes[i] != actualType) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2476 | skipCall |= log_msg( |
| 2477 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2478 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2479 | DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", |
| 2480 | "Write descriptor update has descriptor type %s that does " |
| 2481 | "not match overlapping binding descriptor type of %s!", |
| 2482 | string_VkDescriptorType(actualType), |
| 2483 | string_VkDescriptorType(pLayout->descriptorTypes[i])); |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2484 | } |
| 2485 | if (pLayout->stageFlags[i] != refStageFlags) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2486 | skipCall |= log_msg( |
| 2487 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2488 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2489 | DRAWSTATE_DESCRIPTOR_STAGEFLAGS_MISMATCH, "DS", |
| 2490 | "Write descriptor update has stageFlags %x that do not " |
| 2491 | "match overlapping binding descriptor stageFlags of %x!", |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2492 | refStageFlags, pLayout->stageFlags[i]); |
Tobin Ehlis | 483cc35 | 2015-09-30 08:30:20 -0600 | [diff] [blame] | 2493 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2494 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2495 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2496 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2497 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2498 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2499 | // Determine the update type, allocate a new struct of that type, shadow the |
| 2500 | // given pUpdate |
| 2501 | // struct into the pNewNode param. Return VK_TRUE if error condition |
| 2502 | // encountered and callback signals early exit. |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2503 | // NOTE : Calls to this function should be wrapped in mutex |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2504 | static VkBool32 shadowUpdateNode(layer_data *my_data, const VkDevice device, |
| 2505 | GENERIC_HEADER *pUpdate, |
| 2506 | GENERIC_HEADER **pNewNode) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2507 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2508 | VkWriteDescriptorSet *pWDS = NULL; |
| 2509 | VkCopyDescriptorSet *pCDS = NULL; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2510 | size_t array_size = 0; |
| 2511 | size_t base_array_size = 0; |
| 2512 | size_t total_array_size = 0; |
| 2513 | size_t baseBuffAddr = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2514 | switch (pUpdate->sType) { |
| 2515 | case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: |
| 2516 | pWDS = new VkWriteDescriptorSet; |
| 2517 | *pNewNode = (GENERIC_HEADER *)pWDS; |
| 2518 | memcpy(pWDS, pUpdate, sizeof(VkWriteDescriptorSet)); |
Courtney Goeltzenleuchter | 4cb6d92 | 2015-10-23 13:38:14 -0600 | [diff] [blame] | 2519 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2520 | switch (pWDS->descriptorType) { |
| 2521 | case VK_DESCRIPTOR_TYPE_SAMPLER: |
| 2522 | case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: |
| 2523 | case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: |
| 2524 | case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { |
| 2525 | VkDescriptorImageInfo *info = |
| 2526 | new VkDescriptorImageInfo[pWDS->descriptorCount]; |
| 2527 | memcpy(info, pWDS->pImageInfo, |
| 2528 | pWDS->descriptorCount * sizeof(VkDescriptorImageInfo)); |
| 2529 | pWDS->pImageInfo = info; |
| 2530 | } break; |
| 2531 | case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: |
| 2532 | case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { |
| 2533 | VkBufferView *info = new VkBufferView[pWDS->descriptorCount]; |
| 2534 | memcpy(info, pWDS->pTexelBufferView, |
| 2535 | pWDS->descriptorCount * sizeof(VkBufferView)); |
| 2536 | pWDS->pTexelBufferView = info; |
| 2537 | } break; |
| 2538 | case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: |
| 2539 | case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: |
| 2540 | case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: |
| 2541 | case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { |
| 2542 | VkDescriptorBufferInfo *info = |
| 2543 | new VkDescriptorBufferInfo[pWDS->descriptorCount]; |
| 2544 | memcpy(info, pWDS->pBufferInfo, |
| 2545 | pWDS->descriptorCount * sizeof(VkDescriptorBufferInfo)); |
| 2546 | pWDS->pBufferInfo = info; |
| 2547 | } break; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2548 | default: |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2549 | return VK_ERROR_VALIDATION_FAILED_EXT; |
| 2550 | break; |
| 2551 | } |
| 2552 | break; |
| 2553 | case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET: |
| 2554 | pCDS = new VkCopyDescriptorSet; |
| 2555 | *pNewNode = (GENERIC_HEADER *)pCDS; |
| 2556 | memcpy(pCDS, pUpdate, sizeof(VkCopyDescriptorSet)); |
| 2557 | break; |
| 2558 | default: |
| 2559 | if (log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2560 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 2561 | DRAWSTATE_INVALID_UPDATE_STRUCT, "DS", |
| 2562 | "Unexpected UPDATE struct of type %s (value %u) in " |
| 2563 | "vkUpdateDescriptors() struct tree", |
| 2564 | string_VkStructureType(pUpdate->sType), pUpdate->sType)) |
| 2565 | return VK_TRUE; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2566 | } |
| 2567 | // Make sure that pNext for the end of shadow copy is NULL |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2568 | (*pNewNode)->pNext = NULL; |
| 2569 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2570 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2571 | |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2572 | // Verify that given sampler is valid |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2573 | static VkBool32 validateSampler(const layer_data *my_data, |
| 2574 | const VkSampler *pSampler, |
| 2575 | const VkBool32 immutable) { |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2576 | VkBool32 skipCall = VK_FALSE; |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 2577 | auto sampIt = my_data->sampleMap.find(*pSampler); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2578 | if (sampIt == my_data->sampleMap.end()) { |
| 2579 | if (!immutable) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2580 | skipCall |= log_msg( |
| 2581 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2582 | VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, (uint64_t)*pSampler, |
| 2583 | __LINE__, DRAWSTATE_SAMPLER_DESCRIPTOR_ERROR, "DS", |
| 2584 | "vkUpdateDescriptorSets: Attempt to update descriptor with " |
| 2585 | "invalid sampler %#" PRIxLEAST64, |
| 2586 | (uint64_t)*pSampler); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2587 | } else { // immutable |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2588 | skipCall |= log_msg( |
| 2589 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2590 | VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, (uint64_t)*pSampler, |
| 2591 | __LINE__, DRAWSTATE_SAMPLER_DESCRIPTOR_ERROR, "DS", |
| 2592 | "vkUpdateDescriptorSets: Attempt to update descriptor whose " |
| 2593 | "binding has an invalid immutable sampler %#" PRIxLEAST64, |
| 2594 | (uint64_t)*pSampler); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2595 | } |
| 2596 | } else { |
| 2597 | // TODO : Any further checks we want to do on the sampler? |
| 2598 | } |
| 2599 | return skipCall; |
| 2600 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2601 | |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2602 | // Verify that given imageView is valid |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2603 | static VkBool32 validateImageView(const layer_data *my_data, |
| 2604 | const VkImageView *pImageView, |
| 2605 | const VkImageLayout imageLayout) { |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2606 | VkBool32 skipCall = VK_FALSE; |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 2607 | auto ivIt = my_data->imageViewMap.find(*pImageView); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2608 | if (ivIt == my_data->imageViewMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2609 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2610 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, |
| 2611 | (uint64_t)*pImageView, __LINE__, |
| 2612 | DRAWSTATE_IMAGEVIEW_DESCRIPTOR_ERROR, "DS", |
| 2613 | "vkUpdateDescriptorSets: Attempt to update " |
| 2614 | "descriptor with invalid imageView %#" PRIxLEAST64, |
| 2615 | (uint64_t)*pImageView); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2616 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2617 | // Validate that imageLayout is compatible with aspectMask and image |
| 2618 | // format |
| 2619 | VkImageAspectFlags aspectMask = |
| 2620 | ivIt->second->subresourceRange.aspectMask; |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 2621 | VkImage image = ivIt->second->image; |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 2622 | // TODO : Check here in case we have a bad image |
Tobin Ehlis | 75cd1c5 | 2016-01-21 10:21:04 -0700 | [diff] [blame] | 2623 | auto imgIt = my_data->imageLayoutMap.find(image); |
| 2624 | if (imgIt == my_data->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2625 | skipCall |= log_msg( |
| 2626 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2627 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, (uint64_t)image, |
| 2628 | __LINE__, DRAWSTATE_IMAGEVIEW_DESCRIPTOR_ERROR, "DS", |
| 2629 | "vkUpdateDescriptorSets: Attempt to update descriptor with " |
| 2630 | "invalid image %#" PRIxLEAST64 " in imageView %#" PRIxLEAST64, |
| 2631 | (uint64_t)image, (uint64_t)*pImageView); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2632 | } else { |
| 2633 | VkFormat format = (*imgIt).second->format; |
Courtney Goeltzenleuchter | 6ed5dc2 | 2015-11-03 15:41:43 -0700 | [diff] [blame] | 2634 | VkBool32 ds = vk_format_is_depth_or_stencil(format); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2635 | switch (imageLayout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2636 | case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: |
| 2637 | // Only Color bit must be set |
| 2638 | if ((aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != |
| 2639 | VK_IMAGE_ASPECT_COLOR_BIT) { |
| 2640 | skipCall |= log_msg( |
| 2641 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2642 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, |
| 2643 | (uint64_t)*pImageView, __LINE__, |
| 2644 | DRAWSTATE_INVALID_IMAGE_ASPECT, "DS", |
| 2645 | "vkUpdateDescriptorSets: Updating descriptor with " |
| 2646 | "layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL and " |
| 2647 | "imageView %#" PRIxLEAST64 "" |
| 2648 | " that does not have VK_IMAGE_ASPECT_COLOR_BIT set.", |
| 2649 | (uint64_t)*pImageView); |
| 2650 | } |
| 2651 | // format must NOT be DS |
| 2652 | if (ds) { |
| 2653 | skipCall |= log_msg( |
| 2654 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2655 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, |
| 2656 | (uint64_t)*pImageView, __LINE__, |
| 2657 | DRAWSTATE_IMAGEVIEW_DESCRIPTOR_ERROR, "DS", |
| 2658 | "vkUpdateDescriptorSets: Updating descriptor with " |
| 2659 | "layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL and " |
| 2660 | "imageView %#" PRIxLEAST64 "" |
| 2661 | " but the image format is %s which is not a color " |
| 2662 | "format.", |
| 2663 | (uint64_t)*pImageView, string_VkFormat(format)); |
| 2664 | } |
| 2665 | break; |
| 2666 | case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: |
| 2667 | case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: |
| 2668 | // Depth or stencil bit must be set, but both must NOT be set |
| 2669 | if (aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) { |
| 2670 | if (aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { |
| 2671 | // both must NOT be set |
| 2672 | skipCall |= log_msg( |
| 2673 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2674 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, |
| 2675 | (uint64_t)*pImageView, __LINE__, |
| 2676 | DRAWSTATE_INVALID_IMAGE_ASPECT, "DS", |
| 2677 | "vkUpdateDescriptorSets: Updating descriptor with " |
| 2678 | "imageView %#" PRIxLEAST64 "" |
| 2679 | " that has both STENCIL and DEPTH aspects set", |
| 2680 | (uint64_t)*pImageView); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2681 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2682 | } else if (!(aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) { |
| 2683 | // Neither were set |
| 2684 | skipCall |= log_msg( |
| 2685 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2686 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, |
| 2687 | (uint64_t)*pImageView, __LINE__, |
| 2688 | DRAWSTATE_INVALID_IMAGE_ASPECT, "DS", |
| 2689 | "vkUpdateDescriptorSets: Updating descriptor with " |
| 2690 | "layout %s and imageView %#" PRIxLEAST64 "" |
| 2691 | " that does not have STENCIL or DEPTH aspect set.", |
| 2692 | string_VkImageLayout(imageLayout), |
| 2693 | (uint64_t)*pImageView); |
| 2694 | } |
| 2695 | // format must be DS |
| 2696 | if (!ds) { |
| 2697 | skipCall |= log_msg( |
| 2698 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2699 | VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, |
| 2700 | (uint64_t)*pImageView, __LINE__, |
| 2701 | DRAWSTATE_IMAGEVIEW_DESCRIPTOR_ERROR, "DS", |
| 2702 | "vkUpdateDescriptorSets: Updating descriptor with " |
| 2703 | "layout %s and imageView %#" PRIxLEAST64 "" |
| 2704 | " but the image format is %s which is not a " |
| 2705 | "depth/stencil format.", |
| 2706 | string_VkImageLayout(imageLayout), |
| 2707 | (uint64_t)*pImageView, string_VkFormat(format)); |
| 2708 | } |
| 2709 | break; |
| 2710 | default: |
| 2711 | // anything to check for other layouts? |
| 2712 | break; |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2713 | } |
| 2714 | } |
| 2715 | } |
| 2716 | return skipCall; |
| 2717 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2718 | |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2719 | // Verify that given bufferView is valid |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2720 | static VkBool32 validateBufferView(const layer_data *my_data, |
| 2721 | const VkBufferView *pBufferView) { |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2722 | VkBool32 skipCall = VK_FALSE; |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 2723 | auto sampIt = my_data->bufferViewMap.find(*pBufferView); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2724 | if (sampIt == my_data->bufferViewMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2725 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2726 | VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, |
| 2727 | (uint64_t)*pBufferView, __LINE__, |
| 2728 | DRAWSTATE_BUFFERVIEW_DESCRIPTOR_ERROR, "DS", |
| 2729 | "vkUpdateDescriptorSets: Attempt to update " |
| 2730 | "descriptor with invalid bufferView %#" PRIxLEAST64, |
| 2731 | (uint64_t)*pBufferView); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2732 | } else { |
| 2733 | // TODO : Any further checks we want to do on the bufferView? |
| 2734 | } |
| 2735 | return skipCall; |
| 2736 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2737 | |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2738 | // Verify that given bufferInfo is valid |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2739 | static VkBool32 validateBufferInfo(const layer_data *my_data, |
| 2740 | const VkDescriptorBufferInfo *pBufferInfo) { |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2741 | VkBool32 skipCall = VK_FALSE; |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 2742 | auto sampIt = my_data->bufferMap.find(pBufferInfo->buffer); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2743 | if (sampIt == my_data->bufferMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2744 | skipCall |= |
| 2745 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2746 | VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, |
| 2747 | (uint64_t)pBufferInfo->buffer, __LINE__, |
| 2748 | DRAWSTATE_BUFFERINFO_DESCRIPTOR_ERROR, "DS", |
| 2749 | "vkUpdateDescriptorSets: Attempt to update descriptor " |
| 2750 | "where bufferInfo has invalid buffer %#" PRIxLEAST64, |
| 2751 | (uint64_t)pBufferInfo->buffer); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2752 | } else { |
| 2753 | // TODO : Any further checks we want to do on the bufferView? |
| 2754 | } |
| 2755 | return skipCall; |
| 2756 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 2757 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2758 | static VkBool32 |
| 2759 | validateUpdateContents(const layer_data *my_data, |
| 2760 | const VkWriteDescriptorSet *pWDS, |
| 2761 | const VkDescriptorSetLayoutBinding *pLayoutBinding) { |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2762 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2763 | // First verify that for the given Descriptor type, the correct |
| 2764 | // DescriptorInfo data is supplied |
| 2765 | VkBufferView *pBufferView = NULL; |
| 2766 | const VkSampler *pSampler = NULL; |
| 2767 | VkImageView *pImageView = NULL; |
| 2768 | VkImageLayout *pImageLayout = NULL; |
| 2769 | VkDescriptorBufferInfo *pBufferInfo = NULL; |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2770 | VkBool32 immutable = VK_FALSE; |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2771 | uint32_t i = 0; |
| 2772 | // For given update type, verify that update contents are correct |
| 2773 | switch (pWDS->descriptorType) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2774 | case VK_DESCRIPTOR_TYPE_SAMPLER: |
| 2775 | for (i = 0; i < pWDS->descriptorCount; ++i) { |
| 2776 | skipCall |= validateSampler(my_data, &(pWDS->pImageInfo[i].sampler), |
| 2777 | immutable); |
| 2778 | } |
| 2779 | break; |
| 2780 | case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: |
| 2781 | for (i = 0; i < pWDS->descriptorCount; ++i) { |
| 2782 | if (NULL == pLayoutBinding->pImmutableSamplers) { |
| 2783 | pSampler = &(pWDS->pImageInfo[i].sampler); |
| 2784 | if (immutable) { |
| 2785 | skipCall |= log_msg( |
| 2786 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2787 | VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, |
| 2788 | (uint64_t)*pSampler, __LINE__, |
| 2789 | DRAWSTATE_INCONSISTENT_IMMUTABLE_SAMPLER_UPDATE, "DS", |
| 2790 | "vkUpdateDescriptorSets: Update #%u is not an " |
| 2791 | "immutable sampler %#" PRIxLEAST64 |
| 2792 | ", but previous update(s) from this " |
| 2793 | "VkWriteDescriptorSet struct used an immutable " |
| 2794 | "sampler. All updates from a single struct must either " |
| 2795 | "use immutable or non-immutable samplers.", |
| 2796 | i, (uint64_t)*pSampler); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2797 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2798 | } else { |
| 2799 | if (i > 0 && !immutable) { |
| 2800 | skipCall |= log_msg( |
| 2801 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2802 | VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, |
| 2803 | (uint64_t)*pSampler, __LINE__, |
| 2804 | DRAWSTATE_INCONSISTENT_IMMUTABLE_SAMPLER_UPDATE, "DS", |
| 2805 | "vkUpdateDescriptorSets: Update #%u is an immutable " |
| 2806 | "sampler, but previous update(s) from this " |
| 2807 | "VkWriteDescriptorSet struct used a non-immutable " |
| 2808 | "sampler. All updates from a single struct must either " |
| 2809 | "use immutable or non-immutable samplers.", |
| 2810 | i); |
| 2811 | } |
| 2812 | immutable = VK_TRUE; |
| 2813 | pSampler = &(pLayoutBinding->pImmutableSamplers[i]); |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2814 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2815 | skipCall |= validateSampler(my_data, pSampler, immutable); |
| 2816 | } |
| 2817 | // Intentionally fall through here to also validate image stuff |
| 2818 | case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: |
| 2819 | case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: |
| 2820 | case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: |
| 2821 | for (i = 0; i < pWDS->descriptorCount; ++i) { |
| 2822 | skipCall |= |
| 2823 | validateImageView(my_data, &(pWDS->pImageInfo[i].imageView), |
| 2824 | pWDS->pImageInfo[i].imageLayout); |
| 2825 | } |
| 2826 | break; |
| 2827 | case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: |
| 2828 | case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: |
| 2829 | for (i = 0; i < pWDS->descriptorCount; ++i) { |
| 2830 | skipCall |= |
| 2831 | validateBufferView(my_data, &(pWDS->pTexelBufferView[i])); |
| 2832 | } |
| 2833 | break; |
| 2834 | case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: |
| 2835 | case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: |
| 2836 | case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: |
| 2837 | case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: |
| 2838 | for (i = 0; i < pWDS->descriptorCount; ++i) { |
| 2839 | skipCall |= validateBufferInfo(my_data, &(pWDS->pBufferInfo[i])); |
| 2840 | } |
| 2841 | break; |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2842 | } |
| 2843 | return skipCall; |
| 2844 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2845 | // Validate that given set is valid and that it's not being used by an in-flight |
| 2846 | // CmdBuffer |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 2847 | // func_str is the name of the calling function |
| 2848 | // Return VK_FALSE if no errors occur |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2849 | // Return VK_TRUE if validation error occurs and callback returns VK_TRUE (to |
| 2850 | // skip upcoming API call down the chain) |
| 2851 | VkBool32 validateIdleDescriptorSet(const layer_data *my_data, |
| 2852 | VkDescriptorSet set, std::string func_str) { |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 2853 | VkBool32 skip_call = VK_FALSE; |
| 2854 | auto set_node = my_data->setMap.find(set); |
| 2855 | if (set_node == my_data->setMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2856 | skip_call |= |
| 2857 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2858 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 2859 | (uint64_t)(set), __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS", |
| 2860 | "Cannot call %s() on descriptor set %" PRIxLEAST64 |
| 2861 | " that has not been allocated.", |
| 2862 | func_str.c_str(), (uint64_t)(set)); |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 2863 | } else { |
| 2864 | if (set_node->second->in_use.load()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2865 | skip_call |= |
| 2866 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2867 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 2868 | (uint64_t)(set), __LINE__, DRAWSTATE_OBJECT_INUSE, "DS", |
| 2869 | "Cannot call %s() on descriptor set %" PRIxLEAST64 |
| 2870 | " that is in use by a command buffer.", |
| 2871 | func_str.c_str(), (uint64_t)(set)); |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 2872 | } |
| 2873 | } |
| 2874 | return skip_call; |
| 2875 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2876 | static void invalidateBoundCmdBuffers(layer_data *dev_data, |
| 2877 | const SET_NODE *pSet) { |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 2878 | // Flag any CBs this set is bound to as INVALID |
| 2879 | for (auto cb : pSet->boundCmdBuffers) { |
| 2880 | auto cb_node = dev_data->commandBufferMap.find(cb); |
| 2881 | if (cb_node != dev_data->commandBufferMap.end()) { |
| 2882 | cb_node->second->state = CB_INVALID; |
| 2883 | } |
| 2884 | } |
| 2885 | } |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2886 | // update DS mappings based on write and copy update arrays |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2887 | static VkBool32 dsUpdate(layer_data *my_data, VkDevice device, |
| 2888 | uint32_t descriptorWriteCount, |
| 2889 | const VkWriteDescriptorSet *pWDS, |
| 2890 | uint32_t descriptorCopyCount, |
| 2891 | const VkCopyDescriptorSet *pCDS) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2892 | VkBool32 skipCall = VK_FALSE; |
Chia-I Wu | 9d00ed7 | 2015-05-25 16:27:55 +0800 | [diff] [blame] | 2893 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2894 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2895 | LAYOUT_NODE *pLayout = NULL; |
| 2896 | VkDescriptorSetLayoutCreateInfo *pLayoutCI = NULL; |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2897 | // Validate Write updates |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 2898 | uint32_t i = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2899 | for (i = 0; i < descriptorWriteCount; i++) { |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 2900 | VkDescriptorSet ds = pWDS[i].dstSet; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2901 | SET_NODE *pSet = my_data->setMap[ds]; |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 2902 | // Set being updated cannot be in-flight |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2903 | if ((skipCall = validateIdleDescriptorSet( |
| 2904 | my_data, ds, "VkUpdateDescriptorSets")) == VK_TRUE) |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 2905 | return skipCall; |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 2906 | // If set is bound to any cmdBuffers, mark them invalid |
| 2907 | invalidateBoundCmdBuffers(my_data, pSet); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2908 | GENERIC_HEADER *pUpdate = (GENERIC_HEADER *)&pWDS[i]; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2909 | pLayout = pSet->pLayout; |
Tobin Ehlis | 0174fed | 2015-05-28 12:10:17 -0600 | [diff] [blame] | 2910 | // First verify valid update struct |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2911 | if ((skipCall = validUpdateStruct(my_data, device, pUpdate)) == |
| 2912 | VK_TRUE) { |
Tobin Ehlis | 0174fed | 2015-05-28 12:10:17 -0600 | [diff] [blame] | 2913 | break; |
| 2914 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2915 | uint32_t binding = 0, endIndex = 0; |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 2916 | binding = pWDS[i].dstBinding; |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2917 | // Make sure that layout being updated has the binding being updated |
Chia-I Wu | d46e6ae | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 2918 | if (pLayout->bindings.find(binding) == pLayout->bindings.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2919 | skipCall |= log_msg( |
| 2920 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2921 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)(ds), |
| 2922 | __LINE__, DRAWSTATE_INVALID_UPDATE_INDEX, "DS", |
| 2923 | "Descriptor Set %" PRIu64 " does not have binding to match " |
| 2924 | "update binding %u for update type " |
| 2925 | "%s!", |
| 2926 | (uint64_t)(ds), binding, |
| 2927 | string_VkStructureType(pUpdate->sType)); |
Tobin Ehlis | 9c53644 | 2015-06-19 13:00:59 -0600 | [diff] [blame] | 2928 | } else { |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2929 | // Next verify that update falls within size of given binding |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2930 | endIndex = getUpdateEndIndex(my_data, device, pLayout, binding, |
| 2931 | pWDS[i].dstArrayElement, pUpdate); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 2932 | if (getBindingEndIndex(pLayout, binding) < endIndex) { |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 2933 | pLayoutCI = &pLayout->createInfo; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2934 | string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo( |
| 2935 | pLayoutCI, "{DS} "); |
| 2936 | skipCall |= |
| 2937 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2938 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 2939 | (uint64_t)(ds), __LINE__, |
| 2940 | DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", |
| 2941 | "Descriptor update type of %s is out of bounds for " |
| 2942 | "matching binding %u in Layout w/ CI:\n%s!", |
| 2943 | string_VkStructureType(pUpdate->sType), binding, |
| 2944 | DSstr.c_str()); |
| 2945 | } else { // TODO : should we skip update on a type mismatch or force |
| 2946 | // it? |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 2947 | uint32_t startIndex; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2948 | startIndex = |
| 2949 | getUpdateStartIndex(my_data, device, pLayout, binding, |
| 2950 | pWDS[i].dstArrayElement, pUpdate); |
| 2951 | // Layout bindings match w/ update, now verify that update type |
| 2952 | // & stageFlags are the same for entire update |
| 2953 | if ((skipCall = validateUpdateConsistency( |
| 2954 | my_data, device, pLayout, pUpdate, startIndex, |
| 2955 | endIndex)) == VK_FALSE) { |
| 2956 | // The update is within bounds and consistent, but need to |
| 2957 | // make sure contents make sense as well |
| 2958 | if ((skipCall = validateUpdateContents( |
| 2959 | my_data, &pWDS[i], |
| 2960 | &pLayout->createInfo.pBindings[binding])) == |
| 2961 | VK_FALSE) { |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2962 | // Update is good. Save the update info |
| 2963 | // Create new update struct for this set's shadow copy |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2964 | GENERIC_HEADER *pNewNode = NULL; |
| 2965 | skipCall |= shadowUpdateNode(my_data, device, pUpdate, |
| 2966 | &pNewNode); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2967 | if (NULL == pNewNode) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2968 | skipCall |= log_msg( |
| 2969 | my_data->report_data, |
| 2970 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 2971 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 2972 | (uint64_t)(ds), __LINE__, |
| 2973 | DRAWSTATE_OUT_OF_MEMORY, "DS", |
| 2974 | "Out of memory while attempting to allocate " |
| 2975 | "UPDATE struct in vkUpdateDescriptors()"); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2976 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2977 | // Insert shadow node into LL of updates for this |
| 2978 | // set |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2979 | pNewNode->pNext = pSet->pUpdateStructs; |
| 2980 | pSet->pUpdateStructs = pNewNode; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2981 | // Now update appropriate descriptor(s) to point to |
| 2982 | // new Update node |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2983 | for (uint32_t j = startIndex; j <= endIndex; j++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2984 | assert(j < pSet->descriptorCount); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 2985 | pSet->ppDescriptors[j] = pNewNode; |
| 2986 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2987 | } |
| 2988 | } |
| 2989 | } |
| 2990 | } |
| 2991 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 2992 | } |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 2993 | // Now validate copy updates |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2994 | for (i = 0; i < descriptorCopyCount; ++i) { |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 2995 | SET_NODE *pSrcSet = NULL, *pDstSet = NULL; |
| 2996 | LAYOUT_NODE *pSrcLayout = NULL, *pDstLayout = NULL; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 2997 | uint32_t srcStartIndex = 0, srcEndIndex = 0, dstStartIndex = 0, |
| 2998 | dstEndIndex = 0; |
| 2999 | // For each copy make sure that update falls within given layout and |
| 3000 | // that types match |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 3001 | pSrcSet = my_data->setMap[pCDS[i].srcSet]; |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 3002 | pDstSet = my_data->setMap[pCDS[i].dstSet]; |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 3003 | // Set being updated cannot be in-flight |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3004 | if ((skipCall = validateIdleDescriptorSet( |
| 3005 | my_data, pDstSet->set, "VkUpdateDescriptorSets")) == VK_TRUE) |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 3006 | return skipCall; |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 3007 | invalidateBoundCmdBuffers(my_data, pDstSet); |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3008 | pSrcLayout = pSrcSet->pLayout; |
| 3009 | pDstLayout = pDstSet->pLayout; |
| 3010 | // Validate that src binding is valid for src set layout |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3011 | if (pSrcLayout->bindings.find(pCDS[i].srcBinding) == |
| 3012 | pSrcLayout->bindings.end()) { |
| 3013 | skipCall |= |
| 3014 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3015 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 3016 | (uint64_t)pSrcSet->set, __LINE__, |
| 3017 | DRAWSTATE_INVALID_UPDATE_INDEX, |
| 3018 | "DS", "Copy descriptor update %u has srcBinding %u " |
| 3019 | "which is out of bounds for underlying SetLayout " |
| 3020 | "%#" PRIxLEAST64 " which only has bindings 0-%u.", |
| 3021 | i, pCDS[i].srcBinding, (uint64_t)pSrcLayout->layout, |
| 3022 | pSrcLayout->createInfo.bindingCount - 1); |
| 3023 | } else if (pDstLayout->bindings.find(pCDS[i].dstBinding) == |
| 3024 | pDstLayout->bindings.end()) { |
| 3025 | skipCall |= |
| 3026 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3027 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 3028 | (uint64_t)pDstSet->set, __LINE__, |
| 3029 | DRAWSTATE_INVALID_UPDATE_INDEX, |
| 3030 | "DS", "Copy descriptor update %u has dstBinding %u " |
| 3031 | "which is out of bounds for underlying SetLayout " |
| 3032 | "%#" PRIxLEAST64 " which only has bindings 0-%u.", |
| 3033 | i, pCDS[i].dstBinding, (uint64_t)pDstLayout->layout, |
| 3034 | pDstLayout->createInfo.bindingCount - 1); |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3035 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3036 | // Proceed with validation. Bindings are ok, but make sure update is |
| 3037 | // within bounds of given layout |
| 3038 | srcEndIndex = getUpdateEndIndex( |
| 3039 | my_data, device, pSrcLayout, pCDS[i].srcBinding, |
| 3040 | pCDS[i].srcArrayElement, (const GENERIC_HEADER *)&(pCDS[i])); |
| 3041 | dstEndIndex = getUpdateEndIndex( |
| 3042 | my_data, device, pDstLayout, pCDS[i].dstBinding, |
| 3043 | pCDS[i].dstArrayElement, (const GENERIC_HEADER *)&(pCDS[i])); |
| 3044 | if (getBindingEndIndex(pSrcLayout, pCDS[i].srcBinding) < |
| 3045 | srcEndIndex) { |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3046 | pLayoutCI = &pSrcLayout->createInfo; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3047 | string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo( |
| 3048 | pLayoutCI, "{DS} "); |
| 3049 | skipCall |= |
| 3050 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3051 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 3052 | (uint64_t)pSrcSet->set, __LINE__, |
| 3053 | DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", |
| 3054 | "Copy descriptor src update is out of bounds for " |
| 3055 | "matching binding %u in Layout w/ CI:\n%s!", |
| 3056 | pCDS[i].srcBinding, DSstr.c_str()); |
| 3057 | } else if (getBindingEndIndex(pDstLayout, pCDS[i].dstBinding) < |
| 3058 | dstEndIndex) { |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3059 | pLayoutCI = &pDstLayout->createInfo; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3060 | string DSstr = vk_print_vkdescriptorsetlayoutcreateinfo( |
| 3061 | pLayoutCI, "{DS} "); |
| 3062 | skipCall |= |
| 3063 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3064 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 3065 | (uint64_t)pDstSet->set, __LINE__, |
| 3066 | DRAWSTATE_DESCRIPTOR_UPDATE_OUT_OF_BOUNDS, "DS", |
| 3067 | "Copy descriptor dest update is out of bounds for " |
| 3068 | "matching binding %u in Layout w/ CI:\n%s!", |
| 3069 | pCDS[i].dstBinding, DSstr.c_str()); |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3070 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3071 | srcStartIndex = getUpdateStartIndex( |
| 3072 | my_data, device, pSrcLayout, pCDS[i].srcBinding, |
| 3073 | pCDS[i].srcArrayElement, |
| 3074 | (const GENERIC_HEADER *)&(pCDS[i])); |
| 3075 | dstStartIndex = getUpdateStartIndex( |
| 3076 | my_data, device, pDstLayout, pCDS[i].dstBinding, |
| 3077 | pCDS[i].dstArrayElement, |
| 3078 | (const GENERIC_HEADER *)&(pCDS[i])); |
| 3079 | for (uint32_t j = 0; j < pCDS[i].descriptorCount; ++j) { |
| 3080 | // For copy just make sure that the types match and then |
| 3081 | // perform the update |
| 3082 | if (pSrcLayout->descriptorTypes[srcStartIndex + j] != |
| 3083 | pDstLayout->descriptorTypes[dstStartIndex + j]) { |
| 3084 | skipCall |= log_msg( |
| 3085 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3086 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 3087 | DRAWSTATE_DESCRIPTOR_TYPE_MISMATCH, "DS", |
| 3088 | "Copy descriptor update index %u, update count " |
| 3089 | "#%u, has src update descriptor type %s that does " |
| 3090 | "not match overlapping dest descriptor type of %s!", |
| 3091 | i, j + 1, |
| 3092 | string_VkDescriptorType( |
| 3093 | pSrcLayout->descriptorTypes[srcStartIndex + j]), |
| 3094 | string_VkDescriptorType( |
| 3095 | pDstLayout |
| 3096 | ->descriptorTypes[dstStartIndex + j])); |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3097 | } else { |
| 3098 | // point dst descriptor at corresponding src descriptor |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3099 | // TODO : This may be a hole. I believe copy should be |
| 3100 | // its own copy, |
| 3101 | // otherwise a subsequent write update to src will |
| 3102 | // incorrectly affect the copy |
| 3103 | pDstSet->ppDescriptors[j + dstStartIndex] = |
| 3104 | pSrcSet->ppDescriptors[j + srcStartIndex]; |
Tobin Ehlis | 8a62e63 | 2015-10-27 15:43:38 -0600 | [diff] [blame] | 3105 | } |
| 3106 | } |
| 3107 | } |
| 3108 | } |
| 3109 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3110 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3111 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3112 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3113 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3114 | // Verify that given pool has descriptors that are being requested for |
| 3115 | // allocation |
| 3116 | static VkBool32 validate_descriptor_availability_in_pool( |
| 3117 | layer_data *dev_data, DESCRIPTOR_POOL_NODE *pPoolNode, uint32_t count, |
| 3118 | const VkDescriptorSetLayout *pSetLayouts) { |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3119 | VkBool32 skipCall = VK_FALSE; |
| 3120 | uint32_t i = 0, j = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3121 | for (i = 0; i < count; ++i) { |
| 3122 | LAYOUT_NODE *pLayout = getLayoutNode(dev_data, pSetLayouts[i]); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3123 | if (NULL == pLayout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3124 | skipCall |= log_msg( |
| 3125 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3126 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, |
| 3127 | (uint64_t)pSetLayouts[i], __LINE__, DRAWSTATE_INVALID_LAYOUT, |
| 3128 | "DS", "Unable to find set layout node for layout %#" PRIxLEAST64 |
| 3129 | " specified in vkAllocateDescriptorSets() call", |
| 3130 | (uint64_t)pSetLayouts[i]); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3131 | } else { |
Chia-I Wu | 1b99bb2 | 2015-10-27 19:25:11 +0800 | [diff] [blame] | 3132 | uint32_t typeIndex = 0, poolSizeCount = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3133 | for (j = 0; j < pLayout->createInfo.bindingCount; ++j) { |
| 3134 | typeIndex = static_cast<uint32_t>( |
| 3135 | pLayout->createInfo.pBindings[j].descriptorType); |
| 3136 | poolSizeCount = |
| 3137 | pLayout->createInfo.pBindings[j].descriptorCount; |
| 3138 | if (poolSizeCount > |
| 3139 | pPoolNode->availableDescriptorTypeCount[typeIndex]) { |
| 3140 | skipCall |= log_msg( |
| 3141 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3142 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, |
| 3143 | (uint64_t)pLayout->layout, __LINE__, |
| 3144 | DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS", |
| 3145 | "Unable to allocate %u descriptors of type %s from " |
| 3146 | "pool %#" PRIxLEAST64 ". This pool only has %u " |
| 3147 | "descriptors of this type " |
| 3148 | "remaining.", |
| 3149 | poolSizeCount, |
| 3150 | string_VkDescriptorType( |
| 3151 | pLayout->createInfo.pBindings[j].descriptorType), |
| 3152 | (uint64_t)pPoolNode->pool, |
| 3153 | pPoolNode->availableDescriptorTypeCount[typeIndex]); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3154 | } else { // Decrement available descriptors of this type |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3155 | pPoolNode->availableDescriptorTypeCount[typeIndex] -= |
| 3156 | poolSizeCount; |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3157 | } |
| 3158 | } |
| 3159 | } |
| 3160 | } |
| 3161 | return skipCall; |
| 3162 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3163 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3164 | // Free the shadowed update node for this Set |
| 3165 | // NOTE : Calls to this function should be wrapped in mutex |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3166 | static void freeShadowUpdateTree(SET_NODE *pSet) { |
| 3167 | GENERIC_HEADER *pShadowUpdate = pSet->pUpdateStructs; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3168 | pSet->pUpdateStructs = NULL; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3169 | GENERIC_HEADER *pFreeUpdate = pShadowUpdate; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3170 | // Clear the descriptor mappings as they will now be invalid |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3171 | memset(pSet->ppDescriptors, 0, |
| 3172 | pSet->descriptorCount * sizeof(GENERIC_HEADER *)); |
| 3173 | while (pShadowUpdate) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3174 | pFreeUpdate = pShadowUpdate; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3175 | pShadowUpdate = (GENERIC_HEADER *)pShadowUpdate->pNext; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3176 | uint32_t index = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3177 | VkWriteDescriptorSet *pWDS = NULL; |
| 3178 | VkCopyDescriptorSet *pCDS = NULL; |
| 3179 | void **ppToFree = NULL; |
| 3180 | switch (pFreeUpdate->sType) { |
| 3181 | case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET: |
| 3182 | pWDS = (VkWriteDescriptorSet *)pFreeUpdate; |
| 3183 | switch (pWDS->descriptorType) { |
| 3184 | case VK_DESCRIPTOR_TYPE_SAMPLER: |
| 3185 | case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: |
| 3186 | case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: |
| 3187 | case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { |
| 3188 | delete[] pWDS -> pImageInfo; |
| 3189 | } break; |
| 3190 | case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: |
| 3191 | case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { |
| 3192 | delete[] pWDS -> pTexelBufferView; |
| 3193 | } break; |
| 3194 | case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: |
| 3195 | case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: |
| 3196 | case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: |
| 3197 | case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { |
| 3198 | delete[] pWDS -> pBufferInfo; |
| 3199 | } break; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3200 | default: |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3201 | break; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3202 | } |
| 3203 | break; |
| 3204 | case VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET: |
| 3205 | break; |
| 3206 | default: |
| 3207 | assert(0); |
| 3208 | break; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3209 | } |
Tobin Ehlis | ecc6bd0 | 2015-04-08 10:58:37 -0600 | [diff] [blame] | 3210 | delete pFreeUpdate; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3211 | } |
| 3212 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3213 | |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3214 | // Free all DS Pools including their Sets & related sub-structs |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3215 | // NOTE : Calls to this function should be wrapped in mutex |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3216 | static void deletePools(layer_data *my_data) { |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 3217 | if (my_data->descriptorPoolMap.size() <= 0) |
David Pinedo | d8f83d8 | 2015-04-27 16:36:17 -0600 | [diff] [blame] | 3218 | return; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3219 | for (auto ii = my_data->descriptorPoolMap.begin(); |
| 3220 | ii != my_data->descriptorPoolMap.end(); ++ii) { |
| 3221 | SET_NODE *pSet = (*ii).second->pSets; |
| 3222 | SET_NODE *pFreeSet = pSet; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3223 | while (pSet) { |
| 3224 | pFreeSet = pSet; |
| 3225 | pSet = pSet->pNext; |
Tobin Ehlis | ecc6bd0 | 2015-04-08 10:58:37 -0600 | [diff] [blame] | 3226 | // Freeing layouts handled in deleteLayouts() function |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3227 | // Free Update shadow struct tree |
| 3228 | freeShadowUpdateTree(pFreeSet); |
| 3229 | if (pFreeSet->ppDescriptors) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3230 | delete[] pFreeSet -> ppDescriptors; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3231 | } |
| 3232 | delete pFreeSet; |
| 3233 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3234 | delete (*ii).second; |
| 3235 | } |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 3236 | my_data->descriptorPoolMap.clear(); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3237 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3238 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3239 | // WARN : Once deleteLayouts() called, any layout ptrs in Pool/Set data |
| 3240 | // structure will be invalid |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3241 | // NOTE : Calls to this function should be wrapped in mutex |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3242 | static void deleteLayouts(layer_data *my_data) { |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 3243 | if (my_data->descriptorSetLayoutMap.size() <= 0) |
David Pinedo | d8f83d8 | 2015-04-27 16:36:17 -0600 | [diff] [blame] | 3244 | return; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3245 | for (auto ii = my_data->descriptorSetLayoutMap.begin(); |
| 3246 | ii != my_data->descriptorSetLayoutMap.end(); ++ii) { |
| 3247 | LAYOUT_NODE *pLayout = (*ii).second; |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 3248 | if (pLayout->createInfo.pBindings) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3249 | for (uint32_t i = 0; i < pLayout->createInfo.bindingCount; i++) { |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 3250 | if (pLayout->createInfo.pBindings[i].pImmutableSamplers) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3251 | delete[] pLayout -> createInfo.pBindings[i] |
| 3252 | .pImmutableSamplers; |
Tobin Ehlis | ecc6bd0 | 2015-04-08 10:58:37 -0600 | [diff] [blame] | 3253 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3254 | delete[] pLayout -> createInfo.pBindings; |
Tobin Ehlis | ecc6bd0 | 2015-04-08 10:58:37 -0600 | [diff] [blame] | 3255 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3256 | delete pLayout; |
| 3257 | } |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 3258 | my_data->descriptorSetLayoutMap.clear(); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3259 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3260 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3261 | // Currently clearing a set is removing all previous updates to that set |
| 3262 | // TODO : Validate if this is correct clearing behavior |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3263 | static void clearDescriptorSet(layer_data *my_data, VkDescriptorSet set) { |
| 3264 | SET_NODE *pSet = getSetNode(my_data, set); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3265 | if (!pSet) { |
| 3266 | // TODO : Return error |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 3267 | } else { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3268 | loader_platform_thread_lock_mutex(&globalLock); |
| 3269 | freeShadowUpdateTree(pSet); |
| 3270 | loader_platform_thread_unlock_mutex(&globalLock); |
| 3271 | } |
| 3272 | } |
| 3273 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3274 | static void clearDescriptorPool(layer_data *my_data, const VkDevice device, |
| 3275 | const VkDescriptorPool pool, |
| 3276 | VkDescriptorPoolResetFlags flags) { |
| 3277 | DESCRIPTOR_POOL_NODE *pPool = getPoolNode(my_data, pool); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3278 | if (!pPool) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3279 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3280 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, (uint64_t)pool, |
| 3281 | __LINE__, DRAWSTATE_INVALID_POOL, "DS", |
| 3282 | "Unable to find pool node for pool %#" PRIxLEAST64 |
| 3283 | " specified in vkResetDescriptorPool() call", |
| 3284 | (uint64_t)pool); |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 3285 | } else { |
Courtney Goeltzenleuchter | bee18a9 | 2015-10-23 14:21:05 -0600 | [diff] [blame] | 3286 | // TODO: validate flags |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3287 | // For every set off of this pool, clear it |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3288 | SET_NODE *pSet = pPool->pSets; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3289 | while (pSet) { |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3290 | clearDescriptorSet(my_data, pSet->set); |
Mark Lobodzinski | dcce079 | 2016-01-04 09:40:19 -0700 | [diff] [blame] | 3291 | pSet = pSet->pNext; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3292 | } |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3293 | // Reset available count to max count for this pool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3294 | for (uint32_t i = 0; i < pPool->availableDescriptorTypeCount.size(); |
| 3295 | ++i) { |
| 3296 | pPool->availableDescriptorTypeCount[i] = |
| 3297 | pPool->maxDescriptorTypeCount[i]; |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 3298 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3299 | } |
| 3300 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3301 | |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3302 | // For given CB object, fetch associated CB Node from map |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3303 | static GLOBAL_CB_NODE *getCBNode(layer_data *my_data, |
| 3304 | const VkCommandBuffer cb) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3305 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 3306 | if (my_data->commandBufferMap.count(cb) == 0) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3307 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 3308 | // TODO : How to pass cb as srcObj here? |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3309 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3310 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 3311 | DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", |
| 3312 | "Attempt to use CommandBuffer %#" PRIxLEAST64 |
| 3313 | " that doesn't exist!", |
| 3314 | (uint64_t)(cb)); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3315 | return NULL; |
| 3316 | } |
| 3317 | loader_platform_thread_unlock_mutex(&globalLock); |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 3318 | return my_data->commandBufferMap[cb]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3319 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3320 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3321 | // Free all CB Nodes |
| 3322 | // NOTE : Calls to this function should be wrapped in mutex |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3323 | static void deleteCommandBuffers(layer_data *my_data) { |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 3324 | if (my_data->commandBufferMap.size() <= 0) { |
David Pinedo | d8f83d8 | 2015-04-27 16:36:17 -0600 | [diff] [blame] | 3325 | return; |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 3326 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3327 | for (auto ii = my_data->commandBufferMap.begin(); |
| 3328 | ii != my_data->commandBufferMap.end(); ++ii) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3329 | delete (*ii).second; |
| 3330 | } |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 3331 | my_data->commandBufferMap.clear(); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3332 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3333 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3334 | static VkBool32 report_error_no_cb_begin(const layer_data *dev_data, |
| 3335 | const VkCommandBuffer cb, |
| 3336 | const char *caller_name) { |
| 3337 | return log_msg( |
| 3338 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3339 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, (uint64_t)cb, __LINE__, |
| 3340 | DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, "DS", |
| 3341 | "You must call vkBeginCommandBuffer() before this call to %s", |
| 3342 | caller_name); |
Tobin Ehlis | 9c53644 | 2015-06-19 13:00:59 -0600 | [diff] [blame] | 3343 | } |
Michael Lentine | 3dea651 | 2015-10-28 15:55:18 -0700 | [diff] [blame] | 3344 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3345 | VkBool32 validateCmdsInCmdBuffer(const layer_data *dev_data, |
| 3346 | const GLOBAL_CB_NODE *pCB, |
| 3347 | const CMD_TYPE cmd_type) { |
| 3348 | if (!pCB->activeRenderPass) |
| 3349 | return VK_FALSE; |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 3350 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3351 | if (pCB->activeSubpassContents == |
| 3352 | VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS && |
| 3353 | cmd_type != CMD_EXECUTECOMMANDS) { |
| 3354 | skip_call |= |
| 3355 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3356 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 3357 | DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", |
| 3358 | "Commands cannot be called in a subpass using secondary " |
| 3359 | "command buffers."); |
| 3360 | } else if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_INLINE && |
| 3361 | cmd_type == CMD_EXECUTECOMMANDS) { |
| 3362 | skip_call |= |
| 3363 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3364 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 3365 | DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", |
| 3366 | "vkCmdExecuteCommands() cannot be called in a subpass " |
| 3367 | "using inline commands."); |
Michael Lentine | 2e068b2 | 2015-12-29 16:05:27 -0600 | [diff] [blame] | 3368 | } |
Michael Lentine | 3dea651 | 2015-10-28 15:55:18 -0700 | [diff] [blame] | 3369 | return skip_call; |
| 3370 | } |
| 3371 | |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 3372 | // Add specified CMD to the CmdBuffer in given pCB, flagging errors if CB is not |
| 3373 | // in the recording state or if there's an issue with the Cmd ordering |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3374 | static VkBool32 addCmd(const layer_data *my_data, GLOBAL_CB_NODE *pCB, |
| 3375 | const CMD_TYPE cmd, const char *caller_name) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 3376 | VkBool32 skipCall = VK_FALSE; |
| 3377 | if (pCB->state != CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3378 | skipCall |= |
| 3379 | report_error_no_cb_begin(my_data, pCB->commandBuffer, caller_name); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 3380 | skipCall |= validateCmdsInCmdBuffer(my_data, pCB, cmd); |
Tobin Ehlis | 9a87430 | 2016-01-20 10:25:29 -0700 | [diff] [blame] | 3381 | CMD_NODE cmdNode = {}; |
| 3382 | // init cmd node and append to end of cmd LL |
| 3383 | cmdNode.cmdNumber = ++pCB->numCmds; |
| 3384 | cmdNode.type = cmd; |
| 3385 | pCB->cmds.push_back(cmdNode); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3386 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3387 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3388 | } |
Tobin Ehlis | ef69465 | 2016-01-19 12:03:34 -0700 | [diff] [blame] | 3389 | // Reset the command buffer state |
| 3390 | // Maintain the createInfo and set state to CB_NEW, but clear all other state |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3391 | static void resetCB(layer_data *my_data, const VkCommandBuffer cb) { |
| 3392 | GLOBAL_CB_NODE *pCB = my_data->commandBufferMap[cb]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3393 | if (pCB) { |
Tobin Ehlis | 9a87430 | 2016-01-20 10:25:29 -0700 | [diff] [blame] | 3394 | pCB->cmds.clear(); |
Tobin Ehlis | ef69465 | 2016-01-19 12:03:34 -0700 | [diff] [blame] | 3395 | // Reset CB state (note that createInfo is not cleared) |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 3396 | pCB->commandBuffer = cb; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3397 | memset(&pCB->beginInfo, 0, sizeof(VkCommandBufferBeginInfo)); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3398 | memset(&pCB->inheritanceInfo, 0, |
| 3399 | sizeof(VkCommandBufferInheritanceInfo)); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3400 | pCB->fence = 0; |
| 3401 | pCB->numCmds = 0; |
| 3402 | memset(pCB->drawCount, 0, NUM_DRAW_TYPES * sizeof(uint64_t)); |
| 3403 | pCB->state = CB_NEW; |
| 3404 | pCB->submitCount = 0; |
| 3405 | pCB->status = 0; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3406 | pCB->lastBoundPipeline = 0; |
| 3407 | pCB->viewports.clear(); |
| 3408 | pCB->scissors.clear(); |
| 3409 | pCB->lineWidth = 0; |
| 3410 | pCB->depthBiasConstantFactor = 0; |
| 3411 | pCB->depthBiasClamp = 0; |
| 3412 | pCB->depthBiasSlopeFactor = 0; |
| 3413 | memset(pCB->blendConstants, 0, 4 * sizeof(float)); |
| 3414 | pCB->minDepthBounds = 0; |
| 3415 | pCB->maxDepthBounds = 0; |
| 3416 | memset(&pCB->front, 0, sizeof(stencil_data)); |
| 3417 | memset(&pCB->back, 0, sizeof(stencil_data)); |
| 3418 | pCB->lastBoundDescriptorSet = 0; |
| 3419 | pCB->lastBoundPipelineLayout = 0; |
| 3420 | pCB->activeRenderPass = 0; |
| 3421 | pCB->activeSubpass = 0; |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 3422 | // Before clearing uniqueBoundSets, remove this CB off of its boundCBs |
| 3423 | for (auto set : pCB->uniqueBoundSets) { |
| 3424 | auto set_node = my_data->setMap.find(set); |
| 3425 | if (set_node != my_data->setMap.end()) { |
| 3426 | set_node->second->boundCmdBuffers.erase(pCB->commandBuffer); |
| 3427 | } |
| 3428 | } |
| 3429 | pCB->uniqueBoundSets.clear(); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3430 | pCB->framebuffer = 0; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3431 | pCB->boundDescriptorSets.clear(); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 3432 | pCB->drawData.clear(); |
| 3433 | pCB->currentDrawData.buffers.clear(); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3434 | pCB->imageLayoutMap.clear(); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 3435 | pCB->waitedEvents.clear(); |
| 3436 | pCB->waitedEventsBeforeQueryReset.clear(); |
| 3437 | pCB->queryToStateMap.clear(); |
Tobin Ehlis | f4aafc0 | 2016-01-15 13:34:44 -0700 | [diff] [blame] | 3438 | pCB->secondaryCommandBuffers.clear(); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3439 | } |
| 3440 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3441 | |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 3442 | // Set PSO-related status bits for CB, including dynamic state set via PSO |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3443 | static void set_cb_pso_status(GLOBAL_CB_NODE *pCB, const PIPELINE_NODE *pPipe) { |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 3444 | for (uint32_t i = 0; i < pPipe->cbStateCI.attachmentCount; i++) { |
Chia-I Wu | 1b99bb2 | 2015-10-27 19:25:11 +0800 | [diff] [blame] | 3445 | if (0 != pPipe->pAttachments[i].colorWriteMask) { |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 3446 | pCB->status |= CBSTATUS_COLOR_BLEND_WRITE_ENABLE; |
| 3447 | } |
| 3448 | } |
| 3449 | if (pPipe->dsStateCI.depthWriteEnable) { |
Cody Northrop | 82485a8 | 2015-08-18 15:21:16 -0600 | [diff] [blame] | 3450 | pCB->status |= CBSTATUS_DEPTH_WRITE_ENABLE; |
| 3451 | } |
Cody Northrop | 82485a8 | 2015-08-18 15:21:16 -0600 | [diff] [blame] | 3452 | if (pPipe->dsStateCI.stencilTestEnable) { |
| 3453 | pCB->status |= CBSTATUS_STENCIL_TEST_ENABLE; |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 3454 | } |
Tobin Ehlis | d332f28 | 2015-10-02 11:00:56 -0600 | [diff] [blame] | 3455 | // Account for any dynamic state not set via this PSO |
| 3456 | if (!pPipe->dynStateCI.dynamicStateCount) { // All state is static |
| 3457 | pCB->status = CBSTATUS_ALL; |
| 3458 | } else { |
Tobin Ehlis | 5e5a1e9 | 2015-10-01 09:24:40 -0600 | [diff] [blame] | 3459 | // First consider all state on |
| 3460 | // Then unset any state that's noted as dynamic in PSO |
| 3461 | // Finally OR that into CB statemask |
| 3462 | CBStatusFlags psoDynStateMask = CBSTATUS_ALL; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3463 | for (uint32_t i = 0; i < pPipe->dynStateCI.dynamicStateCount; i++) { |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 3464 | switch (pPipe->dynStateCI.pDynamicStates[i]) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3465 | case VK_DYNAMIC_STATE_VIEWPORT: |
| 3466 | psoDynStateMask &= ~CBSTATUS_VIEWPORT_SET; |
| 3467 | break; |
| 3468 | case VK_DYNAMIC_STATE_SCISSOR: |
| 3469 | psoDynStateMask &= ~CBSTATUS_SCISSOR_SET; |
| 3470 | break; |
| 3471 | case VK_DYNAMIC_STATE_LINE_WIDTH: |
| 3472 | psoDynStateMask &= ~CBSTATUS_LINE_WIDTH_SET; |
| 3473 | break; |
| 3474 | case VK_DYNAMIC_STATE_DEPTH_BIAS: |
| 3475 | psoDynStateMask &= ~CBSTATUS_DEPTH_BIAS_SET; |
| 3476 | break; |
| 3477 | case VK_DYNAMIC_STATE_BLEND_CONSTANTS: |
| 3478 | psoDynStateMask &= ~CBSTATUS_BLEND_SET; |
| 3479 | break; |
| 3480 | case VK_DYNAMIC_STATE_DEPTH_BOUNDS: |
| 3481 | psoDynStateMask &= ~CBSTATUS_DEPTH_BOUNDS_SET; |
| 3482 | break; |
| 3483 | case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: |
| 3484 | psoDynStateMask &= ~CBSTATUS_STENCIL_READ_MASK_SET; |
| 3485 | break; |
| 3486 | case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: |
| 3487 | psoDynStateMask &= ~CBSTATUS_STENCIL_WRITE_MASK_SET; |
| 3488 | break; |
| 3489 | case VK_DYNAMIC_STATE_STENCIL_REFERENCE: |
| 3490 | psoDynStateMask &= ~CBSTATUS_STENCIL_REFERENCE_SET; |
| 3491 | break; |
| 3492 | default: |
| 3493 | // TODO : Flag error here |
| 3494 | break; |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 3495 | } |
| 3496 | } |
Tobin Ehlis | 5e5a1e9 | 2015-10-01 09:24:40 -0600 | [diff] [blame] | 3497 | pCB->status |= psoDynStateMask; |
Tobin Ehlis | 963a404 | 2015-09-29 08:18:34 -0600 | [diff] [blame] | 3498 | } |
Tobin Ehlis | e382c5a | 2015-06-10 12:57:07 -0600 | [diff] [blame] | 3499 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3500 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3501 | // Print the last bound Gfx Pipeline |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3502 | static VkBool32 printPipeline(layer_data *my_data, const VkCommandBuffer cb) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3503 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3504 | GLOBAL_CB_NODE *pCB = getCBNode(my_data, cb); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3505 | if (pCB) { |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3506 | PIPELINE_NODE *pPipeTrav = getPipeline(my_data, pCB->lastBoundPipeline); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3507 | if (!pPipeTrav) { |
| 3508 | // nothing to print |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 3509 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3510 | skipCall |= |
| 3511 | log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3512 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 3513 | DRAWSTATE_NONE, "DS", "%s", |
| 3514 | vk_print_vkgraphicspipelinecreateinfo( |
| 3515 | &pPipeTrav->graphicsPipelineCI, "{DS}").c_str()); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3516 | } |
| 3517 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3518 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3519 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3520 | |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3521 | // Print details of DS config to stdout |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3522 | static VkBool32 printDSConfig(layer_data *my_data, const VkCommandBuffer cb) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3523 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3524 | char ds_config_str[1024 * 256] = {0}; // TODO : Currently making this buffer |
| 3525 | // HUGE w/o overrun protection. Need |
| 3526 | // to be smarter, start smaller, and |
| 3527 | // grow as needed. |
| 3528 | GLOBAL_CB_NODE *pCB = getCBNode(my_data, cb); |
Tobin Ehlis | 93f89e8 | 2015-06-09 08:39:32 -0600 | [diff] [blame] | 3529 | if (pCB && pCB->lastBoundDescriptorSet) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3530 | SET_NODE *pSet = getSetNode(my_data, pCB->lastBoundDescriptorSet); |
| 3531 | DESCRIPTOR_POOL_NODE *pPool = getPoolNode(my_data, pSet->pool); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3532 | // Print out pool details |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3533 | skipCall |= log_msg( |
| 3534 | my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3535 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, "DS", |
| 3536 | "Details for pool %#" PRIxLEAST64 ".", (uint64_t)pPool->pool); |
| 3537 | string poolStr = |
| 3538 | vk_print_vkdescriptorpoolcreateinfo(&pPool->createInfo, " "); |
| 3539 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3540 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 3541 | DRAWSTATE_NONE, "DS", "%s", poolStr.c_str()); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3542 | // Print out set details |
| 3543 | char prefix[10]; |
| 3544 | uint32_t index = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3545 | skipCall |= |
| 3546 | log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3547 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, |
| 3548 | "DS", "Details for descriptor set %#" PRIxLEAST64 ".", |
| 3549 | (uint64_t)pSet->set); |
| 3550 | LAYOUT_NODE *pLayout = pSet->pLayout; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3551 | // Print layout details |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3552 | skipCall |= log_msg( |
| 3553 | my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3554 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, "DS", |
| 3555 | "Layout #%u, (object %#" PRIxLEAST64 ") for DS %#" PRIxLEAST64 ".", |
| 3556 | index + 1, (uint64_t)(pLayout->layout), (uint64_t)(pSet->set)); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3557 | sprintf(prefix, " [L%u] ", index); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3558 | string DSLstr = vk_print_vkdescriptorsetlayoutcreateinfo( |
| 3559 | &pLayout->createInfo, prefix).c_str(); |
| 3560 | skipCall |= log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3561 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 3562 | DRAWSTATE_NONE, "DS", "%s", DSLstr.c_str()); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 3563 | index++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3564 | GENERIC_HEADER *pUpdate = pSet->pUpdateStructs; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3565 | if (pUpdate) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3566 | skipCall |= log_msg( |
| 3567 | my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3568 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, |
| 3569 | "DS", "Update Chain [UC] for descriptor set %#" PRIxLEAST64 ":", |
| 3570 | (uint64_t)pSet->set); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3571 | sprintf(prefix, " [UC] "); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3572 | skipCall |= log_msg( |
| 3573 | my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3574 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, |
| 3575 | "DS", "%s", dynamic_display(pUpdate, prefix).c_str()); |
| 3576 | // TODO : If there is a "view" associated with this update, print CI |
| 3577 | // for that view |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 3578 | } else { |
Tobin Ehlis | bf081f3 | 2015-06-15 08:41:17 -0600 | [diff] [blame] | 3579 | if (0 != pSet->descriptorCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3580 | skipCall |= log_msg( |
| 3581 | my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3582 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, |
| 3583 | "DS", "No Update Chain for descriptor set %#" PRIxLEAST64 |
| 3584 | " which has %u descriptors (vkUpdateDescriptors has " |
| 3585 | "not been called)", |
| 3586 | (uint64_t)pSet->set, pSet->descriptorCount); |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 3587 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3588 | skipCall |= log_msg( |
| 3589 | my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3590 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, |
| 3591 | "DS", |
| 3592 | "FYI: No descriptors in descriptor set %#" PRIxLEAST64 ".", |
| 3593 | (uint64_t)pSet->set); |
Tobin Ehlis | bf081f3 | 2015-06-15 08:41:17 -0600 | [diff] [blame] | 3594 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3595 | } |
| 3596 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3597 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3598 | } |
| 3599 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3600 | static void printCB(layer_data *my_data, const VkCommandBuffer cb) { |
| 3601 | GLOBAL_CB_NODE *pCB = getCBNode(my_data, cb); |
Tobin Ehlis | 9a87430 | 2016-01-20 10:25:29 -0700 | [diff] [blame] | 3602 | if (pCB && pCB->cmds.size() > 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3603 | log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3604 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_NONE, |
| 3605 | "DS", "Cmds in CB %p", (void *)cb); |
Tobin Ehlis | 9a87430 | 2016-01-20 10:25:29 -0700 | [diff] [blame] | 3606 | vector<CMD_NODE> cmds = pCB->cmds; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3607 | for (auto ii = cmds.begin(); ii != cmds.end(); ++ii) { |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 3608 | // TODO : Need to pass cb as srcObj here |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3609 | log_msg(my_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 3610 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 3611 | DRAWSTATE_NONE, "DS", " CMD#%" PRIu64 ": %s", |
| 3612 | (*ii).cmdNumber, cmdTypeToString((*ii).type).c_str()); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3613 | } |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 3614 | } else { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3615 | // Nothing to print |
| 3616 | } |
| 3617 | } |
| 3618 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3619 | static VkBool32 synchAndPrintDSConfig(layer_data *my_data, |
| 3620 | const VkCommandBuffer cb) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3621 | VkBool32 skipCall = VK_FALSE; |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3622 | if (!(my_data->report_data->active_flags & VK_DEBUG_REPORT_INFO_BIT_EXT)) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3623 | return skipCall; |
Mike Stroyan | ba35e35 | 2015-08-12 17:11:28 -0600 | [diff] [blame] | 3624 | } |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3625 | skipCall |= printDSConfig(my_data, cb); |
| 3626 | skipCall |= printPipeline(my_data, cb); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 3627 | return skipCall; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3628 | } |
| 3629 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3630 | // Flags validation error if the associated call is made inside a render pass. |
| 3631 | // The apiName |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 3632 | // routine should ONLY be called outside a render pass. |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3633 | static VkBool32 insideRenderPass(const layer_data *my_data, GLOBAL_CB_NODE *pCB, |
| 3634 | const char *apiName) { |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 3635 | VkBool32 inside = VK_FALSE; |
| 3636 | if (pCB->activeRenderPass) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3637 | inside = log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3638 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 3639 | (uint64_t)pCB->commandBuffer, __LINE__, |
| 3640 | DRAWSTATE_INVALID_RENDERPASS_CMD, "DS", |
| 3641 | "%s: It is invalid to issue this call inside an " |
| 3642 | "active render pass (%#" PRIxLEAST64 ")", |
| 3643 | apiName, (uint64_t)pCB->activeRenderPass); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 3644 | } |
| 3645 | return inside; |
| 3646 | } |
| 3647 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3648 | // Flags validation error if the associated call is made outside a render pass. |
| 3649 | // The apiName |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 3650 | // routine should ONLY be called inside a render pass. |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3651 | static VkBool32 outsideRenderPass(const layer_data *my_data, |
| 3652 | GLOBAL_CB_NODE *pCB, const char *apiName) { |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 3653 | VkBool32 outside = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3654 | if (((pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) && |
| 3655 | (!pCB->activeRenderPass)) || |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 3656 | ((pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) && |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3657 | (!pCB->activeRenderPass) && |
| 3658 | !(pCB->beginInfo.flags & |
| 3659 | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT))) { |
| 3660 | outside = log_msg( |
| 3661 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3662 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 3663 | (uint64_t)pCB->commandBuffer, __LINE__, |
| 3664 | DRAWSTATE_NO_ACTIVE_RENDERPASS, "DS", |
| 3665 | "%s: This call must be issued inside an active render pass.", |
| 3666 | apiName); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 3667 | } |
| 3668 | return outside; |
| 3669 | } |
| 3670 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3671 | static void init_draw_state(layer_data *my_data, |
| 3672 | const VkAllocationCallbacks *pAllocator) { |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3673 | uint32_t report_flags = 0; |
| 3674 | uint32_t debug_action = 0; |
| 3675 | FILE *log_output = NULL; |
| 3676 | const char *option_str; |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3677 | VkDebugReportCallbackEXT callback; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3678 | // initialize DrawState options |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3679 | report_flags = getLayerOptionFlags("DrawStateReportFlags", 0); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3680 | getLayerOptionEnum("DrawStateDebugAction", (uint32_t *)&debug_action); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3681 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3682 | if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) { |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3683 | option_str = getLayerOption("DrawStateLogFilename"); |
Tobin Ehlis | b1df55e | 2015-09-15 09:55:54 -0600 | [diff] [blame] | 3684 | log_output = getLayerLogOutput(option_str, "DrawState"); |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3685 | VkDebugReportCallbackCreateInfoEXT dbgInfo; |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 3686 | memset(&dbgInfo, 0, sizeof(dbgInfo)); |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3687 | dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 3688 | dbgInfo.pfnCallback = log_callback; |
| 3689 | dbgInfo.pUserData = log_output; |
| 3690 | dbgInfo.flags = report_flags; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3691 | layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, |
| 3692 | &callback); |
Courtney Goeltzenleuchter | 62d945a | 2015-10-05 15:58:38 -0600 | [diff] [blame] | 3693 | my_data->logging_callback.push_back(callback); |
| 3694 | } |
| 3695 | |
| 3696 | if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) { |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3697 | VkDebugReportCallbackCreateInfoEXT dbgInfo; |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 3698 | memset(&dbgInfo, 0, sizeof(dbgInfo)); |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3699 | dbgInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 3700 | dbgInfo.pfnCallback = win32_debug_output_msg; |
| 3701 | dbgInfo.pUserData = log_output; |
| 3702 | dbgInfo.flags = report_flags; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3703 | layer_create_msg_callback(my_data->report_data, &dbgInfo, pAllocator, |
| 3704 | &callback); |
Courtney Goeltzenleuchter | 62d945a | 2015-10-05 15:58:38 -0600 | [diff] [blame] | 3705 | my_data->logging_callback.push_back(callback); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3706 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3707 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3708 | if (!globalLockInitialized) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3709 | loader_platform_thread_create_mutex(&globalLock); |
| 3710 | globalLockInitialized = 1; |
| 3711 | } |
| 3712 | } |
| 3713 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3714 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 3715 | vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, |
| 3716 | const VkAllocationCallbacks *pAllocator, |
| 3717 | VkInstance *pInstance) { |
| 3718 | VkLayerInstanceCreateInfo *chain_info = |
| 3719 | get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); |
Courtney Goeltzenleuchter | abc035e | 2015-06-01 14:29:58 -0600 | [diff] [blame] | 3720 | |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3721 | assert(chain_info->u.pLayerInfo); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3722 | PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = |
| 3723 | chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; |
| 3724 | PFN_vkCreateInstance fpCreateInstance = |
| 3725 | (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3726 | if (fpCreateInstance == NULL) { |
| 3727 | return VK_ERROR_INITIALIZATION_FAILED; |
Courtney Goeltzenleuchter | abc035e | 2015-06-01 14:29:58 -0600 | [diff] [blame] | 3728 | } |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3729 | |
| 3730 | // Advance the link info for the next element on the chain |
| 3731 | chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; |
| 3732 | |
| 3733 | VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); |
| 3734 | if (result != VK_SUCCESS) |
| 3735 | return result; |
| 3736 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3737 | layer_data *my_data = |
| 3738 | get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3739 | my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3740 | layer_init_instance_dispatch_table( |
| 3741 | *pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3742 | |
| 3743 | my_data->report_data = debug_report_create_instance( |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3744 | my_data->instance_dispatch_table, *pInstance, |
| 3745 | pCreateInfo->enabledExtensionCount, |
| 3746 | pCreateInfo->ppEnabledExtensionNames); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3747 | |
| 3748 | init_draw_state(my_data, pAllocator); |
| 3749 | |
Courtney Goeltzenleuchter | abc035e | 2015-06-01 14:29:58 -0600 | [diff] [blame] | 3750 | return result; |
| 3751 | } |
| 3752 | |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 3753 | /* hook DestroyInstance to remove tableInstanceMap entry */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3754 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 3755 | vkDestroyInstance(VkInstance instance, |
| 3756 | const VkAllocationCallbacks *pAllocator) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 3757 | // TODOSC : Shouldn't need any customization here |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3758 | dispatch_key key = get_dispatch_key(instance); |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 3759 | layer_data *my_data = get_my_data_ptr(key, layer_data_map); |
| 3760 | VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; |
Chia-I Wu | f7458c5 | 2015-10-26 21:10:41 +0800 | [diff] [blame] | 3761 | pTable->DestroyInstance(instance, pAllocator); |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3762 | |
| 3763 | // Clean up logging callback, if any |
Courtney Goeltzenleuchter | 62d945a | 2015-10-05 15:58:38 -0600 | [diff] [blame] | 3764 | while (my_data->logging_callback.size() > 0) { |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 3765 | VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 3766 | layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); |
Courtney Goeltzenleuchter | 62d945a | 2015-10-05 15:58:38 -0600 | [diff] [blame] | 3767 | my_data->logging_callback.pop_back(); |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3768 | } |
| 3769 | |
Courtney Goeltzenleuchter | ee4027d | 2015-06-28 13:01:17 -0600 | [diff] [blame] | 3770 | layer_debug_report_destroy_instance(my_data->report_data); |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 3771 | delete my_data->instance_dispatch_table; |
| 3772 | layer_data_map.erase(key); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3773 | // TODO : Potential race here with separate threads creating/destroying |
| 3774 | // instance |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 3775 | if (layer_data_map.empty()) { |
Mike Stroyan | fcb4ba6 | 2015-08-18 15:56:18 -0600 | [diff] [blame] | 3776 | // Release mutex when destroying last instance. |
| 3777 | loader_platform_thread_delete_mutex(&globalLock); |
| 3778 | globalLockInitialized = 0; |
| 3779 | } |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 3780 | } |
| 3781 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3782 | static void |
| 3783 | createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, |
| 3784 | VkDevice device) { |
Tony Barbour | 3b4732f | 2015-07-13 13:37:24 -0600 | [diff] [blame] | 3785 | uint32_t i; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3786 | layer_data *dev_data = |
| 3787 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 3788 | dev_data->device_extensions.debug_marker_enabled = false; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3789 | dev_data->device_extensions.wsi_enabled = false; |
| 3790 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3791 | VkLayerDispatchTable *pDisp = dev_data->device_dispatch_table; |
| 3792 | PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3793 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3794 | pDisp->CreateSwapchainKHR = |
| 3795 | (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR"); |
| 3796 | pDisp->DestroySwapchainKHR = |
| 3797 | (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR"); |
| 3798 | pDisp->GetSwapchainImagesKHR = |
| 3799 | (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR"); |
| 3800 | pDisp->AcquireNextImageKHR = |
| 3801 | (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR"); |
| 3802 | pDisp->QueuePresentKHR = |
| 3803 | (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR"); |
Jon Ashburn | e68a9ff | 2015-05-25 14:11:37 -0600 | [diff] [blame] | 3804 | |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 3805 | for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3806 | if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], |
| 3807 | VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) { |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3808 | dev_data->device_extensions.wsi_enabled = true; |
| 3809 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3810 | if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], |
| 3811 | DEBUG_MARKER_EXTENSION_NAME) == 0) { |
| 3812 | /* Found a matching extension name, mark it enabled and init |
| 3813 | * dispatch table*/ |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 3814 | dev_data->device_extensions.debug_marker_enabled = true; |
Jon Ashburn | 1d4b128 | 2015-12-10 19:12:21 -0700 | [diff] [blame] | 3815 | initDebugMarkerTable(device); |
Jon Ashburn | e68a9ff | 2015-05-25 14:11:37 -0600 | [diff] [blame] | 3816 | } |
Jon Ashburn | e68a9ff | 2015-05-25 14:11:37 -0600 | [diff] [blame] | 3817 | } |
| 3818 | } |
| 3819 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3820 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 3821 | vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, |
| 3822 | const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { |
| 3823 | VkLayerDeviceCreateInfo *chain_info = |
| 3824 | get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); |
Mark Lobodzinski | 941aea9 | 2016-01-13 10:23:15 -0700 | [diff] [blame] | 3825 | |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3826 | assert(chain_info->u.pLayerInfo); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3827 | PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = |
| 3828 | chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; |
| 3829 | PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = |
| 3830 | chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; |
| 3831 | PFN_vkCreateDevice fpCreateDevice = |
| 3832 | (PFN_vkCreateDevice)fpGetInstanceProcAddr(NULL, "vkCreateDevice"); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3833 | if (fpCreateDevice == NULL) { |
| 3834 | return VK_ERROR_INITIALIZATION_FAILED; |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 3835 | } |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3836 | |
| 3837 | // Advance the link info for the next element on the chain |
| 3838 | chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; |
| 3839 | |
| 3840 | VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); |
| 3841 | if (result != VK_SUCCESS) { |
| 3842 | return result; |
| 3843 | } |
| 3844 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3845 | layer_data *my_instance_data = |
| 3846 | get_my_data_ptr(get_dispatch_key(gpu), layer_data_map); |
| 3847 | layer_data *my_device_data = |
| 3848 | get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3849 | |
| 3850 | // Setup device dispatch table |
| 3851 | my_device_data->device_dispatch_table = new VkLayerDispatchTable; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3852 | layer_init_device_dispatch_table( |
| 3853 | *pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3854 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3855 | my_device_data->report_data = layer_debug_report_create_device( |
| 3856 | my_instance_data->report_data, *pDevice); |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 3857 | createDeviceRegisterExtensions(pCreateInfo, *pDevice); |
| 3858 | // Get physical device limits for this device |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3859 | my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties( |
| 3860 | gpu, &(my_instance_data->physDevPropertyMap[*pDevice])); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3861 | return result; |
| 3862 | } |
Tobin Ehlis | 559c638 | 2015-11-05 09:52:49 -0700 | [diff] [blame] | 3863 | |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3864 | // prototype |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3865 | static void deleteRenderPasses(layer_data *); |
| 3866 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 3867 | vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 3868 | // TODOSC : Shouldn't need any customization here |
Jeremy Hayes | 5d29ce3 | 2015-06-19 11:37:38 -0600 | [diff] [blame] | 3869 | dispatch_key key = get_dispatch_key(device); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3870 | layer_data *dev_data = get_my_data_ptr(key, layer_data_map); |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3871 | // Free all the memory |
| 3872 | loader_platform_thread_lock_mutex(&globalLock); |
| 3873 | deletePipelines(dev_data); |
| 3874 | deleteRenderPasses(dev_data); |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 3875 | deleteCommandBuffers(dev_data); |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3876 | deletePools(dev_data); |
| 3877 | deleteLayouts(dev_data); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 3878 | dev_data->imageViewMap.clear(); |
| 3879 | dev_data->imageMap.clear(); |
| 3880 | dev_data->bufferViewMap.clear(); |
| 3881 | dev_data->bufferMap.clear(); |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3882 | loader_platform_thread_unlock_mutex(&globalLock); |
| 3883 | |
Chia-I Wu | f7458c5 | 2015-10-26 21:10:41 +0800 | [diff] [blame] | 3884 | dev_data->device_dispatch_table->DestroyDevice(device, pAllocator); |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 3885 | tableDebugMarkerMap.erase(key); |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 3886 | delete dev_data->device_dispatch_table; |
| 3887 | layer_data_map.erase(key); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 3888 | } |
| 3889 | |
Courtney Goeltzenleuchter | 5285766 | 2015-12-01 14:08:28 -0700 | [diff] [blame] | 3890 | static const VkExtensionProperties instance_extensions[] = { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3891 | {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; |
Jon Ashburn | 9fd4cc4 | 2015-04-10 14:33:07 -0600 | [diff] [blame] | 3892 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3893 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 3894 | vkEnumerateInstanceExtensionProperties(const char *pLayerName, |
| 3895 | uint32_t *pCount, |
| 3896 | VkExtensionProperties *pProperties) { |
| 3897 | return util_GetExtensionProperties(1, instance_extensions, pCount, |
| 3898 | pProperties); |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 3899 | } |
Jon Ashburn | 9fd4cc4 | 2015-04-10 14:33:07 -0600 | [diff] [blame] | 3900 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3901 | static const VkLayerProperties ds_global_layers[] = {{ |
| 3902 | "VK_LAYER_LUNARG_draw_state", VK_API_VERSION, VK_MAKE_VERSION(0, 1, 0), |
| 3903 | "Validation layer: draw_state", |
| 3904 | }}; |
Courtney Goeltzenleuchter | 5285766 | 2015-12-01 14:08:28 -0700 | [diff] [blame] | 3905 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3906 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 3907 | vkEnumerateInstanceLayerProperties(uint32_t *pCount, |
| 3908 | VkLayerProperties *pProperties) { |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 3909 | return util_GetLayerProperties(ARRAY_SIZE(ds_global_layers), |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3910 | ds_global_layers, pCount, pProperties); |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 3911 | } |
Jon Ashburn | 9fd4cc4 | 2015-04-10 14:33:07 -0600 | [diff] [blame] | 3912 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3913 | static const VkExtensionProperties ds_device_extensions[] = {{ |
| 3914 | DEBUG_MARKER_EXTENSION_NAME, VK_MAKE_VERSION(0, 1, 0), |
| 3915 | }}; |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 3916 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3917 | static const VkLayerProperties ds_device_layers[] = {{ |
| 3918 | "VK_LAYER_LUNARG_draw_state", VK_API_VERSION, VK_MAKE_VERSION(0, 1, 0), |
| 3919 | "Validation layer: draw_state", |
| 3920 | }}; |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 3921 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3922 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 3923 | vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, |
| 3924 | const char *pLayerName, |
| 3925 | uint32_t *pCount, |
| 3926 | VkExtensionProperties *pProperties) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 3927 | // DrawState does not have any physical device extensions |
Jon Ashburn | 751c484 | 2015-11-02 17:37:20 -0700 | [diff] [blame] | 3928 | if (pLayerName == NULL) { |
| 3929 | dispatch_key key = get_dispatch_key(physicalDevice); |
| 3930 | layer_data *my_data = get_my_data_ptr(key, layer_data_map); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3931 | return my_data->instance_dispatch_table |
| 3932 | ->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, |
| 3933 | pProperties); |
Jon Ashburn | 751c484 | 2015-11-02 17:37:20 -0700 | [diff] [blame] | 3934 | } else { |
| 3935 | return util_GetExtensionProperties(ARRAY_SIZE(ds_device_extensions), |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3936 | ds_device_extensions, pCount, |
| 3937 | pProperties); |
Jon Ashburn | 751c484 | 2015-11-02 17:37:20 -0700 | [diff] [blame] | 3938 | } |
Courtney Goeltzenleuchter | 7ad58c0 | 2015-07-06 22:31:52 -0600 | [diff] [blame] | 3939 | } |
| 3940 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3941 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 3942 | vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, |
| 3943 | uint32_t *pCount, |
| 3944 | VkLayerProperties *pProperties) { |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 3945 | /* DrawState physical device layers are the same as global */ |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3946 | return util_GetLayerProperties(ARRAY_SIZE(ds_device_layers), |
| 3947 | ds_device_layers, pCount, pProperties); |
Jon Ashburn | 9fd4cc4 | 2015-04-10 14:33:07 -0600 | [diff] [blame] | 3948 | } |
| 3949 | |
Courtney Goeltzenleuchter | e6dd808 | 2015-12-16 16:07:01 -0700 | [diff] [blame] | 3950 | VkBool32 ValidateCmdBufImageLayouts(VkCommandBuffer cmdBuffer) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 3951 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3952 | layer_data *dev_data = |
| 3953 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 3954 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3955 | for (auto cb_image_data : pCB->imageLayoutMap) { |
| 3956 | auto image_data = dev_data->imageLayoutMap.find(cb_image_data.first); |
| 3957 | if (image_data == dev_data->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3958 | skip_call |= log_msg( |
| 3959 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3960 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 3961 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 3962 | "Cannot submit cmd buffer using deleted image %" PRIu64 ".", |
| 3963 | (uint64_t)(cb_image_data.first)); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3964 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3965 | if (dev_data->imageLayoutMap[cb_image_data.first]->layout != |
| 3966 | cb_image_data.second.initialLayout) { |
| 3967 | skip_call |= log_msg( |
| 3968 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3969 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 3970 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 3971 | "Cannot submit cmd buffer using image with layout %d when " |
| 3972 | "first use is %d.", |
| 3973 | dev_data->imageLayoutMap[cb_image_data.first]->layout, |
| 3974 | cb_image_data.second.initialLayout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3975 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3976 | dev_data->imageLayoutMap[cb_image_data.first]->layout = |
| 3977 | cb_image_data.second.layout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 3978 | } |
| 3979 | } |
| 3980 | return skip_call; |
| 3981 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3982 | // Track which resources are in-flight by atomically incrementing their "in_use" |
| 3983 | // count |
| 3984 | VkBool32 validateAndIncrementResources(layer_data *my_data, |
| 3985 | GLOBAL_CB_NODE *pCB) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 3986 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 3987 | for (auto drawDataElement : pCB->drawData) { |
| 3988 | for (auto buffer : drawDataElement.buffers) { |
| 3989 | auto buffer_data = my_data->bufferMap.find(buffer); |
| 3990 | if (buffer_data == my_data->bufferMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 3991 | skip_call |= log_msg( |
| 3992 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 3993 | VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, (uint64_t)(buffer), |
| 3994 | __LINE__, DRAWSTATE_INVALID_BUFFER, "DS", |
| 3995 | "Cannot submit cmd buffer using deleted buffer %" PRIu64 |
| 3996 | ".", |
| 3997 | (uint64_t)(buffer)); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 3998 | } else { |
| 3999 | buffer_data->second.in_use.fetch_add(1); |
| 4000 | } |
| 4001 | } |
| 4002 | } |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 4003 | for (auto set : pCB->uniqueBoundSets) { |
| 4004 | auto setNode = my_data->setMap.find(set); |
| 4005 | if (setNode == my_data->setMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4006 | skip_call |= log_msg( |
| 4007 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4008 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)(set), |
| 4009 | __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS", |
| 4010 | "Cannot submit cmd buffer using deleted descriptor set %" PRIu64 |
| 4011 | ".", |
| 4012 | (uint64_t)(set)); |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 4013 | } else { |
| 4014 | setNode->second->in_use.fetch_add(1); |
| 4015 | } |
| 4016 | } |
Michael Lentine | 2e068b2 | 2015-12-29 16:05:27 -0600 | [diff] [blame] | 4017 | return skip_call; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4018 | } |
| 4019 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4020 | void decrementResources(layer_data *my_data, VkCommandBuffer cmdBuffer) { |
| 4021 | GLOBAL_CB_NODE *pCB = getCBNode(my_data, cmdBuffer); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4022 | for (auto drawDataElement : pCB->drawData) { |
| 4023 | for (auto buffer : drawDataElement.buffers) { |
| 4024 | auto buffer_data = my_data->bufferMap.find(buffer); |
| 4025 | if (buffer_data != my_data->bufferMap.end()) { |
| 4026 | buffer_data->second.in_use.fetch_sub(1); |
| 4027 | } |
| 4028 | } |
| 4029 | } |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 4030 | for (auto set : pCB->uniqueBoundSets) { |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 4031 | auto setNode = my_data->setMap.find(set); |
| 4032 | if (setNode != my_data->setMap.end()) { |
| 4033 | setNode->second->in_use.fetch_sub(1); |
| 4034 | } |
| 4035 | } |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4036 | for (auto queryStatePair : pCB->queryToStateMap) { |
| 4037 | my_data->queryToStateMap[queryStatePair.first] = queryStatePair.second; |
| 4038 | } |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4039 | } |
| 4040 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4041 | void decrementResources(layer_data *my_data, uint32_t fenceCount, |
| 4042 | const VkFence *pFences) { |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4043 | for (uint32_t i = 0; i < fenceCount; ++i) { |
| 4044 | auto fence_data = my_data->fenceMap.find(pFences[i]); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4045 | if (fence_data == my_data->fenceMap.end() || |
| 4046 | !fence_data->second.needsSignaled) |
| 4047 | return; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4048 | fence_data->second.needsSignaled = false; |
| 4049 | if (fence_data->second.priorFence != VK_NULL_HANDLE) { |
| 4050 | decrementResources(my_data, 1, &fence_data->second.priorFence); |
| 4051 | } |
| 4052 | for (auto cmdBuffer : fence_data->second.cmdBuffers) { |
| 4053 | decrementResources(my_data, cmdBuffer); |
| 4054 | } |
| 4055 | } |
| 4056 | } |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 4057 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4058 | void decrementResources(layer_data *my_data, VkQueue queue) { |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4059 | auto queue_data = my_data->queueMap.find(queue); |
| 4060 | if (queue_data != my_data->queueMap.end()) { |
| 4061 | for (auto cmdBuffer : queue_data->second.untrackedCmdBuffers) { |
| 4062 | decrementResources(my_data, cmdBuffer); |
| 4063 | } |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 4064 | queue_data->second.untrackedCmdBuffers.clear(); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4065 | decrementResources(my_data, 1, &queue_data->second.priorFence); |
| 4066 | } |
| 4067 | } |
| 4068 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4069 | void trackCommandBuffers(layer_data *my_data, VkQueue queue, |
| 4070 | uint32_t cmdBufferCount, |
| 4071 | const VkCommandBuffer *pCmdBuffers, VkFence fence) { |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4072 | auto queue_data = my_data->queueMap.find(queue); |
| 4073 | if (fence != VK_NULL_HANDLE) { |
| 4074 | VkFence priorFence = VK_NULL_HANDLE; |
| 4075 | if (queue_data != my_data->queueMap.end()) { |
| 4076 | priorFence = queue_data->second.priorFence; |
| 4077 | queue_data->second.priorFence = fence; |
| 4078 | for (auto cmdBuffer : queue_data->second.untrackedCmdBuffers) { |
| 4079 | my_data->fenceMap[fence].cmdBuffers.push_back(cmdBuffer); |
| 4080 | } |
| 4081 | queue_data->second.untrackedCmdBuffers.clear(); |
| 4082 | } |
| 4083 | my_data->fenceMap[fence].cmdBuffers.clear(); |
| 4084 | my_data->fenceMap[fence].priorFence = priorFence; |
| 4085 | my_data->fenceMap[fence].needsSignaled = true; |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4086 | my_data->fenceMap[fence].queue = queue; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4087 | for (uint32_t i = 0; i < cmdBufferCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4088 | for (auto secondaryCmdBuffer : |
| 4089 | my_data->commandBufferMap[pCmdBuffers[i]] |
| 4090 | ->secondaryCommandBuffers) { |
| 4091 | my_data->fenceMap[fence].cmdBuffers.push_back( |
| 4092 | secondaryCmdBuffer); |
Tobin Ehlis | f4aafc0 | 2016-01-15 13:34:44 -0700 | [diff] [blame] | 4093 | } |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4094 | my_data->fenceMap[fence].cmdBuffers.push_back(pCmdBuffers[i]); |
| 4095 | } |
| 4096 | } else { |
| 4097 | if (queue_data != my_data->queueMap.end()) { |
| 4098 | for (uint32_t i = 0; i < cmdBufferCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4099 | for (auto secondaryCmdBuffer : |
| 4100 | my_data->commandBufferMap[pCmdBuffers[i]] |
| 4101 | ->secondaryCommandBuffers) { |
| 4102 | queue_data->second.untrackedCmdBuffers.push_back( |
| 4103 | secondaryCmdBuffer); |
Tobin Ehlis | f4aafc0 | 2016-01-15 13:34:44 -0700 | [diff] [blame] | 4104 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4105 | queue_data->second.untrackedCmdBuffers.push_back( |
| 4106 | pCmdBuffers[i]); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4107 | } |
| 4108 | } |
| 4109 | } |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4110 | if (queue_data != my_data->queueMap.end()) { |
| 4111 | for (uint32_t i = 0; i < cmdBufferCount; ++i) { |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4112 | // Add cmdBuffers to both the global set and queue set |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4113 | for (auto secondaryCmdBuffer : |
| 4114 | my_data->commandBufferMap[pCmdBuffers[i]] |
| 4115 | ->secondaryCommandBuffers) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4116 | my_data->globalInFlightCmdBuffers.insert(secondaryCmdBuffer); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4117 | queue_data->second.inFlightCmdBuffers.insert( |
| 4118 | secondaryCmdBuffer); |
Tobin Ehlis | f4aafc0 | 2016-01-15 13:34:44 -0700 | [diff] [blame] | 4119 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4120 | my_data->globalInFlightCmdBuffers.insert(pCmdBuffers[i]); |
| 4121 | queue_data->second.inFlightCmdBuffers.insert(pCmdBuffers[i]); |
| 4122 | } |
| 4123 | } |
| 4124 | } |
| 4125 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4126 | static VkBool32 validateCommandBufferState(layer_data *dev_data, |
| 4127 | GLOBAL_CB_NODE *pCB) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4128 | // Track in-use for resources off of primary and any secondary CBs |
| 4129 | VkBool32 skipCall = validateAndIncrementResources(dev_data, pCB); |
| 4130 | if (!pCB->secondaryCommandBuffers.empty()) { |
| 4131 | for (auto secondaryCmdBuffer : pCB->secondaryCommandBuffers) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4132 | skipCall |= validateAndIncrementResources( |
| 4133 | dev_data, dev_data->commandBufferMap[secondaryCmdBuffer]); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4134 | } |
| 4135 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4136 | if ((pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) && |
| 4137 | (pCB->submitCount > 1)) { |
| 4138 | skipCall |= |
| 4139 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4140 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 4141 | DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS", |
| 4142 | "CB %#" PRIxLEAST64 |
| 4143 | " was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT " |
| 4144 | "set, but has been submitted %#" PRIxLEAST64 " times.", |
| 4145 | (uint64_t)(pCB->commandBuffer), pCB->submitCount); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4146 | } |
| 4147 | // Validate that cmd buffers have been updated |
| 4148 | if (CB_RECORDED != pCB->state) { |
| 4149 | if (CB_INVALID == pCB->state) { |
| 4150 | // Inform app of reason CB invalid |
| 4151 | if (!pCB->destroyedSets.empty()) { |
| 4152 | std::stringstream set_string; |
| 4153 | for (auto set : pCB->destroyedSets) { |
| 4154 | set_string << " " << set; |
| 4155 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4156 | skipCall |= log_msg( |
| 4157 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4158 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 4159 | (uint64_t)(pCB->commandBuffer), __LINE__, |
| 4160 | DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", |
| 4161 | "You are submitting command buffer %#" PRIxLEAST64 |
| 4162 | " that is invalid because it had the following bound " |
| 4163 | "descriptor set(s) destroyed: %s", |
| 4164 | (uint64_t)(pCB->commandBuffer), set_string.str().c_str()); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4165 | } |
| 4166 | if (!pCB->updatedSets.empty()) { |
| 4167 | std::stringstream set_string; |
| 4168 | for (auto set : pCB->updatedSets) { |
| 4169 | set_string << " " << set; |
| 4170 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4171 | skipCall |= log_msg( |
| 4172 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4173 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 4174 | (uint64_t)(pCB->commandBuffer), __LINE__, |
| 4175 | DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", |
| 4176 | "You are submitting command buffer %#" PRIxLEAST64 |
| 4177 | " that is invalid because it had the following bound " |
| 4178 | "descriptor set(s) updated: %s", |
| 4179 | (uint64_t)(pCB->commandBuffer), set_string.str().c_str()); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4180 | } |
| 4181 | } else { // Flag error for using CB w/o vkEndCommandBuffer() called |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4182 | skipCall |= log_msg( |
| 4183 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4184 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 4185 | (uint64_t)(pCB->commandBuffer), __LINE__, |
| 4186 | DRAWSTATE_NO_END_COMMAND_BUFFER, "DS", |
| 4187 | "You must call vkEndCommandBuffer() on CB %#" PRIxLEAST64 |
| 4188 | " before this call to vkQueueSubmit()!", |
| 4189 | (uint64_t)(pCB->commandBuffer)); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4190 | loader_platform_thread_unlock_mutex(&globalLock); |
| 4191 | return VK_ERROR_VALIDATION_FAILED_EXT; |
| 4192 | } |
| 4193 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4194 | // If USAGE_SIMULTANEOUS_USE_BIT not set then CB cannot already be executing |
| 4195 | // on device |
| 4196 | if (!(pCB->beginInfo.flags & |
| 4197 | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { |
| 4198 | if (dev_data->globalInFlightCmdBuffers.find(pCB->commandBuffer) != |
| 4199 | dev_data->globalInFlightCmdBuffers.end()) { |
| 4200 | skipCall |= log_msg( |
| 4201 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4202 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 4203 | (uint64_t)(pCB->commandBuffer), __LINE__, |
| 4204 | DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS", |
| 4205 | "Attempt to simultaneously execute CB %#" PRIxLEAST64 |
| 4206 | " w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!", |
| 4207 | (uint64_t)(pCB->commandBuffer)); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4208 | } |
| 4209 | } |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4210 | } |
| 4211 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4212 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4213 | vkQueueSubmit(VkQueue queue, uint32_t submitCount, |
| 4214 | const VkSubmitInfo *pSubmits, VkFence fence) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 4215 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4216 | GLOBAL_CB_NODE *pCB = NULL; |
| 4217 | layer_data *dev_data = |
| 4218 | get_my_data_ptr(get_dispatch_key(queue), layer_data_map); |
Courtney Goeltzenleuchter | 646b907 | 2015-10-20 18:04:07 -0600 | [diff] [blame] | 4219 | for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) { |
Chia-I Wu | 40cf0ae | 2015-10-26 17:20:32 +0800 | [diff] [blame] | 4220 | const VkSubmitInfo *submit = &pSubmits[submit_idx]; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4221 | for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) { |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 4222 | if (dev_data->semaphoreSignaledMap[submit->pWaitSemaphores[i]]) { |
| 4223 | dev_data->semaphoreSignaledMap[submit->pWaitSemaphores[i]] = 0; |
| 4224 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4225 | skipCall |= log_msg( |
| 4226 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4227 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 4228 | DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", |
| 4229 | "Queue %#" PRIx64 " is waiting on semaphore %#" PRIx64 |
| 4230 | " that has no way to be signaled.", |
| 4231 | (uint64_t)(queue), (uint64_t)(submit->pWaitSemaphores[i])); |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 4232 | } |
| 4233 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4234 | for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) { |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 4235 | dev_data->semaphoreSignaledMap[submit->pSignalSemaphores[i]] = 1; |
| 4236 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4237 | for (uint32_t i = 0; i < submit->commandBufferCount; i++) { |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 4238 | |
| 4239 | #ifndef DISABLE_IMAGE_LAYOUT_VALIDATION |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4240 | skipCall |= ValidateCmdBufImageLayouts(submit->pCommandBuffers[i]); |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 4241 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
| 4242 | |
Courtney Goeltzenleuchter | 646b907 | 2015-10-20 18:04:07 -0600 | [diff] [blame] | 4243 | pCB = getCBNode(dev_data, submit->pCommandBuffers[i]); |
| 4244 | loader_platform_thread_lock_mutex(&globalLock); |
| 4245 | pCB->submitCount++; // increment submit count |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 4246 | skipCall |= validateCommandBufferState(dev_data, pCB); |
Tobin Ehlis | c4bdde1 | 2015-05-27 14:30:06 -0600 | [diff] [blame] | 4247 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | a9f3d76 | 2015-05-22 12:38:16 -0600 | [diff] [blame] | 4248 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4249 | trackCommandBuffers(dev_data, queue, submit->commandBufferCount, |
| 4250 | submit->pCommandBuffers, fence); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 4251 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 4252 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4253 | return dev_data->device_dispatch_table->QueueSubmit(queue, submitCount, |
| 4254 | pSubmits, fence); |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 4255 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 4256 | } |
| 4257 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4258 | VkBool32 cleanInFlightCmdBuffer(layer_data *my_data, |
| 4259 | VkCommandBuffer cmdBuffer) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 4260 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4261 | GLOBAL_CB_NODE *pCB = getCBNode(my_data, cmdBuffer); |
Mark Lobodzinski | a9e7c04 | 2016-01-25 14:27:49 -0700 | [diff] [blame] | 4262 | if (pCB) { |
| 4263 | for (auto queryEventsPair : pCB->waitedEventsBeforeQueryReset) { |
| 4264 | for (auto event : queryEventsPair.second) { |
| 4265 | if (my_data->eventMap[event].needsSignaled) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4266 | skip_call |= log_msg( |
| 4267 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4268 | VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 0, |
| 4269 | DRAWSTATE_INVALID_QUERY, "DS", |
| 4270 | "Cannot get query results on queryPool %" PRIu64 |
| 4271 | " with index %d which was guarded by unsignaled event " |
| 4272 | "%" PRIu64 ".", |
| 4273 | (uint64_t)(queryEventsPair.first.pool), |
| 4274 | queryEventsPair.first.index, (uint64_t)(event)); |
Mark Lobodzinski | a9e7c04 | 2016-01-25 14:27:49 -0700 | [diff] [blame] | 4275 | } |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4276 | } |
| 4277 | } |
| 4278 | } |
| 4279 | return skip_call; |
| 4280 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4281 | // Remove given cmd_buffer from the global inFlight set. |
| 4282 | // Also, if given queue is valid, then remove the cmd_buffer from that queues |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4283 | // inFlightCmdBuffer set. Finally, check all other queues and if given |
| 4284 | // cmd_buffer |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4285 | // is still in flight on another queue, add it back into the global set. |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4286 | static inline void removeInFlightCmdBuffer(layer_data *dev_data, |
| 4287 | VkCommandBuffer cmd_buffer, |
| 4288 | VkQueue queue) { |
| 4289 | // Pull it off of global list initially, but if we find it in any other |
| 4290 | // queue list, add it back in |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4291 | dev_data->globalInFlightCmdBuffers.erase(cmd_buffer); |
| 4292 | if (dev_data->queueMap.find(queue) != dev_data->queueMap.end()) { |
| 4293 | dev_data->queueMap[queue].inFlightCmdBuffers.erase(cmd_buffer); |
| 4294 | for (auto q : dev_data->queues) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4295 | if ((q != queue) && |
| 4296 | (dev_data->queueMap[q].inFlightCmdBuffers.find(cmd_buffer) != |
| 4297 | dev_data->queueMap[q].inFlightCmdBuffers.end())) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4298 | dev_data->globalInFlightCmdBuffers.insert(cmd_buffer); |
| 4299 | break; |
| 4300 | } |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4301 | } |
| 4302 | } |
| 4303 | } |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4304 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4305 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4306 | vkWaitForFences(VkDevice device, uint32_t fenceCount, |
| 4307 | const VkFence *pFences, VkBool32 waitAll, |
| 4308 | uint64_t timeout) { |
| 4309 | layer_data *dev_data = |
| 4310 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4311 | VkResult result = dev_data->device_dispatch_table->WaitForFences( |
| 4312 | device, fenceCount, pFences, waitAll, timeout); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 4313 | VkBool32 skip_call = VK_FALSE; |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4314 | if (result == VK_SUCCESS) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4315 | // When we know that all fences are complete we can clean/remove their |
| 4316 | // CBs |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4317 | if (waitAll || fenceCount == 1) { |
| 4318 | for (uint32_t i = 0; i < fenceCount; ++i) { |
| 4319 | VkQueue fence_queue = dev_data->fenceMap[pFences[i]].queue; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4320 | for (auto cmdBuffer : |
| 4321 | dev_data->fenceMap[pFences[i]].cmdBuffers) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4322 | skip_call |= cleanInFlightCmdBuffer(dev_data, cmdBuffer); |
| 4323 | removeInFlightCmdBuffer(dev_data, cmdBuffer, fence_queue); |
| 4324 | } |
| 4325 | } |
| 4326 | decrementResources(dev_data, fenceCount, pFences); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4327 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4328 | // NOTE : Alternate case not handled here is when some fences have |
| 4329 | // completed. In |
| 4330 | // this case for app to guarantee which fences completed it will have |
| 4331 | // to call |
| 4332 | // vkGetFenceStatus() at which point we'll clean/remove their CBs if |
| 4333 | // complete. |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4334 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 4335 | if (VK_FALSE != skip_call) |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 4336 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4337 | return result; |
| 4338 | } |
| 4339 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4340 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4341 | vkGetFenceStatus(VkDevice device, VkFence fence) { |
| 4342 | layer_data *dev_data = |
| 4343 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4344 | VkResult result = |
| 4345 | dev_data->device_dispatch_table->GetFenceStatus(device, fence); |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4346 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4347 | if (result == VK_SUCCESS) { |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4348 | auto fence_queue = dev_data->fenceMap[fence].queue; |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4349 | for (auto cmdBuffer : dev_data->fenceMap[fence].cmdBuffers) { |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4350 | skip_call |= cleanInFlightCmdBuffer(dev_data, cmdBuffer); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4351 | removeInFlightCmdBuffer(dev_data, cmdBuffer, fence_queue); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4352 | } |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4353 | decrementResources(dev_data, 1, &fence); |
| 4354 | } |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4355 | if (VK_FALSE != skip_call) |
| 4356 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4357 | return result; |
| 4358 | } |
| 4359 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4360 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4361 | vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, |
| 4362 | uint32_t queueIndex, VkQueue *pQueue) { |
| 4363 | layer_data *dev_data = |
| 4364 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4365 | dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, |
| 4366 | queueIndex, pQueue); |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4367 | dev_data->queues.push_back(*pQueue); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4368 | dev_data->queueMap[*pQueue].device = device; |
| 4369 | } |
| 4370 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4371 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(VkQueue queue) { |
| 4372 | layer_data *dev_data = |
| 4373 | get_my_data_ptr(get_dispatch_key(queue), layer_data_map); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4374 | decrementResources(dev_data, queue); |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4375 | VkBool32 skip_call = VK_FALSE; |
| 4376 | // Iterate over local set since we erase set members as we go in for loop |
| 4377 | auto local_cb_set = dev_data->queueMap[queue].inFlightCmdBuffers; |
| 4378 | for (auto cmdBuffer : local_cb_set) { |
| 4379 | skip_call |= cleanInFlightCmdBuffer(dev_data, cmdBuffer); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4380 | removeInFlightCmdBuffer(dev_data, cmdBuffer, queue); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4381 | } |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4382 | dev_data->queueMap[queue].inFlightCmdBuffers.clear(); |
| 4383 | if (VK_FALSE != skip_call) |
| 4384 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4385 | return dev_data->device_dispatch_table->QueueWaitIdle(queue); |
| 4386 | } |
| 4387 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4388 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4389 | vkDeviceWaitIdle(VkDevice device) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4390 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4391 | layer_data *dev_data = |
| 4392 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Tobin Ehlis | ae82e7f | 2016-01-20 16:23:37 -0700 | [diff] [blame] | 4393 | for (auto queue : dev_data->queues) { |
| 4394 | decrementResources(dev_data, queue); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4395 | if (dev_data->queueMap.find(queue) != dev_data->queueMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4396 | // Clear all of the queue inFlightCmdBuffers (global set cleared |
| 4397 | // below) |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4398 | dev_data->queueMap[queue].inFlightCmdBuffers.clear(); |
| 4399 | } |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4400 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4401 | for (auto cmdBuffer : dev_data->globalInFlightCmdBuffers) { |
| 4402 | skip_call |= cleanInFlightCmdBuffer(dev_data, cmdBuffer); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4403 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4404 | dev_data->globalInFlightCmdBuffers.clear(); |
| 4405 | if (VK_FALSE != skip_call) |
| 4406 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4407 | return dev_data->device_dispatch_table->DeviceWaitIdle(device); |
| 4408 | } |
| 4409 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4410 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4411 | vkDestroyFence(VkDevice device, VkFence fence, |
| 4412 | const VkAllocationCallbacks *pAllocator) { |
| 4413 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4414 | ->device_dispatch_table->DestroyFence(device, fence, pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4415 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4416 | } |
| 4417 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4418 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4419 | vkDestroySemaphore(VkDevice device, VkSemaphore semaphore, |
| 4420 | const VkAllocationCallbacks *pAllocator) { |
| 4421 | layer_data *dev_data = |
| 4422 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4423 | dev_data->device_dispatch_table->DestroySemaphore(device, semaphore, |
| 4424 | pAllocator); |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 4425 | dev_data->semaphoreSignaledMap.erase(semaphore); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4426 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4427 | } |
| 4428 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4429 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4430 | vkDestroyEvent(VkDevice device, VkEvent event, |
| 4431 | const VkAllocationCallbacks *pAllocator) { |
| 4432 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4433 | ->device_dispatch_table->DestroyEvent(device, event, pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4434 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4435 | } |
| 4436 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4437 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4438 | vkDestroyQueryPool(VkDevice device, VkQueryPool queryPool, |
| 4439 | const VkAllocationCallbacks *pAllocator) { |
| 4440 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4441 | ->device_dispatch_table->DestroyQueryPool(device, queryPool, |
| 4442 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4443 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4444 | } |
| 4445 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4446 | VKAPI_ATTR VkResult VKAPI_CALL |
| 4447 | vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, |
| 4448 | uint32_t firstQuery, uint32_t queryCount, |
| 4449 | size_t dataSize, void *pData, VkDeviceSize stride, |
| 4450 | VkQueryResultFlags flags) { |
| 4451 | layer_data *dev_data = |
| 4452 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4453 | unordered_map<QueryObject, vector<VkCommandBuffer>> queriesInFlight; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4454 | GLOBAL_CB_NODE *pCB = nullptr; |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4455 | for (auto cmdBuffer : dev_data->globalInFlightCmdBuffers) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4456 | pCB = getCBNode(dev_data, cmdBuffer); |
| 4457 | for (auto queryStatePair : pCB->queryToStateMap) { |
| 4458 | queriesInFlight[queryStatePair.first].push_back(cmdBuffer); |
| 4459 | } |
| 4460 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 4461 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4462 | for (uint32_t i = 0; i < queryCount; ++i) { |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 4463 | QueryObject query = {queryPool, firstQuery + i}; |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4464 | auto queryElement = queriesInFlight.find(query); |
| 4465 | auto queryToStateElement = dev_data->queryToStateMap.find(query); |
| 4466 | if (queryToStateElement != dev_data->queryToStateMap.end()) { |
| 4467 | } |
| 4468 | // Available and in flight |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4469 | if (queryElement != queriesInFlight.end() && |
| 4470 | queryToStateElement != dev_data->queryToStateMap.end() && |
| 4471 | queryToStateElement->second) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4472 | for (auto cmdBuffer : queryElement->second) { |
| 4473 | pCB = getCBNode(dev_data, cmdBuffer); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4474 | auto queryEventElement = |
| 4475 | pCB->waitedEventsBeforeQueryReset.find(query); |
| 4476 | if (queryEventElement == |
| 4477 | pCB->waitedEventsBeforeQueryReset.end()) { |
| 4478 | skip_call |= log_msg( |
| 4479 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4480 | VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, |
| 4481 | DRAWSTATE_INVALID_QUERY, "DS", |
| 4482 | "Cannot get query results on queryPool %" PRIu64 |
| 4483 | " with index %d which is in flight.", |
| 4484 | (uint64_t)(queryPool), firstQuery + i); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4485 | } else { |
| 4486 | for (auto event : queryEventElement->second) { |
| 4487 | dev_data->eventMap[event].needsSignaled = true; |
| 4488 | } |
| 4489 | } |
| 4490 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4491 | // Unavailable and in flight |
| 4492 | } else if (queryElement != queriesInFlight.end() && |
| 4493 | queryToStateElement != dev_data->queryToStateMap.end() && |
| 4494 | !queryToStateElement->second) { |
| 4495 | // TODO : Can there be the same query in use by multiple command |
| 4496 | // buffers in flight? |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4497 | bool make_available = false; |
| 4498 | for (auto cmdBuffer : queryElement->second) { |
| 4499 | pCB = getCBNode(dev_data, cmdBuffer); |
| 4500 | make_available |= pCB->queryToStateMap[query]; |
| 4501 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4502 | if (!(((flags & VK_QUERY_RESULT_PARTIAL_BIT) || |
| 4503 | (flags & VK_QUERY_RESULT_WAIT_BIT)) && |
| 4504 | make_available)) { |
| 4505 | skip_call |= log_msg( |
| 4506 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4507 | VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, |
| 4508 | DRAWSTATE_INVALID_QUERY, "DS", |
| 4509 | "Cannot get query results on queryPool %" PRIu64 |
| 4510 | " with index %d which is unavailable.", |
| 4511 | (uint64_t)(queryPool), firstQuery + i); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4512 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4513 | // Unavailable |
| 4514 | } else if (queryToStateElement != dev_data->queryToStateMap.end() && |
| 4515 | !queryToStateElement->second) { |
| 4516 | skip_call |= |
| 4517 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4518 | VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, |
| 4519 | DRAWSTATE_INVALID_QUERY, "DS", |
| 4520 | "Cannot get query results on queryPool %" PRIu64 |
| 4521 | " with index %d which is unavailable.", |
| 4522 | (uint64_t)(queryPool), firstQuery + i); |
| 4523 | // Unitialized |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4524 | } else if (queryToStateElement == dev_data->queryToStateMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4525 | skip_call |= |
| 4526 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4527 | VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, |
| 4528 | DRAWSTATE_INVALID_QUERY, "DS", |
| 4529 | "Cannot get query results on queryPool %" PRIu64 |
| 4530 | " with index %d which is uninitialized.", |
| 4531 | (uint64_t)(queryPool), firstQuery + i); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4532 | } |
| 4533 | } |
| 4534 | if (skip_call) |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 4535 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4536 | return dev_data->device_dispatch_table->GetQueryPoolResults( |
| 4537 | device, queryPool, firstQuery, queryCount, dataSize, pData, stride, |
| 4538 | flags); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 4539 | } |
| 4540 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4541 | VkBool32 validateIdleBuffer(const layer_data *my_data, VkBuffer buffer) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 4542 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4543 | auto buffer_data = my_data->bufferMap.find(buffer); |
| 4544 | if (buffer_data == my_data->bufferMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4545 | skip_call |= log_msg( |
| 4546 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4547 | VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, (uint64_t)(buffer), |
| 4548 | __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS", |
| 4549 | "Cannot free buffer %" PRIxLEAST64 " that has not been allocated.", |
| 4550 | (uint64_t)(buffer)); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4551 | } else { |
| 4552 | if (buffer_data->second.in_use.load()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4553 | skip_call |= |
| 4554 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4555 | VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, |
| 4556 | (uint64_t)(buffer), __LINE__, DRAWSTATE_OBJECT_INUSE, |
| 4557 | "DS", "Cannot free buffer %" PRIxLEAST64 |
| 4558 | " that is in use by a command buffer.", |
| 4559 | (uint64_t)(buffer)); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4560 | } |
| 4561 | } |
| 4562 | return skip_call; |
| 4563 | } |
| 4564 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4565 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4566 | vkDestroyBuffer(VkDevice device, VkBuffer buffer, |
| 4567 | const VkAllocationCallbacks *pAllocator) { |
| 4568 | layer_data *dev_data = |
| 4569 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 4570 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4571 | if (!validateIdleBuffer(dev_data, buffer)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4572 | dev_data->device_dispatch_table->DestroyBuffer(device, buffer, |
| 4573 | pAllocator); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4574 | } |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 4575 | dev_data->bufferMap.erase(buffer); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4576 | } |
| 4577 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4578 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4579 | vkDestroyBufferView(VkDevice device, VkBufferView bufferView, |
| 4580 | const VkAllocationCallbacks *pAllocator) { |
| 4581 | layer_data *dev_data = |
| 4582 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4583 | dev_data->device_dispatch_table->DestroyBufferView(device, bufferView, |
| 4584 | pAllocator); |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 4585 | dev_data->bufferViewMap.erase(bufferView); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4586 | } |
| 4587 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4588 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4589 | vkDestroyImage(VkDevice device, VkImage image, |
| 4590 | const VkAllocationCallbacks *pAllocator) { |
| 4591 | layer_data *dev_data = |
| 4592 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Chia-I Wu | f7458c5 | 2015-10-26 21:10:41 +0800 | [diff] [blame] | 4593 | dev_data->device_dispatch_table->DestroyImage(device, image, pAllocator); |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 4594 | dev_data->imageMap.erase(image); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4595 | } |
| 4596 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4597 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4598 | vkDestroyImageView(VkDevice device, VkImageView imageView, |
| 4599 | const VkAllocationCallbacks *pAllocator) { |
| 4600 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4601 | ->device_dispatch_table->DestroyImageView(device, imageView, |
| 4602 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4603 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4604 | } |
| 4605 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4606 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4607 | vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, |
| 4608 | const VkAllocationCallbacks *pAllocator) { |
| 4609 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4610 | ->device_dispatch_table->DestroyShaderModule(device, shaderModule, |
| 4611 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4612 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4613 | } |
| 4614 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4615 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4616 | vkDestroyPipeline(VkDevice device, VkPipeline pipeline, |
| 4617 | const VkAllocationCallbacks *pAllocator) { |
| 4618 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4619 | ->device_dispatch_table->DestroyPipeline(device, pipeline, pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4620 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4621 | } |
| 4622 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4623 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4624 | vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, |
| 4625 | const VkAllocationCallbacks *pAllocator) { |
| 4626 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4627 | ->device_dispatch_table->DestroyPipelineLayout(device, pipelineLayout, |
| 4628 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4629 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4630 | } |
| 4631 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4632 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4633 | vkDestroySampler(VkDevice device, VkSampler sampler, |
| 4634 | const VkAllocationCallbacks *pAllocator) { |
| 4635 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4636 | ->device_dispatch_table->DestroySampler(device, sampler, pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4637 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4638 | } |
| 4639 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4640 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4641 | vkDestroyDescriptorSetLayout(VkDevice device, |
| 4642 | VkDescriptorSetLayout descriptorSetLayout, |
| 4643 | const VkAllocationCallbacks *pAllocator) { |
| 4644 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4645 | ->device_dispatch_table->DestroyDescriptorSetLayout( |
| 4646 | device, descriptorSetLayout, pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4647 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4648 | } |
| 4649 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4650 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4651 | vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, |
| 4652 | const VkAllocationCallbacks *pAllocator) { |
| 4653 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4654 | ->device_dispatch_table->DestroyDescriptorPool(device, descriptorPool, |
| 4655 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4656 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4657 | } |
| 4658 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4659 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4660 | vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, |
| 4661 | uint32_t count, |
| 4662 | const VkCommandBuffer *pCommandBuffers) { |
| 4663 | layer_data *dev_data = |
| 4664 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4665 | |
Courtney Goeltzenleuchter | 5123947 | 2015-12-16 16:06:06 -0700 | [diff] [blame] | 4666 | for (uint32_t i = 0; i < count; i++) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4667 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4668 | // Delete CB information structure, and remove from commandBufferMap |
| 4669 | auto cb = dev_data->commandBufferMap.find(pCommandBuffers[i]); |
| 4670 | if (cb != dev_data->commandBufferMap.end()) { |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 4671 | // reset prior to delete for data clean-up |
| 4672 | resetCB(dev_data, (*cb).second->commandBuffer); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4673 | delete (*cb).second; |
| 4674 | dev_data->commandBufferMap.erase(cb); |
| 4675 | } |
| 4676 | |
| 4677 | // Remove commandBuffer reference from commandPoolMap |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4678 | dev_data->commandPoolMap[commandPool].commandBuffers.remove( |
| 4679 | pCommandBuffers[i]); |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 4680 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4681 | } |
| 4682 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4683 | dev_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, |
| 4684 | count, pCommandBuffers); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4685 | } |
| 4686 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4687 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4688 | vkCreateCommandPool(VkDevice device, |
| 4689 | const VkCommandPoolCreateInfo *pCreateInfo, |
| 4690 | const VkAllocationCallbacks *pAllocator, |
| 4691 | VkCommandPool *pCommandPool) { |
| 4692 | layer_data *dev_data = |
| 4693 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4694 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4695 | VkResult result = dev_data->device_dispatch_table->CreateCommandPool( |
| 4696 | device, pCreateInfo, pAllocator, pCommandPool); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4697 | |
| 4698 | if (VK_SUCCESS == result) { |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 4699 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4700 | dev_data->commandPoolMap[*pCommandPool].createFlags = |
| 4701 | pCreateInfo->flags; |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 4702 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4703 | } |
| 4704 | return result; |
| 4705 | } |
Michael Lentine | e063fe4 | 2016-01-27 17:52:20 -0600 | [diff] [blame] | 4706 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4707 | VkBool32 validateCommandBuffersNotInUse(const layer_data *dev_data, |
| 4708 | VkCommandPool commandPool) { |
Mark Young | baa677f | 2016-01-28 09:36:15 -0700 | [diff] [blame] | 4709 | VkBool32 skipCall = VK_FALSE; |
Michael Lentine | e063fe4 | 2016-01-27 17:52:20 -0600 | [diff] [blame] | 4710 | loader_platform_thread_lock_mutex(&globalLock); |
| 4711 | auto pool_data = dev_data->commandPoolMap.find(commandPool); |
| 4712 | if (pool_data != dev_data->commandPoolMap.end()) { |
| 4713 | for (auto cmdBuffer : pool_data->second.commandBuffers) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4714 | if (dev_data->globalInFlightCmdBuffers.count(cmdBuffer)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4715 | skipCall |= log_msg( |
| 4716 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 4717 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, |
| 4718 | (uint64_t)(commandPool), __LINE__, DRAWSTATE_OBJECT_INUSE, |
| 4719 | "DS", |
| 4720 | "Cannot reset command pool %" PRIx64 |
| 4721 | " when allocated command buffer %" PRIx64 " is in use.", |
| 4722 | (uint64_t)(commandPool), (uint64_t)(cmdBuffer)); |
Michael Lentine | e063fe4 | 2016-01-27 17:52:20 -0600 | [diff] [blame] | 4723 | } |
| 4724 | } |
| 4725 | } |
| 4726 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Young | baa677f | 2016-01-28 09:36:15 -0700 | [diff] [blame] | 4727 | return skipCall; |
Michael Lentine | e063fe4 | 2016-01-27 17:52:20 -0600 | [diff] [blame] | 4728 | } |
| 4729 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4730 | // Destroy commandPool along with all of the commandBuffers allocated from that |
| 4731 | // pool |
| 4732 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4733 | vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, |
| 4734 | const VkAllocationCallbacks *pAllocator) { |
| 4735 | layer_data *dev_data = |
| 4736 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 4737 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4738 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4739 | // Must remove cmdpool from cmdpoolmap, after removing all cmdbuffers in its |
| 4740 | // list from the commandPoolMap |
| 4741 | if (dev_data->commandPoolMap.find(commandPool) != |
| 4742 | dev_data->commandPoolMap.end()) { |
| 4743 | for (auto poolCb = |
| 4744 | dev_data->commandPoolMap[commandPool].commandBuffers.begin(); |
| 4745 | poolCb != |
| 4746 | dev_data->commandPoolMap[commandPool].commandBuffers.end();) { |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4747 | auto del_cb = dev_data->commandBufferMap.find(*poolCb); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4748 | delete (*del_cb).second; // delete CB info structure |
| 4749 | dev_data->commandBufferMap.erase( |
| 4750 | del_cb); // Remove this command buffer from cbMap |
| 4751 | poolCb = dev_data->commandPoolMap[commandPool].commandBuffers.erase( |
| 4752 | poolCb); // Remove CB reference from commandPoolMap's list |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 4753 | } |
| 4754 | } |
| 4755 | dev_data->commandPoolMap.erase(commandPool); |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 4756 | |
| 4757 | loader_platform_thread_unlock_mutex(&globalLock); |
Michael Lentine | e063fe4 | 2016-01-27 17:52:20 -0600 | [diff] [blame] | 4758 | |
Mark Young | baa677f | 2016-01-28 09:36:15 -0700 | [diff] [blame] | 4759 | if (VK_TRUE == validateCommandBuffersNotInUse(dev_data, commandPool)) |
Michael Lentine | e063fe4 | 2016-01-27 17:52:20 -0600 | [diff] [blame] | 4760 | return; |
| 4761 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4762 | dev_data->device_dispatch_table->DestroyCommandPool(device, commandPool, |
| 4763 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4764 | } |
| 4765 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4766 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4767 | vkResetCommandPool(VkDevice device, VkCommandPool commandPool, |
| 4768 | VkCommandPoolResetFlags flags) { |
| 4769 | layer_data *dev_data = |
| 4770 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4771 | VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 4772 | |
Mark Young | baa677f | 2016-01-28 09:36:15 -0700 | [diff] [blame] | 4773 | if (VK_TRUE == validateCommandBuffersNotInUse(dev_data, commandPool)) |
Michael Lentine | d2a7d63 | 2016-01-27 17:02:39 -0600 | [diff] [blame] | 4774 | return VK_ERROR_VALIDATION_FAILED_EXT; |
| 4775 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4776 | result = dev_data->device_dispatch_table->ResetCommandPool( |
| 4777 | device, commandPool, flags); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 4778 | // Reset all of the CBs allocated from this pool |
| 4779 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4780 | loader_platform_thread_lock_mutex(&globalLock); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 4781 | auto it = dev_data->commandPoolMap[commandPool].commandBuffers.begin(); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4782 | while (it != |
| 4783 | dev_data->commandPoolMap[commandPool].commandBuffers.end()) { |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 4784 | resetCB(dev_data, (*it)); |
| 4785 | ++it; |
| 4786 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 4787 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 4788 | } |
| 4789 | return result; |
| 4790 | } |
| 4791 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4792 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4793 | vkDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, |
| 4794 | const VkAllocationCallbacks *pAllocator) { |
| 4795 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4796 | ->device_dispatch_table->DestroyFramebuffer(device, framebuffer, |
| 4797 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4798 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4799 | } |
| 4800 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4801 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 4802 | vkDestroyRenderPass(VkDevice device, VkRenderPass renderPass, |
| 4803 | const VkAllocationCallbacks *pAllocator) { |
| 4804 | get_my_data_ptr(get_dispatch_key(device), layer_data_map) |
| 4805 | ->device_dispatch_table->DestroyRenderPass(device, renderPass, |
| 4806 | pAllocator); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 4807 | // TODO : Clean up any internal data structures using this obj. |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 4808 | } |
| 4809 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4810 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4811 | vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, |
| 4812 | const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) { |
| 4813 | layer_data *dev_data = |
| 4814 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4815 | VkResult result = dev_data->device_dispatch_table->CreateBuffer( |
| 4816 | device, pCreateInfo, pAllocator, pBuffer); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 4817 | if (VK_SUCCESS == result) { |
| 4818 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4819 | // TODO : This doesn't create deep copy of pQueueFamilyIndices so need |
| 4820 | // to fix that if/when we want that data to be valid |
| 4821 | dev_data->bufferMap[*pBuffer].create_info = |
| 4822 | unique_ptr<VkBufferCreateInfo>( |
| 4823 | new VkBufferCreateInfo(*pCreateInfo)); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 4824 | dev_data->bufferMap[*pBuffer].in_use.store(0); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 4825 | loader_platform_thread_unlock_mutex(&globalLock); |
| 4826 | } |
| 4827 | return result; |
| 4828 | } |
| 4829 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4830 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4831 | vkCreateBufferView(VkDevice device, |
| 4832 | const VkBufferViewCreateInfo *pCreateInfo, |
| 4833 | const VkAllocationCallbacks *pAllocator, |
| 4834 | VkBufferView *pView) { |
| 4835 | layer_data *dev_data = |
| 4836 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4837 | VkResult result = dev_data->device_dispatch_table->CreateBufferView( |
| 4838 | device, pCreateInfo, pAllocator, pView); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 4839 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 4840 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4841 | dev_data->bufferViewMap[*pView] = unique_ptr<VkBufferViewCreateInfo>( |
| 4842 | new VkBufferViewCreateInfo(*pCreateInfo)); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 4843 | loader_platform_thread_unlock_mutex(&globalLock); |
| 4844 | } |
| 4845 | return result; |
| 4846 | } |
| 4847 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4848 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4849 | vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, |
| 4850 | const VkAllocationCallbacks *pAllocator, VkImage *pImage) { |
| 4851 | layer_data *dev_data = |
| 4852 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4853 | VkResult result = dev_data->device_dispatch_table->CreateImage( |
| 4854 | device, pCreateInfo, pAllocator, pImage); |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 4855 | if (VK_SUCCESS == result) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4856 | IMAGE_NODE *image_node = new IMAGE_NODE; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 4857 | image_node->layout = pCreateInfo->initialLayout; |
Tobin Ehlis | 75cd1c5 | 2016-01-21 10:21:04 -0700 | [diff] [blame] | 4858 | image_node->format = pCreateInfo->format; |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 4859 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4860 | dev_data->imageMap[*pImage] = |
| 4861 | unique_ptr<VkImageCreateInfo>(new VkImageCreateInfo(*pCreateInfo)); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 4862 | dev_data->imageLayoutMap[*pImage] = image_node; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 4863 | loader_platform_thread_unlock_mutex(&globalLock); |
| 4864 | } |
| 4865 | return result; |
| 4866 | } |
| 4867 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4868 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4869 | vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, |
| 4870 | const VkAllocationCallbacks *pAllocator, |
| 4871 | VkImageView *pView) { |
| 4872 | layer_data *dev_data = |
| 4873 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4874 | VkResult result = dev_data->device_dispatch_table->CreateImageView( |
| 4875 | device, pCreateInfo, pAllocator, pView); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 4876 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 4877 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4878 | dev_data->imageViewMap[*pView] = unique_ptr<VkImageViewCreateInfo>( |
| 4879 | new VkImageViewCreateInfo(*pCreateInfo)); |
Tobin Ehlis | 53eddda | 2015-07-01 16:46:13 -0600 | [diff] [blame] | 4880 | loader_platform_thread_unlock_mutex(&globalLock); |
| 4881 | } |
| 4882 | return result; |
| 4883 | } |
| 4884 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4885 | // TODO handle pipeline caches |
| 4886 | VKAPI_ATTR VkResult VKAPI_CALL |
| 4887 | vkCreatePipelineCache(VkDevice device, |
| 4888 | const VkPipelineCacheCreateInfo *pCreateInfo, |
| 4889 | const VkAllocationCallbacks *pAllocator, |
| 4890 | VkPipelineCache *pPipelineCache) { |
| 4891 | layer_data *dev_data = |
| 4892 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4893 | VkResult result = dev_data->device_dispatch_table->CreatePipelineCache( |
| 4894 | device, pCreateInfo, pAllocator, pPipelineCache); |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 4895 | return result; |
| 4896 | } |
| 4897 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4898 | VKAPI_ATTR void VKAPI_CALL |
| 4899 | vkDestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, |
| 4900 | const VkAllocationCallbacks *pAllocator) { |
| 4901 | layer_data *dev_data = |
| 4902 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4903 | dev_data->device_dispatch_table->DestroyPipelineCache(device, pipelineCache, |
| 4904 | pAllocator); |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 4905 | } |
| 4906 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4907 | VKAPI_ATTR VkResult VKAPI_CALL |
| 4908 | vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, |
| 4909 | size_t *pDataSize, void *pData) { |
| 4910 | layer_data *dev_data = |
| 4911 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4912 | VkResult result = dev_data->device_dispatch_table->GetPipelineCacheData( |
| 4913 | device, pipelineCache, pDataSize, pData); |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 4914 | return result; |
| 4915 | } |
| 4916 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4917 | VKAPI_ATTR VkResult VKAPI_CALL |
| 4918 | vkMergePipelineCaches(VkDevice device, VkPipelineCache dstCache, |
| 4919 | uint32_t srcCacheCount, |
| 4920 | const VkPipelineCache *pSrcCaches) { |
| 4921 | layer_data *dev_data = |
| 4922 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 4923 | VkResult result = dev_data->device_dispatch_table->MergePipelineCaches( |
| 4924 | device, dstCache, srcCacheCount, pSrcCaches); |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 4925 | return result; |
| 4926 | } |
| 4927 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4928 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4929 | vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, |
| 4930 | uint32_t count, |
| 4931 | const VkGraphicsPipelineCreateInfo *pCreateInfos, |
| 4932 | const VkAllocationCallbacks *pAllocator, |
| 4933 | VkPipeline *pPipelines) { |
Courtney Goeltzenleuchter | ed89407 | 2015-09-04 13:39:59 -0600 | [diff] [blame] | 4934 | VkResult result = VK_SUCCESS; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4935 | // TODO What to do with pipelineCache? |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4936 | // The order of operations here is a little convoluted but gets the job done |
| 4937 | // 1. Pipeline create state is first shadowed into PIPELINE_NODE struct |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4938 | // 2. Create state is then validated (which uses flags setup during |
| 4939 | // shadowing) |
| 4940 | // 3. If everything looks good, we'll then create the pipeline and add NODE |
| 4941 | // to pipelineMap |
Tobin Ehlis | 11efc30 | 2015-09-16 10:33:53 -0600 | [diff] [blame] | 4942 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4943 | // TODO : Improve this data struct w/ unique_ptrs so cleanup below is |
| 4944 | // automatic |
| 4945 | vector<PIPELINE_NODE *> pPipeNode(count); |
| 4946 | layer_data *dev_data = |
| 4947 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4948 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4949 | uint32_t i = 0; |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4950 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4951 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4952 | for (i = 0; i < count; i++) { |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4953 | pPipeNode[i] = initGraphicsPipeline(dev_data, &pCreateInfos[i], NULL); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 4954 | skipCall |= verifyPipelineCreateState(dev_data, device, pPipeNode[i]); |
Tobin Ehlis | 11efc30 | 2015-09-16 10:33:53 -0600 | [diff] [blame] | 4955 | } |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4956 | |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4957 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 4958 | |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 4959 | if (VK_FALSE == skipCall) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4960 | result = dev_data->device_dispatch_table->CreateGraphicsPipelines( |
| 4961 | device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines); |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4962 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4963 | for (i = 0; i < count; i++) { |
Tobin Ehlis | 11efc30 | 2015-09-16 10:33:53 -0600 | [diff] [blame] | 4964 | pPipeNode[i]->pipeline = pPipelines[i]; |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 4965 | dev_data->pipelineMap[pPipeNode[i]->pipeline] = pPipeNode[i]; |
Tobin Ehlis | 11efc30 | 2015-09-16 10:33:53 -0600 | [diff] [blame] | 4966 | } |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4967 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 4968 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4969 | for (i = 0; i < count; i++) { |
Tobin Ehlis | 11efc30 | 2015-09-16 10:33:53 -0600 | [diff] [blame] | 4970 | if (pPipeNode[i]) { |
| 4971 | // If we allocated a pipeNode, need to clean it up here |
| 4972 | delete[] pPipeNode[i]->pVertexBindingDescriptions; |
| 4973 | delete[] pPipeNode[i]->pVertexAttributeDescriptions; |
| 4974 | delete[] pPipeNode[i]->pAttachments; |
| 4975 | delete pPipeNode[i]; |
| 4976 | } |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4977 | } |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 4978 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 75283bf | 2015-06-18 15:59:33 -0600 | [diff] [blame] | 4979 | } |
Courtney Goeltzenleuchter | e2aaad0 | 2015-04-13 16:16:04 -0600 | [diff] [blame] | 4980 | return result; |
| 4981 | } |
| 4982 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4983 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 4984 | vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, |
| 4985 | uint32_t count, |
| 4986 | const VkComputePipelineCreateInfo *pCreateInfos, |
| 4987 | const VkAllocationCallbacks *pAllocator, |
| 4988 | VkPipeline *pPipelines) { |
| 4989 | VkResult result = VK_SUCCESS; |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4990 | VkBool32 skipCall = VK_FALSE; |
| 4991 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4992 | // TODO : Improve this data struct w/ unique_ptrs so cleanup below is |
| 4993 | // automatic |
| 4994 | vector<PIPELINE_NODE *> pPipeNode(count); |
| 4995 | layer_data *dev_data = |
| 4996 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4997 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 4998 | uint32_t i = 0; |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 4999 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5000 | for (i = 0; i < count; i++) { |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5001 | // TODO: Verify compute stage bits |
| 5002 | |
| 5003 | // Create and initialize internal tracking data structure |
| 5004 | pPipeNode[i] = new PIPELINE_NODE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5005 | memcpy(&pPipeNode[i]->computePipelineCI, (const void *)&pCreateInfos[i], |
| 5006 | sizeof(VkComputePipelineCreateInfo)); |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5007 | |
| 5008 | // TODO: Add Compute Pipeline Verification |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5009 | // skipCall |= verifyPipelineCreateState(dev_data, device, |
| 5010 | // pPipeNode[i]); |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5011 | } |
| 5012 | loader_platform_thread_unlock_mutex(&globalLock); |
| 5013 | |
| 5014 | if (VK_FALSE == skipCall) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5015 | result = dev_data->device_dispatch_table->CreateComputePipelines( |
| 5016 | device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines); |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5017 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5018 | for (i = 0; i < count; i++) { |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5019 | pPipeNode[i]->pipeline = pPipelines[i]; |
| 5020 | dev_data->pipelineMap[pPipeNode[i]->pipeline] = pPipeNode[i]; |
| 5021 | } |
| 5022 | loader_platform_thread_unlock_mutex(&globalLock); |
| 5023 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5024 | for (i = 0; i < count; i++) { |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5025 | if (pPipeNode[i]) { |
| 5026 | // Clean up any locally allocated data structures |
| 5027 | delete pPipeNode[i]; |
| 5028 | } |
| 5029 | } |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5030 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 5031 | } |
| 5032 | return result; |
| 5033 | } |
| 5034 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5035 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5036 | vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, |
| 5037 | const VkAllocationCallbacks *pAllocator, |
| 5038 | VkSampler *pSampler) { |
| 5039 | layer_data *dev_data = |
| 5040 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5041 | VkResult result = dev_data->device_dispatch_table->CreateSampler( |
| 5042 | device, pCreateInfo, pAllocator, pSampler); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5043 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5044 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5045 | dev_data->sampleMap[*pSampler] = |
| 5046 | unique_ptr<SAMPLER_NODE>(new SAMPLER_NODE(pSampler, pCreateInfo)); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5047 | loader_platform_thread_unlock_mutex(&globalLock); |
| 5048 | } |
| 5049 | return result; |
| 5050 | } |
| 5051 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5052 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( |
| 5053 | VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, |
| 5054 | const VkAllocationCallbacks *pAllocator, |
| 5055 | VkDescriptorSetLayout *pSetLayout) { |
| 5056 | layer_data *dev_data = |
| 5057 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5058 | VkResult result = |
| 5059 | dev_data->device_dispatch_table->CreateDescriptorSetLayout( |
| 5060 | device, pCreateInfo, pAllocator, pSetLayout); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5061 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 5062 | // TODOSC : Capture layout bindings set |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5063 | LAYOUT_NODE *pNewNode = new LAYOUT_NODE; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5064 | if (NULL == pNewNode) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5065 | if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5066 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, |
| 5067 | (uint64_t)*pSetLayout, __LINE__, |
| 5068 | DRAWSTATE_OUT_OF_MEMORY, "DS", |
| 5069 | "Out of memory while attempting to allocate " |
| 5070 | "LAYOUT_NODE in vkCreateDescriptorSetLayout()")) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5071 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5072 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5073 | memcpy((void *)&pNewNode->createInfo, pCreateInfo, |
| 5074 | sizeof(VkDescriptorSetLayoutCreateInfo)); |
| 5075 | pNewNode->createInfo.pBindings = |
| 5076 | new VkDescriptorSetLayoutBinding[pCreateInfo->bindingCount]; |
| 5077 | memcpy((void *)pNewNode->createInfo.pBindings, pCreateInfo->pBindings, |
| 5078 | sizeof(VkDescriptorSetLayoutBinding) * |
| 5079 | pCreateInfo->bindingCount); |
Chia-I Wu | d46e6ae | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 5080 | // g++ does not like reserve with size 0 |
| 5081 | if (pCreateInfo->bindingCount) |
| 5082 | pNewNode->bindings.reserve(pCreateInfo->bindingCount); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5083 | uint32_t totalCount = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5084 | for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { |
| 5085 | if (!pNewNode->bindings.insert(pCreateInfo->pBindings[i].binding) |
| 5086 | .second) { |
| 5087 | if (log_msg( |
| 5088 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5089 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, |
| 5090 | (uint64_t)*pSetLayout, __LINE__, |
| 5091 | DRAWSTATE_INVALID_LAYOUT, "DS", |
| 5092 | "duplicated binding number in " |
| 5093 | "VkDescriptorSetLayoutBinding")) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5094 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Chia-I Wu | d46e6ae | 2015-10-31 00:31:16 +0800 | [diff] [blame] | 5095 | } |
| 5096 | |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 5097 | totalCount += pCreateInfo->pBindings[i].descriptorCount; |
| 5098 | if (pCreateInfo->pBindings[i].pImmutableSamplers) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5099 | VkSampler **ppIS = |
| 5100 | (VkSampler **)&pNewNode->createInfo.pBindings[i] |
| 5101 | .pImmutableSamplers; |
| 5102 | *ppIS = |
| 5103 | new VkSampler[pCreateInfo->pBindings[i].descriptorCount]; |
| 5104 | memcpy(*ppIS, pCreateInfo->pBindings[i].pImmutableSamplers, |
| 5105 | pCreateInfo->pBindings[i].descriptorCount * |
| 5106 | sizeof(VkSampler)); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5107 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5108 | } |
Tobin Ehlis | 43c39c0 | 2016-01-11 13:18:40 -0700 | [diff] [blame] | 5109 | pNewNode->layout = *pSetLayout; |
| 5110 | pNewNode->startIndex = 0; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5111 | if (totalCount > 0) { |
Cody Northrop | 43751cc | 2015-10-26 14:07:35 -0600 | [diff] [blame] | 5112 | pNewNode->descriptorTypes.resize(totalCount); |
Tobin Ehlis | a1f9b64 | 2015-10-27 12:25:35 -0600 | [diff] [blame] | 5113 | pNewNode->stageFlags.resize(totalCount); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5114 | uint32_t offset = 0; |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5115 | uint32_t j = 0; |
Tobin Ehlis | da2f0d0 | 2015-11-04 12:28:28 -0700 | [diff] [blame] | 5116 | VkDescriptorType dType; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5117 | for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { |
Jon Ashburn | 6e23c1f | 2015-12-30 18:01:16 -0700 | [diff] [blame] | 5118 | dType = pCreateInfo->pBindings[i].descriptorType; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5119 | for (j = 0; j < pCreateInfo->pBindings[i].descriptorCount; |
| 5120 | j++) { |
Tobin Ehlis | da2f0d0 | 2015-11-04 12:28:28 -0700 | [diff] [blame] | 5121 | pNewNode->descriptorTypes[offset + j] = dType; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5122 | pNewNode->stageFlags[offset + j] = |
| 5123 | pCreateInfo->pBindings[i].stageFlags; |
Tobin Ehlis | da2f0d0 | 2015-11-04 12:28:28 -0700 | [diff] [blame] | 5124 | if ((dType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) || |
| 5125 | (dType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) { |
| 5126 | pNewNode->dynamicDescriptorCount++; |
| 5127 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5128 | } |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5129 | offset += j; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5130 | } |
Tobin Ehlis | 43c39c0 | 2016-01-11 13:18:40 -0700 | [diff] [blame] | 5131 | pNewNode->endIndex = pNewNode->startIndex + totalCount - 1; |
| 5132 | } else { // no descriptors |
| 5133 | pNewNode->endIndex = 0; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5134 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5135 | // Put new node at Head of global Layer list |
| 5136 | loader_platform_thread_lock_mutex(&globalLock); |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 5137 | dev_data->descriptorSetLayoutMap[*pSetLayout] = pNewNode; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5138 | loader_platform_thread_unlock_mutex(&globalLock); |
| 5139 | } |
| 5140 | return result; |
| 5141 | } |
| 5142 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5143 | VKAPI_ATTR VkResult VKAPI_CALL |
| 5144 | vkCreatePipelineLayout(VkDevice device, |
| 5145 | const VkPipelineLayoutCreateInfo *pCreateInfo, |
| 5146 | const VkAllocationCallbacks *pAllocator, |
| 5147 | VkPipelineLayout *pPipelineLayout) { |
| 5148 | layer_data *dev_data = |
| 5149 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5150 | VkResult result = dev_data->device_dispatch_table->CreatePipelineLayout( |
| 5151 | device, pCreateInfo, pAllocator, pPipelineLayout); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5152 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 5153 | // TODOSC : Merge capture of the setLayouts per pipeline |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5154 | PIPELINE_LAYOUT_NODE &plNode = |
| 5155 | dev_data->pipelineLayoutMap[*pPipelineLayout]; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 5156 | plNode.descriptorSetLayouts.resize(pCreateInfo->setLayoutCount); |
Tobin Ehlis | 644ff04 | 2015-10-20 10:11:55 -0600 | [diff] [blame] | 5157 | uint32_t i = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5158 | for (i = 0; i < pCreateInfo->setLayoutCount; ++i) { |
Tobin Ehlis | 644ff04 | 2015-10-20 10:11:55 -0600 | [diff] [blame] | 5159 | plNode.descriptorSetLayouts[i] = pCreateInfo->pSetLayouts[i]; |
| 5160 | } |
Cody Northrop | 43751cc | 2015-10-26 14:07:35 -0600 | [diff] [blame] | 5161 | plNode.pushConstantRanges.resize(pCreateInfo->pushConstantRangeCount); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5162 | for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { |
Tobin Ehlis | 644ff04 | 2015-10-20 10:11:55 -0600 | [diff] [blame] | 5163 | plNode.pushConstantRanges[i] = pCreateInfo->pPushConstantRanges[i]; |
| 5164 | } |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5165 | } |
| 5166 | return result; |
| 5167 | } |
| 5168 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5169 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5170 | vkCreateDescriptorPool(VkDevice device, |
| 5171 | const VkDescriptorPoolCreateInfo *pCreateInfo, |
| 5172 | const VkAllocationCallbacks *pAllocator, |
| 5173 | VkDescriptorPool *pDescriptorPool) { |
| 5174 | layer_data *dev_data = |
| 5175 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5176 | VkResult result = dev_data->device_dispatch_table->CreateDescriptorPool( |
| 5177 | device, pCreateInfo, pAllocator, pDescriptorPool); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5178 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5179 | // Insert this pool into Global Pool LL at head |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5180 | if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 5181 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, |
| 5182 | (uint64_t)*pDescriptorPool, __LINE__, |
| 5183 | DRAWSTATE_OUT_OF_MEMORY, "DS", |
| 5184 | "Created Descriptor Pool %#" PRIxLEAST64, |
| 5185 | (uint64_t)*pDescriptorPool)) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5186 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5187 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5188 | DESCRIPTOR_POOL_NODE *pNewNode = |
| 5189 | new DESCRIPTOR_POOL_NODE(*pDescriptorPool, pCreateInfo); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5190 | if (NULL == pNewNode) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5191 | if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5192 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, |
| 5193 | (uint64_t)*pDescriptorPool, __LINE__, |
| 5194 | DRAWSTATE_OUT_OF_MEMORY, "DS", |
| 5195 | "Out of memory while attempting to allocate " |
| 5196 | "DESCRIPTOR_POOL_NODE in vkCreateDescriptorPool()")) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5197 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 5198 | } else { |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 5199 | dev_data->descriptorPoolMap[*pDescriptorPool] = pNewNode; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5200 | } |
| 5201 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 5202 | } else { |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5203 | // Need to do anything if pool create fails? |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5204 | } |
| 5205 | return result; |
| 5206 | } |
| 5207 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5208 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5209 | vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, |
| 5210 | VkDescriptorPoolResetFlags flags) { |
| 5211 | layer_data *dev_data = |
| 5212 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5213 | VkResult result = dev_data->device_dispatch_table->ResetDescriptorPool( |
| 5214 | device, descriptorPool, flags); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5215 | if (VK_SUCCESS == result) { |
Courtney Goeltzenleuchter | bee18a9 | 2015-10-23 14:21:05 -0600 | [diff] [blame] | 5216 | clearDescriptorPool(dev_data, device, descriptorPool, flags); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5217 | } |
| 5218 | return result; |
| 5219 | } |
| 5220 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5221 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5222 | vkAllocateDescriptorSets(VkDevice device, |
| 5223 | const VkDescriptorSetAllocateInfo *pAllocateInfo, |
| 5224 | VkDescriptorSet *pDescriptorSets) { |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5225 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5226 | layer_data *dev_data = |
| 5227 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5228 | // Verify that requested descriptorSets are available in pool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5229 | DESCRIPTOR_POOL_NODE *pPoolNode = |
| 5230 | getPoolNode(dev_data, pAllocateInfo->descriptorPool); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5231 | if (!pPoolNode) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5232 | skipCall |= |
| 5233 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5234 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, |
| 5235 | (uint64_t)pAllocateInfo->descriptorPool, __LINE__, |
| 5236 | DRAWSTATE_INVALID_POOL, "DS", |
| 5237 | "Unable to find pool node for pool %#" PRIxLEAST64 |
| 5238 | " specified in vkAllocateDescriptorSets() call", |
| 5239 | (uint64_t)pAllocateInfo->descriptorPool); |
| 5240 | } else { // Make sure pool has all the available descriptors before calling |
| 5241 | // down chain |
| 5242 | skipCall |= validate_descriptor_availability_in_pool( |
| 5243 | dev_data, pPoolNode, pAllocateInfo->descriptorSetCount, |
| 5244 | pAllocateInfo->pSetLayouts); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5245 | } |
| 5246 | if (skipCall) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5247 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5248 | VkResult result = dev_data->device_dispatch_table->AllocateDescriptorSets( |
| 5249 | device, pAllocateInfo, pDescriptorSets); |
Cody Northrop | 1e4f802 | 2015-08-03 12:47:29 -0600 | [diff] [blame] | 5250 | if (VK_SUCCESS == result) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5251 | DESCRIPTOR_POOL_NODE *pPoolNode = |
| 5252 | getPoolNode(dev_data, pAllocateInfo->descriptorPool); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5253 | if (pPoolNode) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 5254 | if (pAllocateInfo->descriptorSetCount == 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5255 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 5256 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5257 | pAllocateInfo->descriptorSetCount, __LINE__, |
| 5258 | DRAWSTATE_NONE, "DS", |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 5259 | "AllocateDescriptorSets called with 0 count"); |
Cody Northrop | 1e4f802 | 2015-08-03 12:47:29 -0600 | [diff] [blame] | 5260 | } |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 5261 | for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5262 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 5263 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5264 | (uint64_t)pDescriptorSets[i], __LINE__, DRAWSTATE_NONE, |
| 5265 | "DS", "Created Descriptor Set %#" PRIxLEAST64, |
| 5266 | (uint64_t)pDescriptorSets[i]); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5267 | // Create new set node and add to head of pool nodes |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5268 | SET_NODE *pNewNode = new SET_NODE; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5269 | if (NULL == pNewNode) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5270 | if (log_msg(dev_data->report_data, |
| 5271 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5272 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5273 | (uint64_t)pDescriptorSets[i], __LINE__, |
| 5274 | DRAWSTATE_OUT_OF_MEMORY, "DS", |
| 5275 | "Out of memory while attempting to allocate " |
| 5276 | "SET_NODE in vkAllocateDescriptorSets()")) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5277 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 5278 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5279 | // TODO : Pool should store a total count of each type of |
| 5280 | // Descriptor available |
| 5281 | // When descriptors are allocated, decrement the count and |
| 5282 | // validate here |
| 5283 | // that the count doesn't go below 0. One reset/free need |
| 5284 | // to bump count back up. |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5285 | // Insert set at head of Set LL for this pool |
| 5286 | pNewNode->pNext = pPoolNode->pSets; |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 5287 | pNewNode->in_use.store(0); |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5288 | pPoolNode->pSets = pNewNode; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5289 | LAYOUT_NODE *pLayout = |
| 5290 | getLayoutNode(dev_data, pAllocateInfo->pSetLayouts[i]); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5291 | if (NULL == pLayout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5292 | if (log_msg( |
| 5293 | dev_data->report_data, |
| 5294 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5295 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, |
| 5296 | (uint64_t)pAllocateInfo->pSetLayouts[i], |
| 5297 | __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS", |
| 5298 | "Unable to find set layout node for layout " |
| 5299 | "%#" PRIxLEAST64 |
| 5300 | " specified in vkAllocateDescriptorSets() call", |
| 5301 | (uint64_t)pAllocateInfo->pSetLayouts[i])) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5302 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5303 | } |
Tobin Ehlis | 793ad30 | 2015-04-03 12:01:11 -0600 | [diff] [blame] | 5304 | pNewNode->pLayout = pLayout; |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 5305 | pNewNode->pool = pAllocateInfo->descriptorPool; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5306 | pNewNode->set = pDescriptorSets[i]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5307 | pNewNode->descriptorCount = pLayout->endIndex + 1; |
| 5308 | if (pNewNode->descriptorCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5309 | size_t descriptorArraySize = sizeof(GENERIC_HEADER *) * |
| 5310 | pNewNode->descriptorCount; |
| 5311 | pNewNode->ppDescriptors = |
| 5312 | new GENERIC_HEADER *[descriptorArraySize]; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5313 | memset(pNewNode->ppDescriptors, 0, descriptorArraySize); |
| 5314 | } |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 5315 | dev_data->setMap[pDescriptorSets[i]] = pNewNode; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5316 | } |
| 5317 | } |
| 5318 | } |
| 5319 | } |
| 5320 | return result; |
| 5321 | } |
| 5322 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5323 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5324 | vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, |
| 5325 | uint32_t count, |
| 5326 | const VkDescriptorSet *pDescriptorSets) { |
Tobin Ehlis | e735c69 | 2015-10-08 13:13:50 -0600 | [diff] [blame] | 5327 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5328 | layer_data *dev_data = |
| 5329 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Tobin Ehlis | 9c4f38d | 2016-01-14 12:47:19 -0700 | [diff] [blame] | 5330 | // Make sure that no sets being destroyed are in-flight |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5331 | for (uint32_t i = 0; i < count; ++i) |
| 5332 | skipCall |= validateIdleDescriptorSet(dev_data, pDescriptorSets[i], |
| 5333 | "vkFreeDesriptorSets"); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 5334 | DESCRIPTOR_POOL_NODE *pPoolNode = getPoolNode(dev_data, descriptorPool); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5335 | if (pPoolNode && |
| 5336 | !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & |
| 5337 | pPoolNode->createInfo.flags)) { |
Courtney Goeltzenleuchter | bee18a9 | 2015-10-23 14:21:05 -0600 | [diff] [blame] | 5338 | // Can't Free from a NON_FREE pool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5339 | skipCall |= |
| 5340 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5341 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, (uint64_t)device, |
| 5342 | __LINE__, DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, "DS", |
| 5343 | "It is invalid to call vkFreeDescriptorSets() with a pool " |
| 5344 | "created without setting " |
| 5345 | "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT."); |
Tobin Ehlis | e735c69 | 2015-10-08 13:13:50 -0600 | [diff] [blame] | 5346 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 5347 | if (VK_FALSE != skipCall) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5348 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5349 | VkResult result = dev_data->device_dispatch_table->FreeDescriptorSets( |
| 5350 | device, descriptorPool, count, pDescriptorSets); |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5351 | if (VK_SUCCESS == result) { |
| 5352 | // For each freed descriptor add it back into the pool as available |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5353 | for (uint32_t i = 0; i < count; ++i) { |
| 5354 | SET_NODE *pSet = |
| 5355 | dev_data->setMap[pDescriptorSets[i]]; // getSetNode() without |
| 5356 | // locking |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 5357 | invalidateBoundCmdBuffers(dev_data, pSet); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5358 | LAYOUT_NODE *pLayout = pSet->pLayout; |
Chia-I Wu | 1b99bb2 | 2015-10-27 19:25:11 +0800 | [diff] [blame] | 5359 | uint32_t typeIndex = 0, poolSizeCount = 0; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5360 | for (uint32_t j = 0; j < pLayout->createInfo.bindingCount; ++j) { |
| 5361 | typeIndex = static_cast<uint32_t>( |
| 5362 | pLayout->createInfo.pBindings[j].descriptorType); |
| 5363 | poolSizeCount = |
| 5364 | pLayout->createInfo.pBindings[j].descriptorCount; |
| 5365 | pPoolNode->availableDescriptorTypeCount[typeIndex] += |
| 5366 | poolSizeCount; |
Tobin Ehlis | f93f1e3 | 2015-10-20 16:16:04 -0600 | [diff] [blame] | 5367 | } |
| 5368 | } |
| 5369 | } |
| 5370 | // TODO : Any other clean-up or book-keeping to do here? |
Tony Barbour | 34ec692 | 2015-07-10 10:50:45 -0600 | [diff] [blame] | 5371 | return result; |
| 5372 | } |
| 5373 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5374 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5375 | vkUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, |
| 5376 | const VkWriteDescriptorSet *pDescriptorWrites, |
| 5377 | uint32_t descriptorCopyCount, |
| 5378 | const VkCopyDescriptorSet *pDescriptorCopies) { |
| 5379 | // dsUpdate will return VK_TRUE only if a bailout error occurs, so we want |
| 5380 | // to call down tree when update returns VK_FALSE |
| 5381 | layer_data *dev_data = |
| 5382 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5383 | if (!dsUpdate(dev_data, device, descriptorWriteCount, pDescriptorWrites, |
| 5384 | descriptorCopyCount, pDescriptorCopies)) { |
| 5385 | dev_data->device_dispatch_table->UpdateDescriptorSets( |
| 5386 | device, descriptorWriteCount, pDescriptorWrites, |
| 5387 | descriptorCopyCount, pDescriptorCopies); |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 5388 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5389 | } |
| 5390 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5391 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5392 | vkAllocateCommandBuffers(VkDevice device, |
| 5393 | const VkCommandBufferAllocateInfo *pCreateInfo, |
| 5394 | VkCommandBuffer *pCommandBuffer) { |
| 5395 | layer_data *dev_data = |
| 5396 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 5397 | VkResult result = dev_data->device_dispatch_table->AllocateCommandBuffers( |
| 5398 | device, pCreateInfo, pCommandBuffer); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5399 | if (VK_SUCCESS == result) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 5400 | for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) { |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 5401 | // Validate command pool |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5402 | if (dev_data->commandPoolMap.find(pCreateInfo->commandPool) != |
| 5403 | dev_data->commandPoolMap.end()) { |
Mark Lobodzinski | b8df78c | 2015-11-20 14:33:48 -0700 | [diff] [blame] | 5404 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 5405 | // Add command buffer to its commandPool map |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5406 | dev_data->commandPoolMap[pCreateInfo->commandPool] |
| 5407 | .commandBuffers.push_back(pCommandBuffer[i]); |
| 5408 | GLOBAL_CB_NODE *pCB = new GLOBAL_CB_NODE; |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 5409 | // Add command buffer to map |
| 5410 | dev_data->commandBufferMap[pCommandBuffer[i]] = pCB; |
| 5411 | resetCB(dev_data, pCommandBuffer[i]); |
| 5412 | pCB->commandBuffer = pCommandBuffer[i]; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5413 | pCB->createInfo = *pCreateInfo; |
| 5414 | pCB->device = device; |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5415 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 5416 | } |
| 5417 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5418 | } |
| 5419 | return result; |
| 5420 | } |
| 5421 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5422 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5423 | vkBeginCommandBuffer(VkCommandBuffer commandBuffer, |
| 5424 | const VkCommandBufferBeginInfo *pBeginInfo) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 5425 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5426 | layer_data *dev_data = |
| 5427 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
Mark Lobodzinski | d9139a6 | 2015-08-04 16:24:20 -0600 | [diff] [blame] | 5428 | // Validate command buffer level |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5429 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Mark Lobodzinski | d9139a6 | 2015-08-04 16:24:20 -0600 | [diff] [blame] | 5430 | if (pCB) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 5431 | if (pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) { |
| 5432 | // Secondary Command Buffer |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5433 | // TODO : Add check here from spec "If commandBuffer is a secondary |
| 5434 | // command buffer and either the |
| 5435 | // occlusionQueryEnable member of pBeginInfo is VK_FALSE, or the |
| 5436 | // precise occlusion queries feature |
| 5437 | // is not enabled, the queryFlags member of pBeginInfo must not |
| 5438 | // contain VK_QUERY_CONTROL_PRECISE_BIT" |
| 5439 | const VkCommandBufferInheritanceInfo *pInfo = |
| 5440 | pBeginInfo->pInheritanceInfo; |
| 5441 | if (pBeginInfo->flags & |
| 5442 | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { |
| 5443 | if (!pInfo->renderPass) { // renderpass should NOT be null for |
| 5444 | // an Secondary CB |
| 5445 | skipCall |= log_msg( |
| 5446 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5447 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5448 | (uint64_t)commandBuffer, __LINE__, |
| 5449 | DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS", |
| 5450 | "vkBeginCommandBuffer(): Secondary Command Buffers " |
| 5451 | "(%p) must specify a valid renderpass parameter.", |
| 5452 | (void *)commandBuffer); |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 5453 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5454 | if (!pInfo->framebuffer) { // framebuffer may be null for an |
| 5455 | // Secondary CB, but this affects |
| 5456 | // perf |
| 5457 | skipCall |= |
| 5458 | log_msg(dev_data->report_data, |
| 5459 | VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 5460 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5461 | (uint64_t)commandBuffer, __LINE__, |
| 5462 | DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS", |
| 5463 | "vkBeginCommandBuffer(): Secondary Command " |
| 5464 | "Buffers (%p) may perform better if a valid " |
| 5465 | "framebuffer parameter is specified.", |
| 5466 | (void *)commandBuffer); |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 5467 | } else { |
| 5468 | string errorString = ""; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5469 | VkRenderPass fbRP = |
| 5470 | dev_data->frameBufferMap[pInfo->framebuffer] |
| 5471 | ->renderPass; |
| 5472 | if (!verify_renderpass_compatibility( |
| 5473 | dev_data, fbRP, pInfo->renderPass, errorString)) { |
| 5474 | // renderPass that framebuffer was created with must be |
| 5475 | // compatible with local renderPass |
| 5476 | skipCall |= log_msg( |
| 5477 | dev_data->report_data, |
| 5478 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5479 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5480 | (uint64_t)commandBuffer, __LINE__, |
| 5481 | DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", |
| 5482 | "vkBeginCommandBuffer(): Secondary Command Buffer " |
| 5483 | "(%p) renderPass (%#" PRIxLEAST64 |
| 5484 | ") is incompatible w/ framebuffer (%#" PRIxLEAST64 |
| 5485 | ") w/ render pass (%#" PRIxLEAST64 ") due to: %s", |
| 5486 | (void *)commandBuffer, (uint64_t)pInfo->renderPass, |
| 5487 | (uint64_t)pInfo->framebuffer, (uint64_t)fbRP, |
| 5488 | errorString.c_str()); |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 5489 | } |
| 5490 | } |
Mark Lobodzinski | d9139a6 | 2015-08-04 16:24:20 -0600 | [diff] [blame] | 5491 | } |
| 5492 | } |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5493 | if (CB_RECORDING == pCB->state) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5494 | skipCall |= |
| 5495 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5496 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5497 | (uint64_t)commandBuffer, __LINE__, |
| 5498 | DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS", |
| 5499 | "vkBeginCommandBuffer(): Cannot call Begin on CB " |
| 5500 | "(%#" PRIxLEAST64 ") in the RECORDING state. Must " |
| 5501 | "first call vkEndCommandBuffer().", |
| 5502 | (uint64_t)commandBuffer); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5503 | } else if (CB_RECORDED == pCB->state) { |
| 5504 | VkCommandPool cmdPool = pCB->createInfo.commandPool; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5505 | if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & |
| 5506 | dev_data->commandPoolMap[cmdPool].createFlags)) { |
| 5507 | skipCall |= log_msg( |
| 5508 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5509 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5510 | (uint64_t)commandBuffer, __LINE__, |
| 5511 | DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS", |
| 5512 | "Call to vkBeginCommandBuffer() on command buffer " |
| 5513 | "(%#" PRIxLEAST64 ") attempts to implicitly reset " |
| 5514 | "cmdBuffer created from command pool " |
| 5515 | "(%#" PRIxLEAST64 |
| 5516 | ") that does NOT have the " |
| 5517 | "VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set.", |
| 5518 | (uint64_t)commandBuffer, (uint64_t)cmdPool); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5519 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5520 | loader_platform_thread_lock_mutex(&globalLock); |
Tobin Ehlis | ef69465 | 2016-01-19 12:03:34 -0700 | [diff] [blame] | 5521 | resetCB(dev_data, commandBuffer); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5522 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5523 | } |
Tobin Ehlis | ef69465 | 2016-01-19 12:03:34 -0700 | [diff] [blame] | 5524 | // Set updated state here in case implicit reset occurs above |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5525 | loader_platform_thread_lock_mutex(&globalLock); |
Tobin Ehlis | ef69465 | 2016-01-19 12:03:34 -0700 | [diff] [blame] | 5526 | pCB->state = CB_RECORDING; |
| 5527 | pCB->beginInfo = *pBeginInfo; |
Tobin Ehlis | cd5bfd8 | 2016-01-19 13:12:52 -0700 | [diff] [blame] | 5528 | if (pCB->beginInfo.pInheritanceInfo) { |
| 5529 | pCB->inheritanceInfo = *(pCB->beginInfo.pInheritanceInfo); |
| 5530 | pCB->beginInfo.pInheritanceInfo = &pCB->inheritanceInfo; |
| 5531 | } |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5532 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 59278bf | 2015-08-18 07:10:58 -0600 | [diff] [blame] | 5533 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5534 | skipCall |= log_msg( |
| 5535 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5536 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5537 | (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, |
| 5538 | "DS", "In vkBeginCommandBuffer() and unable to find CommandBuffer " |
| 5539 | "Node for CB %p!", |
| 5540 | (void *)commandBuffer); |
Mark Lobodzinski | d9139a6 | 2015-08-04 16:24:20 -0600 | [diff] [blame] | 5541 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 5542 | if (VK_FALSE != skipCall) { |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5543 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Courtney Goeltzenleuchter | 5fe086f | 2015-09-04 15:03:52 -0600 | [diff] [blame] | 5544 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5545 | VkResult result = dev_data->device_dispatch_table->BeginCommandBuffer( |
| 5546 | commandBuffer, pBeginInfo); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5547 | return result; |
| 5548 | } |
| 5549 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5550 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5551 | vkEndCommandBuffer(VkCommandBuffer commandBuffer) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5552 | VkBool32 skipCall = VK_FALSE; |
Courtney Goeltzenleuchter | ed89407 | 2015-09-04 13:39:59 -0600 | [diff] [blame] | 5553 | VkResult result = VK_SUCCESS; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5554 | layer_data *dev_data = |
| 5555 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5556 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 9c53644 | 2015-06-19 13:00:59 -0600 | [diff] [blame] | 5557 | if (pCB) { |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5558 | if (pCB->state != CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5559 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 5560 | "vkEndCommandBuffer()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5561 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5562 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5563 | if (VK_FALSE == skipCall) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5564 | result = |
| 5565 | dev_data->device_dispatch_table->EndCommandBuffer(commandBuffer); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5566 | if (VK_SUCCESS == result) { |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5567 | pCB->state = CB_RECORDED; |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5568 | // Reset CB status flags |
| 5569 | pCB->status = 0; |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 5570 | printCB(dev_data, commandBuffer); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5571 | } |
| 5572 | } else { |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5573 | result = VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5574 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5575 | return result; |
| 5576 | } |
| 5577 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5578 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 5579 | vkResetCommandBuffer(VkCommandBuffer commandBuffer, |
| 5580 | VkCommandBufferResetFlags flags) { |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5581 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5582 | layer_data *dev_data = |
| 5583 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5584 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5585 | VkCommandPool cmdPool = pCB->createInfo.commandPool; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5586 | if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & |
| 5587 | dev_data->commandPoolMap[cmdPool].createFlags)) { |
| 5588 | skipCall |= |
| 5589 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5590 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 5591 | (uint64_t)commandBuffer, __LINE__, |
| 5592 | DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS", |
| 5593 | "Attempt to reset command buffer (%#" PRIxLEAST64 |
| 5594 | ") created from command pool (%#" PRIxLEAST64 |
| 5595 | ") that does NOT have the " |
| 5596 | "VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set.", |
| 5597 | (uint64_t)commandBuffer, (uint64_t)cmdPool); |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 5598 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 5599 | if (skipCall != VK_FALSE) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 5600 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5601 | VkResult result = dev_data->device_dispatch_table->ResetCommandBuffer( |
| 5602 | commandBuffer, flags); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 5603 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5604 | loader_platform_thread_lock_mutex(&globalLock); |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 5605 | resetCB(dev_data, commandBuffer); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 5606 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5607 | } |
| 5608 | return result; |
| 5609 | } |
| 5610 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5611 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5612 | vkCmdBindPipeline(VkCommandBuffer commandBuffer, |
| 5613 | VkPipelineBindPoint pipelineBindPoint, |
| 5614 | VkPipeline pipeline) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5615 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5616 | layer_data *dev_data = |
| 5617 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5618 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5619 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5620 | skipCall |= |
| 5621 | addCmd(dev_data, pCB, CMD_BINDPIPELINE, "vkCmdBindPipeline()"); |
| 5622 | if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && |
| 5623 | (pCB->activeRenderPass)) { |
| 5624 | skipCall |= log_msg( |
| 5625 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5626 | VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, (uint64_t)pipeline, |
| 5627 | __LINE__, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS", |
| 5628 | "Incorrectly binding compute pipeline (%#" PRIxLEAST64 |
| 5629 | ") during active RenderPass (%#" PRIxLEAST64 ")", |
| 5630 | (uint64_t)pipeline, (uint64_t)pCB->activeRenderPass); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5631 | } else if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5632 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdBindPipeline"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5633 | } |
| 5634 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5635 | PIPELINE_NODE *pPN = getPipeline(dev_data, pipeline); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5636 | if (pPN) { |
| 5637 | pCB->lastBoundPipeline = pipeline; |
| 5638 | loader_platform_thread_lock_mutex(&globalLock); |
| 5639 | set_cb_pso_status(pCB, pPN); |
| 5640 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5641 | skipCall |= validatePipelineState(dev_data, pCB, pipelineBindPoint, |
| 5642 | pipeline); |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 5643 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5644 | skipCall |= log_msg( |
| 5645 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5646 | VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, (uint64_t)pipeline, |
| 5647 | __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS", |
| 5648 | "Attempt to bind Pipeline %#" PRIxLEAST64 |
| 5649 | " that doesn't exist!", |
| 5650 | (uint64_t)(pipeline)); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5651 | } |
| 5652 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5653 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5654 | dev_data->device_dispatch_table->CmdBindPipeline( |
| 5655 | commandBuffer, pipelineBindPoint, pipeline); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5656 | } |
| 5657 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5658 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5659 | vkCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, |
| 5660 | uint32_t viewportCount, const VkViewport *pViewports) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5661 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5662 | layer_data *dev_data = |
| 5663 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5664 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 9c53644 | 2015-06-19 13:00:59 -0600 | [diff] [blame] | 5665 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5666 | skipCall |= |
| 5667 | addCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5668 | loader_platform_thread_lock_mutex(&globalLock); |
| 5669 | pCB->status |= CBSTATUS_VIEWPORT_SET; |
| 5670 | pCB->viewports.resize(viewportCount); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5671 | memcpy(pCB->viewports.data(), pViewports, |
| 5672 | viewportCount * sizeof(VkViewport)); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5673 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | 9c53644 | 2015-06-19 13:00:59 -0600 | [diff] [blame] | 5674 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5675 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5676 | dev_data->device_dispatch_table->CmdSetViewport( |
| 5677 | commandBuffer, firstViewport, viewportCount, pViewports); |
Courtney Goeltzenleuchter | 078f817 | 2015-09-21 11:44:06 -0600 | [diff] [blame] | 5678 | } |
| 5679 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5680 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5681 | vkCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, |
| 5682 | uint32_t scissorCount, const VkRect2D *pScissors) { |
Courtney Goeltzenleuchter | 078f817 | 2015-09-21 11:44:06 -0600 | [diff] [blame] | 5683 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5684 | layer_data *dev_data = |
| 5685 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5686 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Courtney Goeltzenleuchter | 078f817 | 2015-09-21 11:44:06 -0600 | [diff] [blame] | 5687 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5688 | skipCall |= |
| 5689 | addCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5690 | loader_platform_thread_lock_mutex(&globalLock); |
| 5691 | pCB->status |= CBSTATUS_SCISSOR_SET; |
| 5692 | pCB->scissors.resize(scissorCount); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5693 | memcpy(pCB->scissors.data(), pScissors, |
| 5694 | scissorCount * sizeof(VkRect2D)); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5695 | loader_platform_thread_unlock_mutex(&globalLock); |
Courtney Goeltzenleuchter | 078f817 | 2015-09-21 11:44:06 -0600 | [diff] [blame] | 5696 | } |
| 5697 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5698 | dev_data->device_dispatch_table->CmdSetScissor( |
| 5699 | commandBuffer, firstScissor, scissorCount, pScissors); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5700 | } |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5701 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5702 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5703 | vkCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5704 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5705 | layer_data *dev_data = |
| 5706 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5707 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5708 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5709 | skipCall |= |
| 5710 | addCmd(dev_data, pCB, CMD_SETLINEWIDTHSTATE, "vkCmdSetLineWidth()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5711 | /* TODO: Do we still need this lock? */ |
| 5712 | loader_platform_thread_lock_mutex(&globalLock); |
| 5713 | pCB->status |= CBSTATUS_LINE_WIDTH_SET; |
| 5714 | pCB->lineWidth = lineWidth; |
| 5715 | loader_platform_thread_unlock_mutex(&globalLock); |
Cody Northrop | 1236511 | 2015-08-17 11:10:49 -0600 | [diff] [blame] | 5716 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5717 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5718 | dev_data->device_dispatch_table->CmdSetLineWidth(commandBuffer, |
| 5719 | lineWidth); |
Cody Northrop | 1236511 | 2015-08-17 11:10:49 -0600 | [diff] [blame] | 5720 | } |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5721 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5722 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5723 | vkCmdSetDepthBias(VkCommandBuffer commandBuffer, |
| 5724 | float depthBiasConstantFactor, float depthBiasClamp, |
| 5725 | float depthBiasSlopeFactor) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5726 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5727 | layer_data *dev_data = |
| 5728 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5729 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Cody Northrop | 1236511 | 2015-08-17 11:10:49 -0600 | [diff] [blame] | 5730 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5731 | skipCall |= |
| 5732 | addCmd(dev_data, pCB, CMD_SETDEPTHBIASSTATE, "vkCmdSetDepthBias()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5733 | pCB->status |= CBSTATUS_DEPTH_BIAS_SET; |
| 5734 | pCB->depthBiasConstantFactor = depthBiasConstantFactor; |
| 5735 | pCB->depthBiasClamp = depthBiasClamp; |
| 5736 | pCB->depthBiasSlopeFactor = depthBiasSlopeFactor; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5737 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5738 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5739 | dev_data->device_dispatch_table->CmdSetDepthBias( |
| 5740 | commandBuffer, depthBiasConstantFactor, depthBiasClamp, |
| 5741 | depthBiasSlopeFactor); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5742 | } |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5743 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5744 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5745 | vkCmdSetBlendConstants(VkCommandBuffer commandBuffer, |
| 5746 | const float blendConstants[4]) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5747 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5748 | layer_data *dev_data = |
| 5749 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5750 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5751 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5752 | skipCall |= addCmd(dev_data, pCB, CMD_SETBLENDSTATE, |
| 5753 | "vkCmdSetBlendConstants()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5754 | pCB->status |= CBSTATUS_BLEND_SET; |
| 5755 | memcpy(pCB->blendConstants, blendConstants, 4 * sizeof(float)); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5756 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5757 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5758 | dev_data->device_dispatch_table->CmdSetBlendConstants(commandBuffer, |
| 5759 | blendConstants); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5760 | } |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5761 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5762 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5763 | vkCmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, |
| 5764 | float maxDepthBounds) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5765 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5766 | layer_data *dev_data = |
| 5767 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5768 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5769 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5770 | skipCall |= addCmd(dev_data, pCB, CMD_SETDEPTHBOUNDSSTATE, |
| 5771 | "vkCmdSetDepthBounds()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5772 | pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET; |
| 5773 | pCB->minDepthBounds = minDepthBounds; |
| 5774 | pCB->maxDepthBounds = maxDepthBounds; |
Cody Northrop | 82485a8 | 2015-08-18 15:21:16 -0600 | [diff] [blame] | 5775 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5776 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5777 | dev_data->device_dispatch_table->CmdSetDepthBounds( |
| 5778 | commandBuffer, minDepthBounds, maxDepthBounds); |
Cody Northrop | 82485a8 | 2015-08-18 15:21:16 -0600 | [diff] [blame] | 5779 | } |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5780 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5781 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5782 | vkCmdSetStencilCompareMask(VkCommandBuffer commandBuffer, |
| 5783 | VkStencilFaceFlags faceMask, |
| 5784 | uint32_t compareMask) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5785 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5786 | layer_data *dev_data = |
| 5787 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5788 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Cody Northrop | 82485a8 | 2015-08-18 15:21:16 -0600 | [diff] [blame] | 5789 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5790 | skipCall |= addCmd(dev_data, pCB, CMD_SETSTENCILREADMASKSTATE, |
| 5791 | "vkCmdSetStencilCompareMask()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5792 | if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { |
| 5793 | pCB->front.compareMask = compareMask; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5794 | } |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5795 | if (faceMask & VK_STENCIL_FACE_BACK_BIT) { |
| 5796 | pCB->back.compareMask = compareMask; |
| 5797 | } |
| 5798 | /* TODO: Do we need to track front and back separately? */ |
| 5799 | /* TODO: We aren't capturing the faceMask, do we need to? */ |
| 5800 | pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5801 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5802 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5803 | dev_data->device_dispatch_table->CmdSetStencilCompareMask( |
| 5804 | commandBuffer, faceMask, compareMask); |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 5805 | } |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5806 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5807 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5808 | vkCmdSetStencilWriteMask(VkCommandBuffer commandBuffer, |
| 5809 | VkStencilFaceFlags faceMask, uint32_t writeMask) { |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5810 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5811 | layer_data *dev_data = |
| 5812 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5813 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5814 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5815 | skipCall |= addCmd(dev_data, pCB, CMD_SETSTENCILWRITEMASKSTATE, |
| 5816 | "vkCmdSetStencilWriteMask()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5817 | if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { |
| 5818 | pCB->front.writeMask = writeMask; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5819 | } |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5820 | if (faceMask & VK_STENCIL_FACE_BACK_BIT) { |
| 5821 | pCB->back.writeMask = writeMask; |
| 5822 | } |
| 5823 | pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5824 | } |
| 5825 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5826 | dev_data->device_dispatch_table->CmdSetStencilWriteMask( |
| 5827 | commandBuffer, faceMask, writeMask); |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5828 | } |
| 5829 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5830 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 5831 | vkCmdSetStencilReference(VkCommandBuffer commandBuffer, |
| 5832 | VkStencilFaceFlags faceMask, uint32_t reference) { |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5833 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5834 | layer_data *dev_data = |
| 5835 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5836 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5837 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5838 | skipCall |= addCmd(dev_data, pCB, CMD_SETSTENCILREFERENCESTATE, |
| 5839 | "vkCmdSetStencilReference()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5840 | if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { |
| 5841 | pCB->front.reference = reference; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5842 | } |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 5843 | if (faceMask & VK_STENCIL_FACE_BACK_BIT) { |
| 5844 | pCB->back.reference = reference; |
| 5845 | } |
| 5846 | pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5847 | } |
| 5848 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5849 | dev_data->device_dispatch_table->CmdSetStencilReference( |
| 5850 | commandBuffer, faceMask, reference); |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 5851 | } |
| 5852 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5853 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( |
| 5854 | VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, |
| 5855 | VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, |
| 5856 | const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, |
| 5857 | const uint32_t *pDynamicOffsets) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 5858 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5859 | layer_data *dev_data = |
| 5860 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 5861 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 5862 | if (pCB) { |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5863 | if (pCB->state == CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5864 | if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && |
| 5865 | (pCB->activeRenderPass)) { |
| 5866 | skipCall |= log_msg( |
| 5867 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5868 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 5869 | DRAWSTATE_INVALID_RENDERPASS_CMD, "DS", |
| 5870 | "Incorrectly binding compute DescriptorSets during active " |
| 5871 | "RenderPass (%#" PRIxLEAST64 ")", |
| 5872 | (uint64_t)pCB->activeRenderPass); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5873 | } else if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5874 | skipCall |= |
| 5875 | outsideRenderPass(dev_data, pCB, "vkCmdBindDescriptorSets"); |
Mark Lobodzinski | 7463593 | 2015-12-18 15:35:38 -0700 | [diff] [blame] | 5876 | } |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5877 | if (VK_FALSE == skipCall) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5878 | // Track total count of dynamic descriptor types to make sure we |
| 5879 | // have an offset for each one |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5880 | uint32_t totalDynamicDescriptors = 0; |
| 5881 | string errorString = ""; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5882 | uint32_t lastSetIndex = firstSet + setCount - 1; |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5883 | if (lastSetIndex >= pCB->boundDescriptorSets.size()) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5884 | pCB->boundDescriptorSets.resize(lastSetIndex + 1); |
| 5885 | VkDescriptorSet oldFinalBoundSet = |
| 5886 | pCB->boundDescriptorSets[lastSetIndex]; |
| 5887 | for (uint32_t i = 0; i < setCount; i++) { |
| 5888 | SET_NODE *pSet = getSetNode(dev_data, pDescriptorSets[i]); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5889 | if (pSet) { |
| 5890 | loader_platform_thread_lock_mutex(&globalLock); |
Tobin Ehlis | e6e574b | 2016-01-24 23:25:31 -0700 | [diff] [blame] | 5891 | pCB->uniqueBoundSets.insert(pDescriptorSets[i]); |
| 5892 | pSet->boundCmdBuffers.insert(commandBuffer); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5893 | pCB->lastBoundDescriptorSet = pDescriptorSets[i]; |
| 5894 | pCB->lastBoundPipelineLayout = layout; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5895 | pCB->boundDescriptorSets[i + firstSet] = |
| 5896 | pDescriptorSets[i]; |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5897 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5898 | skipCall |= log_msg( |
| 5899 | dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 5900 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5901 | (uint64_t)pDescriptorSets[i], __LINE__, |
| 5902 | DRAWSTATE_NONE, "DS", |
| 5903 | "DS %#" PRIxLEAST64 " bound on pipeline %s", |
| 5904 | (uint64_t)pDescriptorSets[i], |
| 5905 | string_VkPipelineBindPoint(pipelineBindPoint)); |
| 5906 | if (!pSet->pUpdateStructs && |
| 5907 | (pSet->descriptorCount != 0)) { |
| 5908 | skipCall |= log_msg( |
| 5909 | dev_data->report_data, |
| 5910 | VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 5911 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5912 | (uint64_t)pDescriptorSets[i], __LINE__, |
| 5913 | DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS", |
| 5914 | "DS %#" PRIxLEAST64 |
| 5915 | " bound but it was never updated. You may want " |
| 5916 | "to either update it or not bind it.", |
| 5917 | (uint64_t)pDescriptorSets[i]); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5918 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5919 | // Verify that set being bound is compatible with |
| 5920 | // overlapping setLayout of pipelineLayout |
| 5921 | if (!verify_set_layout_compatibility( |
| 5922 | dev_data, pSet, layout, i + firstSet, |
| 5923 | errorString)) { |
| 5924 | skipCall |= log_msg( |
| 5925 | dev_data->report_data, |
| 5926 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5927 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5928 | (uint64_t)pDescriptorSets[i], __LINE__, |
| 5929 | DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS", |
| 5930 | "descriptorSet #%u being bound is not " |
| 5931 | "compatible with overlapping layout in " |
| 5932 | "pipelineLayout due to: %s", |
| 5933 | i, errorString.c_str()); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 5934 | } |
| 5935 | if (pSet->pLayout->dynamicDescriptorCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5936 | // First make sure we won't overstep bounds of |
| 5937 | // pDynamicOffsets array |
| 5938 | if ((totalDynamicDescriptors + |
| 5939 | pSet->pLayout->dynamicDescriptorCount) > |
| 5940 | dynamicOffsetCount) { |
| 5941 | skipCall |= log_msg( |
| 5942 | dev_data->report_data, |
| 5943 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5944 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 5945 | (uint64_t)pDescriptorSets[i], __LINE__, |
| 5946 | DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, |
| 5947 | "DS", "descriptorSet #%u (%#" PRIxLEAST64 |
| 5948 | ") requires %u dynamicOffsets, but " |
| 5949 | "only %u dynamicOffsets are left in " |
| 5950 | "pDynamicOffsets array. There must " |
| 5951 | "be one dynamic offset for each " |
| 5952 | "dynamic descriptor being bound.", |
| 5953 | i, (uint64_t)pDescriptorSets[i], |
| 5954 | pSet->pLayout->dynamicDescriptorCount, |
| 5955 | (dynamicOffsetCount - |
| 5956 | totalDynamicDescriptors)); |
| 5957 | } else { // Validate and store dynamic offsets with |
| 5958 | // the set |
Mark Lobodzinski | 941aea9 | 2016-01-13 10:23:15 -0700 | [diff] [blame] | 5959 | // Validate Dynamic Offset Minimums |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5960 | uint32_t cur_dyn_offset = |
| 5961 | totalDynamicDescriptors; |
| 5962 | for (uint32_t d = 0; d < pSet->descriptorCount; |
| 5963 | d++) { |
| 5964 | if (pSet->pLayout->descriptorTypes[i] == |
| 5965 | VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) { |
| 5966 | if (vk_safe_modulo( |
| 5967 | pDynamicOffsets[cur_dyn_offset], |
| 5968 | dev_data |
| 5969 | ->physDevPropertyMap |
| 5970 | [pCB->device] |
| 5971 | .limits |
| 5972 | .minUniformBufferOffsetAlignment) != |
| 5973 | 0) { |
| 5974 | skipCall |= log_msg( |
| 5975 | dev_data->report_data, |
| 5976 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 5977 | VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, |
| 5978 | 0, __LINE__, |
| 5979 | DRAWSTATE_INVALID_UNIFORM_BUFFER_OFFSET, |
| 5980 | "DS", "vkCmdBindDescriptorSets(" |
| 5981 | "): pDynamicOffsets[%d] " |
| 5982 | "is %d but must be a " |
| 5983 | "multiple of device " |
| 5984 | "limit " |
| 5985 | "minUniformBufferOffsetAl" |
| 5986 | "ignment %#" PRIxLEAST64, |
| 5987 | cur_dyn_offset, |
| 5988 | pDynamicOffsets[cur_dyn_offset], |
| 5989 | dev_data |
| 5990 | ->physDevPropertyMap |
| 5991 | [pCB->device] |
| 5992 | .limits |
| 5993 | .minUniformBufferOffsetAlignment); |
Mark Lobodzinski | 941aea9 | 2016-01-13 10:23:15 -0700 | [diff] [blame] | 5994 | } |
| 5995 | cur_dyn_offset++; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 5996 | } else if (pSet->pLayout |
| 5997 | ->descriptorTypes[i] == |
| 5998 | VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { |
| 5999 | if (vk_safe_modulo( |
| 6000 | pDynamicOffsets[cur_dyn_offset], |
| 6001 | dev_data |
| 6002 | ->physDevPropertyMap |
| 6003 | [pCB->device] |
| 6004 | .limits |
| 6005 | .minStorageBufferOffsetAlignment) != |
| 6006 | 0) { |
| 6007 | skipCall |= log_msg( |
| 6008 | dev_data->report_data, |
| 6009 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6010 | VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, |
| 6011 | 0, __LINE__, |
| 6012 | DRAWSTATE_INVALID_STORAGE_BUFFER_OFFSET, |
| 6013 | "DS", "vkCmdBindDescriptorSets(" |
| 6014 | "): pDynamicOffsets[%d] " |
| 6015 | "is %d but must be a " |
| 6016 | "multiple of device " |
| 6017 | "limit " |
| 6018 | "minStorageBufferOffsetAl" |
| 6019 | "ignment %#" PRIxLEAST64, |
| 6020 | cur_dyn_offset, |
| 6021 | pDynamicOffsets[cur_dyn_offset], |
| 6022 | dev_data |
| 6023 | ->physDevPropertyMap |
| 6024 | [pCB->device] |
| 6025 | .limits |
| 6026 | .minStorageBufferOffsetAlignment); |
Mark Lobodzinski | 941aea9 | 2016-01-13 10:23:15 -0700 | [diff] [blame] | 6027 | } |
| 6028 | cur_dyn_offset++; |
| 6029 | } |
| 6030 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6031 | // Keep running total of dynamic descriptor |
| 6032 | // count to verify at the end |
| 6033 | totalDynamicDescriptors += |
| 6034 | pSet->pLayout->dynamicDescriptorCount; |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6035 | } |
| 6036 | } |
| 6037 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6038 | skipCall |= log_msg( |
| 6039 | dev_data->report_data, |
| 6040 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6041 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 6042 | (uint64_t)pDescriptorSets[i], __LINE__, |
| 6043 | DRAWSTATE_INVALID_SET, "DS", |
| 6044 | "Attempt to bind DS %#" PRIxLEAST64 |
| 6045 | " that doesn't exist!", |
| 6046 | (uint64_t)pDescriptorSets[i]); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6047 | } |
| 6048 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6049 | skipCall |= addCmd(dev_data, pCB, CMD_BINDDESCRIPTORSETS, |
| 6050 | "vkCmdBindDescrsiptorSets()"); |
| 6051 | // For any previously bound sets, need to set them to "invalid" |
| 6052 | // if they were disturbed by this update |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6053 | if (firstSet > 0) { // Check set #s below the first bound set |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6054 | for (uint32_t i = 0; i < firstSet; ++i) { |
| 6055 | if (pCB->boundDescriptorSets[i] && |
| 6056 | !verify_set_layout_compatibility( |
| 6057 | dev_data, |
| 6058 | dev_data->setMap[pCB->boundDescriptorSets[i]], |
| 6059 | layout, i, errorString)) { |
| 6060 | skipCall |= log_msg( |
| 6061 | dev_data->report_data, |
| 6062 | VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 6063 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 6064 | (uint64_t)pCB->boundDescriptorSets[i], __LINE__, |
| 6065 | DRAWSTATE_NONE, "DS", |
| 6066 | "DescriptorSetDS %#" PRIxLEAST64 |
| 6067 | " previously bound as set #%u was disturbed by " |
| 6068 | "newly bound pipelineLayout (%#" PRIxLEAST64 |
| 6069 | ")", |
| 6070 | (uint64_t)pCB->boundDescriptorSets[i], i, |
| 6071 | (uint64_t)layout); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6072 | pCB->boundDescriptorSets[i] = VK_NULL_HANDLE; |
| 6073 | } |
| 6074 | } |
| 6075 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6076 | // Check if newly last bound set invalidates any remaining bound |
| 6077 | // sets |
| 6078 | if ((pCB->boundDescriptorSets.size() - 1) > (lastSetIndex)) { |
| 6079 | if (oldFinalBoundSet && |
| 6080 | !verify_set_layout_compatibility( |
| 6081 | dev_data, dev_data->setMap[oldFinalBoundSet], |
| 6082 | layout, lastSetIndex, errorString)) { |
| 6083 | skipCall |= log_msg( |
| 6084 | dev_data->report_data, |
| 6085 | VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 6086 | VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, |
| 6087 | (uint64_t)oldFinalBoundSet, __LINE__, |
| 6088 | DRAWSTATE_NONE, "DS", |
| 6089 | "DescriptorSetDS %#" PRIxLEAST64 |
| 6090 | " previously bound as set #%u is incompatible with " |
| 6091 | "set %#" PRIxLEAST64 |
| 6092 | " newly bound as set #%u so set #%u and any " |
| 6093 | "subsequent sets were disturbed by newly bound " |
| 6094 | "pipelineLayout (%#" PRIxLEAST64 ")", |
| 6095 | (uint64_t)oldFinalBoundSet, lastSetIndex, |
| 6096 | (uint64_t)pCB->boundDescriptorSets[lastSetIndex], |
| 6097 | lastSetIndex, lastSetIndex + 1, (uint64_t)layout); |
| 6098 | pCB->boundDescriptorSets.resize(lastSetIndex + 1); |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6099 | } |
| 6100 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6101 | // dynamicOffsetCount must equal the total number of dynamic |
| 6102 | // descriptors in the sets being bound |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6103 | if (totalDynamicDescriptors != dynamicOffsetCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6104 | skipCall |= log_msg( |
| 6105 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6106 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 6107 | (uint64_t)commandBuffer, __LINE__, |
| 6108 | DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, "DS", |
| 6109 | "Attempting to bind %u descriptorSets with %u dynamic " |
| 6110 | "descriptors, but dynamicOffsetCount is %u. It should " |
| 6111 | "exactly match the number of dynamic descriptors.", |
| 6112 | setCount, totalDynamicDescriptors, dynamicOffsetCount); |
Tobin Ehlis | da2f0d0 | 2015-11-04 12:28:28 -0700 | [diff] [blame] | 6113 | } |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 6114 | if (dynamicOffsetCount) { |
| 6115 | // Save dynamicOffsets bound to this CB |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6116 | pCB->dynamicOffsets.assign( |
| 6117 | pDynamicOffsets, pDynamicOffsets + dynamicOffsetCount); |
Tobin Ehlis | d239377 | 2016-01-29 11:50:47 -0700 | [diff] [blame] | 6118 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6119 | } |
Tobin Ehlis | f658505 | 2015-12-17 11:48:42 -0700 | [diff] [blame] | 6120 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6121 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 6122 | "vkCmdBindDescriptorSets()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6123 | } |
| 6124 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6125 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6126 | dev_data->device_dispatch_table->CmdBindDescriptorSets( |
| 6127 | commandBuffer, pipelineBindPoint, layout, firstSet, setCount, |
| 6128 | pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6129 | } |
| 6130 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6131 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6132 | vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, |
| 6133 | VkDeviceSize offset, VkIndexType indexType) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6134 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6135 | layer_data *dev_data = |
| 6136 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6137 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6138 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6139 | skipCall |= addCmd(dev_data, pCB, CMD_BINDINDEXBUFFER, |
| 6140 | "vkCmdBindIndexBuffer()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6141 | VkDeviceSize offset_align = 0; |
| 6142 | switch (indexType) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6143 | case VK_INDEX_TYPE_UINT16: |
| 6144 | offset_align = 2; |
| 6145 | break; |
| 6146 | case VK_INDEX_TYPE_UINT32: |
| 6147 | offset_align = 4; |
| 6148 | break; |
| 6149 | default: |
| 6150 | // ParamChecker should catch bad enum, we'll also throw alignment |
| 6151 | // error below if offset_align stays 0 |
| 6152 | break; |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6153 | } |
| 6154 | if (!offset_align || (offset % offset_align)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6155 | skipCall |= |
| 6156 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6157 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6158 | DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, "DS", |
| 6159 | "vkCmdBindIndexBuffer() offset (%#" PRIxLEAST64 |
| 6160 | ") does not fall on alignment (%s) boundary.", |
| 6161 | offset, string_VkIndexType(indexType)); |
Tobin Ehlis | 9c53644 | 2015-06-19 13:00:59 -0600 | [diff] [blame] | 6162 | } |
Tobin Ehlis | c4c2318 | 2015-09-17 12:24:13 -0600 | [diff] [blame] | 6163 | pCB->status |= CBSTATUS_INDEX_BUFFER_BOUND; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6164 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6165 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6166 | dev_data->device_dispatch_table->CmdBindIndexBuffer( |
| 6167 | commandBuffer, buffer, offset, indexType); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6168 | } |
| 6169 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6170 | void updateResourceTracking(GLOBAL_CB_NODE *pCB, uint32_t firstBinding, |
| 6171 | uint32_t bindingCount, const VkBuffer *pBuffers) { |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 6172 | uint32_t end = firstBinding + bindingCount; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6173 | if (pCB->currentDrawData.buffers.size() < end) { |
| 6174 | pCB->currentDrawData.buffers.resize(end); |
| 6175 | } |
| 6176 | for (uint32_t i = 0; i < bindingCount; ++i) { |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 6177 | pCB->currentDrawData.buffers[i + firstBinding] = pBuffers[i]; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6178 | } |
| 6179 | } |
| 6180 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6181 | void updateResourceTrackingOnDraw(GLOBAL_CB_NODE *pCB) { |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6182 | pCB->drawData.push_back(pCB->currentDrawData); |
| 6183 | } |
| 6184 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6185 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6186 | vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, |
| 6187 | uint32_t bindingCount, const VkBuffer *pBuffers, |
| 6188 | const VkDeviceSize *pOffsets) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6189 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6190 | layer_data *dev_data = |
| 6191 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6192 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6193 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6194 | addCmd(dev_data, pCB, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffer()"); |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 6195 | updateResourceTracking(pCB, firstBinding, bindingCount, pBuffers); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6196 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6197 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 6198 | "vkCmdBindVertexBuffer()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6199 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6200 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6201 | dev_data->device_dispatch_table->CmdBindVertexBuffers( |
| 6202 | commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6203 | } |
| 6204 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6205 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6206 | vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, |
| 6207 | uint32_t instanceCount, uint32_t firstVertex, |
| 6208 | uint32_t firstInstance) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6209 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6210 | layer_data *dev_data = |
| 6211 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6212 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6213 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6214 | skipCall |= addCmd(dev_data, pCB, CMD_DRAW, "vkCmdDraw()"); |
| 6215 | pCB->drawCount[DRAW]++; |
| 6216 | skipCall |= validate_draw_state(dev_data, pCB, VK_FALSE); |
| 6217 | // TODO : Need to pass commandBuffer as srcObj here |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6218 | skipCall |= |
| 6219 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 6220 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 6221 | DRAWSTATE_NONE, "DS", |
| 6222 | "vkCmdDraw() call #%" PRIu64 ", reporting DS state:", |
| 6223 | g_drawCount[DRAW]++); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6224 | skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6225 | if (VK_FALSE == skipCall) { |
| 6226 | updateResourceTrackingOnDraw(pCB); |
| 6227 | } |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6228 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDraw"); |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 6229 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6230 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6231 | dev_data->device_dispatch_table->CmdDraw(commandBuffer, vertexCount, |
| 6232 | instanceCount, firstVertex, |
| 6233 | firstInstance); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6234 | } |
| 6235 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6236 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6237 | vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, |
| 6238 | uint32_t instanceCount, uint32_t firstIndex, |
| 6239 | int32_t vertexOffset, uint32_t firstInstance) { |
| 6240 | layer_data *dev_data = |
| 6241 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6242 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6243 | VkBool32 skipCall = VK_FALSE; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6244 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6245 | skipCall |= |
| 6246 | addCmd(dev_data, pCB, CMD_DRAWINDEXED, "vkCmdDrawIndexed()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6247 | pCB->drawCount[DRAW_INDEXED]++; |
| 6248 | skipCall |= validate_draw_state(dev_data, pCB, VK_TRUE); |
| 6249 | // TODO : Need to pass commandBuffer as srcObj here |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6250 | skipCall |= |
| 6251 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 6252 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 6253 | DRAWSTATE_NONE, "DS", |
| 6254 | "vkCmdDrawIndexed() call #%" PRIu64 ", reporting DS state:", |
| 6255 | g_drawCount[DRAW_INDEXED]++); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6256 | skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6257 | if (VK_FALSE == skipCall) { |
| 6258 | updateResourceTrackingOnDraw(pCB); |
| 6259 | } |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6260 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDrawIndexed"); |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 6261 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6262 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6263 | dev_data->device_dispatch_table->CmdDrawIndexed( |
| 6264 | commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, |
| 6265 | firstInstance); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6266 | } |
| 6267 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6268 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6269 | vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, |
| 6270 | VkDeviceSize offset, uint32_t count, uint32_t stride) { |
| 6271 | layer_data *dev_data = |
| 6272 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6273 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6274 | VkBool32 skipCall = VK_FALSE; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6275 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6276 | skipCall |= |
| 6277 | addCmd(dev_data, pCB, CMD_DRAWINDIRECT, "vkCmdDrawIndirect()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6278 | pCB->drawCount[DRAW_INDIRECT]++; |
| 6279 | skipCall |= validate_draw_state(dev_data, pCB, VK_FALSE); |
| 6280 | // TODO : Need to pass commandBuffer as srcObj here |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6281 | skipCall |= |
| 6282 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 6283 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 6284 | DRAWSTATE_NONE, "DS", "vkCmdDrawIndirect() call #%" PRIu64 |
| 6285 | ", reporting DS state:", |
| 6286 | g_drawCount[DRAW_INDIRECT]++); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6287 | skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6288 | if (VK_FALSE == skipCall) { |
| 6289 | updateResourceTrackingOnDraw(pCB); |
| 6290 | } |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6291 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdDrawIndirect"); |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 6292 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6293 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6294 | dev_data->device_dispatch_table->CmdDrawIndirect(commandBuffer, buffer, |
| 6295 | offset, count, stride); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6296 | } |
| 6297 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6298 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6299 | vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, |
| 6300 | VkDeviceSize offset, uint32_t count, |
| 6301 | uint32_t stride) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6302 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6303 | layer_data *dev_data = |
| 6304 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6305 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6306 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6307 | skipCall |= addCmd(dev_data, pCB, CMD_DRAWINDEXEDINDIRECT, |
| 6308 | "vkCmdDrawIndexedIndirect()"); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6309 | pCB->drawCount[DRAW_INDEXED_INDIRECT]++; |
| 6310 | skipCall |= validate_draw_state(dev_data, pCB, VK_TRUE); |
| 6311 | // TODO : Need to pass commandBuffer as srcObj here |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6312 | skipCall |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFO_BIT_EXT, |
| 6313 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, |
| 6314 | __LINE__, DRAWSTATE_NONE, "DS", |
| 6315 | "vkCmdDrawIndexedIndirect() call #%" PRIu64 |
| 6316 | ", reporting DS state:", |
| 6317 | g_drawCount[DRAW_INDEXED_INDIRECT]++); |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6318 | skipCall |= synchAndPrintDSConfig(dev_data, commandBuffer); |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 6319 | if (VK_FALSE == skipCall) { |
| 6320 | updateResourceTrackingOnDraw(pCB); |
| 6321 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6322 | skipCall |= |
| 6323 | outsideRenderPass(dev_data, pCB, "vkCmdDrawIndexedIndirect"); |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 6324 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6325 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6326 | dev_data->device_dispatch_table->CmdDrawIndexedIndirect( |
| 6327 | commandBuffer, buffer, offset, count, stride); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6328 | } |
| 6329 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6330 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6331 | vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, |
| 6332 | uint32_t z) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6333 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6334 | layer_data *dev_data = |
| 6335 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6336 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6337 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6338 | skipCall |= addCmd(dev_data, pCB, CMD_DISPATCH, "vkCmdDispatch()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6339 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdDispatch"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6340 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6341 | if (VK_FALSE == skipCall) |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 6342 | dev_data->device_dispatch_table->CmdDispatch(commandBuffer, x, y, z); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6343 | } |
| 6344 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6345 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6346 | vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, |
| 6347 | VkDeviceSize offset) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6348 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6349 | layer_data *dev_data = |
| 6350 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6351 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6352 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6353 | skipCall |= addCmd(dev_data, pCB, CMD_DISPATCHINDIRECT, |
| 6354 | "vkCmdDispatchIndirect()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6355 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdDispatchIndirect"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6356 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6357 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6358 | dev_data->device_dispatch_table->CmdDispatchIndirect(commandBuffer, |
| 6359 | buffer, offset); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6360 | } |
| 6361 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6362 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6363 | vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, |
| 6364 | VkBuffer dstBuffer, uint32_t regionCount, |
| 6365 | const VkBufferCopy *pRegions) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6366 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6367 | layer_data *dev_data = |
| 6368 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6369 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6370 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6371 | skipCall |= addCmd(dev_data, pCB, CMD_COPYBUFFER, "vkCmdCopyBuffer()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6372 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyBuffer"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6373 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6374 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6375 | dev_data->device_dispatch_table->CmdCopyBuffer( |
| 6376 | commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6377 | } |
| 6378 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6379 | VkBool32 VerifySourceImageLayout(VkCommandBuffer cmdBuffer, VkImage srcImage, |
| 6380 | VkImageLayout srcImageLayout) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6381 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 6382 | |
| 6383 | #ifdef DISABLE_IMAGE_LAYOUT_VALIDATION |
| 6384 | // TODO: Fix -- initialLayout may have been set in a previous command buffer |
| 6385 | return skip_call; |
| 6386 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
| 6387 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6388 | layer_data *dev_data = |
| 6389 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 6390 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6391 | auto src_image_element = pCB->imageLayoutMap.find(srcImage); |
| 6392 | if (src_image_element == pCB->imageLayoutMap.end()) { |
| 6393 | pCB->imageLayoutMap[srcImage].initialLayout = srcImageLayout; |
| 6394 | pCB->imageLayoutMap[srcImage].layout = srcImageLayout; |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6395 | return VK_FALSE; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6396 | } |
| 6397 | if (src_image_element->second.layout != srcImageLayout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6398 | skip_call |= |
| 6399 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6400 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 6401 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6402 | "Cannot copy from an image whose source layout is %d and " |
| 6403 | "doesn't match the current layout %d.", |
| 6404 | srcImageLayout, src_image_element->second.layout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6405 | } |
| 6406 | if (srcImageLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) { |
| 6407 | if (srcImageLayout == VK_IMAGE_LAYOUT_GENERAL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6408 | // LAYOUT_GENERAL is allowed, but may not be performance optimal, |
| 6409 | // flag as perf warning. |
| 6410 | skip_call |= log_msg(dev_data->report_data, |
| 6411 | VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 6412 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6413 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6414 | "Layout for input image should be " |
| 6415 | "TRANSFER_SRC_OPTIMAL instead of GENERAL."); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6416 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6417 | skip_call |= |
| 6418 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6419 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6420 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6421 | "Layout for input image is %d but can only be " |
| 6422 | "TRANSFER_SRC_OPTIMAL or GENERAL.", |
| 6423 | srcImageLayout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6424 | } |
| 6425 | } |
| 6426 | return skip_call; |
| 6427 | } |
| 6428 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6429 | VkBool32 VerifyDestImageLayout(VkCommandBuffer cmdBuffer, VkImage destImage, |
| 6430 | VkImageLayout destImageLayout) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6431 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 6432 | |
| 6433 | #ifdef DISABLE_IMAGE_LAYOUT_VALIDATION |
| 6434 | // TODO: Fix -- initialLayout may have been set in a previous command buffer |
| 6435 | return skip_call; |
| 6436 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
| 6437 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6438 | layer_data *dev_data = |
| 6439 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 6440 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6441 | auto dest_image_element = pCB->imageLayoutMap.find(destImage); |
| 6442 | if (dest_image_element == pCB->imageLayoutMap.end()) { |
| 6443 | pCB->imageLayoutMap[destImage].initialLayout = destImageLayout; |
| 6444 | pCB->imageLayoutMap[destImage].layout = destImageLayout; |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6445 | return VK_FALSE; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6446 | } |
| 6447 | if (dest_image_element->second.layout != destImageLayout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6448 | skip_call |= |
| 6449 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6450 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 6451 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6452 | "Cannot copy from an image whose dest layout is %d and " |
| 6453 | "doesn't match the current layout %d.", |
| 6454 | destImageLayout, dest_image_element->second.layout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6455 | } |
| 6456 | if (destImageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { |
| 6457 | if (destImageLayout == VK_IMAGE_LAYOUT_GENERAL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6458 | // LAYOUT_GENERAL is allowed, but may not be performance optimal, |
| 6459 | // flag as perf warning. |
| 6460 | skip_call |= log_msg(dev_data->report_data, |
| 6461 | VK_DEBUG_REPORT_PERF_WARN_BIT_EXT, |
| 6462 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6463 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6464 | "Layout for output image should be " |
| 6465 | "TRANSFER_DST_OPTIMAL instead of GENERAL."); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6466 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6467 | skip_call |= |
| 6468 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6469 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6470 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6471 | "Layout for output image is %d but can only be " |
| 6472 | "TRANSFER_DST_OPTIMAL or GENERAL.", |
| 6473 | destImageLayout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6474 | } |
| 6475 | } |
| 6476 | return skip_call; |
| 6477 | } |
| 6478 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6479 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6480 | vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, |
| 6481 | VkImageLayout srcImageLayout, VkImage dstImage, |
| 6482 | VkImageLayout dstImageLayout, uint32_t regionCount, |
| 6483 | const VkImageCopy *pRegions) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6484 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6485 | layer_data *dev_data = |
| 6486 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6487 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6488 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6489 | skipCall |= addCmd(dev_data, pCB, CMD_COPYIMAGE, "vkCmdCopyImage()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6490 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyImage"); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6491 | skipCall |= |
| 6492 | VerifySourceImageLayout(commandBuffer, srcImage, srcImageLayout); |
| 6493 | skipCall |= |
| 6494 | VerifyDestImageLayout(commandBuffer, dstImage, dstImageLayout); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6495 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6496 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6497 | dev_data->device_dispatch_table->CmdCopyImage( |
| 6498 | commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, |
| 6499 | regionCount, pRegions); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6500 | } |
| 6501 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6502 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6503 | vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, |
| 6504 | VkImageLayout srcImageLayout, VkImage dstImage, |
| 6505 | VkImageLayout dstImageLayout, uint32_t regionCount, |
| 6506 | const VkImageBlit *pRegions, VkFilter filter) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6507 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6508 | layer_data *dev_data = |
| 6509 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6510 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Courtney Goeltzenleuchter | 91f9cee | 2015-04-03 14:42:51 -0600 | [diff] [blame] | 6511 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6512 | skipCall |= addCmd(dev_data, pCB, CMD_BLITIMAGE, "vkCmdBlitImage()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6513 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdBlitImage"); |
Courtney Goeltzenleuchter | 91f9cee | 2015-04-03 14:42:51 -0600 | [diff] [blame] | 6514 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6515 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6516 | dev_data->device_dispatch_table->CmdBlitImage( |
| 6517 | commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, |
| 6518 | regionCount, pRegions, filter); |
Courtney Goeltzenleuchter | 91f9cee | 2015-04-03 14:42:51 -0600 | [diff] [blame] | 6519 | } |
| 6520 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6521 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6522 | vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, |
| 6523 | VkImage dstImage, VkImageLayout dstImageLayout, |
| 6524 | uint32_t regionCount, |
| 6525 | const VkBufferImageCopy *pRegions) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6526 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6527 | layer_data *dev_data = |
| 6528 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6529 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6530 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6531 | skipCall |= addCmd(dev_data, pCB, CMD_COPYBUFFERTOIMAGE, |
| 6532 | "vkCmdCopyBufferToImage()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6533 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyBufferToImage"); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6534 | skipCall |= |
| 6535 | VerifyDestImageLayout(commandBuffer, dstImage, dstImageLayout); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6536 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6537 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6538 | dev_data->device_dispatch_table->CmdCopyBufferToImage( |
| 6539 | commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, |
| 6540 | pRegions); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6541 | } |
| 6542 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6543 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6544 | vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, |
| 6545 | VkImageLayout srcImageLayout, VkBuffer dstBuffer, |
| 6546 | uint32_t regionCount, |
| 6547 | const VkBufferImageCopy *pRegions) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6548 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6549 | layer_data *dev_data = |
| 6550 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6551 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6552 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6553 | skipCall |= addCmd(dev_data, pCB, CMD_COPYIMAGETOBUFFER, |
| 6554 | "vkCmdCopyImageToBuffer()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6555 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyImageToBuffer"); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6556 | skipCall |= |
| 6557 | VerifySourceImageLayout(commandBuffer, srcImage, srcImageLayout); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6558 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6559 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6560 | dev_data->device_dispatch_table->CmdCopyImageToBuffer( |
| 6561 | commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, |
| 6562 | pRegions); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6563 | } |
| 6564 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6565 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6566 | vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, |
| 6567 | VkDeviceSize dstOffset, VkDeviceSize dataSize, |
| 6568 | const uint32_t *pData) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6569 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6570 | layer_data *dev_data = |
| 6571 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6572 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6573 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6574 | skipCall |= |
| 6575 | addCmd(dev_data, pCB, CMD_UPDATEBUFFER, "vkCmdUpdateBuffer()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6576 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyUpdateBuffer"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6577 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6578 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6579 | dev_data->device_dispatch_table->CmdUpdateBuffer( |
| 6580 | commandBuffer, dstBuffer, dstOffset, dataSize, pData); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6581 | } |
| 6582 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6583 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6584 | vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, |
| 6585 | VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6586 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6587 | layer_data *dev_data = |
| 6588 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6589 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6590 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6591 | skipCall |= addCmd(dev_data, pCB, CMD_FILLBUFFER, "vkCmdFillBuffer()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6592 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdCopyFillBuffer"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6593 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6594 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6595 | dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, |
| 6596 | dstOffset, size, data); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6597 | } |
| 6598 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6599 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6600 | vkCmdClearAttachments(VkCommandBuffer commandBuffer, |
| 6601 | uint32_t attachmentCount, |
| 6602 | const VkClearAttachment *pAttachments, |
| 6603 | uint32_t rectCount, const VkClearRect *pRects) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6604 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6605 | layer_data *dev_data = |
| 6606 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6607 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 53eddda | 2015-07-01 16:46:13 -0600 | [diff] [blame] | 6608 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6609 | skipCall |= addCmd(dev_data, pCB, CMD_CLEARATTACHMENTS, |
| 6610 | "vkCmdClearAttachments()"); |
| 6611 | // Warn if this is issued prior to Draw Cmd and clearing the entire |
| 6612 | // attachment |
| 6613 | if (!hasDrawCmd(pCB) && |
| 6614 | (pCB->activeRenderPassBeginInfo.renderArea.extent.width == |
| 6615 | pRects[0].rect.extent.width) && |
| 6616 | (pCB->activeRenderPassBeginInfo.renderArea.extent.height == |
| 6617 | pRects[0].rect.extent.height)) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6618 | // TODO : commandBuffer should be srcObj |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6619 | skipCall |= log_msg( |
| 6620 | dev_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 6621 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 6622 | DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS", |
| 6623 | "vkCmdClearAttachments() issued on CB object 0x%" PRIxLEAST64 |
| 6624 | " prior to any Draw Cmds." |
| 6625 | " It is recommended you use RenderPass LOAD_OP_CLEAR on " |
| 6626 | "Attachments prior to any Draw.", |
| 6627 | (uint64_t)(commandBuffer)); |
Tobin Ehlis | 53eddda | 2015-07-01 16:46:13 -0600 | [diff] [blame] | 6628 | } |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 6629 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdClearAttachments"); |
| 6630 | } |
| 6631 | |
| 6632 | // Validate that attachment is in reference list of active subpass |
| 6633 | if (pCB->activeRenderPass) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6634 | const VkRenderPassCreateInfo *pRPCI = |
| 6635 | dev_data->renderPassMap[pCB->activeRenderPass]->pCreateInfo; |
| 6636 | const VkSubpassDescription *pSD = |
| 6637 | &pRPCI->pSubpasses[pCB->activeSubpass]; |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 6638 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6639 | for (uint32_t attachment_idx = 0; attachment_idx < attachmentCount; |
| 6640 | attachment_idx++) { |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 6641 | const VkClearAttachment *attachment = &pAttachments[attachment_idx]; |
| 6642 | if (attachment->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { |
| 6643 | VkBool32 found = VK_FALSE; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 6644 | for (uint32_t i = 0; i < pSD->colorAttachmentCount; i++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6645 | if (attachment->colorAttachment == |
| 6646 | pSD->pColorAttachments[i].attachment) { |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 6647 | found = VK_TRUE; |
| 6648 | break; |
| 6649 | } |
| 6650 | } |
| 6651 | if (VK_FALSE == found) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6652 | skipCall |= log_msg( |
| 6653 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6654 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 6655 | (uint64_t)commandBuffer, __LINE__, |
| 6656 | DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS", |
| 6657 | "vkCmdClearAttachments() attachment index %d not found " |
| 6658 | "in attachment reference array of active subpass %d", |
| 6659 | attachment->colorAttachment, pCB->activeSubpass); |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 6660 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6661 | } else if (attachment->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | |
| 6662 | VK_IMAGE_ASPECT_STENCIL_BIT)) { |
| 6663 | if (!pSD->pDepthStencilAttachment || // Says no DS will be used |
| 6664 | // in active subpass |
| 6665 | (pSD->pDepthStencilAttachment->attachment == |
| 6666 | VK_ATTACHMENT_UNUSED)) { // Says no DS will be used in |
| 6667 | // active subpass |
Mark Lobodzinski | d6e7bff | 2015-11-17 15:11:24 -0700 | [diff] [blame] | 6668 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6669 | skipCall |= log_msg( |
| 6670 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6671 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 6672 | (uint64_t)commandBuffer, __LINE__, |
| 6673 | DRAWSTATE_MISSING_ATTACHMENT_REFERENCE, "DS", |
| 6674 | "vkCmdClearAttachments() attachment index %d does not " |
| 6675 | "match depthStencilAttachment.attachment (%d) found in " |
| 6676 | "active subpass %d", |
Mark Lobodzinski | d6e7bff | 2015-11-17 15:11:24 -0700 | [diff] [blame] | 6677 | attachment->colorAttachment, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6678 | (pSD->pDepthStencilAttachment) |
| 6679 | ? pSD->pDepthStencilAttachment->attachment |
| 6680 | : VK_ATTACHMENT_UNUSED, |
Mark Lobodzinski | d6e7bff | 2015-11-17 15:11:24 -0700 | [diff] [blame] | 6681 | pCB->activeSubpass); |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 6682 | } |
| 6683 | } |
| 6684 | } |
Tobin Ehlis | 53eddda | 2015-07-01 16:46:13 -0600 | [diff] [blame] | 6685 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6686 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6687 | dev_data->device_dispatch_table->CmdClearAttachments( |
| 6688 | commandBuffer, attachmentCount, pAttachments, rectCount, pRects); |
Tobin Ehlis | 53eddda | 2015-07-01 16:46:13 -0600 | [diff] [blame] | 6689 | } |
| 6690 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6691 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6692 | vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, |
| 6693 | VkImageLayout imageLayout, |
| 6694 | const VkClearColorValue *pColor, uint32_t rangeCount, |
| 6695 | const VkImageSubresourceRange *pRanges) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6696 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6697 | layer_data *dev_data = |
| 6698 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6699 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6700 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6701 | skipCall |= addCmd(dev_data, pCB, CMD_CLEARCOLORIMAGE, |
| 6702 | "vkCmdClearColorImage()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6703 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdClearColorImage"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6704 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6705 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6706 | dev_data->device_dispatch_table->CmdClearColorImage( |
| 6707 | commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6708 | } |
| 6709 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6710 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6711 | vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, |
| 6712 | VkImageLayout imageLayout, |
| 6713 | const VkClearDepthStencilValue *pDepthStencil, |
| 6714 | uint32_t rangeCount, |
| 6715 | const VkImageSubresourceRange *pRanges) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6716 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6717 | layer_data *dev_data = |
| 6718 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6719 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6720 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6721 | skipCall |= addCmd(dev_data, pCB, CMD_CLEARDEPTHSTENCILIMAGE, |
| 6722 | "vkCmdClearDepthStencilImage()"); |
| 6723 | skipCall |= |
| 6724 | insideRenderPass(dev_data, pCB, "vkCmdClearDepthStencilImage"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6725 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6726 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6727 | dev_data->device_dispatch_table->CmdClearDepthStencilImage( |
| 6728 | commandBuffer, image, imageLayout, pDepthStencil, rangeCount, |
| 6729 | pRanges); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6730 | } |
| 6731 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6732 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6733 | vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, |
| 6734 | VkImageLayout srcImageLayout, VkImage dstImage, |
| 6735 | VkImageLayout dstImageLayout, uint32_t regionCount, |
| 6736 | const VkImageResolve *pRegions) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6737 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6738 | layer_data *dev_data = |
| 6739 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6740 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6741 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6742 | skipCall |= |
| 6743 | addCmd(dev_data, pCB, CMD_RESOLVEIMAGE, "vkCmdResolveImage()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6744 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdResolveImage"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6745 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6746 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6747 | dev_data->device_dispatch_table->CmdResolveImage( |
| 6748 | commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, |
| 6749 | regionCount, pRegions); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6750 | } |
| 6751 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6752 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6753 | vkCmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, |
| 6754 | VkPipelineStageFlags stageMask) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6755 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6756 | layer_data *dev_data = |
| 6757 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6758 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6759 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6760 | skipCall |= addCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6761 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6762 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6763 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6764 | dev_data->device_dispatch_table->CmdSetEvent(commandBuffer, event, |
| 6765 | stageMask); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6766 | } |
| 6767 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6768 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 6769 | vkCmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, |
| 6770 | VkPipelineStageFlags stageMask) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6771 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6772 | layer_data *dev_data = |
| 6773 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 6774 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6775 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 6776 | skipCall |= addCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()"); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 6777 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6778 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 6779 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6780 | dev_data->device_dispatch_table->CmdResetEvent(commandBuffer, event, |
| 6781 | stageMask); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 6782 | } |
| 6783 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6784 | VkBool32 TransitionImageLayouts(VkCommandBuffer cmdBuffer, |
| 6785 | uint32_t memBarrierCount, |
| 6786 | const VkImageMemoryBarrier *pImgMemBarriers) { |
| 6787 | layer_data *dev_data = |
| 6788 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 6789 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6790 | VkBool32 skip = VK_FALSE; |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 6791 | |
| 6792 | #ifdef DISABLE_IMAGE_LAYOUT_VALIDATION |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6793 | // TODO: Fix -- pay attention to image subresource ranges -- not all |
| 6794 | // subresources transition at the same time |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 6795 | return skip; |
| 6796 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
| 6797 | |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6798 | for (uint32_t i = 0; i < memBarrierCount; ++i) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 6799 | auto mem_barrier = &pImgMemBarriers[i]; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6800 | if (mem_barrier && |
| 6801 | mem_barrier->sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 6802 | auto image_data = pCB->imageLayoutMap.find(mem_barrier->image); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6803 | if (image_data == pCB->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6804 | pCB->imageLayoutMap[mem_barrier->image].initialLayout = |
| 6805 | mem_barrier->oldLayout; |
| 6806 | pCB->imageLayoutMap[mem_barrier->image].layout = |
| 6807 | mem_barrier->newLayout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6808 | } else { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 6809 | if (image_data->second.layout != mem_barrier->oldLayout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6810 | skip |= log_msg( |
| 6811 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6812 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6813 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 6814 | "You cannot transition the layout from %d when current " |
| 6815 | "layout is %d.", |
| 6816 | mem_barrier->oldLayout, image_data->second.layout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6817 | } |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 6818 | image_data->second.layout = mem_barrier->newLayout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 6819 | } |
| 6820 | } |
| 6821 | } |
| 6822 | return skip; |
| 6823 | } |
| 6824 | |
Mark Lobodzinski | a3a8611 | 2016-01-05 17:17:55 -0700 | [diff] [blame] | 6825 | // Print readable FlagBits in FlagMask |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6826 | std::string string_VkAccessFlags(VkAccessFlags accessMask) { |
Mark Lobodzinski | a3a8611 | 2016-01-05 17:17:55 -0700 | [diff] [blame] | 6827 | std::string result; |
| 6828 | std::string separator; |
| 6829 | |
| 6830 | if (accessMask == 0) { |
| 6831 | result = "[None]"; |
| 6832 | } else { |
| 6833 | result = "["; |
| 6834 | for (auto i = 0; i < 32; i++) { |
| 6835 | if (accessMask & (1 << i)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6836 | result = result + separator + |
| 6837 | string_VkAccessFlagBits((VkAccessFlagBits)(1 << i)); |
Mark Lobodzinski | a3a8611 | 2016-01-05 17:17:55 -0700 | [diff] [blame] | 6838 | separator = " | "; |
| 6839 | } |
| 6840 | } |
| 6841 | result = result + "]"; |
| 6842 | } |
| 6843 | return result; |
| 6844 | } |
| 6845 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6846 | // AccessFlags MUST have 'required_bit' set, and may have one or more of |
| 6847 | // 'optional_bits' set. |
| 6848 | // If required_bit is zero, accessMask must have at least one of 'optional_bits' |
| 6849 | // set |
| 6850 | // TODO: Add tracking to ensure that at least one barrier has been set for these |
| 6851 | // layout transitions |
| 6852 | VkBool32 ValidateMaskBits(const layer_data *my_data, VkCommandBuffer cmdBuffer, |
| 6853 | const VkAccessFlags &accessMask, |
| 6854 | const VkImageLayout &layout, |
| 6855 | VkAccessFlags required_bit, |
| 6856 | VkAccessFlags optional_bits, const char *type) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6857 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | 882655d | 2016-01-05 11:32:53 -0700 | [diff] [blame] | 6858 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6859 | if ((accessMask & required_bit) || |
| 6860 | (!required_bit && (accessMask & optional_bits))) { |
Michael Lentine | 97eb746 | 2015-11-20 09:48:52 -0800 | [diff] [blame] | 6861 | if (accessMask & !(required_bit | optional_bits)) { |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 6862 | // TODO: Verify against Valid Use |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6863 | skip_call |= log_msg( |
| 6864 | my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 6865 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6866 | DRAWSTATE_INVALID_BARRIER, "DS", "Additional bits in %s " |
| 6867 | "accessMask %d %s are " |
| 6868 | "specified when layout is %s.", |
| 6869 | type, accessMask, string_VkAccessFlags(accessMask).c_str(), |
| 6870 | string_VkImageLayout(layout)); |
Michael Lentine | ecc32b7 | 2015-10-16 18:08:09 -0500 | [diff] [blame] | 6871 | } |
| 6872 | } else { |
Michael Lentine | 97eb746 | 2015-11-20 09:48:52 -0800 | [diff] [blame] | 6873 | if (!required_bit) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6874 | skip_call |= log_msg( |
| 6875 | my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 6876 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6877 | DRAWSTATE_INVALID_BARRIER, "DS", |
| 6878 | "%s AccessMask %d %s must contain at least one of access bits " |
| 6879 | "%d %s when layout is %s, unless the app has previously added " |
| 6880 | "a barrier for this transition.", |
| 6881 | type, accessMask, string_VkAccessFlags(accessMask).c_str(), |
| 6882 | optional_bits, string_VkAccessFlags(optional_bits).c_str(), |
| 6883 | string_VkImageLayout(layout)); |
Michael Lentine | 97eb746 | 2015-11-20 09:48:52 -0800 | [diff] [blame] | 6884 | } else { |
Mark Lobodzinski | f2cc2a5 | 2016-01-05 13:35:29 -0700 | [diff] [blame] | 6885 | std::string opt_bits; |
| 6886 | if (optional_bits != 0) { |
Michael Lentine | 6bd4f12 | 2016-01-19 14:00:53 -0600 | [diff] [blame] | 6887 | std::stringstream ss; |
| 6888 | ss << optional_bits; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6889 | opt_bits = "and may have optional bits " + ss.str() + ' ' + |
| 6890 | string_VkAccessFlags(optional_bits); |
Mark Lobodzinski | f2cc2a5 | 2016-01-05 13:35:29 -0700 | [diff] [blame] | 6891 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6892 | skip_call |= log_msg( |
| 6893 | my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 6894 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6895 | DRAWSTATE_INVALID_BARRIER, "DS", |
| 6896 | "%s AccessMask %d %s must have required access bit %d %s %s " |
| 6897 | "when layout is %s, unless the app has previously added a " |
| 6898 | "barrier for this transition.", |
| 6899 | type, accessMask, string_VkAccessFlags(accessMask).c_str(), |
| 6900 | required_bit, string_VkAccessFlags(required_bit).c_str(), |
| 6901 | opt_bits.c_str(), string_VkImageLayout(layout)); |
Michael Lentine | 97eb746 | 2015-11-20 09:48:52 -0800 | [diff] [blame] | 6902 | } |
Michael Lentine | ecc32b7 | 2015-10-16 18:08:09 -0500 | [diff] [blame] | 6903 | } |
| 6904 | return skip_call; |
| 6905 | } |
| 6906 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6907 | VkBool32 ValidateMaskBitsFromLayouts(const layer_data *my_data, |
| 6908 | VkCommandBuffer cmdBuffer, |
| 6909 | const VkAccessFlags &accessMask, |
| 6910 | const VkImageLayout &layout, |
| 6911 | const char *type) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6912 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 97eb746 | 2015-11-20 09:48:52 -0800 | [diff] [blame] | 6913 | switch (layout) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6914 | case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: { |
| 6915 | skip_call |= |
| 6916 | ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, |
| 6917 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, |
| 6918 | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, type); |
| 6919 | break; |
| 6920 | } |
| 6921 | case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: { |
| 6922 | skip_call |= |
| 6923 | ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, |
| 6924 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, |
| 6925 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, type); |
| 6926 | break; |
| 6927 | } |
| 6928 | case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: { |
| 6929 | skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, |
| 6930 | VK_ACCESS_TRANSFER_WRITE_BIT, 0, type); |
| 6931 | break; |
| 6932 | } |
| 6933 | case VK_IMAGE_LAYOUT_PREINITIALIZED: { |
| 6934 | skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, |
| 6935 | VK_ACCESS_HOST_WRITE_BIT, 0, type); |
| 6936 | break; |
| 6937 | } |
| 6938 | case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: { |
| 6939 | skip_call |= |
| 6940 | ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, 0, |
| 6941 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | |
| 6942 | VK_ACCESS_SHADER_READ_BIT, |
| 6943 | type); |
| 6944 | break; |
| 6945 | } |
| 6946 | case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: { |
| 6947 | skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, 0, |
| 6948 | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | |
| 6949 | VK_ACCESS_SHADER_READ_BIT, |
| 6950 | type); |
| 6951 | break; |
| 6952 | } |
| 6953 | case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: { |
| 6954 | skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, |
| 6955 | VK_ACCESS_TRANSFER_READ_BIT, 0, type); |
| 6956 | break; |
| 6957 | } |
| 6958 | case VK_IMAGE_LAYOUT_UNDEFINED: { |
| 6959 | if (accessMask != 0) { |
| 6960 | // TODO: Verify against Valid Use section spec |
| 6961 | skip_call |= log_msg( |
| 6962 | my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 6963 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6964 | DRAWSTATE_INVALID_BARRIER, "DS", "Additional bits in %s " |
| 6965 | "accessMask %d %s are " |
| 6966 | "specified when layout is %s.", |
| 6967 | type, accessMask, string_VkAccessFlags(accessMask).c_str(), |
| 6968 | string_VkImageLayout(layout)); |
Michael Lentine | ecc32b7 | 2015-10-16 18:08:09 -0500 | [diff] [blame] | 6969 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6970 | break; |
| 6971 | } |
| 6972 | case VK_IMAGE_LAYOUT_GENERAL: |
| 6973 | default: { break; } |
Michael Lentine | ecc32b7 | 2015-10-16 18:08:09 -0500 | [diff] [blame] | 6974 | } |
| 6975 | return skip_call; |
| 6976 | } |
| 6977 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6978 | VkBool32 ValidateBarriers(VkCommandBuffer cmdBuffer, uint32_t memBarrierCount, |
| 6979 | const VkMemoryBarrier *pMemBarriers, |
| 6980 | uint32_t imageMemBarrierCount, |
| 6981 | const VkImageMemoryBarrier *pImageMemBarriers) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 6982 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6983 | layer_data *dev_data = |
| 6984 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 6985 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 6986 | if (pCB->activeRenderPass && memBarrierCount) { |
| 6987 | for (uint32_t i = 0; i < memBarrierCount; ++i) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 6988 | auto mem_barrier = &pMemBarriers[i]; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6989 | if (mem_barrier && |
| 6990 | mem_barrier->sType != VK_STRUCTURE_TYPE_MEMORY_BARRIER) { |
| 6991 | skip_call |= log_msg(dev_data->report_data, |
| 6992 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 6993 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 6994 | DRAWSTATE_INVALID_BARRIER, "DS", |
| 6995 | "Image or Buffers Barriers cannot be used " |
| 6996 | "during a render pass."); |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 6997 | } |
| 6998 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 6999 | if (!dev_data->renderPassMap[pCB->activeRenderPass] |
| 7000 | ->hasSelfDependency[pCB->activeSubpass]) { |
| 7001 | skip_call |= |
| 7002 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7003 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7004 | DRAWSTATE_INVALID_BARRIER, "DS", |
| 7005 | "Barriers cannot be set during subpass %d with no self " |
| 7006 | "dependency specified.", |
| 7007 | pCB->activeSubpass); |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7008 | } |
| 7009 | } |
Mark Lobodzinski | 73a37ec | 2015-11-20 09:27:27 -0700 | [diff] [blame] | 7010 | |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 7011 | for (uint32_t i = 0; i < imageMemBarrierCount; ++i) { |
| 7012 | auto mem_barrier = &pImageMemBarriers[i]; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7013 | if (mem_barrier && |
| 7014 | mem_barrier->sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER) { |
| 7015 | skip_call |= ValidateMaskBitsFromLayouts( |
| 7016 | dev_data, cmdBuffer, mem_barrier->srcAccessMask, |
| 7017 | mem_barrier->oldLayout, "Source"); |
| 7018 | skip_call |= ValidateMaskBitsFromLayouts( |
| 7019 | dev_data, cmdBuffer, mem_barrier->dstAccessMask, |
| 7020 | mem_barrier->newLayout, "Dest"); |
Michael Lentine | ecc32b7 | 2015-10-16 18:08:09 -0500 | [diff] [blame] | 7021 | } |
| 7022 | } |
Mark Lobodzinski | 3cba24a | 2015-12-03 15:42:32 -0700 | [diff] [blame] | 7023 | |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7024 | return skip_call; |
| 7025 | } |
| 7026 | |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 7027 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7028 | VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, |
| 7029 | VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask, |
| 7030 | uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, |
| 7031 | uint32_t bufferMemoryBarrierCount, |
| 7032 | const VkBufferMemoryBarrier *pBufferMemoryBarriers, |
| 7033 | uint32_t imageMemoryBarrierCount, |
| 7034 | const VkImageMemoryBarrier *pImageMemoryBarriers) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7035 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7036 | layer_data *dev_data = |
| 7037 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7038 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7039 | if (pCB) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7040 | for (uint32_t i = 0; i < eventCount; ++i) { |
| 7041 | pCB->waitedEvents.push_back(pEvents[i]); |
| 7042 | } |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7043 | if (pCB->state == CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7044 | skipCall |= |
| 7045 | addCmd(dev_data, pCB, CMD_WAITEVENTS, "vkCmdWaitEvents()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7046 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7047 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 7048 | "vkCmdWaitEvents()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7049 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7050 | skipCall |= TransitionImageLayouts( |
| 7051 | commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); |
| 7052 | skipCall |= |
| 7053 | ValidateBarriers(commandBuffer, memoryBarrierCount, pMemoryBarriers, |
| 7054 | imageMemoryBarrierCount, pImageMemoryBarriers); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7055 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7056 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7057 | dev_data->device_dispatch_table->CmdWaitEvents( |
| 7058 | commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask, |
| 7059 | memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, |
| 7060 | pBufferMemoryBarriers, imageMemoryBarrierCount, |
| 7061 | pImageMemoryBarriers); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7062 | } |
| 7063 | |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 7064 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7065 | VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, |
| 7066 | VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, |
| 7067 | uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, |
| 7068 | uint32_t bufferMemoryBarrierCount, |
| 7069 | const VkBufferMemoryBarrier *pBufferMemoryBarriers, |
| 7070 | uint32_t imageMemoryBarrierCount, |
| 7071 | const VkImageMemoryBarrier *pImageMemoryBarriers) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7072 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7073 | layer_data *dev_data = |
| 7074 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7075 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7076 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7077 | skipCall |= addCmd(dev_data, pCB, CMD_PIPELINEBARRIER, |
| 7078 | "vkCmdPipelineBarrier()"); |
| 7079 | skipCall |= TransitionImageLayouts( |
| 7080 | commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); |
| 7081 | skipCall |= |
| 7082 | ValidateBarriers(commandBuffer, memoryBarrierCount, pMemoryBarriers, |
| 7083 | imageMemoryBarrierCount, pImageMemoryBarriers); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7084 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7085 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7086 | dev_data->device_dispatch_table->CmdPipelineBarrier( |
| 7087 | commandBuffer, srcStageMask, dstStageMask, dependencyFlags, |
| 7088 | memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, |
| 7089 | pBufferMemoryBarriers, imageMemoryBarrierCount, |
| 7090 | pImageMemoryBarriers); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7091 | } |
| 7092 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7093 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7094 | vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, |
| 7095 | uint32_t slot, VkFlags flags) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7096 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7097 | layer_data *dev_data = |
| 7098 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7099 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7100 | if (pCB) { |
Tobin Ehlis | 61b36f3 | 2015-12-16 08:19:42 -0700 | [diff] [blame] | 7101 | skipCall |= addCmd(dev_data, pCB, CMD_BEGINQUERY, "vkCmdBeginQuery()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7102 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7103 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7104 | dev_data->device_dispatch_table->CmdBeginQuery(commandBuffer, queryPool, |
| 7105 | slot, flags); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7106 | } |
| 7107 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7108 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7109 | vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, |
| 7110 | uint32_t slot) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7111 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7112 | layer_data *dev_data = |
| 7113 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7114 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7115 | if (pCB) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7116 | QueryObject query = {queryPool, slot}; |
| 7117 | pCB->queryToStateMap[query] = 1; |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7118 | if (pCB->state == CB_RECORDING) { |
| 7119 | skipCall |= addCmd(dev_data, pCB, CMD_ENDQUERY, "VkCmdEndQuery()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7120 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7121 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 7122 | "vkCmdEndQuery()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7123 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7124 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7125 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7126 | dev_data->device_dispatch_table->CmdEndQuery(commandBuffer, queryPool, |
| 7127 | slot); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7128 | } |
| 7129 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7130 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7131 | vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, |
| 7132 | uint32_t firstQuery, uint32_t queryCount) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7133 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7134 | layer_data *dev_data = |
| 7135 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7136 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7137 | if (pCB) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7138 | for (uint32_t i = 0; i < queryCount; i++) { |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7139 | QueryObject query = {queryPool, firstQuery + i}; |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7140 | pCB->waitedEventsBeforeQueryReset[query] = pCB->waitedEvents; |
| 7141 | pCB->queryToStateMap[query] = 0; |
| 7142 | } |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7143 | if (pCB->state == CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7144 | skipCall |= addCmd(dev_data, pCB, CMD_RESETQUERYPOOL, |
| 7145 | "VkCmdResetQueryPool()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7146 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7147 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 7148 | "vkCmdResetQueryPool()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7149 | } |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 7150 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdQueryPool"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7151 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7152 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7153 | dev_data->device_dispatch_table->CmdResetQueryPool( |
| 7154 | commandBuffer, queryPool, firstQuery, queryCount); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7155 | } |
| 7156 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7157 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7158 | vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, |
| 7159 | VkQueryPool queryPool, uint32_t firstQuery, |
| 7160 | uint32_t queryCount, VkBuffer dstBuffer, |
| 7161 | VkDeviceSize dstOffset, VkDeviceSize stride, |
| 7162 | VkQueryResultFlags flags) { |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7163 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7164 | layer_data *dev_data = |
| 7165 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7166 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7167 | if (pCB) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7168 | for (uint32_t i = 0; i < queryCount; i++) { |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7169 | QueryObject query = {queryPool, firstQuery + i}; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7170 | if (!pCB->queryToStateMap[query]) { |
| 7171 | skipCall |= log_msg( |
| 7172 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7173 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7174 | DRAWSTATE_INVALID_QUERY, "DS", |
| 7175 | "Requesting a copy from query to buffer with invalid " |
| 7176 | "query: queryPool %" PRIu64 ", index %d", |
| 7177 | (uint64_t)(queryPool), firstQuery + i); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7178 | } |
| 7179 | } |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7180 | if (pCB->state == CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7181 | skipCall |= addCmd(dev_data, pCB, CMD_COPYQUERYPOOLRESULTS, |
| 7182 | "vkCmdCopyQueryPoolResults()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7183 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7184 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 7185 | "vkCmdCopyQueryPoolResults()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7186 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7187 | skipCall |= |
| 7188 | insideRenderPass(dev_data, pCB, "vkCmdCopyQueryPoolResults"); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7189 | } |
| 7190 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7191 | dev_data->device_dispatch_table->CmdCopyQueryPoolResults( |
| 7192 | commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, |
| 7193 | dstOffset, stride, flags); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7194 | } |
| 7195 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7196 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7197 | vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, |
| 7198 | VkPipelineStageFlagBits pipelineStage, |
| 7199 | VkQueryPool queryPool, uint32_t slot) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7200 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7201 | layer_data *dev_data = |
| 7202 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7203 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7204 | if (pCB) { |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7205 | QueryObject query = {queryPool, slot}; |
| 7206 | pCB->queryToStateMap[query] = 1; |
Mark Lobodzinski | ce73885 | 2016-01-07 10:04:02 -0700 | [diff] [blame] | 7207 | if (pCB->state == CB_RECORDING) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7208 | skipCall |= addCmd(dev_data, pCB, CMD_WRITETIMESTAMP, |
| 7209 | "vkCmdWriteTimestamp()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7210 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7211 | skipCall |= report_error_no_cb_begin(dev_data, commandBuffer, |
| 7212 | "vkCmdWriteTimestamp()"); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 7213 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7214 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7215 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7216 | dev_data->device_dispatch_table->CmdWriteTimestamp( |
| 7217 | commandBuffer, pipelineStage, queryPool, slot); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7218 | } |
| 7219 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7220 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 7221 | vkCreateFramebuffer(VkDevice device, |
| 7222 | const VkFramebufferCreateInfo *pCreateInfo, |
| 7223 | const VkAllocationCallbacks *pAllocator, |
| 7224 | VkFramebuffer *pFramebuffer) { |
| 7225 | layer_data *dev_data = |
| 7226 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 7227 | VkResult result = dev_data->device_dispatch_table->CreateFramebuffer( |
| 7228 | device, pCreateInfo, pAllocator, pFramebuffer); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 7229 | if (VK_SUCCESS == result) { |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7230 | // Shadow create info and store in map |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7231 | VkFramebufferCreateInfo *localFBCI = |
| 7232 | new VkFramebufferCreateInfo(*pCreateInfo); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7233 | if (pCreateInfo->pAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7234 | localFBCI->pAttachments = |
| 7235 | new VkImageView[localFBCI->attachmentCount]; |
| 7236 | memcpy((void *)localFBCI->pAttachments, pCreateInfo->pAttachments, |
| 7237 | localFBCI->attachmentCount * sizeof(VkImageView)); |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7238 | } |
Chia-I Wu | e2fc552 | 2015-10-26 20:04:44 +0800 | [diff] [blame] | 7239 | dev_data->frameBufferMap[*pFramebuffer] = localFBCI; |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7240 | } |
| 7241 | return result; |
| 7242 | } |
| 7243 | |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7244 | // Store the DAG. |
| 7245 | struct DAGNode { |
| 7246 | uint32_t pass; |
| 7247 | std::vector<uint32_t> prev; |
| 7248 | std::vector<uint32_t> next; |
| 7249 | }; |
| 7250 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7251 | VkBool32 FindDependency(const int index, const int dependent, |
| 7252 | const std::vector<DAGNode> &subpass_to_node, |
| 7253 | std::unordered_set<uint32_t> &processed_nodes) { |
| 7254 | // If we have already checked this node we have not found a dependency path |
| 7255 | // so return false. |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7256 | if (processed_nodes.count(index)) |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7257 | return VK_FALSE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7258 | processed_nodes.insert(index); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7259 | const DAGNode &node = subpass_to_node[index]; |
| 7260 | // Look for a dependency path. If one exists return true else recurse on the |
| 7261 | // previous nodes. |
| 7262 | if (std::find(node.prev.begin(), node.prev.end(), dependent) == |
| 7263 | node.prev.end()) { |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7264 | for (auto elem : node.prev) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7265 | if (FindDependency(elem, dependent, subpass_to_node, |
| 7266 | processed_nodes)) |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7267 | return VK_TRUE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7268 | } |
| 7269 | } else { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7270 | return VK_TRUE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7271 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7272 | return VK_FALSE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7273 | } |
| 7274 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7275 | VkBool32 CheckDependencyExists(const layer_data *my_data, VkDevice device, |
| 7276 | const int subpass, |
| 7277 | const std::vector<uint32_t> &dependent_subpasses, |
| 7278 | const std::vector<DAGNode> &subpass_to_node, |
| 7279 | VkBool32 &skip_call) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7280 | VkBool32 result = VK_TRUE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7281 | // Loop through all subpasses that share the same attachment and make sure a |
| 7282 | // dependency exists |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7283 | for (uint32_t k = 0; k < dependent_subpasses.size(); ++k) { |
| 7284 | if (subpass == dependent_subpasses[k]) |
| 7285 | continue; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7286 | const DAGNode &node = subpass_to_node[subpass]; |
| 7287 | // Check for a specified dependency between the two nodes. If one exists |
| 7288 | // we are done. |
| 7289 | auto prev_elem = std::find(node.prev.begin(), node.prev.end(), |
| 7290 | dependent_subpasses[k]); |
| 7291 | auto next_elem = std::find(node.next.begin(), node.next.end(), |
| 7292 | dependent_subpasses[k]); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7293 | if (prev_elem == node.prev.end() && next_elem == node.next.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7294 | // If no dependency exits an implicit dependency still might. If so, |
| 7295 | // warn and if not throw an error. |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7296 | std::unordered_set<uint32_t> processed_nodes; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7297 | if (FindDependency(subpass, dependent_subpasses[k], subpass_to_node, |
| 7298 | processed_nodes) || |
| 7299 | FindDependency(dependent_subpasses[k], subpass, subpass_to_node, |
| 7300 | processed_nodes)) { |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 7301 | // TODO: Verify against Valid Use section of spec |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7302 | skip_call |= |
| 7303 | log_msg(my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 7304 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7305 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7306 | "A dependency between subpasses %d and %d must " |
| 7307 | "exist but only an implicit one is specified.", |
| 7308 | subpass, dependent_subpasses[k]); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7309 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7310 | skip_call |= |
| 7311 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7312 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7313 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7314 | "A dependency between subpasses %d and %d must " |
| 7315 | "exist but one is not specified.", |
| 7316 | subpass, dependent_subpasses[k]); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7317 | result = VK_FALSE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7318 | } |
| 7319 | } |
| 7320 | } |
| 7321 | return result; |
| 7322 | } |
| 7323 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7324 | VkBool32 CheckPreserved(const layer_data *my_data, VkDevice device, |
| 7325 | const VkRenderPassCreateInfo *pCreateInfo, |
| 7326 | const int index, const uint32_t attachment, |
| 7327 | const std::vector<DAGNode> &subpass_to_node, int depth, |
| 7328 | VkBool32 &skip_call) { |
| 7329 | const DAGNode &node = subpass_to_node[index]; |
| 7330 | // If this node writes to the attachment return true as next nodes need to |
| 7331 | // preserve the attachment. |
| 7332 | const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[index]; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7333 | for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7334 | if (attachment == subpass.pColorAttachments[j].attachment) |
Courtney Goeltzenleuchter | 6ed5dc2 | 2015-11-03 15:41:43 -0700 | [diff] [blame] | 7335 | return VK_TRUE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7336 | } |
Chia-I Wu | 1efb7e5 | 2015-10-26 17:32:47 +0800 | [diff] [blame] | 7337 | if (subpass.pDepthStencilAttachment && |
| 7338 | subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { |
| 7339 | if (attachment == subpass.pDepthStencilAttachment->attachment) |
Courtney Goeltzenleuchter | 6ed5dc2 | 2015-11-03 15:41:43 -0700 | [diff] [blame] | 7340 | return VK_TRUE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7341 | } |
Courtney Goeltzenleuchter | 6ed5dc2 | 2015-11-03 15:41:43 -0700 | [diff] [blame] | 7342 | VkBool32 result = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7343 | // Loop through previous nodes and see if any of them write to the |
| 7344 | // attachment. |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7345 | for (auto elem : node.prev) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7346 | result |= CheckPreserved(my_data, device, pCreateInfo, elem, attachment, |
| 7347 | subpass_to_node, depth + 1, skip_call); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7348 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7349 | // If the attachment was written to by a previous node than this node needs |
| 7350 | // to preserve it. |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7351 | if (result && depth > 0) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7352 | const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[index]; |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7353 | VkBool32 has_preserved = VK_FALSE; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7354 | for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) { |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 7355 | if (subpass.pPreserveAttachments[j] == attachment) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7356 | has_preserved = VK_TRUE; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7357 | break; |
| 7358 | } |
| 7359 | } |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7360 | if (has_preserved == VK_FALSE) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7361 | skip_call |= |
| 7362 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7363 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7364 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7365 | "Attachment %d is used by a later subpass and must be " |
| 7366 | "preserved in subpass %d.", |
| 7367 | attachment, index); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7368 | } |
| 7369 | } |
| 7370 | return result; |
| 7371 | } |
| 7372 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7373 | VkBool32 ValidateDependencies(const layer_data *my_data, VkDevice device, |
| 7374 | const VkRenderPassCreateInfo *pCreateInfo, |
| 7375 | const std::vector<DAGNode> &subpass_to_node) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7376 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7377 | std::vector<std::vector<uint32_t>> output_attachment_to_subpass( |
| 7378 | pCreateInfo->attachmentCount); |
| 7379 | std::vector<std::vector<uint32_t>> input_attachment_to_subpass( |
| 7380 | pCreateInfo->attachmentCount); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7381 | // Find for each attachment the subpasses that use them. |
| 7382 | for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7383 | const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7384 | for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7385 | input_attachment_to_subpass[subpass.pInputAttachments[j].attachment] |
| 7386 | .push_back(i); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7387 | } |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7388 | for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7389 | output_attachment_to_subpass[subpass.pColorAttachments[j] |
| 7390 | .attachment].push_back(i); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7391 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7392 | if (subpass.pDepthStencilAttachment && |
| 7393 | subpass.pDepthStencilAttachment->attachment != |
| 7394 | VK_ATTACHMENT_UNUSED) { |
| 7395 | output_attachment_to_subpass[subpass.pDepthStencilAttachment |
| 7396 | ->attachment].push_back(i); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7397 | } |
| 7398 | } |
| 7399 | // If there is a dependency needed make sure one exists |
| 7400 | for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7401 | const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; |
| 7402 | // If the attachment is an input then all subpasses that output must |
| 7403 | // have a dependency relationship |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7404 | for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7405 | const uint32_t &attachment = |
| 7406 | subpass.pInputAttachments[j].attachment; |
| 7407 | CheckDependencyExists(my_data, device, i, |
| 7408 | output_attachment_to_subpass[attachment], |
| 7409 | subpass_to_node, skip_call); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7410 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7411 | // If the attachment is an output then all subpasses that use the |
| 7412 | // attachment must have a dependency relationship |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7413 | for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7414 | const uint32_t &attachment = |
| 7415 | subpass.pColorAttachments[j].attachment; |
| 7416 | CheckDependencyExists(my_data, device, i, |
| 7417 | output_attachment_to_subpass[attachment], |
| 7418 | subpass_to_node, skip_call); |
| 7419 | CheckDependencyExists(my_data, device, i, |
| 7420 | input_attachment_to_subpass[attachment], |
| 7421 | subpass_to_node, skip_call); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7422 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7423 | if (subpass.pDepthStencilAttachment && |
| 7424 | subpass.pDepthStencilAttachment->attachment != |
| 7425 | VK_ATTACHMENT_UNUSED) { |
| 7426 | const uint32_t &attachment = |
| 7427 | subpass.pDepthStencilAttachment->attachment; |
| 7428 | CheckDependencyExists(my_data, device, i, |
| 7429 | output_attachment_to_subpass[attachment], |
| 7430 | subpass_to_node, skip_call); |
| 7431 | CheckDependencyExists(my_data, device, i, |
| 7432 | input_attachment_to_subpass[attachment], |
| 7433 | subpass_to_node, skip_call); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7434 | } |
| 7435 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7436 | // Loop through implicit dependencies, if this pass reads make sure the |
| 7437 | // attachment is preserved for all passes after it was written. |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7438 | for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7439 | const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7440 | for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7441 | CheckPreserved(my_data, device, pCreateInfo, i, |
| 7442 | subpass.pInputAttachments[j].attachment, |
| 7443 | subpass_to_node, 0, skip_call); |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7444 | } |
| 7445 | } |
| 7446 | return skip_call; |
| 7447 | } |
| 7448 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7449 | VkBool32 ValidateLayouts(const layer_data *my_data, VkDevice device, |
| 7450 | const VkRenderPassCreateInfo *pCreateInfo) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7451 | VkBool32 skip = VK_FALSE; |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 7452 | |
| 7453 | #ifdef DISABLE_IMAGE_LAYOUT_VALIDATION |
| 7454 | return skip; |
| 7455 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
| 7456 | |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7457 | for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7458 | const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7459 | for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7460 | if (subpass.pInputAttachments[j].layout != |
| 7461 | VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL && |
| 7462 | subpass.pInputAttachments[j].layout != |
| 7463 | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { |
| 7464 | if (subpass.pInputAttachments[j].layout == |
| 7465 | VK_IMAGE_LAYOUT_GENERAL) { |
| 7466 | // TODO: Verify Valid Use in spec. I believe this is allowed |
| 7467 | // (valid) but may not be optimal performance |
| 7468 | skip |= log_msg(my_data->report_data, |
| 7469 | VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 7470 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7471 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 7472 | "Layout for input attachment is GENERAL " |
| 7473 | "but should be READ_ONLY_OPTIMAL."); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7474 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7475 | skip |= log_msg(my_data->report_data, |
| 7476 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7477 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7478 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 7479 | "Layout for input attachment is %d but can " |
| 7480 | "only be READ_ONLY_OPTIMAL or GENERAL.", |
| 7481 | subpass.pInputAttachments[j].attachment); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7482 | } |
| 7483 | } |
| 7484 | } |
| 7485 | for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7486 | if (subpass.pColorAttachments[j].layout != |
| 7487 | VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { |
| 7488 | if (subpass.pColorAttachments[j].layout == |
| 7489 | VK_IMAGE_LAYOUT_GENERAL) { |
| 7490 | // TODO: Verify Valid Use in spec. I believe this is allowed |
| 7491 | // (valid) but may not be optimal performance |
| 7492 | skip |= log_msg(my_data->report_data, |
| 7493 | VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 7494 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7495 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 7496 | "Layout for color attachment is GENERAL " |
| 7497 | "but should be COLOR_ATTACHMENT_OPTIMAL."); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7498 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7499 | skip |= log_msg( |
| 7500 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7501 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7502 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 7503 | "Layout for color attachment is %d but can only be " |
| 7504 | "COLOR_ATTACHMENT_OPTIMAL or GENERAL.", |
| 7505 | subpass.pColorAttachments[j].attachment); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7506 | } |
| 7507 | } |
| 7508 | } |
Mark Lobodzinski | 0f30f9e | 2015-10-28 13:03:56 -0600 | [diff] [blame] | 7509 | if ((subpass.pDepthStencilAttachment != NULL) && |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7510 | (subpass.pDepthStencilAttachment->attachment != |
| 7511 | VK_ATTACHMENT_UNUSED)) { |
| 7512 | if (subpass.pDepthStencilAttachment->layout != |
| 7513 | VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { |
| 7514 | if (subpass.pDepthStencilAttachment->layout == |
| 7515 | VK_IMAGE_LAYOUT_GENERAL) { |
| 7516 | // TODO: Verify Valid Use in spec. I believe this is allowed |
| 7517 | // (valid) but may not be optimal performance |
| 7518 | skip |= log_msg( |
| 7519 | my_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 7520 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7521 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 7522 | "Layout for depth attachment is GENERAL but should be " |
| 7523 | "DEPTH_STENCIL_ATTACHMENT_OPTIMAL."); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7524 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7525 | skip |= log_msg( |
| 7526 | my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7527 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7528 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 7529 | "Layout for depth attachment is %d but can only be " |
| 7530 | "DEPTH_STENCIL_ATTACHMENT_OPTIMAL or GENERAL.", |
| 7531 | subpass.pDepthStencilAttachment->attachment); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7532 | } |
| 7533 | } |
| 7534 | } |
| 7535 | } |
| 7536 | return skip; |
| 7537 | } |
| 7538 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7539 | VkBool32 CreatePassDAG(const layer_data *my_data, VkDevice device, |
| 7540 | const VkRenderPassCreateInfo *pCreateInfo, |
| 7541 | std::vector<DAGNode> &subpass_to_node, |
| 7542 | std::vector<bool> &has_self_dependency) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7543 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7544 | for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7545 | DAGNode &subpass_node = subpass_to_node[i]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7546 | subpass_node.pass = i; |
| 7547 | } |
| 7548 | for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7549 | const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i]; |
| 7550 | if (dependency.srcSubpass > dependency.dstSubpass && |
| 7551 | dependency.srcSubpass != VK_SUBPASS_EXTERNAL && |
| 7552 | dependency.dstSubpass != VK_SUBPASS_EXTERNAL) { |
| 7553 | skip_call |= |
| 7554 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7555 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7556 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7557 | "Depedency graph must be specified such that an " |
| 7558 | "earlier pass cannot depend on a later pass."); |
| 7559 | } else if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL && |
| 7560 | dependency.dstSubpass == VK_SUBPASS_EXTERNAL) { |
| 7561 | skip_call |= |
| 7562 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7563 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7564 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7565 | "The src and dest subpasses cannot both be external."); |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7566 | } else if (dependency.srcSubpass == dependency.dstSubpass) { |
| 7567 | has_self_dependency[dependency.srcSubpass] = true; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7568 | } |
Michael Lentine | 6bd4f12 | 2016-01-19 14:00:53 -0600 | [diff] [blame] | 7569 | if (dependency.dstSubpass != VK_SUBPASS_EXTERNAL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7570 | subpass_to_node[dependency.dstSubpass].prev.push_back( |
| 7571 | dependency.srcSubpass); |
Michael Lentine | 6bd4f12 | 2016-01-19 14:00:53 -0600 | [diff] [blame] | 7572 | } |
| 7573 | if (dependency.srcSubpass != VK_SUBPASS_EXTERNAL) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7574 | subpass_to_node[dependency.srcSubpass].next.push_back( |
| 7575 | dependency.dstSubpass); |
Michael Lentine | 6bd4f12 | 2016-01-19 14:00:53 -0600 | [diff] [blame] | 7576 | } |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7577 | } |
| 7578 | return skip_call; |
| 7579 | } |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 7580 | // TODOSC : Add intercept of vkCreateShaderModule |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7581 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7582 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 7583 | vkCreateShaderModule(VkDevice device, |
| 7584 | const VkShaderModuleCreateInfo *pCreateInfo, |
| 7585 | const VkAllocationCallbacks *pAllocator, |
| 7586 | VkShaderModule *pShaderModule) { |
| 7587 | layer_data *my_data = |
| 7588 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7589 | VkBool32 skip_call = VK_FALSE; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7590 | if (!shader_is_spirv(pCreateInfo)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7591 | skip_call |= |
| 7592 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7593 | VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, |
| 7594 | /* dev */ 0, __LINE__, SHADER_CHECKER_NON_SPIRV_SHADER, |
| 7595 | "SC", "Shader is not SPIR-V"); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7596 | } |
| 7597 | |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7598 | if (VK_FALSE != skip_call) |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 7599 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7600 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7601 | VkResult res = my_data->device_dispatch_table->CreateShaderModule( |
| 7602 | device, pCreateInfo, pAllocator, pShaderModule); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7603 | |
| 7604 | if (res == VK_SUCCESS) { |
| 7605 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7606 | my_data->shaderModuleMap[*pShaderModule] = |
| 7607 | new shader_module(pCreateInfo); |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7608 | loader_platform_thread_unlock_mutex(&globalLock); |
| 7609 | } |
| 7610 | return res; |
| 7611 | } |
| 7612 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7613 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 7614 | vkCreateRenderPass(VkDevice device, |
| 7615 | const VkRenderPassCreateInfo *pCreateInfo, |
| 7616 | const VkAllocationCallbacks *pAllocator, |
| 7617 | VkRenderPass *pRenderPass) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7618 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7619 | layer_data *dev_data = |
| 7620 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7621 | // Create DAG |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7622 | std::vector<bool> has_self_dependency(pCreateInfo->subpassCount); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7623 | std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7624 | skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, |
| 7625 | has_self_dependency); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7626 | // Validate using DAG |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7627 | skip_call |= |
| 7628 | ValidateDependencies(dev_data, device, pCreateInfo, subpass_to_node); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7629 | skip_call |= ValidateLayouts(dev_data, device, pCreateInfo); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7630 | if (VK_FALSE != skip_call) { |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 7631 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | b698675 | 2015-10-06 14:56:18 -0700 | [diff] [blame] | 7632 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7633 | VkResult result = dev_data->device_dispatch_table->CreateRenderPass( |
| 7634 | device, pCreateInfo, pAllocator, pRenderPass); |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 7635 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 8fab656 | 2015-12-01 09:57:09 -0700 | [diff] [blame] | 7636 | // TODOSC : Merge in tracking of renderpass from ShaderChecker |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7637 | // Shadow create info and store in map |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7638 | VkRenderPassCreateInfo *localRPCI = |
| 7639 | new VkRenderPassCreateInfo(*pCreateInfo); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7640 | if (pCreateInfo->pAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7641 | localRPCI->pAttachments = |
| 7642 | new VkAttachmentDescription[localRPCI->attachmentCount]; |
| 7643 | memcpy((void *)localRPCI->pAttachments, pCreateInfo->pAttachments, |
| 7644 | localRPCI->attachmentCount * |
| 7645 | sizeof(VkAttachmentDescription)); |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7646 | } |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7647 | if (pCreateInfo->pSubpasses) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7648 | localRPCI->pSubpasses = |
| 7649 | new VkSubpassDescription[localRPCI->subpassCount]; |
| 7650 | memcpy((void *)localRPCI->pSubpasses, pCreateInfo->pSubpasses, |
| 7651 | localRPCI->subpassCount * sizeof(VkSubpassDescription)); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7652 | |
| 7653 | for (uint32_t i = 0; i < localRPCI->subpassCount; i++) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7654 | VkSubpassDescription *subpass = |
| 7655 | (VkSubpassDescription *)&localRPCI->pSubpasses[i]; |
| 7656 | const uint32_t attachmentCount = |
| 7657 | subpass->inputAttachmentCount + |
| 7658 | subpass->colorAttachmentCount * |
| 7659 | (1 + (subpass->pResolveAttachments ? 1 : 0)) + |
| 7660 | ((subpass->pDepthStencilAttachment) ? 1 : 0) + |
| 7661 | subpass->preserveAttachmentCount; |
| 7662 | VkAttachmentReference *attachments = |
| 7663 | new VkAttachmentReference[attachmentCount]; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7664 | |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7665 | memcpy(attachments, subpass->pInputAttachments, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7666 | sizeof(attachments[0]) * subpass->inputAttachmentCount); |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7667 | subpass->pInputAttachments = attachments; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7668 | attachments += subpass->inputAttachmentCount; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7669 | |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7670 | memcpy(attachments, subpass->pColorAttachments, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7671 | sizeof(attachments[0]) * subpass->colorAttachmentCount); |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7672 | subpass->pColorAttachments = attachments; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7673 | attachments += subpass->colorAttachmentCount; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7674 | |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7675 | if (subpass->pResolveAttachments) { |
| 7676 | memcpy(attachments, subpass->pResolveAttachments, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7677 | sizeof(attachments[0]) * |
| 7678 | subpass->colorAttachmentCount); |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7679 | subpass->pResolveAttachments = attachments; |
Chia-I Wu | d50a7d7 | 2015-10-26 20:48:51 +0800 | [diff] [blame] | 7680 | attachments += subpass->colorAttachmentCount; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7681 | } |
| 7682 | |
Chia-I Wu | 1efb7e5 | 2015-10-26 17:32:47 +0800 | [diff] [blame] | 7683 | if (subpass->pDepthStencilAttachment) { |
| 7684 | memcpy(attachments, subpass->pDepthStencilAttachment, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7685 | sizeof(attachments[0]) * 1); |
Chia-I Wu | 1efb7e5 | 2015-10-26 17:32:47 +0800 | [diff] [blame] | 7686 | subpass->pDepthStencilAttachment = attachments; |
| 7687 | attachments += 1; |
| 7688 | } |
| 7689 | |
Cody Northrop | a505dda | 2015-08-04 11:16:41 -0600 | [diff] [blame] | 7690 | memcpy(attachments, subpass->pPreserveAttachments, |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7691 | sizeof(attachments[0]) * |
| 7692 | subpass->preserveAttachmentCount); |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 7693 | subpass->pPreserveAttachments = &attachments->attachment; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7694 | } |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7695 | } |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7696 | if (pCreateInfo->pDependencies) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7697 | localRPCI->pDependencies = |
| 7698 | new VkSubpassDependency[localRPCI->dependencyCount]; |
| 7699 | memcpy((void *)localRPCI->pDependencies, pCreateInfo->pDependencies, |
| 7700 | localRPCI->dependencyCount * sizeof(VkSubpassDependency)); |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7701 | } |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7702 | loader_platform_thread_lock_mutex(&globalLock); |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 7703 | dev_data->renderPassMap[*pRenderPass] = new RENDER_PASS_NODE(localRPCI); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7704 | dev_data->renderPassMap[*pRenderPass]->hasSelfDependency = |
| 7705 | has_self_dependency; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 7706 | loader_platform_thread_unlock_mutex(&globalLock); |
Tobin Ehlis | eba312c | 2015-04-01 08:40:34 -0600 | [diff] [blame] | 7707 | } |
| 7708 | return result; |
| 7709 | } |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7710 | // Free the renderpass shadow |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7711 | static void deleteRenderPasses(layer_data *my_data) { |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7712 | if (my_data->renderPassMap.size() <= 0) |
| 7713 | return; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7714 | for (auto ii = my_data->renderPassMap.begin(); |
| 7715 | ii != my_data->renderPassMap.end(); ++ii) { |
| 7716 | const VkRenderPassCreateInfo *pRenderPassInfo = |
| 7717 | (*ii).second->pCreateInfo; |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7718 | if (pRenderPassInfo->pAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7719 | delete[] pRenderPassInfo -> pAttachments; |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7720 | } |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7721 | if (pRenderPassInfo->pSubpasses) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7722 | for (uint32_t i = 0; i < pRenderPassInfo->subpassCount; ++i) { |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7723 | // Attachements are all allocated in a block, so just need to |
| 7724 | // find the first non-null one to delete |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7725 | if (pRenderPassInfo->pSubpasses[i].pInputAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7726 | delete[] pRenderPassInfo -> pSubpasses[i].pInputAttachments; |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7727 | } else if (pRenderPassInfo->pSubpasses[i].pColorAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7728 | delete[] pRenderPassInfo -> pSubpasses[i].pColorAttachments; |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7729 | } else if (pRenderPassInfo->pSubpasses[i].pResolveAttachments) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7730 | delete[] pRenderPassInfo -> pSubpasses[i] |
| 7731 | .pResolveAttachments; |
| 7732 | } else if (pRenderPassInfo->pSubpasses[i] |
| 7733 | .pPreserveAttachments) { |
| 7734 | delete[] pRenderPassInfo -> pSubpasses[i] |
| 7735 | .pPreserveAttachments; |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7736 | } |
| 7737 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7738 | delete[] pRenderPassInfo -> pSubpasses; |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7739 | } |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7740 | if (pRenderPassInfo->pDependencies) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7741 | delete[] pRenderPassInfo -> pDependencies; |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7742 | } |
Tobin Ehlis | 3f5ddbb | 2015-12-02 13:53:34 -0700 | [diff] [blame] | 7743 | delete pRenderPassInfo; |
Michael Lentine | 48930b8 | 2015-10-15 17:07:00 -0500 | [diff] [blame] | 7744 | delete (*ii).second; |
Tobin Ehlis | b212dfc | 2015-10-07 15:40:22 -0600 | [diff] [blame] | 7745 | } |
| 7746 | my_data->renderPassMap.clear(); |
| 7747 | } |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7748 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7749 | VkBool32 VerifyFramebufferAndRenderPassLayouts( |
| 7750 | VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo *pRenderPassBegin) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7751 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7752 | layer_data *dev_data = |
| 7753 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 7754 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
| 7755 | const VkRenderPassCreateInfo *pRenderPassInfo = |
| 7756 | dev_data->renderPassMap[pRenderPassBegin->renderPass]->pCreateInfo; |
| 7757 | const VkFramebufferCreateInfo *pFramebufferInfo = |
| 7758 | dev_data->frameBufferMap[pRenderPassBegin->framebuffer]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7759 | if (pRenderPassInfo->attachmentCount != pFramebufferInfo->attachmentCount) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7760 | skip_call |= |
| 7761 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7762 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7763 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7764 | "You cannot start a render pass using a framebuffer with a " |
| 7765 | "different number of attachments."); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7766 | } |
| 7767 | for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7768 | const VkImageView &image_view = pFramebufferInfo->pAttachments[i]; |
| 7769 | const VkImage &image = dev_data->imageViewMap[image_view]->image; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7770 | auto image_data = pCB->imageLayoutMap.find(image); |
| 7771 | if (image_data == pCB->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7772 | pCB->imageLayoutMap[image].initialLayout = |
| 7773 | pRenderPassInfo->pAttachments[i].initialLayout; |
| 7774 | pCB->imageLayoutMap[image].layout = |
| 7775 | pRenderPassInfo->pAttachments[i].initialLayout; |
| 7776 | } else if (pRenderPassInfo->pAttachments[i].initialLayout != |
| 7777 | image_data->second.layout) { |
| 7778 | skip_call |= log_msg( |
| 7779 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7780 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7781 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7782 | "You cannot start a render pass using attachment %i where the " |
| 7783 | "intial layout differs from the starting layout.", |
| 7784 | i); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7785 | } |
| 7786 | } |
| 7787 | return skip_call; |
| 7788 | } |
| 7789 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7790 | void TransitionSubpassLayouts(VkCommandBuffer cmdBuffer, |
| 7791 | const VkRenderPassBeginInfo *pRenderPassBegin, |
| 7792 | const int subpass_index) { |
| 7793 | layer_data *dev_data = |
| 7794 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 7795 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
| 7796 | auto render_pass_data = |
| 7797 | dev_data->renderPassMap.find(pRenderPassBegin->renderPass); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7798 | if (render_pass_data == dev_data->renderPassMap.end()) { |
| 7799 | return; |
| 7800 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7801 | const VkRenderPassCreateInfo *pRenderPassInfo = |
| 7802 | render_pass_data->second->pCreateInfo; |
| 7803 | auto framebuffer_data = |
| 7804 | dev_data->frameBufferMap.find(pRenderPassBegin->framebuffer); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7805 | if (framebuffer_data == dev_data->frameBufferMap.end()) { |
| 7806 | return; |
| 7807 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7808 | const VkFramebufferCreateInfo *pFramebufferInfo = framebuffer_data->second; |
| 7809 | const VkSubpassDescription &subpass = |
| 7810 | pRenderPassInfo->pSubpasses[subpass_index]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7811 | for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7812 | const VkImageView &image_view = |
| 7813 | pFramebufferInfo |
| 7814 | ->pAttachments[subpass.pInputAttachments[j].attachment]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7815 | auto image_view_data = dev_data->imageViewMap.find(image_view); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7816 | if (image_view_data != dev_data->imageViewMap.end()) { |
| 7817 | auto image_layout = |
| 7818 | pCB->imageLayoutMap.find(image_view_data->second->image); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7819 | if (image_layout != pCB->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7820 | image_layout->second.layout = |
| 7821 | subpass.pInputAttachments[j].layout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7822 | } |
| 7823 | } |
| 7824 | } |
| 7825 | for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7826 | const VkImageView &image_view = |
| 7827 | pFramebufferInfo |
| 7828 | ->pAttachments[subpass.pColorAttachments[j].attachment]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7829 | auto image_view_data = dev_data->imageViewMap.find(image_view); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7830 | if (image_view_data != dev_data->imageViewMap.end()) { |
| 7831 | auto image_layout = |
| 7832 | pCB->imageLayoutMap.find(image_view_data->second->image); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7833 | if (image_layout != pCB->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7834 | image_layout->second.layout = |
| 7835 | subpass.pColorAttachments[j].layout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7836 | } |
| 7837 | } |
| 7838 | } |
Michael Lentine | 3dea651 | 2015-10-28 15:55:18 -0700 | [diff] [blame] | 7839 | if ((subpass.pDepthStencilAttachment != NULL) && |
Mark Lobodzinski | 0f30f9e | 2015-10-28 13:03:56 -0600 | [diff] [blame] | 7840 | (subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7841 | const VkImageView &image_view = |
| 7842 | pFramebufferInfo |
| 7843 | ->pAttachments[subpass.pDepthStencilAttachment->attachment]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7844 | auto image_view_data = dev_data->imageViewMap.find(image_view); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7845 | if (image_view_data != dev_data->imageViewMap.end()) { |
| 7846 | auto image_layout = |
| 7847 | pCB->imageLayoutMap.find(image_view_data->second->image); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7848 | if (image_layout != pCB->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7849 | image_layout->second.layout = |
| 7850 | subpass.pDepthStencilAttachment->layout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7851 | } |
| 7852 | } |
| 7853 | } |
| 7854 | } |
| 7855 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7856 | VkBool32 validatePrimaryCommandBuffer(const layer_data *my_data, |
| 7857 | const GLOBAL_CB_NODE *pCB, |
| 7858 | const std::string &cmd_name) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 7859 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 3dea651 | 2015-10-28 15:55:18 -0700 | [diff] [blame] | 7860 | if (pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7861 | skip_call |= |
| 7862 | log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7863 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7864 | DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", |
| 7865 | "Cannot execute command %s on a secondary command buffer.", |
| 7866 | cmd_name.c_str()); |
Michael Lentine | 3dea651 | 2015-10-28 15:55:18 -0700 | [diff] [blame] | 7867 | } |
| 7868 | return skip_call; |
| 7869 | } |
| 7870 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7871 | void |
| 7872 | TransitionFinalSubpassLayouts(VkCommandBuffer cmdBuffer, |
| 7873 | const VkRenderPassBeginInfo *pRenderPassBegin) { |
| 7874 | layer_data *dev_data = |
| 7875 | get_my_data_ptr(get_dispatch_key(cmdBuffer), layer_data_map); |
| 7876 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, cmdBuffer); |
| 7877 | auto render_pass_data = |
| 7878 | dev_data->renderPassMap.find(pRenderPassBegin->renderPass); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7879 | if (render_pass_data == dev_data->renderPassMap.end()) { |
| 7880 | return; |
| 7881 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7882 | const VkRenderPassCreateInfo *pRenderPassInfo = |
| 7883 | render_pass_data->second->pCreateInfo; |
| 7884 | auto framebuffer_data = |
| 7885 | dev_data->frameBufferMap.find(pRenderPassBegin->framebuffer); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7886 | if (framebuffer_data == dev_data->frameBufferMap.end()) { |
| 7887 | return; |
| 7888 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7889 | const VkFramebufferCreateInfo *pFramebufferInfo = framebuffer_data->second; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7890 | for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7891 | const VkImageView &image_view = pFramebufferInfo->pAttachments[i]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7892 | auto image_view_data = dev_data->imageViewMap.find(image_view); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7893 | if (image_view_data != dev_data->imageViewMap.end()) { |
| 7894 | auto image_layout = |
| 7895 | pCB->imageLayoutMap.find(image_view_data->second->image); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7896 | if (image_layout != pCB->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7897 | image_layout->second.layout = |
| 7898 | pRenderPassInfo->pAttachments[i].finalLayout; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7899 | } |
| 7900 | } |
| 7901 | } |
| 7902 | } |
| 7903 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7904 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7905 | vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, |
| 7906 | const VkRenderPassBeginInfo *pRenderPassBegin, |
| 7907 | VkSubpassContents contents) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7908 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7909 | layer_data *dev_data = |
| 7910 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7911 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7912 | if (pCB) { |
Tobin Ehlis | 259730a | 2015-06-23 16:13:03 -0600 | [diff] [blame] | 7913 | if (pRenderPassBegin && pRenderPassBegin->renderPass) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7914 | skipCall |= VerifyFramebufferAndRenderPassLayouts(commandBuffer, |
| 7915 | pRenderPassBegin); |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 7916 | skipCall |= insideRenderPass(dev_data, pCB, "vkCmdBeginRenderPass"); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7917 | skipCall |= validatePrimaryCommandBuffer(dev_data, pCB, |
| 7918 | "vkCmdBeginRenderPass"); |
| 7919 | skipCall |= addCmd(dev_data, pCB, CMD_BEGINRENDERPASS, |
| 7920 | "vkCmdBeginRenderPass()"); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7921 | pCB->activeRenderPass = pRenderPassBegin->renderPass; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 7922 | // This is a shallow copy as that is all that is needed for now |
| 7923 | pCB->activeRenderPassBeginInfo = *pRenderPassBegin; |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7924 | pCB->activeSubpass = 0; |
Michael Lentine | 2e068b2 | 2015-12-29 16:05:27 -0600 | [diff] [blame] | 7925 | pCB->activeSubpassContents = contents; |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7926 | pCB->framebuffer = pRenderPassBegin->framebuffer; |
Tobin Ehlis | 502480b | 2015-06-24 15:53:07 -0600 | [diff] [blame] | 7927 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7928 | skipCall |= |
| 7929 | log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 7930 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 7931 | DRAWSTATE_INVALID_RENDERPASS, "DS", |
| 7932 | "You cannot use a NULL RenderPass object in " |
| 7933 | "vkCmdBeginRenderPass()"); |
Tony Barbour | badda99 | 2015-04-06 11:09:26 -0600 | [diff] [blame] | 7934 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7935 | } |
Mark Lobodzinski | 0f30f9e | 2015-10-28 13:03:56 -0600 | [diff] [blame] | 7936 | if (VK_FALSE == skipCall) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7937 | dev_data->device_dispatch_table->CmdBeginRenderPass( |
| 7938 | commandBuffer, pRenderPassBegin, contents); |
Mark Lobodzinski | 0f30f9e | 2015-10-28 13:03:56 -0600 | [diff] [blame] | 7939 | // This is a shallow copy as that is all that is needed for now |
| 7940 | dev_data->renderPassBeginInfo = *pRenderPassBegin; |
| 7941 | dev_data->currentSubpass = 0; |
| 7942 | } |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7943 | } |
| 7944 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7945 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7946 | vkCmdNextSubpass(VkCommandBuffer commandBuffer, |
| 7947 | VkSubpassContents contents) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7948 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7949 | layer_data *dev_data = |
| 7950 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7951 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
| 7952 | TransitionSubpassLayouts(commandBuffer, &dev_data->renderPassBeginInfo, |
| 7953 | ++dev_data->currentSubpass); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7954 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7955 | skipCall |= |
| 7956 | validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass"); |
| 7957 | skipCall |= |
| 7958 | addCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()"); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7959 | pCB->activeSubpass++; |
Michael Lentine | 2e068b2 | 2015-12-29 16:05:27 -0600 | [diff] [blame] | 7960 | pCB->activeSubpassContents = contents; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7961 | TransitionSubpassLayouts(commandBuffer, &pCB->activeRenderPassBeginInfo, |
| 7962 | pCB->activeSubpass); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7963 | if (pCB->lastBoundPipeline) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7964 | skipCall |= validatePipelineState(dev_data, pCB, |
| 7965 | VK_PIPELINE_BIND_POINT_GRAPHICS, |
| 7966 | pCB->lastBoundPipeline); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7967 | } |
Tobin Ehlis | 432ef5c | 2015-10-20 17:06:16 -0600 | [diff] [blame] | 7968 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass"); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7969 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7970 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7971 | dev_data->device_dispatch_table->CmdNextSubpass(commandBuffer, |
| 7972 | contents); |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 7973 | } |
| 7974 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7975 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7976 | vkCmdEndRenderPass(VkCommandBuffer commandBuffer) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7977 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7978 | layer_data *dev_data = |
| 7979 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 7980 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
| 7981 | TransitionFinalSubpassLayouts(commandBuffer, |
| 7982 | &dev_data->renderPassBeginInfo); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 7983 | if (pCB) { |
Michael Lentine | 3dea651 | 2015-10-28 15:55:18 -0700 | [diff] [blame] | 7984 | skipCall |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass"); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7985 | skipCall |= |
| 7986 | validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass"); |
| 7987 | skipCall |= |
| 7988 | addCmd(dev_data, pCB, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()"); |
| 7989 | TransitionFinalSubpassLayouts(commandBuffer, |
| 7990 | &pCB->activeRenderPassBeginInfo); |
Mark Lobodzinski | 5495d13 | 2015-09-30 16:19:16 -0600 | [diff] [blame] | 7991 | pCB->activeRenderPass = 0; |
| 7992 | pCB->activeSubpass = 0; |
Chia-I Wu | 0b50a1c | 2015-06-26 15:34:39 +0800 | [diff] [blame] | 7993 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 7994 | if (VK_FALSE == skipCall) |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 7995 | dev_data->device_dispatch_table->CmdEndRenderPass(commandBuffer); |
Chia-I Wu | 0b50a1c | 2015-06-26 15:34:39 +0800 | [diff] [blame] | 7996 | } |
| 7997 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 7998 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 7999 | vkCmdExecuteCommands(VkCommandBuffer commandBuffer, |
| 8000 | uint32_t commandBuffersCount, |
| 8001 | const VkCommandBuffer *pCommandBuffers) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 8002 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8003 | layer_data *dev_data = |
| 8004 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 8005 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Chia-I Wu | 0b50a1c | 2015-06-26 15:34:39 +0800 | [diff] [blame] | 8006 | if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8007 | GLOBAL_CB_NODE *pSubCB = NULL; |
| 8008 | for (uint32_t i = 0; i < commandBuffersCount; i++) { |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 8009 | pSubCB = getCBNode(dev_data, pCommandBuffers[i]); |
Tobin Ehlis | 4b34ddc | 2015-09-17 14:18:16 -0600 | [diff] [blame] | 8010 | if (!pSubCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8011 | skipCall |= log_msg( |
| 8012 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8013 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 8014 | DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", |
| 8015 | "vkCmdExecuteCommands() called w/ invalid Cmd Buffer %p in " |
| 8016 | "element %u of pCommandBuffers array.", |
| 8017 | (void *)pCommandBuffers[i], i); |
| 8018 | } else if (VK_COMMAND_BUFFER_LEVEL_PRIMARY == |
| 8019 | pSubCB->createInfo.level) { |
| 8020 | skipCall |= log_msg( |
| 8021 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8022 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 8023 | DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", |
| 8024 | "vkCmdExecuteCommands() called w/ Primary Cmd Buffer %p in " |
| 8025 | "element %u of pCommandBuffers array. All cmd buffers in " |
| 8026 | "pCommandBuffers array must be secondary.", |
| 8027 | (void *)pCommandBuffers[i], i); |
| 8028 | } else if (pCB->activeRenderPass) { // Secondary CB w/i RenderPass |
| 8029 | // must have *CONTINUE_BIT set |
| 8030 | if (!(pSubCB->beginInfo.flags & |
| 8031 | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { |
| 8032 | skipCall |= log_msg( |
| 8033 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8034 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8035 | (uint64_t)pCommandBuffers[i], __LINE__, |
| 8036 | DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS", |
| 8037 | "vkCmdExecuteCommands(): Secondary Command Buffer (%p) " |
| 8038 | "executed within render pass (%#" PRIxLEAST64 |
| 8039 | ") must have had vkBeginCommandBuffer() called w/ " |
| 8040 | "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT set.", |
| 8041 | (void *)pCommandBuffers[i], |
| 8042 | (uint64_t)pCB->activeRenderPass); |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 8043 | } |
| 8044 | string errorString = ""; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8045 | if (!verify_renderpass_compatibility( |
| 8046 | dev_data, pCB->activeRenderPass, |
| 8047 | pSubCB->beginInfo.pInheritanceInfo->renderPass, |
| 8048 | errorString)) { |
| 8049 | skipCall |= log_msg( |
| 8050 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8051 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8052 | (uint64_t)pCommandBuffers[i], __LINE__, |
| 8053 | DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", |
| 8054 | "vkCmdExecuteCommands(): Secondary Command Buffer (%p) " |
| 8055 | "w/ render pass (%#" PRIxLEAST64 |
| 8056 | ") is incompatible w/ primary command buffer (%p) w/ " |
| 8057 | "render pass (%#" PRIxLEAST64 ") due to: %s", |
| 8058 | (void *)pCommandBuffers[i], |
| 8059 | (uint64_t) |
| 8060 | pSubCB->beginInfo.pInheritanceInfo->renderPass, |
| 8061 | (void *)commandBuffer, (uint64_t)pCB->activeRenderPass, |
| 8062 | errorString.c_str()); |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 8063 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8064 | // If framebuffer for secondary CB is not NULL, then it must |
| 8065 | // match FB from vkCmdBeginRenderPass() |
| 8066 | // that this CB will be executed in AND framebuffer must have |
| 8067 | // been created w/ RP compatible w/ renderpass |
Jon Ashburn | f19916e | 2016-01-11 13:12:43 -0700 | [diff] [blame] | 8068 | if (pSubCB->beginInfo.pInheritanceInfo->framebuffer) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8069 | if (pSubCB->beginInfo.pInheritanceInfo->framebuffer != |
| 8070 | pCB->activeRenderPassBeginInfo.framebuffer) { |
| 8071 | skipCall |= log_msg( |
| 8072 | dev_data->report_data, |
| 8073 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8074 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8075 | (uint64_t)pCommandBuffers[i], __LINE__, |
| 8076 | DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, "DS", |
| 8077 | "vkCmdExecuteCommands(): Secondary Command Buffer " |
| 8078 | "(%p) references framebuffer (%#" PRIxLEAST64 |
| 8079 | ") that does not match framebuffer (%#" PRIxLEAST64 |
| 8080 | ") in active renderpass (%#" PRIxLEAST64 ").", |
| 8081 | (void *)pCommandBuffers[i], |
| 8082 | (uint64_t) |
| 8083 | pSubCB->beginInfo.pInheritanceInfo->framebuffer, |
| 8084 | (uint64_t) |
| 8085 | pCB->activeRenderPassBeginInfo.framebuffer, |
| 8086 | (uint64_t)pCB->activeRenderPass); |
Tobin Ehlis | 651d9b0 | 2015-12-16 05:01:22 -0700 | [diff] [blame] | 8087 | } |
| 8088 | } |
Tobin Ehlis | 4b34ddc | 2015-09-17 14:18:16 -0600 | [diff] [blame] | 8089 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8090 | // Secondary cmdBuffers are considered pending execution starting w/ |
| 8091 | // being recorded |
| 8092 | if (!(pSubCB->beginInfo.flags & |
| 8093 | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { |
| 8094 | if (dev_data->globalInFlightCmdBuffers.find( |
| 8095 | pSubCB->commandBuffer) != |
| 8096 | dev_data->globalInFlightCmdBuffers.end()) { |
| 8097 | skipCall |= log_msg( |
| 8098 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8099 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8100 | (uint64_t)(pCB->commandBuffer), __LINE__, |
| 8101 | DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS", |
| 8102 | "Attempt to simultaneously execute CB %#" PRIxLEAST64 |
| 8103 | " w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT " |
| 8104 | "set!", |
| 8105 | (uint64_t)(pCB->commandBuffer)); |
Tobin Ehlis | f4aafc0 | 2016-01-15 13:34:44 -0700 | [diff] [blame] | 8106 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8107 | if (pCB->beginInfo.flags & |
| 8108 | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) { |
| 8109 | // Warn that non-simultaneous secondary cmd buffer renders |
| 8110 | // primary non-simultaneous |
| 8111 | skipCall |= log_msg( |
| 8112 | dev_data->report_data, VK_DEBUG_REPORT_WARN_BIT_EXT, |
| 8113 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8114 | (uint64_t)(pCommandBuffers[i]), __LINE__, |
| 8115 | DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS", |
| 8116 | "vkCmdExecuteCommands(): Secondary Command Buffer " |
| 8117 | "(%#" PRIxLEAST64 |
| 8118 | ") does not have " |
| 8119 | "VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and " |
| 8120 | "will cause primary command buffer (%#" PRIxLEAST64 |
| 8121 | ") to be treated as if it does not have " |
| 8122 | "VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set, " |
| 8123 | "even though it does.", |
| 8124 | (uint64_t)(pCommandBuffers[i]), |
| 8125 | (uint64_t)(pCB->commandBuffer)); |
| 8126 | pCB->beginInfo.flags &= |
| 8127 | ~VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; |
Tobin Ehlis | f4aafc0 | 2016-01-15 13:34:44 -0700 | [diff] [blame] | 8128 | } |
| 8129 | } |
| 8130 | pCB->secondaryCommandBuffers.insert(pSubCB->commandBuffer); |
Tobin Ehlis | 74714d2 | 2016-01-25 15:24:34 -0800 | [diff] [blame] | 8131 | dev_data->globalInFlightCmdBuffers.insert(pSubCB->commandBuffer); |
Tobin Ehlis | 4b34ddc | 2015-09-17 14:18:16 -0600 | [diff] [blame] | 8132 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8133 | skipCall |= |
| 8134 | validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteComands"); |
| 8135 | skipCall |= |
| 8136 | addCmd(dev_data, pCB, CMD_EXECUTECOMMANDS, "vkCmdExecuteComands()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8137 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 8138 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8139 | dev_data->device_dispatch_table->CmdExecuteCommands( |
| 8140 | commandBuffer, commandBuffersCount, pCommandBuffers); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8141 | } |
| 8142 | |
Courtney Goeltzenleuchter | e6dd808 | 2015-12-16 16:07:01 -0700 | [diff] [blame] | 8143 | VkBool32 ValidateMapImageLayouts(VkDevice device, VkDeviceMemory mem) { |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 8144 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8145 | layer_data *dev_data = |
| 8146 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8147 | auto mem_data = dev_data->memImageMap.find(mem); |
| 8148 | if (mem_data != dev_data->memImageMap.end()) { |
| 8149 | auto image_data = dev_data->imageLayoutMap.find(mem_data->second); |
| 8150 | if (image_data != dev_data->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8151 | if (image_data->second->layout != VK_IMAGE_LAYOUT_PREINITIALIZED && |
| 8152 | image_data->second->layout != VK_IMAGE_LAYOUT_GENERAL) { |
| 8153 | skip_call |= log_msg(dev_data->report_data, |
| 8154 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8155 | (VkDebugReportObjectTypeEXT)0, 0, __LINE__, |
| 8156 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 8157 | "Cannot map an image with layout %d. Only " |
| 8158 | "GENERAL or PREINITIALIZED are supported.", |
| 8159 | image_data->second->layout); |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8160 | } |
| 8161 | } |
| 8162 | } |
| 8163 | return skip_call; |
| 8164 | } |
| 8165 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8166 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 8167 | vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, |
| 8168 | VkDeviceSize size, VkFlags flags, void **ppData) { |
| 8169 | layer_data *dev_data = |
| 8170 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 8171 | |
Courtney Goeltzenleuchter | e6dd808 | 2015-12-16 16:07:01 -0700 | [diff] [blame] | 8172 | VkBool32 skip_call = VK_FALSE; |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 8173 | #ifndef DISABLE_IMAGE_LAYOUT_VALIDATION |
| 8174 | skip_call = ValidateMapImageLayouts(device, mem); |
| 8175 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
| 8176 | |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8177 | if (VK_FALSE == skip_call) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8178 | return dev_data->device_dispatch_table->MapMemory(device, mem, offset, |
| 8179 | size, flags, ppData); |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8180 | } |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 8181 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8182 | } |
| 8183 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8184 | VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(VkDevice device, VkImage image, |
| 8185 | VkDeviceMemory mem, |
| 8186 | VkDeviceSize memOffset) { |
| 8187 | layer_data *dev_data = |
| 8188 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 8189 | VkResult result = dev_data->device_dispatch_table->BindImageMemory( |
| 8190 | device, image, mem, memOffset); |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8191 | loader_platform_thread_lock_mutex(&globalLock); |
| 8192 | dev_data->memImageMap[mem] = image; |
| 8193 | loader_platform_thread_unlock_mutex(&globalLock); |
| 8194 | return result; |
| 8195 | } |
| 8196 | |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 8197 | VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(VkDevice device, VkEvent event) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8198 | layer_data *dev_data = |
| 8199 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 8200 | dev_data->eventMap[event].needsSignaled = false; |
| 8201 | VkResult result = dev_data->device_dispatch_table->SetEvent(device, event); |
| 8202 | return result; |
| 8203 | } |
| 8204 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8205 | VKAPI_ATTR VkResult VKAPI_CALL |
| 8206 | vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, |
| 8207 | const VkBindSparseInfo *pBindInfo, VkFence fence) { |
| 8208 | layer_data *dev_data = |
| 8209 | get_my_data_ptr(get_dispatch_key(queue), layer_data_map); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 8210 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8211 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8212 | for (uint32_t bindIdx = 0; bindIdx < bindInfoCount; ++bindIdx) { |
| 8213 | const VkBindSparseInfo &bindInfo = pBindInfo[bindIdx]; |
| 8214 | for (uint32_t i = 0; i < bindInfo.waitSemaphoreCount; ++i) { |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8215 | if (dev_data->semaphoreSignaledMap[bindInfo.pWaitSemaphores[i]]) { |
| 8216 | dev_data->semaphoreSignaledMap[bindInfo.pWaitSemaphores[i]] = 0; |
| 8217 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8218 | skip_call |= log_msg( |
| 8219 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8220 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 8221 | DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", |
| 8222 | "Queue %#" PRIx64 " is waiting on semaphore %#" PRIx64 |
| 8223 | " that has no way to be signaled.", |
| 8224 | (uint64_t)(queue), (uint64_t)(bindInfo.pWaitSemaphores[i])); |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8225 | } |
| 8226 | } |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8227 | for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) { |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8228 | dev_data->semaphoreSignaledMap[bindInfo.pSignalSemaphores[i]] = 1; |
| 8229 | } |
| 8230 | } |
| 8231 | |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 8232 | if (VK_FALSE == skip_call) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8233 | return dev_data->device_dispatch_table->QueueBindSparse( |
| 8234 | queue, bindInfoCount, pBindInfo, fence); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 8235 | else |
| 8236 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8237 | } |
| 8238 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8239 | VKAPI_ATTR VkResult VKAPI_CALL |
| 8240 | vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, |
| 8241 | const VkAllocationCallbacks *pAllocator, |
| 8242 | VkSemaphore *pSemaphore) { |
| 8243 | layer_data *dev_data = |
| 8244 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 8245 | VkResult result = dev_data->device_dispatch_table->CreateSemaphore( |
| 8246 | device, pCreateInfo, pAllocator, pSemaphore); |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8247 | if (result == VK_SUCCESS) { |
| 8248 | dev_data->semaphoreSignaledMap[*pSemaphore] = 0; |
| 8249 | } |
Tobin Ehlis | 51b78af | 2016-01-06 10:27:47 -0700 | [diff] [blame] | 8250 | return result; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8251 | } |
| 8252 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8253 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 8254 | vkCreateSwapchainKHR(VkDevice device, |
| 8255 | const VkSwapchainCreateInfoKHR *pCreateInfo, |
| 8256 | const VkAllocationCallbacks *pAllocator, |
| 8257 | VkSwapchainKHR *pSwapchain) { |
| 8258 | layer_data *dev_data = |
| 8259 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 8260 | VkResult result = dev_data->device_dispatch_table->CreateSwapchainKHR( |
| 8261 | device, pCreateInfo, pAllocator, pSwapchain); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8262 | |
| 8263 | if (VK_SUCCESS == result) { |
Tobin Ehlis | 75cd1c5 | 2016-01-21 10:21:04 -0700 | [diff] [blame] | 8264 | SWAPCHAIN_NODE *swapchain_data = new SWAPCHAIN_NODE(pCreateInfo); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8265 | loader_platform_thread_lock_mutex(&globalLock); |
| 8266 | dev_data->device_extensions.swapchainMap[*pSwapchain] = swapchain_data; |
| 8267 | loader_platform_thread_unlock_mutex(&globalLock); |
| 8268 | } |
| 8269 | |
| 8270 | return result; |
| 8271 | } |
| 8272 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8273 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 8274 | vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, |
| 8275 | const VkAllocationCallbacks *pAllocator) { |
| 8276 | layer_data *dev_data = |
| 8277 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8278 | |
| 8279 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8280 | auto swapchain_data = |
| 8281 | dev_data->device_extensions.swapchainMap.find(swapchain); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8282 | if (swapchain_data != dev_data->device_extensions.swapchainMap.end()) { |
| 8283 | if (swapchain_data->second->images.size() > 0) { |
| 8284 | for (auto swapchain_image : swapchain_data->second->images) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8285 | auto image_item = |
| 8286 | dev_data->imageLayoutMap.find(swapchain_image); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8287 | if (image_item != dev_data->imageLayoutMap.end()) |
| 8288 | dev_data->imageLayoutMap.erase(image_item); |
| 8289 | } |
| 8290 | } |
| 8291 | delete swapchain_data->second; |
| 8292 | dev_data->device_extensions.swapchainMap.erase(swapchain); |
| 8293 | } |
| 8294 | loader_platform_thread_unlock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8295 | return dev_data->device_dispatch_table->DestroySwapchainKHR( |
| 8296 | device, swapchain, pAllocator); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8297 | } |
| 8298 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8299 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 8300 | vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, |
| 8301 | uint32_t *pCount, VkImage *pSwapchainImages) { |
| 8302 | layer_data *dev_data = |
| 8303 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 8304 | VkResult result = dev_data->device_dispatch_table->GetSwapchainImagesKHR( |
| 8305 | device, swapchain, pCount, pSwapchainImages); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8306 | |
| 8307 | if (result == VK_SUCCESS && pSwapchainImages != NULL) { |
| 8308 | // This should never happen and is checked by param checker. |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8309 | if (!pCount) |
| 8310 | return result; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8311 | for (uint32_t i = 0; i < *pCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8312 | IMAGE_NODE *image_node = new IMAGE_NODE; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8313 | image_node->layout = VK_IMAGE_LAYOUT_UNDEFINED; |
| 8314 | loader_platform_thread_lock_mutex(&globalLock); |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8315 | auto swapchain_node = |
| 8316 | dev_data->device_extensions.swapchainMap[swapchain]; |
Tobin Ehlis | 75cd1c5 | 2016-01-21 10:21:04 -0700 | [diff] [blame] | 8317 | image_node->format = swapchain_node->createInfo.imageFormat; |
| 8318 | swapchain_node->images.push_back(pSwapchainImages[i]); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8319 | dev_data->imageLayoutMap[pSwapchainImages[i]] = image_node; |
| 8320 | loader_platform_thread_unlock_mutex(&globalLock); |
| 8321 | } |
| 8322 | } |
| 8323 | return result; |
| 8324 | } |
| 8325 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8326 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL |
| 8327 | vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) { |
| 8328 | layer_data *dev_data = |
| 8329 | get_my_data_ptr(get_dispatch_key(queue), layer_data_map); |
Mark Young | b20a6a8 | 2016-01-07 15:41:43 -0700 | [diff] [blame] | 8330 | VkBool32 skip_call = VK_FALSE; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8331 | |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 8332 | #ifndef DISABLE_IMAGE_LAYOUT_VALIDATION |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8333 | if (pPresentInfo) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8334 | for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) { |
| 8335 | if (dev_data |
| 8336 | ->semaphoreSignaledMap[pPresentInfo->pWaitSemaphores[i]]) { |
| 8337 | dev_data |
| 8338 | ->semaphoreSignaledMap[pPresentInfo->pWaitSemaphores[i]] = |
| 8339 | 0; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8340 | } else { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8341 | skipCall |= log_msg( |
| 8342 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8343 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, |
| 8344 | DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", |
| 8345 | "Queue %#" PRIx64 " is waiting on semaphore %#" PRIx64 |
| 8346 | " that has no way to be signaled.", |
| 8347 | (uint64_t)(queue), |
| 8348 | (uint64_t)(pPresentInfo->pWaitSemaphores[i])); |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8349 | } |
| 8350 | } |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8351 | for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8352 | auto swapchain_data = dev_data->device_extensions.swapchainMap.find( |
| 8353 | pPresentInfo->pSwapchains[i]); |
| 8354 | if (swapchain_data != |
| 8355 | dev_data->device_extensions.swapchainMap.end() && |
| 8356 | pPresentInfo->pImageIndices[i] < |
| 8357 | swapchain_data->second->images.size()) { |
| 8358 | VkImage image = swapchain_data->second |
| 8359 | ->images[pPresentInfo->pImageIndices[i]]; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8360 | auto image_data = dev_data->imageLayoutMap.find(image); |
| 8361 | if (image_data != dev_data->imageLayoutMap.end()) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8362 | if (image_data->second->layout != |
| 8363 | VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { |
| 8364 | skip_call |= |
| 8365 | log_msg(dev_data->report_data, |
| 8366 | VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8367 | VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, |
| 8368 | (uint64_t)queue, __LINE__, |
| 8369 | DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS", |
| 8370 | "Images passed to present must be in " |
| 8371 | "layout PRESENT_SOURCE_KHR but is in %d", |
| 8372 | image_data->second->layout); |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8373 | } |
| 8374 | } |
| 8375 | } |
| 8376 | } |
| 8377 | } |
Mark Lobodzinski | 31e5f28 | 2015-11-30 16:48:53 -0700 | [diff] [blame] | 8378 | #endif // DISABLE_IMAGE_LAYOUT_VALIDATION |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8379 | |
| 8380 | if (VK_FALSE == skip_call) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8381 | return dev_data->device_dispatch_table->QueuePresentKHR(queue, |
| 8382 | pPresentInfo); |
Courtney Goeltzenleuchter | 52fee65 | 2015-12-10 16:41:22 -0700 | [diff] [blame] | 8383 | return VK_ERROR_VALIDATION_FAILED_EXT; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8384 | } |
| 8385 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8386 | VKAPI_ATTR VkResult VKAPI_CALL |
| 8387 | vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, |
| 8388 | uint64_t timeout, VkSemaphore semaphore, |
| 8389 | VkFence fence, uint32_t *pImageIndex) { |
| 8390 | layer_data *dev_data = |
| 8391 | get_my_data_ptr(get_dispatch_key(device), layer_data_map); |
| 8392 | VkResult result = dev_data->device_dispatch_table->AcquireNextImageKHR( |
| 8393 | device, swapchain, timeout, semaphore, fence, pImageIndex); |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8394 | dev_data->semaphoreSignaledMap[semaphore] = 1; |
Tobin Ehlis | 51b78af | 2016-01-06 10:27:47 -0700 | [diff] [blame] | 8395 | return result; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8396 | } |
| 8397 | |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 8398 | VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8399 | VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, |
| 8400 | const VkAllocationCallbacks *pAllocator, |
| 8401 | VkDebugReportCallbackEXT *pMsgCallback) { |
| 8402 | layer_data *my_data = |
| 8403 | get_my_data_ptr(get_dispatch_key(instance), layer_data_map); |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 8404 | VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8405 | VkResult res = pTable->CreateDebugReportCallbackEXT( |
| 8406 | instance, pCreateInfo, pAllocator, pMsgCallback); |
Tobin Ehlis | c16c3e9 | 2015-06-16 09:04:30 -0600 | [diff] [blame] | 8407 | if (VK_SUCCESS == res) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8408 | res = layer_create_msg_callback(my_data->report_data, pCreateInfo, |
| 8409 | pAllocator, pMsgCallback); |
Tobin Ehlis | c16c3e9 | 2015-06-16 09:04:30 -0600 | [diff] [blame] | 8410 | } |
| 8411 | return res; |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8412 | } |
| 8413 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8414 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 8415 | vkDestroyDebugReportCallbackEXT(VkInstance instance, |
| 8416 | VkDebugReportCallbackEXT msgCallback, |
| 8417 | const VkAllocationCallbacks *pAllocator) { |
| 8418 | layer_data *my_data = |
| 8419 | get_my_data_ptr(get_dispatch_key(instance), layer_data_map); |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 8420 | VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; |
Courtney Goeltzenleuchter | 7415d5a | 2015-12-09 15:48:16 -0700 | [diff] [blame] | 8421 | pTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); |
Courtney Goeltzenleuchter | 05854bf | 2015-11-30 12:13:14 -0700 | [diff] [blame] | 8422 | layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8423 | } |
| 8424 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8425 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 8426 | vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, |
| 8427 | VkDebugReportObjectTypeEXT objType, uint64_t object, |
| 8428 | size_t location, int32_t msgCode, |
| 8429 | const char *pLayerPrefix, const char *pMsg) { |
| 8430 | layer_data *my_data = |
| 8431 | get_my_data_ptr(get_dispatch_key(instance), layer_data_map); |
| 8432 | my_data->instance_dispatch_table->DebugReportMessageEXT( |
| 8433 | instance, flags, objType, object, location, msgCode, pLayerPrefix, |
| 8434 | pMsg); |
Courtney Goeltzenleuchter | f0de724 | 2015-12-01 14:10:55 -0700 | [diff] [blame] | 8435 | } |
| 8436 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8437 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 8438 | vkCmdDbgMarkerBegin(VkCommandBuffer commandBuffer, const char *pMarker) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 8439 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8440 | layer_data *dev_data = |
| 8441 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 8442 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 8443 | if (!dev_data->device_extensions.debug_marker_enabled) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8444 | skipCall |= log_msg( |
| 8445 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8446 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8447 | (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_EXTENSION, |
| 8448 | "DS", "Attempt to use CmdDbgMarkerBegin but extension disabled!"); |
Jon Ashburn | eab3449 | 2015-06-01 09:37:38 -0600 | [diff] [blame] | 8449 | return; |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 8450 | } else if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8451 | skipCall |= |
| 8452 | addCmd(dev_data, pCB, CMD_DBGMARKERBEGIN, "vkCmdDbgMarkerBegin()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8453 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 8454 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8455 | debug_marker_dispatch_table(commandBuffer) |
| 8456 | ->CmdDbgMarkerBegin(commandBuffer, pMarker); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8457 | } |
| 8458 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8459 | VK_LAYER_EXPORT VKAPI_ATTR void VKAPI_CALL |
| 8460 | vkCmdDbgMarkerEnd(VkCommandBuffer commandBuffer) { |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 8461 | VkBool32 skipCall = VK_FALSE; |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8462 | layer_data *dev_data = |
| 8463 | get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map); |
| 8464 | GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer); |
Tobin Ehlis | 0b63233 | 2015-10-07 09:38:40 -0600 | [diff] [blame] | 8465 | if (!dev_data->device_extensions.debug_marker_enabled) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8466 | skipCall |= log_msg( |
| 8467 | dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, |
| 8468 | VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, |
| 8469 | (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_EXTENSION, |
| 8470 | "DS", "Attempt to use CmdDbgMarkerEnd but extension disabled!"); |
Jon Ashburn | eab3449 | 2015-06-01 09:37:38 -0600 | [diff] [blame] | 8471 | return; |
Tobin Ehlis | ce132d8 | 2015-06-19 15:07:05 -0600 | [diff] [blame] | 8472 | } else if (pCB) { |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8473 | skipCall |= |
| 8474 | addCmd(dev_data, pCB, CMD_DBGMARKEREND, "vkCmdDbgMarkerEnd()"); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8475 | } |
Tobin Ehlis | 1cfb30a | 2015-09-09 11:31:10 -0600 | [diff] [blame] | 8476 | if (VK_FALSE == skipCall) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8477 | debug_marker_dispatch_table(commandBuffer) |
| 8478 | ->CmdDbgMarkerEnd(commandBuffer); |
Jon Ashburn | eab3449 | 2015-06-01 09:37:38 -0600 | [diff] [blame] | 8479 | } |
| 8480 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8481 | VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL |
| 8482 | vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8483 | if (!strcmp(funcName, "vkGetDeviceProcAddr")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8484 | return (PFN_vkVoidFunction)vkGetDeviceProcAddr; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8485 | if (!strcmp(funcName, "vkDestroyDevice")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8486 | return (PFN_vkVoidFunction)vkDestroyDevice; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8487 | if (!strcmp(funcName, "vkQueueSubmit")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8488 | return (PFN_vkVoidFunction)vkQueueSubmit; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 8489 | if (!strcmp(funcName, "vkWaitForFences")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8490 | return (PFN_vkVoidFunction)vkWaitForFences; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 8491 | if (!strcmp(funcName, "vkGetFenceStatus")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8492 | return (PFN_vkVoidFunction)vkGetFenceStatus; |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 8493 | if (!strcmp(funcName, "vkQueueWaitIdle")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8494 | return (PFN_vkVoidFunction)vkQueueWaitIdle; |
Mark Lobodzinski | 8da0d1e | 2016-01-06 14:58:59 -0700 | [diff] [blame] | 8495 | if (!strcmp(funcName, "vkDeviceWaitIdle")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8496 | return (PFN_vkVoidFunction)vkDeviceWaitIdle; |
Michael Lentine | 700b0aa | 2015-10-30 17:57:32 -0700 | [diff] [blame] | 8497 | if (!strcmp(funcName, "vkGetDeviceQueue")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8498 | return (PFN_vkVoidFunction)vkGetDeviceQueue; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8499 | if (!strcmp(funcName, "vkDestroyInstance")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8500 | return (PFN_vkVoidFunction)vkDestroyInstance; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8501 | if (!strcmp(funcName, "vkDestroyDevice")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8502 | return (PFN_vkVoidFunction)vkDestroyDevice; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8503 | if (!strcmp(funcName, "vkDestroyFence")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8504 | return (PFN_vkVoidFunction)vkDestroyFence; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8505 | if (!strcmp(funcName, "vkDestroySemaphore")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8506 | return (PFN_vkVoidFunction)vkDestroySemaphore; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8507 | if (!strcmp(funcName, "vkDestroyEvent")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8508 | return (PFN_vkVoidFunction)vkDestroyEvent; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8509 | if (!strcmp(funcName, "vkDestroyQueryPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8510 | return (PFN_vkVoidFunction)vkDestroyQueryPool; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8511 | if (!strcmp(funcName, "vkDestroyBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8512 | return (PFN_vkVoidFunction)vkDestroyBuffer; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8513 | if (!strcmp(funcName, "vkDestroyBufferView")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8514 | return (PFN_vkVoidFunction)vkDestroyBufferView; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8515 | if (!strcmp(funcName, "vkDestroyImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8516 | return (PFN_vkVoidFunction)vkDestroyImage; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8517 | if (!strcmp(funcName, "vkDestroyImageView")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8518 | return (PFN_vkVoidFunction)vkDestroyImageView; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8519 | if (!strcmp(funcName, "vkDestroyShaderModule")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8520 | return (PFN_vkVoidFunction)vkDestroyShaderModule; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8521 | if (!strcmp(funcName, "vkDestroyPipeline")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8522 | return (PFN_vkVoidFunction)vkDestroyPipeline; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8523 | if (!strcmp(funcName, "vkDestroyPipelineLayout")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8524 | return (PFN_vkVoidFunction)vkDestroyPipelineLayout; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8525 | if (!strcmp(funcName, "vkDestroySampler")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8526 | return (PFN_vkVoidFunction)vkDestroySampler; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8527 | if (!strcmp(funcName, "vkDestroyDescriptorSetLayout")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8528 | return (PFN_vkVoidFunction)vkDestroyDescriptorSetLayout; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8529 | if (!strcmp(funcName, "vkDestroyDescriptorPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8530 | return (PFN_vkVoidFunction)vkDestroyDescriptorPool; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8531 | if (!strcmp(funcName, "vkDestroyFramebuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8532 | return (PFN_vkVoidFunction)vkDestroyFramebuffer; |
Tobin Ehlis | 60a9b4f | 2015-07-07 10:42:20 -0600 | [diff] [blame] | 8533 | if (!strcmp(funcName, "vkDestroyRenderPass")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8534 | return (PFN_vkVoidFunction)vkDestroyRenderPass; |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 8535 | if (!strcmp(funcName, "vkCreateBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8536 | return (PFN_vkVoidFunction)vkCreateBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8537 | if (!strcmp(funcName, "vkCreateBufferView")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8538 | return (PFN_vkVoidFunction)vkCreateBufferView; |
Tobin Ehlis | a1c2856 | 2015-10-23 16:00:08 -0600 | [diff] [blame] | 8539 | if (!strcmp(funcName, "vkCreateImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8540 | return (PFN_vkVoidFunction)vkCreateImage; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8541 | if (!strcmp(funcName, "vkCreateImageView")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8542 | return (PFN_vkVoidFunction)vkCreateImageView; |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 8543 | if (!strcmp(funcName, "CreatePipelineCache")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8544 | return (PFN_vkVoidFunction)vkCreatePipelineCache; |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 8545 | if (!strcmp(funcName, "DestroyPipelineCache")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8546 | return (PFN_vkVoidFunction)vkDestroyPipelineCache; |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 8547 | if (!strcmp(funcName, "GetPipelineCacheData")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8548 | return (PFN_vkVoidFunction)vkGetPipelineCacheData; |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 8549 | if (!strcmp(funcName, "MergePipelineCaches")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8550 | return (PFN_vkVoidFunction)vkMergePipelineCaches; |
Jon Ashburn | c669cc6 | 2015-07-09 15:02:25 -0600 | [diff] [blame] | 8551 | if (!strcmp(funcName, "vkCreateGraphicsPipelines")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8552 | return (PFN_vkVoidFunction)vkCreateGraphicsPipelines; |
Mark Lobodzinski | 475a218 | 2015-11-10 15:25:01 -0700 | [diff] [blame] | 8553 | if (!strcmp(funcName, "vkCreateComputePipelines")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8554 | return (PFN_vkVoidFunction)vkCreateComputePipelines; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8555 | if (!strcmp(funcName, "vkCreateSampler")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8556 | return (PFN_vkVoidFunction)vkCreateSampler; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8557 | if (!strcmp(funcName, "vkCreateDescriptorSetLayout")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8558 | return (PFN_vkVoidFunction)vkCreateDescriptorSetLayout; |
Mark Lobodzinski | 0fadf5f | 2015-04-17 14:11:39 -0500 | [diff] [blame] | 8559 | if (!strcmp(funcName, "vkCreatePipelineLayout")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8560 | return (PFN_vkVoidFunction)vkCreatePipelineLayout; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8561 | if (!strcmp(funcName, "vkCreateDescriptorPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8562 | return (PFN_vkVoidFunction)vkCreateDescriptorPool; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8563 | if (!strcmp(funcName, "vkResetDescriptorPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8564 | return (PFN_vkVoidFunction)vkResetDescriptorPool; |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 8565 | if (!strcmp(funcName, "vkAllocateDescriptorSets")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8566 | return (PFN_vkVoidFunction)vkAllocateDescriptorSets; |
Tobin Ehlis | e735c69 | 2015-10-08 13:13:50 -0600 | [diff] [blame] | 8567 | if (!strcmp(funcName, "vkFreeDescriptorSets")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8568 | return (PFN_vkVoidFunction)vkFreeDescriptorSets; |
Chia-I Wu | 9d00ed7 | 2015-05-25 16:27:55 +0800 | [diff] [blame] | 8569 | if (!strcmp(funcName, "vkUpdateDescriptorSets")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8570 | return (PFN_vkVoidFunction)vkUpdateDescriptorSets; |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 8571 | if (!strcmp(funcName, "vkCreateCommandPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8572 | return (PFN_vkVoidFunction)vkCreateCommandPool; |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 8573 | if (!strcmp(funcName, "vkDestroyCommandPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8574 | return (PFN_vkVoidFunction)vkDestroyCommandPool; |
Tobin Ehlis | ac0ef84 | 2015-12-14 13:46:38 -0700 | [diff] [blame] | 8575 | if (!strcmp(funcName, "vkResetCommandPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8576 | return (PFN_vkVoidFunction)vkResetCommandPool; |
Chia-I Wu | 3432a0c | 2015-10-27 18:04:07 +0800 | [diff] [blame] | 8577 | if (!strcmp(funcName, "vkAllocateCommandBuffers")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8578 | return (PFN_vkVoidFunction)vkAllocateCommandBuffers; |
Mark Lobodzinski | 3929863 | 2015-11-18 08:38:27 -0700 | [diff] [blame] | 8579 | if (!strcmp(funcName, "vkFreeCommandBuffers")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8580 | return (PFN_vkVoidFunction)vkFreeCommandBuffers; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8581 | if (!strcmp(funcName, "vkBeginCommandBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8582 | return (PFN_vkVoidFunction)vkBeginCommandBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8583 | if (!strcmp(funcName, "vkEndCommandBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8584 | return (PFN_vkVoidFunction)vkEndCommandBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8585 | if (!strcmp(funcName, "vkResetCommandBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8586 | return (PFN_vkVoidFunction)vkResetCommandBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8587 | if (!strcmp(funcName, "vkCmdBindPipeline")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8588 | return (PFN_vkVoidFunction)vkCmdBindPipeline; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8589 | if (!strcmp(funcName, "vkCmdSetViewport")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8590 | return (PFN_vkVoidFunction)vkCmdSetViewport; |
Courtney Goeltzenleuchter | 078f817 | 2015-09-21 11:44:06 -0600 | [diff] [blame] | 8591 | if (!strcmp(funcName, "vkCmdSetScissor")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8592 | return (PFN_vkVoidFunction)vkCmdSetScissor; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8593 | if (!strcmp(funcName, "vkCmdSetLineWidth")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8594 | return (PFN_vkVoidFunction)vkCmdSetLineWidth; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8595 | if (!strcmp(funcName, "vkCmdSetDepthBias")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8596 | return (PFN_vkVoidFunction)vkCmdSetDepthBias; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8597 | if (!strcmp(funcName, "vkCmdSetBlendConstants")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8598 | return (PFN_vkVoidFunction)vkCmdSetBlendConstants; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8599 | if (!strcmp(funcName, "vkCmdSetDepthBounds")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8600 | return (PFN_vkVoidFunction)vkCmdSetDepthBounds; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8601 | if (!strcmp(funcName, "vkCmdSetStencilCompareMask")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8602 | return (PFN_vkVoidFunction)vkCmdSetStencilCompareMask; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8603 | if (!strcmp(funcName, "vkCmdSetStencilWriteMask")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8604 | return (PFN_vkVoidFunction)vkCmdSetStencilWriteMask; |
Courtney Goeltzenleuchter | 49c7308 | 2015-09-17 15:06:17 -0600 | [diff] [blame] | 8605 | if (!strcmp(funcName, "vkCmdSetStencilReference")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8606 | return (PFN_vkVoidFunction)vkCmdSetStencilReference; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8607 | if (!strcmp(funcName, "vkCmdBindDescriptorSets")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8608 | return (PFN_vkVoidFunction)vkCmdBindDescriptorSets; |
Courtney Goeltzenleuchter | f68ad72 | 2015-04-16 13:38:46 -0600 | [diff] [blame] | 8609 | if (!strcmp(funcName, "vkCmdBindVertexBuffers")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8610 | return (PFN_vkVoidFunction)vkCmdBindVertexBuffers; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8611 | if (!strcmp(funcName, "vkCmdBindIndexBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8612 | return (PFN_vkVoidFunction)vkCmdBindIndexBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8613 | if (!strcmp(funcName, "vkCmdDraw")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8614 | return (PFN_vkVoidFunction)vkCmdDraw; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8615 | if (!strcmp(funcName, "vkCmdDrawIndexed")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8616 | return (PFN_vkVoidFunction)vkCmdDrawIndexed; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8617 | if (!strcmp(funcName, "vkCmdDrawIndirect")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8618 | return (PFN_vkVoidFunction)vkCmdDrawIndirect; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8619 | if (!strcmp(funcName, "vkCmdDrawIndexedIndirect")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8620 | return (PFN_vkVoidFunction)vkCmdDrawIndexedIndirect; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8621 | if (!strcmp(funcName, "vkCmdDispatch")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8622 | return (PFN_vkVoidFunction)vkCmdDispatch; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8623 | if (!strcmp(funcName, "vkCmdDispatchIndirect")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8624 | return (PFN_vkVoidFunction)vkCmdDispatchIndirect; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8625 | if (!strcmp(funcName, "vkCmdCopyBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8626 | return (PFN_vkVoidFunction)vkCmdCopyBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8627 | if (!strcmp(funcName, "vkCmdCopyImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8628 | return (PFN_vkVoidFunction)vkCmdCopyImage; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8629 | if (!strcmp(funcName, "vkCmdCopyBufferToImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8630 | return (PFN_vkVoidFunction)vkCmdCopyBufferToImage; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8631 | if (!strcmp(funcName, "vkCmdCopyImageToBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8632 | return (PFN_vkVoidFunction)vkCmdCopyImageToBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8633 | if (!strcmp(funcName, "vkCmdUpdateBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8634 | return (PFN_vkVoidFunction)vkCmdUpdateBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8635 | if (!strcmp(funcName, "vkCmdFillBuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8636 | return (PFN_vkVoidFunction)vkCmdFillBuffer; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8637 | if (!strcmp(funcName, "vkCmdClearColorImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8638 | return (PFN_vkVoidFunction)vkCmdClearColorImage; |
Chris Forbes | d9be82b | 2015-06-22 17:21:59 +1200 | [diff] [blame] | 8639 | if (!strcmp(funcName, "vkCmdClearDepthStencilImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8640 | return (PFN_vkVoidFunction)vkCmdClearDepthStencilImage; |
Courtney Goeltzenleuchter | c9323e0 | 2015-10-15 16:51:05 -0600 | [diff] [blame] | 8641 | if (!strcmp(funcName, "vkCmdClearAttachments")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8642 | return (PFN_vkVoidFunction)vkCmdClearAttachments; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8643 | if (!strcmp(funcName, "vkCmdResolveImage")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8644 | return (PFN_vkVoidFunction)vkCmdResolveImage; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8645 | if (!strcmp(funcName, "vkCmdSetEvent")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8646 | return (PFN_vkVoidFunction)vkCmdSetEvent; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8647 | if (!strcmp(funcName, "vkCmdResetEvent")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8648 | return (PFN_vkVoidFunction)vkCmdResetEvent; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8649 | if (!strcmp(funcName, "vkCmdWaitEvents")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8650 | return (PFN_vkVoidFunction)vkCmdWaitEvents; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8651 | if (!strcmp(funcName, "vkCmdPipelineBarrier")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8652 | return (PFN_vkVoidFunction)vkCmdPipelineBarrier; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8653 | if (!strcmp(funcName, "vkCmdBeginQuery")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8654 | return (PFN_vkVoidFunction)vkCmdBeginQuery; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8655 | if (!strcmp(funcName, "vkCmdEndQuery")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8656 | return (PFN_vkVoidFunction)vkCmdEndQuery; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8657 | if (!strcmp(funcName, "vkCmdResetQueryPool")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8658 | return (PFN_vkVoidFunction)vkCmdResetQueryPool; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8659 | if (!strcmp(funcName, "vkCmdWriteTimestamp")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8660 | return (PFN_vkVoidFunction)vkCmdWriteTimestamp; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8661 | if (!strcmp(funcName, "vkCreateFramebuffer")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8662 | return (PFN_vkVoidFunction)vkCreateFramebuffer; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 8663 | if (!strcmp(funcName, "vkCreateShaderModule")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8664 | return (PFN_vkVoidFunction)vkCreateShaderModule; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8665 | if (!strcmp(funcName, "vkCreateRenderPass")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8666 | return (PFN_vkVoidFunction)vkCreateRenderPass; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8667 | if (!strcmp(funcName, "vkCmdBeginRenderPass")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8668 | return (PFN_vkVoidFunction)vkCmdBeginRenderPass; |
Chia-I Wu | 08accc6 | 2015-07-07 11:50:03 +0800 | [diff] [blame] | 8669 | if (!strcmp(funcName, "vkCmdNextSubpass")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8670 | return (PFN_vkVoidFunction)vkCmdNextSubpass; |
Courtney Goeltzenleuchter | d8e229c | 2015-04-08 15:36:08 -0600 | [diff] [blame] | 8671 | if (!strcmp(funcName, "vkCmdEndRenderPass")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8672 | return (PFN_vkVoidFunction)vkCmdEndRenderPass; |
Tobin Ehlis | 4b34ddc | 2015-09-17 14:18:16 -0600 | [diff] [blame] | 8673 | if (!strcmp(funcName, "vkCmdExecuteCommands")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8674 | return (PFN_vkVoidFunction)vkCmdExecuteCommands; |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 8675 | if (!strcmp(funcName, "vkSetEvent")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8676 | return (PFN_vkVoidFunction)vkSetEvent; |
Michael Lentine | 7b23626 | 2015-10-23 12:41:44 -0700 | [diff] [blame] | 8677 | if (!strcmp(funcName, "vkMapMemory")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8678 | return (PFN_vkVoidFunction)vkMapMemory; |
Michael Lentine | b887b0a | 2015-12-29 14:12:11 -0600 | [diff] [blame] | 8679 | if (!strcmp(funcName, "vkGetQueryPoolResults")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8680 | return (PFN_vkVoidFunction)vkGetQueryPoolResults; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8681 | if (!strcmp(funcName, "vkBindImageMemory")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8682 | return (PFN_vkVoidFunction)vkBindImageMemory; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8683 | if (!strcmp(funcName, "vkQueueBindSparse")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8684 | return (PFN_vkVoidFunction)vkQueueBindSparse; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8685 | if (!strcmp(funcName, "vkCreateSemaphore")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8686 | return (PFN_vkVoidFunction)vkCreateSemaphore; |
Jon Ashburn | eab3449 | 2015-06-01 09:37:38 -0600 | [diff] [blame] | 8687 | |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8688 | if (dev == NULL) |
| 8689 | return NULL; |
| 8690 | |
| 8691 | layer_data *dev_data; |
| 8692 | dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map); |
| 8693 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8694 | if (dev_data->device_extensions.wsi_enabled) { |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8695 | if (!strcmp(funcName, "vkCreateSwapchainKHR")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8696 | return (PFN_vkVoidFunction)vkCreateSwapchainKHR; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8697 | if (!strcmp(funcName, "vkDestroySwapchainKHR")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8698 | return (PFN_vkVoidFunction)vkDestroySwapchainKHR; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8699 | if (!strcmp(funcName, "vkGetSwapchainImagesKHR")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8700 | return (PFN_vkVoidFunction)vkGetSwapchainImagesKHR; |
Michael Lentine | 15a4788 | 2016-01-06 10:05:48 -0600 | [diff] [blame] | 8701 | if (!strcmp(funcName, "vkAcquireNextImageKHR")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8702 | return (PFN_vkVoidFunction)vkAcquireNextImageKHR; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8703 | if (!strcmp(funcName, "vkQueuePresentKHR")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8704 | return (PFN_vkVoidFunction)vkQueuePresentKHR; |
Michael Lentine | abc5e92 | 2015-10-12 11:30:14 -0500 | [diff] [blame] | 8705 | } |
| 8706 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8707 | VkLayerDispatchTable *pTable = dev_data->device_dispatch_table; |
| 8708 | if (dev_data->device_extensions.debug_marker_enabled) { |
Jon Ashburn | 747f2b6 | 2015-06-18 15:02:58 -0600 | [diff] [blame] | 8709 | if (!strcmp(funcName, "vkCmdDbgMarkerBegin")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8710 | return (PFN_vkVoidFunction)vkCmdDbgMarkerBegin; |
Jon Ashburn | 747f2b6 | 2015-06-18 15:02:58 -0600 | [diff] [blame] | 8711 | if (!strcmp(funcName, "vkCmdDbgMarkerEnd")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8712 | return (PFN_vkVoidFunction)vkCmdDbgMarkerEnd; |
Jon Ashburn | eab3449 | 2015-06-01 09:37:38 -0600 | [diff] [blame] | 8713 | } |
| 8714 | { |
Jon Ashburn | 8fd0825 | 2015-05-28 16:25:02 -0600 | [diff] [blame] | 8715 | if (pTable->GetDeviceProcAddr == NULL) |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8716 | return NULL; |
Jon Ashburn | 8fd0825 | 2015-05-28 16:25:02 -0600 | [diff] [blame] | 8717 | return pTable->GetDeviceProcAddr(dev, funcName); |
Jon Ashburn | f6b33db | 2015-05-05 14:22:52 -0600 | [diff] [blame] | 8718 | } |
| 8719 | } |
| 8720 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8721 | VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL |
| 8722 | vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8723 | if (!strcmp(funcName, "vkGetInstanceProcAddr")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8724 | return (PFN_vkVoidFunction)vkGetInstanceProcAddr; |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8725 | if (!strcmp(funcName, "vkGetDeviceProcAddr")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8726 | return (PFN_vkVoidFunction)vkGetDeviceProcAddr; |
Courtney Goeltzenleuchter | abc035e | 2015-06-01 14:29:58 -0600 | [diff] [blame] | 8727 | if (!strcmp(funcName, "vkCreateInstance")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8728 | return (PFN_vkVoidFunction)vkCreateInstance; |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8729 | if (!strcmp(funcName, "vkCreateDevice")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8730 | return (PFN_vkVoidFunction)vkCreateDevice; |
Jon Ashburn | 3950e1b | 2015-05-20 09:00:28 -0600 | [diff] [blame] | 8731 | if (!strcmp(funcName, "vkDestroyInstance")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8732 | return (PFN_vkVoidFunction)vkDestroyInstance; |
Courtney Goeltzenleuchter | 35985f6 | 2015-09-14 17:22:16 -0600 | [diff] [blame] | 8733 | if (!strcmp(funcName, "vkEnumerateInstanceLayerProperties")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8734 | return (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties; |
Courtney Goeltzenleuchter | 35985f6 | 2015-09-14 17:22:16 -0600 | [diff] [blame] | 8735 | if (!strcmp(funcName, "vkEnumerateInstanceExtensionProperties")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8736 | return (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties; |
Courtney Goeltzenleuchter | 35985f6 | 2015-09-14 17:22:16 -0600 | [diff] [blame] | 8737 | if (!strcmp(funcName, "vkEnumerateDeviceLayerProperties")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8738 | return (PFN_vkVoidFunction)vkEnumerateDeviceLayerProperties; |
Courtney Goeltzenleuchter | 35985f6 | 2015-09-14 17:22:16 -0600 | [diff] [blame] | 8739 | if (!strcmp(funcName, "vkEnumerateDeviceExtensionProperties")) |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8740 | return (PFN_vkVoidFunction)vkEnumerateDeviceExtensionProperties; |
Courtney Goeltzenleuchter | ee56287 | 2015-06-01 14:33:14 -0600 | [diff] [blame] | 8741 | |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8742 | if (instance == NULL) |
| 8743 | return NULL; |
| 8744 | |
| 8745 | PFN_vkVoidFunction fptr; |
| 8746 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8747 | layer_data *my_data; |
Tobin Ehlis | 7e2ad75 | 2015-12-01 09:48:58 -0700 | [diff] [blame] | 8748 | my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map); |
Tobin Ehlis | a16e892 | 2015-06-16 15:50:44 -0600 | [diff] [blame] | 8749 | fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName); |
Courtney Goeltzenleuchter | ee56287 | 2015-06-01 14:33:14 -0600 | [diff] [blame] | 8750 | if (fptr) |
| 8751 | return fptr; |
| 8752 | |
Mark Lobodzinski | b39d9e6 | 2016-02-02 17:06:29 -0700 | [diff] [blame^] | 8753 | VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; |
Courtney Goeltzenleuchter | 00150eb | 2016-01-08 12:18:43 -0700 | [diff] [blame] | 8754 | if (pTable->GetInstanceProcAddr == NULL) |
| 8755 | return NULL; |
| 8756 | return pTable->GetInstanceProcAddr(instance, funcName); |
Tobin Ehlis | 10ae8c1 | 2015-03-17 16:24:32 -0600 | [diff] [blame] | 8757 | } |