Jeremy Gebben | 159b3cc | 2021-06-03 09:09:03 -0600 | [diff] [blame] | 1 | /* Copyright (c) 2015-2021 The Khronos Group Inc. |
| 2 | * Copyright (c) 2015-2021 Valve Corporation |
| 3 | * Copyright (c) 2015-2021 LunarG, Inc. |
| 4 | * Copyright (C) 2015-2021 Google Inc. |
| 5 | * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. |
| 6 | * |
| 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | * you may not use this file except in compliance with the License. |
| 9 | * You may obtain a copy of the License at |
| 10 | * |
| 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | * |
| 13 | * Unless required by applicable law or agreed to in writing, software |
| 14 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | * See the License for the specific language governing permissions and |
| 17 | * limitations under the License. |
| 18 | * |
| 19 | * Author: Courtney Goeltzenleuchter <courtneygo@google.com> |
| 20 | * Author: Tobin Ehlis <tobine@google.com> |
| 21 | * Author: Chris Forbes <chrisf@ijw.co.nz> |
| 22 | * Author: Mark Lobodzinski <mark@lunarg.com> |
| 23 | * Author: Dave Houlton <daveh@lunarg.com> |
| 24 | * Author: John Zulauf <jzulauf@lunarg.com> |
| 25 | * Author: Tobias Hector <tobias.hector@amd.com> |
| 26 | */ |
| 27 | #include "cmd_buffer_state.h" |
| 28 | #include "render_pass_state.h" |
| 29 | |
| 30 | const char *CommandTypeString(CMD_TYPE type) { |
| 31 | // Autogenerated as part of the command_validation.h codegen |
| 32 | return kGeneratedCommandNameList[type]; |
| 33 | } |
| 34 | |
| 35 | VkDynamicState ConvertToDynamicState(CBStatusFlagBits flag) { |
| 36 | switch (flag) { |
| 37 | case CBSTATUS_LINE_WIDTH_SET: |
| 38 | return VK_DYNAMIC_STATE_LINE_WIDTH; |
| 39 | case CBSTATUS_DEPTH_BIAS_SET: |
| 40 | return VK_DYNAMIC_STATE_DEPTH_BIAS; |
| 41 | case CBSTATUS_BLEND_CONSTANTS_SET: |
| 42 | return VK_DYNAMIC_STATE_BLEND_CONSTANTS; |
| 43 | case CBSTATUS_DEPTH_BOUNDS_SET: |
| 44 | return VK_DYNAMIC_STATE_DEPTH_BOUNDS; |
| 45 | case CBSTATUS_STENCIL_READ_MASK_SET: |
| 46 | return VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; |
| 47 | case CBSTATUS_STENCIL_WRITE_MASK_SET: |
| 48 | return VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; |
| 49 | case CBSTATUS_STENCIL_REFERENCE_SET: |
| 50 | return VK_DYNAMIC_STATE_STENCIL_REFERENCE; |
| 51 | case CBSTATUS_VIEWPORT_SET: |
| 52 | return VK_DYNAMIC_STATE_VIEWPORT; |
| 53 | case CBSTATUS_SCISSOR_SET: |
| 54 | return VK_DYNAMIC_STATE_SCISSOR; |
| 55 | case CBSTATUS_EXCLUSIVE_SCISSOR_SET: |
| 56 | return VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV; |
| 57 | case CBSTATUS_SHADING_RATE_PALETTE_SET: |
| 58 | return VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV; |
| 59 | case CBSTATUS_LINE_STIPPLE_SET: |
| 60 | return VK_DYNAMIC_STATE_LINE_STIPPLE_EXT; |
| 61 | case CBSTATUS_VIEWPORT_W_SCALING_SET: |
| 62 | return VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV; |
| 63 | case CBSTATUS_CULL_MODE_SET: |
| 64 | return VK_DYNAMIC_STATE_CULL_MODE_EXT; |
| 65 | case CBSTATUS_FRONT_FACE_SET: |
| 66 | return VK_DYNAMIC_STATE_FRONT_FACE_EXT; |
| 67 | case CBSTATUS_PRIMITIVE_TOPOLOGY_SET: |
| 68 | return VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT; |
| 69 | case CBSTATUS_VIEWPORT_WITH_COUNT_SET: |
| 70 | return VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT; |
| 71 | case CBSTATUS_SCISSOR_WITH_COUNT_SET: |
| 72 | return VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT; |
| 73 | case CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET: |
| 74 | return VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT; |
| 75 | case CBSTATUS_DEPTH_TEST_ENABLE_SET: |
| 76 | return VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT; |
| 77 | case CBSTATUS_DEPTH_WRITE_ENABLE_SET: |
| 78 | return VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT; |
| 79 | case CBSTATUS_DEPTH_COMPARE_OP_SET: |
| 80 | return VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT; |
| 81 | case CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET: |
| 82 | return VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT; |
| 83 | case CBSTATUS_STENCIL_TEST_ENABLE_SET: |
| 84 | return VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT; |
| 85 | case CBSTATUS_STENCIL_OP_SET: |
| 86 | return VK_DYNAMIC_STATE_STENCIL_OP_EXT; |
| 87 | case CBSTATUS_DISCARD_RECTANGLE_SET: |
| 88 | return VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT; |
| 89 | case CBSTATUS_SAMPLE_LOCATIONS_SET: |
| 90 | return VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT; |
| 91 | case CBSTATUS_COARSE_SAMPLE_ORDER_SET: |
| 92 | return VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV; |
| 93 | case CBSTATUS_PATCH_CONTROL_POINTS_SET: |
| 94 | return VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT; |
| 95 | case CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET: |
| 96 | return VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT; |
| 97 | case CBSTATUS_DEPTH_BIAS_ENABLE_SET: |
| 98 | return VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT; |
| 99 | case CBSTATUS_LOGIC_OP_SET: |
| 100 | return VK_DYNAMIC_STATE_LOGIC_OP_EXT; |
| 101 | case CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET: |
| 102 | return VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT; |
| 103 | case CBSTATUS_VERTEX_INPUT_SET: |
| 104 | return VK_DYNAMIC_STATE_VERTEX_INPUT_EXT; |
| 105 | default: |
| 106 | // CBSTATUS_INDEX_BUFFER_BOUND is not in VkDynamicState |
| 107 | return VK_DYNAMIC_STATE_MAX_ENUM; |
| 108 | } |
| 109 | return VK_DYNAMIC_STATE_MAX_ENUM; |
| 110 | } |
| 111 | |
| 112 | CBStatusFlagBits ConvertToCBStatusFlagBits(VkDynamicState state) { |
| 113 | switch (state) { |
| 114 | case VK_DYNAMIC_STATE_VIEWPORT: |
| 115 | return CBSTATUS_VIEWPORT_SET; |
| 116 | case VK_DYNAMIC_STATE_SCISSOR: |
| 117 | return CBSTATUS_SCISSOR_SET; |
| 118 | case VK_DYNAMIC_STATE_LINE_WIDTH: |
| 119 | return CBSTATUS_LINE_WIDTH_SET; |
| 120 | case VK_DYNAMIC_STATE_DEPTH_BIAS: |
| 121 | return CBSTATUS_DEPTH_BIAS_SET; |
| 122 | case VK_DYNAMIC_STATE_BLEND_CONSTANTS: |
| 123 | return CBSTATUS_BLEND_CONSTANTS_SET; |
| 124 | case VK_DYNAMIC_STATE_DEPTH_BOUNDS: |
| 125 | return CBSTATUS_DEPTH_BOUNDS_SET; |
| 126 | case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: |
| 127 | return CBSTATUS_STENCIL_READ_MASK_SET; |
| 128 | case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: |
| 129 | return CBSTATUS_STENCIL_WRITE_MASK_SET; |
| 130 | case VK_DYNAMIC_STATE_STENCIL_REFERENCE: |
| 131 | return CBSTATUS_STENCIL_REFERENCE_SET; |
| 132 | case VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV: |
| 133 | return CBSTATUS_VIEWPORT_W_SCALING_SET; |
| 134 | case VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT: |
| 135 | return CBSTATUS_DISCARD_RECTANGLE_SET; |
| 136 | case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT: |
| 137 | return CBSTATUS_SAMPLE_LOCATIONS_SET; |
| 138 | case VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV: |
| 139 | return CBSTATUS_SHADING_RATE_PALETTE_SET; |
| 140 | case VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV: |
| 141 | return CBSTATUS_COARSE_SAMPLE_ORDER_SET; |
| 142 | case VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV: |
| 143 | return CBSTATUS_EXCLUSIVE_SCISSOR_SET; |
| 144 | case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT: |
| 145 | return CBSTATUS_LINE_STIPPLE_SET; |
| 146 | case VK_DYNAMIC_STATE_CULL_MODE_EXT: |
| 147 | return CBSTATUS_CULL_MODE_SET; |
| 148 | case VK_DYNAMIC_STATE_FRONT_FACE_EXT: |
| 149 | return CBSTATUS_FRONT_FACE_SET; |
| 150 | case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT: |
| 151 | return CBSTATUS_PRIMITIVE_TOPOLOGY_SET; |
| 152 | case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT: |
| 153 | return CBSTATUS_VIEWPORT_WITH_COUNT_SET; |
| 154 | case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT: |
| 155 | return CBSTATUS_SCISSOR_WITH_COUNT_SET; |
| 156 | case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT: |
| 157 | return CBSTATUS_VERTEX_INPUT_BINDING_STRIDE_SET; |
| 158 | case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT: |
| 159 | return CBSTATUS_DEPTH_TEST_ENABLE_SET; |
| 160 | case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT: |
| 161 | return CBSTATUS_DEPTH_WRITE_ENABLE_SET; |
| 162 | case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT: |
| 163 | return CBSTATUS_DEPTH_COMPARE_OP_SET; |
| 164 | case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT: |
| 165 | return CBSTATUS_DEPTH_BOUNDS_TEST_ENABLE_SET; |
| 166 | case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT: |
| 167 | return CBSTATUS_STENCIL_TEST_ENABLE_SET; |
| 168 | case VK_DYNAMIC_STATE_STENCIL_OP_EXT: |
| 169 | return CBSTATUS_STENCIL_OP_SET; |
| 170 | case VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT: |
| 171 | return CBSTATUS_PATCH_CONTROL_POINTS_SET; |
| 172 | case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT: |
| 173 | return CBSTATUS_RASTERIZER_DISCARD_ENABLE_SET; |
| 174 | case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT: |
| 175 | return CBSTATUS_DEPTH_BIAS_ENABLE_SET; |
| 176 | case VK_DYNAMIC_STATE_LOGIC_OP_EXT: |
| 177 | return CBSTATUS_LOGIC_OP_SET; |
| 178 | case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT: |
| 179 | return CBSTATUS_PRIMITIVE_RESTART_ENABLE_SET; |
| 180 | case VK_DYNAMIC_STATE_VERTEX_INPUT_EXT: |
| 181 | return CBSTATUS_VERTEX_INPUT_SET; |
| 182 | default: |
| 183 | return CBSTATUS_NONE; |
| 184 | } |
| 185 | return CBSTATUS_NONE; |
| 186 | } |
| 187 | |
| 188 | // Get the image viewstate for a given framebuffer attachment |
| 189 | IMAGE_VIEW_STATE *CMD_BUFFER_STATE::GetActiveAttachmentImageViewState(uint32_t index) { |
| 190 | assert(active_attachments && index != VK_ATTACHMENT_UNUSED && (index < active_attachments->size())); |
| 191 | return active_attachments->at(index); |
| 192 | } |
| 193 | |
| 194 | // Get the image viewstate for a given framebuffer attachment |
| 195 | const IMAGE_VIEW_STATE *CMD_BUFFER_STATE::GetActiveAttachmentImageViewState(uint32_t index) const { |
| 196 | assert(active_attachments && index != VK_ATTACHMENT_UNUSED && (index < active_attachments->size())); |
| 197 | return active_attachments->at(index); |
| 198 | } |
| 199 | |
| 200 | void CMD_BUFFER_STATE::AddChild(BASE_NODE *child_node) { |
| 201 | if (child_node->AddParent(this)) { |
| 202 | object_bindings.insert(child_node->Handle()); |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | void CMD_BUFFER_STATE::RemoveChild(BASE_NODE *child_node) { |
| 207 | child_node->RemoveParent(this); |
| 208 | object_bindings.erase(child_node->Handle()); |
| 209 | } |
| 210 | |
| 211 | void CMD_BUFFER_STATE::Reset() { |
| 212 | ResetUse(); |
| 213 | // Reset CB state (note that createInfo is not cleared) |
| 214 | memset(&beginInfo, 0, sizeof(VkCommandBufferBeginInfo)); |
| 215 | memset(&inheritanceInfo, 0, sizeof(VkCommandBufferInheritanceInfo)); |
| 216 | hasDrawCmd = false; |
| 217 | hasTraceRaysCmd = false; |
| 218 | hasBuildAccelerationStructureCmd = false; |
| 219 | hasDispatchCmd = false; |
| 220 | state = CB_NEW; |
| 221 | commandCount = 0; |
| 222 | submitCount = 0; |
| 223 | image_layout_change_count = 1; // Start at 1. 0 is insert value for validation cache versions, s.t. new == dirty |
| 224 | status = 0; |
| 225 | static_status = 0; |
| 226 | inheritedViewportDepths.clear(); |
| 227 | usedViewportScissorCount = 0; |
| 228 | pipelineStaticViewportCount = 0; |
| 229 | pipelineStaticScissorCount = 0; |
| 230 | viewportMask = 0; |
| 231 | viewportWithCountMask = 0; |
| 232 | viewportWithCountCount = 0; |
| 233 | scissorMask = 0; |
| 234 | scissorWithCountMask = 0; |
| 235 | scissorWithCountCount = 0; |
| 236 | trashedViewportMask = 0; |
| 237 | trashedScissorMask = 0; |
| 238 | trashedViewportCount = false; |
| 239 | trashedScissorCount = false; |
| 240 | usedDynamicViewportCount = false; |
| 241 | usedDynamicScissorCount = false; |
| 242 | primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; |
| 243 | |
| 244 | activeRenderPassBeginInfo = safe_VkRenderPassBeginInfo(); |
| 245 | activeRenderPass = nullptr; |
| 246 | active_attachments = nullptr; |
| 247 | active_subpasses = nullptr; |
| 248 | attachments_view_states.clear(); |
| 249 | activeSubpassContents = VK_SUBPASS_CONTENTS_INLINE; |
| 250 | activeSubpass = 0; |
| 251 | broken_bindings.clear(); |
| 252 | waitedEvents.clear(); |
| 253 | events.clear(); |
| 254 | writeEventsBeforeWait.clear(); |
| 255 | activeQueries.clear(); |
| 256 | startedQueries.clear(); |
| 257 | image_layout_map.clear(); |
| 258 | current_vertex_buffer_binding_info.vertex_buffer_bindings.clear(); |
| 259 | vertex_buffer_used = false; |
| 260 | primaryCommandBuffer = VK_NULL_HANDLE; |
| 261 | |
| 262 | linkedCommandBuffers.clear(); |
| 263 | // Remove reverse command buffer links. |
| 264 | Invalidate(true); |
| 265 | |
| 266 | queue_submit_functions.clear(); |
Hans-Kristian Arntzen | 59c2c3f | 2021-06-14 11:40:12 +0200 | [diff] [blame^] | 267 | queue_submit_functions_after_render_pass.clear(); |
Jeremy Gebben | 159b3cc | 2021-06-03 09:09:03 -0600 | [diff] [blame] | 268 | cmd_execute_commands_functions.clear(); |
| 269 | eventUpdates.clear(); |
| 270 | queryUpdates.clear(); |
| 271 | |
| 272 | // Remove object bindings |
| 273 | for (const auto &obj : object_bindings) { |
| 274 | if (obj.node) { |
| 275 | obj.node->RemoveParent(this); |
| 276 | } |
| 277 | } |
| 278 | object_bindings.clear(); |
| 279 | |
| 280 | for (auto &item : lastBound) { |
| 281 | item.Reset(); |
| 282 | } |
| 283 | // Remove this cmdBuffer's reference from each FrameBuffer's CB ref list |
| 284 | for (auto &framebuffer : framebuffers) { |
| 285 | framebuffer->RemoveParent(this); |
| 286 | } |
| 287 | framebuffers.clear(); |
| 288 | activeFramebuffer = VK_NULL_HANDLE; |
| 289 | index_buffer_binding.reset(); |
| 290 | |
| 291 | qfo_transfer_image_barriers.Reset(); |
| 292 | qfo_transfer_buffer_barriers.Reset(); |
| 293 | |
| 294 | // Clean up the label data |
| 295 | debug_label.Reset(); |
| 296 | validate_descriptorsets_in_queuesubmit.clear(); |
| 297 | |
| 298 | // Best practices info |
| 299 | small_indexed_draw_call_count = 0; |
| 300 | |
| 301 | transform_feedback_active = false; |
| 302 | |
| 303 | // Remove object bindings |
| 304 | for (const auto &obj : object_bindings) { |
| 305 | BASE_NODE *base_obj = obj.node; |
| 306 | if (base_obj) RemoveChild(base_obj); |
| 307 | } |
| 308 | object_bindings.clear(); |
| 309 | } |
| 310 | |
| 311 | void CMD_BUFFER_STATE::Destroy() { |
| 312 | Reset(); |
| 313 | BASE_NODE::Destroy(); |
| 314 | } |
| 315 | |
| 316 | void CMD_BUFFER_STATE::NotifyInvalidate(const LogObjectList &invalid_handles, bool unlink) { |
| 317 | if (state == CB_RECORDING) { |
| 318 | state = CB_INVALID_INCOMPLETE; |
| 319 | } else if (state == CB_RECORDED) { |
| 320 | state = CB_INVALID_COMPLETE; |
| 321 | } |
| 322 | assert(!invalid_handles.object_list.empty()); |
| 323 | broken_bindings.emplace(invalid_handles.object_list[0], invalid_handles); |
| 324 | |
| 325 | if (unlink) { |
| 326 | for (auto &obj : invalid_handles.object_list) { |
| 327 | object_bindings.erase(obj); |
| 328 | if (obj.type == kVulkanObjectTypeCommandBuffer) { |
| 329 | linkedCommandBuffers.erase(static_cast<CMD_BUFFER_STATE *>(obj.node)); |
| 330 | } |
| 331 | } |
| 332 | } |
| 333 | BASE_NODE::NotifyInvalidate(invalid_handles, unlink); |
| 334 | } |
| 335 | |
| 336 | // The const variant only need the image as it is the key for the map |
| 337 | const ImageSubresourceLayoutMap *CMD_BUFFER_STATE::GetImageSubresourceLayoutMap(VkImage image) const { |
| 338 | auto it = image_layout_map.find(image); |
| 339 | if (it == image_layout_map.cend()) { |
| 340 | return nullptr; |
| 341 | } |
| 342 | return &it->second; |
| 343 | } |
| 344 | |
| 345 | // The non-const variant only needs the image state, as the factory requires it to construct a new entry |
| 346 | ImageSubresourceLayoutMap *CMD_BUFFER_STATE::GetImageSubresourceLayoutMap(const IMAGE_STATE &image_state) { |
| 347 | auto &layout_map = image_layout_map[image_state.image()]; |
| 348 | if (!layout_map) { |
| 349 | // Was an empty slot... fill it in. |
| 350 | layout_map.emplace(image_state); |
| 351 | } |
| 352 | return &layout_map; |
| 353 | } |
| 354 | |