core_validation.cpp revision 79fc00370d55e7cbfd4052b579120e64b0a1a4be
14f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes/* Copyright (c) 2015-2017 The Khronos Group Inc. 24f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes * Copyright (c) 2015-2017 Valve Corporation 34f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes * Copyright (c) 2015-2017 LunarG, Inc. 44f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes * Copyright (C) 2015-2017 Google Inc. 55b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * 643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Licensed under the Apache License, Version 2.0 (the "License"); 743b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * you may not use this file except in compliance with the License. 843b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * You may obtain a copy of the License at 95b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * 1043b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * http://www.apache.org/licenses/LICENSE-2.0 115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * 1243b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Unless required by applicable law or agreed to in writing, software 1343b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * distributed under the License is distributed on an "AS IS" BASIS, 1443b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1543b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * See the License for the specific language governing permissions and 1643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * limitations under the License. 175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * 185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Cody Northrop <cnorthrop@google.com> 195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Michael Lentine <mlentine@google.com> 205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Tobin Ehlis <tobine@google.com> 215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Chia-I Wu <olv@google.com> 225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Chris Forbes <chrisf@ijw.co.nz> 235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Mark Lobodzinski <mark@lunarg.com> 245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis * Author: Ian Elliott <ianelliott@google.com> 2560cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Dave Houlton <daveh@lunarg.com> 2660cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Dustin Graves <dustin@lunarg.com> 2760cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Jeremy Hayes <jeremy@lunarg.com> 2860cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Jon Ashburn <jon@lunarg.com> 2960cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Karl Schultz <karl@lunarg.com> 3060cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Mark Young <marky@lunarg.com> 3160cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Mike Schuchardt <mikes@lunarg.com> 3260cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Mike Weiblen <mikew@lunarg.com> 3360cbbd8f316f5dfc7997bb66833a2e624f832e37Mark Lobodzinski * Author: Tony Barbour <tony@LunarG.com> 345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis */ 355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Allow use of STL min and max functions in Windows 375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#define NOMINMAX 385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3994c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <algorithm> 4094c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <assert.h> 4194c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <iostream> 4294c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <list> 4394c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <map> 44c8bee427d7a8ed0ccec899fbf47134d582dcafbdGabríel Arthúr Pétursson#include <memory> 45b9e992386a44404152747d66817a733aa127e281Jeremy Hayes#include <mutex> 4694c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <set> 4768d157d34807071526e5d78b3b3b68c5a4c6185fMark Lobodzinski#include <sstream> 485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include <stdio.h> 495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include <stdlib.h> 505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include <string.h> 5194c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis#include <string> 525770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus#include <inttypes.h> 535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "vk_loader_platform.h" 555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "vk_dispatch_table_helper.h" 5668d157d34807071526e5d78b3b3b68c5a4c6185fMark Lobodzinski#include "vk_enum_string_helper.h" 575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#if defined(__GNUC__) 585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#pragma GCC diagnostic ignored "-Wwrite-strings" 595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#endif 605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#if defined(__GNUC__) 615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#pragma GCC diagnostic warning "-Wwrite-strings" 625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#endif 635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "core_validation.h" 64c06c9b88f5f5bcc7033ba41d5547b048fa6015a4Mark Lobodzinski#include "buffer_validation.h" 65d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes#include "shader_validation.h" 665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "vk_layer_table.h" 675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "vk_layer_data.h" 685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "vk_layer_extension_utils.h" 695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include "vk_layer_utils.h" 705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#if defined __ANDROID__ 725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#include <android/log.h> 735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#define LOGCONSOLE(...) ((void)__android_log_print(ANDROID_LOG_INFO, "DS", __VA_ARGS__)) 745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#else 75cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#define LOGCONSOLE(...) \ 76cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski { \ 77cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski printf(__VA_ARGS__); \ 78cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski printf("\n"); \ 79c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#endif 815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 825770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus// TODO: remove on NDK update (r15 will probably have proper STL impl) 835770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus#ifdef __ANDROID__ 845770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausnamespace std { 855770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 865770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraustemplate <typename T> 875770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstd::string to_string(T var) { 885770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::ostringstream ss; 895770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ss << var; 905770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return ss.str(); 915770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus} 925770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus} 935770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus#endif 945770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 95d147a5463f8581604ca542aa1a44a27e512e0f60Mike Stroyan// This intentionally includes a cpp file 96d147a5463f8581604ca542aa1a44a27e512e0f60Mike Stroyan#include "vk_safe_struct.cpp" 97d147a5463f8581604ca542aa1a44a27e512e0f60Mike Stroyan 98ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesusing mutex_t = std::mutex; 99ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesusing lock_guard_t = std::lock_guard<mutex_t>; 100ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesusing unique_lock_t = std::unique_lock<mutex_t>; 101ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes 102d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wunamespace core_validation { 103d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 1045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisusing std::unordered_map; 1055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisusing std::unordered_set; 1060c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::unique_ptr; 1070c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::vector; 1080c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::string; 1090c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::stringstream; 1100c55adf45a81f44300db04ec71a797d790ef103cTobin Ehlisusing std::max; 1115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// WSI Image Objects bypass usual Image Object creation methods. A special Memory 1135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Object value will be used to identify them internally. 1145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY = (VkDeviceMemory)(-1); 115888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis// 2nd special memory handle used to flag object as unbound from memory 116888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlisstatic const VkDeviceMemory MEMORY_UNBOUND = VkDeviceMemory(~((uint64_t)(0)) - 1); 117b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis 1182e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill// A special value of (0xFFFFFFFF, 0xFFFFFFFF) indicates that the surface size will be determined 1192e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill// by the extent of a swapchain targeting the surface. 1202e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madillstatic const uint32_t kSurfaceSizeFromSwapchain = 0xFFFFFFFFu; 1212e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill 122f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstruct instance_layer_data { 123d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes VkInstance instance = VK_NULL_HANDLE; 124d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes debug_report_data *report_data = nullptr; 1255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<VkDebugReportCallbackEXT> logging_callback; 1269172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes VkLayerInstanceDispatchTable dispatch_table; 1279172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes 128219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes CALL_STATE vkEnumeratePhysicalDevicesState = UNCALLED; 129219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes uint32_t physical_devices_count = 0; 130b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young CALL_STATE vkEnumeratePhysicalDeviceGroupsState = UNCALLED; 131b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young uint32_t physical_device_groups_count = 0; 132219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes CHECK_DISABLED disabled = {}; 133219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes 134f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes unordered_map<VkPhysicalDevice, PHYSICAL_DEVICE_STATE> physical_device_map; 135747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes unordered_map<VkSurfaceKHR, SURFACE_STATE> surface_map; 136747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 1370cf009a4e2a5c22e4645f343c7a998f188a22015Chris Forbes InstanceExtensions extensions; 138f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes}; 139f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes 140f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstruct layer_data { 141f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes debug_report_data *report_data = nullptr; 1424a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkLayerDispatchTable dispatch_table; 14394c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis 144a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski DeviceExtensions extensions = {}; 145cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski unordered_set<VkQueue> queues; // All queues under given device 1465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Layer specific data 147d31a44af6da568692a73201825459689c9431867Tobin Ehlis unordered_map<VkSampler, unique_ptr<SAMPLER_STATE>> samplerMap; 14879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis unordered_map<VkImageView, unique_ptr<IMAGE_VIEW_STATE>> imageViewMap; 1491facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis unordered_map<VkImage, unique_ptr<IMAGE_STATE>> imageMap; 15039267c0c27b8f032f05a6747eb02d4508247fdc1Tobin Ehlis unordered_map<VkBufferView, unique_ptr<BUFFER_VIEW_STATE>> bufferViewMap; 1515cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis unordered_map<VkBuffer, unique_ptr<BUFFER_STATE>> bufferMap; 1524c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis unordered_map<VkPipeline, PIPELINE_STATE *> pipelineMap; 1538d6a38de0389036581ada119e548180c614fe0efChris Forbes unordered_map<VkCommandPool, COMMAND_POOL_NODE> commandPoolMap; 154a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_STATE *> descriptorPoolMap; 155397d27da37095073c8b86f9ff5289d0a39ce486eTobin Ehlis unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> setMap; 1563f75ec6fa8700769a790d84e07c270579ded5468Tobin Ehlis unordered_map<VkDescriptorSetLayout, std::shared_ptr<cvdescriptorset::DescriptorSetLayout const>> descriptorSetLayoutMap; 1575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkPipelineLayout, PIPELINE_LAYOUT_NODE> pipelineLayoutMap; 15857fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis unordered_map<VkDeviceMemory, unique_ptr<DEVICE_MEM_INFO>> memObjMap; 1595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkFence, FENCE_NODE> fenceMap; 16036c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlis unordered_map<VkQueue, QUEUE_STATE> queueMap; 1614710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis unordered_map<VkEvent, EVENT_STATE> eventMap; 1625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<QueryObject, bool> queryToStateMap; 1635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkQueryPool, QUERY_POOL_NODE> queryPoolMap; 1645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkSemaphore, SEMAPHORE_NODE> semaphoreMap; 16572d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis unordered_map<VkCommandBuffer, GLOBAL_CB_NODE *> commandBufferMap; 166c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_STATE>> frameBufferMap; 1675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap; 1685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap; 169127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis unordered_map<VkRenderPass, unique_ptr<RENDER_PASS_STATE>> renderPassMap; 170918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap; 1716246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski unordered_map<VkDescriptorUpdateTemplateKHR, unique_ptr<TEMPLATE_STATE>> desc_template_map; 17216a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes unordered_map<VkSwapchainKHR, std::unique_ptr<SWAPCHAIN_NODE>> swapchainMap; 17307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 174d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes VkDevice device = VK_NULL_HANDLE; 175ec85232c4d8d9ddf7d2ae57cb8203c5ab52c1106Mark Lobodzinski VkPhysicalDevice physical_device = VK_NULL_HANDLE; 1765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 177cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski instance_layer_data *instance_data = nullptr; // from device to enclosing instance 17807a464bd7fec9583f346b8c4b8d43c88d2e9ffa4Chris Forbes 179f71dd305f197826a61f398bff725267a20ea1d90Chris Forbes VkPhysicalDeviceFeatures enabled_features = {}; 1805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Device specific data 181d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes PHYS_DEV_PROPERTIES_NODE phys_dev_properties = {}; 182d3578035fec44db2380099c2f59d3e4d8e0b98d6Chris Forbes VkPhysicalDeviceMemoryProperties phys_dev_mem_props = {}; 183e47dbc3f3340fa177d877a67b2adb76a570027e5Mark Lobodzinski VkPhysicalDeviceProperties phys_dev_props = {}; 1845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis}; 1855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 186b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis// TODO : Do we need to guard access to layer_data_map w/ lock? 187b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlisstatic unordered_map<void *, layer_data *> layer_data_map; 188f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstatic unordered_map<void *, instance_layer_data *> instance_layer_data_map; 189b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis 190b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Youngstatic uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION; 191b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 192e11120777bcd1543455d1de54b89292879bcd2bbChia-I Wustatic const VkLayerProperties global_layer = { 193f1ea418f193d10a8455cdf47e0eeeeb1f4d8b5bfJon Ashburn "VK_LAYER_LUNARG_core_validation", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer", 194e11120777bcd1543455d1de54b89292879bcd2bbChia-I Wu}; 1955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 196cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskitemplate <class TCreateInfo> 197cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskivoid ValidateLayerOrdering(const TCreateInfo &createInfo) { 1985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis bool foundLayer = false; 1995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < createInfo.enabledLayerCount; ++i) { 200e11120777bcd1543455d1de54b89292879bcd2bbChia-I Wu if (!strcmp(createInfo.ppEnabledLayerNames[i], global_layer.layerName)) { 2015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis foundLayer = true; 2025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // This has to be logged to console as we don't have a callback at this point. 2045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!foundLayer && !strcmp(createInfo.ppEnabledLayerNames[0], "VK_LAYER_GOOGLE_unique_objects")) { 205bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski LOGCONSOLE("Cannot activate layer VK_LAYER_GOOGLE_unique_objects prior to activating %s.", global_layer.layerName); 2065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 2095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// TODO : This can be much smarter, using separate locks for separate global data 211ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbesstatic mutex_t global_lock; 212593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 21379fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis// Return IMAGE_VIEW_STATE ptr for specified imageView or else NULL 2149a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisIMAGE_VIEW_STATE *GetImageViewState(const layer_data *dev_data, VkImageView image_view) { 2152c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis auto iv_it = dev_data->imageViewMap.find(image_view); 2162c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis if (iv_it == dev_data->imageViewMap.end()) { 2172c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis return nullptr; 2182c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis } 2192c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis return iv_it->second.get(); 2202c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis} 2219a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis// Return sampler node ptr for specified sampler or else NULL 2229a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSAMPLER_STATE *GetSamplerState(const layer_data *dev_data, VkSampler sampler) { 2232c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis auto sampler_it = dev_data->samplerMap.find(sampler); 2242c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis if (sampler_it == dev_data->samplerMap.end()) { 2259a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis return nullptr; 2269a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis } 2279a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis return sampler_it->second.get(); 2289a55ca3674bb3fac3fbdfca9515a16a224aa9055Tobin Ehlis} 2295cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis// Return image state ptr for specified image or else NULL 2309a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisIMAGE_STATE *GetImageState(const layer_data *dev_data, VkImage image) { 2316d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis auto img_it = dev_data->imageMap.find(image); 2326d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis if (img_it == dev_data->imageMap.end()) { 2336d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis return nullptr; 2346d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis } 2356d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis return img_it->second.get(); 2366d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis} 2375cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis// Return buffer state ptr for specified buffer or else NULL 2389a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisBUFFER_STATE *GetBufferState(const layer_data *dev_data, VkBuffer buffer) { 2392c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis auto buff_it = dev_data->bufferMap.find(buffer); 2402c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis if (buff_it == dev_data->bufferMap.end()) { 2418718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis return nullptr; 2428718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis } 2438718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis return buff_it->second.get(); 2448718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis} 245b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis// Return swapchain node for specified swapchain or else NULL 2469a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSWAPCHAIN_NODE *GetSwapchainNode(const layer_data *dev_data, VkSwapchainKHR swapchain) { 24716a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes auto swp_it = dev_data->swapchainMap.find(swapchain); 24816a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes if (swp_it == dev_data->swapchainMap.end()) { 249b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis return nullptr; 250b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis } 2513f687bf405355f3eec6bd1bc0e8d04daba37a0f9Tobin Ehlis return swp_it->second.get(); 252b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis} 2532f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis// Return buffer node ptr for specified buffer or else NULL 2549a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisBUFFER_VIEW_STATE *GetBufferViewState(const layer_data *dev_data, VkBufferView buffer_view) { 25551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto bv_it = dev_data->bufferViewMap.find(buffer_view); 25651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (bv_it == dev_data->bufferViewMap.end()) { 2572f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis return nullptr; 2582f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis } 2592f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis return bv_it->second.get(); 2602f2db584f5d79892bd84d0a24b8ca3499985a5c2Tobin Ehlis} 2618718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis 2629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisFENCE_NODE *GetFenceNode(layer_data *dev_data, VkFence fence) { 26366fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes auto it = dev_data->fenceMap.find(fence); 26466fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes if (it == dev_data->fenceMap.end()) { 26566fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return nullptr; 26666fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes } 26766fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return &it->second; 26866fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes} 26966fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes 2709a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisEVENT_STATE *GetEventNode(layer_data *dev_data, VkEvent event) { 2719556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis auto it = dev_data->eventMap.find(event); 2729556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis if (it == dev_data->eventMap.end()) { 2739556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis return nullptr; 2749556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis } 2759556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis return &it->second; 2769556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis} 2779556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis 2789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisQUERY_POOL_NODE *GetQueryPoolNode(layer_data *dev_data, VkQueryPool query_pool) { 279ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis auto it = dev_data->queryPoolMap.find(query_pool); 280ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis if (it == dev_data->queryPoolMap.end()) { 281ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis return nullptr; 282ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis } 283ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis return &it->second; 284ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis} 285ccdcc9686c664e9407dd03262f3aaf3245b23be2Tobin Ehlis 2869a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisQUEUE_STATE *GetQueueState(layer_data *dev_data, VkQueue queue) { 28766fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes auto it = dev_data->queueMap.find(queue); 28866fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes if (it == dev_data->queueMap.end()) { 28966fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return nullptr; 29066fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes } 29166fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes return &it->second; 29266fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes} 29366fb98d19a758f79dd11ba354e47d0c66c6aac1eChris Forbes 2949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSEMAPHORE_NODE *GetSemaphoreNode(layer_data *dev_data, VkSemaphore semaphore) { 2955e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes auto it = dev_data->semaphoreMap.find(semaphore); 2965e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes if (it == dev_data->semaphoreMap.end()) { 2975e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes return nullptr; 2985e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes } 2995e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes return &it->second; 3005e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes} 3015e92f3cfdca6a52a3dcefd053c41f728bd036cebChris Forbes 3029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisCOMMAND_POOL_NODE *GetCommandPoolNode(layer_data *dev_data, VkCommandPool pool) { 3038d6a38de0389036581ada119e548180c614fe0efChris Forbes auto it = dev_data->commandPoolMap.find(pool); 3048d6a38de0389036581ada119e548180c614fe0efChris Forbes if (it == dev_data->commandPoolMap.end()) { 3058d6a38de0389036581ada119e548180c614fe0efChris Forbes return nullptr; 3068d6a38de0389036581ada119e548180c614fe0efChris Forbes } 3078d6a38de0389036581ada119e548180c614fe0efChris Forbes return &it->second; 3088d6a38de0389036581ada119e548180c614fe0efChris Forbes} 3093bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes 3109a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisPHYSICAL_DEVICE_STATE *GetPhysicalDeviceState(instance_layer_data *instance_data, VkPhysicalDevice phys) { 311f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes auto it = instance_data->physical_device_map.find(phys); 312f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbes if (it == instance_data->physical_device_map.end()) { 3133bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes return nullptr; 3143bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes } 3153bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes return &it->second; 3163bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes} 3173bb2c67470811e4eaf908b3eade82f73aa3f87bcChris Forbes 3189a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisSURFACE_STATE *GetSurfaceState(instance_layer_data *instance_data, VkSurfaceKHR surface) { 319747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes auto it = instance_data->surface_map.find(surface); 320747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes if (it == instance_data->surface_map.end()) { 321747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return nullptr; 322747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 323747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return &it->second; 324747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 325747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 326d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris ForbesDeviceExtensions const *GetEnabledExtensions(layer_data const *dev_data) { 327d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return &dev_data->extensions; 328d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes} 329d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes 330f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// Return ptr to memory binding for given handle of specified type 3317a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic BINDABLE *GetObjectMemBinding(layer_data *dev_data, uint64_t handle, VulkanObjectType type) { 3325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis switch (type) { 3337a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeImage: 3349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return GetImageState(dev_data, VkImage(handle)); 3357a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeBuffer: 3369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return GetBufferState(dev_data, VkBuffer(handle)); 337cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 338cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 3395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 34094c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis return nullptr; 3415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 34272d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis// prototype 3439a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisGLOBAL_CB_NODE *GetCBNode(layer_data const *, const VkCommandBuffer); 34472d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis 3455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Return ptr to info in map container containing mem, or NULL if not found 3465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Calls to this function should be wrapped in mutex 3479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisDEVICE_MEM_INFO *GetMemObjInfo(const layer_data *dev_data, const VkDeviceMemory mem) { 34857fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis auto mem_it = dev_data->memObjMap.find(mem); 34957fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_it == dev_data->memObjMap.end()) { 3505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 3515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 35257fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis return mem_it->second.get(); 3535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 3545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 35551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void add_mem_obj_info(layer_data *dev_data, void *object, const VkDeviceMemory mem, 3565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkMemoryAllocateInfo *pAllocateInfo) { 3575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis assert(object != NULL); 3585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 35951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->memObjMap[mem] = unique_ptr<DEVICE_MEM_INFO>(new DEVICE_MEM_INFO(object, mem, pAllocateInfo)); 3605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 361dc21d4c322604e04e0b8433970f6a1ced6a0b647Tobin Ehlis 362cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis// For given bound_object_handle, bound to given mem allocation, verify that the range for the bound object is valid 3637a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic bool ValidateMemoryIsValid(layer_data *dev_data, VkDeviceMemory mem, uint64_t bound_object_handle, VulkanObjectType type, 3647a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski const char *functionName) { 3659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 366f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis if (mem_info) { 367f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis if (!mem_info->bound_ranges[bound_object_handle].valid) { 368f48a83f5b5548cd46a12770c7542ff902537ad3eKarl Schultz return log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 3699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM", 370dc21d4c322604e04e0b8433970f6a1ced6a0b647Tobin Ehlis "%s: Cannot read invalid region of memory allocation 0x%" PRIx64 " for bound %s object 0x%" PRIx64 371dc21d4c322604e04e0b8433970f6a1ced6a0b647Tobin Ehlis ", please fill the memory before using.", 3729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName, HandleToUint64(mem), object_string[type], bound_object_handle); 373f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis } 374f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis } 375f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis return false; 376f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 3771facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis// For given image_state 3781facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis// If mem is special swapchain key, then verify that image_state valid member is true 379f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// Else verify that the image's bound memory range is valid 38060568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinskibool ValidateImageMemoryIsValid(layer_data *dev_data, IMAGE_STATE *image_state, const char *functionName) { 381e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { 3821facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (!image_state->valid) { 383f48a83f5b5548cd46a12770c7542ff902537ad3eKarl Schultz return log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 3849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->binding.mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM", 385414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller "%s: Cannot read invalid swapchain image 0x%" PRIx64 ", please fill the memory before using.", 3869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName, HandleToUint64(image_state->image)); 3875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 3899b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateMemoryIsValid(dev_data, image_state->binding.mem, HandleToUint64(image_state->image), kVulkanObjectTypeImage, 3909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName); 3915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 3935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 3945cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis// For given buffer_state, verify that the range it's bound to is valid 395c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskibool ValidateBufferMemoryIsValid(layer_data *dev_data, BUFFER_STATE *buffer_state, const char *functionName) { 3969b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateMemoryIsValid(dev_data, buffer_state->binding.mem, HandleToUint64(buffer_state->buffer), kVulkanObjectTypeBuffer, 3979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus functionName); 398f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 399f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// For the given memory allocation, set the range bound by the given handle object to the valid param value 400f989de4217bce0f293121d0da53dc8328276370fTobin Ehlisstatic void SetMemoryValid(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, bool valid) { 4019a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 402f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis if (mem_info) { 403f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis mem_info->bound_ranges[handle].valid = valid; 404f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis } 405f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 406f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// For given image node 4071facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis// If mem is special swapchain key, then set entire image_state to valid param value 408f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// Else set the image's bound memory range to valid param value 409623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinskivoid SetImageMemoryValid(layer_data *dev_data, IMAGE_STATE *image_state, bool valid) { 410e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { 4111facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->valid = valid; 4125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 4139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus SetMemoryValid(dev_data, image_state->binding.mem, HandleToUint64(image_state->image), valid); 4145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 416f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis// For given buffer node set the buffer's bound memory range to valid param value 417c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinskivoid SetBufferMemoryValid(layer_data *dev_data, BUFFER_STATE *buffer_state, bool valid) { 4189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus SetMemoryValid(dev_data, buffer_state->binding.mem, HandleToUint64(buffer_state->buffer), valid); 419f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis} 420ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 42156f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis// Create binding link between given sampler and command buffer node 422d31a44af6da568692a73201825459689c9431867Tobin Ehlisvoid AddCommandBufferBindingSampler(GLOBAL_CB_NODE *cb_node, SAMPLER_STATE *sampler_state) { 423d31a44af6da568692a73201825459689c9431867Tobin Ehlis sampler_state->cb_bindings.insert(cb_node); 4249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(sampler_state->sampler), kVulkanObjectTypeSampler}); 42556f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis} 42656f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis 42756f8a8f9b7e8c01d76d73be117ebcb66035db6dfTobin Ehlis// Create binding link between given image node and command buffer node 4281facd2c91911508b9fb61f54a56269841299f663Tobin Ehlisvoid AddCommandBufferBindingImage(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *image_state) { 429ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // Skip validation if this image was created through WSI 430e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_state->binding.mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) { 431ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // First update CB binding in MemObj mini CB list 432d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis for (auto mem_binding : image_state->GetBoundMemory()) { 4339a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *pMemInfo = GetMemObjInfo(dev_data, mem_binding); 434d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis if (pMemInfo) { 435d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis pMemInfo->cb_bindings.insert(cb_node); 436d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis // Now update CBInfo's Mem reference list 437d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis cb_node->memObjs.insert(mem_binding); 438d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis } 439ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } 440f940225c9e5e3e14b3f5a32d3ea360b585614600Tobin Ehlis // Now update cb binding for image 4419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(image_state->image), kVulkanObjectTypeImage}); 4421facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->cb_bindings.insert(cb_node); 443ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } 444ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis} 445ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 44603ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis// Create binding link between given image view node and its image with command buffer node 44703ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlisvoid AddCommandBufferBindingImageView(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_VIEW_STATE *view_state) { 44803ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis // First add bindings for imageView 44903ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis view_state->cb_bindings.insert(cb_node); 4509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(view_state->image_view), kVulkanObjectTypeImageView}); 4519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, view_state->create_info.image); 45203ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis // Add bindings for image within imageView 4531facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (image_state) { 4541facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis AddCommandBufferBindingImage(dev_data, cb_node, image_state); 45503ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis } 45603ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis} 45703ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis 458ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis// Create binding link between given buffer node and command buffer node 4595cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlisvoid AddCommandBufferBindingBuffer(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_STATE *buffer_state) { 460ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // First update CB binding in MemObj mini CB list 4615cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis for (auto mem_binding : buffer_state->GetBoundMemory()) { 4629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *pMemInfo = GetMemObjInfo(dev_data, mem_binding); 463d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis if (pMemInfo) { 464d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis pMemInfo->cb_bindings.insert(cb_node); 465d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis // Now update CBInfo's Mem reference list 466d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis cb_node->memObjs.insert(mem_binding); 467d87d172d120ea3f00bfd34335537332d7ce61a89Tobin Ehlis } 468ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } 469ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // Now update cb binding for buffer 4709b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(buffer_state->buffer), kVulkanObjectTypeBuffer}); 4715cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis buffer_state->cb_bindings.insert(cb_node); 472ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis} 473ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 47477b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis// Create binding link between given buffer view node and its buffer with command buffer node 47577b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlisvoid AddCommandBufferBindingBufferView(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_VIEW_STATE *view_state) { 47677b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis // First add bindings for bufferView 47777b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis view_state->cb_bindings.insert(cb_node); 4789b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_node->object_bindings.insert({HandleToUint64(view_state->buffer_view), kVulkanObjectTypeBufferView}); 4799a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, view_state->create_info.buffer); 48077b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis // Add bindings for buffer within bufferView 4815cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 4825cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_node, buffer_state); 48377b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis } 48477b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis} 48577b6217754b9c167b08cb151e70b41a948e36277Tobin Ehlis 486400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis// For every mem obj bound to particular CB, free bindings related to that CB 487d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlisstatic void clear_cmd_buf_and_mem_references(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { 488d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis if (cb_node) { 489d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis if (cb_node->memObjs.size() > 0) { 490d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto mem : cb_node->memObjs) { 4919a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *pInfo = GetMemObjInfo(dev_data, mem); 4925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pInfo) { 493d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis pInfo->cb_bindings.erase(cb_node); 4945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 496d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis cb_node->memObjs.clear(); 4975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 5005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 501f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// Clear a single object binding from given memory object, or report error if binding is missing 5027a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic bool ClearMemoryObjectBinding(layer_data *dev_data, uint64_t handle, VulkanObjectType type, VkDeviceMemory mem) { 5039a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 504f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // This obj is bound to a memory object. Remove the reference to this object in that memory object's list 505d4cd34fd49caa759cf01cafa5fa271401b17c3b9Jeremy Hayes if (mem_info) { 506d4cd34fd49caa759cf01cafa5fa271401b17c3b9Jeremy Hayes mem_info->obj_bindings.erase({handle, type}); 507f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis } 508f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis return false; 509f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis} 510f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis 511f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// ClearMemoryObjectBindings clears the binding of objects to memory 512f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// For the given object it pulls the memory bindings and makes sure that the bindings 513f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis// no longer refer to the object being cleared. This occurs when objects are destroyed. 5147a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskibool ClearMemoryObjectBindings(layer_data *dev_data, uint64_t handle, VulkanObjectType type) { 515f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis bool skip = false; 516f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 517f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (mem_binding) { 518f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (!mem_binding->sparse) { 519f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis skip = ClearMemoryObjectBinding(dev_data, handle, type, mem_binding->binding.mem); 520cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // Sparse, clear all bindings 521bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski for (auto &sparse_mem_binding : mem_binding->sparse_bindings) { 522f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis skip |= ClearMemoryObjectBinding(dev_data, handle, type, sparse_mem_binding.mem); 5235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 526f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis return skip; 5275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 5285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 529888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis// For given mem object, verify that it is not null or UNBOUND, if it is, report error. Return skip value. 530888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlisbool VerifyBoundMemoryIsValid(const layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, const char *api_name, 53135ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis const char *type_name, UNIQUE_VALIDATION_ERROR_CODE error_code) { 532888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis bool result = false; 533888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis if (VK_NULL_HANDLE == mem) { 534888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, handle, 535cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski __LINE__, error_code, "MEM", "%s: Vk%s object 0x%" PRIxLEAST64 536cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " used with no memory bound. Memory should be bound by calling " 537cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkBind%sMemory(). %s", 53835ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis api_name, type_name, handle, type_name, validation_error_map[error_code]); 539888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis } else if (MEMORY_UNBOUND == mem) { 540888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, handle, 541cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski __LINE__, error_code, "MEM", "%s: Vk%s object 0x%" PRIxLEAST64 542cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " used with no memory bound and previously bound memory was freed. " 543cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "Memory must not be freed prior to this operation. %s", 54435ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis api_name, type_name, handle, validation_error_map[error_code]); 545888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis } 546888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis return result; 547888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis} 548888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis 549b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski// Check to see if memory was ever bound to this image 55035ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlisbool ValidateMemoryIsBoundToImage(const layer_data *dev_data, const IMAGE_STATE *image_state, const char *api_name, 55135ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 552b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski bool result = false; 5531facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (0 == (static_cast<uint32_t>(image_state->createInfo.flags) & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { 5549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus result = VerifyBoundMemoryIsValid(dev_data, image_state->binding.mem, HandleToUint64(image_state->image), api_name, "Image", 5559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus error_code); 556b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski } 557b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski return result; 558b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski} 559b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 560b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski// Check to see if memory was bound to this buffer 56135ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlisbool ValidateMemoryIsBoundToBuffer(const layer_data *dev_data, const BUFFER_STATE *buffer_state, const char *api_name, 56235ec5e14e463d342b74ffe33ee542be13d5c6639Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 563b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski bool result = false; 5645cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (0 == (static_cast<uint32_t>(buffer_state->createInfo.flags) & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) { 5659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus result = VerifyBoundMemoryIsValid(dev_data, buffer_state->binding.mem, HandleToUint64(buffer_state->buffer), api_name, 5669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Buffer", error_code); 567b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski } 568b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski return result; 569b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski} 570b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 5713a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// SetMemBinding is used to establish immutable, non-sparse binding between a single image/buffer object and memory object. 5723a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Corresponding valid usage checks are in ValidateSetMemBinding(). 5737a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic void SetMemBinding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, VulkanObjectType type, const char *apiName) { 574c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (mem != VK_NULL_HANDLE) { 575c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 576c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton assert(mem_binding); 577c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 578c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (mem_info) { 579c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton mem_info->obj_bindings.insert({handle, type}); 580c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // For image objects, make sure default memory state is correctly set 581c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // TODO : What's the best/correct way to handle this? 5827a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski if (kVulkanObjectTypeImage == type) { 583c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton auto const image_state = GetImageState(dev_data, VkImage(handle)); 584c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (image_state) { 585c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton VkImageCreateInfo ici = image_state->createInfo; 586c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 587c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // TODO:: More memory state transition stuff. 588c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 589c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 590c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 591c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton mem_binding->binding.mem = mem; 592c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 593c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton } 594c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton} 5953a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton 5963a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Valid usage checks for a call to SetMemBinding(). 5973a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// For NULL mem case, output warning 5983a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Make sure given object is in global object map 5993a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// IF a previous binding existed, output validation error 6003a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Otherwise, add reference from objectInfo to memoryInfo 6013a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// Add reference off of objInfo 6023a6c2a8f5135475de5be6de7675ffd9dd27b30d3Cort Stratton// TODO: We may need to refactor or pass in multiple valid usage statements to handle multiple valid usage conditions. 6037a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinskistatic bool ValidateSetMemBinding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, VulkanObjectType type, 604c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton const char *apiName) { 6053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 606f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // It's an error to bind an object to NULL memory 607d3876b4ff7c293a14f73fe3622513d1fa91bf2d0Jeremy Hayes if (mem != VK_NULL_HANDLE) { 608f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 609888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis assert(mem_binding); 61010ffe2d353eaff714ed92a2835af77d8b5042d31Cort if (mem_binding->sparse) { 611315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_1740082a; 61210ffe2d353eaff714ed92a2835af77d8b5042d31Cort const char *handle_type = "IMAGE"; 61374300755ed9ec780d6073af71e47f201217008d6Cort Stratton if (strcmp(apiName, "vkBindBufferMemory()") == 0) { 614315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis error_code = VALIDATION_ERROR_1700080c; 61510ffe2d353eaff714ed92a2835af77d8b5042d31Cort handle_type = "BUFFER"; 61610ffe2d353eaff714ed92a2835af77d8b5042d31Cort } else { 61774300755ed9ec780d6073af71e47f201217008d6Cort Stratton assert(strcmp(apiName, "vkBindImageMemory()") == 0); 61810ffe2d353eaff714ed92a2835af77d8b5042d31Cort } 6193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 6209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, error_code, "MEM", 6213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 6223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") which was created with sparse memory flags (VK_%s_CREATE_SPARSE_*_BIT). %s", 6239b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiName, HandleToUint64(mem), handle, handle_type, validation_error_map[error_code]); 62410ffe2d353eaff714ed92a2835af77d8b5042d31Cort } 6259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 626888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis if (mem_info) { 6279a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *prev_binding = GetMemObjInfo(dev_data, mem_binding->binding.mem); 628888cae09036ec622d6014e18efbda55e6226cf22Tobin Ehlis if (prev_binding) { 629315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = VALIDATION_ERROR_17400828; 63074300755ed9ec780d6073af71e47f201217008d6Cort Stratton if (strcmp(apiName, "vkBindBufferMemory()") == 0) { 631315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis error_code = VALIDATION_ERROR_1700080a; 63298c2a17e1a549df84f4239f619bc0955f632cb43Cort } else { 63374300755ed9ec780d6073af71e47f201217008d6Cort Stratton assert(strcmp(apiName, "vkBindImageMemory()") == 0); 63498c2a17e1a549df84f4239f619bc0955f632cb43Cort } 6353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 6369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, error_code, "MEM", 6373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 6383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") which has already been bound to mem object 0x%" PRIxLEAST64 ". %s", 6399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiName, HandleToUint64(mem), handle, HandleToUint64(prev_binding->mem), 6403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski validation_error_map[error_code]); 641f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis } else if (mem_binding->binding.mem == MEMORY_UNBOUND) { 6423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 6439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_REBIND_OBJECT, "MEM", 6443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 6453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") which was previous bound to memory that has since been freed. Memory bindings are immutable in " 6463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Vulkan so this attempt to bind to new memory is not allowed.", 6479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiName, HandleToUint64(mem), handle); 6485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 6535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// For NULL mem case, clear any previous binding Else... 6555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Make sure given object is in its object map 6565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// IF a previous binding existed, update binding 6575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Add reference from objectInfo to memoryInfo 6585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Add reference off of object's binding info 6590a1ce3dfd81c9f4efbe46f5ba5ddaea70bc4aa61Chris Forbes// Return VK_TRUE if addition is successful, VK_FALSE otherwise 660ece0e981ee4a5ad2572d146a89fc64d699d79f36Chris Forbesstatic bool SetSparseMemBinding(layer_data *dev_data, MEM_BINDING binding, uint64_t handle, VulkanObjectType type) { 6613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = VK_FALSE; 6625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Handle NULL case separately, just clear previous binding & decrement reference 663f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (binding.mem == VK_NULL_HANDLE) { 664f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // TODO : This should cause the range of the resource to be unbound according to spec 6655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 666f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type); 667f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis assert(mem_binding); 668f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis assert(mem_binding->sparse); 6699a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, binding.mem); 670f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (mem_info) { 671f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis mem_info->obj_bindings.insert({handle, type}); 6722e415b757c1e43fda35311aad026af8d5c96681cTobin Ehlis // Need to set mem binding for this object 673f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis mem_binding->sparse_bindings.insert(binding); 6745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 677caf05e0db4959ae196ab34b024f352d9c0326870Tobin Ehlis} 678caf05e0db4959ae196ab34b024f352d9c0326870Tobin Ehlis 6795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Check object status for selected flag state 68051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool validate_status(layer_data *dev_data, GLOBAL_CB_NODE *pNode, CBStatusFlags status_mask, VkFlags msg_flags, 6814f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes const char *fail_msg, UNIQUE_VALIDATION_ERROR_CODE const msg_code) { 6823d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (!(pNode->status & status_mask)) { 6834f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes char const *const message = validation_error_map[msg_code]; 68451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis return log_msg(dev_data->report_data, msg_flags, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6859b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pNode->commandBuffer), __LINE__, msg_code, "DS", "command buffer object 0x%p: %s. %s.", 6869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pNode->commandBuffer, fail_msg, message); 6875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 688e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 6895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 6905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Retrieve pipeline node ptr for given pipeline object 69251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic PIPELINE_STATE *getPipelineState(layer_data const *dev_data, VkPipeline pipeline) { 69351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->pipelineMap.find(pipeline); 69451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->pipelineMap.end()) { 695ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes return nullptr; 6965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 697ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes return it->second; 6985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 6995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7009a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisRENDER_PASS_STATE *GetRenderPassState(layer_data const *dev_data, VkRenderPass renderpass) { 70151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->renderPassMap.find(renderpass); 70251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->renderPassMap.end()) { 70316387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes return nullptr; 70416387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes } 705fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes return it->second.get(); 70616387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes} 70716387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes 7089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisFRAMEBUFFER_STATE *GetFramebufferState(const layer_data *dev_data, VkFramebuffer framebuffer) { 70951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->frameBufferMap.find(framebuffer); 71051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->frameBufferMap.end()) { 711f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes return nullptr; 712f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes } 71304861caca7eb93a5241b164e8480bb93c826902cTobin Ehlis return it->second.get(); 714f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes} 715f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes 7163f75ec6fa8700769a790d84e07c270579ded5468Tobin Ehlisstd::shared_ptr<cvdescriptorset::DescriptorSetLayout const> const GetDescriptorSetLayout(layer_data const *dev_data, 7173f75ec6fa8700769a790d84e07c270579ded5468Tobin Ehlis VkDescriptorSetLayout dsLayout) { 71851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->descriptorSetLayoutMap.find(dsLayout); 71951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->descriptorSetLayoutMap.end()) { 72011f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes return nullptr; 72111f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes } 722d34b2c191243c1646f1ccc2378262383e9ec1348Tobin Ehlis return it->second; 72311f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes} 72411f1fde2721c198a619e4a22fff60eef9a16fae8Chris Forbes 72551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic PIPELINE_LAYOUT_NODE const *getPipelineLayout(layer_data const *dev_data, VkPipelineLayout pipeLayout) { 72651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->pipelineLayoutMap.find(pipeLayout); 72751ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->pipelineLayoutMap.end()) { 7284a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes return nullptr; 7294a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes } 7304a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes return &it->second; 7314a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes} 7324a45a42023b281f55953222c1a6c3e80f50e5f2aChris Forbes 733d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbesshader_module const *GetShaderModuleState(layer_data const *dev_data, VkShaderModule module) { 734d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes auto it = dev_data->shaderModuleMap.find(module); 735d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes if (it == dev_data->shaderModuleMap.end()) { 736d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return nullptr; 737d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes } 738d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return it->second.get(); 739d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes} 740d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes 741e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves// Return true if for a given PSO, the given state enum is dynamic, else return false 7424c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic bool isDynamic(const PIPELINE_STATE *pPipeline, const VkDynamicState state) { 7435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) { 7445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pPipeline->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) { 745cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (state == pPipeline->graphicsPipelineCI.pDynamicState->pDynamicStates[i]) return true; 7465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 748e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 7495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Validate state stored as flags at time of draw call 7524f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayesstatic bool validate_draw_state_flags(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe, bool indexed, 7534f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes UNIQUE_VALIDATION_ERROR_CODE const msg_code) { 7549c4006684a13db43f0dbc8d0015a9ef34872ca09Chris Forbes bool result = false; 755ca546210846c65808717f8875deae39bd227c240Tobin Ehlis if (pPipe->graphicsPipelineCI.pInputAssemblyState && 756ca546210846c65808717f8875deae39bd227c240Tobin Ehlis ((pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST) || 757ca546210846c65808717f8875deae39bd227c240Tobin Ehlis (pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP))) { 7583d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_LINE_WIDTH_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7594f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic line width state not set for this command buffer", msg_code); 7603d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 76145824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves if (pPipe->graphicsPipelineCI.pRasterizationState && 76245824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves (pPipe->graphicsPipelineCI.pRasterizationState->depthBiasEnable == VK_TRUE)) { 7633d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_DEPTH_BIAS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7644f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic depth bias state not set for this command buffer", msg_code); 7653d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 7663d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (pPipe->blendConstantsEnabled) { 7673d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_BLEND_CONSTANTS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7684f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic blend constants state not set for this command buffer", msg_code); 7693d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 77045824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves if (pPipe->graphicsPipelineCI.pDepthStencilState && 77145824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves (pPipe->graphicsPipelineCI.pDepthStencilState->depthBoundsTestEnable == VK_TRUE)) { 7723d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_DEPTH_BOUNDS_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7734f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic depth bounds state not set for this command buffer", msg_code); 7743d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 77545824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves if (pPipe->graphicsPipelineCI.pDepthStencilState && 77645824955f3d4d2baee6d225f84ac9c2553981b3eDustin Graves (pPipe->graphicsPipelineCI.pDepthStencilState->stencilTestEnable == VK_TRUE)) { 7773d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_READ_MASK_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7784f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic stencil read mask state not set for this command buffer", msg_code); 7793d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_WRITE_MASK_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7804f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic stencil write mask state not set for this command buffer", msg_code); 7813d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_STENCIL_REFERENCE_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7824f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Dynamic stencil reference state not set for this command buffer", msg_code); 7833d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 7841c130ea631a82716dc7334de17767536525f2292Tobin Ehlis if (indexed) { 7853d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis result |= validate_status(dev_data, pCB, CBSTATUS_INDEX_BUFFER_BOUND, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7864f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes "Index buffer object not bound to this command buffer when Indexed Draw attempted", msg_code); 7873d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 7884f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes 7895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 7905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Verify attachment reference compatibility according to spec 7935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// If one array is larger, treat missing elements of shorter array as VK_ATTACHMENT_UNUSED & other array much match this 7945ca3c071afc98f9144f489b74aa3affaa93633b0Mark Lobodzinski// If both AttachmentReference arrays have requested index, check their corresponding AttachmentDescriptions 7955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// to make sure that format and samples counts match. 7965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// If not, they are not compatible. 7975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic bool attachment_references_compatible(const uint32_t index, const VkAttachmentReference *pPrimary, 7985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const uint32_t primaryCount, const VkAttachmentDescription *pPrimaryAttachments, 7995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkAttachmentReference *pSecondary, const uint32_t secondaryCount, 8005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkAttachmentDescription *pSecondaryAttachments) { 801e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis // Check potential NULL cases first to avoid nullptr issues later 802e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis if (pPrimary == nullptr) { 803e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis if (pSecondary == nullptr) { 804e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis return true; 805e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis } 806e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis return false; 807e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis } else if (pSecondary == nullptr) { 808e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis return false; 809e62f2e46eeffde494c0d734964b389c09dec9d64Tobin Ehlis } 810cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (index >= primaryCount) { // Check secondary as if primary is VK_ATTACHMENT_UNUSED 811cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (VK_ATTACHMENT_UNUSED == pSecondary[index].attachment) return true; 812cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else if (index >= secondaryCount) { // Check primary as if secondary is VK_ATTACHMENT_UNUSED 813cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (VK_ATTACHMENT_UNUSED == pPrimary[index].attachment) return true; 814cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // Format and sample count must match 8155ca3c071afc98f9144f489b74aa3affaa93633b0Mark Lobodzinski if ((pPrimary[index].attachment == VK_ATTACHMENT_UNUSED) && (pSecondary[index].attachment == VK_ATTACHMENT_UNUSED)) { 8165ca3c071afc98f9144f489b74aa3affaa93633b0Mark Lobodzinski return true; 8175ca3c071afc98f9144f489b74aa3affaa93633b0Mark Lobodzinski } else if ((pPrimary[index].attachment == VK_ATTACHMENT_UNUSED) || (pSecondary[index].attachment == VK_ATTACHMENT_UNUSED)) { 8185ca3c071afc98f9144f489b74aa3affaa93633b0Mark Lobodzinski return false; 8195ca3c071afc98f9144f489b74aa3affaa93633b0Mark Lobodzinski } 8205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if ((pPrimaryAttachments[pPrimary[index].attachment].format == 8215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pSecondaryAttachments[pSecondary[index].attachment].format) && 8225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (pPrimaryAttachments[pPrimary[index].attachment].samples == 8235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pSecondaryAttachments[pSecondary[index].attachment].samples)) 8245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return true; 8255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Format and sample counts didn't match 8275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 8285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 829a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis// TODO : Scrub verify_renderpass_compatibility() and validateRenderPassCompatibility() and unify them and/or share code 830266231a5421564c314f6b5d5bd3fed26fd389484Chris Forbes// For given primary RenderPass object and secondary RenderPassCreateInfo, verify that they're compatible 83151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool verify_renderpass_compatibility(const layer_data *dev_data, const VkRenderPassCreateInfo *primaryRPCI, 8328da1edac0fbed13831b2f458f27c51e64d6210ffTobin Ehlis const VkRenderPassCreateInfo *secondaryRPCI, string &errorMsg) { 8335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (primaryRPCI->subpassCount != secondaryRPCI->subpassCount) { 834c07fa78efa7d4edfaa4ffbb0c2046ee8154b27beChris Forbes stringstream errorStr; 8355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorStr << "RenderPass for primary cmdBuffer has " << primaryRPCI->subpassCount 8365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis << " subpasses but renderPass for secondary cmdBuffer has " << secondaryRPCI->subpassCount << " subpasses."; 8375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorMsg = errorStr.str(); 8385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 8395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t spIndex = 0; 8415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (spIndex = 0; spIndex < primaryRPCI->subpassCount; ++spIndex) { 8425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // For each subpass, verify that corresponding color, input, resolve & depth/stencil attachment references are compatible 8435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t primaryColorCount = primaryRPCI->pSubpasses[spIndex].colorAttachmentCount; 8445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t secondaryColorCount = secondaryRPCI->pSubpasses[spIndex].colorAttachmentCount; 8455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t colorMax = std::max(primaryColorCount, secondaryColorCount); 8465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t cIdx = 0; cIdx < colorMax; ++cIdx) { 8475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!attachment_references_compatible(cIdx, primaryRPCI->pSubpasses[spIndex].pColorAttachments, primaryColorCount, 8485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primaryRPCI->pAttachments, secondaryRPCI->pSubpasses[spIndex].pColorAttachments, 8495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondaryColorCount, secondaryRPCI->pAttachments)) { 850c07fa78efa7d4edfaa4ffbb0c2046ee8154b27beChris Forbes stringstream errorStr; 8515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorStr << "color attachments at index " << cIdx << " of subpass index " << spIndex << " are not compatible."; 8525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorMsg = errorStr.str(); 8535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 8545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (!attachment_references_compatible(cIdx, primaryRPCI->pSubpasses[spIndex].pResolveAttachments, 8555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primaryColorCount, primaryRPCI->pAttachments, 8565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondaryRPCI->pSubpasses[spIndex].pResolveAttachments, 8575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondaryColorCount, secondaryRPCI->pAttachments)) { 858c07fa78efa7d4edfaa4ffbb0c2046ee8154b27beChris Forbes stringstream errorStr; 8595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorStr << "resolve attachments at index " << cIdx << " of subpass index " << spIndex << " are not compatible."; 8605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorMsg = errorStr.str(); 8615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 8625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 864fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes 865bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (!attachment_references_compatible(0, primaryRPCI->pSubpasses[spIndex].pDepthStencilAttachment, 1, 866bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski primaryRPCI->pAttachments, secondaryRPCI->pSubpasses[spIndex].pDepthStencilAttachment, 867fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes 1, secondaryRPCI->pAttachments)) { 868c07fa78efa7d4edfaa4ffbb0c2046ee8154b27beChris Forbes stringstream errorStr; 869fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes errorStr << "depth/stencil attachments of subpass index " << spIndex << " are not compatible."; 870fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes errorMsg = errorStr.str(); 871fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes return false; 872fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes } 873fd50683af1a7a54c6b8c13d790ad57c48072f55bChris Forbes 8745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t primaryInputCount = primaryRPCI->pSubpasses[spIndex].inputAttachmentCount; 8755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t secondaryInputCount = secondaryRPCI->pSubpasses[spIndex].inputAttachmentCount; 8765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t inputMax = std::max(primaryInputCount, secondaryInputCount); 8775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < inputMax; ++i) { 8781e49a9dd0518c3cd335dd040218aa9c25d7cb600Tobin Ehlis if (!attachment_references_compatible(i, primaryRPCI->pSubpasses[spIndex].pInputAttachments, primaryInputCount, 8795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primaryRPCI->pAttachments, secondaryRPCI->pSubpasses[spIndex].pInputAttachments, 8801e49a9dd0518c3cd335dd040218aa9c25d7cb600Tobin Ehlis secondaryInputCount, secondaryRPCI->pAttachments)) { 881c07fa78efa7d4edfaa4ffbb0c2046ee8154b27beChris Forbes stringstream errorStr; 8825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorStr << "input attachments at index " << i << " of subpass index " << spIndex << " are not compatible."; 8835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis errorMsg = errorStr.str(); 8845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 8855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return true; 8895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 8905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Return Set node ptr for specified set or else NULL 8929a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehliscvdescriptorset::DescriptorSet *GetSetNode(const layer_data *dev_data, VkDescriptorSet set) { 89351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto set_it = dev_data->setMap.find(set); 89451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (set_it == dev_data->setMap.end()) { 8955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 8965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 897104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis return set_it->second; 8985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 8995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 900eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young// For given pipeline, return number of MSAA samples, or one if MSAA disabled 9014c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic VkSampleCountFlagBits getNumSamples(PIPELINE_STATE const *pipe) { 902ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes if (pipe->graphicsPipelineCI.pMultisampleState != NULL && 903ea8349eeee76ae2859c10870fd8bd9e60309eb28Chris Forbes VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pipe->graphicsPipelineCI.pMultisampleState->sType) { 904eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young return pipe->graphicsPipelineCI.pMultisampleState->rasterizationSamples; 905eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 906eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young return VK_SAMPLE_COUNT_1_BIT; 907eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young} 908eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 909bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic void list_bits(std::ostream &s, uint32_t bits) { 910b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes for (int i = 0; i < 32 && bits; i++) { 911b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (bits & (1 << i)) { 912b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes s << i; 913b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes bits &= ~(1 << i); 914b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (bits) { 915b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes s << ","; 916b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes } 917b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes } 918b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes } 919b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes} 920b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes 921eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young// Validate draw-time state related to the PSO 92251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool ValidatePipelineDrawtimeState(layer_data const *dev_data, LAST_BOUND_STATE const &state, const GLOBAL_CB_NODE *pCB, 9234c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE const *pPipeline) { 9243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 92529d196e071b2dc1db47702085469396f2b956820Chris Forbes 926d79335137b414d5f89284a9ab3e014beb4ada3ebMike Weiblen // Verify vertex binding 92729d196e071b2dc1db47702085469396f2b956820Chris Forbes if (pPipeline->vertexBindingDescriptions.size() > 0) { 92829d196e071b2dc1db47702085469396f2b956820Chris Forbes for (size_t i = 0; i < pPipeline->vertexBindingDescriptions.size(); i++) { 929312129ec52e6249aa453e27e6be17a8dab1e98b8Tobin Ehlis auto vertex_binding = pPipeline->vertexBindingDescriptions[i].binding; 930312129ec52e6249aa453e27e6be17a8dab1e98b8Tobin Ehlis if ((pCB->currentDrawData.buffers.size() < (vertex_binding + 1)) || 931312129ec52e6249aa453e27e6be17a8dab1e98b8Tobin Ehlis (pCB->currentDrawData.buffers[vertex_binding] == VK_NULL_HANDLE)) { 9323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 933df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 9349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", 935cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "The Pipeline State Object (0x%" PRIxLEAST64 936cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski ") expects that this Command Buffer's vertex binding Index %u " 937cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "should be set via vkCmdBindVertexBuffers. This is because VkVertexInputBindingDescription struct " 938cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "at index " PRINTF_SIZE_T_SPECIFIER " of pVertexBindingDescriptions has a binding value of %u.", 9399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(state.pipeline_state->pipeline), vertex_binding, i, vertex_binding); 94029d196e071b2dc1db47702085469396f2b956820Chris Forbes } 94129d196e071b2dc1db47702085469396f2b956820Chris Forbes } 94229d196e071b2dc1db47702085469396f2b956820Chris Forbes } else { 94358b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (!pCB->currentDrawData.buffers.empty() && !pCB->vertex_buffer_used) { 9443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 9459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), __LINE__, 9469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS", 9473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Vertex buffers are bound to command buffer (0x%p" 9483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") but no vertex buffers are attached to this Pipeline State Object (0x%" PRIxLEAST64 ").", 9499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pCB->commandBuffer, HandleToUint64(state.pipeline_state->pipeline)); 95029d196e071b2dc1db47702085469396f2b956820Chris Forbes } 95129d196e071b2dc1db47702085469396f2b956820Chris Forbes } 95229d196e071b2dc1db47702085469396f2b956820Chris Forbes // If Viewport or scissors are dynamic, verify that dynamic count matches PSO count. 95329d196e071b2dc1db47702085469396f2b956820Chris Forbes // Skip check if rasterization is disabled or there is no viewport. 95429d196e071b2dc1db47702085469396f2b956820Chris Forbes if ((!pPipeline->graphicsPipelineCI.pRasterizationState || 95529d196e071b2dc1db47702085469396f2b956820Chris Forbes (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) && 95629d196e071b2dc1db47702085469396f2b956820Chris Forbes pPipeline->graphicsPipelineCI.pViewportState) { 95729d196e071b2dc1db47702085469396f2b956820Chris Forbes bool dynViewport = isDynamic(pPipeline, VK_DYNAMIC_STATE_VIEWPORT); 95829d196e071b2dc1db47702085469396f2b956820Chris Forbes bool dynScissor = isDynamic(pPipeline, VK_DYNAMIC_STATE_SCISSOR); 959b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes 96029d196e071b2dc1db47702085469396f2b956820Chris Forbes if (dynViewport) { 961b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto requiredViewportsMask = (1 << pPipeline->graphicsPipelineCI.pViewportState->viewportCount) - 1; 962b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto missingViewportMask = ~pCB->viewportMask & requiredViewportsMask; 963b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (missingViewportMask) { 964b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes std::stringstream ss; 965b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes ss << "Dynamic viewport(s) "; 966b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes list_bits(ss, missingViewportMask); 967d79335137b414d5f89284a9ab3e014beb4ada3ebMike Weiblen ss << " are used by pipeline state object, but were not provided via calls to vkCmdSetViewport()."; 9683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 9693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", "%s", ss.str().c_str()); 97029d196e071b2dc1db47702085469396f2b956820Chris Forbes } 97129d196e071b2dc1db47702085469396f2b956820Chris Forbes } 972b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes 97329d196e071b2dc1db47702085469396f2b956820Chris Forbes if (dynScissor) { 974b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto requiredScissorMask = (1 << pPipeline->graphicsPipelineCI.pViewportState->scissorCount) - 1; 975b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes auto missingScissorMask = ~pCB->scissorMask & requiredScissorMask; 976b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes if (missingScissorMask) { 977b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes std::stringstream ss; 978b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes ss << "Dynamic scissor(s) "; 979b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes list_bits(ss, missingScissorMask); 980d79335137b414d5f89284a9ab3e014beb4ada3ebMike Weiblen ss << " are used by pipeline state object, but were not provided via calls to vkCmdSetScissor()."; 9813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 9823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS", "%s", ss.str().c_str()); 98329d196e071b2dc1db47702085469396f2b956820Chris Forbes } 98429d196e071b2dc1db47702085469396f2b956820Chris Forbes } 98529d196e071b2dc1db47702085469396f2b956820Chris Forbes } 98629d196e071b2dc1db47702085469396f2b956820Chris Forbes 98729d196e071b2dc1db47702085469396f2b956820Chris Forbes // Verify that any MSAA request in PSO matches sample# in bound FB 98829d196e071b2dc1db47702085469396f2b956820Chris Forbes // Skip the check if rasterization is disabled. 98929d196e071b2dc1db47702085469396f2b956820Chris Forbes if (!pPipeline->graphicsPipelineCI.pRasterizationState || 99029d196e071b2dc1db47702085469396f2b956820Chris Forbes (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) { 99129d196e071b2dc1db47702085469396f2b956820Chris Forbes VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline); 99229d196e071b2dc1db47702085469396f2b956820Chris Forbes if (pCB->activeRenderPass) { 993fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto const render_pass_info = pCB->activeRenderPass->createInfo.ptr(); 99429d196e071b2dc1db47702085469396f2b956820Chris Forbes const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass]; 99529d196e071b2dc1db47702085469396f2b956820Chris Forbes uint32_t i; 99676957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes unsigned subpass_num_samples = 0; 9970a7ed0466d3d3c6c71be07d66c200482d9a9d073Chris Forbes 99829d196e071b2dc1db47702085469396f2b956820Chris Forbes for (i = 0; i < subpass_desc->colorAttachmentCount; i++) { 99976957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes auto attachment = subpass_desc->pColorAttachments[i].attachment; 100076957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes if (attachment != VK_ATTACHMENT_UNUSED) 100176957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes subpass_num_samples |= (unsigned)render_pass_info->pAttachments[attachment].samples; 100229d196e071b2dc1db47702085469396f2b956820Chris Forbes } 10030a7ed0466d3d3c6c71be07d66c200482d9a9d073Chris Forbes 100476957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes if (subpass_desc->pDepthStencilAttachment && 100576957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 100676957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes auto attachment = subpass_desc->pDepthStencilAttachment->attachment; 100776957dd352738b7ceec82c38be8b1b1347a90040Chris Forbes subpass_num_samples |= (unsigned)render_pass_info->pAttachments[attachment].samples; 100829d196e071b2dc1db47702085469396f2b956820Chris Forbes } 1009eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 10100dc3fd4e57b8531638781daa01a2fb5d1048a6fbJamie Madill if (subpass_num_samples && static_cast<unsigned>(pso_num_samples) != subpass_num_samples) { 10113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 10129b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", 10139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Num samples mismatch! At draw-time in Pipeline (0x%" PRIxLEAST64 10149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") with %u samples while current RenderPass (0x%" PRIxLEAST64 ") w/ %u samples!", 10159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), pso_num_samples, 10169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->activeRenderPass->renderPass), subpass_num_samples); 1017eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 101829d196e071b2dc1db47702085469396f2b956820Chris Forbes } else { 10193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 10209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS", 10213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "No active render pass found at draw-time in Pipeline (0x%" PRIxLEAST64 ")!", 10229b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline)); 1023eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 1024eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young } 1025528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis // Verify that PSO creation renderPass is compatible with active renderPass 1026528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis if (pCB->activeRenderPass) { 1027528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis std::string err_string; 1028a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if ((pCB->activeRenderPass->renderPass != pPipeline->graphicsPipelineCI.renderPass) && 102951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(), pPipeline->render_pass_ci.ptr(), 1030528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis err_string)) { 1031528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with 10323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 10339b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", 10349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "At Draw time the active render pass (0x%" PRIxLEAST64 10359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") is incompatible w/ gfx pipeline " 10369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "(0x%" PRIxLEAST64 ") that was created w/ render pass (0x%" PRIxLEAST64 ") due to: %s", 10379b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->activeRenderPass->renderPass), HandleToUint64(pPipeline->pipeline), 10389b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->graphicsPipelineCI.renderPass), err_string.c_str()); 1039528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis } 1040c307df2953e6b023531a6ef7fd11e3ee2f2c58b0Chris Forbes 1041c307df2953e6b023531a6ef7fd11e3ee2f2c58b0Chris Forbes if (pPipeline->graphicsPipelineCI.subpass != pCB->activeSubpass) { 10423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 10439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", 10449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Pipeline was built for subpass %u but used in subpass %u", pPipeline->graphicsPipelineCI.subpass, 10453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCB->activeSubpass); 1046c307df2953e6b023531a6ef7fd11e3ee2f2c58b0Chris Forbes } 1047528f623d935b0ab102a2f9c1c82787a8810ca360Tobin Ehlis } 104829d196e071b2dc1db47702085469396f2b956820Chris Forbes // TODO : Add more checks here 104929d196e071b2dc1db47702085469396f2b956820Chris Forbes 10503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 1051eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young} 1052eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 1053d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes// For given cvdescriptorset::DescriptorSet, verify that its Set is compatible w/ the setLayout corresponding to 1054d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes// pipelineLayout[layoutIndex] 1055d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbesstatic bool verify_set_layout_compatibility(const cvdescriptorset::DescriptorSet *descriptor_set, 1056d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes PIPELINE_LAYOUT_NODE const *pipeline_layout, const uint32_t layoutIndex, 1057d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes string &errorMsg) { 1058d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes auto num_sets = pipeline_layout->set_layouts.size(); 1059d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes if (layoutIndex >= num_sets) { 1060d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes stringstream errorStr; 1061d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes errorStr << "VkPipelineLayout (" << pipeline_layout->layout << ") only contains " << num_sets 1062d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes << " setLayouts corresponding to sets 0-" << num_sets - 1 << ", but you're attempting to bind set to index " 1063d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes << layoutIndex; 1064d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes errorMsg = errorStr.str(); 1065d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes return false; 1066d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes } 1067d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes auto layout_node = pipeline_layout->set_layouts[layoutIndex]; 106888224335ef7965e89477c393331ef5fa628a9335Tobin Ehlis return descriptor_set->IsCompatible(layout_node.get(), &errorMsg); 1069d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes} 1070d7aee1a79b51b1a46cb4f3b0667c24f9416fdd64Chris Forbes 10715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Validate overall state at the time of a draw call 107251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool ValidateDrawState(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, const bool indexed, 10734f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes const VkPipelineBindPoint bind_point, const char *function, 10744f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes UNIQUE_VALIDATION_ERROR_CODE const msg_code) { 1075e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool result = false; 10761c130ea631a82716dc7334de17767536525f2292Tobin Ehlis auto const &state = cb_node->lastBound[bind_point]; 10774c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pPipe = state.pipeline_state; 107822fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis if (nullptr == pPipe) { 107922fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis result |= log_msg( 1080df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 10819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS", 108222fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis "At Draw/Dispatch time no valid VkPipeline is bound! This is illegal. Please bind one with vkCmdBindPipeline()."); 108322fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis // Early return as any further checks below will be busted w/o a pipeline 1084cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (result) return true; 108522fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis } 10863d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis // First check flag states 10871c130ea631a82716dc7334de17767536525f2292Tobin Ehlis if (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) 108851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis result = validate_draw_state_flags(dev_data, cb_node, pPipe, indexed, msg_code); 10897a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis 10905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Now complete other state checks 109169b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis if (VK_NULL_HANDLE != state.pipeline_layout.layout) { 109222fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis string errorString; 109369b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis auto pipeline_layout = pPipe->pipeline_layout; 1094169c4506062f06d6676eb4da3c9e0437d1d9d659Chris Forbes 10951c130ea631a82716dc7334de17767536525f2292Tobin Ehlis for (const auto &set_binding_pair : pPipe->active_slots) { 10961c130ea631a82716dc7334de17767536525f2292Tobin Ehlis uint32_t setIndex = set_binding_pair.first; 109722fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis // If valid set is not bound throw an error 109822fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis if ((state.boundDescriptorSets.size() <= setIndex) || (!state.boundDescriptorSets[setIndex])) { 10999b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus result |= 11009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 11019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_BOUND, "DS", 11029b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "VkPipeline 0x%" PRIxLEAST64 " uses set #%u but that set is not bound.", 11039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipe->pipeline), setIndex); 110412b7fc342b53fbdd399aae4a85959e37685936acChris Forbes } else if (!verify_set_layout_compatibility(state.boundDescriptorSets[setIndex], &pipeline_layout, setIndex, 110569b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis errorString)) { 110669b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis // Set is bound but not compatible w/ overlapping pipeline_layout from PSO 110771511c5a10533c910bfe62c3bcf58e2a4054e7acTobin Ehlis VkDescriptorSet setHandle = state.boundDescriptorSets[setIndex]->GetSet(); 110822fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis result |= 110951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 11109b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(setHandle), __LINE__, DRAWSTATE_PIPELINE_LAYOUTS_INCOMPATIBLE, "DS", 1111414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller "VkDescriptorSet (0x%" PRIxLEAST64 1112414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller ") bound as set #%u is not compatible with overlapping VkPipelineLayout 0x%" PRIxLEAST64 " due to: %s", 11139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(setHandle), setIndex, HandleToUint64(pipeline_layout.layout), errorString.c_str()); 1114cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // Valid set is bound and layout compatible, validate that it's updated 111522fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis // Pull the set node 11161c130ea631a82716dc7334de17767536525f2292Tobin Ehlis cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex]; 11177433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis // Validate the draw-time state for this descriptor set 11187433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis std::string err_str; 11190db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis if (!descriptor_set->ValidateDrawState(set_binding_pair.second, state.dynamicOffsets[setIndex], cb_node, function, 11200db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis &err_str)) { 11211c130ea631a82716dc7334de17767536525f2292Tobin Ehlis auto set = descriptor_set->GetSet(); 11220db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 11239b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(set), __LINE__, 11249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS", 11250db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis "Descriptor set 0x%" PRIxLEAST64 " encountered the following validation error at %s time: %s", 11269b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(set), function, err_str.c_str()); 11277433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis } 11285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 112922fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis } 113022fb3c0393ef588b11f8313f01c508028d77dec0Tobin Ehlis } 1131eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 1132eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young // Check general pipeline state that needs to be validated at drawtime 113351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) result |= ValidatePipelineDrawtimeState(dev_data, state, cb_node, pPipe); 1134eca2d52a6bfa3f9d63a86ca9fd30abc0adf775b7Mark Young 11355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 11365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 11375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 113851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void UpdateDrawState(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, const VkPipelineBindPoint bind_point) { 11391c130ea631a82716dc7334de17767536525f2292Tobin Ehlis auto const &state = cb_state->lastBound[bind_point]; 1140ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis PIPELINE_STATE *pPipe = state.pipeline_state; 1141ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis if (VK_NULL_HANDLE != state.pipeline_layout.layout) { 11421c130ea631a82716dc7334de17767536525f2292Tobin Ehlis for (const auto &set_binding_pair : pPipe->active_slots) { 11431c130ea631a82716dc7334de17767536525f2292Tobin Ehlis uint32_t setIndex = set_binding_pair.first; 1144ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis // Pull the set node 11451c130ea631a82716dc7334de17767536525f2292Tobin Ehlis cvdescriptorset::DescriptorSet *descriptor_set = state.boundDescriptorSets[setIndex]; 1146ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis // Bind this set and its active descriptor resources to the command buffer 11471c130ea631a82716dc7334de17767536525f2292Tobin Ehlis descriptor_set->BindCommandBuffer(cb_state, set_binding_pair.second); 11487433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis // For given active slots record updated images & buffers 11491c130ea631a82716dc7334de17767536525f2292Tobin Ehlis descriptor_set->GetStorageUpdates(set_binding_pair.second, &cb_state->updateBuffers, &cb_state->updateImages); 1150ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis } 1151ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis } 115258b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (pPipe->vertexBindingDescriptions.size() > 0) { 115358b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis cb_state->vertex_buffer_used = true; 115458b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis } 1155ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis} 1156ec2ff49aea47929f28679d7bbe598ec439db7bb5Tobin Ehlis 1157a27508babf63d50aea75883a3702979193c23683Mark Young// Validate HW line width capabilities prior to setting requested line width. 115806727c7f56d1080aff506a9ae1ae9d8c174b3e9dMark Lobodzinskistatic bool verifyLineWidth(layer_data *dev_data, DRAW_STATE_ERROR dsError, VulkanObjectType object_type, const uint64_t &target, 115906727c7f56d1080aff506a9ae1ae9d8c174b3e9dMark Lobodzinski float lineWidth) { 11603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1161a27508babf63d50aea75883a3702979193c23683Mark Young 1162a27508babf63d50aea75883a3702979193c23683Mark Young // First check to see if the physical device supports wide lines. 116351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if ((VK_FALSE == dev_data->enabled_features.wideLines) && (1.0f != lineWidth)) { 11643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], target, __LINE__, 11653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski dsError, "DS", 11663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attempt to set lineWidth to %f but physical device wideLines feature " 11673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "not supported/enabled so lineWidth must be 1.0f!", 11683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski lineWidth); 1169a27508babf63d50aea75883a3702979193c23683Mark Young } else { 1170a27508babf63d50aea75883a3702979193c23683Mark Young // Otherwise, make sure the width falls in the valid range. 117151ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if ((dev_data->phys_dev_properties.properties.limits.lineWidthRange[0] > lineWidth) || 117251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis (dev_data->phys_dev_properties.properties.limits.lineWidthRange[1] < lineWidth)) { 11733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object_type], target, 11743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, dsError, "DS", 11753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attempt to set lineWidth to %f but physical device limits line width " 11763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "to between [%f, %f]!", 11773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski lineWidth, dev_data->phys_dev_properties.properties.limits.lineWidthRange[0], 11783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski dev_data->phys_dev_properties.properties.limits.lineWidthRange[1]); 1179a27508babf63d50aea75883a3702979193c23683Mark Young } 1180a27508babf63d50aea75883a3702979193c23683Mark Young } 1181a27508babf63d50aea75883a3702979193c23683Mark Young 11823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 1183a27508babf63d50aea75883a3702979193c23683Mark Young} 1184a27508babf63d50aea75883a3702979193c23683Mark Young 11852f521eee4ccb1c84512ea767880df8f38751c0d4Chris Forbesstatic bool ValidatePipelineLocked(layer_data *dev_data, std::vector<PIPELINE_STATE *> const &pPipelines, int pipelineIndex) { 11863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 11875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 11884c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pPipeline = pPipelines[pipelineIndex]; 11895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 11905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If create derivative bit is set, check that we've specified a base 11915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // pipeline correctly, and that the base pipeline was created to allow 11925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // derivatives. 11935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) { 11944c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pBasePipeline = nullptr; 11955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!((pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) ^ 11965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (pPipeline->graphicsPipelineCI.basePipelineIndex != -1))) { 1197315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // This check is a superset of VALIDATION_ERROR_096005a8 and VALIDATION_ERROR_096005aa 11983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 11999b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", 12009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid Pipeline CreateInfo: exactly one of base pipeline index and handle must be specified"); 12015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (pPipeline->graphicsPipelineCI.basePipelineIndex != -1) { 12025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline->graphicsPipelineCI.basePipelineIndex >= pipelineIndex) { 12033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 1204df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1205315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_208005a0, "DS", 1206f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt "Invalid Pipeline CreateInfo: base pipeline must occur earlier in array than derivative pipeline. %s", 1207315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_208005a0]); 12085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 12095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pBasePipeline = pPipelines[pPipeline->graphicsPipelineCI.basePipelineIndex]; 12105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) { 121251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis pBasePipeline = getPipelineState(dev_data, pPipeline->graphicsPipelineCI.basePipelineHandle); 12135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 12155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pBasePipeline && !(pBasePipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT)) { 12163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 12179b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", 12189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid Pipeline CreateInfo: base pipeline does not allow derivatives."); 12195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1222c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes return skip; 1223c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes} 1224c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 1225c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes// UNLOCKED pipeline validation. DO NOT lookup objects in the layer_data->* maps in this function. 1226c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbesstatic bool ValidatePipelineUnlocked(layer_data *dev_data, std::vector<PIPELINE_STATE *> const &pPipelines, int pipelineIndex) { 1227c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes bool skip = false; 1228c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 1229c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes PIPELINE_STATE *pPipeline = pPipelines[pipelineIndex]; 1230c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 1231fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes // Ensure the subpass index is valid. If not, then validate_and_capture_pipeline_shader_state 1232fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes // produces nonsense errors that confuse users. Other layers should already 1233fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes // emit errors for renderpass being invalid. 1234146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes auto subpass_desc = &pPipeline->render_pass_ci.pSubpasses[pPipeline->graphicsPipelineCI.subpass]; 1235146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes if (pPipeline->graphicsPipelineCI.subpass >= pPipeline->render_pass_ci.subpassCount) { 1236fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1237fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005ee, "DS", 1238fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes "Invalid Pipeline CreateInfo State: Subpass index %u " 1239fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes "is out of range for this renderpass (0..%u). %s", 1240146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes pPipeline->graphicsPipelineCI.subpass, pPipeline->render_pass_ci.subpassCount - 1, 1241fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes validation_error_map[VALIDATION_ERROR_096005ee]); 1242146a87545e7b707b1dbddbd9cb8b41869ad402ccChris Forbes subpass_desc = nullptr; 1243fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes } 1244fa30cd33537b2773dae129822b4e7c654a027929Chris Forbes 12455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pPipeline->graphicsPipelineCI.pColorBlendState != NULL) { 1246fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis const safe_VkPipelineColorBlendStateCreateInfo *color_blend_state = pPipeline->graphicsPipelineCI.pColorBlendState; 1247fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis if (color_blend_state->attachmentCount != subpass_desc->colorAttachmentCount) { 12483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 124951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1250315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005d4, "DS", 1251fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis "vkCreateGraphicsPipelines(): Render pass (0x%" PRIxLEAST64 1252fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis ") subpass %u has colorAttachmentCount of %u which doesn't match the pColorBlendState->attachmentCount of %u. %s", 12539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->graphicsPipelineCI.renderPass), pPipeline->graphicsPipelineCI.subpass, 1254fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis subpass_desc->colorAttachmentCount, color_blend_state->attachmentCount, 1255315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005d4]); 1256fb4e70f35eef785ce77fca908d4d64f60539893dTobin Ehlis } 125751ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (!dev_data->enabled_features.independentBlend) { 12583d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (pPipeline->attachments.size() > 1) { 125926c548826ff0f83d12c769b51e7d6f76d1265c0eChris Forbes VkPipelineColorBlendAttachmentState *pAttachments = &pPipeline->attachments[0]; 1260c7bd67f06427b08ba65cdf2dd529c8234beebdd5Mark Lobodzinski for (size_t i = 1; i < pPipeline->attachments.size(); i++) { 126106811df0256552cd7da9d7297672af377463fc4aMark Mueller // Quoting the spec: "If [the independent blend] feature is not enabled, the VkPipelineColorBlendAttachmentState 126206811df0256552cd7da9d7297672af377463fc4aMark Mueller // settings for all color attachments must be identical." VkPipelineColorBlendAttachmentState contains 126306811df0256552cd7da9d7297672af377463fc4aMark Mueller // only attachment state, so memcmp is best suited for the comparison 126406811df0256552cd7da9d7297672af377463fc4aMark Mueller if (memcmp(static_cast<const void *>(pAttachments), static_cast<const void *>(&pAttachments[i]), 126506811df0256552cd7da9d7297672af377463fc4aMark Mueller sizeof(pAttachments[0]))) { 12663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 1267df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1268315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_0f4004ba, "DS", 1269df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "Invalid Pipeline CreateInfo: If independent blend feature not " 1270df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "enabled, all elements of pAttachments must be identical. %s", 1271315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0f4004ba]); 127206811df0256552cd7da9d7297672af377463fc4aMark Mueller break; 1273c7bd67f06427b08ba65cdf2dd529c8234beebdd5Mark Lobodzinski } 12745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 127751ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (!dev_data->enabled_features.logicOp && (pPipeline->graphicsPipelineCI.pColorBlendState->logicOpEnable != VK_FALSE)) { 12783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 1279df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1280315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_0f4004bc, "DS", 1281f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt "Invalid Pipeline CreateInfo: If logic operations feature not enabled, logicOpEnable must be VK_FALSE. %s", 1282315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0f4004bc]); 12835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 12855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 128659ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis if (validate_and_capture_pipeline_shader_state(dev_data, pPipeline)) { 12873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = true; 12885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 128952156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes // Each shader's stage must be unique 129052156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes if (pPipeline->duplicate_shaders) { 129152156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes for (uint32_t stage = VK_SHADER_STAGE_VERTEX_BIT; stage & VK_SHADER_STAGE_ALL_GRAPHICS; stage <<= 1) { 129252156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes if (pPipeline->duplicate_shaders & stage) { 12939b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 12949b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", 12959b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid Pipeline CreateInfo State: Multiple shaders provided for stage %s", 12969b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus string_VkShaderStageFlagBits(VkShaderStageFlagBits(stage))); 129752156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes } 129852156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes } 129952156ec29c88c0e52eb89fb42867adacb1dd31bbChris Forbes } 13005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // VS is required 13015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) { 1302315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1303315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005ae, "DS", 1304315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "Invalid Pipeline CreateInfo State: Vertex Shader required. %s", 1305315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005ae]); 13065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Either both or neither TC/TE shaders should be defined 13083067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton bool has_control = (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0; 13093067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton bool has_eval = (pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0; 13103067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (has_control && !has_eval) { 13113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1312315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005b2, "DS", 13133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair. %s", 1314315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005b2]); 1315f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt } 13163067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (!has_control && has_eval) { 13173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1318315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005b4, "DS", 13193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: TE and TC shaders must be included or excluded as a pair. %s", 1320315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005b4]); 13215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Compute shaders should be specified independent of Gfx shaders 1323f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt if (pPipeline->active_shaders & VK_SHADER_STAGE_COMPUTE_BIT) { 13243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1325315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005b0, "DS", 13263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: Do not specify Compute Shader for Gfx Pipeline. %s", 1327315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005b0]); 13285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive topology is only valid for tessellation pipelines. 13305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Mismatching primitive topology and tessellation fails graphics pipeline creation. 13313067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (has_control && has_eval && 1332ca546210846c65808717f8875deae39bd227c240Tobin Ehlis (!pPipeline->graphicsPipelineCI.pInputAssemblyState || 1333ca546210846c65808717f8875deae39bd227c240Tobin Ehlis pPipeline->graphicsPipelineCI.pInputAssemblyState->topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST)) { 13343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1335315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005c0, "DS", 13363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: " 13373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST must be set as IA " 13383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "topology for tessellation pipelines. %s", 1339315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005c0]); 13405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1341ca546210846c65808717f8875deae39bd227c240Tobin Ehlis if (pPipeline->graphicsPipelineCI.pInputAssemblyState && 1342ca546210846c65808717f8875deae39bd227c240Tobin Ehlis pPipeline->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) { 13433067e46adf202d2cc3ce1e06909dc7fadf0c8c3bCort Stratton if (!has_control || !has_eval) { 13443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1345315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005c2, "DS", 13463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: " 13473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_PRIMITIVE_TOPOLOGY_PATCH_LIST primitive " 13483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "topology is only valid for tessellation pipelines. %s", 1349315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005c2]); 13505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 13515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1352f62c50f00d7d03e27fbc3769e582761e8a4944ddMike Schuchardt 13536b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // If a rasterization state is provided... 1354a27508babf63d50aea75883a3702979193c23683Mark Young if (pPipeline->graphicsPipelineCI.pRasterizationState) { 13556b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // Make sure that the line width conforms to the HW. 1356a27508babf63d50aea75883a3702979193c23683Mark Young if (!isDynamic(pPipeline, VK_DYNAMIC_STATE_LINE_WIDTH)) { 13579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 13589b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus verifyLineWidth(dev_data, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, kVulkanObjectTypePipeline, 13599b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), pPipeline->graphicsPipelineCI.pRasterizationState->lineWidth); 1360a27508babf63d50aea75883a3702979193c23683Mark Young } 13615dcdd90e54199dfeb29938a3a03d998397c22664Chris Forbes 136258c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski if ((pPipeline->graphicsPipelineCI.pRasterizationState->depthClampEnable == VK_TRUE) && 136358c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski (!dev_data->enabled_features.depthClamp)) { 13643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1365315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_1020061c, "DS", 13663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateGraphicsPipelines(): the depthClamp device feature is disabled: the depthClampEnable " 13673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "member of the VkPipelineRasterizationStateCreateInfo structure must be set to VK_FALSE. %s", 1368315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1020061c]); 136958c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski } 137058c5552c73679f81f57a64a809f7d4d6d52f4ce3Mark Lobodzinski 1371434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski if (!isDynamic(pPipeline, VK_DYNAMIC_STATE_DEPTH_BIAS) && 1372434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski (pPipeline->graphicsPipelineCI.pRasterizationState->depthBiasClamp != 0.0) && 1373434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski (!dev_data->enabled_features.depthBiasClamp)) { 13743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 13759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_FEATURE, "DS", 13763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateGraphicsPipelines(): the depthBiasClamp device feature is disabled: the depthBiasClamp " 13773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "member of the VkPipelineRasterizationStateCreateInfo structure must be set to 0.0 unless the " 13783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state is enabled"); 1379434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski } 1380434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski 13816b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // If rasterization is enabled... 13826b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen if (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE) { 1383148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski if ((pPipeline->graphicsPipelineCI.pMultisampleState->alphaToOneEnable == VK_TRUE) && 1384148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski (!dev_data->enabled_features.alphaToOne)) { 13853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1386315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_10000622, "DS", 13873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateGraphicsPipelines(): the alphaToOne device feature is disabled: the alphaToOneEnable " 13883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "member of the VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE. %s", 1389315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_10000622]); 1390148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski } 1391148e8028deee2b4b00ccd4a69210897add328265Mark Lobodzinski 13926b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen // If subpass uses a depth/stencil attachment, pDepthStencilState must be a pointer to a valid structure 13936b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen if (subpass_desc && subpass_desc->pDepthStencilAttachment && 13946b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 13956b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen if (!pPipeline->graphicsPipelineCI.pDepthStencilState) { 13963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1397315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005e0, "DS", 13983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: pDepthStencilState is NULL when rasterization is " 13993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "enabled and subpass uses a depth/stencil attachment. %s", 1400315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005e0]); 14019580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski 14029580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski } else if ((pPipeline->graphicsPipelineCI.pDepthStencilState->depthBoundsTestEnable == VK_TRUE) && 14039580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski (!dev_data->enabled_features.depthBounds)) { 14043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 1405df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 14069b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPipeline->pipeline), __LINE__, DRAWSTATE_INVALID_FEATURE, "DS", 14079580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski "vkCreateGraphicsPipelines(): the depthBounds device feature is disabled: the depthBoundsTestEnable " 14089580629edfc5154cc9e36974cca12966fbd748b9Mark Lobodzinski "member of the VkPipelineDepthStencilStateCreateInfo structure must be set to VK_FALSE."); 14096b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen } 14105dcdd90e54199dfeb29938a3a03d998397c22664Chris Forbes } 1411326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen 1412326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen // If subpass uses color attachments, pColorBlendState must be valid pointer 1413326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen if (subpass_desc) { 1414326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen uint32_t color_attachment_count = 0; 1415326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen for (uint32_t i = 0; i < subpass_desc->colorAttachmentCount; ++i) { 1416326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen if (subpass_desc->pColorAttachments[i].attachment != VK_ATTACHMENT_UNUSED) { 1417326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen ++color_attachment_count; 1418326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 1419326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 1420326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen if (color_attachment_count > 0 && pPipeline->graphicsPipelineCI.pColorBlendState == nullptr) { 14213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 1422315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPipeline->pipeline), __LINE__, VALIDATION_ERROR_096005e2, "DS", 14233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Invalid Pipeline CreateInfo State: pColorBlendState is NULL when rasterization is " 14243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "enabled and subpass uses color attachments. %s", 1425315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_096005e2]); 1426326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 1427326fc9f00659303e0a5b3fc4019db2bda641c7bdMike Weiblen } 14285dcdd90e54199dfeb29938a3a03d998397c22664Chris Forbes } 14295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 14306b8d2b83e8400e5238705a0856b5e3acff8df742Mike Weiblen 1431740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes auto vi = pPipeline->graphicsPipelineCI.pVertexInputState; 1432740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes if (vi != NULL) { 1433740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes for (uint32_t j = 0; j < vi->vertexAttributeDescriptionCount; j++) { 1434740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes VkFormat format = vi->pVertexAttributeDescriptions[j].format; 1435740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes // Internal call to get format info. Still goes through layers, could potentially go directly to ICD. 1436740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes VkFormatProperties properties; 1437740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes dev_data->instance_data->dispatch_table.GetPhysicalDeviceFormatProperties(dev_data->physical_device, format, &properties); 1438740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes if ((properties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0) { 1439740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes skip |= log_msg( 1440740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 1441740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes __LINE__, VALIDATION_ERROR_14a004de, "IMAGE", 1442740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes "vkCreateGraphicsPipelines: pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].format " 1443740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes "(%s) is not a supported vertex buffer format. %s", 1444740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes pipelineIndex, j, string_VkFormat(format), validation_error_map[VALIDATION_ERROR_14a004de]); 1445740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes } 1446740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes } 1447740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes } 1448740a9cdda3aa9cc7a4124184bd58146e6e99d772Chris Forbes 14493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 14505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 14515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 14525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Free the Pipeline nodes 145351ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void deletePipelines(layer_data *dev_data) { 145451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (dev_data->pipelineMap.size() <= 0) return; 145551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis for (auto &pipe_map_pair : dev_data->pipelineMap) { 1456ca546210846c65808717f8875deae39bd227c240Tobin Ehlis delete pipe_map_pair.second; 14575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 145851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->pipelineMap.clear(); 14595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 14605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 14615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Block of code at start here specifically for managing/tracking DSs 14625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 14635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Return Pool node ptr for specified pool or else NULL 14649a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisDESCRIPTOR_POOL_STATE *GetDescriptorPoolState(const layer_data *dev_data, const VkDescriptorPool pool) { 1465bb7ea477706f90eb2a72887f652795bc79f60ddeTobin Ehlis auto pool_it = dev_data->descriptorPoolMap.find(pool); 1466bb7ea477706f90eb2a72887f652795bc79f60ddeTobin Ehlis if (pool_it == dev_data->descriptorPoolMap.end()) { 14675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 14685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1469bb7ea477706f90eb2a72887f652795bc79f60ddeTobin Ehlis return pool_it->second; 14705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 14715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 14725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Validate that given set is valid and that it's not being used by an in-flight CmdBuffer 14735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// func_str is the name of the calling function 1474e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves// Return false if no errors occur 1475e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves// Return true if validation error occurs and callback returns true (to skip upcoming API call down the chain) 14760dcd0f7b37456e2e552d37094ba503c0d089b906Tobin Ehlisstatic bool validateIdleDescriptorSet(const layer_data *dev_data, VkDescriptorSet set, std::string func_str) { 1477cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.idle_descriptor_set) return false; 14783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 14790dcd0f7b37456e2e552d37094ba503c0d089b906Tobin Ehlis auto set_node = dev_data->setMap.find(set); 14800dcd0f7b37456e2e552d37094ba503c0d089b906Tobin Ehlis if (set_node == dev_data->setMap.end()) { 14813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 14829b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(set), __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS", 14833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that has not been allocated.", func_str.c_str(), 14849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(set)); 14855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 14861c48e214b2ed50690da7f42f2013be3a6ef267dfTobin Ehlis // TODO : This covers various error cases so should pass error enum into this function and use passed in enum here 14875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (set_node->second->in_use.load()) { 14883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 1489315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(set), __LINE__, VALIDATION_ERROR_2860026a, "DS", 14903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that is in use by a command buffer. %s", 1491315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_str.c_str(), HandleToUint64(set), validation_error_map[VALIDATION_ERROR_2860026a]); 14925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 14935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 14943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 14955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 1496f80bf38f4fb3f177b3e1be11b7b1c5edcdbf7d9bChris Forbes 1497e6651096ed8f07840447783c66827cc16d659a49Tobin Ehlis// Remove set from setMap and delete the set 14989dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlisstatic void freeDescriptorSet(layer_data *dev_data, cvdescriptorset::DescriptorSet *descriptor_set) { 14999dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlis dev_data->setMap.erase(descriptor_set->GetSet()); 15009dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlis delete descriptor_set; 15019dd448578d59cb5ce692e833ba230783b30f3550Tobin Ehlis} 15025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Free all DS Pools including their Sets & related sub-structs 15035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// NOTE : Calls to this function should be wrapped in mutex 150451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void deletePools(layer_data *dev_data) { 1505ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson for (auto ii = dev_data->descriptorPoolMap.begin(); ii != dev_data->descriptorPoolMap.end();) { 1506c5f47f0a54e14c47d402aeabc6498d981ecda9ccTobin Ehlis // Remove this pools' sets from setMap and delete them 1507ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson for (auto ds : ii->second->sets) { 150851ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis freeDescriptorSet(dev_data, ds); 15095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1510ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson ii->second->sets.clear(); 1511ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson delete ii->second; 1512ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson ii = dev_data->descriptorPoolMap.erase(ii); 15135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 15145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 151651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void clearDescriptorPool(layer_data *dev_data, const VkDevice device, const VkDescriptorPool pool, 15175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkDescriptorPoolResetFlags flags) { 15189a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DESCRIPTOR_POOL_STATE *pPool = GetDescriptorPoolState(dev_data, pool); 1519de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis // TODO: validate flags 1520de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet 1521de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis for (auto ds : pPool->sets) { 152251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis freeDescriptorSet(dev_data, ds); 1523de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis } 1524de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis pPool->sets.clear(); 1525de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis // Reset available count for each type and available sets for this pool 1526de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis for (uint32_t i = 0; i < pPool->availableDescriptorTypeCount.size(); ++i) { 1527de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis pPool->availableDescriptorTypeCount[i] = pPool->maxDescriptorTypeCount[i]; 15285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 1529de7672b6b749c09c5991bd8038b3a35ef82a69dcTobin Ehlis pPool->availableSets = pPool->maxSets; 15305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 15325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// For given CB object, fetch associated CB Node from map 15339a9a0db2a973034d4286b6d4c62a46beb7641791Tobin EhlisGLOBAL_CB_NODE *GetCBNode(layer_data const *dev_data, const VkCommandBuffer cb) { 153451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto it = dev_data->commandBufferMap.find(cb); 153551ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (it == dev_data->commandBufferMap.end()) { 15365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return NULL; 15375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 15385121a8dcacb23766ba4455b4eea429f0a3d62099Chris Forbes return it->second; 15395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 154129f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlis// If a renderpass is active, verify that the given command type is appropriate for current subpass state 154229f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlisbool ValidateCmdSubpassState(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, const CMD_TYPE cmd_type) { 1543cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!pCB->activeRenderPass) return false; 15443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1545d0d8e333806eaac08bdc87ddeff886dc2b0f09e7Tobin Ehlis if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS && 1546d0d8e333806eaac08bdc87ddeff886dc2b0f09e7Tobin Ehlis (cmd_type != CMD_EXECUTECOMMANDS && cmd_type != CMD_NEXTSUBPASS && cmd_type != CMD_ENDRENDERPASS)) { 15473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15489b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 15493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Commands cannot be called in a subpass using secondary command buffers."); 15505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (pCB->activeSubpassContents == VK_SUBPASS_CONTENTS_INLINE && cmd_type == CMD_EXECUTECOMMANDS) { 15513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 15533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() cannot be called in a subpass using inline commands."); 15545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 15553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 15565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1558e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisbool ValidateCmdQueueFlags(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *caller_name, 1559e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis VkQueueFlags required_flags, UNIQUE_VALIDATION_ERROR_CODE error_code) { 1560baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt auto pool = GetCommandPoolNode(dev_data, cb_node->createInfo.commandPool); 1561baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (pool) { 1562baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt VkQueueFlags queue_flags = dev_data->phys_dev_properties.queue_family_properties[pool->queueFamilyIndex].queueFlags; 1563baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (!(required_flags & queue_flags)) { 1564baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt string required_flags_string; 1565baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt for (auto flag : {VK_QUEUE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT, VK_QUEUE_COMPUTE_BIT}) { 1566baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (flag & required_flags) { 1567baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt if (required_flags_string.size()) { 1568baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt required_flags_string += " or "; 1569baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1570baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt required_flags_string += string_VkQueueFlagBits(flag); 1571baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1572baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1573baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, error_code, "DS", 1575baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt "Cannot call %s on a command buffer allocated from a pool without %s capabilities. %s.", caller_name, 1576baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt required_flags_string.c_str(), validation_error_map[error_code]); 1577baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 1578baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt } 15795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return false; 15805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 15815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1582d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbesstatic char const * GetCauseStr(VK_OBJECT obj) { 1583d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes if (obj.type == kVulkanObjectTypeDescriptorSet) 1584d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes return "destroyed or updated"; 1585d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes if (obj.type == kVulkanObjectTypeCommandBuffer) 1586d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes return "destroyed or rerecorded"; 1587d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes return "destroyed"; 1588d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes} 1589d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes 1590e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisstatic bool ReportInvalidCommandBuffer(layer_data *dev_data, const GLOBAL_CB_NODE *cb_state, const char *call_source) { 1591ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski bool skip = false; 1592ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski for (auto obj : cb_state->broken_bindings) { 15937a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski const char *type_str = object_string[obj.type]; 1594d00947f5dcd29a4d8aab59e62f72df50444d2537Chris Forbes const char *cause_str = GetCauseStr(obj); 1595ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 15969b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 1597ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski "You are adding %s to command buffer 0x%p that is invalid because bound %s 0x%" PRIxLEAST64 " was %s.", 1598ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski call_source, cb_state->commandBuffer, type_str, obj.handle, cause_str); 1599ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 1600ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski return skip; 1601ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski} 1602ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 1603623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// Validate the given command being added to the specified cmd buffer, flagging errors if CB is not in the recording state or if 1604623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// there's an issue with the Cmd ordering 1605e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisbool ValidateCmd(layer_data *dev_data, const GLOBAL_CB_NODE *cb_state, const CMD_TYPE cmd, const char *caller_name) { 160633f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes switch (cb_state->state) { 160733f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes case CB_RECORDING: 160833f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes return ValidateCmdSubpassState(dev_data, cb_state, cmd); 160933f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes 161046daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_COMPLETE: 161146daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_INCOMPLETE: 161233f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes return ReportInvalidCommandBuffer(dev_data, cb_state, caller_name); 161333f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes 161433f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes default: 161533f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 16169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_NO_BEGIN_COMMAND_BUFFER, "DS", 161733f3623e8124c3a6081b60f68b9d39a19a5840aeChris Forbes "You must call vkBeginCommandBuffer() before this call to %s", caller_name); 16185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 16195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 162029f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlis 16217e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// For given object struct return a ptr of BASE_NODE type for its wrapping struct 16227e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin EhlisBASE_NODE *GetStateStructPtrFromObject(layer_data *dev_data, VK_OBJECT object_struct) { 16237e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis BASE_NODE *base_ptr = nullptr; 16247e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis switch (object_struct.type) { 1625ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeDescriptorSet: { 16269a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetSetNode(dev_data, reinterpret_cast<VkDescriptorSet &>(object_struct.handle)); 1627cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1628cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1629ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeSampler: { 16309a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetSamplerState(dev_data, reinterpret_cast<VkSampler &>(object_struct.handle)); 1631cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1632cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1633ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeQueryPool: { 16349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetQueryPoolNode(dev_data, reinterpret_cast<VkQueryPool &>(object_struct.handle)); 1635cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1636cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1637ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypePipeline: { 1638cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski base_ptr = getPipelineState(dev_data, reinterpret_cast<VkPipeline &>(object_struct.handle)); 1639cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1640cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1641ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeBuffer: { 16429a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetBufferState(dev_data, reinterpret_cast<VkBuffer &>(object_struct.handle)); 1643cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1644cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1645ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeBufferView: { 16469a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetBufferViewState(dev_data, reinterpret_cast<VkBufferView &>(object_struct.handle)); 1647cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1648cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1649ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeImage: { 16509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetImageState(dev_data, reinterpret_cast<VkImage &>(object_struct.handle)); 1651cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1652cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1653ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeImageView: { 16549a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetImageViewState(dev_data, reinterpret_cast<VkImageView &>(object_struct.handle)); 1655cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1656cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1657ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeEvent: { 16589a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetEventNode(dev_data, reinterpret_cast<VkEvent &>(object_struct.handle)); 1659cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1660cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1661ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeDescriptorPool: { 16629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetDescriptorPoolState(dev_data, reinterpret_cast<VkDescriptorPool &>(object_struct.handle)); 1663cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1664cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1665ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeCommandPool: { 16669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetCommandPoolNode(dev_data, reinterpret_cast<VkCommandPool &>(object_struct.handle)); 1667cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1668cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1669ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeFramebuffer: { 16709a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetFramebufferState(dev_data, reinterpret_cast<VkFramebuffer &>(object_struct.handle)); 1671cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1672cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1673ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeRenderPass: { 16749a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetRenderPassState(dev_data, reinterpret_cast<VkRenderPass &>(object_struct.handle)); 1675cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1676cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1677ed832a346f5de647635da80bcdb95e29634c70d2Chris Forbes case kVulkanObjectTypeDeviceMemory: { 16789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis base_ptr = GetMemObjInfo(dev_data, reinterpret_cast<VkDeviceMemory &>(object_struct.handle)); 1679cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1680cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 1681cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 1682cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // TODO : Any other objects to be handled here? 1683cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(0); 1684cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1685bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis } 16867e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis return base_ptr; 16877e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis} 16887e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis 16897e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// Tie the VK_OBJECT to the cmd buffer which includes: 16907e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// Add object_binding to cmd buffer 16917e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// Add cb_binding to object 16927e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlisstatic void addCommandBufferBinding(std::unordered_set<GLOBAL_CB_NODE *> *cb_bindings, VK_OBJECT obj, GLOBAL_CB_NODE *cb_node) { 16937e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis cb_bindings->insert(cb_node); 16947e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis cb_node->object_bindings.insert(obj); 16957e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis} 16967e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis// For a given object, if cb_node is in that objects cb_bindings, remove cb_node 16977e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlisstatic void removeCommandBufferBinding(layer_data *dev_data, VK_OBJECT const *object, GLOBAL_CB_NODE *cb_node) { 16987e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis BASE_NODE *base_obj = GetStateStructPtrFromObject(dev_data, *object); 1699cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (base_obj) base_obj->cb_bindings.erase(cb_node); 1700bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis} 17015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Reset the command buffer state 17025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Maintain the createInfo and set state to CB_NEW, but clear all other state 1703400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlisstatic void resetCB(layer_data *dev_data, const VkCommandBuffer cb) { 1704400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis GLOBAL_CB_NODE *pCB = dev_data->commandBufferMap[cb]; 17055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 1706b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine pCB->in_use.store(0); 17075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Reset CB state (note that createInfo is not cleared) 17085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->commandBuffer = cb; 17095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis memset(&pCB->beginInfo, 0, sizeof(VkCommandBufferBeginInfo)); 17105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis memset(&pCB->inheritanceInfo, 0, sizeof(VkCommandBufferInheritanceInfo)); 1711b68b13ed4952bce61f6ebb0023542660c26b0562Chris Forbes pCB->hasDrawCmd = false; 17125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->state = CB_NEW; 17135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->submitCount = 0; 17145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status = 0; 1715b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes pCB->viewportMask = 0; 1716b0df98f4fa837a06691c1e3c05b4ed21c7e2d014Chris Forbes pCB->scissorMask = 0; 171793c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 171872d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis for (uint32_t i = 0; i < VK_PIPELINE_BIND_POINT_RANGE_SIZE; ++i) { 171972d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis pCB->lastBound[i].reset(); 172072d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 172193c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 17225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis memset(&pCB->activeRenderPassBeginInfo, 0, sizeof(pCB->activeRenderPassBeginInfo)); 1723ee691f5c5fa87aac3750454d2bca2cb582e4e817Chris Forbes pCB->activeRenderPass = nullptr; 17245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->activeSubpassContents = VK_SUBPASS_CONTENTS_INLINE; 17255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->activeSubpass = 0; 1726e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis pCB->broken_bindings.clear(); 17275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->waitedEvents.clear(); 17285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->events.clear(); 1729c7e6bc41aa9c6e5a677b138b9459b252cd3bedf2Mark Lobodzinski pCB->writeEventsBeforeWait.clear(); 17305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->waitedEventsBeforeQueryReset.clear(); 17315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->queryToStateMap.clear(); 17325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->activeQueries.clear(); 17335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->startedQueries.clear(); 17345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->imageLayoutMap.clear(); 17355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->eventToStageMap.clear(); 17365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->drawData.clear(); 17375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->currentDrawData.buffers.clear(); 173858b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis pCB->vertex_buffer_used = false; 17395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->primaryCommandBuffer = VK_NULL_HANDLE; 17401a3660584634742a3297915c94768d73f360e794Chris Forbes // If secondary, invalidate any primary command buffer that may call us. 17411a3660584634742a3297915c94768d73f360e794Chris Forbes if (pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) { 17421a3660584634742a3297915c94768d73f360e794Chris Forbes invalidateCommandBuffers(dev_data, 17431a3660584634742a3297915c94768d73f360e794Chris Forbes pCB->linkedCommandBuffers, 17441a3660584634742a3297915c94768d73f360e794Chris Forbes {HandleToUint64(cb), kVulkanObjectTypeCommandBuffer}); 17451a3660584634742a3297915c94768d73f360e794Chris Forbes } 17461a3660584634742a3297915c94768d73f360e794Chris Forbes 17471a3660584634742a3297915c94768d73f360e794Chris Forbes // Remove reverse command buffer links. 17481a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto pSubCB : pCB->linkedCommandBuffers) { 17491a3660584634742a3297915c94768d73f360e794Chris Forbes pSubCB->linkedCommandBuffers.erase(pCB); 17501a3660584634742a3297915c94768d73f360e794Chris Forbes } 17511a3660584634742a3297915c94768d73f360e794Chris Forbes pCB->linkedCommandBuffers.clear(); 17527a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis pCB->updateImages.clear(); 17537a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis pCB->updateBuffers.clear(); 1754400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis clear_cmd_buf_and_mem_references(dev_data, pCB); 17557974f09e53c82a1d5ae164be83c0b88a92ab8ee5Chris Forbes pCB->validate_functions.clear(); 175679fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis pCB->cmd_execute_commands_functions.clear(); 1757b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine pCB->eventUpdates.clear(); 1758d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine pCB->queryUpdates.clear(); 175993c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 1760bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis // Remove object bindings 1761bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis for (auto obj : pCB->object_bindings) { 1762bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis removeCommandBufferBinding(dev_data, &obj, pCB); 1763bf66bca5d96f2721897c5f3100da2df741da9addTobin Ehlis } 1764a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis pCB->object_bindings.clear(); 176593c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski // Remove this cmdBuffer's reference from each FrameBuffer's CB ref list 176693c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski for (auto framebuffer : pCB->framebuffers) { 17679a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fb_state = GetFramebufferState(dev_data, framebuffer); 1768cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (fb_state) fb_state->cb_bindings.erase(pCB); 176993c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski } 177093c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski pCB->framebuffers.clear(); 17717003b38da5cc27a063af3c45080f3a35438283eeTobin Ehlis pCB->activeFramebuffer = VK_NULL_HANDLE; 17725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 17735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 17745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 17755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Set PSO-related status bits for CB, including dynamic state set via PSO 17764c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic void set_cb_pso_status(GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe) { 17775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Account for any dynamic state not set via this PSO 1778ca546210846c65808717f8875deae39bd227c240Tobin Ehlis if (!pPipe->graphicsPipelineCI.pDynamicState || 1779cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski !pPipe->graphicsPipelineCI.pDynamicState->dynamicStateCount) { // All state is static 17804052946ae557337ff95f3725e879131b1c63f865Tobin Ehlis pCB->status |= CBSTATUS_ALL_STATE_SET; 17815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 17825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // First consider all state on 17835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Then unset any state that's noted as dynamic in PSO 17845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Finally OR that into CB statemask 17854052946ae557337ff95f3725e879131b1c63f865Tobin Ehlis CBStatusFlags psoDynStateMask = CBSTATUS_ALL_STATE_SET; 1786ca546210846c65808717f8875deae39bd227c240Tobin Ehlis for (uint32_t i = 0; i < pPipe->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) { 1787ca546210846c65808717f8875deae39bd227c240Tobin Ehlis switch (pPipe->graphicsPipelineCI.pDynamicState->pDynamicStates[i]) { 1788cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_LINE_WIDTH: 1789cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_LINE_WIDTH_SET; 1790cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1791cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_DEPTH_BIAS: 1792cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_DEPTH_BIAS_SET; 1793cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1794cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_BLEND_CONSTANTS: 1795cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_BLEND_CONSTANTS_SET; 1796cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1797cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_DEPTH_BOUNDS: 1798cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_DEPTH_BOUNDS_SET; 1799cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1800cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: 1801cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_STENCIL_READ_MASK_SET; 1802cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1803cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: 1804cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_STENCIL_WRITE_MASK_SET; 1805cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1806cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case VK_DYNAMIC_STATE_STENCIL_REFERENCE: 1807cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski psoDynStateMask &= ~CBSTATUS_STENCIL_REFERENCE_SET; 1808cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 1809cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 1810cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // TODO : Flag error here 1811cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 18125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status |= psoDynStateMask; 18155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 18175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1818623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// Flags validation error if the associated call is made inside a render pass. The apiName routine should ONLY be called outside a 1819623784ad78c8b77a78c4db613db974c12e5f5a43Mark Lobodzinski// render pass. 1820e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisbool insideRenderPass(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, const char *apiName, 1821e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE msgCode) { 1822e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool inside = false; 18235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->activeRenderPass) { 182451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis inside = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 18259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, msgCode, "DS", 1826ff97d1b78192ab7853965cd7a0462273c4813333Mike Weiblen "%s: It is invalid to issue this call inside an active render pass (0x%" PRIxLEAST64 "). %s", apiName, 18279b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->activeRenderPass->renderPass), validation_error_map[msgCode]); 18285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return inside; 18305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 18315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 18325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Flags validation error if the associated call is made outside a render pass. The apiName 18335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// routine should ONLY be called inside a render pass. 183451ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisbool outsideRenderPass(const layer_data *dev_data, GLOBAL_CB_NODE *pCB, const char *apiName, UNIQUE_VALIDATION_ERROR_CODE msgCode) { 1835e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool outside = false; 18365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (((pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) && (!pCB->activeRenderPass)) || 18375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ((pCB->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) && (!pCB->activeRenderPass) && 18385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT))) { 183951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis outside = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 18409b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, msgCode, "DS", 1841ff97d1b78192ab7853965cd7a0462273c4813333Mike Weiblen "%s: This call must be issued inside an active render pass. %s", apiName, validation_error_map[msgCode]); 18425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 18435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return outside; 18445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 18455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1846f0f7d8aa2286bd7516d9fb5c2e58890505e3e5d4Chris Forbesstatic void init_core_validation(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) { 1847b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "lunarg_core_validation"); 18485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 18495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 18507a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis// For the given ValidationCheck enum, set all relevant instance disabled flags to true 18517a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlisvoid SetDisabledFlags(instance_layer_data *instance_data, VkValidationFlagsEXT *val_flags_struct) { 18527a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis for (uint32_t i = 0; i < val_flags_struct->disabledValidationCheckCount; ++i) { 18537a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis switch (val_flags_struct->pDisabledValidationChecks[i]) { 185459ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis case VK_VALIDATION_CHECK_SHADERS_EXT: 185559ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis instance_data->disabled.shader_validation = true; 185659ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis break; 18577a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis case VK_VALIDATION_CHECK_ALL_EXT: 18587a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Set all disabled flags to true 18597a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis instance_data->disabled.SetAll(true); 18607a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis break; 18617a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis default: 18627a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis break; 18637a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 18647a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 18657a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis} 18667a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis 1867bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, 1868bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkInstance *pInstance) { 18695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 18705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 18715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis assert(chain_info->u.pLayerInfo); 18725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 18735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); 1874cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (fpCreateInstance == NULL) return VK_ERROR_INITIALIZATION_FAILED; 18755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 18765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Advance the link info for the next element on the chain 18775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 18785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 18795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); 1880cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (result != VK_SUCCESS) return result; 18815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 188256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), instance_layer_data_map); 188356a5ba3e60a723781945959ffc10e2e215350de5Chia-I Wu instance_data->instance = *pInstance; 18849172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr); 18859172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->report_data = debug_report_create_instance( 18869172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes &instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); 18870cf009a4e2a5c22e4645f343c7a998f188a22015Chris Forbes instance_data->extensions.InitFromInstanceCreateInfo(pCreateInfo); 1888b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis init_core_validation(instance_data, pAllocator); 1889825ac70f99460ccb9494d34f93d8ee7ec303e5deMark Lobodzinski 18905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ValidateLayerOrdering(*pCreateInfo); 18917a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Parse any pNext chains 18927a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis if (pCreateInfo->pNext) { 18937a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis GENERIC_HEADER *struct_header = (GENERIC_HEADER *)pCreateInfo->pNext; 18947a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis while (struct_header) { 18957a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Check for VkValidationFlagsExt 18967a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis if (VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT == struct_header->sType) { 18977a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis SetDisabledFlags(instance_data, (VkValidationFlagsEXT *)struct_header); 18987a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 18997a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis struct_header = (GENERIC_HEADER *)struct_header->pNext; 19007a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 19017a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis } 19025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 19045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 19055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 190625002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski// Hook DestroyInstance to remove tableInstanceMap entry 190789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { 19085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODOSC : Shouldn't need any customization here 19095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dispatch_key key = get_dispatch_key(instance); 19105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TBD: Need any locking this early, in case this function is called at the 19115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // same time by more than one thread? 191256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(key, instance_layer_data_map); 19139172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->dispatch_table.DestroyInstance(instance, pAllocator); 19145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1915ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 19165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Clean up logging callback, if any 19179172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes while (instance_data->logging_callback.size() > 0) { 19189172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes VkDebugReportCallbackEXT callback = instance_data->logging_callback.back(); 19199172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator); 19209172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->logging_callback.pop_back(); 19215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 19225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19239172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes layer_debug_report_destroy_instance(instance_data->report_data); 1924d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson FreeLayerDataPtr(key, instance_layer_data_map); 19255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 19265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 19275770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstatic bool ValidatePhysicalDeviceQueueFamily(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state, 19285770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t requested_queue_family, int32_t err_code, const char *cmd_name, 19295770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const char *queue_family_var_name, const char *vu_note = nullptr) { 19303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 19315770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19325770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (!vu_note) vu_note = validation_error_map[err_code]; 19335770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19345770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const char *conditional_ext_cmd = 1935d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski instance_data->extensions.vk_khr_get_physical_device_properties_2 ? "or vkGetPhysicalDeviceQueueFamilyProperties2KHR" : ""; 19365770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19375770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::string count_note = (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) 19385770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ? "the pQueueFamilyPropertyCount was never obtained" 19395770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus : "i.e. is not less than " + std::to_string(pd_state->queue_family_count); 19405770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19415770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (requested_queue_family >= pd_state->queue_family_count) { 19423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 19439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pd_state->phys_device), __LINE__, err_code, "DL", 19449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s: %s (= %" PRIu32 19459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") is not less than any previously obtained pQueueFamilyPropertyCount from " 19465770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "vkGetPhysicalDeviceQueueFamilyProperties%s (%s). %s", 19475770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus cmd_name, queue_family_var_name, requested_queue_family, conditional_ext_cmd, count_note.c_str(), vu_note); 19485770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus } 19495770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return skip; 19505770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus} 19515770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19525770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus// Verify VkDeviceQueueCreateInfos 19535770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstatic bool ValidateDeviceQueueCreateInfos(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state, 19545770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t info_count, const VkDeviceQueueCreateInfo *infos) { 19555770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus bool skip = false; 19565770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19575770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus for (uint32_t i = 0; i < info_count; ++i) { 19585770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const auto requested_queue_family = infos[i].queueFamilyIndex; 19595770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19605770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Verify that requested queue family is known to be valid at this point in time 19615770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::string queue_family_var_name = "pCreateInfo->pQueueCreateInfos[" + std::to_string(i) + "].queueFamilyIndex"; 1962315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, requested_queue_family, VALIDATION_ERROR_06c002fa, 19635770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "vkCreateDevice", queue_family_var_name.c_str()); 19645770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19655770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Verify that requested queue count of queue family is known to be valid at this point in time 19665770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (requested_queue_family < pd_state->queue_family_count) { 19675770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const auto requested_queue_count = infos[i].queueCount; 19685770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const auto queue_family_props_count = pd_state->queue_family_properties.size(); 19695770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const bool queue_family_has_props = requested_queue_family < queue_family_props_count; 1970d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski const char *conditional_ext_cmd = instance_data->extensions.vk_khr_get_physical_device_properties_2 19715770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ? "or vkGetPhysicalDeviceQueueFamilyProperties2KHR" 19725770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus : ""; 19735770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::string count_note = 19745770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus !queue_family_has_props 19755770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ? "the pQueueFamilyProperties[" + std::to_string(requested_queue_family) + "] was never obtained" 19765770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus : "i.e. is not less than or equal to " + 19775770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus std::to_string(pd_state->queue_family_properties[requested_queue_family].queueCount); 19785770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19795770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (!queue_family_has_props || 19805770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus requested_queue_count > pd_state->queue_family_properties[requested_queue_family].queueCount) { 19813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 19829b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(pd_state->phys_device), __LINE__, 1983315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_06c002fc, "DL", 19849b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueCount (=%" PRIu32 19859b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") is not " 19865770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "less than or equal to available queue count for this " 19879b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex} (=%" PRIu32 19889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") obtained previously " 19895770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "from vkGetPhysicalDeviceQueueFamilyProperties%s (%s). %s", 19905770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus i, requested_queue_count, i, requested_queue_family, conditional_ext_cmd, count_note.c_str(), 1991315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_06c002fc]); 1992838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski } 1993838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski } 1994838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski } 19955770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 19963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 1997838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski} 1998838e3917bc1a0479174dd753b5c28b8b2cf1954dMark Lobodzinski 1999f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski// Verify that features have been queried and that they are available 20005770f8ad21c40b2475201e73e9368a899b6886d0Petr Krausstatic bool ValidateRequestedFeatures(instance_layer_data *instance_data, const PHYSICAL_DEVICE_STATE *pd_state, 2001bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkPhysicalDeviceFeatures *requested_features) { 20023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2003f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 20045770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const VkBool32 *actual = reinterpret_cast<const VkBool32 *>(&pd_state->features); 2005825ac70f99460ccb9494d34f93d8ee7ec303e5deMark Lobodzinski const VkBool32 *requested = reinterpret_cast<const VkBool32 *>(requested_features); 2006f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues 2007f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // Need to provide the struct member name with the issue. To do that seems like we'll 2008f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // have to loop through each struct member which should be done w/ codegen to keep in synch. 2009f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski uint32_t errors = 0; 2010f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski uint32_t total_bools = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 2011f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski for (uint32_t i = 0; i < total_bools; i++) { 2012f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski if (requested[i] > actual[i]) { 20135770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 20145770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL", 201591c2ca58e9ab21299931a4eadf03baf93118242bMark Lobodzinski "While calling vkCreateDevice(), requesting feature '%s' in VkPhysicalDeviceFeatures struct, " 20163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which is not available on this device.", 201791c2ca58e9ab21299931a4eadf03baf93118242bMark Lobodzinski GetPhysDevFeatureString(i)); 2018f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski errors++; 2019f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 2020f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 20215770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (errors && (UNCALLED == pd_state->vkGetPhysicalDeviceFeaturesState)) { 2022f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // If user didn't request features, notify them that they should 2023f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error 20245770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 20255770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 0, __LINE__, DEVLIMITS_INVALID_FEATURE_REQUESTED, "DL", 20263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "You requested features that are unavailable on this device. You should first query feature " 20273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "availability by calling vkGetPhysicalDeviceFeatures()."); 2028f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 20293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 2030f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski} 2031f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 203289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, 203389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { 20343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 20355770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(gpu), instance_layer_data_map); 2036f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 2037ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 2038f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus auto pd_state = GetPhysicalDeviceState(instance_data, gpu); 2039f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 2040f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // TODO: object_tracker should perhaps do this instead 2041f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // and it does not seem to currently work anyway -- the loader just crashes before this point 2042f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (!GetPhysicalDeviceState(instance_data, gpu)) { 2043f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 2044f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 2045f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices()."); 2046f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus } 2047f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 2048f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski // Check that any requested features are available 2049f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski if (pCreateInfo->pEnabledFeatures) { 20505770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= ValidateRequestedFeatures(instance_data, pd_state, pCreateInfo->pEnabledFeatures); 2051f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 20525770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= 20535770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ValidateDeviceQueueCreateInfos(instance_data, pd_state, pCreateInfo->queueCreateInfoCount, pCreateInfo->pQueueCreateInfos); 2054f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 20555770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 20561d659b4113b77a95325df10d602a03f1e7abf8b7Mark Mueller 20575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); 20585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 20595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis assert(chain_info->u.pLayerInfo); 20605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; 20615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr; 206256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(instance_data->instance, "vkCreateDevice"); 20635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (fpCreateDevice == NULL) { 20645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_INITIALIZATION_FAILED; 20655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 20665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 20675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Advance the link info for the next element on the chain 20685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; 20695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 20705770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.unlock(); 20715770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 20725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice); 20735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result != VK_SUCCESS) { 20745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 20755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 20765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 20775770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.lock(); 207856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map); 20795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 208056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->instance_data = instance_data; 20815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Setup device dispatch table 208256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_init_device_dispatch_table(*pDevice, &device_data->dispatch_table, fpGetDeviceProcAddr); 208356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->device = *pDevice; 2084ec85232c4d8d9ddf7d2ae57cb8203c5ab52c1106Mark Lobodzinski // Save PhysicalDevice handle 208556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->physical_device = gpu; 20865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 208756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice); 2088a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski device_data->extensions.InitFromDeviceCreateInfo(&instance_data->extensions, pCreateInfo); 2089d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski 20905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Get physical device limits for this device 209156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &(device_data->phys_dev_properties.properties)); 20925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t count; 209356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr); 209456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->phys_dev_properties.queue_family_properties.resize(count); 209556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties( 209656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis gpu, &count, &device_data->phys_dev_properties.queue_family_properties[0]); 20975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO: device limits should make sure these are compatible 20985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCreateInfo->pEnabledFeatures) { 209956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis device_data->enabled_features = *pCreateInfo->pEnabledFeatures; 21005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 210156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis memset(&device_data->enabled_features, 0, sizeof(VkPhysicalDeviceFeatures)); 21025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2103e47dbc3f3340fa177d877a67b2adb76a570027e5Mark Lobodzinski // Store physical device properties and physical device mem limits into device layer_data structs 210456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceMemoryProperties(gpu, &device_data->phys_dev_mem_props); 210556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &device_data->phys_dev_props); 2106b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 21075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ValidateLayerOrdering(*pCreateInfo); 21095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 21115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 21125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// prototype 211489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { 21155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODOSC : Shouldn't need any customization here 21165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dispatch_key key = get_dispatch_key(device); 211756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(key, layer_data_map); 21185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Free all the memory 2119ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 21205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis deletePipelines(dev_data); 2121fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes dev_data->renderPassMap.clear(); 21229b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes for (auto ii = dev_data->commandBufferMap.begin(); ii != dev_data->commandBufferMap.end(); ++ii) { 21239b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes delete (*ii).second; 21249b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes } 21259b36ac77fbf55bd7ffdeb9020f2277fff3a5a807Chris Forbes dev_data->commandBufferMap.clear(); 2126f13bee0887f3c3d1d597c82869864be3be836737Tobin Ehlis // This will also delete all sets in the pool & remove them from setMap 21275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis deletePools(dev_data); 2128f13bee0887f3c3d1d597c82869864be3be836737Tobin Ehlis // All sets should be removed 2129f13bee0887f3c3d1d597c82869864be3be836737Tobin Ehlis assert(dev_data->setMap.empty()); 2130fce842878e9ddcc7f37e1c457a4b018d52358087Tobin Ehlis dev_data->descriptorSetLayoutMap.clear(); 21315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageViewMap.clear(); 21325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageMap.clear(); 21335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageSubresourceMap.clear(); 21345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageLayoutMap.clear(); 21355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->bufferViewMap.clear(); 21365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->bufferMap.clear(); 21371344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis // Queues persist until device is destroyed 21381344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis dev_data->queueMap.clear(); 21395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Report any memory leaks 21405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis layer_debug_report_destroy_device(device); 2141b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 21425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#if DISPATCH_MAP_DEBUG 2144414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller fprintf(stderr, "Device: 0x%p, key: 0x%p\n", device, key); 21455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis#endif 2146d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson 2147d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson dev_data->dispatch_table.DestroyDevice(device, pAllocator); 2148d27b109eaf4da0a5514dc2ae2f3dd6a76976ba0dGabríel Arthúr Pétursson FreeLayerDataPtr(key, layer_data_map); 21495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 21505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 21515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}}; 21525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2153208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis// For given stage mask, if Geometry shader stage is on w/o GS being enabled, report geo_error_id 2154208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis// and if Tessellation Control or Evaluation shader stages are on w/o TS being enabled, report tess_error_id 2155208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlisstatic bool ValidateStageMaskGsTsEnables(layer_data *dev_data, VkPipelineStageFlags stageMask, const char *caller, 2156208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE geo_error_id, UNIQUE_VALIDATION_ERROR_CODE tess_error_id) { 2157208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis bool skip = false; 2158208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis if (!dev_data->enabled_features.geometryShader && (stageMask & VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT)) { 2159208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2160cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski geo_error_id, "DL", 2161cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "%s call includes a stageMask with VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT bit set when " 2162cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "device does not have geometryShader feature enabled. %s", 2163208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis caller, validation_error_map[geo_error_id]); 2164208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis } 2165208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis if (!dev_data->enabled_features.tessellationShader && 2166208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis (stageMask & (VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT))) { 2167208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 2168cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski tess_error_id, "DL", 2169cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "%s call includes a stageMask with VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT " 2170cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "and/or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT bit(s) set when device " 2171cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "does not have tessellationShader feature enabled. %s", 2172208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis caller, validation_error_map[tess_error_id]); 2173208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis } 2174208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis return skip; 2175208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis} 2176208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis 2177ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayes// Loop through bound objects and increment their in_use counts. 2178ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayesstatic void IncrementBoundObjects(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) { 2179a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis for (auto obj : cb_node->object_bindings) { 2180a317e7593a0fe227635fc8241908471acb36c952Chris Forbes auto base_obj = GetStateStructPtrFromObject(dev_data, obj); 2181ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayes if (base_obj) { 218251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour base_obj->in_use.fetch_add(1); 2183162dac96d3883e8fffaa1f988043f62c06662d2eTobin Ehlis } 2184a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis } 2185a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis} 21865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// Track which resources are in-flight by atomically incrementing their "in_use" count 218751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic void incrementResources(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { 218851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour cb_node->submitCount++; 21899a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis cb_node->in_use.fetch_add(1); 2190a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 2191a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // First Increment for all "generic" objects bound to cmd buffer, followed by special-case objects below 2192ad97d033b614e6265aaa8c8f0d21a044982d4de7Jeremy Hayes IncrementBoundObjects(dev_data, cb_node); 2193a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // TODO : We should be able to remove the NULL look-up checks from the code below as long as 2194a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // all the corresponding cases are verified to cause CB_INVALID state and the CB_INVALID state 2195a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // should then be flagged prior to calling this function 21969a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto drawDataElement : cb_node->drawData) { 21975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto buffer : drawDataElement.buffers) { 21989a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 219951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (buffer_state) { 22005cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis buffer_state->in_use.fetch_add(1); 22015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 22025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 22035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 22049a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto event : cb_node->writeEventsBeforeWait) { 22059a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 2206cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (event_state) event_state->write_in_use++; 2207c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 22085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 22095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2210b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// Note: This function assumes that the global lock is held by the calling thread. 2211b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// For the given queue, verify the queue state up to the given seq number. 2212b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// Currently the only check is to make sure that if there are events to be waited on prior to 2213b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// a QueryReset, make sure that all such events have been signalled. 2214d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbesstatic bool VerifyQueueStateToSeq(layer_data *dev_data, QUEUE_STATE *initial_queue, uint64_t initial_seq) { 2215b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis bool skip = false; 2216d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2217d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // sequence number we want to validate up to, per queue 2218d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes std::unordered_map<QUEUE_STATE *, uint64_t> target_seqs { { initial_queue, initial_seq } }; 2219d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // sequence number we've completed validation for, per queue 2220d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes std::unordered_map<QUEUE_STATE *, uint64_t> done_seqs; 2221d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes std::vector<QUEUE_STATE *> worklist { initial_queue }; 2222d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2223d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes while (worklist.size()) { 2224d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto queue = worklist.back(); 2225d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes worklist.pop_back(); 2226d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2227d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto target_seq = target_seqs[queue]; 2228d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto seq = std::max(done_seqs[queue], queue->seq); 2229d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto sub_it = queue->submissions.begin() + int(seq - queue->seq); // seq >= queue->seq 2230d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2231d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (; seq < target_seq; ++sub_it, ++seq) { 2232d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto &wait : sub_it->waitSemaphores) { 2233d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto other_queue = GetQueueState(dev_data, wait.queue); 2234d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2235d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (other_queue == queue) 2236d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes continue; // semaphores /always/ point backwards, so no point here. 2237d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2238d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto other_target_seq = std::max(target_seqs[other_queue], wait.seq); 2239d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto other_done_seq = std::max(done_seqs[other_queue], other_queue->seq); 2240d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2241d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // if this wait is for another queue, and covers new sequence 2242d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // numbers beyond what we've already validated, mark the new 2243d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // target seq and (possibly-re)add the queue to the worklist. 2244d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (other_done_seq < other_target_seq) { 2245d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes target_seqs[other_queue] = other_target_seq; 2246d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes worklist.push_back(other_queue); 2247d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes } 2248d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes } 2249d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2250d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto cb : sub_it->cbs) { 2251d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes auto cb_node = GetCBNode(dev_data, cb); 2252d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (cb_node) { 2253d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto queryEventsPair : cb_node->waitedEventsBeforeQueryReset) { 2254d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes for (auto event : queryEventsPair.second) { 2255d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes if (dev_data->eventMap[event].needsSignaled) { 2256d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 2257d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 0, DRAWSTATE_INVALID_QUERY, "DS", 2258d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes "Cannot get query results on queryPool 0x%" PRIx64 2259d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes " with index %d which was guarded by unsignaled event 0x%" PRIx64 ".", 22609b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(queryEventsPair.first.pool), queryEventsPair.first.index, 22619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event)); 2262d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes } 2263b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis } 2264b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis } 2265b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine } 2266b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine } 2267b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine } 2268d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2269d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes // finally mark the point we've now validated this queue to. 2270d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes done_seqs[queue] = seq; 227192b1701c552e96e96fdbbb77e4b106a9526f3b8cTobin Ehlis } 2272d9944715fa5a4a750a26680f08e5defe85aa7a66Chris Forbes 2273b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis return skip; 2274b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis} 2275b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis 2276b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis// When the given fence is retired, verify outstanding queue operations through the point of the fence 2277b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic bool VerifyQueueStateToFence(layer_data *dev_data, VkFence fence) { 22789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fence_state = GetFenceNode(dev_data, fence); 2279b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis if (VK_NULL_HANDLE != fence_state->signaler.first) { 22809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return VerifyQueueStateToSeq(dev_data, GetQueueState(dev_data, fence_state->signaler.first), fence_state->signaler.second); 2281b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis } 2282b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis return false; 2283b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine} 22847d33205c3aa4aba751a2c07f956634aac616f916Chris Forbes 2285a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis// Decrement in-use count for objects bound to command buffer 22862f8cbf3b166e175174877a59929902e005953d6dTobin Ehlisstatic void DecrementBoundResources(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) { 228700e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis BASE_NODE *base_obj = nullptr; 2288a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis for (auto obj : cb_node->object_bindings) { 22897e5c0c26004626cf6826dfe2779a738a1f9f1fffTobin Ehlis base_obj = GetStateStructPtrFromObject(dev_data, obj); 229000e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis if (base_obj) { 229100e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis base_obj->in_use.fetch_sub(1); 229200e8ce2e6c1c191758f7b7c15eeaf350e5b4a3b6Tobin Ehlis } 2293a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis } 2294a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis} 2295da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes 229636c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic void RetireWorkOnQueue(layer_data *dev_data, QUEUE_STATE *pQueue, uint64_t seq) { 22979867daedbf52debc77d6568162ee21e071699b80Chris Forbes std::unordered_map<VkQueue, uint64_t> otherQueueSeqs; 22989867daedbf52debc77d6568162ee21e071699b80Chris Forbes 22999867daedbf52debc77d6568162ee21e071699b80Chris Forbes // Roll this queue forward, one submission at a time. 23009867daedbf52debc77d6568162ee21e071699b80Chris Forbes while (pQueue->seq < seq) { 2301bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &submission = pQueue->submissions.front(); 23029867daedbf52debc77d6568162ee21e071699b80Chris Forbes 2303bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski for (auto &wait : submission.waitSemaphores) { 23049a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, wait.semaphore); 2305c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski if (pSemaphore) { 2306c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski pSemaphore->in_use.fetch_sub(1); 2307c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski } 2308bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &lastSeq = otherQueueSeqs[wait.queue]; 23099867daedbf52debc77d6568162ee21e071699b80Chris Forbes lastSeq = std::max(lastSeq, wait.seq); 2310da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes } 2311cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes 2312bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski for (auto &semaphore : submission.signalSemaphores) { 23139a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 2314c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski if (pSemaphore) { 2315c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski pSemaphore->in_use.fetch_sub(1); 2316c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski } 23179867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 2318cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes 23199867daedbf52debc77d6568162ee21e071699b80Chris Forbes for (auto cb : submission.cbs) { 23209a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, cb); 2321c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski if (!cb_node) { 2322c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski continue; 2323c91c376e7f18eba22f2996e514eb4714417fb343Mark Lobodzinski } 2324a45bdcb94b2fbda36bc191e12cc20218f62fb0e0Tobin Ehlis // First perform decrement on general case bound objects 23259a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis DecrementBoundResources(dev_data, cb_node); 23269a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto drawDataElement : cb_node->drawData) { 23279867daedbf52debc77d6568162ee21e071699b80Chris Forbes for (auto buffer : drawDataElement.buffers) { 23289a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 23295cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 23305cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis buffer_state->in_use.fetch_sub(1); 23319867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 23329867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 2333da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes } 23349a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto event : cb_node->writeEventsBeforeWait) { 23359867daedbf52debc77d6568162ee21e071699b80Chris Forbes auto eventNode = dev_data->eventMap.find(event); 23369867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (eventNode != dev_data->eventMap.end()) { 23379867daedbf52debc77d6568162ee21e071699b80Chris Forbes eventNode->second.write_in_use--; 23389867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 23399867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 23409a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto queryStatePair : cb_node->queryToStateMap) { 23419867daedbf52debc77d6568162ee21e071699b80Chris Forbes dev_data->queryToStateMap[queryStatePair.first] = queryStatePair.second; 23429867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 23439a61300d900fe3e43e9a03c7fa6876934bc1264eTobin Ehlis for (auto eventStagePair : cb_node->eventToStageMap) { 23449867daedbf52debc77d6568162ee21e071699b80Chris Forbes dev_data->eventMap[eventStagePair.first].stageMask = eventStagePair.second; 2345da8f07baf262972eb3e719fa07b073c180dff157Chris Forbes } 23460a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine 2347a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes cb_node->in_use.fetch_sub(1); 23480a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine } 23499867daedbf52debc77d6568162ee21e071699b80Chris Forbes 23509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, submission.fence); 23519867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (pFence) { 23529867daedbf52debc77d6568162ee21e071699b80Chris Forbes pFence->state = FENCE_RETIRED; 23530a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine } 23549867daedbf52debc77d6568162ee21e071699b80Chris Forbes 23559867daedbf52debc77d6568162ee21e071699b80Chris Forbes pQueue->submissions.pop_front(); 23569867daedbf52debc77d6568162ee21e071699b80Chris Forbes pQueue->seq++; 2357b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 23589867daedbf52debc77d6568162ee21e071699b80Chris Forbes 23599867daedbf52debc77d6568162ee21e071699b80Chris Forbes // Roll other queues forward to the highest seq we saw a wait for 23609867daedbf52debc77d6568162ee21e071699b80Chris Forbes for (auto qs : otherQueueSeqs) { 23619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis RetireWorkOnQueue(dev_data, GetQueueState(dev_data, qs.first), qs.second); 2362d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 23639867daedbf52debc77d6568162ee21e071699b80Chris Forbes} 2364651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 2365651d92815dfff917308137bb67aacccc4f60df86Chris Forbes// Submit a fence to a queue, delimiting previous fences and previous untracked 2366651d92815dfff917308137bb67aacccc4f60df86Chris Forbes// work by it. 236736c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic void SubmitFence(QUEUE_STATE *pQueue, FENCE_NODE *pFence, uint64_t submitCount) { 2368cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes pFence->state = FENCE_INFLIGHT; 23699867daedbf52debc77d6568162ee21e071699b80Chris Forbes pFence->signaler.first = pQueue->queue; 23709867daedbf52debc77d6568162ee21e071699b80Chris Forbes pFence->signaler.second = pQueue->seq + pQueue->submissions.size() + submitCount; 2371b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine} 2372b3d308d63ba34f40839f009ac83b33962d7f26b2Michael Lentine 237351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool validateCommandBufferSimultaneousUse(layer_data *dev_data, GLOBAL_CB_NODE *pCB, int current_submit_count) { 23743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2375a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if ((pCB->in_use.load() || current_submit_count > 1) && 23765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { 23773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 2378315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_31a0008e, "DS", 23793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Command Buffer 0x%p is already in use and is not marked for simultaneous use. %s", pCB->commandBuffer, 2380315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31a0008e]); 23815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 23823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 23835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 23845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2385946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinskistatic bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, const char *call_source, 23860de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski int current_submit_count, UNIQUE_VALIDATION_ERROR_CODE vu_id) { 2387c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis bool skip = false; 2388cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.command_buffer_state) return skip; 23890a59acde4b40fde3bbfea5811d2abf2c85ca62f4Tobin Ehlis // Validate ONE_TIME_SUBMIT_BIT CB is not being submitted more than once 2390946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if ((cb_state->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) && 2391946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski (cb_state->submitCount + current_submit_count > 1)) { 2392c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 2393c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS", 2394226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "Commandbuffer 0x%p was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT " 2395c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis "set, but has been submitted 0x%" PRIxLEAST64 " times.", 2396946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->commandBuffer, cb_state->submitCount + current_submit_count); 23970a59acde4b40fde3bbfea5811d2abf2c85ca62f4Tobin Ehlis } 239894307efee520ad91d5da2ff8f40609b31f05b2efChris Forbes 23995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate that cmd buffers have been updated 240046daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes switch (cb_state->state) { 240146daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_INCOMPLETE: 240246daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_INVALID_COMPLETE: 2403946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ReportInvalidCommandBuffer(dev_data, cb_state, call_source); 240446daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 240546daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes 240646daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_NEW: 24070de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24080de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski (uint64_t)(cb_state->commandBuffer), __LINE__, vu_id, "DS", 24090de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "Command buffer 0x%p used in the call to %s is unrecorded and contains no commands. %s", 24100de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski cb_state->commandBuffer, call_source, validation_error_map[vu_id]); 241146daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 241246daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes 241346daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes case CB_RECORDING: 2414c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 24159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_NO_END_COMMAND_BUFFER, "DS", 2416946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "You must call vkEndCommandBuffer() on command buffer 0x%p before this call to %s!", 2417946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->commandBuffer, call_source); 241846daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 241946daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes 242046daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes default: /* recorded */ 242146daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes break; 24225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2423c264142df95edb7eb96b5dc2d87562efce6ded43Tobin Ehlis return skip; 24245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 24255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 242651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool validateResources(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) { 24273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 242851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 242951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // TODO : We should be able to remove the NULL look-up checks from the code below as long as 243051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // all the corresponding cases are verified to cause CB_INVALID state and the CB_INVALID state 243151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // should then be flagged prior to calling this function 243251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (auto drawDataElement : cb_node->drawData) { 243351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (auto buffer : drawDataElement.buffers) { 243451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto buffer_state = GetBufferState(dev_data, buffer); 243551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (!buffer_state) { 24363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 24379b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(buffer), __LINE__, DRAWSTATE_INVALID_BUFFER, "DS", 24389b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Cannot submit cmd buffer using deleted buffer 0x%" PRIx64 ".", HandleToUint64(buffer)); 243951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 244051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 244151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 24423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 244351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 244451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2445f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski// Check that the queue family index of 'queue' matches one of the entries in pQueueFamilyIndices 2446f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinskibool ValidImageBufferQueue(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, const VK_OBJECT *object, VkQueue queue, uint32_t count, 2447f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski const uint32_t *indices) { 2448f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski bool found = false; 2449f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski bool skip = false; 2450f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski auto queue_state = GetQueueState(dev_data, queue); 2451f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (queue_state) { 2452f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski for (uint32_t i = 0; i < count; i++) { 2453f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (indices[i] == queue_state->queueFamilyIndex) { 2454f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski found = true; 2455f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski break; 2456f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2457f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2458f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski 2459f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (!found) { 24609b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = log_msg( 24619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[object->type], object->handle, __LINE__, 24629b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DRAWSTATE_INVALID_QUEUE_FAMILY, "DS", "vkQueueSubmit: Command buffer 0x%" PRIxLEAST64 " contains %s 0x%" PRIxLEAST64 24639b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus " which was not created allowing concurrent access to this queue family %d.", 24649b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), object_string[object->type], object->handle, queue_state->queueFamilyIndex); 2465f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2466f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2467f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski return skip; 2468f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski} 2469f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski 24707bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski// Validate that queueFamilyIndices of primary command buffers match this queue 24717bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski// Secondary command buffers were previously validated in vkCmdExecuteCommands(). 24727bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinskistatic bool validateQueueFamilyIndices(layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkQueue queue) { 24733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 24749a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, pCB->createInfo.commandPool); 24759a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto queue_state = GetQueueState(dev_data, queue); 24767bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 2477f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (pPool && queue_state) { 2478f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (pPool->queueFamilyIndex != queue_state->queueFamilyIndex) { 24793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 2480315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCB->commandBuffer), __LINE__, VALIDATION_ERROR_31a00094, "DS", 24813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkQueueSubmit: Primary command buffer 0x%p created in queue family %d is being submitted on queue " 24823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "0x%p from queue family %d. %s", 24833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCB->commandBuffer, pPool->queueFamilyIndex, queue, queue_state->queueFamilyIndex, 2484315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31a00094]); 2485f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2486f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski 2487f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski // Ensure that any bound images or buffers created with SHARING_MODE_CONCURRENT have access to the current queue family 2488f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski for (auto object : pCB->object_bindings) { 24897a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski if (object.type == kVulkanObjectTypeImage) { 2490f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski auto image_state = GetImageState(dev_data, reinterpret_cast<VkImage &>(object.handle)); 2491f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (image_state && image_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) { 24923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidImageBufferQueue(dev_data, pCB, &object, queue, image_state->createInfo.queueFamilyIndexCount, 24933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski image_state->createInfo.pQueueFamilyIndices); 2494f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 24957a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski } else if (object.type == kVulkanObjectTypeBuffer) { 2496f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski auto buffer_state = GetBufferState(dev_data, reinterpret_cast<VkBuffer &>(object.handle)); 2497f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski if (buffer_state && buffer_state->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) { 24983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidImageBufferQueue(dev_data, pCB, &object, queue, buffer_state->createInfo.queueFamilyIndexCount, 24993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski buffer_state->createInfo.pQueueFamilyIndices); 2500f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2501f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 2502f26f0f4b1c6b014d9abc2414a9ed255ecade9f04Mark Lobodzinski } 25037bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski } 25047bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 25053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 25067bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski} 25077bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 250851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool validatePrimaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB, int current_submit_count) { 25095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Track in-use for resources off of primary and any secondary CBs 25103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 2511a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 2512a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes // If USAGE_SIMULTANEOUS_USE_BIT not set then CB cannot already be executing 2513a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes // on device 25143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateCommandBufferSimultaneousUse(dev_data, pCB, current_submit_count); 2515a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 25163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateResources(dev_data, pCB); 2517a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 25181a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto pSubCB : pCB->linkedCommandBuffers) { 251911decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes skip |= validateResources(dev_data, pSubCB); 25201a3660584634742a3297915c94768d73f360e794Chris Forbes // TODO: replace with invalidateCommandBuffers() at recording. 252111decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes if ((pSubCB->primaryCommandBuffer != pCB->commandBuffer) && 252211decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes !(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { 2523315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 2524315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_31a00092, "DS", 2525315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "Commandbuffer 0x%p was submitted with secondary buffer 0x%p but that buffer has subsequently been bound to " 2526f634be57d858a71969b3183cd0e322fe1d0ad0fbMike Weiblen "primary cmd buffer 0x%p and it does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set. %s", 2527315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCB->commandBuffer, pSubCB->commandBuffer, pSubCB->primaryCommandBuffer, 2528315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31a00092]); 25295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 25305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2531a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 2532315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validateCommandBufferState(dev_data, pCB, "vkQueueSubmit()", current_submit_count, VALIDATION_ERROR_31a00090); 2533a2d08a743ac1178e4d46da4d41c73fb73b5e79d7Chris Forbes 25343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 25355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 25365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2537bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic bool ValidateFenceForSubmit(layer_data *dev_data, FENCE_NODE *pFence) { 25383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 253981c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 2540651d92815dfff917308137bb67aacccc4f60df86Chris Forbes if (pFence) { 2541cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes if (pFence->state == FENCE_INFLIGHT) { 2542315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO: opportunities for VALIDATION_ERROR_31a00080, VALIDATION_ERROR_316008b4, VALIDATION_ERROR_16400a0e 25433251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 25449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pFence->fence), __LINE__, DRAWSTATE_INVALID_FENCE, "DS", 25459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Fence 0x%" PRIx64 " is already in use by another submission.", HandleToUint64(pFence->fence)); 2546a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis } 254781c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 2548cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes else if (pFence->state == FENCE_RETIRED) { 2549315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO: opportunities for VALIDATION_ERROR_31a0007e, VALIDATION_ERROR_316008b2, VALIDATION_ERROR_16400a0e 25503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 25519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pFence->fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM", 25523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Fence 0x%" PRIxLEAST64 " submitted in SIGNALED state. Fences must be reset before being submitted", 25539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pFence->fence)); 2554a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis } 25555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 255681c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 25573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 255881c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes} 255981c4a32a622486043c15e427fb0e85cc1cf7dd47Chris Forbes 256051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic void PostCallRecordQueueSubmit(layer_data *dev_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, 256151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkFence fence) { 25629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pQueue = GetQueueState(dev_data, queue); 25639a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 2564d7d60cccc862fee2d0b3ad410c5fdcc40ddc83aeChris Forbes 2565651d92815dfff917308137bb67aacccc4f60df86Chris Forbes // Mark the fence in-use. 2566651d92815dfff917308137bb67aacccc4f60df86Chris Forbes if (pFence) { 25679867daedbf52debc77d6568162ee21e071699b80Chris Forbes SubmitFence(pQueue, pFence, std::max(1u, submitCount)); 2568651d92815dfff917308137bb67aacccc4f60df86Chris Forbes } 2569651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 257051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // Now process each individual submit 25715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) { 257251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour std::vector<VkCommandBuffer> cbs; 25735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubmitInfo *submit = &pSubmits[submit_idx]; 25749867daedbf52debc77d6568162ee21e071699b80Chris Forbes vector<SEMAPHORE_WAIT> semaphore_waits; 25759867daedbf52debc77d6568162ee21e071699b80Chris Forbes vector<VkSemaphore> semaphore_signals; 25765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) { 257751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkSemaphore semaphore = submit->pWaitSemaphores[i]; 257851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 257951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (pSemaphore) { 258051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (pSemaphore->signaler.first != VK_NULL_HANDLE) { 258151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour semaphore_waits.push_back({semaphore, pSemaphore->signaler.first, pSemaphore->signaler.second}); 258251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->in_use.fetch_add(1); 258351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 258451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->signaler.first = VK_NULL_HANDLE; 258551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->signaled = false; 258651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 258751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 258851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) { 258951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkSemaphore semaphore = submit->pSignalSemaphores[i]; 259051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 259151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (pSemaphore) { 259251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->signaler.first = queue; 259351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->signaler.second = pQueue->seq + pQueue->submissions.size() + 1; 259451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->signaled = true; 259551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pSemaphore->in_use.fetch_add(1); 259651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour semaphore_signals.push_back(semaphore); 259751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 259851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 259951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t i = 0; i < submit->commandBufferCount; i++) { 260051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto cb_node = GetCBNode(dev_data, submit->pCommandBuffers[i]); 260151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (cb_node) { 260251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour cbs.push_back(submit->pCommandBuffers[i]); 26031a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) { 260411decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes cbs.push_back(secondaryCmdBuffer->commandBuffer); 260551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 260651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour UpdateCmdBufImageLayouts(dev_data, cb_node); 260751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour incrementResources(dev_data, cb_node); 26081a3660584634742a3297915c94768d73f360e794Chris Forbes for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) { 260911decd82041d4b10aac41360fc76b6fda4f4bd27Chris Forbes incrementResources(dev_data, secondaryCmdBuffer); 261051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 261151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 261251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 261351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pQueue->submissions.emplace_back(cbs, semaphore_waits, semaphore_signals, 261451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour submit_idx == submitCount - 1 ? fence : VK_NULL_HANDLE); 261551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 261651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 261751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (pFence && !submitCount) { 261851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // If no submissions, but just dropping a fence on the end of the queue, 261951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // record an empty submission with just the fence, so we can determine 262051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // its completion. 262151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), std::vector<SEMAPHORE_WAIT>(), std::vector<VkSemaphore>(), 262251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour fence); 262351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 262451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 262551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 262651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbourstatic bool PreCallValidateQueueSubmit(layer_data *dev_data, VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, 262751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkFence fence) { 262851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour auto pFence = GetFenceNode(dev_data, fence); 26293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = ValidateFenceForSubmit(dev_data, pFence); 26303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 263151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 263251920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 263351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 263451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unordered_set<VkSemaphore> signaled_semaphores; 263551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unordered_set<VkSemaphore> unsignaled_semaphores; 263651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour vector<VkCommandBuffer> current_cmds; 2637c25ac48846c975d698243e53750c6bca28bba33eChris Forbes unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> localImageLayoutMap; 263851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour // Now verify each individual submit 263951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) { 264051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour const VkSubmitInfo *submit = &pSubmits[submit_idx]; 264151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour for (uint32_t i = 0; i < submit->waitSemaphoreCount; ++i) { 2642315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, submit->pWaitDstStageMask[i], "vkQueueSubmit()", 2643315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_13c00098, VALIDATION_ERROR_13c0009a); 264401a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = submit->pWaitSemaphores[i]; 26459a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 264601a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore) { 264751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour if (unsignaled_semaphores.count(semaphore) || 2648440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour (!(signaled_semaphores.count(semaphore)) && !(pSemaphore->signaled))) { 26493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 26509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 26513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Queue 0x%p is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.", queue, 26529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore)); 265351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } else { 265451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour signaled_semaphores.erase(semaphore); 265551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unsignaled_semaphores.insert(semaphore); 26561344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 26575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 26585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 26595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < submit->signalSemaphoreCount; ++i) { 266001a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = submit->pSignalSemaphores[i]; 26619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 266201a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore) { 2663440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour if (signaled_semaphores.count(semaphore) || (!(unsignaled_semaphores.count(semaphore)) && pSemaphore->signaled)) { 26643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 26659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 26663251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Queue 0x%p is signaling semaphore 0x%" PRIx64 26673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that has already been signaled but not waited on by queue 0x%" PRIx64 ".", 26689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus queue, HandleToUint64(semaphore), HandleToUint64(pSemaphore->signaler.first)); 26691344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } else { 267051920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour unsignaled_semaphores.erase(semaphore); 267151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour signaled_semaphores.insert(semaphore); 26721344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 26730a32ed7bdf03e7bda914e03c0bfa6ebf400cdf5bMichael Lentine } 26745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 26755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < submit->commandBufferCount; i++) { 26769a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, submit->pCommandBuffers[i]); 2677d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis if (cb_node) { 2678c25ac48846c975d698243e53750c6bca28bba33eChris Forbes skip |= ValidateCmdBufImageLayouts(dev_data, cb_node, dev_data->imageLayoutMap, localImageLayoutMap); 267951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour current_cmds.push_back(submit->pCommandBuffers[i]); 26803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validatePrimaryCommandBufferState( 268151920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour dev_data, cb_node, (int)std::count(current_cmds.begin(), current_cmds.end(), submit->pCommandBuffers[i])); 26823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateQueueFamilyIndices(dev_data, cb_node, queue); 268351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 2684ea371fa7c8c57edb4d1436e4570cf54f3fc0463fTobin Ehlis // Potential early exit here as bad object state may crash in delayed function calls 26853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 268651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour return true; 268751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour } 268851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 26891344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis // Call submit-time functions to validate/update state 2690d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto &function : cb_node->validate_functions) { 26913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= function(); 26921344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 2693d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto &function : cb_node->eventUpdates) { 26943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= function(queue); 26951344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 2696d74f8771414d9e80618cd7604ea4b1c459dfa42eTobin Ehlis for (auto &function : cb_node->queryUpdates) { 26973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= function(queue); 2698d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 26991344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } 27005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 27019867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 27023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 270351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour} 27049867daedbf52debc77d6568162ee21e071699b80Chris Forbes 270551920949f887ce8d3666c73c28ff19a5d8325a37Tony BarbourVKAPI_ATTR VkResult VKAPI_CALL QueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) { 270651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 2707ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 270851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 270951920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour bool skip = PreCallValidateQueueSubmit(dev_data, queue, submitCount, pSubmits, fence); 2710b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 27115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2712440bdd357701497c3442e3515f12ac1cfffc180aTony Barbour if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 271351920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 271451920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour VkResult result = dev_data->dispatch_table.QueueSubmit(queue, submitCount, pSubmits, fence); 271551920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour 271651920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour lock.lock(); 271751920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour PostCallRecordQueueSubmit(dev_data, queue, submitCount, pSubmits, fence); 271851920949f887ce8d3666c73c28ff19a5d8325a37Tony Barbour lock.unlock(); 27195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 27205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 27215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2722f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultzstatic bool PreCallValidateAllocateMemory(layer_data *dev_data) { 2723f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz bool skip = false; 2724f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz if (dev_data->memObjMap.size() >= dev_data->phys_dev_properties.properties.limits.maxMemoryAllocationCount) { 2725f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 2726315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_16c004f8, "MEM", 2727f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz "Number of currently valid memory objects is not less than the maximum allowed (%u). %s", 2728f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz dev_data->phys_dev_properties.properties.limits.maxMemoryAllocationCount, 2729315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_16c004f8]); 2730f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz } 2731f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz return skip; 2732f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz} 2733f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz 2734f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultzstatic void PostCallRecordAllocateMemory(layer_data *dev_data, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory) { 2735f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz add_mem_obj_info(dev_data, dev_data->device, *pMemory, pAllocateInfo); 2736f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz return; 2737f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz} 2738f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz 273989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, 274089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) { 2741f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 274256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 2743ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 2744f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz bool skip = PreCallValidateAllocateMemory(dev_data); 2745f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz if (!skip) { 2746f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz lock.unlock(); 2747f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz result = dev_data->dispatch_table.AllocateMemory(device, pAllocateInfo, pAllocator, pMemory); 2748f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz lock.lock(); 2749f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz if (VK_SUCCESS == result) { 2750f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz PostCallRecordAllocateMemory(dev_data, pAllocateInfo, pMemory); 2751f9e31fcaf5f4630e1bf38870a6457e1a04b4a486Karl Schultz } 2752e12739a56d02ca2fb5f0273862668e7475a21a6cMark Lobodzinski } 27535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 27545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 27555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2756177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis// For given obj node, if it is use, flag a validation error and return callback result, else return false 2757177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlisbool ValidateObjectNotInUse(const layer_data *dev_data, BASE_NODE *obj_node, VK_OBJECT obj_struct, 2758177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 2759cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.object_in_use) return false; 2760177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis bool skip = false; 2761177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis if (obj_node->in_use.load()) { 27627a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski skip |= 276302a510945ff39f3d9e486e456aca5bfa6ea0c43aMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, get_debug_report_enum[obj_struct.type], obj_struct.handle, 27647a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski __LINE__, error_code, "DS", "Cannot delete %s 0x%" PRIx64 " that is currently in use by a command buffer. %s", 27657a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski object_string[obj_struct.type], obj_struct.handle, validation_error_map[error_code]); 2766177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2767177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis return skip; 2768177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis} 27695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2770177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlisstatic bool PreCallValidateFreeMemory(layer_data *dev_data, VkDeviceMemory mem, DEVICE_MEM_INFO **mem_info, VK_OBJECT *obj_struct) { 27719a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *mem_info = GetMemObjInfo(dev_data, mem); 27729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(mem), kVulkanObjectTypeDeviceMemory}; 2773cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.free_memory) return false; 2774177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis bool skip = false; 2775177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis if (*mem_info) { 2776315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *mem_info, *obj_struct, VALIDATION_ERROR_2880054a); 2777177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2778177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis return skip; 2779177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis} 27805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2781177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlisstatic void PostCallRecordFreeMemory(layer_data *dev_data, VkDeviceMemory mem, DEVICE_MEM_INFO *mem_info, VK_OBJECT obj_struct) { 2782177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis // Clear mem binding for any bound objects 278347705d01140c9f1492885e6efc5fa262e7e1c6a0Tobin Ehlis for (auto obj : mem_info->obj_bindings) { 278402a510945ff39f3d9e486e456aca5bfa6ea0c43aMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, get_debug_report_enum[obj.type], obj.handle, __LINE__, 27857a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski MEMTRACK_FREED_MEM_REF, "MEM", "VK Object 0x%" PRIxLEAST64 " still has a reference to mem obj 0x%" PRIxLEAST64, 27869b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus obj.handle, HandleToUint64(mem_info->mem)); 278747705d01140c9f1492885e6efc5fa262e7e1c6a0Tobin Ehlis switch (obj.type) { 27887a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeImage: { 27899a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, reinterpret_cast<VkImage &>(obj.handle)); 2790cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(image_state); // Any destroyed images should already be removed from bindings 2791cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski image_state->binding.mem = MEMORY_UNBOUND; 2792cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 2793cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 27947a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski case kVulkanObjectTypeBuffer: { 27959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, reinterpret_cast<VkBuffer &>(obj.handle)); 2796cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(buffer_state); // Any destroyed buffers should already be removed from bindings 2797cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski buffer_state->binding.mem = MEMORY_UNBOUND; 2798cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 2799cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 2800cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 2801cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // Should only have buffer or image objects bound to memory 2802cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski assert(0); 2803177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2804177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis } 2805177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis // Any bound cmd buffers are now invalid 280639c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, mem_info->cb_bindings, obj_struct); 2807177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis dev_data->memObjMap.erase(mem); 2808177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis} 2809177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis 2810177063aac84fac6f4e650c2629a08b48be643f96Tobin EhlisVKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) { 281156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 2812177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis DEVICE_MEM_INFO *mem_info = nullptr; 2813177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis VK_OBJECT obj_struct; 2814ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 2815177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis bool skip = PreCallValidateFreeMemory(dev_data, mem, &mem_info, &obj_struct); 2816177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis if (!skip) { 2817177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis lock.unlock(); 2818177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis dev_data->dispatch_table.FreeMemory(device, mem, pAllocator); 2819177063aac84fac6f4e650c2629a08b48be643f96Tobin Ehlis lock.lock(); 2820405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (mem != VK_NULL_HANDLE) { 2821405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordFreeMemory(dev_data, mem, mem_info, obj_struct); 2822405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 282374243a735fe102b370237ddf80d3e6f7ec5246dbMark Mueller } 28245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 28255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 2826f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// Validate that given Map memory range is valid. This means that the memory should not already be mapped, 2827f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// and that the size of the map range should be: 2828f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// 1. Not zero 2829f57fc64ac43691ad98e1713886b345465573070aTobin Ehlis// 2. Within the size of the memory allocation 283051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool ValidateMapMemRange(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) { 28313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 28325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 28335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (size == 0) { 28343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 28359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 28363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VkMapMemory: Attempting to map memory range of size zero"); 28375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 283951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis auto mem_element = dev_data->memObjMap.find(mem); 284051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis if (mem_element != dev_data->memObjMap.end()) { 284157fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis auto mem_info = mem_element->second.get(); 28425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // It is an application error to call VkMapMemory on an object that is already mapped 2843de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (mem_info->mem_range.size != 0) { 28449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = 28459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 28469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 28479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "VkMapMemory: Attempting to map memory on an already-mapped object 0x%" PRIxLEAST64, HandleToUint64(mem)); 28485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 28505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate that offset + size is within object's allocationSize 28515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (size == VK_WHOLE_SIZE) { 2852de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (offset >= mem_info->alloc_info.allocationSize) { 28533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 28549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 28553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 28563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " with size of VK_WHOLE_SIZE oversteps total array size 0x%" PRIx64, 28573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski offset, mem_info->alloc_info.allocationSize, mem_info->alloc_info.allocationSize); 28585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 2860de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if ((offset + size) > mem_info->alloc_info.allocationSize) { 28613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 2862315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), __LINE__, VALIDATION_ERROR_31200552, "MEM", 28633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Mapping Memory from 0x%" PRIx64 " to 0x%" PRIx64 " oversteps total array size 0x%" PRIx64 ". %s", 28643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski offset, size + offset, mem_info->alloc_info.allocationSize, 2865315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31200552]); 28665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 28705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 28715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 287251ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic void storeMemRanges(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size) { 28739a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 287457fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 2875de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->mem_range.offset = offset; 2876de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->mem_range.size = size; 28775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 28795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 288051ea774638f432bd8e700ec8291a980f405f429eTobin Ehlisstatic bool deleteMemRanges(layer_data *dev_data, VkDeviceMemory mem) { 28813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 28829a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 288357fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 2884de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (!mem_info->mem_range.size) { 28855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Valid Usage: memory must currently be mapped 28863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 2887315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), __LINE__, VALIDATION_ERROR_33600562, "MEM", 28889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Unmapping Memory without memory being mapped: mem obj 0x%" PRIxLEAST64 ". %s", HandleToUint64(mem), 2889315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_33600562]); 28905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 2891de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->mem_range.size = 0; 28925f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski if (mem_info->shadow_copy) { 28935f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski free(mem_info->shadow_copy_base); 28945f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy_base = 0; 28955f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy = 0; 28965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 28983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 28995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 29005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 29015f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski// Guard value for pad data 29025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisstatic char NoncoherentMemoryFillValue = 0xb; 29035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 29045f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinskistatic void initializeAndTrackMemory(layer_data *dev_data, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, 29055f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski void **ppData) { 29069a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 290757fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 2908de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis mem_info->p_driver_data = *ppData; 2909de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis uint32_t index = mem_info->alloc_info.memoryTypeIndex; 2910b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis if (dev_data->phys_dev_mem_props.memoryTypes[index].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { 29115f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy = 0; 29125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 29135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (size == VK_WHOLE_SIZE) { 29145f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski size = mem_info->alloc_info.allocationSize - offset; 29155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29165f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_pad_size = dev_data->phys_dev_properties.properties.limits.minMemoryMapAlignment; 291716769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton assert(SafeModulo(mem_info->shadow_pad_size, 29185f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski dev_data->phys_dev_properties.properties.limits.minMemoryMapAlignment) == 0); 29195f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski // Ensure start of mapped region reflects hardware alignment constraints 29205f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski uint64_t map_alignment = dev_data->phys_dev_properties.properties.limits.minMemoryMapAlignment; 29215f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 29225f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski // From spec: (ppData - offset) must be aligned to at least limits::minMemoryMapAlignment. 29235f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski uint64_t start_offset = offset % map_alignment; 29245f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski // Data passed to driver will be wrapped by a guardband of data to detect over- or under-writes. 2925bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski mem_info->shadow_copy_base = 2926bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski malloc(static_cast<size_t>(2 * mem_info->shadow_pad_size + size + map_alignment + start_offset)); 29275f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 29285f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski mem_info->shadow_copy = 29295f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski reinterpret_cast<char *>((reinterpret_cast<uintptr_t>(mem_info->shadow_copy_base) + map_alignment) & 2930bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski ~(map_alignment - 1)) + 2931bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski start_offset; 293216769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton assert(SafeModulo(reinterpret_cast<uintptr_t>(mem_info->shadow_copy) + mem_info->shadow_pad_size - start_offset, 29335f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski map_alignment) == 0); 29345f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 29356e17c244b21ce43ac57404a00a0d844039eed363Mark Lobodzinski memset(mem_info->shadow_copy, NoncoherentMemoryFillValue, static_cast<size_t>(2 * mem_info->shadow_pad_size + size)); 29365f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski *ppData = static_cast<char *>(mem_info->shadow_copy) + mem_info->shadow_pad_size; 29375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 29405f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski 2941a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis// Verify that state for fence being waited on is appropriate. That is, 29429867daedbf52debc77d6568162ee21e071699b80Chris Forbes// a fence being waited on should not already be signaled and 2943a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis// it should have been submitted on a queue or during acquire next image 294449f6132af865afd5b7f413c91125971ac97c135aChris Forbesstatic inline bool verifyWaitFenceState(layer_data *dev_data, VkFence fence, const char *apiCall) { 29453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 29469b48b44dd917f95b5f34dd629ec4076fc87eb3a2Chris Forbes 29479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 29489b48b44dd917f95b5f34dd629ec4076fc87eb3a2Chris Forbes if (pFence) { 2949cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes if (pFence->state == FENCE_UNSIGNALED) { 29503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 29519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(fence), __LINE__, MEMTRACK_INVALID_FENCE_STATE, "MEM", 29523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s called for fence 0x%" PRIxLEAST64 29533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " which has not been submitted on a Queue or during " 29543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "acquire next image.", 29559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus apiCall, HandleToUint64(fence)); 29565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 29583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 29595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 2960a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis 2961b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic void RetireFence(layer_data *dev_data, VkFence fence) { 29629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 2963b3ecd4c1fb44a2e65dfc13256afa9150aabde1d4Chris Forbes if (pFence->signaler.first != VK_NULL_HANDLE) { 296425002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski // Fence signaller is a queue -- use this as proof that prior operations on that queue have completed. 29659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis RetireWorkOnQueue(dev_data, GetQueueState(dev_data, pFence->signaler.first), pFence->signaler.second); 2966bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski } else { 296725002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski // Fence signaller is the WSI. We're not tracking what the WSI op actually /was/ in CV yet, but we need to mark 296825002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski // the fence as retired. 2969d4513979120463171eb479cdded9336eb9944da1Chris Forbes pFence->state = FENCE_RETIRED; 2970d4513979120463171eb479cdded9336eb9944da1Chris Forbes } 2971b3ecd4c1fb44a2e65dfc13256afa9150aabde1d4Chris Forbes} 2972b3ecd4c1fb44a2e65dfc13256afa9150aabde1d4Chris Forbes 2973accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlisstatic bool PreCallValidateWaitForFences(layer_data *dev_data, uint32_t fence_count, const VkFence *fences) { 2974cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.wait_for_fences) return false; 2975accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis bool skip = false; 2976accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis for (uint32_t i = 0; i < fence_count; i++) { 2977accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis skip |= verifyWaitFenceState(dev_data, fences[i], "vkWaitForFences"); 2978b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis skip |= VerifyQueueStateToFence(dev_data, fences[i]); 2979accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis } 2980accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis return skip; 2981accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis} 2982accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis 2983b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic void PostCallRecordWaitForFences(layer_data *dev_data, uint32_t fence_count, const VkFence *fences, VkBool32 wait_all) { 2984b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis // When we know that all fences are complete we can clean/remove their CBs 2985accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis if ((VK_TRUE == wait_all) || (1 == fence_count)) { 2986accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis for (uint32_t i = 0; i < fence_count; i++) { 2987b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis RetireFence(dev_data, fences[i]); 2988accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis } 2989accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis } 2990accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis // NOTE : Alternate case not handled here is when some fences have completed. In 2991accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis // this case for app to guarantee which fences completed it will have to call 2992b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis // vkGetFenceStatus() at which point we'll clean/remove their CBs if complete. 2993accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis} 2994accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis 2995bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, 2996bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint64_t timeout) { 299756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 29985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Verify fence status of submitted fences 2999ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3000accdf1d467e269e05b89764faf204fb2ff600b57Tobin Ehlis bool skip = PreCallValidateWaitForFences(dev_data, fenceCount, pFences); 3001b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3002cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 3003a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis 30044a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.WaitForFences(device, fenceCount, pFences, waitAll, timeout); 3005414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller 30065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 3007b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 3008b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis PostCallRecordWaitForFences(dev_data, fenceCount, pFences, waitAll); 3009b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 30105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 30125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 30135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3014f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlisstatic bool PreCallValidateGetFenceStatus(layer_data *dev_data, VkFence fence) { 3015cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.get_fence_state) return false; 3016f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis return verifyWaitFenceState(dev_data, fence, "vkGetFenceStatus"); 3017f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis} 3018f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis 3019b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlisstatic void PostCallRecordGetFenceStatus(layer_data *dev_data, VkFence fence) { RetireFence(dev_data, fence); } 3020f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis 302189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL GetFenceStatus(VkDevice device, VkFence fence) { 302256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3023ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3024f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis bool skip = PreCallValidateGetFenceStatus(dev_data, fence); 3025b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3026cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 3027a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis 30284a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.GetFenceStatus(device, fence); 30295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 3030f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis lock.lock(); 3031b7d814f72a72fb2eee7efa0f48e6a67a86eaf588Tobin Ehlis PostCallRecordGetFenceStatus(dev_data, fence); 3032f073b96e7a0030b55a66b780bd3ed57262cf1fa2Tobin Ehlis lock.unlock(); 30335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 30345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 30355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 30365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 30373b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlisstatic void PostCallRecordGetDeviceQueue(layer_data *dev_data, uint32_t q_family_index, VkQueue queue) { 30383b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis // Add queue to tracking set only if it is new 30393b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis auto result = dev_data->queues.emplace(queue); 30403b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis if (result.second == true) { 304136c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlis QUEUE_STATE *queue_state = &dev_data->queueMap[queue]; 30423b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis queue_state->queue = queue; 30433b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis queue_state->queueFamilyIndex = q_family_index; 30443b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis queue_state->seq = 0; 30453b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis } 30463b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis} 30473b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis 3048bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) { 304956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 30504a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); 3051ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 3052b376edacad6f7ab3fcc0a914e9b1673a9fcd5143Mark Lobodzinski 30533b3fccc991a6cbe649b96880f36d90318b3c7cc2Tobin Ehlis PostCallRecordGetDeviceQueue(dev_data, queueFamilyIndex, *pQueue); 30545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 30555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 305636c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic bool PreCallValidateQueueWaitIdle(layer_data *dev_data, VkQueue queue, QUEUE_STATE **queue_state) { 30579a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *queue_state = GetQueueState(dev_data, queue); 3058cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.queue_wait_idle) return false; 3059e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis return VerifyQueueStateToSeq(dev_data, *queue_state, (*queue_state)->seq + (*queue_state)->submissions.size()); 30604273a1c157585a645dca4c960086032793899d05Tobin Ehlis} 30614273a1c157585a645dca4c960086032793899d05Tobin Ehlis 306236c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlisstatic void PostCallRecordQueueWaitIdle(layer_data *dev_data, QUEUE_STATE *queue_state) { 3063e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis RetireWorkOnQueue(dev_data, queue_state, queue_state->seq + queue_state->submissions.size()); 30644273a1c157585a645dca4c960086032793899d05Tobin Ehlis} 30654273a1c157585a645dca4c960086032793899d05Tobin Ehlis 306689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL QueueWaitIdle(VkQueue queue) { 306756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 306836c3a4fe8455762d2dc0b2b9ece44675a3ee8d97Tobin Ehlis QUEUE_STATE *queue_state = nullptr; 3069ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 30704273a1c157585a645dca4c960086032793899d05Tobin Ehlis bool skip = PreCallValidateQueueWaitIdle(dev_data, queue, &queue_state); 30719867daedbf52debc77d6568162ee21e071699b80Chris Forbes lock.unlock(); 3072cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 30734a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.QueueWaitIdle(queue); 30744273a1c157585a645dca4c960086032793899d05Tobin Ehlis if (VK_SUCCESS == result) { 3075e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis lock.lock(); 3076e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis PostCallRecordQueueWaitIdle(dev_data, queue_state); 3077e0cec9ec6dd3cfd83345cabba55ec021681801dbTobin Ehlis lock.unlock(); 30784273a1c157585a645dca4c960086032793899d05Tobin Ehlis } 30795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 30805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 30815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 30828767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlisstatic bool PreCallValidateDeviceWaitIdle(layer_data *dev_data) { 3083cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.device_wait_idle) return false; 30848767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis bool skip = false; 30858767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis for (auto &queue : dev_data->queueMap) { 30868767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis skip |= VerifyQueueStateToSeq(dev_data, &queue.second, queue.second.seq + queue.second.submissions.size()); 30878767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis } 30888767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis return skip; 30898767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis} 30908767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis 30918767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlisstatic void PostCallRecordDeviceWaitIdle(layer_data *dev_data) { 30928767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis for (auto &queue : dev_data->queueMap) { 30938767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis RetireWorkOnQueue(dev_data, &queue.second, queue.second.seq + queue.second.submissions.size()); 30948767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis } 30958767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis} 30968767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis 309789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL DeviceWaitIdle(VkDevice device) { 309856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3099ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 31008767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis bool skip = PreCallValidateDeviceWaitIdle(dev_data); 3101b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3102cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 31034a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.DeviceWaitIdle(device); 31048767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis if (VK_SUCCESS == result) { 31058767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis lock.lock(); 31068767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis PostCallRecordDeviceWaitIdle(dev_data); 31078767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis lock.unlock(); 31088767ceaf6a7d5675c2fe0502df31a1339a5a6337Tobin Ehlis } 31095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 31105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 31115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 31121d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlisstatic bool PreCallValidateDestroyFence(layer_data *dev_data, VkFence fence, FENCE_NODE **fence_node, VK_OBJECT *obj_struct) { 31139a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *fence_node = GetFenceNode(dev_data, fence); 31149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(fence), kVulkanObjectTypeFence}; 3115cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_fence) return false; 31161d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis bool skip = false; 31171d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis if (*fence_node) { 31181d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis if ((*fence_node)->state == FENCE_INFLIGHT) { 31191d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 3120315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(fence), __LINE__, VALIDATION_ERROR_24e008c0, "DS", "Fence 0x%" PRIx64 " is in use. %s", 3121315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(fence), validation_error_map[VALIDATION_ERROR_24e008c0]); 31221d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis } 31231d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis } 31241d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis return skip; 31251d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis} 31261d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis 31271d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlisstatic void PostCallRecordDestroyFence(layer_data *dev_data, VkFence fence) { dev_data->fenceMap.erase(fence); } 31281d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis 312989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyFence(VkDevice device, VkFence fence, const VkAllocationCallbacks *pAllocator) { 313056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 31311d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis // Common data objects used pre & post call 31321d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis FENCE_NODE *fence_node = nullptr; 31331d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis VK_OBJECT obj_struct; 3134ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 31351d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis bool skip = PreCallValidateDestroyFence(dev_data, fence, &fence_node, &obj_struct); 31361344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 31371d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis if (!skip) { 31381d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis lock.unlock(); 31394a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyFence(device, fence, pAllocator); 31401d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis lock.lock(); 31411d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis PostCallRecordDestroyFence(dev_data, fence); 31421d3dce01906e45faf7282cffc3334cbda1662656Tobin Ehlis } 31435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 31445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3145c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlisstatic bool PreCallValidateDestroySemaphore(layer_data *dev_data, VkSemaphore semaphore, SEMAPHORE_NODE **sema_node, 3146c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis VK_OBJECT *obj_struct) { 31479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *sema_node = GetSemaphoreNode(dev_data, semaphore); 31489b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(semaphore), kVulkanObjectTypeSemaphore}; 3149cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_semaphore) return false; 3150c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis bool skip = false; 3151c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis if (*sema_node) { 3152315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *sema_node, *obj_struct, VALIDATION_ERROR_268008e2); 3153c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis } 3154c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis return skip; 3155c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis} 3156c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis 3157c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlisstatic void PostCallRecordDestroySemaphore(layer_data *dev_data, VkSemaphore sema) { dev_data->semaphoreMap.erase(sema); } 3158c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis 3159bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroySemaphore(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks *pAllocator) { 316056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3161c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis SEMAPHORE_NODE *sema_node; 3162c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis VK_OBJECT obj_struct; 3163ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3164c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis bool skip = PreCallValidateDestroySemaphore(dev_data, semaphore, &sema_node, &obj_struct); 3165eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis if (!skip) { 3166eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis lock.unlock(); 31674a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroySemaphore(device, semaphore, pAllocator); 3168c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis lock.lock(); 3169c0f1f8368ec7be6f098e2599b31622f81ff00185Tobin Ehlis PostCallRecordDestroySemaphore(dev_data, semaphore); 317099d938c90c2f000ee73fb13513dacf84ffa5651fMark Mueller } 31715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 31725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 31734710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlisstatic bool PreCallValidateDestroyEvent(layer_data *dev_data, VkEvent event, EVENT_STATE **event_state, VK_OBJECT *obj_struct) { 31749a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *event_state = GetEventNode(dev_data, event); 31759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(event), kVulkanObjectTypeEvent}; 3176cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_event) return false; 3177d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis bool skip = false; 3178d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis if (*event_state) { 3179315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *event_state, *obj_struct, VALIDATION_ERROR_24c008f2); 3180d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis } 3181d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis return skip; 3182d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis} 3183d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis 31844710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlisstatic void PostCallRecordDestroyEvent(layer_data *dev_data, VkEvent event, EVENT_STATE *event_state, VK_OBJECT obj_struct) { 318539c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, event_state->cb_bindings, obj_struct); 3186d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis dev_data->eventMap.erase(event); 3187d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis} 3188d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis 318989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) { 319056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 31914710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis EVENT_STATE *event_state = nullptr; 3192d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis VK_OBJECT obj_struct; 3193ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3194d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis bool skip = PreCallValidateDestroyEvent(dev_data, event, &event_state, &obj_struct); 3195f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3196f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 31974a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyEvent(device, event, pAllocator); 3198d379c77e4254a740aa838a82e7af186525524617Tobin Ehlis lock.lock(); 3199405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (event != VK_NULL_HANDLE) { 3200405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyEvent(dev_data, event, event_state, obj_struct); 3201405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3202f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 32035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 32045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 320583c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlisstatic bool PreCallValidateDestroyQueryPool(layer_data *dev_data, VkQueryPool query_pool, QUERY_POOL_NODE **qp_state, 320683c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis VK_OBJECT *obj_struct) { 32079a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *qp_state = GetQueryPoolNode(dev_data, query_pool); 32089b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(query_pool), kVulkanObjectTypeQueryPool}; 3209cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_query_pool) return false; 321083c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis bool skip = false; 321183c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis if (*qp_state) { 3212315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *qp_state, *obj_struct, VALIDATION_ERROR_26200632); 321383c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis } 321483c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis return skip; 321583c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis} 321683c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis 3217bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic void PostCallRecordDestroyQueryPool(layer_data *dev_data, VkQueryPool query_pool, QUERY_POOL_NODE *qp_state, 3218bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VK_OBJECT obj_struct) { 321983c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis invalidateCommandBuffers(dev_data, qp_state->cb_bindings, obj_struct); 322083c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis dev_data->queryPoolMap.erase(query_pool); 322183c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis} 322283c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis 3223bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyQueryPool(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks *pAllocator) { 322456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 322583c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis QUERY_POOL_NODE *qp_state = nullptr; 322683c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis VK_OBJECT obj_struct; 3227ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 322883c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis bool skip = PreCallValidateDestroyQueryPool(dev_data, queryPool, &qp_state, &obj_struct); 3229f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3230f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 32314a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyQueryPool(device, queryPool, pAllocator); 323283c1f2cdfb8eca95c7d450aca7863d5b269b7be6Tobin Ehlis lock.lock(); 3233405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (queryPool != VK_NULL_HANDLE) { 3234405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyQueryPool(dev_data, queryPool, qp_state, obj_struct); 3235405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3236f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 32375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 32389fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlisstatic bool PreCallValidateGetQueryPoolResults(layer_data *dev_data, VkQueryPool query_pool, uint32_t first_query, 32399fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis uint32_t query_count, VkQueryResultFlags flags, 32409fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis unordered_map<QueryObject, vector<VkCommandBuffer>> *queries_in_flight) { 3241a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes // TODO: clean this up, it's insanely wasteful. 3242a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes for (auto cmd_buffer : dev_data->commandBufferMap) { 3243a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if (cmd_buffer.second->in_use.load()) { 3244a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes for (auto query_state_pair : cmd_buffer.second->queryToStateMap) { 3245a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes (*queries_in_flight)[query_state_pair.first].push_back( 3246a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes cmd_buffer.first); 3247a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes } 32485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 32495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3250cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.get_query_pool_results) return false; 32519fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis bool skip = false; 32529fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (uint32_t i = 0; i < query_count; ++i) { 32539fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis QueryObject query = {query_pool, first_query + i}; 32549fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto qif_pair = queries_in_flight->find(query); 32559fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_state_pair = dev_data->queryToStateMap.find(query); 32569fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_state_pair != dev_data->queryToStateMap.end()) { 3257ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski // Available and in flight 32589fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (qif_pair != queries_in_flight->end() && query_state_pair != dev_data->queryToStateMap.end() && 32599fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis query_state_pair->second) { 32609fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (auto cmd_buffer : qif_pair->second) { 32619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb = GetCBNode(dev_data, cmd_buffer); 32629fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_event_pair = cb->waitedEventsBeforeQueryReset.find(query); 32639fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_event_pair == cb->waitedEventsBeforeQueryReset.end()) { 32649fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 32659fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 32669fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis "Cannot get query results on queryPool 0x%" PRIx64 " with index %d which is in flight.", 32679b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(query_pool), first_query + i); 3268ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski } 3269ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski } 3270ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski // Unavailable and in flight 32719fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } else if (qif_pair != queries_in_flight->end() && query_state_pair != dev_data->queryToStateMap.end() && 32729fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis !query_state_pair->second) { 3273ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski // TODO : Can there be the same query in use by multiple command buffers in flight? 3274ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski bool make_available = false; 32759fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (auto cmd_buffer : qif_pair->second) { 32769a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb = GetCBNode(dev_data, cmd_buffer); 32779fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis make_available |= cb->queryToStateMap[query]; 3278ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski } 3279ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski if (!(((flags & VK_QUERY_RESULT_PARTIAL_BIT) || (flags & VK_QUERY_RESULT_WAIT_BIT)) && make_available)) { 32809fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 32819fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 32829fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis "Cannot get query results on queryPool 0x%" PRIx64 " with index %d which is unavailable.", 32839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(query_pool), first_query + i); 32845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3285ec27ab7d1aa03fa187755b6720e1be995a994f5cMark Lobodzinski // Unavailable 32869fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } else if (query_state_pair != dev_data->queryToStateMap.end() && !query_state_pair->second) { 32879fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 32889fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 32899fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis "Cannot get query results on queryPool 0x%" PRIx64 " with index %d which is unavailable.", 32909b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(query_pool), first_query + i); 32919fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis // Uninitialized 32929fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } else if (query_state_pair == dev_data->queryToStateMap.end()) { 32939fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 32949fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 32959fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis "Cannot get query results on queryPool 0x%" PRIx64 32969fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis " with index %d as data has not been collected for this index.", 32979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(query_pool), first_query + i); 32985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 32995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 33005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 33019fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis return skip; 33029fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis} 33039fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis 33049fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlisstatic void PostCallRecordGetQueryPoolResults(layer_data *dev_data, VkQueryPool query_pool, uint32_t first_query, 33059fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis uint32_t query_count, 33069fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis unordered_map<QueryObject, vector<VkCommandBuffer>> *queries_in_flight) { 33079fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (uint32_t i = 0; i < query_count; ++i) { 33089fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis QueryObject query = {query_pool, first_query + i}; 33099fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto qif_pair = queries_in_flight->find(query); 33109fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_state_pair = dev_data->queryToStateMap.find(query); 33119fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_state_pair != dev_data->queryToStateMap.end()) { 33129fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis // Available and in flight 33139fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (qif_pair != queries_in_flight->end() && query_state_pair != dev_data->queryToStateMap.end() && 33149fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis query_state_pair->second) { 33159fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (auto cmd_buffer : qif_pair->second) { 33169a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb = GetCBNode(dev_data, cmd_buffer); 33179fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis auto query_event_pair = cb->waitedEventsBeforeQueryReset.find(query); 33189fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis if (query_event_pair != cb->waitedEventsBeforeQueryReset.end()) { 33199fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis for (auto event : query_event_pair->second) { 33209fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis dev_data->eventMap[event].needsSignaled = true; 33219fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 33229fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 33239fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 33249fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 33259fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 33269fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis } 33279fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis} 33289fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis 33299fdee42cd357379efb9aa27f90beb75d1f824955Tobin EhlisVKAPI_ATTR VkResult VKAPI_CALL GetQueryPoolResults(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, 33309fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis size_t dataSize, void *pData, VkDeviceSize stride, VkQueryResultFlags flags) { 333156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 33329fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis unordered_map<QueryObject, vector<VkCommandBuffer>> queries_in_flight; 3333ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 33349fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis bool skip = PreCallValidateGetQueryPoolResults(dev_data, queryPool, firstQuery, queryCount, flags, &queries_in_flight); 3335b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3336cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 33379fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis VkResult result = 33389fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis dev_data->dispatch_table.GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags); 33399fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis lock.lock(); 33409fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis PostCallRecordGetQueryPoolResults(dev_data, queryPool, firstQuery, queryCount, &queries_in_flight); 33419fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis lock.unlock(); 33429fdee42cd357379efb9aa27f90beb75d1f824955Tobin Ehlis return result; 33435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 33445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3345825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Return true if given ranges intersect, else false 3346825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Prereq : For both ranges, range->end - range->start > 0. This case should have already resulted 3347825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// in an error so not checking that here 3348825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// pad_ranges bool indicates a linear and non-linear comparison which requires padding 33493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski// In the case where padding is required, if an alias is encountered then a validation error is reported and skip 33503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski// may be set by the callback function so caller should merge in skip value if padding case is possible. 33512ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton// This check can be skipped by passing skip_checks=true, for call sites outside the validation path. 33523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinskistatic bool rangesIntersect(layer_data const *dev_data, MEMORY_RANGE const *range1, MEMORY_RANGE const *range2, bool *skip, 33532ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton bool skip_checks) { 33543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *skip = false; 3355825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r1_start = range1->start; 3356825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r1_end = range1->end; 3357825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r2_start = range2->start; 3358825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto r2_end = range2->end; 3359825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis VkDeviceSize pad_align = 1; 3360825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis if (range1->linear != range2->linear) { 3361825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis pad_align = dev_data->phys_dev_properties.properties.limits.bufferImageGranularity; 3362825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis } 3363cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if ((r1_end & ~(pad_align - 1)) < (r2_start & ~(pad_align - 1))) return false; 3364cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if ((r1_start & ~(pad_align - 1)) > (r2_end & ~(pad_align - 1))) return false; 336547aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 33662ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (!skip_checks && (range1->linear != range2->linear)) { 336753ecec26e80e4d18b57d24ed6eb91a3c9da4b95cTobin Ehlis // In linear vs. non-linear case, warn of aliasing 3368825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r1_linear_str = range1->linear ? "Linear" : "Non-linear"; 3369825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r1_type_str = range1->image ? "image" : "buffer"; 3370825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r2_linear_str = range2->linear ? "linear" : "non-linear"; 3371825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis const char *r2_type_str = range2->image ? "image" : "buffer"; 3372825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto obj_type = range1->image ? VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT : VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT; 33733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, obj_type, range1->handle, 0, 33743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski MEMTRACK_INVALID_ALIASING, "MEM", "%s %s 0x%" PRIx64 " is aliased with %s %s 0x%" PRIx64 33753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " which may indicate a bug. For further info refer to the " 33763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Buffer-Image Granularity section of the Vulkan specification. " 33773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "(https://www.khronos.org/registry/vulkan/specs/1.0-extensions/" 33783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "xhtml/vkspec.html#resources-bufferimagegranularity)", 33793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski r1_linear_str, r1_type_str, range1->handle, r2_linear_str, r2_type_str, range2->handle); 338047aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 3381825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis // Ranges intersect 3382825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis return true; 338347aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski} 3384623548a271287ae55415e45e3c654ee66d4e79ffTobin Ehlis// Simplified rangesIntersect that calls above function to check range1 for intersection with offset & end addresses 3385c3340a06ecac4d7b9540592cae339f8fc224d0b1Mark Lobodzinskibool rangesIntersect(layer_data const *dev_data, MEMORY_RANGE const *range1, VkDeviceSize offset, VkDeviceSize end) { 3386825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis // Create a local MEMORY_RANGE struct to wrap offset/size 3387825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis MEMORY_RANGE range_wrap; 3388825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis // Synch linear with range1 to avoid padding and potential validation error case 3389825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range_wrap.linear = range1->linear; 3390825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range_wrap.start = offset; 3391cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis range_wrap.end = end; 3392825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis bool tmp_bool; 33932ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton return rangesIntersect(dev_data, range1, &range_wrap, &tmp_bool, true); 3394825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis} 3395cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis// For given mem_info, set all ranges valid that intersect [offset-end] range 3396cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis// TODO : For ranges where there is no alias, we may want to create new buffer ranges that are valid 3397cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlisstatic void SetMemRangesValid(layer_data const *dev_data, DEVICE_MEM_INFO *mem_info, VkDeviceSize offset, VkDeviceSize end) { 3398cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis bool tmp_bool = false; 3399f6e16b28b808a342cb92768001afa2cfeee08a11Tobin Ehlis MEMORY_RANGE map_range = {}; 3400cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis map_range.linear = true; 3401cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis map_range.start = offset; 3402cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis map_range.end = end; 3403cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis for (auto &handle_range_pair : mem_info->bound_ranges) { 34042ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (rangesIntersect(dev_data, &handle_range_pair.second, &map_range, &tmp_bool, false)) { 3405cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis // TODO : WARN here if tmp_bool true? 3406cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis handle_range_pair.second.valid = true; 3407cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis } 3408cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis } 3409cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis} 34100ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 34110ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic bool ValidateInsertMemoryRange(layer_data const *dev_data, uint64_t handle, DEVICE_MEM_INFO *mem_info, 34120ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkDeviceSize memoryOffset, VkMemoryRequirements memRequirements, bool is_image, 34130ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton bool is_linear, const char *api_name) { 34140ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton bool skip = false; 34150ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 34160ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton MEMORY_RANGE range; 34170ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.image = is_image; 34180ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.handle = handle; 34190ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.linear = is_linear; 34200ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.valid = mem_info->global_valid; 34210ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.memory = mem_info->mem; 34220ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.start = memoryOffset; 34230ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.size = memRequirements.size; 34240ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.end = memoryOffset + memRequirements.size - 1; 34250ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.aliases.clear(); 34260ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 34270ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Check for aliasing problems. 34280ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton for (auto &obj_range_pair : mem_info->bound_ranges) { 34290ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton auto check_range = &obj_range_pair.second; 34300ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton bool intersection_error = false; 34312ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (rangesIntersect(dev_data, &range, check_range, &intersection_error, false)) { 34320ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip |= intersection_error; 34330ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton range.aliases.insert(check_range); 34340ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 34350ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 34360ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 34370ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton if (memoryOffset >= mem_info->alloc_info.allocationSize) { 3438315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code = is_image ? VALIDATION_ERROR_1740082c : VALIDATION_ERROR_1700080e; 34390ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 34409b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_info->mem), __LINE__, error_code, "MEM", 34410ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64 34420ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton "), memoryOffset=0x%" PRIxLEAST64 " must be less than the memory allocation size 0x%" PRIxLEAST64 ". %s", 34439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus api_name, HandleToUint64(mem_info->mem), handle, memoryOffset, mem_info->alloc_info.allocationSize, 34449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus validation_error_map[error_code]); 34450ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 34460ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 34470ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton return skip; 34480ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton} 34490ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 3450825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Object with given handle is being bound to memory w/ given mem_info struct. 3451825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Track the newly bound memory range with given memoryOffset 3452825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Also scan any previous ranges, track aliased ranges with new range, and flag an error if a linear 3453825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// and non-linear range incorrectly overlap. 3454825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Return true if an error is flagged and the user callback returns "true", otherwise false 3455825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// is_image indicates an image object, otherwise handle is for a buffer 3456825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// is_linear indicates a buffer or linear image 34570ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic void InsertMemoryRange(layer_data const *dev_data, uint64_t handle, DEVICE_MEM_INFO *mem_info, VkDeviceSize memoryOffset, 34580ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkMemoryRequirements memRequirements, bool is_image, bool is_linear) { 34595360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis MEMORY_RANGE range; 3460825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 3461825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.image = is_image; 346247aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski range.handle = handle; 3463825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.linear = is_linear; 3464f541bf53dee6daf82a4c8304354eac599a884d29Tobin Ehlis range.valid = mem_info->global_valid; 3465825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.memory = mem_info->mem; 346647aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski range.start = memoryOffset; 3467825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.size = memRequirements.size; 346847aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski range.end = memoryOffset + memRequirements.size - 1; 34695360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis range.aliases.clear(); 34705360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis // Update Memory aliasing 347175f4c8cec0996021a4258b9bf920a9e0fea4eac1Tobin Ehlis // Save aliased ranges so we can copy into final map entry below. Can't do it in loop b/c we don't yet have final ptr. If we 34725360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis // inserted into map before loop to get the final ptr, then we may enter loop when not needed & we check range against itself 34735360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis std::unordered_set<MEMORY_RANGE *> tmp_alias_ranges; 3474825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis for (auto &obj_range_pair : mem_info->bound_ranges) { 3475825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto check_range = &obj_range_pair.second; 34765360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis bool intersection_error = false; 34772ea938737c34152a86f5e453eaef7f77b45c0ea3Cort Stratton if (rangesIntersect(dev_data, &range, check_range, &intersection_error, true)) { 3478825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis range.aliases.insert(check_range); 34795360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis tmp_alias_ranges.insert(check_range); 3480825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis } 3481825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis } 34825360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis mem_info->bound_ranges[handle] = std::move(range); 34835360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis for (auto tmp_range : tmp_alias_ranges) { 34845360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis tmp_range->aliases.insert(&mem_info->bound_ranges[handle]); 34855360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis } 3486825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis if (is_image) 3487825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_images.insert(handle); 3488825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis else 3489825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_buffers.insert(handle); 349047aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski} 349147aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 34920ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic bool ValidateInsertImageMemoryRange(layer_data const *dev_data, VkImage image, DEVICE_MEM_INFO *mem_info, 34930ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkDeviceSize mem_offset, VkMemoryRequirements mem_reqs, bool is_linear, 34940ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton const char *api_name) { 34959b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateInsertMemoryRange(dev_data, HandleToUint64(image), mem_info, mem_offset, mem_reqs, true, is_linear, api_name); 34960ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton} 34970ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic void InsertImageMemoryRange(layer_data const *dev_data, VkImage image, DEVICE_MEM_INFO *mem_info, VkDeviceSize mem_offset, 34980ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkMemoryRequirements mem_reqs, bool is_linear) { 34999b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus InsertMemoryRange(dev_data, HandleToUint64(image), mem_info, mem_offset, mem_reqs, true, is_linear); 3500825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis} 3501825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 35020ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic bool ValidateInsertBufferMemoryRange(layer_data const *dev_data, VkBuffer buffer, DEVICE_MEM_INFO *mem_info, 35030ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkDeviceSize mem_offset, VkMemoryRequirements mem_reqs, const char *api_name) { 35049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus return ValidateInsertMemoryRange(dev_data, HandleToUint64(buffer), mem_info, mem_offset, mem_reqs, false, true, api_name); 35050ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton} 35060ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Strattonstatic void InsertBufferMemoryRange(layer_data const *dev_data, VkBuffer buffer, DEVICE_MEM_INFO *mem_info, VkDeviceSize mem_offset, 35070ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton VkMemoryRequirements mem_reqs) { 35089b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus InsertMemoryRange(dev_data, HandleToUint64(buffer), mem_info, mem_offset, mem_reqs, false, true); 3509825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis} 3510825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 3511825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// Remove MEMORY_RANGE struct for give handle from bound_ranges of mem_info 3512825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// is_image indicates if handle is for image or buffer 3513825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// This function will also remove the handle-to-index mapping from the appropriate 3514825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis// map and clean up any aliases for range being removed. 3515825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlisstatic void RemoveMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info, bool is_image) { 3516825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis auto erase_range = &mem_info->bound_ranges[handle]; 3517825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis for (auto alias_range : erase_range->aliases) { 3518825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis alias_range->aliases.erase(erase_range); 351947aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 35205360871dd546e8aa7c1a273e9036c201fe4e3ffbTobin Ehlis erase_range->aliases.clear(); 3521825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_ranges.erase(handle); 35221cba4e1b5940c6818572e05dcad5a3a47fafbc9eTobin Ehlis if (is_image) { 3523825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_images.erase(handle); 35241cba4e1b5940c6818572e05dcad5a3a47fafbc9eTobin Ehlis } else { 3525825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis mem_info->bound_buffers.erase(handle); 35261cba4e1b5940c6818572e05dcad5a3a47fafbc9eTobin Ehlis } 352747aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski} 352847aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 3529842b2d28ded1c6e2c38491a81213d0e1d1b7295aMark Lobodzinskivoid RemoveBufferMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info) { RemoveMemoryRange(handle, mem_info, false); } 3530825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 35318c59133586421be878d393799b30044497f77727Mark Lobodzinskivoid RemoveImageMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info) { RemoveMemoryRange(handle, mem_info, true); } 3532825446075d5f6c6b531754c0709bddd9dae8945fTobin Ehlis 3533bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) { 353456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3535e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 3536e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis VK_OBJECT obj_struct; 3537ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3538e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis bool skip = PreCallValidateDestroyBuffer(dev_data, buffer, &buffer_state, &obj_struct); 3539e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis if (!skip) { 3540b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 35414a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyBuffer(device, buffer, pAllocator); 3542e1056daefb39e3a3fed0088874725c56a1359e54Tobin Ehlis lock.lock(); 3543405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (buffer != VK_NULL_HANDLE) { 3544405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyBuffer(dev_data, buffer, buffer_state, obj_struct); 3545405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 354647aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 35475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 35485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3549bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) { 355056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3551f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis // Common data objects used pre & post call 35528e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis BUFFER_VIEW_STATE *buffer_view_state = nullptr; 35538e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis VK_OBJECT obj_struct; 3554ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 35558e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis // Validate state before calling down chain, update common data if we'll be calling down chain 35568e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis bool skip = PreCallValidateDestroyBufferView(dev_data, bufferView, &buffer_view_state, &obj_struct); 355738e26abbaa884eb48bfec4ddb4e0ae2c90634e06Tobin Ehlis if (!skip) { 355838e26abbaa884eb48bfec4ddb4e0ae2c90634e06Tobin Ehlis lock.unlock(); 35594a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyBufferView(device, bufferView, pAllocator); 35608e0ffae5b5c87fa062229b8c003be10c7e48aea1Tobin Ehlis lock.lock(); 3561405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (bufferView != VK_NULL_HANDLE) { 3562405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyBufferView(dev_data, bufferView, buffer_view_state, obj_struct); 3563405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 35645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 35655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 35665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 35672a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin EhlisVKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) { 356856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 35691facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis IMAGE_STATE *image_state = nullptr; 35702a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis VK_OBJECT obj_struct; 3571ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 35722a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis bool skip = PreCallValidateDestroyImage(dev_data, image, &image_state, &obj_struct); 35732a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis if (!skip) { 3574f940225c9e5e3e14b3f5a32d3ea360b585614600Tobin Ehlis lock.unlock(); 35754a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyImage(device, image, pAllocator); 35762a0dd15a44bf665c97a3ff6adcbe7fe5853cdf60Tobin Ehlis lock.lock(); 3577405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (image != VK_NULL_HANDLE) { 3578405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyImage(dev_data, image, image_state, obj_struct); 3579405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 35805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 35815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 35825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 35834261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinskistatic bool ValidateMemoryTypes(const layer_data *dev_data, const DEVICE_MEM_INFO *mem_info, const uint32_t memory_type_bits, 3584f634be57d858a71969b3183cd0e322fe1d0ad0fbMike Weiblen const char *funcName, UNIQUE_VALIDATION_ERROR_CODE msgCode) { 35853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 3586de1d2592cdd497642de5b0e6f27ebc439018383bTobin Ehlis if (((1 << mem_info->alloc_info.memoryTypeIndex) & memory_type_bits) == 0) { 35873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 35889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_info->mem), __LINE__, msgCode, "MT", 35893251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s(): MemoryRequirements->memoryTypeBits (0x%X) for this object type are not compatible with the memory " 35903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "type (0x%X) of this memory object 0x%" PRIx64 ". %s", 35919b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, memory_type_bits, mem_info->alloc_info.memoryTypeIndex, HandleToUint64(mem_info->mem), 35929b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus validation_error_map[msgCode]); 35934261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinski } 35943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 35954261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinski} 35964261f1e2c91c90ce040ab36a13c9d92f6e988f10Mark Lobodzinski 3597160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic bool PreCallValidateBindBufferMemory(layer_data *dev_data, VkBuffer buffer, BUFFER_STATE *buffer_state, VkDeviceMemory mem, 3598160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 35999207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton bool skip = false; 36005cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 3601ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 36029207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // Track objects tied to memory 36039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t buffer_handle = HandleToUint64(buffer); 36047a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski skip = ValidateSetMemBinding(dev_data, mem, buffer_handle, kVulkanObjectTypeBuffer, "vkBindBufferMemory()"); 36052eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis if (!buffer_state->memory_requirements_checked) { 36062eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis // There's not an explicit requirement in the spec to call vkGetBufferMemoryRequirements() prior to calling 36079207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // BindBufferMemory, but it's implied in that memory being bound must conform with VkMemoryRequirements from 36089207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // vkGetBufferMemoryRequirements() 36099207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 36109207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_handle, __LINE__, DRAWSTATE_INVALID_BUFFER, "DS", 36119207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton "vkBindBufferMemory(): Binding memory to buffer 0x%" PRIxLEAST64 36129207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton " but vkGetBufferMemoryRequirements() has not been called on that buffer.", 36139207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_handle); 36142eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis // Make the call for them so we can verify the state 36152eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis lock.unlock(); 36169207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton dev_data->dispatch_table.GetBufferMemoryRequirements(dev_data->device, buffer, &buffer_state->requirements); 36172eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis lock.lock(); 36182eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis } 361947aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 36200ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Validate bound memory range information 36219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 362257fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 36230ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip |= ValidateInsertBufferMemoryRange(dev_data, buffer, mem_info, memoryOffset, buffer_state->requirements, 36240ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton "vkBindBufferMemory()"); 36259207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton skip |= ValidateMemoryTypes(dev_data, mem_info, buffer_state->requirements.memoryTypeBits, "vkBindBufferMemory()", 3626315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17000816); 362747aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 362847aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 36292c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves // Validate memory requirements alignment 363016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(memoryOffset, buffer_state->requirements.alignment) != 0) { 3631f60e41965223825191505eebc96491bb52e494a2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 3632315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis buffer_handle, __LINE__, VALIDATION_ERROR_17000818, "DS", 36339207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton "vkBindBufferMemory(): memoryOffset is 0x%" PRIxLEAST64 36349207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton " but must be an integer multiple of the " 36359207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton "VkMemoryRequirements::alignment value 0x%" PRIxLEAST64 36369207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton ", returned from a call to vkGetBufferMemoryRequirements with buffer. %s", 3637315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis memoryOffset, buffer_state->requirements.alignment, validation_error_map[VALIDATION_ERROR_17000818]); 36382c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves } 3639ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller 3640160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton // Validate memory requirements size 3641160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton if (buffer_state->requirements.size > (mem_info->alloc_info.allocationSize - memoryOffset)) { 3642160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 3643315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis buffer_handle, __LINE__, VALIDATION_ERROR_1700081a, "DS", 3644160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "vkBindBufferMemory(): memory size minus memoryOffset is 0x%" PRIxLEAST64 3645160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton " but must be at least as large as " 3646160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "VkMemoryRequirements::size value 0x%" PRIxLEAST64 3647160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton ", returned from a call to vkGetBufferMemoryRequirements with buffer. %s", 3648160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton mem_info->alloc_info.allocationSize - memoryOffset, buffer_state->requirements.size, 3649315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1700081a]); 3650160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton } 3651160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton 36522c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves // Validate device limits alignments 3653ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller static const VkBufferUsageFlagBits usage_list[3] = { 3654ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller static_cast<VkBufferUsageFlagBits>(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), 3655bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT}; 3656bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski static const char *memory_type[3] = {"texel", "uniform", "storage"}; 3657bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski static const char *offset_name[3] = {"minTexelBufferOffsetAlignment", "minUniformBufferOffsetAlignment", 3658bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "minStorageBufferOffsetAlignment"}; 3659cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski 36609207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton // TODO: vk_validation_stats.py cannot abide braces immediately preceding or following a validation error enum 3661cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // clang-format off 3662315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis static const UNIQUE_VALIDATION_ERROR_CODE msgCode[3] = { VALIDATION_ERROR_17000810, VALIDATION_ERROR_17000812, 3663315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17000814 }; 3664cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // clang-format on 3665ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller 3666ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller // Keep this one fresh! 3667ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller const VkDeviceSize offset_requirement[3] = { 3668ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller dev_data->phys_dev_properties.properties.limits.minTexelBufferOffsetAlignment, 3669ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment, 3670bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment}; 36718718070cf3e206488c168f1e6b9dd06d6880c9bcTobin Ehlis VkBufferUsageFlags usage = dev_data->bufferMap[buffer].get()->createInfo.usage; 3672ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller 3673ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller for (int i = 0; i < 3; i++) { 3674ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller if (usage & usage_list[i]) { 367516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(memoryOffset, offset_requirement[i]) != 0) { 36769207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton skip |= log_msg( 3677f60e41965223825191505eebc96491bb52e494a2Cort Stratton dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, buffer_handle, 3678cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski __LINE__, msgCode[i], "DS", "vkBindBufferMemory(): %s memoryOffset is 0x%" PRIxLEAST64 3679cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " but must be a multiple of " 3680cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "device limit %s 0x%" PRIxLEAST64 ". %s", 3681cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski memory_type[i], memoryOffset, offset_name[i], offset_requirement[i], validation_error_map[msgCode[i]]); 3682ba4316045bf5f1054629bb7c2fced7bae98ed52aMark Mueller } 36832c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves } 36842c905c8b5aca814df6c680348145ca48885f9f69Dustin Graves } 36855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 36869207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton return skip; 36879207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton} 36889207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton 3689160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic void PostCallRecordBindBufferMemory(layer_data *dev_data, VkBuffer buffer, BUFFER_STATE *buffer_state, VkDeviceMemory mem, 3690160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 36919207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton if (buffer_state) { 3692ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 36930ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Track bound memory range information 36940ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton auto mem_info = GetMemObjInfo(dev_data, mem); 36950ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton if (mem_info) { 36960ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton InsertBufferMemoryRange(dev_data, buffer, mem_info, memoryOffset, buffer_state->requirements); 36970ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 36980ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 3699c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // Track objects tied to memory 37009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t buffer_handle = HandleToUint64(buffer); 37017a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski SetMemBinding(dev_data, mem, buffer_handle, kVulkanObjectTypeBuffer, "vkBindBufferMemory()"); 3702c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton 37039207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_state->binding.mem = mem; 37049207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_state->binding.offset = memoryOffset; 37059207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton buffer_state->binding.size = buffer_state->requirements.size; 37069207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton } 37079207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton} 37089207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton 37099207132ef623d47fcbdfeb9ebc796eade35a2f4cCort StrattonVKAPI_ATTR VkResult VKAPI_CALL BindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memoryOffset) { 37109207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 37119207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 3712160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton auto buffer_state = GetBufferState(dev_data, buffer); 3713160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton bool skip = PreCallValidateBindBufferMemory(dev_data, buffer, buffer_state, mem, memoryOffset); 37149207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton if (!skip) { 37154a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.BindBufferMemory(device, buffer, mem, memoryOffset); 37169207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton if (result == VK_SUCCESS) { 3717160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton PostCallRecordBindBufferMemory(dev_data, buffer, buffer_state, mem, memoryOffset); 37189207132ef623d47fcbdfeb9ebc796eade35a2f4cCort Stratton } 37195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 37205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 37215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 37225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3723bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL GetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, 3724bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkMemoryRequirements *pMemoryRequirements) { 372556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 372615caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis dev_data->dispatch_table.GetBufferMemoryRequirements(device, buffer, pMemoryRequirements); 37279a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 372815caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis if (buffer_state) { 372915caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis buffer_state->requirements = *pMemoryRequirements; 37302eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis buffer_state->memory_requirements_checked = true; 373115caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis } 37325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 37335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3734bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL GetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements *pMemoryRequirements) { 373556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 373615caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis dev_data->dispatch_table.GetImageMemoryRequirements(device, image, pMemoryRequirements); 37379a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 373815caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis if (image_state) { 373915caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis image_state->requirements = *pMemoryRequirements; 37402eda842d84a02b9d5bfb03d6c26c5f7c00e6e8beTobin Ehlis image_state->memory_requirements_checked = true; 374115caa3e8f88f57bdcc42a3eabb9375e57007e5aaTobin Ehlis } 37425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 3743593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 3744bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) { 374556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3746f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis // Common data objects used pre & post call 3747f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis IMAGE_VIEW_STATE *image_view_state = nullptr; 3748f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis VK_OBJECT obj_struct; 3749ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3750f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis bool skip = PreCallValidateDestroyImageView(dev_data, imageView, &image_view_state, &obj_struct); 3751d85c42a6c1d6ad7a6f684c5bd793aab482b7705cTobin Ehlis if (!skip) { 3752d85c42a6c1d6ad7a6f684c5bd793aab482b7705cTobin Ehlis lock.unlock(); 37534a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyImageView(device, imageView, pAllocator); 3754f61017735c3291a2665487f2bac310578fc60a68Tobin Ehlis lock.lock(); 3755405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (imageView != VK_NULL_HANDLE) { 3756405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyImageView(dev_data, imageView, image_view_state, obj_struct); 3757405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3758d85c42a6c1d6ad7a6f684c5bd793aab482b7705cTobin Ehlis } 37595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 37605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3761bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyShaderModule(VkDevice device, VkShaderModule shaderModule, 3762bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 376356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3764918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes 3765ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 376651ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->shaderModuleMap.erase(shaderModule); 3767b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3768918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes 376951ea774638f432bd8e700ec8291a980f405f429eTobin Ehlis dev_data->dispatch_table.DestroyShaderModule(device, shaderModule, pAllocator); 37705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 37715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 37724c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic bool PreCallValidateDestroyPipeline(layer_data *dev_data, VkPipeline pipeline, PIPELINE_STATE **pipeline_state, 37738bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis VK_OBJECT *obj_struct) { 377494165f5005d1fa37801d49067fe7751789b89d27Tobin Ehlis *pipeline_state = getPipelineState(dev_data, pipeline); 37759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(pipeline), kVulkanObjectTypePipeline}; 3776cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_pipeline) return false; 37778bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis bool skip = false; 37788bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis if (*pipeline_state) { 3779315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *pipeline_state, *obj_struct, VALIDATION_ERROR_25c005fa); 37808bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis } 37818bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis return skip; 37828bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis} 37838bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis 37844c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisstatic void PostCallRecordDestroyPipeline(layer_data *dev_data, VkPipeline pipeline, PIPELINE_STATE *pipeline_state, 37858bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis VK_OBJECT obj_struct) { 37868bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis // Any bound cmd buffers are now invalid 378739c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, pipeline_state->cb_bindings, obj_struct); 37880a136bc9fe42c042857c90a421d0426bd0c029efGabríel Arthúr Pétursson delete getPipelineState(dev_data, pipeline); 37898bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis dev_data->pipelineMap.erase(pipeline); 37908bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis} 37918bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis 3792bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) { 379356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 37944c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pipeline_state = nullptr; 37958bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis VK_OBJECT obj_struct; 3796ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 37978bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis bool skip = PreCallValidateDestroyPipeline(dev_data, pipeline, &pipeline_state, &obj_struct); 3798f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3799f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 38004a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyPipeline(device, pipeline, pAllocator); 38018bd2ec9a26cca477de2de93304774cdba0af77bcTobin Ehlis lock.lock(); 3802405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (pipeline != VK_NULL_HANDLE) { 3803405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyPipeline(dev_data, pipeline, pipeline_state, obj_struct); 3804405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3805f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 38065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3808bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, 3809bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 381056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3811ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 38126792ea7cc0ce5fa64b7bd6c946460608cbda91c7Tobin Ehlis dev_data->pipelineLayoutMap.erase(pipelineLayout); 3813e28cddb35c63274c13873b9a7060ad43b255c6f1Tobin Ehlis lock.unlock(); 3814e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 38154a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyPipelineLayout(device, pipelineLayout, pAllocator); 38165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3818d31a44af6da568692a73201825459689c9431867Tobin Ehlisstatic bool PreCallValidateDestroySampler(layer_data *dev_data, VkSampler sampler, SAMPLER_STATE **sampler_state, 3819806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis VK_OBJECT *obj_struct) { 38209a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *sampler_state = GetSamplerState(dev_data, sampler); 38219b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(sampler), kVulkanObjectTypeSampler}; 3822cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_sampler) return false; 3823806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis bool skip = false; 3824806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis if (*sampler_state) { 3825315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *sampler_state, *obj_struct, VALIDATION_ERROR_26600874); 3826806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis } 3827806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis return skip; 3828806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis} 3829806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis 3830d31a44af6da568692a73201825459689c9431867Tobin Ehlisstatic void PostCallRecordDestroySampler(layer_data *dev_data, VkSampler sampler, SAMPLER_STATE *sampler_state, 3831806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis VK_OBJECT obj_struct) { 3832806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis // Any bound cmd buffers are now invalid 3833cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (sampler_state) invalidateCommandBuffers(dev_data, sampler_state->cb_bindings, obj_struct); 3834806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis dev_data->samplerMap.erase(sampler); 3835806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis} 3836806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis 3837bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) { 383856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3839d31a44af6da568692a73201825459689c9431867Tobin Ehlis SAMPLER_STATE *sampler_state = nullptr; 3840806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis VK_OBJECT obj_struct; 3841ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3842806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis bool skip = PreCallValidateDestroySampler(dev_data, sampler, &sampler_state, &obj_struct); 3843f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis if (!skip) { 3844f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis lock.unlock(); 38454a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroySampler(device, sampler, pAllocator); 3846806095ea973371ad4c82bd0c2c58d53cc5557f0bTobin Ehlis lock.lock(); 3847405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (sampler != VK_NULL_HANDLE) { 3848405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroySampler(dev_data, sampler, sampler_state, obj_struct); 3849405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3850f57cf525e45f3a65e25c2691464d65e29a79ba77Tobin Ehlis } 38515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 385379c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlisstatic void PostCallRecordDestroyDescriptorSetLayout(layer_data *dev_data, VkDescriptorSetLayout ds_layout) { 385479c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis dev_data->descriptorSetLayoutMap.erase(ds_layout); 385579c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis} 385679c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis 3857bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, 3858bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 385956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 386079c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis dev_data->dispatch_table.DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator); 3861ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 386279c5b660cd51e93e279c1aa001a42801d3bf7a5dTobin Ehlis PostCallRecordDestroyDescriptorSetLayout(dev_data, descriptorSetLayout); 38635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 38645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3865c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlisstatic bool PreCallValidateDestroyDescriptorPool(layer_data *dev_data, VkDescriptorPool pool, 3866a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE **desc_pool_state, VK_OBJECT *obj_struct) { 38679a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *desc_pool_state = GetDescriptorPoolState(dev_data, pool); 38689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(pool), kVulkanObjectTypeDescriptorPool}; 3869cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_descriptor_pool) return false; 3870c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis bool skip = false; 3871c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis if (*desc_pool_state) { 3872315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *desc_pool_state, *obj_struct, VALIDATION_ERROR_2440025e); 3873c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis } 3874c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis return skip; 3875c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis} 3876c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis 3877c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlisstatic void PostCallRecordDestroyDescriptorPool(layer_data *dev_data, VkDescriptorPool descriptorPool, 3878a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE *desc_pool_state, VK_OBJECT obj_struct) { 3879c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis // Any bound cmd buffers are now invalid 388039c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, desc_pool_state->cb_bindings, obj_struct); 3881c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis // Free sets that were in this pool 3882c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis for (auto ds : desc_pool_state->sets) { 3883c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis freeDescriptorSet(dev_data, ds); 3884c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis } 3885c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis dev_data->descriptorPoolMap.erase(descriptorPool); 3886ee7e96d032744c1db89cab21362ac8ecad6eec5aGabríel Arthúr Pétursson delete desc_pool_state; 3887c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis} 3888c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis 3889bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, 3890bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 389156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 3892a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE *desc_pool_state = nullptr; 3893c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis VK_OBJECT obj_struct; 3894ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3895c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis bool skip = PreCallValidateDestroyDescriptorPool(dev_data, descriptorPool, &desc_pool_state, &obj_struct); 3896c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis if (!skip) { 3897c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis lock.unlock(); 3898c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis dev_data->dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator); 3899c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis lock.lock(); 3900405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (descriptorPool != VK_NULL_HANDLE) { 3901405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyDescriptorPool(dev_data, descriptorPool, desc_pool_state, obj_struct); 3902405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 3903c656e38f76da254b8b19e653d0945cabb43329bcTobin Ehlis } 39045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski// Verify cmdBuffer in given cb_node is not in global in-flight set, and return skip result 3906bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// If this is a secondary command buffer, then make sure its primary is also in-flight 3907bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// If primary is not in-flight, then remove secondary from global in-flight set 3908bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// This function is only valid at a point when cmdBuffer is being reset or freed 3909cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlisstatic bool checkCommandBufferInFlight(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *action, 3910cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 39113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 3912a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if (cb_node->in_use.load()) { 3913a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 3914a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes HandleToUint64(cb_node->commandBuffer), __LINE__, error_code, "DS", 3915a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes "Attempt to %s command buffer (0x%p) which is in use. %s", action, cb_node->commandBuffer, 3916a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes validation_error_map[error_code]); 3917bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis } 39183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 3919bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis} 3920a964cad279f9749cd9ebfc7555247ff3bff26d53Chris Forbes 3921bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis// Iterate over all cmdBuffers in given commandPool and verify that each is not in use 3922cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlisstatic bool checkCommandBuffersInFlight(layer_data *dev_data, COMMAND_POOL_NODE *pPool, const char *action, 3923cdc73d5b6b64942b377db7220cd16b4045f73c9aTobin Ehlis UNIQUE_VALIDATION_ERROR_CODE error_code) { 39243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 3925a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes for (auto cmd_buffer : pPool->commandBuffers) { 3926a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes skip |= checkCommandBufferInFlight(dev_data, GetCBNode(dev_data, cmd_buffer), action, error_code); 3927bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis } 39283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 3929bc300ace5ad8d1935d42ee5dbbf36ce6ace4c0e8Tobin Ehlis} 39305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 3931bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, 3932bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkCommandBuffer *pCommandBuffers) { 393356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 39343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 3935ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 3936c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes 39375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < commandBufferCount; i++) { 39389a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, pCommandBuffers[i]); 39395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Delete CB information structure, and remove from commandBufferMap 39409f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis if (cb_node) { 3941315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBufferInFlight(dev_data, cb_node, "free", VALIDATION_ERROR_2840005e); 3942c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes } 3943c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes } 3944c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes 39453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return; 3946c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes 39479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, commandPool); 3948c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes for (uint32_t i = 0; i < commandBufferCount; i++) { 39499a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, pCommandBuffers[i]); 3950c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes // Delete CB information structure, and remove from commandBufferMap 39519f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis if (cb_node) { 39525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // reset prior to delete for data clean-up 3953a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes // TODO: fix this, it's insane. 39549f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis resetCB(dev_data, cb_node->commandBuffer); 39559f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis dev_data->commandBufferMap.erase(cb_node->commandBuffer); 39569f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis delete cb_node; 39575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 39585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 39595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Remove commandBuffer reference from commandPoolMap 3960c05d773a018aa47e89841533a6968d9e5b314038Chris Forbes pPool->commandBuffers.remove(pCommandBuffers[i]); 39615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 3962b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 3963e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 39644a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers); 39655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 396789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, 3968bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool) { 396956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 39705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 39714a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool); 39725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 39735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 3974ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 39755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->commandPoolMap[*pCommandPool].createFlags = pCreateInfo->flags; 39765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->commandPoolMap[*pCommandPool].queueFamilyIndex = pCreateInfo->queueFamilyIndex; 39775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 39785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 39795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 39805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 398189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, 398289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) { 398356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 39840c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis bool skip = false; 39850c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis if (pCreateInfo && pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) { 39860c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis if (!dev_data->enabled_features.pipelineStatisticsQuery) { 39870c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, 0, 3988315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11c0062e, "DS", 39890c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis "Query pool with type VK_QUERY_TYPE_PIPELINE_STATISTICS created on a device " 39900c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis "with VkDeviceCreateInfo.pEnabledFeatures.pipelineStatisticsQuery == VK_FALSE. %s", 3991315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_11c0062e]); 39920c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis } 39930c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis } 39940c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis 39950c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 39960c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis if (!skip) { 39970c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis result = dev_data->dispatch_table.CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool); 39980c45ab93ccfb9d39698ae47d6102d2e308ff476eTobin Ehlis } 39995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 4000ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4001eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis QUERY_POOL_NODE *qp_node = &dev_data->queryPoolMap[*pQueryPool]; 4002eafbf0b68ee6ea6e0bf33f07e0058d00a96efd9aTobin Ehlis qp_node->createInfo = *pCreateInfo; 40035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 40045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 40055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 40065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 40075f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlisstatic bool PreCallValidateDestroyCommandPool(layer_data *dev_data, VkCommandPool pool, COMMAND_POOL_NODE **cp_state) { 40089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *cp_state = GetCommandPoolNode(dev_data, pool); 4009cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_command_pool) return false; 40105f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis bool skip = false; 40115f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis if (*cp_state) { 40125f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis // Verify that command buffers in pool are complete (not in-flight) 4013315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBuffersInFlight(dev_data, *cp_state, "destroy command pool with", VALIDATION_ERROR_24000052); 40145f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis } 40155f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis return skip; 40165f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis} 40175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 40185f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlisstatic void PostCallRecordDestroyCommandPool(layer_data *dev_data, VkCommandPool pool, COMMAND_POOL_NODE *cp_state) { 40199f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis // Must remove cmdpool from cmdpoolmap, after removing all cmdbuffers in its list from the commandBufferMap 40205f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis for (auto cb : cp_state->commandBuffers) { 40219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, cb); 40227b34d10b918c1f69e7252174965c6a7a7c35ae05Chris Forbes clear_cmd_buf_and_mem_references(dev_data, cb_node); 4023d61de0e68063faa169a9a632f811c9c9adec9897Tobin Ehlis // Remove references to this cb_node prior to delete 4024d61de0e68063faa169a9a632f811c9c9adec9897Tobin Ehlis // TODO : Need better solution here, resetCB? 40257165385f3a39f1f951f3a6a9a06ed2cce4642b6dMark Lobodzinski for (auto obj : cb_node->object_bindings) { 40267165385f3a39f1f951f3a6a9a06ed2cce4642b6dMark Lobodzinski removeCommandBufferBinding(dev_data, &obj, cb_node); 40277165385f3a39f1f951f3a6a9a06ed2cce4642b6dMark Lobodzinski } 4028d61de0e68063faa169a9a632f811c9c9adec9897Tobin Ehlis for (auto framebuffer : cb_node->framebuffers) { 40299a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fb_state = GetFramebufferState(dev_data, framebuffer); 4030cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (fb_state) fb_state->cb_bindings.erase(cb_node); 4031d61de0e68063faa169a9a632f811c9c9adec9897Tobin Ehlis } 4032cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski dev_data->commandBufferMap.erase(cb); // Remove this command buffer 4033cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski delete cb_node; // delete CB info structure 4034a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes } 40355f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis dev_data->commandPoolMap.erase(pool); 40365f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis} 4037e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 40385f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis// Destroy commandPool along with all of the commandBuffers allocated from that pool 40395f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin EhlisVKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) { 404056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 40415f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis COMMAND_POOL_NODE *cp_state = nullptr; 4042ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 40435f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis bool skip = PreCallValidateDestroyCommandPool(dev_data, commandPool, &cp_state); 40445f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis if (!skip) { 40455f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis lock.unlock(); 40465f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis dev_data->dispatch_table.DestroyCommandPool(device, commandPool, pAllocator); 40475f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis lock.lock(); 4048405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (commandPool != VK_NULL_HANDLE) { 4049405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyCommandPool(dev_data, commandPool, cp_state); 4050405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 40515f9c0dbd099bd351bc564e0f05170ceeadcc995dTobin Ehlis } 40525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 40535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4054bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL ResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags) { 405556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 40563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4057400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis 4058ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 40599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, commandPool); 4060315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBuffersInFlight(dev_data, pPool, "reset command pool with", VALIDATION_ERROR_32800050); 40611ec6311a8537f4467db08eacbd762ebaa87e70b0Chris Forbes lock.unlock(); 4062a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes 40633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 40645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 40654a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetCommandPool(device, commandPool, flags); 40665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 40675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Reset all of the CBs allocated from this pool 40685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 40691ec6311a8537f4467db08eacbd762ebaa87e70b0Chris Forbes lock.lock(); 4070a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes for (auto cmdBuffer : pPool->commandBuffers) { 4071a01b5eb150981aad061238e64b173d0da8c11140Chris Forbes resetCB(dev_data, cmdBuffer); 40725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 40731ec6311a8537f4467db08eacbd762ebaa87e70b0Chris Forbes lock.unlock(); 40745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 40755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 40765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 40775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 407889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) { 407956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 40803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4081ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 40825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < fenceCount; ++i) { 40839a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, pFences[i]); 4084090da73358f71ba026e2474a822fecf55267d166Chris Forbes if (pFence && pFence->state == FENCE_INFLIGHT) { 4085315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 4086315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, 4087315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pFences[i]), __LINE__, VALIDATION_ERROR_32e008c6, "DS", "Fence 0x%" PRIx64 " is in use. %s", 4088315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pFences[i]), validation_error_map[VALIDATION_ERROR_32e008c6]); 40895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 40905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4091b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 4092090da73358f71ba026e2474a822fecf55267d166Chris Forbes 40933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 4094090da73358f71ba026e2474a822fecf55267d166Chris Forbes 40954a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetFences(device, fenceCount, pFences); 4096090da73358f71ba026e2474a822fecf55267d166Chris Forbes 4097090da73358f71ba026e2474a822fecf55267d166Chris Forbes if (result == VK_SUCCESS) { 4098090da73358f71ba026e2474a822fecf55267d166Chris Forbes lock.lock(); 4099090da73358f71ba026e2474a822fecf55267d166Chris Forbes for (uint32_t i = 0; i < fenceCount; ++i) { 41009a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, pFences[i]); 4101090da73358f71ba026e2474a822fecf55267d166Chris Forbes if (pFence) { 4102090da73358f71ba026e2474a822fecf55267d166Chris Forbes pFence->state = FENCE_UNSIGNALED; 4103090da73358f71ba026e2474a822fecf55267d166Chris Forbes } 4104090da73358f71ba026e2474a822fecf55267d166Chris Forbes } 4105090da73358f71ba026e2474a822fecf55267d166Chris Forbes lock.unlock(); 4106090da73358f71ba026e2474a822fecf55267d166Chris Forbes } 4107090da73358f71ba026e2474a822fecf55267d166Chris Forbes 41085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 41095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4111e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis// For given cb_nodes, invalidate them and track object causing invalidation 41120a4087f99558069e9f6a437ff2dbb5a9c1c22ccaTobin Ehlisvoid invalidateCommandBuffers(const layer_data *dev_data, std::unordered_set<GLOBAL_CB_NODE *> const &cb_nodes, VK_OBJECT obj) { 4113e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis for (auto cb_node : cb_nodes) { 411439c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis if (cb_node->state == CB_RECORDING) { 411539c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 41169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", 4117226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "Invalidating a command buffer that's currently being recorded: 0x%p.", cb_node->commandBuffer); 411846daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes cb_node->state = CB_INVALID_INCOMPLETE; 411946daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes } 412046daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes else { 412146daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes cb_node->state = CB_INVALID_COMPLETE; 412239c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis } 4123e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis cb_node->broken_bindings.push_back(obj); 4124db365f522319df6446b50584277a3bbfee1c1052Chris Forbes 4125db365f522319df6446b50584277a3bbfee1c1052Chris Forbes // if secondary, then propagate the invalidation to the primaries that will call us. 4126db365f522319df6446b50584277a3bbfee1c1052Chris Forbes if (cb_node->createInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) { 4127db365f522319df6446b50584277a3bbfee1c1052Chris Forbes invalidateCommandBuffers(dev_data, cb_node->linkedCommandBuffers, obj); 4128db365f522319df6446b50584277a3bbfee1c1052Chris Forbes } 4129e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis } 4130e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis} 4131e1cc7cf9e8a7808209ecc45df2421f3a494dacccTobin Ehlis 4132c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic bool PreCallValidateDestroyFramebuffer(layer_data *dev_data, VkFramebuffer framebuffer, 4133c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis FRAMEBUFFER_STATE **framebuffer_state, VK_OBJECT *obj_struct) { 41349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *framebuffer_state = GetFramebufferState(dev_data, framebuffer); 41359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(framebuffer), kVulkanObjectTypeFramebuffer}; 4136cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_framebuffer) return false; 4137728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis bool skip = false; 4138728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis if (*framebuffer_state) { 4139315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *framebuffer_state, *obj_struct, VALIDATION_ERROR_250006f8); 4140728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis } 4141728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis return skip; 4142728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis} 4143728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis 4144c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic void PostCallRecordDestroyFramebuffer(layer_data *dev_data, VkFramebuffer framebuffer, FRAMEBUFFER_STATE *framebuffer_state, 4145728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis VK_OBJECT obj_struct) { 414639c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, framebuffer_state->cb_bindings, obj_struct); 4147728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis dev_data->frameBufferMap.erase(framebuffer); 4148728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis} 4149728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis 4150bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) { 415156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4152c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis FRAMEBUFFER_STATE *framebuffer_state = nullptr; 4153728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis VK_OBJECT obj_struct; 4154ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4155728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis bool skip = PreCallValidateDestroyFramebuffer(dev_data, framebuffer, &framebuffer_state, &obj_struct); 4156728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis if (!skip) { 4157728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis lock.unlock(); 4158728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis dev_data->dispatch_table.DestroyFramebuffer(device, framebuffer, pAllocator); 4159728a3e68af2277743cc59185dab7281e96480efeTobin Ehlis lock.lock(); 4160405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (framebuffer != VK_NULL_HANDLE) { 4161405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyFramebuffer(dev_data, framebuffer, framebuffer_state, obj_struct); 4162405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 41635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 41645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 41660ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlisstatic bool PreCallValidateDestroyRenderPass(layer_data *dev_data, VkRenderPass render_pass, RENDER_PASS_STATE **rp_state, 41670ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis VK_OBJECT *obj_struct) { 41689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *rp_state = GetRenderPassState(dev_data, render_pass); 41699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus *obj_struct = {HandleToUint64(render_pass), kVulkanObjectTypeRenderPass}; 4170cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.destroy_renderpass) return false; 41710ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis bool skip = false; 41720ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis if (*rp_state) { 4173315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateObjectNotInUse(dev_data, *rp_state, *obj_struct, VALIDATION_ERROR_264006d2); 41740ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis } 41750ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis return skip; 41760ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis} 41770ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis 41780ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlisstatic void PostCallRecordDestroyRenderPass(layer_data *dev_data, VkRenderPass render_pass, RENDER_PASS_STATE *rp_state, 41790ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis VK_OBJECT obj_struct) { 418039c845ed4c066740e9efaed0a00af51be07c67c1Tobin Ehlis invalidateCommandBuffers(dev_data, rp_state->cb_bindings, obj_struct); 41810ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis dev_data->renderPassMap.erase(render_pass); 41820ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis} 41830ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis 4184bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) { 418556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 41860ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis RENDER_PASS_STATE *rp_state = nullptr; 41870ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis VK_OBJECT obj_struct; 4188ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 41890ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis bool skip = PreCallValidateDestroyRenderPass(dev_data, renderPass, &rp_state, &obj_struct); 4190a9fbfe0c622e9fa4b56ddd015ed4c3c409020c2eTobin Ehlis if (!skip) { 4191a9fbfe0c622e9fa4b56ddd015ed4c3c409020c2eTobin Ehlis lock.unlock(); 41924a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyRenderPass(device, renderPass, pAllocator); 41930ffd03853dc28123fa113e6cd49264838559ee39Tobin Ehlis lock.lock(); 4194405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (renderPass != VK_NULL_HANDLE) { 4195405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour PostCallRecordDestroyRenderPass(dev_data, renderPass, rp_state, obj_struct); 4196405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4197a9fbfe0c622e9fa4b56ddd015ed4c3c409020c2eTobin Ehlis } 41985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 41995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 420089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, 420189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) { 420256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4203ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 42043683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski bool skip = PreCallValidateCreateBuffer(dev_data, pCreateInfo); 42053683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski lock.unlock(); 42063683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 42073683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 42084a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateBuffer(device, pCreateInfo, pAllocator, pBuffer); 42095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 42105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 42113683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski lock.lock(); 42123683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski PostCallRecordCreateBuffer(dev_data, pCreateInfo, pBuffer); 42133683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski lock.unlock(); 42145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 42155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 42165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 42175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 421889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo, 421989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkBufferView *pView) { 422056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4221ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 42223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateCreateBufferView(dev_data, pCreateInfo); 42238c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 42243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 42254a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateBufferView(device, pCreateInfo, pAllocator, pView); 42265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 42278c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.lock(); 42283683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski PostCallRecordCreateBufferView(dev_data, pCreateInfo, pView); 42298c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 42305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 42315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 42325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 42335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 42348dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski// Access helper functions for external modules 4235d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinskiconst VkFormatProperties *GetFormatProperties(core_validation::layer_data *device_data, VkFormat format) { 4236d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski VkFormatProperties *format_properties = new VkFormatProperties; 4237d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_layer_data *instance_data = 4238d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski GetLayerDataPtr(get_dispatch_key(device_data->instance_data->instance), instance_layer_data_map); 4239d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceFormatProperties(device_data->physical_device, format, format_properties); 4240d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski return format_properties; 42418dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 42428dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 4243d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinskiconst VkImageFormatProperties *GetImageFormatProperties(core_validation::layer_data *device_data, VkFormat format, 4244d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski VkImageType image_type, VkImageTiling tiling, VkImageUsageFlags usage, 4245d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski VkImageCreateFlags flags) { 4246d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski VkImageFormatProperties *image_format_properties = new VkImageFormatProperties; 4247d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_layer_data *instance_data = 4248d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski GetLayerDataPtr(get_dispatch_key(device_data->instance_data->instance), instance_layer_data_map); 4249d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceImageFormatProperties(device_data->physical_device, format, image_type, tiling, 4250d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski usage, flags, image_format_properties); 4251d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinski return image_format_properties; 42528dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 42538dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 42547a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlisconst debug_report_data *GetReportData(const core_validation::layer_data *device_data) { return device_data->report_data; } 42558dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 42568dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinskiconst VkPhysicalDeviceProperties *GetPhysicalDeviceProperties(core_validation::layer_data *device_data) { 42578dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski return &device_data->phys_dev_props; 42588dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski} 42598dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski 42608c59133586421be878d393799b30044497f77727Mark Lobodzinskiconst CHECK_DISABLED *GetDisables(core_validation::layer_data *device_data) { return &device_data->instance_data->disabled; } 42618c59133586421be878d393799b30044497f77727Mark Lobodzinski 42628c59133586421be878d393799b30044497f77727Mark Lobodzinskistd::unordered_map<VkImage, std::unique_ptr<IMAGE_STATE>> *GetImageMap(core_validation::layer_data *device_data) { 42638c59133586421be878d393799b30044497f77727Mark Lobodzinski return &device_data->imageMap; 42648c59133586421be878d393799b30044497f77727Mark Lobodzinski} 42658c59133586421be878d393799b30044497f77727Mark Lobodzinski 42668c59133586421be878d393799b30044497f77727Mark Lobodzinskistd::unordered_map<VkImage, std::vector<ImageSubresourcePair>> *GetImageSubresourceMap(core_validation::layer_data *device_data) { 42678c59133586421be878d393799b30044497f77727Mark Lobodzinski return &device_data->imageSubresourceMap; 42688c59133586421be878d393799b30044497f77727Mark Lobodzinski} 42698c59133586421be878d393799b30044497f77727Mark Lobodzinski 42708c59133586421be878d393799b30044497f77727Mark Lobodzinskistd::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> *GetImageLayoutMap(layer_data *device_data) { 42718c59133586421be878d393799b30044497f77727Mark Lobodzinski return &device_data->imageLayoutMap; 42728c59133586421be878d393799b30044497f77727Mark Lobodzinski} 42738c59133586421be878d393799b30044497f77727Mark Lobodzinski 42740db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlisstd::unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> const *GetImageLayoutMap(layer_data const *device_data) { 42750db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis return &device_data->imageLayoutMap; 42760db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis} 42770db18ab1345f9e10907913b22ea5d57bd48077ebTobin Ehlis 42783683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskistd::unordered_map<VkBuffer, std::unique_ptr<BUFFER_STATE>> *GetBufferMap(layer_data *device_data) { 42793683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski return &device_data->bufferMap; 42803683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 42813683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 42823683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinskistd::unordered_map<VkBufferView, std::unique_ptr<BUFFER_VIEW_STATE>> *GetBufferViewMap(layer_data *device_data) { 42833683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski return &device_data->bufferViewMap; 42843683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski} 42853683836d93195a82dfd2c715ce9d56b030801598Mark Lobodzinski 42861c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinskistd::unordered_map<VkImageView, std::unique_ptr<IMAGE_VIEW_STATE>> *GetImageViewMap(layer_data *device_data) { 42871c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski return &device_data->imageViewMap; 42881c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski} 42891c143ebdb651ea034e0b1f8731cb9f361e2f8b82Mark Lobodzinski 4290d0b59d0aabea9048c518840e762c7a510927c132Mark Lobodzinskiconst PHYS_DEV_PROPERTIES_NODE *GetPhysDevProperties(const layer_data *device_data) { 42916a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski return &device_data->phys_dev_properties; 42926a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski} 42936a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski 42945f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinskiconst VkPhysicalDeviceFeatures *GetEnabledFeatures(const layer_data *device_data) { 42955f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinski return &device_data->enabled_features; 42965f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinski} 42975f3e7c34de87353f38bbcd79e12de8af4a9e7695Mark Lobodzinski 4298a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinskiconst DeviceExtensions *GetDeviceExtensions(const layer_data *device_data) { return &device_data->extensions; } 42990e2296e24065d02615ee87561bbb80af414a1ddfMike Schuchardt 430089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, 430189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkImage *pImage) { 43028dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 430356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43048dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski bool skip = PreCallValidateCreateImage(dev_data, pCreateInfo, pAllocator, pImage); 43058dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski if (!skip) { 43068dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski result = dev_data->dispatch_table.CreateImage(device, pCreateInfo, pAllocator, pImage); 43078dea300c362f709ad26886548ea46eb4c315e401Mark Lobodzinski } 43085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4309ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4310920311b6aa5614a545cad59521770d0898a75d65Mark Lobodzinski PostCallRecordCreateImage(dev_data, pCreateInfo, pImage); 43115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 43125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 43158c07a094dc9cc4afb6b62181f341c12b9e969041Mark YoungVKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, 43168c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young const VkAllocationCallbacks *pAllocator, VkImageView *pView) { 431756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4318ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 4319e3effabf8e97cae8e006477806ceaca62e4f2ce7Tobin Ehlis bool skip = PreCallValidateCreateImageView(dev_data, pCreateInfo); 43208c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 4321cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 43224a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateImageView(device, pCreateInfo, pAllocator, pView); 43235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 43248c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.lock(); 432579fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis PostCallRecordCreateImageView(dev_data, pCreateInfo, *pView); 43268c07a094dc9cc4afb6b62181f341c12b9e969041Mark Young lock.unlock(); 43275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4328bb6624cb996175d8945190886a200e720b3871efChris Forbes 43295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4332bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, 4333bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkFence *pFence) { 433456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43354a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateFence(device, pCreateInfo, pAllocator, pFence); 43365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4337ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4338a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis auto &fence_node = dev_data->fenceMap[*pFence]; 43398988ad37ea5a054ff2ae3cbe4b767ae6c13cf48bChris Forbes fence_node.fence = *pFence; 4340a265a8ed3bbb32ade305b1be3148d6001a870b76Tobin Ehlis fence_node.createInfo = *pCreateInfo; 4341cdb1ea0ff0d966dda02543468377eae93b9e2f8fChris Forbes fence_node.state = (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) ? FENCE_RETIRED : FENCE_UNSIGNALED; 43425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 43435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 43465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis// TODO handle pipeline caches 434789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo, 434889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache) { 434956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43504a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache); 43515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4354bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, 4355bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 435656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43574a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.DestroyPipelineCache(device, pipelineCache, pAllocator); 43585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4360bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, 4361bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski void *pData) { 436256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43634a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.GetPipelineCacheData(device, pipelineCache, pDataSize, pData); 43645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4367bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, 4368bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkPipelineCache *pSrcCaches) { 436956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 43704a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches); 43715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 43725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 43735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 43743d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis// utility function to set collective state for pipeline 43754c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlisvoid set_pipeline_state(PIPELINE_STATE *pPipe) { 43763d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis // If any attachment used by this pipeline has blendEnable, set top-level blendEnable 43773d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (pPipe->graphicsPipelineCI.pColorBlendState) { 43783d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis for (size_t i = 0; i < pPipe->attachments.size(); ++i) { 43793d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (VK_TRUE == pPipe->attachments[i].blendEnable) { 43803d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis if (((pPipe->attachments[i].dstAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 43813d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].dstAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) || 43823d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis ((pPipe->attachments[i].dstColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 43833d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].dstColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) || 43843d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis ((pPipe->attachments[i].srcAlphaBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 43853d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].srcAlphaBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)) || 43863d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis ((pPipe->attachments[i].srcColorBlendFactor >= VK_BLEND_FACTOR_CONSTANT_COLOR) && 43873d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis (pPipe->attachments[i].srcColorBlendFactor <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA))) { 43883d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis pPipe->blendConstantsEnabled = true; 43893d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 43903d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 43913d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 43923d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis } 43933d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis} 43943d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis 4395daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinskibool validate_dual_src_blend_feature(layer_data *device_data, PIPELINE_STATE *pipe_state) { 4396daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski bool skip = false; 4397daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski if (pipe_state->graphicsPipelineCI.pColorBlendState) { 4398daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski for (size_t i = 0; i < pipe_state->attachments.size(); ++i) { 4399daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski if (!device_data->enabled_features.dualSrcBlend) { 4400daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski if ((pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_COLOR) || 4401daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR) || 4402daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_ALPHA) || 4403daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].dstAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA) || 4404daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_COLOR) || 4405daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR) || 4406daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_SRC1_ALPHA) || 4407daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski (pipe_state->attachments[i].srcAlphaBlendFactor == VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA)) { 4408daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski skip |= 4409daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 44109b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pipe_state->pipeline), __LINE__, DRAWSTATE_INVALID_FEATURE, "DS", 4411daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski "CmdBindPipeline: vkPipeline (0x%" PRIxLEAST64 ") attachment[" PRINTF_SIZE_T_SPECIFIER 4412daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski "] has a dual-source blend factor but this device feature is not enabled.", 44139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pipe_state->pipeline), i); 4414daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4415daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4416daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4417daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski } 4418daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski return skip; 4419daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski} 4420daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski 4421bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, 4422bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkGraphicsPipelineCreateInfo *pCreateInfos, 4423bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { 44245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO What to do with pipelineCache? 44255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // The order of operations here is a little convoluted but gets the job done 44264c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis // 1. Pipeline create state is first shadowed into PIPELINE_STATE struct 44275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // 2. Create state is then validated (which uses flags setup during shadowing) 44285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // 3. If everything looks good, we'll then create the pipeline and add NODE to pipelineMap 442942486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski bool skip = false; 44305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic 443142486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski vector<PIPELINE_STATE *> pipe_state(count); 443256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t i = 0; 4435ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 44365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < count; i++) { 443842486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski pipe_state[i] = new PIPELINE_STATE; 443942486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski pipe_state[i]->initGraphicsPipeline(&pCreateInfos[i]); 44409a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis pipe_state[i]->render_pass_ci.initialize(GetRenderPassState(dev_data, pCreateInfos[i].renderPass)->createInfo.ptr()); 444142486a20f07b16f0c5361cdc00fd789b07b1989aMark Lobodzinski pipe_state[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout); 44425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 44434260fe87d0d168d6f4e7d65a648be05ebe1dedb3Chris Forbes 44444260fe87d0d168d6f4e7d65a648be05ebe1dedb3Chris Forbes for (i = 0; i < count; i++) { 44452f521eee4ccb1c84512ea767880df8f38751c0d4Chris Forbes skip |= ValidatePipelineLocked(dev_data, pipe_state, i); 44464260fe87d0d168d6f4e7d65a648be05ebe1dedb3Chris Forbes } 44475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 444829243a95b358b0d96ab15064fb3f9b0c0f64b8e9Chris Forbes lock.unlock(); 444929243a95b358b0d96ab15064fb3f9b0c0f64b8e9Chris Forbes 4450c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes for (i = 0; i < count; i++) { 4451c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes skip |= ValidatePipelineUnlocked(dev_data, pipe_state, i); 4452c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes } 4453c3e70f769bd4aa0988652050444d57cab4925c16Chris Forbes 4454c70226063be6148056ceeccf835175a1fd59f24fChris Forbes if (skip) { 4455c70226063be6148056ceeccf835175a1fd59f24fChris Forbes for (i = 0; i < count; i++) { 4456c70226063be6148056ceeccf835175a1fd59f24fChris Forbes delete pipe_state[i]; 44571ab616b32d4e5b7d62d4a8c41b0c03ea335ab845Chris Forbes pPipelines[i] = VK_NULL_HANDLE; 4458c70226063be6148056ceeccf835175a1fd59f24fChris Forbes } 44597a456d188475c23b566334be45dc0489b2789653Chris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 44607a456d188475c23b566334be45dc0489b2789653Chris Forbes } 44617a456d188475c23b566334be45dc0489b2789653Chris Forbes 4462bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 4463bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->dispatch_table.CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines); 44647a456d188475c23b566334be45dc0489b2789653Chris Forbes lock.lock(); 44657a456d188475c23b566334be45dc0489b2789653Chris Forbes for (i = 0; i < count; i++) { 446661943a7503bc8594338f3364ef42f1d863486c04Chris Forbes if (pPipelines[i] == VK_NULL_HANDLE) { 446761943a7503bc8594338f3364ef42f1d863486c04Chris Forbes delete pipe_state[i]; 4468bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski } else { 446961943a7503bc8594338f3364ef42f1d863486c04Chris Forbes pipe_state[i]->pipeline = pPipelines[i]; 447061943a7503bc8594338f3364ef42f1d863486c04Chris Forbes dev_data->pipelineMap[pipe_state[i]->pipeline] = pipe_state[i]; 447161943a7503bc8594338f3364ef42f1d863486c04Chris Forbes } 44725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4473c70226063be6148056ceeccf835175a1fd59f24fChris Forbes 44745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 44755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 44765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4477bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, 4478bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkComputePipelineCreateInfo *pCreateInfos, 4479bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { 44800108a1af0b7c6949846e9d71d00bbfb322b6f7caChris Forbes bool skip = false; 44815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic 44834c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis vector<PIPELINE_STATE *> pPipeState(count); 448456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 44855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t i = 0; 4487ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 44885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < count; i++) { 44895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO: Verify compute stage bits 44905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Create and initialize internal tracking data structure 44924c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis pPipeState[i] = new PIPELINE_STATE; 44934c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis pPipeState[i]->initComputePipeline(&pCreateInfos[i]); 4494c2a5a36d03bbe52f5854a5884346e4a84115e259Tobin Ehlis pPipeState[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout); 44955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 44965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO: Add Compute Pipeline Verification 4497e446ad08318228362ef35d73e7a0636075cb3636Chris Forbes skip |= validate_compute_pipeline(dev_data, pPipeState[i]); 44985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 44995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 45007a456d188475c23b566334be45dc0489b2789653Chris Forbes if (skip) { 45015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < count; i++) { 45025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Clean up any locally allocated data structures 45034c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis delete pPipeState[i]; 4504fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes pPipelines[i] = VK_NULL_HANDLE; 45055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 45065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 45075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 45087a456d188475c23b566334be45dc0489b2789653Chris Forbes 45097a456d188475c23b566334be45dc0489b2789653Chris Forbes lock.unlock(); 4510bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 4511bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->dispatch_table.CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines); 45127a456d188475c23b566334be45dc0489b2789653Chris Forbes lock.lock(); 45137a456d188475c23b566334be45dc0489b2789653Chris Forbes for (i = 0; i < count; i++) { 4514fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes if (pPipelines[i] == VK_NULL_HANDLE) { 4515fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes delete pPipeState[i]; 4516bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski } else { 4517fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes pPipeState[i]->pipeline = pPipelines[i]; 4518fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes dev_data->pipelineMap[pPipeState[i]->pipeline] = pPipeState[i]; 4519fcf67c021fdfcbeb12fb04daa9a69ecd7d376c5cChris Forbes } 45207a456d188475c23b566334be45dc0489b2789653Chris Forbes } 45217a456d188475c23b566334be45dc0489b2789653Chris Forbes 45225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 45235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 45245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 452589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, 452689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) { 452756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 45284a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateSampler(device, pCreateInfo, pAllocator, pSampler); 45295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4530ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 4531d31a44af6da568692a73201825459689c9431867Tobin Ehlis dev_data->samplerMap[*pSampler] = unique_ptr<SAMPLER_STATE>(new SAMPLER_STATE(pSampler, pCreateInfo)); 45325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 45335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 45345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 45355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 45360c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlisstatic bool PreCallValidateCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info) { 4537cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.create_descriptor_set_layout) return false; 45380c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis return cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(dev_data->report_data, create_info); 45390c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis} 45400c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis 45410c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlisstatic void PostCallRecordCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info, 45420c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis VkDescriptorSetLayout set_layout) { 45437e180d382f501c7c04408bda1f5fe79317736a4fTobin Ehlis dev_data->descriptorSetLayoutMap[set_layout] = std::make_shared<cvdescriptorset::DescriptorSetLayout>(create_info, set_layout); 45440c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis} 45450c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis 4546bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 4547bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, 4548bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDescriptorSetLayout *pSetLayout) { 454956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 45500c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 4551ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 45520c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis bool skip = PreCallValidateCreateDescriptorSetLayout(dev_data, pCreateInfo); 45530c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis if (!skip) { 45540c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis lock.unlock(); 45550c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis result = dev_data->dispatch_table.CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout); 45560c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis if (VK_SUCCESS == result) { 45570c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis lock.lock(); 45580c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis PostCallRecordCreateDescriptorSetLayout(dev_data, pCreateInfo, *pSetLayout); 45590c347fc6b08172b778c259e1a1219a2403495d48Tobin Ehlis } 45605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 45615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 45625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 45635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 45649e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz// Used by CreatePipelineLayout and CmdPushConstants. 45659e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz// Note that the index argument is optional and only used by CreatePipelineLayout. 45669e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultzstatic bool validatePushConstantRange(const layer_data *dev_data, const uint32_t offset, const uint32_t size, 45679e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz const char *caller_name, uint32_t index = 0) { 4568cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.push_constant_range) return false; 45699e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz uint32_t const maxPushConstantsSize = dev_data->phys_dev_properties.properties.limits.maxPushConstantsSize; 45703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 45719e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // Check that offset + size don't exceed the max. 45729e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // Prevent arithetic overflow here by avoiding addition and testing in this order. 45739e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if ((offset >= maxPushConstantsSize) || (size > maxPushConstantsSize - offset)) { 45749e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // This is a pain just to adapt the log message to the caller, but better to sort it out only when there is a problem. 45759e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) { 4576e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis if (offset >= maxPushConstantsSize) { 45773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4578315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a0024c, "DS", 45793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with offset %u that " 45803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "exceeds this device's maxPushConstantSize of %u. %s", 4581315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, maxPushConstantsSize, validation_error_map[VALIDATION_ERROR_11a0024c]); 4582e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis } 4583e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis if (size > maxPushConstantsSize - offset) { 4584315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4585315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a00254, "DS", 4586315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "%s call has push constants index %u with offset %u and size %u that " 4587315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "exceeds this device's maxPushConstantSize of %u. %s", 4588315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, size, maxPushConstantsSize, 4589315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_11a00254]); 4590e420dd92dcfc04f279e98796a49ee26b2c3ddafeTobin Ehlis } 45919e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) { 45924527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (offset >= maxPushConstantsSize) { 45933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4594315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e4, "DS", 45953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with offset %u that " 45963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "exceeds this device's maxPushConstantSize of %u. %s", 4597315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, maxPushConstantsSize, validation_error_map[VALIDATION_ERROR_1bc002e4]); 45984527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 45994527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (size > maxPushConstantsSize - offset) { 4600315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4601315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e6, "DS", 4602315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "%s call has push constants index %u with offset %u and size %u that " 4603315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "exceeds this device's maxPushConstantSize of %u. %s", 4604315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, size, maxPushConstantsSize, 4605315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1bc002e6]); 46064527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 46079e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else { 46083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 46093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name); 46109e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46119e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46129e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // size needs to be non-zero and a multiple of 4. 46139e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if ((size == 0) || ((size & 0x3) != 0)) { 46149e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) { 4615891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis if (size == 0) { 46163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4617315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a00250, "DS", 46183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 46193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be greater than zero. %s", 4620315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_11a00250]); 4621891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis } 4622891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis if (size & 0x3) { 46233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4624315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a00252, "DS", 46253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 46263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be a multiple of 4. %s", 4627315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_11a00252]); 4628891f13be101e95697e5af9503f06da38b0c48f79Tobin Ehlis } 46299e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) { 46304527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (size == 0) { 46313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4632315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc2c21b, "DS", 46333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 46343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be greater than zero. %s", 4635315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_1bc2c21b]); 46364527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 46374527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if (size & 0x3) { 46383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4639315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e2, "DS", 46403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 46413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "size %u. Size must be a multiple of 4. %s", 4642315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, size, validation_error_map[VALIDATION_ERROR_1bc002e2]); 46434527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton } 46449e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else { 46453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 46463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name); 46479e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46489e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46499e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // offset needs to be a multiple of 4. 46509e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if ((offset & 0x3) != 0) { 46519e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) { 46523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4653315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a0024e, "DS", 46543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants index %u with " 46553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "offset %u. Offset must be a multiple of 4. %s", 4656315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, index, offset, validation_error_map[VALIDATION_ERROR_11a0024e]); 46579e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) { 46583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4659315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_1bc002e0, "DS", 46603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s call has push constants with " 46613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "offset %u. Offset must be a multiple of 4. %s", 4662315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis caller_name, offset, validation_error_map[VALIDATION_ERROR_1bc002e0]); 46639e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } else { 46643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 46653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INTERNAL_ERROR, "DS", "%s caller not supported.", caller_name); 46669e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 46695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 46705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4671bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo, 467289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) { 46733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 467456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4675bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // TODO : Add checks for VALIDATION_ERRORS 865-870 46769e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz // Push Constant Range checks 467707a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz uint32_t i, j; 46785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 46793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validatePushConstantRange(dev_data, pCreateInfo->pPushConstantRanges[i].offset, 46803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->pPushConstantRanges[i].size, "vkCreatePipelineLayout()", i); 46819e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == pCreateInfo->pPushConstantRanges[i].stageFlags) { 46823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4683315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_11a2dc03, "DS", "vkCreatePipelineLayout() call has no stageFlags set. %s", 4684315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_11a2dc03]); 46859e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46869e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 468807a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz 4689bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // As of 1.0.28, there is a VU that states that a stage flag cannot appear more than once in the list of push constant ranges. 469007a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 469107a398f7c8da45c8286cba4ef33239646ee87dc9Karl Schultz for (j = i + 1; j < pCreateInfo->pushConstantRangeCount; ++j) { 4692bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if (0 != (pCreateInfo->pPushConstantRanges[i].stageFlags & pCreateInfo->pPushConstantRanges[j].stageFlags)) { 46933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 4694315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_0fe00248, "DS", 46953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreatePipelineLayout() Duplicate stage flags found in ranges %d and %d. %s", i, j, 4696315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0fe00248]); 46979e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 46985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 46995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4700f73b2046273413ea1338dd714d67c39f8e0fa09eChris Forbes 47014a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout); 47025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4703ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 47045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis PIPELINE_LAYOUT_NODE &plNode = dev_data->pipelineLayoutMap[*pPipelineLayout]; 470569b71d9c89447ec87d823669ee9edbfc58af174aTobin Ehlis plNode.layout = *pPipelineLayout; 4706416bfef833408786b4a17f725b0ed6480bc65120Tobin Ehlis plNode.set_layouts.resize(pCreateInfo->setLayoutCount); 47075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < pCreateInfo->setLayoutCount; ++i) { 47089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis plNode.set_layouts[i] = GetDescriptorSetLayout(dev_data, pCreateInfo->pSetLayouts[i]); 47095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4710416bfef833408786b4a17f725b0ed6480bc65120Tobin Ehlis plNode.push_constant_ranges.resize(pCreateInfo->pushConstantRangeCount); 47115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 4712416bfef833408786b4a17f725b0ed6480bc65120Tobin Ehlis plNode.push_constant_ranges[i] = pCreateInfo->pPushConstantRanges[i]; 47135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 47165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 47175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4718bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, 4719bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkDescriptorPool *pDescriptorPool) { 472056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 47214a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool); 47225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4723a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis DESCRIPTOR_POOL_STATE *pNewNode = new DESCRIPTOR_POOL_STATE(*pDescriptorPool, pCreateInfo); 47245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (NULL == pNewNode) { 47255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, 47269b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(*pDescriptorPool), __LINE__, DRAWSTATE_OUT_OF_MEMORY, "DS", 4727a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis "Out of memory while attempting to allocate DESCRIPTOR_POOL_STATE in vkCreateDescriptorPool()")) 47285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 47295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 4730ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 47315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->descriptorPoolMap[*pDescriptorPool] = pNewNode; 47325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 47345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Need to do anything if pool create fails? 47355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 47375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 47385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4739bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, 4740bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDescriptorPoolResetFlags flags) { 4741315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO : Add checks for VALIDATION_ERROR_32a00272 474256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 47434a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetDescriptorPool(device, descriptorPool, flags); 47445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4745ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 47465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis clearDescriptorPool(dev_data, device, descriptorPool, flags); 47475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 47495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 47502c4e180a4442f968b44f3d5136f7ffda706f6428Chris Forbes// Ensure the pool contains enough descriptors and descriptor sets to satisfy 4751789832b514862c7a7b5b847eeb8e7cacb733b77bTobin Ehlis// an allocation request. Fills common_data with the total number of descriptors of each type required, 4752789832b514862c7a7b5b847eeb8e7cacb733b77bTobin Ehlis// as well as DescriptorSetLayout ptrs used for later update. 47537f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlisstatic bool PreCallValidateAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo, 47547f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis cvdescriptorset::AllocateDescriptorSetsData *common_data) { 47557a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis // Always update common data 47567a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis cvdescriptorset::UpdateAllocateDescriptorSetsData(dev_data, pAllocateInfo, common_data); 4757cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.allocate_descriptor_sets) return false; 47587e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis // All state checks for AllocateDescriptorSets is done in single function 47597a7c05af97a73fc6d4917ddda909f119583ff9fcTobin Ehlis return cvdescriptorset::ValidateAllocateDescriptorSets(dev_data, pAllocateInfo, common_data); 47607e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis} 47617e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis// Allocation state was good and call down chain was made so update state based on allocating descriptor sets 47627e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlisstatic void PostCallRecordAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo, 47637f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis VkDescriptorSet *pDescriptorSets, 47647f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis const cvdescriptorset::AllocateDescriptorSetsData *common_data) { 47657e73e5c6b3020b96a821985f73012f2af0f1b992Tobin Ehlis // All the updates are contained in a single cvdescriptorset function 47662c59c1d90b22aa759d785e4233e468616990ff92Tobin Ehlis cvdescriptorset::PerformAllocateDescriptorSets(pAllocateInfo, pDescriptorSets, common_data, &dev_data->descriptorPoolMap, 4767b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis &dev_data->setMap, dev_data); 47682c4e180a4442f968b44f3d5136f7ffda706f6428Chris Forbes} 47692c4e180a4442f968b44f3d5136f7ffda706f6428Chris Forbes 4770827e8708bfc431aa792cba005ebf9f1fe35cc7e3Mark Lobodzinski// TODO: PostCallRecord routine is dependent on data generated in PreCallValidate -- needs to be moved out 4771bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL AllocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, 4772bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDescriptorSet *pDescriptorSets) { 477356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4774ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 47757f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis cvdescriptorset::AllocateDescriptorSetsData common_data(pAllocateInfo->descriptorSetCount); 47763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateAllocateDescriptorSets(dev_data, pAllocateInfo, &common_data); 4777b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 4778d173e0daab123373ce75105f2a908f6ae7cef6abChris Forbes 47793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 4780d173e0daab123373ce75105f2a908f6ae7cef6abChris Forbes 47814a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets); 47826511ce241f7f210211e0c0e882f3c14889071f4dChris Forbes 47835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4784b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 47857f61868b44f1da1dfa6a4ff726020411db92ce0dTobin Ehlis PostCallRecordAllocateDescriptorSets(dev_data, pAllocateInfo, pDescriptorSets, &common_data); 4786b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 47875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 47885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 47895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 4790cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis// Verify state before freeing DescriptorSets 4791cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlisstatic bool PreCallValidateFreeDescriptorSets(const layer_data *dev_data, VkDescriptorPool pool, uint32_t count, 4792cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis const VkDescriptorSet *descriptor_sets) { 4793cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.free_descriptor_sets) return false; 47943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 4795cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // First make sure sets being destroyed are not currently in-use 4796405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour for (uint32_t i = 0; i < count; ++i) { 4797405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (descriptor_sets[i] != VK_NULL_HANDLE) { 47983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateIdleDescriptorSet(dev_data, descriptor_sets[i], "vkFreeDescriptorSets"); 4799405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4800405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4801cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis 48029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(dev_data, pool); 4803a21f0d8ac8389dc4e23749efc02d82a7ec1eaee3Tobin Ehlis if (pool_state && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pool_state->createInfo.flags)) { 4804cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // Can't Free from a NON_FREE pool 48053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, 4806315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pool), __LINE__, VALIDATION_ERROR_28600270, "DS", 48073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "It is invalid to call vkFreeDescriptorSets() with a pool created without setting " 48083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT. %s", 4809315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_28600270]); 4810cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis } 48113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 4812cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis} 4813cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis// Sets have been removed from the pool so update underlying state 4814cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlisstatic void PostCallRecordFreeDescriptorSets(layer_data *dev_data, VkDescriptorPool pool, uint32_t count, 4815cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis const VkDescriptorSet *descriptor_sets) { 48169a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DESCRIPTOR_POOL_STATE *pool_state = GetDescriptorPoolState(dev_data, pool); 4817cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // Update available descriptor sets in pool 4818cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis pool_state->availableSets += count; 4819cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis 4820cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis // For each freed descriptor add its resources back into the pool as available and remove from pool and setMap 4821cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis for (uint32_t i = 0; i < count; ++i) { 4822405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour if (descriptor_sets[i] != VK_NULL_HANDLE) { 4823405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour auto descriptor_set = dev_data->setMap[descriptor_sets[i]]; 4824405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour uint32_t type_index = 0, descriptor_count = 0; 4825405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour for (uint32_t j = 0; j < descriptor_set->GetBindingCount(); ++j) { 4826405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour type_index = static_cast<uint32_t>(descriptor_set->GetTypeFromIndex(j)); 4827405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour descriptor_count = descriptor_set->GetDescriptorCountFromIndex(j); 4828405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour pool_state->availableDescriptorTypeCount[type_index] += descriptor_count; 4829405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4830405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour freeDescriptorSet(dev_data, descriptor_set); 4831405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour pool_state->sets.erase(descriptor_set); 4832405404ef7f928520a56949bcc4c62f6a337514a9Tony Barbour } 4833cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis } 4834cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis} 48355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4836bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL FreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, 4837bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkDescriptorSet *pDescriptorSets) { 483856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 48395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Make sure that no sets being destroyed are in-flight 4840ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 48413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets); 4842b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 4843e1a3be272f365a7d75f9cc1338d2eebafbf1e6cdTobin Ehlis 48443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 48454a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets); 48465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4847b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 4848cd53549dd5a597894f308b4bb993c02ae30817d6Tobin Ehlis PostCallRecordFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets); 4849b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 48505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 48515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 48525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 48536b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// TODO : This is a Proof-of-concept for core validation architecture 48546b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// Really we'll want to break out these functions to separate files but 48556b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// keeping it all together here to prove out design 48566b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// PreCallValidate* handles validating all of the state prior to calling down chain to UpdateDescriptorSets() 48576b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlisstatic bool PreCallValidateUpdateDescriptorSets(layer_data *dev_data, uint32_t descriptorWriteCount, 48586b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 48596b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis const VkCopyDescriptorSet *pDescriptorCopies) { 4860cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (dev_data->instance_data->disabled.update_descriptor_sets) return false; 48616b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // First thing to do is perform map look-ups. 48626b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // NOTE : UpdateDescriptorSets is somewhat unique in that it's operating on a number of DescriptorSets 48636b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // so we can't just do a single map look-up up-front, but do them individually in functions below 48646b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis 48656b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // Now make call(s) that validate state, but don't perform state updates in this function 48666b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // Note, here DescriptorSets is unique in that we don't yet have an instance. Using a helper function in the 48676b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // namespace which will parse params and make calls into specific class instances 4868104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis return cvdescriptorset::ValidateUpdateDescriptorSets(dev_data->report_data, dev_data, descriptorWriteCount, pDescriptorWrites, 4869104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis descriptorCopyCount, pDescriptorCopies); 48706b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis} 48716b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis// PostCallRecord* handles recording state updates following call down chain to UpdateDescriptorSets() 48720c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlisstatic void PreCallRecordUpdateDescriptorSets(layer_data *dev_data, uint32_t descriptorWriteCount, 48730c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 48740c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis const VkCopyDescriptorSet *pDescriptorCopies) { 4875104ab082916e41467ef60baaab7a5a8b2e02c59cTobin Ehlis cvdescriptorset::PerformUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 48766b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis pDescriptorCopies); 48776b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis} 48785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4879bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL UpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount, 4880bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, 4881bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkCopyDescriptorSet *pDescriptorCopies) { 48826b67c2aac9862a21e0dd068966c8b0b3aaf0bafdTobin Ehlis // Only map look-up at top level is for device-level layer_data 488356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 4884ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 48853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 48863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pDescriptorCopies); 48873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 48880c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis // Since UpdateDescriptorSets() is void, nothing to check prior to updating state & we can update before call down chain 48890c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis PreCallRecordUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 48900c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis pDescriptorCopies); 48910c9526fb9fbc2d95ebda8902e1de9d9007ba4e9eTobin Ehlis lock.unlock(); 48924a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, 48934a0754042cf090e131e9e769d8a3633c228625beChris Forbes pDescriptorCopies); 48945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 48955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 48965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4897bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, 4898bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkCommandBuffer *pCommandBuffer) { 489956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 49004a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer); 49015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 4902ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 49039a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, pCreateInfo->commandPool); 4904cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes 4905cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes if (pPool) { 490672d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis for (uint32_t i = 0; i < pCreateInfo->commandBufferCount; i++) { 49075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Add command buffer to its commandPool map 4908cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes pPool->commandBuffers.push_back(pCommandBuffer[i]); 49095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis GLOBAL_CB_NODE *pCB = new GLOBAL_CB_NODE; 49105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Add command buffer to map 49115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->commandBufferMap[pCommandBuffer[i]] = pCB; 49125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis resetCB(dev_data, pCommandBuffer[i]); 49135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->createInfo = *pCreateInfo; 49145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->device = device; 49155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4917b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 49185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 49205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 49215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 4922883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis// Add bindings between the given cmd buffer & framebuffer and the framebuffer's children 4923c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic void AddFramebufferBinding(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, FRAMEBUFFER_STATE *fb_state) { 49249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&fb_state->cb_bindings, {HandleToUint64(fb_state->framebuffer), kVulkanObjectTypeFramebuffer}, 49250245b74a083d2cb3b083571deb0fe13b4ab428a4Tobin Ehlis cb_state); 4926883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis for (auto attachment : fb_state->attachments) { 4927883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis auto view_state = attachment.view_state; 4928883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis if (view_state) { 492903ea795b83fdf0099594808a1a57064dea7f02a1Tobin Ehlis AddCommandBufferBindingImageView(dev_data, cb_state, view_state); 4930883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis } 49319a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto rp_state = GetRenderPassState(dev_data, fb_state->createInfo.renderPass); 4932883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis if (rp_state) { 49339b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&rp_state->cb_bindings, {HandleToUint64(rp_state->renderPass), kVulkanObjectTypeRenderPass}, 49349b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_state); 4935883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis } 4936883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis } 4937883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis} 4938883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis 4939bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) { 49403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 494156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 4942ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 49435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate command buffer level 49449a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_node = GetCBNode(dev_data, commandBuffer); 4945f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node) { 49465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // This implicitly resets the Cmd Buffer so make sure any fence is done and then clear memory references 4947a7fef8833e0b4e1e4c7ea20ab56da451a6856c0cChris Forbes if (cb_node->in_use.load()) { 49483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 4949315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00062, "MEM", 495059ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis "Calling vkBeginCommandBuffer() on active command buffer %p before it has completed. " 49513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "You must check command buffer fence before this call. %s", 4952315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, validation_error_map[VALIDATION_ERROR_16e00062]); 49535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 4954f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis clear_cmd_buf_and_mem_references(dev_data, cb_node); 4955f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) { 49565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Secondary Command Buffer 49575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo; 49585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!pInfo) { 49593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 49605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 4961315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00066, "DS", 4962bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must have inheritance info. %s", commandBuffer, 4963315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_16e00066]); 49645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 49655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { 49662c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis assert(pInfo->renderPass); 49672c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis string errorString = ""; 49689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto framebuffer = GetFramebufferState(dev_data, pInfo->framebuffer); 49692c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis if (framebuffer) { 49702c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis if ((framebuffer->createInfo.renderPass != pInfo->renderPass) && 49712c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis !verify_renderpass_compatibility(dev_data, framebuffer->renderPassCreateInfo.ptr(), 49729a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GetRenderPassState(dev_data, pInfo->renderPass)->createInfo.ptr(), 49732c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis errorString)) { 49742c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis // renderPass that framebuffer was created with must be compatible with local renderPass 49753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 49769b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 4977315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_0280006e, "DS", 49783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command " 49793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Buffer (0x%p) renderPass (0x%" PRIxLEAST64 49803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") is incompatible w/ framebuffer " 49813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "(0x%" PRIxLEAST64 ") w/ render pass (0x%" PRIxLEAST64 ") due to: %s. %s", 49829b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus commandBuffer, HandleToUint64(pInfo->renderPass), HandleToUint64(pInfo->framebuffer), 49839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(framebuffer->createInfo.renderPass), errorString.c_str(), 4984315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0280006e]); 49855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49862c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis // Connect this framebuffer and its children to this cmdBuffer 49872c09b45e970dcf95b0e03a2528662a93e0f5dc6fTobin Ehlis AddFramebufferBinding(dev_data, cb_node, framebuffer); 49885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 49904527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if ((pInfo->occlusionQueryEnable == VK_FALSE || dev_data->enabled_features.occlusionQueryPrecise == VK_FALSE) && 49915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (pInfo->queryFlags & VK_QUERY_CONTROL_PRECISE_BIT)) { 49923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 49939b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 4994315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_16e00068, "DS", 49953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command Buffer (0x%p) must not have " 49963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "VK_QUERY_CONTROL_PRECISE_BIT if occulusionQuery is disabled or the device does not " 49973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "support precise occlusion queries. %s", 4998315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, validation_error_map[VALIDATION_ERROR_16e00068]); 49995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) { 50029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto renderPass = GetRenderPassState(dev_data, pInfo->renderPass); 500316387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes if (renderPass) { 5004fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes if (pInfo->subpass >= renderPass->createInfo.subpassCount) { 50053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 50069b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 5007315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_0280006c, "DS", 50083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must have a subpass index (%d) " 50093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "that is less than the number of subpasses (%d). %s", 50103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski commandBuffer, pInfo->subpass, renderPass->createInfo.subpassCount, 5011315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0280006c]); 50125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5016f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (CB_RECORDING == cb_node->state) { 50173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5018315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00062, "DS", 50193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkBeginCommandBuffer(): Cannot call Begin on command buffer (0x%p" 50203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") in the RECORDING state. Must first call vkEndCommandBuffer(). %s", 5021315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, validation_error_map[VALIDATION_ERROR_16e00062]); 502246daa701a01b92ae19e3ee9e661d677128fe7e6dChris Forbes } else if (CB_RECORDED == cb_node->state || CB_INVALID_COMPLETE == cb_node->state) { 5023f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis VkCommandPool cmdPool = cb_node->createInfo.commandPool; 50249a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, cmdPool); 5025cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & pPool->createFlags)) { 50263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 50275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5028315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_16e00064, "DS", 5029226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "Call to vkBeginCommandBuffer() on command buffer (0x%p" 5030414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller ") attempts to implicitly reset cmdBuffer created from command pool (0x%" PRIxLEAST64 50314527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set. %s", 5032315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, HandleToUint64(cmdPool), validation_error_map[VALIDATION_ERROR_16e00064]); 50335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis resetCB(dev_data, commandBuffer); 50355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Set updated state here in case implicit reset occurs above 5037f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->state = CB_RECORDING; 5038f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->beginInfo = *pBeginInfo; 5039f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node->beginInfo.pInheritanceInfo) { 5040f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->inheritanceInfo = *(cb_node->beginInfo.pInheritanceInfo); 5041f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->beginInfo.pInheritanceInfo = &cb_node->inheritanceInfo; 5042888e1d268098177fde4a2263e3d7b7cc415f1debMark Young // If we are a secondary command-buffer and inheriting. Update the items we should inherit. 5043f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if ((cb_node->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) && 5044f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis (cb_node->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { 50459a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis cb_node->activeRenderPass = GetRenderPassState(dev_data, cb_node->beginInfo.pInheritanceInfo->renderPass); 5046f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeSubpass = cb_node->beginInfo.pInheritanceInfo->subpass; 5047350841afb70bf8dcfc3c6ec6b66f0aaa639553a3Tobin Ehlis cb_node->activeFramebuffer = cb_node->beginInfo.pInheritanceInfo->framebuffer; 5048f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->framebuffers.insert(cb_node->beginInfo.pInheritanceInfo->framebuffer); 5049888e1d268098177fde4a2263e3d7b7cc415f1debMark Young } 50505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5052b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 50533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 50545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 50555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50564a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.BeginCommandBuffer(commandBuffer, pBeginInfo); 5057400cff9fad0e19c80f6c9ed1181795d411a4bec5Tobin Ehlis 50585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 50595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 50605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 506189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL EndCommandBuffer(VkCommandBuffer commandBuffer) { 50623251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 506356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5064ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 50659a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 50665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 50674527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton if ((VK_COMMAND_BUFFER_LEVEL_PRIMARY == pCB->createInfo.level) || 50684527dcafa951a1fa931b258bbcd2d48b283610a7Dave Houlton !(pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { 5069fd61966f8d41b5bce15620b70563b7864cbb28feCody Northrop // This needs spec clarification to update valid usage, see comments in PR: 5070fd61966f8d41b5bce15620b70563b7864cbb28feCody Northrop // https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/pull/516#discussion_r63013756 5071315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, pCB, "vkEndCommandBuffer()", VALIDATION_ERROR_27400078); 5072fd61966f8d41b5bce15620b70563b7864cbb28feCody Northrop } 50733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_END, "vkEndCommandBuffer()"); 50745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto query : pCB->activeQueries) { 50753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5076315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_2740007a, "DS", 50773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Ending command buffer with in progress query: queryPool 0x%" PRIx64 ", index %d. %s", 5078315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(query.pool), query.index, validation_error_map[VALIDATION_ERROR_2740007a]); 50795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 5082b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 50830d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes auto result = dev_data->dispatch_table.EndCommandBuffer(commandBuffer); 5084b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 50855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 50865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->state = CB_RECORDED; 50875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50880d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes return result; 50895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 50900d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 50915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 50925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 50935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5094bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL ResetCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags) { 50953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 509656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5097ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 50989a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 50995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkCommandPool cmdPool = pCB->createInfo.commandPool; 51009a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pPool = GetCommandPoolNode(dev_data, cmdPool); 5101cd9a648074f67a1d44c15a056b90fc66da8ead17Chris Forbes if (!(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT & pPool->createFlags)) { 51023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5103315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_3260005c, "DS", 51043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attempt to reset command buffer (0x%p) created from command pool (0x%" PRIxLEAST64 51053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set. %s", 5106315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis commandBuffer, HandleToUint64(cmdPool), validation_error_map[VALIDATION_ERROR_3260005c]); 51075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5108315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= checkCommandBufferInFlight(dev_data, pCB, "reset", VALIDATION_ERROR_3260005a); 5109b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 51103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 51114a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.ResetCommandBuffer(commandBuffer, flags); 51125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 5113b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.lock(); 51145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis resetCB(dev_data, commandBuffer); 5115b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 51165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 51185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 511993c396d566d722dc5c6f438eae212da0e9337ba3Mark Lobodzinski 5120bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 5121bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkPipeline pipeline) { 5122e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis bool skip = false; 512356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5124ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 51259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 5126e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis if (cb_state) { 5127baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBindPipeline()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 5128315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_18002415); 512929f880e9c3c837307e7a19c0ef7275448d483e04Tobin Ehlis skip |= ValidateCmd(dev_data, cb_state, CMD_BINDPIPELINE, "vkCmdBindPipeline()"); 5130e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis if ((VK_PIPELINE_BIND_POINT_COMPUTE == pipelineBindPoint) && (cb_state->activeRenderPass)) { 5131e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis skip |= 51325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 51339b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pipeline), __LINE__, DRAWSTATE_INVALID_RENDERPASS_CMD, "DS", 5134414e9a4117b500eac650d8b8f01a6e1b22d05aaeMark Mueller "Incorrectly binding compute pipeline (0x%" PRIxLEAST64 ") during active RenderPass (0x%" PRIxLEAST64 ")", 51359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pipeline), HandleToUint64(cb_state->activeRenderPass->renderPass)); 51365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5137315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO: VALIDATION_ERROR_18000612 VALIDATION_ERROR_18000616 51385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5139e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis PIPELINE_STATE *pipe_state = getPipelineState(dev_data, pipeline); 5140e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis if (pipe_state) { 5141e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis cb_state->lastBound[pipelineBindPoint].pipeline_state = pipe_state; 5142e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis set_cb_pso_status(cb_state, pipe_state); 5143e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis set_pipeline_state(pipe_state); 5144daaf8f4ce66b35b4509bb7a7fdf4256e4f324ba7Mark Lobodzinski skip |= validate_dual_src_blend_feature(dev_data, pipe_state); 51455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 5146e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 5147315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pipeline), __LINE__, VALIDATION_ERROR_18027e01, "DS", 51489b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attempt to bind Pipeline 0x%" PRIxLEAST64 " that doesn't exist! %s", HandleToUint64(pipeline), 5149315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_18027e01]); 5150e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis } 51519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&pipe_state->cb_bindings, {HandleToUint64(pipeline), kVulkanObjectTypePipeline}, cb_state); 5152e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis if (VK_PIPELINE_BIND_POINT_GRAPHICS == pipelineBindPoint) { 5153e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis // Add binding for child renderpass 51549a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto rp_state = GetRenderPassState(dev_data, pipe_state->graphicsPipelineCI.renderPass); 5155e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis if (rp_state) { 51569b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&rp_state->cb_bindings, {HandleToUint64(rp_state->renderPass), kVulkanObjectTypeRenderPass}, 51579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus cb_state); 5158e92495715edaa63453ce5775bf60f3795df72876Tobin Ehlis } 51595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 51605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5161b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5162cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline); 51635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 51645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5165bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, 5166bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkViewport *pViewports) { 51673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 516856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5169ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 51709a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 51715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5172315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetViewport()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1e002415); 51733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()"); 5174bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pCB->viewportMask |= ((1u << viewportCount) - 1u) << firstViewport; 51755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5176b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 51773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports); 51785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 51795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5180bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, 5181bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkRect2D *pScissors) { 51823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 518356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5184ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 51859a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 51865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5187315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetScissor()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1d802415); 51883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()"); 5189bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pCB->scissorMask |= ((1u << scissorCount) - 1u) << firstScissor; 51905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5191b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 51923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors); 51935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 51945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 519589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) { 51963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 519756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5198ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 51999a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5201315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetLineWidth()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1d602415); 52023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETLINEWIDTHSTATE, "vkCmdSetLineWidth()"); 52035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status |= CBSTATUS_LINE_WIDTH_SET; 5204a27508babf63d50aea75883a3702979193c23683Mark Young 52054c0df90de562aa248b524a28b355765d8e3eff25Tobin Ehlis PIPELINE_STATE *pPipeTrav = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline_state; 5206a27508babf63d50aea75883a3702979193c23683Mark Young if (pPipeTrav != NULL && !isDynamic(pPipeTrav, VK_DYNAMIC_STATE_LINE_WIDTH)) { 52073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5208315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1d600626, "DS", 52093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdSetLineWidth called but pipeline was created without VK_DYNAMIC_STATE_LINE_WIDTH " 52103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "flag. This is undefined behavior and could be ignored. %s", 5211315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1d600626]); 5212a27508babf63d50aea75883a3702979193c23683Mark Young } else { 52139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= verifyLineWidth(dev_data, DRAWSTATE_INVALID_SET, kVulkanObjectTypeCommandBuffer, HandleToUint64(commandBuffer), 52149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus lineWidth); 5215a27508babf63d50aea75883a3702979193c23683Mark Young } 52165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5217b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetLineWidth(commandBuffer, lineWidth); 52195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5221bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, 5222bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski float depthBiasSlopeFactor) { 52233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 522456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5225ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52269a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5228315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetDepthBias()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1cc02415); 52293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETDEPTHBIASSTATE, "vkCmdSetDepthBias()"); 5230434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski if ((depthBiasClamp != 0.0) && (!dev_data->enabled_features.depthBiasClamp)) { 52313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5232315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1cc0062c, "DS", 52333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdSetDepthBias(): the depthBiasClamp device feature is disabled: the depthBiasClamp " 52343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "parameter must be set to 0.0. %s", 5235315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1cc0062c]); 5236434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski } 52373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 5238434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski pCB->status |= CBSTATUS_DEPTH_BIAS_SET; 5239434c3e2a778a3ca5a0a5414cbedd7c0f20a883b7Mark Lobodzinski } 52405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5241b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) 52434a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor); 52445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 524689d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) { 52473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 524856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5249ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5252315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetBlendConstants()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1ca02415); 52533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETBLENDSTATE, "vkCmdSetBlendConstants()"); 52543d3e06b40a06f099e741b9299efa66bddb69a074Tobin Ehlis pCB->status |= CBSTATUS_BLEND_CONSTANTS_SET; 52555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5256b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetBlendConstants(commandBuffer, blendConstants); 52585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5260bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) { 52613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 526256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5263ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52649a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5266315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetDepthBounds()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1ce02415); 52673251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETDEPTHBOUNDSSTATE, "vkCmdSetDepthBounds()"); 52685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status |= CBSTATUS_DEPTH_BOUNDS_SET; 52695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5270b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds); 52725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5274bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, 5275bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t compareMask) { 52763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 527756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5278ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52799a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5281315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5282315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilCompareMask()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1da02415); 52833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILREADMASKSTATE, "vkCmdSetStencilCompareMask()"); 52845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status |= CBSTATUS_STENCIL_READ_MASK_SET; 52855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5286b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 52873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask); 52885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 52895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5290bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask) { 52913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 529256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5293ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 52949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 52955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5296315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5297315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilWriteMask()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1de02415); 52983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILWRITEMASKSTATE, "vkCmdSetStencilWriteMask()"); 52995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status |= CBSTATUS_STENCIL_WRITE_MASK_SET; 53005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5301b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 53023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask); 53035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 53045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5305bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference) { 53063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 530756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5308ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 53099a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 53105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 5311315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5312315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetStencilReference()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1dc02415); 53133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETSTENCILREFERENCESTATE, "vkCmdSetStencilReference()"); 53145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->status |= CBSTATUS_STENCIL_REFERENCE_SET; 53155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5316b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 53173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetStencilReference(commandBuffer, faceMask, reference); 53185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 53195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5320bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 5321bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, 5322bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, 5323bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const uint32_t *pDynamicOffsets) { 5324946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 532556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5326ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5327946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 5328946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 5329baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdBindDescriptorSets()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 5330315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17c02415); 5331946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_BINDDESCRIPTORSETS, "vkCmdBindDescriptorSets()"); 5332ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // Track total count of dynamic descriptor types to make sure we have an offset for each one 5333946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski uint32_t total_dynamic_descriptors = 0; 5334946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski string error_string = ""; 5335946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski uint32_t last_set_index = firstSet + setCount - 1; 5336946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (last_set_index >= cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.size()) { 5337946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.resize(last_set_index + 1); 5338946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].dynamicOffsets.resize(last_set_index + 1); 5339946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski } 5340946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski auto old_final_bound_set = cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[last_set_index]; 5341ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski auto pipeline_layout = getPipelineLayout(dev_data, layout); 5342ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski for (uint32_t set_idx = 0; set_idx < setCount; set_idx++) { 5343ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski cvdescriptorset::DescriptorSet *descriptor_set = GetSetNode(dev_data, pDescriptorSets[set_idx]); 5344ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski if (descriptor_set) { 5345946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].pipeline_layout = *pipeline_layout; 5346946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[set_idx + firstSet] = descriptor_set; 5347ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski if (!descriptor_set->IsUpdated() && (descriptor_set->GetTotalDescriptorCount() != 0)) { 5348946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 53499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(pDescriptorSets[set_idx]), 53509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS", 5351946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "Descriptor Set 0x%" PRIxLEAST64 5352946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski " bound but it was never updated. You may want to either update it or not bind it.", 53539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pDescriptorSets[set_idx])); 5354ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5355ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // Verify that set being bound is compatible with overlapping setLayout of pipelineLayout 535612b7fc342b53fbdd399aae4a85959e37685936acChris Forbes if (!verify_set_layout_compatibility(descriptor_set, pipeline_layout, set_idx + firstSet, error_string)) { 5357946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 53589b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(pDescriptorSets[set_idx]), 5359315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_17c002cc, "DS", 5360946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "descriptorSet #%u being bound is not compatible with overlapping descriptorSetLayout " 5361946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "at index %u of pipelineLayout 0x%" PRIxLEAST64 " due to: %s. %s", 53629b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus set_idx, set_idx + firstSet, HandleToUint64(layout), error_string.c_str(), 5363315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17c002cc]); 53645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5365ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 5366946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski auto set_dynamic_descriptor_count = descriptor_set->GetDynamicDescriptorCount(); 5367ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 5368946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].dynamicOffsets[firstSet + set_idx].clear(); 5369ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 5370946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (set_dynamic_descriptor_count) { 5371ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // First make sure we won't overstep bounds of pDynamicOffsets array 5372946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if ((total_dynamic_descriptors + set_dynamic_descriptor_count) > dynamicOffsetCount) { 53739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 53749b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 53759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pDescriptorSets[set_idx]), __LINE__, DRAWSTATE_INVALID_DYNAMIC_OFFSET_COUNT, "DS", 53769b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "descriptorSet #%u (0x%" PRIxLEAST64 53779b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ") requires %u dynamicOffsets, but only %u dynamicOffsets are left in pDynamicOffsets " 53789b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "array. There must be one dynamic offset for each dynamic descriptor being bound.", 53799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus set_idx, HandleToUint64(pDescriptorSets[set_idx]), descriptor_set->GetDynamicDescriptorCount(), 53809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus (dynamicOffsetCount - total_dynamic_descriptors)); 5381ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } else { // Validate and store dynamic offsets with the set 5382ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // Validate Dynamic Offset Minimums 5383946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski uint32_t cur_dyn_offset = total_dynamic_descriptors; 5384ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski for (uint32_t d = 0; d < descriptor_set->GetTotalDescriptorCount(); d++) { 5385ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski if (descriptor_set->GetTypeFromGlobalIndex(d) == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) { 538616769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo( 5387ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski pDynamicOffsets[cur_dyn_offset], 5388ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment) != 0) { 5389315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5390315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 5391315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 5392315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17c002d4, "DS", 5393315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdBindDescriptorSets(): pDynamicOffsets[%d] is %d but must be a multiple of " 5394315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64 ". %s", 5395315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis cur_dyn_offset, pDynamicOffsets[cur_dyn_offset], 5396315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis dev_data->phys_dev_properties.properties.limits.minUniformBufferOffsetAlignment, 5397315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17c002d4]); 5398ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5399ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski cur_dyn_offset++; 5400ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } else if (descriptor_set->GetTypeFromGlobalIndex(d) == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { 540116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo( 5402ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski pDynamicOffsets[cur_dyn_offset], 5403ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment) != 0) { 5404315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5405315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 5406315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, 5407315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17c002d4, "DS", 5408315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdBindDescriptorSets(): pDynamicOffsets[%d] is %d but must be a multiple of " 5409315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64 ". %s", 5410315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis cur_dyn_offset, pDynamicOffsets[cur_dyn_offset], 5411315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis dev_data->phys_dev_properties.properties.limits.minStorageBufferOffsetAlignment, 5412315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17c002d4]); 5413ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5414ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski cur_dyn_offset++; 5415ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 541672d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 5417ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski 5418946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].dynamicOffsets[firstSet + set_idx] = 5419946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski std::vector<uint32_t>(pDynamicOffsets + total_dynamic_descriptors, 5420946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski pDynamicOffsets + total_dynamic_descriptors + set_dynamic_descriptor_count); 5421ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // Keep running total of dynamic descriptor count to verify at the end 5422946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski total_dynamic_descriptors += set_dynamic_descriptor_count; 542372d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 542472d66f0c1639cbaca92459498452d06db32d7aefTobin Ehlis } 5425ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } else { 54269b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 54279b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 54289b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pDescriptorSets[set_idx]), __LINE__, DRAWSTATE_INVALID_SET, "DS", 54299b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attempt to bind descriptor set 0x%" PRIxLEAST64 " that doesn't exist!", 54309b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pDescriptorSets[set_idx])); 5431ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5432ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // For any previously bound sets, need to set them to "invalid" if they were disturbed by this update 5433ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski if (firstSet > 0) { // Check set #s below the first bound set 5434ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski for (uint32_t i = 0; i < firstSet; ++i) { 5435946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[i] && 543612b7fc342b53fbdd399aae4a85959e37685936acChris Forbes !verify_set_layout_compatibility(cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[i], 5437946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski pipeline_layout, i, error_string)) { 5438946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= log_msg( 5439ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 5440ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, 54419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[i]), __LINE__, DRAWSTATE_NONE, 54429b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "DS", "DescriptorSet 0x%" PRIxLEAST64 54439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus " previously bound as set #%u was disturbed by newly bound pipelineLayout (0x%" PRIxLEAST64 ")", 54449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[i]), i, 54459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(layout)); 5446946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[i] = VK_NULL_HANDLE; 54475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 54485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 54495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5450ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // Check if newly last bound set invalidates any remaining bound sets 5451946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if ((cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.size() - 1) > (last_set_index)) { 5452946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (old_final_bound_set && 545312b7fc342b53fbdd399aae4a85959e37685936acChris Forbes !verify_set_layout_compatibility(old_final_bound_set, pipeline_layout, last_set_index, error_string)) { 5454946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski auto old_set = old_final_bound_set->GetSet(); 5455946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, 54569b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, HandleToUint64(old_set), __LINE__, 5457946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski DRAWSTATE_NONE, "DS", "DescriptorSet 0x%" PRIxLEAST64 5458946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski " previously bound as set #%u is incompatible with set 0x%" PRIxLEAST64 5459946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski " newly bound as set #%u so set #%u and any subsequent sets were " 5460946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "disturbed by newly bound pipelineLayout (0x%" PRIxLEAST64 ")", 54619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(old_set), last_set_index, 54629b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(cb_state->lastBound[pipelineBindPoint].boundDescriptorSets[last_set_index]), 54639b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus last_set_index, last_set_index + 1, HandleToUint64(layout)); 5464946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski cb_state->lastBound[pipelineBindPoint].boundDescriptorSets.resize(last_set_index + 1); 5465ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5466787f29d93dee194c015789cf61c079504c980572Tobin Ehlis } 5467ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5468ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // dynamicOffsetCount must equal the total number of dynamic descriptors in the sets being bound 5469946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (total_dynamic_descriptors != dynamicOffsetCount) { 5470315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5471315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 5472315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_17c002ce, "DS", 5473315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "Attempting to bind %u descriptorSets with %u dynamic descriptors, but dynamicOffsetCount " 5474315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "is %u. It should exactly match the number of dynamic descriptors. %s", 5475315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis setCount, total_dynamic_descriptors, dynamicOffsetCount, validation_error_map[VALIDATION_ERROR_17c002ce]); 54765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 54775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5478b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5479946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!skip) 54804a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, setCount, 54814a0754042cf090e131e9e769d8a3633c228625beChris Forbes pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); 54825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 54835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5484bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 5485bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkIndexType indexType) { 5486946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 548756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5488593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis // TODO : Somewhere need to verify that IBs have correct usage state flagged 5489ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5490b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 54919a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 54929a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 54935cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (cb_node && buffer_state) { 5494315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5495315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBindIndexBuffer()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_17e02415); 5496946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_node, CMD_BINDINDEXBUFFER, "vkCmdBindIndexBuffer()"); 5497315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, buffer_state, "vkCmdBindIndexBuffer()", VALIDATION_ERROR_17e00364); 5498ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski std::function<bool()> function = [=]() { 5499ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski return ValidateBufferMemoryIsValid(dev_data, buffer_state, "vkCmdBindIndexBuffer()"); 5500ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski }; 5501ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski cb_node->validate_functions.push_back(function); 5502ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski VkDeviceSize offset_align = 0; 5503ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski switch (indexType) { 5504ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski case VK_INDEX_TYPE_UINT16: 5505ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski offset_align = 2; 5506ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski break; 5507ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski case VK_INDEX_TYPE_UINT32: 5508ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski offset_align = 4; 5509ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski break; 5510ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski default: 5511ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski // ParamChecker should catch bad enum, we'll also throw alignment error below if offset_align stays 0 5512ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski break; 55135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5514ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski if (!offset_align || (offset % offset_align)) { 5515df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 55169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(commandBuffer), __LINE__, DRAWSTATE_VTX_INDEX_ALIGNMENT_ERROR, "DS", 5517946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "vkCmdBindIndexBuffer() offset (0x%" PRIxLEAST64 ") does not fall on alignment (%s) boundary.", offset, 5518946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski string_VkIndexType(indexType)); 5519ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski } 5520ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski cb_node->status |= CBSTATUS_INDEX_BUFFER_BOUND; 5521ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 5522ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 55235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5524b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5525946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType); 55265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 55275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 55285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisvoid updateResourceTracking(GLOBAL_CB_NODE *pCB, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers) { 55295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t end = firstBinding + bindingCount; 55305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->currentDrawData.buffers.size() < end) { 55315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->currentDrawData.buffers.resize(end); 55325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 55335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < bindingCount; ++i) { 55345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->currentDrawData.buffers[i + firstBinding] = pBuffers[i]; 55355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 55365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 55375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5538e3319189d6f8e3126522df7a5935d2c42f656291Dustin Gravesstatic inline void updateResourceTrackingOnDraw(GLOBAL_CB_NODE *pCB) { pCB->drawData.push_back(pCB->currentDrawData); } 55395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5540bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, 5541bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) { 5542946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 554356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5544593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis // TODO : Somewhere need to verify that VBs have correct usage state flagged 5545ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5546b3c2024e0ed61d7f68630d7eb7c8c03100689bb1Mark Lobodzinski 55479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 55489f229695cf32913dab3fb75e5d52548ea57b3851Tobin Ehlis if (cb_node) { 5549315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 5550315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBindVertexBuffers()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_18202415); 5551baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmd(dev_data, cb_node, CMD_BINDVERTEXBUFFER, "vkCmdBindVertexBuffers()"); 5552ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski for (uint32_t i = 0; i < bindingCount; ++i) { 5553ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski auto buffer_state = GetBufferState(dev_data, pBuffers[i]); 5554ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski assert(buffer_state); 5555315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, buffer_state, "vkCmdBindVertexBuffers()", VALIDATION_ERROR_182004e8); 5556ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski std::function<bool()> function = [=]() { 5557ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski return ValidateBufferMemoryIsValid(dev_data, buffer_state, "vkCmdBindVertexBuffers()"); 5558ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski }; 5559ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski cb_node->validate_functions.push_back(function); 55605fe7f75f980a78c0179ff93438d8786e6cb44b20Tony Barbour if (pOffsets[i] >= buffer_state->createInfo.size) { 55615fe7f75f980a78c0179ff93438d8786e6cb44b20Tony Barbour skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, 5562315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(buffer_state->buffer), __LINE__, VALIDATION_ERROR_182004e4, "DS", 55635fe7f75f980a78c0179ff93438d8786e6cb44b20Tony Barbour "vkCmdBindVertexBuffers() offset (0x%" PRIxLEAST64 ") is beyond the end of the buffer. %s", 5564315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pOffsets[i], validation_error_map[VALIDATION_ERROR_182004e4]); 55655fe7f75f980a78c0179ff93438d8786e6cb44b20Tony Barbour } 55665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5567ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski updateResourceTracking(cb_node, firstBinding, bindingCount, pBuffers); 55685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 55697828015969ab31ee01d597f0288cbb124b637fcdMark Lobodzinski assert(0); 55705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5571b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5572946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); 55735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 55745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 557525002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski// Expects global_lock to be held by caller 55765569d6457ac22e7d245f3cdee045e71ffbc8b06eTobin Ehlisstatic void MarkStoreImagesAndBuffersAsWritten(layer_data *dev_data, GLOBAL_CB_NODE *pCB) { 55777a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis for (auto imageView : pCB->updateImages) { 55789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, imageView); 5579cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!view_state) continue; 5580249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis 55819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, view_state->create_info.image); 55821facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis assert(image_state); 5583e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves std::function<bool()> function = [=]() { 55841facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis SetImageMemoryValid(dev_data, image_state, true); 5585e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 55867a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis }; 55877a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis pCB->validate_functions.push_back(function); 55887a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis } 55897a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis for (auto buffer : pCB->updateBuffers) { 55909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto buffer_state = GetBufferState(dev_data, buffer); 55915cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis assert(buffer_state); 5592e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves std::function<bool()> function = [=]() { 55935cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis SetBufferMemoryValid(dev_data, buffer_state, true); 5594e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 55957a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis }; 55967a3985a8a9d255dcca9f5992ca2262c7e5df41c6Tobin Ehlis pCB->validate_functions.push_back(function); 55975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 55985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 55995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5600ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis// Generic function to handle validation for all CmdDraw* type functions 5601ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool ValidateCmdDrawType(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, 5602baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt CMD_TYPE cmd_type, GLOBAL_CB_NODE **cb_state, const char *caller, VkQueueFlags queue_flags, 5603baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt UNIQUE_VALIDATION_ERROR_CODE queue_flag_code, UNIQUE_VALIDATION_ERROR_CODE msg_code, 5604baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt UNIQUE_VALIDATION_ERROR_CODE const dynamic_state_msg_code) { 560558b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis bool skip = false; 56069a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *cb_state = GetCBNode(dev_data, cmd_buffer); 560758b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (*cb_state) { 5608baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, *cb_state, caller, queue_flags, queue_flag_code); 5609ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis skip |= ValidateCmd(dev_data, *cb_state, cmd_type, caller); 56104f5a71335df5361d740a23b4548d54fc72a28d4fJeremy Hayes skip |= ValidateDrawState(dev_data, *cb_state, indexed, bind_point, caller, dynamic_state_msg_code); 561125d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis skip |= (VK_PIPELINE_BIND_POINT_GRAPHICS == bind_point) ? outsideRenderPass(dev_data, *cb_state, caller, msg_code) 561225d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis : insideRenderPass(dev_data, *cb_state, caller, msg_code); 561358b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis } 561458b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis return skip; 561558b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis} 561658b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis 561725d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis// Generic function to handle state update for all CmdDraw* and CmdDispatch* type functions 56186b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbesstatic void UpdateStateCmdDrawDispatchType(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 5619ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis UpdateDrawState(dev_data, cb_state, bind_point); 56202f921d33544c162dcb726fc3c7b915e89c02ff24Tobin Ehlis MarkStoreImagesAndBuffersAsWritten(dev_data, cb_state); 562125d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis} 562225d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis 5623ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis// Generic function to handle state update for all CmdDraw* type functions 56246b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbesstatic void UpdateStateCmdDrawType(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 56256b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawDispatchType(dev_data, cb_state, bind_point); 5626c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis updateResourceTrackingOnDraw(cb_state); 5627b68b13ed4952bce61f6ebb0023542660c26b0562Chris Forbes cb_state->hasDrawCmd = true; 5628ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5629ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5630ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDraw(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, VkPipelineBindPoint bind_point, 5631ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis GLOBAL_CB_NODE **cb_state, const char *caller) { 5632baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAW, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, 5633315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1a202415, VALIDATION_ERROR_1a200017, VALIDATION_ERROR_1a200376); 5634ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5635ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5636ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDraw(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 56376b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 5638c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis} 5639c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis 564089d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, 564189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu uint32_t firstVertex, uint32_t firstInstance) { 564256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 564358b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5644ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5645ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis bool skip = PreCallValidateCmdDraw(dev_data, commandBuffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state, "vkCmdDraw()"); 5646b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 564758b923895f7f6be1b7d48bd4ee3e85e0b3dd0c4dTobin Ehlis if (!skip) { 56484a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 5649c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis lock.lock(); 5650ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDraw(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS); 5651c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis lock.unlock(); 5652c0b225e42808ba8fada7a2f67ecd662e376ccf15Tobin Ehlis } 56535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 56545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5655ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDrawIndexed(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, 5656ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { 5657baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXED, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, 5658315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1a402415, VALIDATION_ERROR_1a400017, VALIDATION_ERROR_1a40039c); 5659ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5660ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5661ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDrawIndexed(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 56626b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 5663ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis} 5664ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis 5665bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, 5666bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) { 566756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5668ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5669ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5670ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis bool skip = PreCallValidateCmdDrawIndexed(dev_data, commandBuffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state, 5671ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis "vkCmdDrawIndexed()"); 5672b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5673ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis if (!skip) { 56744a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 5675ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis lock.lock(); 5676ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDrawIndexed(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS); 5677ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis lock.unlock(); 5678ac4451d7e5da96a3a5d51e613c583c057aee9cf4Tobin Ehlis } 56795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 56805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5681ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDrawIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, 5682ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, BUFFER_STATE **buffer_state, 5683ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis const char *caller) { 5684315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis bool skip = 5685315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDIRECT, cb_state, caller, VK_QUEUE_GRAPHICS_BIT, 5686315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1aa02415, VALIDATION_ERROR_1aa00017, VALIDATION_ERROR_1aa003cc); 56879a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *buffer_state = GetBufferState(dev_data, buffer); 5688315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_1aa003b4); 568913c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the 569013c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // VkDrawIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 'buffer'. 5691d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis return skip; 5692d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis} 5693d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis 5694ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDrawIndirect(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, 5695ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE *buffer_state) { 56966b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 5697d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_state, buffer_state); 5698d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis} 5699d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis 5700bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, 5701bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t stride) { 570256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5703d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5704d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 5705ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5706872a2f0ca3ffdeddfa7483e777191fa64b853892Tony Barbour bool skip = PreCallValidateCmdDrawIndirect(dev_data, commandBuffer, buffer, false, VK_PIPELINE_BIND_POINT_GRAPHICS, &cb_state, 5707ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis &buffer_state, "vkCmdDrawIndirect()"); 5708b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5709d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis if (!skip) { 57104a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDrawIndirect(commandBuffer, buffer, offset, count, stride); 5711d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis lock.lock(); 5712ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDrawIndirect(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, buffer_state); 5713d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis lock.unlock(); 5714d6df438f6e5bf5142a66c857e5c84dd402451242Tobin Ehlis } 57155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 57165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5717ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDrawIndexedIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, 5718ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, 5719ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE **buffer_state, const char *caller) { 5720315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis bool skip = 5721315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DRAWINDEXEDINDIRECT, cb_state, caller, 5722315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1a602415, VALIDATION_ERROR_1a600017, VALIDATION_ERROR_1a600434); 57239a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *buffer_state = GetBufferState(dev_data, buffer); 5724315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_1a60041c); 572513c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // TODO: If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the 572613c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // VkDrawIndexedIndirectCommand structures accessed by this command must be 0, which will require access to the contents of 572713c4316d0072cbc5bf3cd729abef4d114f3c96edMark Lobodzinski // 'buffer'. 57280c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis return skip; 57290c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis} 57300c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis 5731ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDrawIndexedIndirect(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, 5732ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE *buffer_state) { 57336b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawType(dev_data, cb_state, bind_point); 57340c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_state, buffer_state); 57350c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis} 57360c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis 5737bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 5738bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t count, uint32_t stride) { 573956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 57400c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 57410c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 5742ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 57430c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis bool skip = PreCallValidateCmdDrawIndexedIndirect(dev_data, commandBuffer, buffer, true, VK_PIPELINE_BIND_POINT_GRAPHICS, 5744ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis &cb_state, &buffer_state, "vkCmdDrawIndexedIndirect()"); 5745b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 57460c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis if (!skip) { 57474a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride); 57480c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis lock.lock(); 5749ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDrawIndexedIndirect(dev_data, cb_state, VK_PIPELINE_BIND_POINT_GRAPHICS, buffer_state); 57500c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis lock.unlock(); 57510c9ad626388bcde527db8d89829c45ebf0a94723Tobin Ehlis } 57525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 57535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5754ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDispatch(layer_data *dev_data, VkCommandBuffer cmd_buffer, bool indexed, 5755ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, const char *caller) { 5756baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt return ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCH, cb_state, caller, VK_QUEUE_COMPUTE_BIT, 5757315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_19c02415, VALIDATION_ERROR_19c00017, VALIDATION_ERROR_UNDEFINED); 575825d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis} 575925d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis 5760ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDispatch(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point) { 57616b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawDispatchType(dev_data, cb_state, bind_point); 576225d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis} 576325d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis 576489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) { 576556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 576625d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 5767ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5768ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis bool skip = 5769ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PreCallValidateCmdDispatch(dev_data, commandBuffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, &cb_state, "vkCmdDispatch()"); 5770b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 577125d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis if (!skip) { 57724a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDispatch(commandBuffer, x, y, z); 577325d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis lock.lock(); 5774ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDispatch(dev_data, cb_state, VK_PIPELINE_BIND_POINT_COMPUTE); 577525d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis lock.unlock(); 577625d3241067a529052f120867aa4c6161047cdb60Tobin Ehlis } 57775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 57785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5779ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic bool PreCallValidateCmdDispatchIndirect(layer_data *dev_data, VkCommandBuffer cmd_buffer, VkBuffer buffer, bool indexed, 5780ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis VkPipelineBindPoint bind_point, GLOBAL_CB_NODE **cb_state, 5781ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE **buffer_state, const char *caller) { 5782baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt bool skip = 5783baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt ValidateCmdDrawType(dev_data, cmd_buffer, indexed, bind_point, CMD_DISPATCHINDIRECT, cb_state, caller, VK_QUEUE_COMPUTE_BIT, 5784315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1a002415, VALIDATION_ERROR_1a000017, VALIDATION_ERROR_UNDEFINED); 57859a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis *buffer_state = GetBufferState(dev_data, buffer); 5786315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, *buffer_state, caller, VALIDATION_ERROR_1a000322); 578779c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis return skip; 578879c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis} 578979c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis 5790ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlisstatic void PostCallRecordCmdDispatchIndirect(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, VkPipelineBindPoint bind_point, 5791ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis BUFFER_STATE *buffer_state) { 57926b33c4e6a6f232fca84e0a6229106717b0012488Chris Forbes UpdateStateCmdDrawDispatchType(dev_data, cb_state, bind_point); 579379c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis AddCommandBufferBindingBuffer(dev_data, cb_state, buffer_state); 579479c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis} 579579c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis 5796bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) { 579756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 579879c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis GLOBAL_CB_NODE *cb_state = nullptr; 579979c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis BUFFER_STATE *buffer_state = nullptr; 5800ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 58017433ab60c7ff16d37edb0f8b17b606ccd363e210Tobin Ehlis bool skip = PreCallValidateCmdDispatchIndirect(dev_data, commandBuffer, buffer, false, VK_PIPELINE_BIND_POINT_COMPUTE, 5802ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis &cb_state, &buffer_state, "vkCmdDispatchIndirect()"); 5803b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 580479c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis if (!skip) { 58054a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdDispatchIndirect(commandBuffer, buffer, offset); 580679c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis lock.lock(); 5807ffa1c08650c9dbe798f25b88bef4b28d33d57b01Tobin Ehlis PostCallRecordCmdDispatchIndirect(dev_data, cb_state, VK_PIPELINE_BIND_POINT_COMPUTE, buffer_state); 580879c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis lock.unlock(); 580979c66dcd1e0db7de8556bce6deb782a150c77b92Tobin Ehlis } 58105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 58115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 581289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, 581389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu uint32_t regionCount, const VkBufferCopy *pRegions) { 5814c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5815ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5816ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 5817c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 5818c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski auto src_buffer_state = GetBufferState(device_data, srcBuffer); 5819c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski auto dst_buffer_state = GetBufferState(device_data, dstBuffer); 5820593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 5821c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski if (cb_node && src_buffer_state && dst_buffer_state) { 5822c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski bool skip = PreCallValidateCmdCopyBuffer(device_data, cb_node, src_buffer_state, dst_buffer_state); 5823c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski if (!skip) { 5824c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski PreCallRecordCmdCopyBuffer(device_data, cb_node, src_buffer_state, dst_buffer_state); 5825c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski lock.unlock(); 5826c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski device_data->dispatch_table.CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); 5827c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski } 5828ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 5829c40a396f8341e1e1e5fdf1d023a987b874763446Mark Lobodzinski lock.unlock(); 5830ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 58315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 58325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 58335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5834bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 5835bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 5836bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkImageCopy *pRegions) { 58376a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski bool skip = false; 58386a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5839ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5840249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis 58416a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 58426a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto src_image_state = GetImageState(device_data, srcImage); 58436a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski auto dst_image_state = GetImageState(device_data, dstImage); 58441facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (cb_node && src_image_state && dst_image_state) { 58456a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski skip = PreCallValidateCmdCopyImage(device_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, 58466a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski srcImageLayout, dstImageLayout); 58476a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski if (!skip) { 5848a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis PreCallRecordCmdCopyImage(device_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, srcImageLayout, 5849a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis dstImageLayout); 58506a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski lock.unlock(); 58516a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski device_data->dispatch_table.CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 58526a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski pRegions); 58535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5854249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis } else { 58556a7544432041a5ced84128597a44c55dfde2105cMark Lobodzinski lock.unlock(); 5856249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis assert(0); 58575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 58585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 58595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5860eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski// Validate that an image's sampleCount matches the requirement for a specific API call 586160568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinskibool ValidateImageSampleCount(layer_data *dev_data, IMAGE_STATE *image_state, VkSampleCountFlagBits sample_count, 586260568995aca225f81acda8ce40cfabbea2c19397Mark Lobodzinski const char *location, UNIQUE_VALIDATION_ERROR_CODE msgCode) { 5863eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski bool skip = false; 58641facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (image_state->createInfo.samples != sample_count) { 58659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 58669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), 0, msgCode, "DS", 58679b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s for image 0x%" PRIxLEAST64 " was created with a sample count of %s but must be %s. %s", location, 58689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(image_state->image), string_VkSampleCountFlagBits(image_state->createInfo.samples), 58699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus string_VkSampleCountFlagBits(sample_count), validation_error_map[msgCode]); 5870eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski } 5871eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski return skip; 5872eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski} 5873eebf670a2f04c402f2875f85aa4f889b06db48fcMark Lobodzinski 5874bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 5875bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 5876bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkImageBlit *pRegions, VkFilter filter) { 587756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5878ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5879593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 58809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 58819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto src_image_state = GetImageState(dev_data, srcImage); 58829a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_image_state = GetImageState(dev_data, dstImage); 58830dc51740dbd7b9f0ba7c071e0bf96f63d6d48c85Mark Lobodzinski 5884055112ec99304db71d55b69a60e1da14e8af8f60Mark Lobodzinski bool skip = PreCallValidateCmdBlitImage(dev_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions, filter); 58850dc51740dbd7b9f0ba7c071e0bf96f63d6d48c85Mark Lobodzinski 5886dca02371c9531e7a9a2a51decae1db4d297862c4Mark Lobodzinski if (!skip) { 5887eebd811afd800663f15fda8fc71bc203a03fe294Mark Lobodzinski PreCallRecordCmdBlitImage(dev_data, cb_node, src_image_state, dst_image_state); 5888eebd811afd800663f15fda8fc71bc203a03fe294Mark Lobodzinski lock.unlock(); 58894a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 58904a0754042cf090e131e9e769d8a3633c228625beChris Forbes pRegions, filter); 58910dc51740dbd7b9f0ba7c071e0bf96f63d6d48c85Mark Lobodzinski } 58925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 58935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5894bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, 5895bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImageLayout dstImageLayout, uint32_t regionCount, 5896bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkBufferImageCopy *pRegions) { 5897940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5898ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5899940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski bool skip = false; 5900940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 5901940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto src_buffer_state = GetBufferState(device_data, srcBuffer); 5902940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto dst_image_state = GetImageState(device_data, dstImage); 5903940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (cb_node && src_buffer_state && dst_image_state) { 5904940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip = PreCallValidateCmdCopyBufferToImage(device_data, dstImageLayout, cb_node, src_buffer_state, dst_image_state, 590571c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski regionCount, pRegions, "vkCmdCopyBufferToImage()"); 5906ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 5907d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 5908ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 5909e4d82c37d6c861b388dbc80297c18d6255858cb4Dave Houlton // TODO: report VU01244 here, or put in object tracker? 59105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5911940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (!skip) { 5912a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis PreCallRecordCmdCopyBufferToImage(device_data, cb_node, src_buffer_state, dst_image_state, regionCount, pRegions, 5913a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis dstImageLayout); 5914d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 5915940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski device_data->dispatch_table.CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); 5916d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 59175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 59185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5919bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 5920bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy *pRegions) { 5921940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski bool skip = false; 5922940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5923ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5924593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 5925940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 5926940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto src_image_state = GetImageState(device_data, srcImage); 5927940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski auto dst_buffer_state = GetBufferState(device_data, dstBuffer); 5928940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (cb_node && src_image_state && dst_buffer_state) { 5929940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski skip = PreCallValidateCmdCopyImageToBuffer(device_data, srcImageLayout, cb_node, src_image_state, dst_buffer_state, 593071c68ce753146a69508694cfc5fc2dcfa08c692eMark Lobodzinski regionCount, pRegions, "vkCmdCopyImageToBuffer()"); 5931ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 5932d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 5933ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 5934e4d82c37d6c861b388dbc80297c18d6255858cb4Dave Houlton // TODO: report VU01262 here, or put in object tracker? 59355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 5936940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski if (!skip) { 5937a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis PreCallRecordCmdCopyImageToBuffer(device_data, cb_node, src_image_state, dst_buffer_state, regionCount, pRegions, 5938a07ae8bd5f566eb9b073498dd4280efdb0b838b9Tobin Ehlis srcImageLayout); 5939d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski lock.unlock(); 5940940f70f1340803d185c67633b05ef048d277952eMark Lobodzinski device_data->dispatch_table.CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); 5941d5cde34b61eb694c6fe1d5e53de61bb87bf6936aMark Lobodzinski } 59425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 59435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5944e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisstatic bool PreCallCmdUpdateBuffer(layer_data *device_data, const GLOBAL_CB_NODE *cb_state, const BUFFER_STATE *dst_buffer_state) { 5945e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis bool skip = false; 5946e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(device_data, dst_buffer_state, "vkCmdUpdateBuffer()", VALIDATION_ERROR_1e400046); 5947e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis // Validate that DST buffer has correct usage flags set 5948e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateBufferUsageFlags(device_data, dst_buffer_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, 5949e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis VALIDATION_ERROR_1e400044, "vkCmdUpdateBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 5950e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateCmdQueueFlags(device_data, cb_state, "vkCmdUpdateBuffer()", 5951e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1e402415); 5952e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= ValidateCmd(device_data, cb_state, CMD_UPDATEBUFFER, "vkCmdUpdateBuffer()"); 5953e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= insideRenderPass(device_data, cb_state, "vkCmdUpdateBuffer()", VALIDATION_ERROR_1e400017); 5954e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis return skip; 5955e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis} 5956e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis 5957e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlisstatic void PostCallRecordCmdUpdateBuffer(layer_data *device_data, GLOBAL_CB_NODE *cb_state, BUFFER_STATE *dst_buffer_state) { 5958e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis // Update bindings between buffer and cmd buffer 5959e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis AddCommandBufferBindingBuffer(device_data, cb_state, dst_buffer_state); 5960e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis std::function<bool()> function = [=]() { 5961e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis SetBufferMemoryValid(device_data, dst_buffer_state, true); 5962e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis return false; 5963e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis }; 5964e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis cb_state->validate_functions.push_back(function); 5965e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis} 5966e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis 5967bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 5968bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDeviceSize dataSize, const uint32_t *pData) { 59693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 597056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5971ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 5972593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 5973e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis auto cb_state = GetCBNode(dev_data, commandBuffer); 5974e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis assert(cb_state); 59759a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_buff_state = GetBufferState(dev_data, dstBuffer); 5976e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis assert(dst_buff_state); 5977e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis skip |= PreCallCmdUpdateBuffer(dev_data, cb_state, dst_buff_state); 5978b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 5979e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis if (!skip) { 5980e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis dev_data->dispatch_table.CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData); 5981e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis lock.lock(); 5982e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis PostCallRecordCmdUpdateBuffer(dev_data, cb_state, dst_buff_state); 5983e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis lock.unlock(); 5984e08cf6348d38dc73e984f4ef9bc483f0aabb1914Tobin Ehlis } 59855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 59865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 5987bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 5988bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDeviceSize size, uint32_t data) { 598923bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 5990ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 599123bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski auto cb_node = GetCBNode(device_data, commandBuffer); 599223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski auto buffer_state = GetBufferState(device_data, dstBuffer); 5993593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 599423bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski if (cb_node && buffer_state) { 599523bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski bool skip = PreCallValidateCmdFillBuffer(device_data, cb_node, buffer_state); 599623bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski if (!skip) { 599723bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski PreCallRecordCmdFillBuffer(device_data, cb_node, buffer_state); 599823bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski lock.unlock(); 599923bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski device_data->dispatch_table.CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); 600023bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski } 6001ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis } else { 600223bb5a2fd221f6788daf2dd976bf19a5e9b20fb9Mark Lobodzinski lock.unlock(); 6003ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis assert(0); 60045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 60055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 60074028af23e688ab5730f48ab2244dd042e2eefaedMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 60084028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski const VkClearAttachment *pAttachments, uint32_t rectCount, 60094028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski const VkClearRect *pRects) { 60104028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski bool skip = false; 601156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 60124028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski { 6013ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 60144028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski skip = PreCallValidateCmdClearAttachments(dev_data, commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 60154028af23e688ab5730f48ab2244dd042e2eefaedMark Lobodzinski } 6016cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 60175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 60190482c55760707900fcd072f6895c121bcf055f6eMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 60200482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkClearColorValue *pColor, uint32_t rangeCount, 60210482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkImageSubresourceRange *pRanges) { 602256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6023ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 60240482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski 60250482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski bool skip = PreCallValidateCmdClearColorImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 60260482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski if (!skip) { 60270619dc1df076bfedcf0c999ceca3bdecd5ea5171Chris Forbes PreCallRecordCmdClearImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 60280482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski lock.unlock(); 60290482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski dev_data->dispatch_table.CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); 60300482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski } 60310482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski} 60320482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski 60330482c55760707900fcd072f6895c121bcf055f6eMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, 60340482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, 60350482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski const VkImageSubresourceRange *pRanges) { 603656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6037ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 60380482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski 60390482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski bool skip = PreCallValidateCmdClearDepthStencilImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 60400482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski if (!skip) { 60410619dc1df076bfedcf0c999ceca3bdecd5ea5171Chris Forbes PreCallRecordCmdClearImage(dev_data, commandBuffer, image, imageLayout, rangeCount, pRanges); 60420482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski lock.unlock(); 60430482c55760707900fcd072f6895c121bcf055f6eMark Lobodzinski dev_data->dispatch_table.CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); 60447f8aa8f5abceedbb599ef69af1dfbb38c0df2660Slawomir Cygan } 60455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6047bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, 6048bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, 6049bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkImageResolve *pRegions) { 605056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6051ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6052593c857d8db57cf9ae2c590b75e22dadd51bd3d4Tobin Ehlis 60539a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 60549a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto src_image_state = GetImageState(dev_data, srcImage); 60559a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_image_state = GetImageState(dev_data, dstImage); 605609fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski 605725f7873c9ce3ed39d18bba8750d7538905e150dfMark Lobodzinski bool skip = PreCallValidateCmdResolveImage(dev_data, cb_node, src_image_state, dst_image_state, regionCount, pRegions); 605809fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski 605909fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski if (!skip) { 60606c0400e625554ce7fddb833eeace0de19cfcc965Mark Lobodzinski PreCallRecordCmdResolveImage(dev_data, cb_node, src_image_state, dst_image_state); 60616c0400e625554ce7fddb833eeace0de19cfcc965Mark Lobodzinski lock.unlock(); 60624a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 60634a0754042cf090e131e9e769d8a3633c228625beChris Forbes pRegions); 606409fe5ac5edaec7f0dbcc9fd696e68194569aea89Mark Lobodzinski } 60655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 60665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6067a8d1e377bdeaf61a3209cb997502da4356a185bbMike WeiblenVKAPI_ATTR void VKAPI_CALL GetImageSubresourceLayout(VkDevice device, VkImage image, const VkImageSubresource *pSubresource, 6068a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen VkSubresourceLayout *pLayout) { 6069a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 6070a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen 6071a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen bool skip = PreCallValidateGetImageSubresourceLayout(device_data, image, pSubresource); 6072a8d1e377bdeaf61a3209cb997502da4356a185bbMike Weiblen if (!skip) { 6073b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski device_data->dispatch_table.GetImageSubresourceLayout(device, image, pSubresource, pLayout); 6074b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski } 6075b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski} 6076b06379a335598a3d8c53c694e875dda19eeab612Mark Lobodzinski 6077b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentinebool setEventStageMask(VkQueue queue, VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 607856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 60799a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 6080b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine if (pCB) { 6081b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine pCB->eventToStageMap[event] = stageMask; 6082b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6083b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine auto queue_data = dev_data->queueMap.find(queue); 6084b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine if (queue_data != dev_data->queueMap.end()) { 6085b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine queue_data->second.eventToStageMap[event] = stageMask; 6086b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6087b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine return false; 6088b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine} 6089b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine 6090bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 60913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 609256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6093ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 60949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 60955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 60963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdSetEvent()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6097315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1d402415); 60983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()"); 6099315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent()", VALIDATION_ERROR_1d400017); 6100315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, stageMask, "vkCmdSetEvent()", VALIDATION_ERROR_1d4008fc, 6101315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1d4008fe); 61029a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 61034710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 61049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&event_state->cb_bindings, {HandleToUint64(event), kVulkanObjectTypeEvent}, pCB); 61054710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->cb_bindings.insert(pCB); 6106ad13b09db50a49347ea6a8c1408fcc5280042898Tobin Ehlis } 61075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->events.push_back(event); 6108c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine if (!pCB->waitedEvents.count(event)) { 6109c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine pCB->writeEventsBeforeWait.push_back(event); 6110c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 6111f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes pCB->eventUpdates.emplace_back([=](VkQueue q){return setEventStageMask(q, commandBuffer, event, stageMask);}); 61125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6113b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 61143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdSetEvent(commandBuffer, event, stageMask); 61155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 61165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6117bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) { 61183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 611956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6120ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 61219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 61225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 61233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdResetEvent()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6124315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1c402415); 61253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()"); 6126315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent()", VALIDATION_ERROR_1c400017); 6127315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, stageMask, "vkCmdResetEvent()", VALIDATION_ERROR_1c400904, 6128315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1c400906); 61299a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 61304710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 61319b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&event_state->cb_bindings, {HandleToUint64(event), kVulkanObjectTypeEvent}, pCB); 61324710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->cb_bindings.insert(pCB); 6133ad13b09db50a49347ea6a8c1408fcc5280042898Tobin Ehlis } 61345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->events.push_back(event); 6135c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine if (!pCB->waitedEvents.count(event)) { 6136c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine pCB->writeEventsBeforeWait.push_back(event); 6137c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine } 6138315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis // TODO : Add check for VALIDATION_ERROR_32c008f8 6139f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes pCB->eventUpdates.emplace_back([=](VkQueue q){return setEventStageMask(q, commandBuffer, event, VkPipelineStageFlags(0));}); 61405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6141b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 61423251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdResetEvent(commandBuffer, event, stageMask); 61435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 61445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6145a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis// Return input pipeline stage flags, expanded for individual bits if VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT 6146a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlisstatic VkPipelineStageFlags ExpandPipelineStageFlags(VkPipelineStageFlags inflags) { 6147a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis return (inflags != VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT) 6148a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis ? inflags 6149a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis : (VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | 6150a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6151a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6152a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | 6153a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | 6154a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); 6155a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis} 6156a54aea2a72be3bd84371773cc79a678816615587Tobin Ehlis 6157f384f33742c2b72888372332747298d08135ac92Tobin Ehlis// Verify image barrier image state and that the image is consistent with FB image 6158f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool ValidateImageBarrierImage(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state, 615979fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis VkFramebuffer framebuffer, uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, 616079fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis uint64_t rp_handle, uint32_t img_index, const VkImageMemoryBarrier &img_barrier) { 6161f384f33742c2b72888372332747298d08135ac92Tobin Ehlis bool skip = false; 616279fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis const auto &fb_state = GetFramebufferState(device_data, framebuffer); 6163f384f33742c2b72888372332747298d08135ac92Tobin Ehlis assert(fb_state); 6164f384f33742c2b72888372332747298d08135ac92Tobin Ehlis const auto img_bar_image = img_barrier.image; 6165f384f33742c2b72888372332747298d08135ac92Tobin Ehlis bool image_match = false; 6166f384f33742c2b72888372332747298d08135ac92Tobin Ehlis bool sub_image_found = false; // Do we find a corresponding subpass description 6167f384f33742c2b72888372332747298d08135ac92Tobin Ehlis VkImageLayout sub_image_layout = VK_IMAGE_LAYOUT_UNDEFINED; 6168f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t attach_index = 0; 6169f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t index_count = 0; 6170f384f33742c2b72888372332747298d08135ac92Tobin Ehlis // Verify that a framebuffer image matches barrier image 6171f384f33742c2b72888372332747298d08135ac92Tobin Ehlis for (const auto &fb_attach : fb_state->attachments) { 6172f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (img_bar_image == fb_attach.image) { 6173f384f33742c2b72888372332747298d08135ac92Tobin Ehlis image_match = true; 6174f384f33742c2b72888372332747298d08135ac92Tobin Ehlis attach_index = index_count; 6175f384f33742c2b72888372332747298d08135ac92Tobin Ehlis break; 6176f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6177f384f33742c2b72888372332747298d08135ac92Tobin Ehlis index_count++; 6178f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6179f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (image_match) { // Make sure subpass is referring to matching attachment 6180f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (sub_desc.pDepthStencilAttachment && sub_desc.pDepthStencilAttachment->attachment == attach_index) { 6181f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_layout = sub_desc.pDepthStencilAttachment->layout; 6182f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_found = true; 6183f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { 6184f384f33742c2b72888372332747298d08135ac92Tobin Ehlis for (uint32_t j = 0; j < sub_desc.colorAttachmentCount; ++j) { 6185f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (sub_desc.pColorAttachments && sub_desc.pColorAttachments[j].attachment == attach_index) { 6186f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_layout = sub_desc.pColorAttachments[j].layout; 6187f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_found = true; 6188f384f33742c2b72888372332747298d08135ac92Tobin Ehlis break; 6189f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else if (sub_desc.pResolveAttachments && sub_desc.pResolveAttachments[j].attachment == attach_index) { 6190f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_layout = sub_desc.pResolveAttachments[j].layout; 6191f384f33742c2b72888372332747298d08135ac92Tobin Ehlis sub_image_found = true; 6192f384f33742c2b72888372332747298d08135ac92Tobin Ehlis break; 6193f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6194f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6195f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6196f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (!sub_image_found) { 6197f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= log_msg( 6198f384f33742c2b72888372332747298d08135ac92Tobin Ehlis device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, 6199f384f33742c2b72888372332747298d08135ac92Tobin Ehlis __LINE__, VALIDATION_ERROR_1b800936, "CORE", 6200f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].image (0x%" PRIx64 6201f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") is not referenced by the VkSubpassDescription for active subpass (%d) of current renderPass (0x%" PRIx64 "). %s", 6202f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, img_index, HandleToUint64(img_bar_image), active_subpass, rp_handle, 6203f384f33742c2b72888372332747298d08135ac92Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b800936]); 6204f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6205f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { // !image_match 6206f384f33742c2b72888372332747298d08135ac92Tobin Ehlis auto const fb_handle = HandleToUint64(fb_state->framebuffer); 6207f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= 6208f384f33742c2b72888372332747298d08135ac92Tobin Ehlis log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, fb_handle, 6209f384f33742c2b72888372332747298d08135ac92Tobin Ehlis __LINE__, VALIDATION_ERROR_1b800936, "CORE", 6210f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].image (0x%" PRIx64 6211f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") does not match an image from the current framebuffer (0x%" PRIx64 "). %s", 6212f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, img_index, HandleToUint64(img_bar_image), fb_handle, validation_error_map[VALIDATION_ERROR_1b800936]); 6213f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6214f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (img_barrier.oldLayout != img_barrier.newLayout) { 6215f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6216f384f33742c2b72888372332747298d08135ac92Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b80093a, "CORE", 6217f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: As the Image Barrier for image 0x%" PRIx64 6218f384f33742c2b72888372332747298d08135ac92Tobin Ehlis " is being executed within a render pass instance, oldLayout must equal newLayout yet they are " 6219f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s and %s. %s", 6220f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, HandleToUint64(img_barrier.image), string_VkImageLayout(img_barrier.oldLayout), 6221f384f33742c2b72888372332747298d08135ac92Tobin Ehlis string_VkImageLayout(img_barrier.newLayout), validation_error_map[VALIDATION_ERROR_1b80093a]); 6222f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { 6223f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (sub_image_found && sub_image_layout != img_barrier.oldLayout) { 6224f384f33742c2b72888372332747298d08135ac92Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 6225f384f33742c2b72888372332747298d08135ac92Tobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800938, "CORE", 6226f384f33742c2b72888372332747298d08135ac92Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].image (0x%" PRIx64 6227f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") is referenced by the VkSubpassDescription for active subpass (%d) of current renderPass (0x%" PRIx64 6228f384f33742c2b72888372332747298d08135ac92Tobin Ehlis ") as having layout %s, but image barrier has layout %s. %s", 6229f384f33742c2b72888372332747298d08135ac92Tobin Ehlis funcName, img_index, HandleToUint64(img_bar_image), active_subpass, rp_handle, 6230f384f33742c2b72888372332747298d08135ac92Tobin Ehlis string_VkImageLayout(img_barrier.oldLayout), string_VkImageLayout(sub_image_layout), 6231f384f33742c2b72888372332747298d08135ac92Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b800938]); 6232f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6233f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 6234f384f33742c2b72888372332747298d08135ac92Tobin Ehlis return skip; 6235f384f33742c2b72888372332747298d08135ac92Tobin Ehlis} 6236f384f33742c2b72888372332747298d08135ac92Tobin Ehlis 62374cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis// Validate image barriers within a renderPass 6238f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool ValidateRenderPassImageBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE *cb_state, 62394cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis uint32_t active_subpass, const safe_VkSubpassDescription &sub_desc, uint64_t rp_handle, 62404cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VkAccessFlags sub_src_access_mask, VkAccessFlags sub_dst_access_mask, 62414cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis uint32_t image_mem_barrier_count, const VkImageMemoryBarrier *image_barriers) { 6242a4a1923d21087ded8e990190acd6752264712319Tobin Ehlis bool skip = false; 62434cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis for (uint32_t i = 0; i < image_mem_barrier_count; ++i) { 62444cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &img_barrier = image_barriers[i]; 62454cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &img_src_access_mask = img_barrier.srcAccessMask; 62464cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (img_src_access_mask != (sub_src_access_mask & img_src_access_mask)) { 6247c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 62484cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE", 62494cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency " 62504cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "srcAccessMask(0x%X) of " 6251e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 62524cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, img_src_access_mask, sub_src_access_mask, active_subpass, rp_handle, 62534cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092e]); 6254e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis } 62554cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &img_dst_access_mask = img_barrier.dstAccessMask; 62564cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (img_dst_access_mask != (sub_dst_access_mask & img_dst_access_mask)) { 6257c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 62584cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE", 62594cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency " 62604cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "dstAccessMask(0x%X) of " 6261e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 62624cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, img_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle, 62634cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b800930]); 62645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 62658f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis if (VK_QUEUE_FAMILY_IGNORED != img_barrier.srcQueueFamilyIndex || 62668f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis VK_QUEUE_FAMILY_IGNORED != img_barrier.dstQueueFamilyIndex) { 62678f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 62688f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80093c, "CORE", 62698f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis "%s: Barrier pImageMemoryBarriers[%d].srcQueueFamilyIndex is %d and " 62708f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis "pImageMemoryBarriers[%d].dstQueueFamilyIndex is %d but both must be VK_QUEUE_FAMILY_IGNORED. %s", 62718f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis funcName, i, img_barrier.srcQueueFamilyIndex, i, img_barrier.dstQueueFamilyIndex, 62728f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b80093c]); 62738f2467c1db3d48bcfd09dd91188dcb0318fa5c43Tobin Ehlis } 6274f384f33742c2b72888372332747298d08135ac92Tobin Ehlis // Secondary CBs can have null framebuffer so queue up validation in that case 'til FB is known 6275f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (VK_NULL_HANDLE == cb_state->activeFramebuffer) { 6276f384f33742c2b72888372332747298d08135ac92Tobin Ehlis assert(VK_COMMAND_BUFFER_LEVEL_SECONDARY == cb_state->createInfo.level); 6277f384f33742c2b72888372332747298d08135ac92Tobin Ehlis // Secondary CB case w/o FB specified delay validation 627879fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis cb_state->cmd_execute_commands_functions.emplace_back([=](VkFramebuffer fb) { 627979fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis return ValidateImageBarrierImage(device_data, funcName, cb_state, fb, active_subpass, sub_desc, rp_handle, i, 6280f384f33742c2b72888372332747298d08135ac92Tobin Ehlis img_barrier); 6281f384f33742c2b72888372332747298d08135ac92Tobin Ehlis }); 6282f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } else { 628379fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis skip |= ValidateImageBarrierImage(device_data, funcName, cb_state, cb_state->activeFramebuffer, active_subpass, 628479fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis sub_desc, rp_handle, i, img_barrier); 62853025e72bc2b727622969d036966f50057392551aTobin Ehlis } 62864cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 62874cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis return skip; 62884cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis} 62894cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis 62904cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis// Validate VUs for Pipeline Barriers that are within a renderPass 62914cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis// Pre: cb_state->activeRenderPass must be a pointer to valid renderPass state 6292f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool ValidateRenderPassPipelineBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE *cb_state, 62934cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, 62944cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VkDependencyFlags dependency_flags, uint32_t mem_barrier_count, 62954cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const VkMemoryBarrier *mem_barriers, uint32_t buffer_mem_barrier_count, 62964cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const VkBufferMemoryBarrier *buffer_mem_barriers, uint32_t image_mem_barrier_count, 62974cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const VkImageMemoryBarrier *image_barriers) { 62984cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis bool skip = false; 62994cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis auto rp_state = cb_state->activeRenderPass; 63004cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto active_subpass = cb_state->activeSubpass; 63014cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis auto rp_handle = HandleToUint64(rp_state->renderPass); 63024cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (!rp_state->hasSelfDependency[active_subpass]) { 63034cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 63044cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800928, "CORE", 63054cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barriers cannot be set during subpass %d of renderPass 0x%" PRIx64 63064cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis " with no self-dependency specified. %s", 63074cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, active_subpass, rp_handle, validation_error_map[VALIDATION_ERROR_1b800928]); 63084cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } else { 63094cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis assert(rp_state->subpass_to_dependency_index[cb_state->activeSubpass] != -1); 63104cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis // Grab ref to current subpassDescription up-front for use below 63114cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_desc = rp_state->createInfo.pSubpasses[active_subpass]; 63124cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_dep = rp_state->createInfo.pDependencies[rp_state->subpass_to_dependency_index[active_subpass]]; 63134cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_src_stage_mask = ExpandPipelineStageFlags(sub_dep.srcStageMask); 63144cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_dst_stage_mask = ExpandPipelineStageFlags(sub_dep.dstStageMask); 63154cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if ((sub_src_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) && 63164cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis (src_stage_mask != (sub_src_stage_mask & src_stage_mask))) { 63174cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 63184cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80092a, "CORE", 63194cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier srcStageMask(0x%X) is not a subset of VkSubpassDependency srcStageMask(0x%X) of " 63204cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 63214cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, src_stage_mask, sub_src_stage_mask, active_subpass, rp_handle, 63224cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092a]); 63234cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 63244cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if ((sub_dst_stage_mask != VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) && 63254cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis (dst_stage_mask != (sub_dst_stage_mask & dst_stage_mask))) { 63264cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 63274cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b80092c, "CORE", 63284cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier dstStageMask(0x%X) is not a subset of VkSubpassDependency dstStageMask(0x%X) of " 63294cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 63304cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, dst_stage_mask, sub_dst_stage_mask, active_subpass, rp_handle, 63314cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092c]); 63324cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 63334cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (0 != buffer_mem_barrier_count) { 63344cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 63354cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800934, "CORE", 63364cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: bufferMemoryBarrierCount is non-zero (%d) for " 63374cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 63384cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, buffer_mem_barrier_count, active_subpass, rp_handle, 63394cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b800934]); 63404cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 63414cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_src_access_mask = sub_dep.srcAccessMask; 63424cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &sub_dst_access_mask = sub_dep.dstAccessMask; 63434cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis for (uint32_t i = 0; i < mem_barrier_count; ++i) { 63444cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &mb_src_access_mask = mem_barriers[i].srcAccessMask; 63454cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (mb_src_access_mask != (sub_src_access_mask & mb_src_access_mask)) { 63464cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 63474cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b80092e, "CORE", 63484cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pMemoryBarriers[%d].srcAccessMask(0x%X) is not a subset of VkSubpassDependency " 63494cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "srcAccessMask(0x%X) of " 63504cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 63514cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, mb_src_access_mask, sub_src_access_mask, active_subpass, rp_handle, 63524cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b80092e]); 63534cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 63544cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis const auto &mb_dst_access_mask = mem_barriers[i].dstAccessMask; 63554cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis if (mb_dst_access_mask != (sub_dst_access_mask & mb_dst_access_mask)) { 63564cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 63574cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, rp_handle, __LINE__, VALIDATION_ERROR_1b800930, "CORE", 63584cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "%s: Barrier pMemoryBarriers[%d].dstAccessMask(0x%X) is not a subset of VkSubpassDependency " 63594cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "dstAccessMask(0x%X) of " 63604cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 63614cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis funcName, i, mb_dst_access_mask, sub_dst_access_mask, active_subpass, rp_handle, 63624cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis validation_error_map[VALIDATION_ERROR_1b800930]); 63634cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 63644cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis } 63654cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis skip |= ValidateRenderPassImageBarriers(device_data, funcName, cb_state, active_subpass, sub_desc, rp_handle, 63664cb62e790b73480ea81682b140a23d3717bd42abTobin Ehlis sub_src_access_mask, sub_dst_access_mask, image_mem_barrier_count, image_barriers); 6367c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis if (sub_dep.dependencyFlags != dependency_flags) { 6368c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 6369c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis rp_handle, __LINE__, VALIDATION_ERROR_1b800932, "CORE", 6370c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis "%s: dependencyFlags param (0x%X) does not equal VkSubpassDependency " 6371c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis "dependencyFlags value (0x%X) for " 6372c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis "subpass %d of renderPass 0x%" PRIx64 ". %s", 6373c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis funcName, dependency_flags, sub_dep.dependencyFlags, cb_state->activeSubpass, rp_handle, 6374c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b800932]); 6375c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis } 63765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6377e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis return skip; 6378e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis} 6379e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis 6380d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis// Array to mask individual accessMask to corresponding stageMask 6381d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis// accessMask active bit position (0-31) maps to index 6382d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlisconst static VkPipelineStageFlags AccessMaskToPipeStage[20] = { 6383d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0 6384d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 6385d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_INDEX_READ_BIT = 1 6386d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 6387d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 2 6388d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 6389d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_UNIFORM_READ_BIT = 3 6390d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6391d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6392d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 6393d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 4 6394d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 6395d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_SHADER_READ_BIT = 5 6396d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6397d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6398d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 6399d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_SHADER_WRITE_BIT = 6 6400d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | 6401d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | 6402d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 6403d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 7 6404d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6405d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 8 6406d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 6407d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 9 6408d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6409d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 10 6410d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 6411d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_TRANSFER_READ_BIT = 11 6412d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TRANSFER_BIT, 6413d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_TRANSFER_WRITE_BIT = 12 6414d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_TRANSFER_BIT, 6415d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_HOST_READ_BIT = 13 6416d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_HOST_BIT, 6417d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_HOST_WRITE_BIT = 14 6418d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_HOST_BIT, 6419d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_MEMORY_READ_BIT = 15 6420d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_ACCESS_FLAG_BITS_MAX_ENUM, // Always match 6421d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_MEMORY_WRITE_BIT = 16 6422d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_ACCESS_FLAG_BITS_MAX_ENUM, // Always match 6423d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 17 6424d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, 6425d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 18 6426d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, 6427d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis}; 6428d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis 6429d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis// Verify that all bits of access_mask are supported by the src_stage_mask 6430d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlisstatic bool ValidateAccessMaskPipelineStage(VkAccessFlags access_mask, VkPipelineStageFlags stage_mask) { 6431d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // Early out if all commands set, or access_mask NULL 6432d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if ((stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) || (0 == access_mask)) return true; 6433d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis 6434d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis stage_mask = ExpandPipelineStageFlags(stage_mask); 6435d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis int index = 0; 6436d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // for each of the set bits in access_mask, make sure that supporting stage mask bit(s) are set 6437d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis while (access_mask) { 6438d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis index = (u_ffs(access_mask) - 1); 6439d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis assert(index >= 0); 6440d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis // Must have "!= 0" compare to prevent warning from MSVC 6441d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if ((AccessMaskToPipeStage[index] & stage_mask) == 0) return false; // early out 6442d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis access_mask &= ~(1 << index); // Mask off bit that's been checked 6443d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 6444d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis return true; 6445d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis} 6446d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis 6447e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlisstatic bool ValidateBarriers(layer_data *device_data, const char *funcName, GLOBAL_CB_NODE const *cb_state, 6448e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask, uint32_t memBarrierCount, 6449e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis const VkMemoryBarrier *pMemBarriers, uint32_t bufferBarrierCount, 6450e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis const VkBufferMemoryBarrier *pBufferMemBarriers, uint32_t imageMemBarrierCount, 6451e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis const VkImageMemoryBarrier *pImageMemBarriers) { 6452e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis bool skip = false; 6453d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis for (uint32_t i = 0; i < memBarrierCount; ++i) { 6454d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis const auto &mem_barrier = pMemBarriers[i]; 6455d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier.srcAccessMask, src_stage_mask)) { 6456d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6457d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800940, "DS", 6458d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis "%s: pMemBarriers[%d].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X). %s", funcName, i, 6459d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis mem_barrier.srcAccessMask, src_stage_mask, validation_error_map[VALIDATION_ERROR_1b800940]); 6460d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 64611ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier.dstAccessMask, dst_stage_mask)) { 64621ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 64631ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800942, "DS", 64641ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis "%s: pMemBarriers[%d].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X). %s", funcName, i, 64651ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis mem_barrier.dstAccessMask, dst_stage_mask, validation_error_map[VALIDATION_ERROR_1b800942]); 64661ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis } 6467d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 64685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < imageMemBarrierCount; ++i) { 64695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto mem_barrier = &pImageMemBarriers[i]; 6470d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->srcAccessMask, src_stage_mask)) { 6471d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6472d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800940, "DS", 6473d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis "%s: pImageMemBarriers[%d].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X). %s", funcName, 6474d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis i, mem_barrier->srcAccessMask, src_stage_mask, validation_error_map[VALIDATION_ERROR_1b800940]); 6475d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 64761ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->dstAccessMask, dst_stage_mask)) { 64771ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 64781ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800942, "DS", 64791ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis "%s: pImageMemBarriers[%d].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X). %s", funcName, 64801ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis i, mem_barrier->dstAccessMask, dst_stage_mask, validation_error_map[VALIDATION_ERROR_1b800942]); 64811ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis } 6482e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis auto image_data = GetImageState(device_data, mem_barrier->image); 64838f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (image_data) { 64848f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski uint32_t src_q_f_index = mem_barrier->srcQueueFamilyIndex; 64858f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski uint32_t dst_q_f_index = mem_barrier->dstQueueFamilyIndex; 64868f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (image_data->createInfo.sharingMode == VK_SHARING_MODE_CONCURRENT) { 64878f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // srcQueueFamilyIndex and dstQueueFamilyIndex must both 64888f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // be VK_QUEUE_FAMILY_IGNORED 64898f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if ((src_q_f_index != VK_QUEUE_FAMILY_IGNORED) || (dst_q_f_index != VK_QUEUE_FAMILY_IGNORED)) { 6490e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 6491e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), 6492e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 6493e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "%s: Image Barrier for image 0x%" PRIx64 6494e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis " was created with sharingMode of " 6495e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "VK_SHARING_MODE_CONCURRENT. Src and dst " 6496e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "queueFamilyIndices must be VK_QUEUE_FAMILY_IGNORED.", 64979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->image)); 64988f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 64998f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } else { 65008f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // Sharing mode is VK_SHARING_MODE_EXCLUSIVE. srcQueueFamilyIndex and 65018f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // dstQueueFamilyIndex must either both be VK_QUEUE_FAMILY_IGNORED, 65028f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski // or both be a valid queue family 65038f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (((src_q_f_index == VK_QUEUE_FAMILY_IGNORED) || (dst_q_f_index == VK_QUEUE_FAMILY_IGNORED)) && 65048f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski (src_q_f_index != dst_q_f_index)) { 6505e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 6506e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), 6507e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 6508e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "%s: Image 0x%" PRIx64 6509e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis " was created with sharingMode " 6510e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "of VK_SHARING_MODE_EXCLUSIVE. If one of src- or " 6511e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "dstQueueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, both " 6512e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "must be.", 65139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->image)); 65148f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } else if (((src_q_f_index != VK_QUEUE_FAMILY_IGNORED) && (dst_q_f_index != VK_QUEUE_FAMILY_IGNORED)) && 6515e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis ((src_q_f_index >= device_data->phys_dev_properties.queue_family_properties.size()) || 6516e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis (dst_q_f_index >= device_data->phys_dev_properties.queue_family_properties.size()))) { 6517e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 6518e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(cb_state->commandBuffer), 6519e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 65208f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski "%s: Image 0x%" PRIx64 65218f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski " was created with sharingMode " 65228f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski "of VK_SHARING_MODE_EXCLUSIVE, but srcQueueFamilyIndex %d" 65238f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski " or dstQueueFamilyIndex %d is greater than " PRINTF_SIZE_T_SPECIFIER 65248f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski "queueFamilies crated for this device.", 65259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->image), src_q_f_index, dst_q_f_index, 6526e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis device_data->phys_dev_properties.queue_family_properties.size()); 65275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 65285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 65298f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 65305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 65318f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (mem_barrier->oldLayout != mem_barrier->newLayout) { 6532e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateMaskBitsFromLayouts(device_data, cb_state->commandBuffer, mem_barrier->srcAccessMask, 6533e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis mem_barrier->oldLayout, "Source"); 6534e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateMaskBitsFromLayouts(device_data, cb_state->commandBuffer, mem_barrier->dstAccessMask, 6535e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis mem_barrier->newLayout, "Dest"); 65368f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 65378f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (mem_barrier->newLayout == VK_IMAGE_LAYOUT_UNDEFINED || mem_barrier->newLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) { 6538e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6539e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 6540df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "%s: Image Layout cannot be transitioned to UNDEFINED or " 6541df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "PREINITIALIZED.", 6542df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski funcName); 65438f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski } 65448f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski if (image_data) { 65458f3c2a27e8e6feeb21d6be3b6f9f8d0606f67457Mark Lobodzinski auto aspect_mask = mem_barrier->subresourceRange.aspectMask; 6546e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageAspectMask(device_data, image_data->image, image_data->createInfo.format, aspect_mask, funcName); 654795b7894efd5e101e410da92fc697429aec3ffa7bMark Lobodzinski 654823c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus std::string param_name = "pImageMemoryBarriers[" + std::to_string(i) + "].subresourceRange"; 6549e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateImageSubresourceRange(device_data, image_data, false, mem_barrier->subresourceRange, funcName, 655023c5a2092f724fef497a5c87a489f32c8fa51e58Petr Kraus param_name.c_str()); 65515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 65525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 65532044b110851e8f1b75d6d406a0c88612476c63dbChris Forbes 65545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < bufferBarrierCount; ++i) { 65555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto mem_barrier = &pBufferMemBarriers[i]; 6556cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!mem_barrier) continue; 65575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6558d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->srcAccessMask, src_stage_mask)) { 6559d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6560d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800940, "DS", 6561d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis "%s: pBufferMemBarriers[%d].srcAccessMask (0x%X) is not supported by srcStageMask (0x%X). %s", funcName, 6562d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis i, mem_barrier->srcAccessMask, src_stage_mask, validation_error_map[VALIDATION_ERROR_1b800940]); 6563d8aeb60bc6809b7ecac32f95db7f89d9c79a0a1cTobin Ehlis } 65641ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis if (!ValidateAccessMaskPipelineStage(mem_barrier->dstAccessMask, dst_stage_mask)) { 65651ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 65661ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, VALIDATION_ERROR_1b800942, "DS", 65671ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis "%s: pBufferMemBarriers[%d].dstAccessMask (0x%X) is not supported by dstStageMask (0x%X). %s", funcName, 65681ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis i, mem_barrier->dstAccessMask, dst_stage_mask, validation_error_map[VALIDATION_ERROR_1b800942]); 65691ce9b1e7d3dfd0841efede007022bdc960917008Tobin Ehlis } 65705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Validate buffer barrier queue family indices 65715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if ((mem_barrier->srcQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED && 6572e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis mem_barrier->srcQueueFamilyIndex >= device_data->phys_dev_properties.queue_family_properties.size()) || 65735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis (mem_barrier->dstQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED && 6574e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis mem_barrier->dstQueueFamilyIndex >= device_data->phys_dev_properties.queue_family_properties.size())) { 6575e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6576e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_INDEX, "DS", 6577cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "%s: Buffer Barrier 0x%" PRIx64 6578cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " has QueueFamilyIndex greater " 6579a4a1923d21087ded8e990190acd6752264712319Tobin Ehlis "than the number of QueueFamilies (" PRINTF_SIZE_T_SPECIFIER ") for this device.", 65809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->buffer), 6581e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis device_data->phys_dev_properties.queue_family_properties.size()); 65825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 65835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6584e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis auto buffer_state = GetBufferState(device_data, mem_barrier->buffer); 65855cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (buffer_state) { 65865cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis auto buffer_size = buffer_state->requirements.size; 65875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (mem_barrier->offset >= buffer_size) { 6588e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= log_msg( 6589e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6590e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 6591e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis "%s: Buffer Barrier 0x%" PRIx64 " has offset 0x%" PRIx64 " which is not less than total size 0x%" PRIx64 ".", 6592e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis funcName, HandleToUint64(mem_barrier->buffer), HandleToUint64(mem_barrier->offset), 6593e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(buffer_size)); 6594df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski } else if (mem_barrier->size != VK_WHOLE_SIZE && (mem_barrier->offset + mem_barrier->size > buffer_size)) { 6595df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= 6596e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6597e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis HandleToUint64(cb_state->commandBuffer), __LINE__, DRAWSTATE_INVALID_BARRIER, "DS", 6598df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "%s: Buffer Barrier 0x%" PRIx64 " has offset 0x%" PRIx64 " and size 0x%" PRIx64 6599df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski " whose sum is greater than total size 0x%" PRIx64 ".", 66009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus funcName, HandleToUint64(mem_barrier->buffer), HandleToUint64(mem_barrier->offset), 66019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_barrier->size), HandleToUint64(buffer_size)); 66025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 66035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 66045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6605a4a1923d21087ded8e990190acd6752264712319Tobin Ehlis return skip; 66065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 66075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6608bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskibool validateEventStageMask(VkQueue queue, GLOBAL_CB_NODE *pCB, uint32_t eventCount, size_t firstEventIndex, 6609bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkPipelineStageFlags sourceStageMask) { 66103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 6611b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine VkPipelineStageFlags stageMask = 0; 661256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 6613b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine for (uint32_t i = 0; i < eventCount; ++i) { 66142ab14387df9b890fe4b13494ea249dd03cf898d2Chris Forbes auto event = pCB->events[firstEventIndex + i]; 6615b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine auto queue_data = dev_data->queueMap.find(queue); 6616cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (queue_data == dev_data->queueMap.end()) return false; 66172ab14387df9b890fe4b13494ea249dd03cf898d2Chris Forbes auto event_data = queue_data->second.eventToStageMap.find(event); 6618b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine if (event_data != queue_data->second.eventToStageMap.end()) { 6619b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine stageMask |= event_data->second; 6620b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } else { 66219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto global_event_data = GetEventNode(dev_data, event); 66229556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis if (!global_event_data) { 66233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, 66249b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event), __LINE__, DRAWSTATE_INVALID_EVENT, "DS", 66259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Event 0x%" PRIx64 " cannot be waited on if it has never been set.", HandleToUint64(event)); 6626b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } else { 66279556936067fd0c4eb74c4a13631bc163b154faedTobin Ehlis stageMask |= global_event_data->stageMask; 6628b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6629b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6630b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 6631c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine // TODO: Need to validate that host_bit is only set if set event is called 6632c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine // but set event can be called at any time. 6633c1eb2a3736e03aaa15b849d217fd963021dc9780Michael Lentine if (sourceStageMask != stageMask && sourceStageMask != (stageMask | VK_PIPELINE_STAGE_HOST_BIT)) { 66343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6635315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCB->commandBuffer), __LINE__, VALIDATION_ERROR_1e62d401, "DS", 66363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Submitting cmdbuffer with call to VkCmdWaitEvents " 66373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "using srcStageMask 0x%X which must be the bitwise " 66383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "OR of the stageMask parameters used in calls to " 66393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdSetEvent and VK_PIPELINE_STAGE_HOST_BIT if " 66403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "used with vkSetEvent but instead is 0x%X. %s", 6641315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis sourceStageMask, stageMask, validation_error_map[VALIDATION_ERROR_1e62d401]); 6642b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine } 66433251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6644b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine} 6645b4cc521cc1250cec2a064e22a4d840f1ab42370dMichael Lentine 664607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski// Note that we only check bits that HAVE required queueflags -- don't care entries are skipped 664707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinskistatic std::unordered_map<VkPipelineStageFlags, VkQueueFlags> supported_pipeline_stages_table = { 664807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT}, 664907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT}, 665007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_QUEUE_GRAPHICS_BIT}, 665107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 665207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 665307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 665407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 665507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_QUEUE_GRAPHICS_BIT}, 665607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_QUEUE_GRAPHICS_BIT}, 665707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_QUEUE_GRAPHICS_BIT}, 665807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_QUEUE_GRAPHICS_BIT}, 665907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_QUEUE_COMPUTE_BIT}, 666007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT}, 666107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski {VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_QUEUE_GRAPHICS_BIT}}; 666207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 666307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinskistatic const VkPipelineStageFlags stage_flag_bit_array[] = {VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX, 666407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 666507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 666607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 666707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, 666807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, 666907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, 667007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 667107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, 667207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 667307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 667407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 667507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_TRANSFER_BIT, 667607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT}; 667707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 667807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinskibool CheckStageMaskQueueCompatibility(layer_data *dev_data, VkCommandBuffer command_buffer, VkPipelineStageFlags stage_mask, 667907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VkQueueFlags queue_flags, const char *function, const char *src_or_dest, 668007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski UNIQUE_VALIDATION_ERROR_CODE error_code) { 668107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski bool skip = false; 668207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // Lookup each bit in the stagemask and check for overlap between its table bits and queue_flags 668307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski for (const auto &item : stage_flag_bit_array) { 668407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if (stage_mask & item) { 668507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if ((supported_pipeline_stages_table[item] & queue_flags) == 0) { 668607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski skip |= 668707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 66889b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(command_buffer), __LINE__, error_code, "DL", 668907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski "%s(): %s flag %s is not compatible with the queue family properties of this " 669007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski "command buffer. %s", 669107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski function, src_or_dest, string_VkPipelineStageFlagBits(static_cast<VkPipelineStageFlagBits>(item)), 669207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski validation_error_map[error_code]); 669307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 669407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 669507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 669607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski return skip; 669707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski} 669807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 6699e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlisbool ValidateStageMasksAgainstQueueCapabilities(layer_data *dev_data, GLOBAL_CB_NODE const *cb_state, 670007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VkPipelineStageFlags source_stage_mask, VkPipelineStageFlags dest_stage_mask, 670107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski const char *function, UNIQUE_VALIDATION_ERROR_CODE error_code) { 670207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski bool skip = false; 670307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski uint32_t queue_family_index = dev_data->commandPoolMap[cb_state->createInfo.commandPool].queueFamilyIndex; 670456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(dev_data->physical_device), instance_layer_data_map); 67059a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, dev_data->physical_device); 670607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 670707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // Any pipeline stage included in srcStageMask or dstStageMask must be supported by the capabilities of the queue family 670807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // specified by the queueFamilyIndex member of the VkCommandPoolCreateInfo structure that was used to create the VkCommandPool 670907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski // that commandBuffer was allocated from, as specified in the table of supported pipeline stages. 671007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 671107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if (queue_family_index < physical_device_state->queue_family_properties.size()) { 671207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski VkQueueFlags specified_queue_flags = physical_device_state->queue_family_properties[queue_family_index].queueFlags; 671307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 671407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if ((source_stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) == 0) { 671507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski skip |= CheckStageMaskQueueCompatibility(dev_data, cb_state->commandBuffer, source_stage_mask, specified_queue_flags, 671607059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski function, "srcStageMask", error_code); 671707059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 671807059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski if ((dest_stage_mask & VK_PIPELINE_STAGE_ALL_COMMANDS_BIT) == 0) { 671907059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski skip |= CheckStageMaskQueueCompatibility(dev_data, cb_state->commandBuffer, dest_stage_mask, specified_queue_flags, 672007059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski function, "dstStageMask", error_code); 672107059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 672207059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski } 672307059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski return skip; 672407059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski} 672507059341a6ab09b3bd64727d2689082828492191Mark Lobodzinski 6726d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, 6727d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski VkPipelineStageFlags sourceStageMask, VkPipelineStageFlags dstStageMask, 6728d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 6729d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 6730d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 6731d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski bool skip = false; 673256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6733ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 67349a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 6735d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski if (cb_state) { 6736d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski skip |= ValidateStageMasksAgainstQueueCapabilities(dev_data, cb_state, sourceStageMask, dstStageMask, "vkCmdWaitEvents", 6737315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e600918); 6738315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, sourceStageMask, "vkCmdWaitEvents()", VALIDATION_ERROR_1e60090e, 6739315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e600912); 6740315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(dev_data, dstStageMask, "vkCmdWaitEvents()", VALIDATION_ERROR_1e600910, 6741315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e600914); 6742d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski auto first_event_index = cb_state->events.size(); 67435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < eventCount; ++i) { 67449a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, pEvents[i]); 67454710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 67469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus addCommandBufferBinding(&event_state->cb_bindings, {HandleToUint64(pEvents[i]), kVulkanObjectTypeEvent}, cb_state); 6747d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski event_state->cb_bindings.insert(cb_state); 6748ad13b09db50a49347ea6a8c1408fcc5280042898Tobin Ehlis } 6749d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski cb_state->waitedEvents.insert(pEvents[i]); 6750d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski cb_state->events.push_back(pEvents[i]); 67515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6752f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes cb_state->eventUpdates.emplace_back([=](VkQueue q){ 6753f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes return validateEventStageMask(q, cb_state, eventCount, first_event_index, sourceStageMask); 6754f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes }); 6755baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdWaitEvents()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6756315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e602415); 6757ecf8b73f862ce67b99fdc57435d3d092afe4e705Mark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_WAITEVENTS, "vkCmdWaitEvents()"); 6758e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateBarriersToImages(dev_data, cb_state, imageMemoryBarrierCount, pImageMemoryBarriers, "vkCmdWaitEvents()"); 6759e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski if (!skip) { 6760e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski TransitionImageLayouts(dev_data, commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); 6761e659c986db0f3146726d6c744c75772316c3e0c6Mark Lobodzinski } 6762e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateBarriers(dev_data, "vkCmdWaitEvents()", cb_state, sourceStageMask, dstStageMask, memoryBarrierCount, 6763e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, 6764e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pImageMemoryBarriers); 67655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6766b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 6767d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski if (!skip) 67684a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask, 67694a0754042cf090e131e9e769d8a3633c228625beChris Forbes memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, 67704a0754042cf090e131e9e769d8a3633c228625beChris Forbes imageMemoryBarrierCount, pImageMemoryBarriers); 67715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 67725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6773f384f33742c2b72888372332747298d08135ac92Tobin Ehlisstatic bool PreCallValidateCmdPipelineBarrier(layer_data *device_data, GLOBAL_CB_NODE *cb_state, VkPipelineStageFlags srcStageMask, 6774f384f33742c2b72888372332747298d08135ac92Tobin Ehlis VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, 6775f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 6776f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 6777f384f33742c2b72888372332747298d08135ac92Tobin Ehlis uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 677803122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski bool skip = false; 677903122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski skip |= ValidateStageMasksAgainstQueueCapabilities(device_data, cb_state, srcStageMask, dstStageMask, "vkCmdPipelineBarrier", 6780315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b80093e); 6781baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(device_data, cb_state, "vkCmdPipelineBarrier()", 6782315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1b802415); 678303122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski skip |= ValidateCmd(device_data, cb_state, CMD_PIPELINEBARRIER, "vkCmdPipelineBarrier()"); 6784315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(device_data, srcStageMask, "vkCmdPipelineBarrier()", VALIDATION_ERROR_1b800920, 6785315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b800924); 6786315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateStageMaskGsTsEnables(device_data, dstStageMask, "vkCmdPipelineBarrier()", VALIDATION_ERROR_1b800922, 6787315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b800926); 6788e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis if (cb_state->activeRenderPass) { 6789e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateRenderPassPipelineBarriers(device_data, "vkCmdPipelineBarrier()", cb_state, srcStageMask, dstStageMask, 6790c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 6791e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 6792a287b10c55baa7d2d2ac891eb729666f988766eaTobin Ehlis if (skip) return true; // Early return to avoid redundant errors from below calls 6793e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis } 6794a287b10c55baa7d2d2ac891eb729666f988766eaTobin Ehlis skip |= 6795a287b10c55baa7d2d2ac891eb729666f988766eaTobin Ehlis ValidateBarriersToImages(device_data, cb_state, imageMemoryBarrierCount, pImageMemoryBarriers, "vkCmdPipelineBarrier()"); 6796e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis skip |= ValidateBarriers(device_data, "vkCmdPipelineBarrier()", cb_state, srcStageMask, dstStageMask, memoryBarrierCount, 6797e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, 6798e2d4ce3059fa77badeea63fa2003b83a04ca9c98Tobin Ehlis pImageMemoryBarriers); 679903122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski return skip; 680003122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski} 680103122452370ba372b7fb62eaad6ef56a963b3fb0Mark Lobodzinski 68026f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinskistatic void PreCallRecordCmdPipelineBarrier(layer_data *device_data, GLOBAL_CB_NODE *cb_state, VkCommandBuffer commandBuffer, 68036f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 68046f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski TransitionImageLayouts(device_data, commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); 68056f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski} 68066f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski 6807d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, 6808d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, 6809d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 6810d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, 6811d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { 6812d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski bool skip = false; 68136f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6814ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 68156f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(device_data, commandBuffer); 6816d91b0b35cff4dc73d88fcf4ea567bd37997bbd98Mark Lobodzinski if (cb_state) { 6817c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis skip |= PreCallValidateCmdPipelineBarrier(device_data, cb_state, srcStageMask, dstStageMask, dependencyFlags, 6818c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 6819c1c43cc01e333f3762c65ce4ad926c33235583d2Tobin Ehlis pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 68206f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski if (!skip) { 68216f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski PreCallRecordCmdPipelineBarrier(device_data, cb_state, commandBuffer, imageMemoryBarrierCount, pImageMemoryBarriers); 68226f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski } 68236f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski } else { 68246f88609b0b59259ed29581f1d824ee5e9d7c82ccMark Lobodzinski assert(0); 68255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6826b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 6827a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour if (!skip) { 6828a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour device_data->dispatch_table.CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, 6829a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, 6830a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour imageMemoryBarrierCount, pImageMemoryBarriers); 6831a79957f762f6fc6b74c25cb94d35a3fc36967471Tony Barbour } 68325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 68335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 683443ec3f090ca979777b306abe7c25662b9429e06dChris Forbesstatic bool setQueryState(VkQueue queue, VkCommandBuffer commandBuffer, QueryObject object, bool value) { 683556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 68369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 6837d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine if (pCB) { 6838d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine pCB->queryToStateMap[object] = value; 6839d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 6840d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine auto queue_data = dev_data->queueMap.find(queue); 6841d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine if (queue_data != dev_data->queueMap.end()) { 6842d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine queue_data->second.queryToStateMap[object] = value; 6843d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 6844d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine return false; 6845d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine} 6846d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine 6847bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot, VkFlags flags) { 68483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 684956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6850ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 68519a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 68525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 68533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdBeginQuery()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6854315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17802415); 68553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_BEGINQUERY, "vkCmdBeginQuery()"); 685643ec3f090ca979777b306abe7c25662b9429e06dChris Forbes } 685743ec3f090ca979777b306abe7c25662b9429e06dChris Forbes lock.unlock(); 685843ec3f090ca979777b306abe7c25662b9429e06dChris Forbes 685943ec3f090ca979777b306abe7c25662b9429e06dChris Forbes if (skip) return; 686043ec3f090ca979777b306abe7c25662b9429e06dChris Forbes 686143ec3f090ca979777b306abe7c25662b9429e06dChris Forbes dev_data->dispatch_table.CmdBeginQuery(commandBuffer, queryPool, slot, flags); 686243ec3f090ca979777b306abe7c25662b9429e06dChris Forbes 686343ec3f090ca979777b306abe7c25662b9429e06dChris Forbes lock.lock(); 686443ec3f090ca979777b306abe7c25662b9429e06dChris Forbes if (pCB) { 686543ec3f090ca979777b306abe7c25662b9429e06dChris Forbes QueryObject query = {queryPool, slot}; 686643ec3f090ca979777b306abe7c25662b9429e06dChris Forbes pCB->activeQueries.insert(query); 686743ec3f090ca979777b306abe7c25662b9429e06dChris Forbes pCB->startedQueries.insert(query); 68689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 68699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, pCB); 68705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 68715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 68725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 687389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) { 6874946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 687556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6876ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6877e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes QueryObject query = {queryPool, slot}; 6878946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 6879946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 6880946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!cb_state->activeQueries.count(query)) { 6881df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 6882315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1ae00652, "DS", 68839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Ending a query before it was started: queryPool 0x%" PRIx64 ", index %d. %s", 6884315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(queryPool), slot, validation_error_map[VALIDATION_ERROR_1ae00652]); 68855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 6886baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "VkCmdEndQuery()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6887315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1ae02415); 6888946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_ENDQUERY, "VkCmdEndQuery()"); 6889e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes } 6890e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes lock.unlock(); 6891e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes 6892e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes if (skip) return; 6893e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes 6894e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes dev_data->dispatch_table.CmdEndQuery(commandBuffer, queryPool, slot); 6895e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes 6896e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes lock.lock(); 6897e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes if (cb_state) { 6898e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes cb_state->activeQueries.erase(query); 6899e17228238940d38a82570bc5b0ed4dd44e4cbd6dChris Forbes cb_state->queryUpdates.emplace_back([=](VkQueue q){return setQueryState(q, commandBuffer, query, true);}); 69009a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 69019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, cb_state); 69025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 69035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 69045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 6905bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, 6906bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t queryCount) { 6907946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 690856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6909ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6910946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 69113a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes skip |= insideRenderPass(dev_data, cb_state, "vkCmdResetQueryPool()", VALIDATION_ERROR_1c600017); 69123a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes skip |= ValidateCmd(dev_data, cb_state, CMD_RESETQUERYPOOL, "VkCmdResetQueryPool()"); 6913baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "VkCmdResetQueryPool()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 6914315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1c602415); 6915b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 69163a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes 69173a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes if (skip) return; 69183a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes 69193a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes dev_data->dispatch_table.CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount); 69203a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes 69213a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes lock.lock(); 69223a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes for (uint32_t i = 0; i < queryCount; i++) { 69233a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes QueryObject query = {queryPool, firstQuery + i}; 69243a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes cb_state->waitedEventsBeforeQueryReset[query] = cb_state->waitedEvents; 6925f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes cb_state->queryUpdates.emplace_back([=](VkQueue q){return setQueryState(q, commandBuffer, query, false);}); 69263a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes } 69273a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 69283a4c679ed508b10fd119bb97c127c79b5d126d74Chris Forbes {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, cb_state); 69295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 69305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 69317ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbesstatic bool IsQueryInvalid(layer_data *dev_data, QUEUE_STATE *queue_data, VkQueryPool queryPool, uint32_t queryIndex) { 69327ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes QueryObject query = {queryPool, queryIndex}; 69337ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes auto query_data = queue_data->queryToStateMap.find(query); 69347ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (query_data != queue_data->queryToStateMap.end()) { 69357ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (!query_data->second) return true; 69367ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes } else { 69377ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes auto it = dev_data->queryToStateMap.find(query); 69387ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (it == dev_data->queryToStateMap.end() || !it->second) 69397ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes return true; 69407ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes } 69417ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes 69427ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes return false; 69437ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes} 69447ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes 69457ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbesstatic bool validateQuery(VkQueue queue, GLOBAL_CB_NODE *pCB, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) { 69463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 694756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(pCB->commandBuffer), layer_data_map); 69487ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes auto queue_data = GetQueueState(dev_data, queue); 69497ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (!queue_data) return false; 6950d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine for (uint32_t i = 0; i < queryCount; i++) { 69517ffbe89a37f5f822858a35646be0213fd2cd2b08Chris Forbes if (IsQueryInvalid(dev_data, queue_data, queryPool, firstQuery + i)) { 69523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 69539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUERY, "DS", 69543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requesting a copy from query to buffer with invalid query: queryPool 0x%" PRIx64 ", index %d", 69559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(queryPool), firstQuery + i); 6956d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 6957d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine } 69583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 6959d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine} 6960d78749ee260a3ce7244cbfd97c11aacc2250f8d3Michael Lentine 6961bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, 6962bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, 6963bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDeviceSize stride, VkQueryResultFlags flags) { 6964946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 696556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 6966ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 6967ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis 69689a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_node = GetCBNode(dev_data, commandBuffer); 69699a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto dst_buff_state = GetBufferState(dev_data, dstBuffer); 69705cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis if (cb_node && dst_buff_state) { 6971315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_state, "vkCmdCopyQueryPoolResults()", VALIDATION_ERROR_19400674); 6972ebc92c86f5a63df6ab4d325f83d385b23c11bf5eTobin Ehlis // Validate that DST buffer has correct usage flags set 6973315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 6974315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateBufferUsageFlags(dev_data, dst_buff_state, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true, VALIDATION_ERROR_19400672, 6975315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdCopyQueryPoolResults()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT"); 69764d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdCopyQueryPoolResults()", 69774d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_19402415); 69784d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes skip |= ValidateCmd(dev_data, cb_node, CMD_COPYQUERYPOOLRESULTS, "vkCmdCopyQueryPoolResults()"); 69794d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes skip |= insideRenderPass(dev_data, cb_node, "vkCmdCopyQueryPoolResults()", VALIDATION_ERROR_19400017); 69804d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes } 69814d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes lock.unlock(); 69824d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes 69834d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes if (skip) return; 69844d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes 69854d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes dev_data->dispatch_table.CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, 69864d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes stride, flags); 69874d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes 69884d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes lock.lock(); 69894d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes if (cb_node && dst_buff_state) { 69904d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes AddCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_state); 69914d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes cb_node->validate_functions.emplace_back([=]() { 69925cca7b0a90e0b6fe1cc28ddbe9037c3ce3f3ee13Tobin Ehlis SetBufferMemoryValid(dev_data, dst_buff_state, true); 6993e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 69944d285deca53ab503c0c9eb65ba1c4fb711138d7cChris Forbes }); 6995f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes cb_node->queryUpdates.emplace_back([=](VkQueue q) { 6996f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes return validateQuery(q, cb_node, queryPool, firstQuery, queryCount); 6997f49bd2b5f4c968a3033b3e5099bbbcff51201575Chris Forbes }); 69989a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis addCommandBufferBinding(&GetQueryPoolNode(dev_data, queryPool)->cb_bindings, 69999b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus {HandleToUint64(queryPool), kVulkanObjectTypeQueryPool}, cb_node); 70005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 70015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 70025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7003bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, 7004bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t offset, uint32_t size, const void *pValues) { 7005946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 700656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7007ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7008946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 7009946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 7010baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdPushConstants()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7011315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1bc02415); 7012946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_PUSHCONSTANTS, "vkCmdPushConstants()"); 70135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7014946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= validatePushConstantRange(dev_data, offset, size, "vkCmdPushConstants()"); 70159e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz if (0 == stageFlags) { 7016df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7017315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1bc2dc03, "DS", 7018315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdPushConstants() call has no stageFlags set. %s", validation_error_map[VALIDATION_ERROR_1bc2dc03]); 70199e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 70209e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz 7021bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // Check if specified push constant range falls within a pipeline-defined range which has matching stageFlags. 7022bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // The spec doesn't seem to disallow having multiple push constant ranges with the 7023bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // same offset and size, but different stageFlags. So we can't just check the 7024bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz // stageFlags in the first range with matching offset and size. 7025bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if (!skip) { 7026bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz const auto &ranges = getPipelineLayout(dev_data, layout)->push_constant_ranges; 7027bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz bool found_matching_range = false; 7028bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz for (const auto &range : ranges) { 7029bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if ((stageFlags == range.stageFlags) && (offset >= range.offset) && (offset + size <= range.offset + range.size)) { 7030bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz found_matching_range = true; 703115a574466ede280b595c451ad52f2b7b18f20b2dTobin Ehlis break; 7032a95cb74c9d0947ab3821b15e1289755286ea78eeKarl Schultz } 70339e24d8153ab63bc3ac08b5a1517c203930b5de91Karl Schultz } 7034bf0fa2ad7830118e59f0fb8ff88efae18a72e833Karl Schultz if (!found_matching_range) { 7035315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7036315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1bc002de, "DS", 7037315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "vkCmdPushConstants() stageFlags = 0x%" PRIx32 7038315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis " do not match the stageFlags in any of the ranges with" 7039315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis " offset = %d and size = %d in pipeline layout 0x%" PRIx64 ". %s", 7040315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis (uint32_t)stageFlags, offset, size, HandleToUint64(layout), 7041315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1bc002de]); 704215a574466ede280b595c451ad52f2b7b18f20b2dTobin Ehlis } 70435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7044b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 7045946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues); 70465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 70475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7048bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, 7049bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkQueryPool queryPool, uint32_t slot) { 7050946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 705156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7052ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 7053946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski GLOBAL_CB_NODE *cb_state = GetCBNode(dev_data, commandBuffer); 7054946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski if (cb_state) { 7055baa50ccc5a8cf7a6f7474148f301802c5480e715Mike Schuchardt skip |= ValidateCmdQueueFlags(dev_data, cb_state, "vkCmdWriteTimestamp()", VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 7056315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1e802415); 7057946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski skip |= ValidateCmd(dev_data, cb_state, CMD_WRITETIMESTAMP, "vkCmdWriteTimestamp()"); 70585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7059b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 70606eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes 70616eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes if (skip) return; 70626eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes 70636eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes dev_data->dispatch_table.CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot); 70646eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes 70656eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes lock.lock(); 70666eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes if (cb_state) { 70676eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes QueryObject query = {queryPool, slot}; 70686eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes cb_state->queryUpdates.emplace_back([=](VkQueue q) {return setQueryState(q, commandBuffer, query, true);}); 70696eff586acc3c02decfb0c3af269693252efc8ef8Chris Forbes } 70705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 70715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 70726600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinskistatic bool MatchUsage(layer_data *dev_data, uint32_t count, const VkAttachmentReference *attachments, 70739bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt const VkFramebufferCreateInfo *fbci, VkImageUsageFlagBits usage_flag, 70749bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt UNIQUE_VALIDATION_ERROR_CODE error_code) { 7075946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski bool skip = false; 70766600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 70776600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski for (uint32_t attach = 0; attach < count; attach++) { 70786600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (attachments[attach].attachment != VK_ATTACHMENT_UNUSED) { 70796600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Attachment counts are verified elsewhere, but prevent an invalid access 70806600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (attachments[attach].attachment < fbci->attachmentCount) { 70816600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski const VkImageView *image_view = &fbci->pAttachments[attachments[attach].attachment]; 70829a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, *image_view); 708379fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (view_state) { 70849a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis const VkImageCreateInfo *ici = &GetImageState(dev_data, view_state->create_info.image)->createInfo; 70856600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (ici != nullptr) { 70866600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if ((ici->usage & usage_flag) == 0) { 7087df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 7088df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, error_code, "DS", 7089946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "vkCreateFramebuffer: Framebuffer Attachment (%d) conflicts with the image's " 7090946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski "IMAGE_USAGE flags (%s). %s", 7091946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski attachments[attach].attachment, string_VkImageUsageFlagBits(usage_flag), 7092946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski validation_error_map[error_code]); 70936600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 70946600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 70956600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 70966600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 70976600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 70986600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 7099946ddda6ec99e024f51a806278ba21c6779de88aMark Lobodzinski return skip; 71006600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski} 71016600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 7102d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis// Validate VkFramebufferCreateInfo which includes: 7103d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis// 1. attachmentCount equals renderPass attachmentCount 71045ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 2. corresponding framebuffer and renderpass attachments have matching formats 71055ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 3. corresponding framebuffer and renderpass attachments have matching sample counts 71065ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 4. fb attachments only have a single mip level 71075ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 5. fb attachment dimensions are each at least as large as the fb 71085ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 6. fb attachments use idenity swizzle 71095ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis// 7. fb attachments used by renderPass for color/input/ds have correct usage bit set 71106fb721e0f21c85d4457561d17c196280601cebc1Tobin Ehlis// 8. fb dimensions are within physical device limits 7111d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlisstatic bool ValidateFramebufferCreateInfo(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) { 71123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 71136600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 71149a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto rp_state = GetRenderPassState(dev_data, pCreateInfo->renderPass); 7115127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis if (rp_state) { 7116127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis const VkRenderPassCreateInfo *rpci = rp_state->createInfo.ptr(); 7117d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis if (rpci->attachmentCount != pCreateInfo->attachmentCount) { 71183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 7119d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7120315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), __LINE__, VALIDATION_ERROR_094006d8, "DS", 7121d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis "vkCreateFramebuffer(): VkFramebufferCreateInfo attachmentCount of %u does not match attachmentCount of %u of " 71229bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "renderPass (0x%" PRIxLEAST64 ") being used to create Framebuffer. %s", 71239b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pCreateInfo->attachmentCount, rpci->attachmentCount, HandleToUint64(pCreateInfo->renderPass), 7124315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006d8]); 71255ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } else { 712641ebcb6b517b1de5ae456d46d866f5e84a96a2c5Tobin Ehlis // attachmentCounts match, so make sure corresponding attachment details line up 71275ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis const VkImageView *image_views = pCreateInfo->pAttachments; 71285ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 71299a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, image_views[i]); 713012d5600c2f9e32343016fd944432ba95df370797Tobin Ehlis auto &ivci = view_state->create_info; 713179fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (ivci.format != rpci->pAttachments[i].format) { 71323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 71335ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7134315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), __LINE__, VALIDATION_ERROR_094006e0, "DS", 71359bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has format of %s that does not match " 71369bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "the format of " 71379bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "%s used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 "). %s", 713879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis i, string_VkFormat(ivci.format), string_VkFormat(rpci->pAttachments[i].format), 7139315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), validation_error_map[VALIDATION_ERROR_094006e0]); 71405ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 71419a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis const VkImageCreateInfo *ici = &GetImageState(dev_data, ivci.image)->createInfo; 71425ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis if (ici->samples != rpci->pAttachments[i].samples) { 71433251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 714441ebcb6b517b1de5ae456d46d866f5e84a96a2c5Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7145315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), __LINE__, VALIDATION_ERROR_094006e2, "DS", 71469bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has %s samples that do not match " 71479bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "the %s samples used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 "). %s", 714841ebcb6b517b1de5ae456d46d866f5e84a96a2c5Tobin Ehlis i, string_VkSampleCountFlagBits(ici->samples), string_VkSampleCountFlagBits(rpci->pAttachments[i].samples), 7149315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCreateInfo->renderPass), validation_error_map[VALIDATION_ERROR_094006e2]); 71505ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 71515ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis // Verify that view only has a single mip level 715279fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (ivci.subresourceRange.levelCount != 1) { 71533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7154315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_094006e6, "DS", 71553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has mip levelCount of %u " 71563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "but only a single mip level (levelCount == 1) is allowed when creating a Framebuffer. %s", 7157315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, ivci.subresourceRange.levelCount, validation_error_map[VALIDATION_ERROR_094006e6]); 71585ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 715979fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis const uint32_t mip_level = ivci.subresourceRange.baseMipLevel; 7160aac6fea2aeb81a0d354d80a9226bdc5de2aef5e2Tobin Ehlis uint32_t mip_width = max(1u, ici->extent.width >> mip_level); 7161aac6fea2aeb81a0d354d80a9226bdc5de2aef5e2Tobin Ehlis uint32_t mip_height = max(1u, ici->extent.height >> mip_level); 716279fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if ((ivci.subresourceRange.layerCount < pCreateInfo->layers) || (mip_width < pCreateInfo->width) || 7163aac6fea2aeb81a0d354d80a9226bdc5de2aef5e2Tobin Ehlis (mip_height < pCreateInfo->height)) { 71642c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton skip |= log_msg( 71652c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7166315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006e4, "DS", 71672c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u mip level %u has dimensions smaller " 71682c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "than the corresponding framebuffer dimensions. Here are the respective dimensions for attachment #%u, " 71692c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "framebuffer:\n" 71702c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "width: %u, %u\n" 71712c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "height: %u, %u\n" 71722c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton "layerCount: %u, %u\n%s", 71732c911c34092d685a7fa4630028f6fcf4bf80e349Cort Stratton i, ivci.subresourceRange.baseMipLevel, i, mip_width, pCreateInfo->width, mip_height, pCreateInfo->height, 7174315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ivci.subresourceRange.layerCount, pCreateInfo->layers, validation_error_map[VALIDATION_ERROR_094006e4]); 71755ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 717679fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (((ivci.components.r != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.r != VK_COMPONENT_SWIZZLE_R)) || 717779fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis ((ivci.components.g != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.g != VK_COMPONENT_SWIZZLE_G)) || 717879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis ((ivci.components.b != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.b != VK_COMPONENT_SWIZZLE_B)) || 717979fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis ((ivci.components.a != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.a != VK_COMPONENT_SWIZZLE_A))) { 71803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 71815b9ab1fb8720c30edfbe8dd974e2364425471ad5Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7182315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006e8, "DS", 7183da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has non-identy swizzle. All framebuffer " 7184da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "attachments must have been created with the identity swizzle. Here are the actual swizzle values:\n" 7185da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "r swizzle = %s\n" 7186da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "g swizzle = %s\n" 7187da5b8b1df2368168be93e563eccdb500d62b97a5Tobin Ehlis "b swizzle = %s\n" 71889bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "a swizzle = %s\n" 71899bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt "%s", 719079fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis i, string_VkComponentSwizzle(ivci.components.r), string_VkComponentSwizzle(ivci.components.g), 71919bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt string_VkComponentSwizzle(ivci.components.b), string_VkComponentSwizzle(ivci.components.a), 7192315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006e8]); 71935ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 71945ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis } 7195d73d9c5ffd42f300d3ec49f64910a2b370694186Tobin Ehlis } 71965ef4ed03801d1456b7c30dd59ea014be126df771Tobin Ehlis // Verify correct attachment usage flags 71976600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski for (uint32_t subpass = 0; subpass < rpci->subpassCount; subpass++) { 71986600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Verify input attachments: 71993251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 72009bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt MatchUsage(dev_data, rpci->pSubpasses[subpass].inputAttachmentCount, rpci->pSubpasses[subpass].pInputAttachments, 7201315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VALIDATION_ERROR_094006de); 72026600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Verify color attachments: 72033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 72049bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt MatchUsage(dev_data, rpci->pSubpasses[subpass].colorAttachmentCount, rpci->pSubpasses[subpass].pColorAttachments, 7205315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VALIDATION_ERROR_094006da); 72066600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski // Verify depth/stencil attachments: 72076600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski if (rpci->pSubpasses[subpass].pDepthStencilAttachment != nullptr) { 72083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= MatchUsage(dev_data, 1, rpci->pSubpasses[subpass].pDepthStencilAttachment, pCreateInfo, 7209315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VALIDATION_ERROR_094006dc); 72106600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 72116600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 72126600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski } 72136fb721e0f21c85d4457561d17c196280601cebc1Tobin Ehlis // Verify FB dimensions are within physical device limits 72149bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt if (pCreateInfo->width > dev_data->phys_dev_properties.properties.limits.maxFramebufferWidth) { 72153251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7216315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006ec, "DS", 72173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo width exceeds physical device limits. " 72183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requested width: %u, device max: %u\n" 72193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s", 72203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->width, dev_data->phys_dev_properties.properties.limits.maxFramebufferWidth, 7221315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006ec]); 72229bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt } 72239bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt if (pCreateInfo->height > dev_data->phys_dev_properties.properties.limits.maxFramebufferHeight) { 72243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7225315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006f0, "DS", 72263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo height exceeds physical device limits. " 72273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requested height: %u, device max: %u\n" 72283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s", 72293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->height, dev_data->phys_dev_properties.properties.limits.maxFramebufferHeight, 7230315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006f0]); 72319bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt } 72329bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt if (pCreateInfo->layers > dev_data->phys_dev_properties.properties.limits.maxFramebufferLayers) { 72333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7234315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006f4, "DS", 72353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo layers exceeds physical device limits. " 72363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Requested layers: %u, device max: %u\n" 72373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "%s", 72383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCreateInfo->layers, dev_data->phys_dev_properties.properties.limits.maxFramebufferLayers, 7239315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006f4]); 72406fb721e0f21c85d4457561d17c196280601cebc1Tobin Ehlis } 7241c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton // Verify FB dimensions are greater than zero 7242c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton if (pCreateInfo->width <= 0) { 7243c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7244315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006ea, "DS", 7245c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo width must be greater than zero. %s", 7246315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006ea]); 7247c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton } 7248c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton if (pCreateInfo->height <= 0) { 7249c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7250315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006ee, "DS", 7251c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo height must be greater than zero. %s", 7252315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006ee]); 7253c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton } 7254c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton if (pCreateInfo->layers <= 0) { 7255c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7256315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_094006f2, "DS", 7257c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton "vkCreateFramebuffer(): Requested VkFramebufferCreateInfo layers must be greater than zero. %s", 7258315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_094006f2]); 7259c70c914e514d6ee222af18505e6d4ce8387c3fa2Cort Stratton } 72603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 72616600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski} 72626600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 726364c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis// Validate VkFramebufferCreateInfo state prior to calling down chain to create Framebuffer object 726464c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis// Return true if an error is encountered and callback returns true to skip call down chain 726564c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis// false indicates that call down chain should proceed 726664c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlisstatic bool PreCallValidateCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) { 726764c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis // TODO : Verify that renderPass FB is created with is compatible with FB 72683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 72693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateFramebufferCreateInfo(dev_data, pCreateInfo); 72703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 727164c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis} 727264c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis 727354e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis// CreateFramebuffer state has been validated and call down chain completed so record new framebuffer object 727454e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlisstatic void PostCallRecordCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo, VkFramebuffer fb) { 727554e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis // Shadow create info and store in map 7276c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis std::unique_ptr<FRAMEBUFFER_STATE> fb_state( 7277c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis new FRAMEBUFFER_STATE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->createInfo.ptr())); 727876f04ca0e692f9f15d5ef7e0c658c24d11f34ebcTobin Ehlis 727954e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 728054e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis VkImageView view = pCreateInfo->pAttachments[i]; 72819a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state = GetImageViewState(dev_data, view); 728279fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (!view_state) { 728354e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis continue; 728454e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis } 728554e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis MT_FB_ATTACHMENT_INFO fb_info; 7286883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis fb_info.view_state = view_state; 728779fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis fb_info.image = view_state->create_info.image; 7288c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis fb_state->attachments.push_back(fb_info); 728954e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis } 7290c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis dev_data->frameBufferMap[fb] = std::move(fb_state); 729154e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis} 729254e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis 729389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo, 7294bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer) { 729556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 7296ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 72973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = PreCallValidateCreateFramebuffer(dev_data, pCreateInfo); 729864c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis lock.unlock(); 729964c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis 73003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 730164c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis 73024a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer); 73036600a7662f6dac6a8c8622a8305f02625439bf30Mark Lobodzinski 73045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 730564c259c2660d24b5b032f0cfa668de086dcd7eb4Tobin Ehlis lock.lock(); 730654e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis PostCallRecordCreateFramebuffer(dev_data, pCreateInfo, *pFramebuffer); 730754e0bb0ace13cc34255e0dc9ca6b0da2b4ac5be1Tobin Ehlis lock.unlock(); 73085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 73105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 73124e11bb1277f55311686a42000520791e1db1dd7bbungemanstatic bool FindDependency(const uint32_t index, const uint32_t dependent, const std::vector<DAGNode> &subpass_to_node, 7313e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves std::unordered_set<uint32_t> &processed_nodes) { 73145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If we have already checked this node we have not found a dependency path so return false. 7315cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (processed_nodes.count(index)) return false; 73165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis processed_nodes.insert(index); 73175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const DAGNode &node = subpass_to_node[index]; 73185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Look for a dependency path. If one exists return true else recurse on the previous nodes. 73194e11bb1277f55311686a42000520791e1db1dd7bbungeman if (std::find(node.prev.begin(), node.prev.end(), dependent) == node.prev.end()) { 73205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto elem : node.prev) { 7321cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (FindDependency(elem, dependent, subpass_to_node, processed_nodes)) return true; 73225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else { 7324e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return true; 73255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7326e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves return false; 73275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 73294e11bb1277f55311686a42000520791e1db1dd7bbungemanstatic bool CheckDependencyExists(const layer_data *dev_data, const uint32_t subpass, 73303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski const std::vector<uint32_t> &dependent_subpasses, const std::vector<DAGNode> &subpass_to_node, 73313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool &skip) { 7332e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool result = true; 73335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Loop through all subpasses that share the same attachment and make sure a dependency exists 73345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t k = 0; k < dependent_subpasses.size(); ++k) { 7335cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (static_cast<uint32_t>(subpass) == dependent_subpasses[k]) continue; 73365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const DAGNode &node = subpass_to_node[subpass]; 73375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Check for a specified dependency between the two nodes. If one exists we are done. 73385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto prev_elem = std::find(node.prev.begin(), node.prev.end(), dependent_subpasses[k]); 73395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto next_elem = std::find(node.next.begin(), node.next.end(), dependent_subpasses[k]); 73405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (prev_elem == node.prev.end() && next_elem == node.next.end()) { 73417655cb8b5eb52badee0b011729a05afa36316d69Jan-Harald Fredriksen // If no dependency exits an implicit dependency still might. If not, throw an error. 73425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::unordered_set<uint32_t> processed_nodes; 73437655cb8b5eb52badee0b011729a05afa36316d69Jan-Harald Fredriksen if (!(FindDependency(subpass, dependent_subpasses[k], subpass_to_node, processed_nodes) || 7344bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski FindDependency(dependent_subpasses[k], subpass, subpass_to_node, processed_nodes))) { 73453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 73463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 73473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "A dependency between subpasses %d and %d must exist but one is not specified.", subpass, 73483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski dependent_subpasses[k]); 7349e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves result = false; 73505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73525b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 73545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 73568860b85a52096f9f9b28616bc37feed505497a54Chris Forbesstatic bool CheckPreserved(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, const int index, 73573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski const uint32_t attachment, const std::vector<DAGNode> &subpass_to_node, int depth, bool &skip) { 73585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const DAGNode &node = subpass_to_node[index]; 73595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If this node writes to the attachment return true as next nodes need to preserve the attachment. 73605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[index]; 73615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 7362cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == subpass.pColorAttachments[j].attachment) return true; 73635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7364a4ea781e8fff70c9db0bedad7fcb6bba08e35da7Tony Barbour for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 7365a4ea781e8fff70c9db0bedad7fcb6bba08e35da7Tony Barbour if (attachment == subpass.pInputAttachments[j].attachment) return true; 7366a4ea781e8fff70c9db0bedad7fcb6bba08e35da7Tony Barbour } 73675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 7368cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == subpass.pDepthStencilAttachment->attachment) return true; 73695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7370e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool result = false; 73715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Loop through previous nodes and see if any of them write to the attachment. 73725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto elem : node.prev) { 73733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski result |= CheckPreserved(dev_data, pCreateInfo, elem, attachment, subpass_to_node, depth + 1, skip); 73745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If the attachment was written to by a previous node than this node needs to preserve it. 73765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result && depth > 0) { 7377e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves bool has_preserved = false; 73785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) { 73795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pPreserveAttachments[j] == attachment) { 7380e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves has_preserved = true; 73815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis break; 73825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7384e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves if (!has_preserved) { 73853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 73863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 73873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attachment %d is used by a later subpass and must be preserved in subpass %d.", attachment, index); 73885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 73905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 73915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7393cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskitemplate <class T> 7394cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskibool isRangeOverlapping(T offset1, T size1, T offset2, T size2) { 73955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return (((offset1 + size1) > offset2) && ((offset1 + size1) < (offset2 + size2))) || 73965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ((offset1 > offset2) && (offset1 < (offset2 + size2))); 73975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 73985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 73995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlisbool isRegionOverlapping(VkImageSubresourceRange range1, VkImageSubresourceRange range2) { 74005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return (isRangeOverlapping(range1.baseMipLevel, range1.levelCount, range2.baseMipLevel, range2.levelCount) && 74015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis isRangeOverlapping(range1.baseArrayLayer, range1.layerCount, range2.baseArrayLayer, range2.layerCount)); 74025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 74035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 7404c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlisstatic bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE const *framebuffer, 7405127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis RENDER_PASS_STATE const *renderPass) { 74063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 7407fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto const pFramebufferInfo = framebuffer->createInfo.ptr(); 7408fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto const pCreateInfo = renderPass->createInfo.ptr(); 7409bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto const &subpass_to_node = renderPass->subpassToNode; 74105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<std::vector<uint32_t>> output_attachment_to_subpass(pCreateInfo->attachmentCount); 74115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<std::vector<uint32_t>> input_attachment_to_subpass(pCreateInfo->attachmentCount); 74125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis std::vector<std::vector<uint32_t>> overlapping_attachments(pCreateInfo->attachmentCount); 74135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Find overlapping attachments 74145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) { 74155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = i + 1; j < pCreateInfo->attachmentCount; ++j) { 74165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkImageView viewi = pFramebufferInfo->pAttachments[i]; 74175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkImageView viewj = pFramebufferInfo->pAttachments[j]; 74185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (viewi == viewj) { 74195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[i].push_back(j); 74205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[j].push_back(i); 74215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 74225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74239a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state_i = GetImageViewState(dev_data, viewi); 74249a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto view_state_j = GetImageViewState(dev_data, viewj); 742579fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (!view_state_i || !view_state_j) { 74265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 74275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 742879fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis auto view_ci_i = view_state_i->create_info; 742979fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis auto view_ci_j = view_state_j->create_info; 743079fde938178535f598e030a0e9d19a0cb61b72e0Tobin Ehlis if (view_ci_i.image == view_ci_j.image && isRegionOverlapping(view_ci_i.subresourceRange, view_ci_j.subresourceRange)) { 74315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[i].push_back(j); 74325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[j].push_back(i); 74335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 74345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74359a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_data_i = GetImageState(dev_data, view_ci_i.image); 74369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_data_j = GetImageState(dev_data, view_ci_j.image); 74376d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis if (!image_data_i || !image_data_j) { 74385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis continue; 74395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7440e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis if (image_data_i->binding.mem == image_data_j->binding.mem && 7441e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis isRangeOverlapping(image_data_i->binding.offset, image_data_i->binding.size, image_data_j->binding.offset, 7442e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis image_data_j->binding.size)) { 74435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[i].push_back(j); 74445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis overlapping_attachments[j].push_back(i); 74455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < overlapping_attachments.size(); ++i) { 74495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = i; 74505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto other_attachment : overlapping_attachments[i]) { 74515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pCreateInfo->pAttachments[attachment].flags & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT)) { 74529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, 7453315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(framebuffer->framebuffer), __LINE__, VALIDATION_ERROR_12200682, "DS", 74549b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attachment %d aliases attachment %d but doesn't " 74559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "set VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT. %s", 7456315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis attachment, other_attachment, validation_error_map[VALIDATION_ERROR_12200682]); 74575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pCreateInfo->pAttachments[other_attachment].flags & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT)) { 74599b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, 7460315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(framebuffer->framebuffer), __LINE__, VALIDATION_ERROR_12200682, "DS", 74619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Attachment %d aliases attachment %d but doesn't " 74629b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "set VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT. %s", 7463315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis other_attachment, attachment, validation_error_map[VALIDATION_ERROR_12200682]); 74645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Find for each attachment the subpasses that use them. 74681c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young unordered_set<uint32_t> attachmentIndices; 74695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 74705b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 74711c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young attachmentIndices.clear(); 74725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 74735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = subpass.pInputAttachments[j].attachment; 7474cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 74755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis input_attachment_to_subpass[attachment].push_back(i); 74765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto overlapping_attachment : overlapping_attachments[attachment]) { 74775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis input_attachment_to_subpass[overlapping_attachment].push_back(i); 74785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 74815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = subpass.pColorAttachments[j].attachment; 7482cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 74835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[attachment].push_back(i); 74845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto overlapping_attachment : overlapping_attachments[attachment]) { 74855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[overlapping_attachment].push_back(i); 74865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74871c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young attachmentIndices.insert(attachment); 74885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 74905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t attachment = subpass.pDepthStencilAttachment->attachment; 74915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[attachment].push_back(i); 74925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto overlapping_attachment : overlapping_attachments[attachment]) { 74935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis output_attachment_to_subpass[overlapping_attachment].push_back(i); 74945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 74951c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young 74961c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young if (attachmentIndices.count(attachment)) { 74973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 7498df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7499df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 75008860b85a52096f9f9b28616bc37feed505497a54Chris Forbes "Cannot use same attachment (%u) as both color and depth output in same subpass (%u).", attachment, i); 75011c1ee7bf64fb8cc2ba4b8661baa11dce24b3b23aMark Young } 75025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If there is a dependency needed make sure one exists 75055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 75065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 75075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If the attachment is an input then all subpasses that output must have a dependency relationship 75085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 750993fe72ec8460857bdb3c101095e6eb96d6171341Chris Forbes uint32_t attachment = subpass.pInputAttachments[j].attachment; 7510cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 75113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip); 75125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // If the attachment is an output then all subpasses that use the attachment must have a dependency relationship 75145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 751593fe72ec8460857bdb3c101095e6eb96d6171341Chris Forbes uint32_t attachment = subpass.pColorAttachments[j].attachment; 7516cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) continue; 75173251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip); 75183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip); 75195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 75215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const uint32_t &attachment = subpass.pDepthStencilAttachment->attachment; 75223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip); 75233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckDependencyExists(dev_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip); 75245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Loop through implicit dependencies, if this pass reads make sure the attachment is preserved for all passes after it was 75275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // written. 75285b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 75295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 75305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 75313251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski CheckPreserved(dev_data, pCreateInfo, i, subpass.pInputAttachments[j].attachment, subpass_to_node, 0, skip); 75325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 75355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 75365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 753732f68580aa01aab3e923cb52915a1d3dd4e993c5Chris Forbesstatic bool CreatePassDAG(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, 7538ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis std::vector<DAGNode> &subpass_to_node, std::vector<bool> &has_self_dependency, 7539ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis std::vector<int32_t> &subpass_to_dep_index) { 75403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 75415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 75425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis DAGNode &subpass_node = subpass_to_node[i]; 75435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis subpass_node.pass = i; 7544ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis subpass_to_dep_index[i] = -1; // Default to no dependency and overwrite below as needed 75455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { 75475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i]; 754866a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL || dependency.dstSubpass == VK_SUBPASS_EXTERNAL) { 754966a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes if (dependency.srcSubpass == dependency.dstSubpass) { 75503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 7551df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7552df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", "The src and dest subpasses cannot both be external."); 755366a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes } 755466a7318a24c9dd8162a6ae49fd62867a263d4402Chris Forbes } else if (dependency.srcSubpass > dependency.dstSubpass) { 75553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 75563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS", 7557ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis "Dependency graph must be specified such that an earlier pass cannot depend on a later pass."); 75585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } else if (dependency.srcSubpass == dependency.dstSubpass) { 75595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis has_self_dependency[dependency.srcSubpass] = true; 75605c6aacf95832467d52b2fde1130b04bef559573aChris Forbes } else { 75615c6aacf95832467d52b2fde1130b04bef559573aChris Forbes subpass_to_node[dependency.dstSubpass].prev.push_back(dependency.srcSubpass); 75625c6aacf95832467d52b2fde1130b04bef559573aChris Forbes subpass_to_node[dependency.srcSubpass].next.push_back(dependency.dstSubpass); 75635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7564ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis if (dependency.srcSubpass != VK_SUBPASS_EXTERNAL) { 7565ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis subpass_to_dep_index[dependency.srcSubpass] = i; 7566ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis } 75675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 75695b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 7570918c283ac4f8c604b79abd0c8b5706d2a7352a34Chris Forbes 757189d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo, 7572bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule) { 757356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 75747aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes bool spirv_valid; 7575b1f65702539fd041337fccd493dc6d38dd2a603eChris Forbes 75767aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes if (PreCallValidateCreateShaderModule(dev_data, pCreateInfo, &spirv_valid)) 75777aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 75785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 75794a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult res = dev_data->dispatch_table.CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule); 75805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 758159ae0ccadec962d9ca2cce7584fad6c57c1a4458Tobin Ehlis if (res == VK_SUCCESS) { 7582ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 75837aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes unique_ptr<shader_module> new_shader_module(spirv_valid ? new shader_module(pCreateInfo) : new shader_module()); 75847aec8a354c8de254cab09f6da7f24a794525d31eChris Forbes dev_data->shaderModuleMap[*pShaderModule] = std::move(new_shader_module); 75855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 75865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return res; 75875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 75885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 75894f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinskistatic bool ValidateAttachmentIndex(layer_data *dev_data, uint32_t attachment, uint32_t attachment_count, const char *type) { 75903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 75914f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (attachment >= attachment_count && attachment != VK_ATTACHMENT_UNUSED) { 75923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7593315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_12200684, "DS", 75943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: %s attachment %d must be less than the total number of attachments %d. %s", type, 7595315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis attachment, attachment_count, validation_error_map[VALIDATION_ERROR_12200684]); 75964f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 75973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 75984f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski} 75994f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 7600bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic bool IsPowerOfTwo(unsigned x) { return x && !(x & (x - 1)); } 7601805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 76024f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinskistatic bool ValidateRenderpassAttachmentUsage(layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo) { 76033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 76044f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 76054f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 76064f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (subpass.pipelineBindPoint != VK_PIPELINE_BIND_POINT_GRAPHICS) { 76073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7608315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_14000698, "DS", 76093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Pipeline bind point for subpass %d must be VK_PIPELINE_BIND_POINT_GRAPHICS. %s", i, 7610315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_14000698]); 76114f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7612ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 76134f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t j = 0; j < subpass.preserveAttachmentCount; ++j) { 76144f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment = subpass.pPreserveAttachments[j]; 76154f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (attachment == VK_ATTACHMENT_UNUSED) { 76163251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7617315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_140006aa, "DS", 76183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Preserve attachment (%d) must not be VK_ATTACHMENT_UNUSED. %s", j, 7619315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_140006aa]); 76204f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } else { 76213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Preserve"); 7622ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 7623ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton bool found = (subpass.pDepthStencilAttachment != NULL && subpass.pDepthStencilAttachment->attachment == attachment); 7624ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t r = 0; !found && r < subpass.inputAttachmentCount; ++r) { 7625ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton found = (subpass.pInputAttachments[r].attachment == attachment); 7626ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7627ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton for (uint32_t r = 0; !found && r < subpass.colorAttachmentCount; ++r) { 7628ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton found = (subpass.pColorAttachments[r].attachment == attachment) || 7629ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton (subpass.pResolveAttachments != NULL && subpass.pResolveAttachments[r].attachment == attachment); 7630ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7631ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (found) { 7632ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg( 7633ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7634315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_140006ac, "DS", 7635ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "CreateRenderPass: subpass %u pPreserveAttachments[%u] (%u) must not be used elsewhere in the subpass. %s", 7636315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, j, attachment, validation_error_map[VALIDATION_ERROR_140006ac]); 7637ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 76384f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 76394f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 76406a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 7641bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto subpass_performs_resolve = 7642bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski subpass.pResolveAttachments && 7643bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski std::any_of(subpass.pResolveAttachments, subpass.pResolveAttachments + subpass.colorAttachmentCount, 7644bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski [](VkAttachmentReference ref) { return ref.attachment != VK_ATTACHMENT_UNUSED; }); 76456a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 7646805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes unsigned sample_count = 0; 7647805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 76484f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 76494f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment; 76504f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (subpass.pResolveAttachments) { 76514f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski attachment = subpass.pResolveAttachments[j].attachment; 76523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Resolve"); 76536a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 76543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip && attachment != VK_ATTACHMENT_UNUSED && 76556a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes pCreateInfo->pAttachments[attachment].samples != VK_SAMPLE_COUNT_1_BIT) { 76563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7657315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_140006a2, "DS", 76583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Subpass %u requests multisample resolve into attachment %u, " 76593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which must have VK_SAMPLE_COUNT_1_BIT but has %s. %s", 76603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski i, attachment, string_VkSampleCountFlagBits(pCreateInfo->pAttachments[attachment].samples), 7661315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_140006a2]); 76626a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes } 7663ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 7664ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (!skip && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED && 7665ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton subpass.pColorAttachments[j].attachment == VK_ATTACHMENT_UNUSED) { 7666ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7667315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_1400069e, "DS", 7668ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "CreateRenderPass: Subpass %u requests multisample resolve from attachment %u " 7669ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton "which has attachment=VK_ATTACHMENT_UNUSED. %s", 7670315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, attachment, validation_error_map[VALIDATION_ERROR_1400069e]); 7671ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 76724f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 76734f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski attachment = subpass.pColorAttachments[j].attachment; 76743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Color"); 76756a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes 76763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip && attachment != VK_ATTACHMENT_UNUSED) { 7677805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples; 7678805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 7679bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (subpass_performs_resolve && pCreateInfo->pAttachments[attachment].samples == VK_SAMPLE_COUNT_1_BIT) { 76803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7681315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_140006a0, "DS", 76823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Subpass %u requests multisample resolve from attachment %u " 76833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which has VK_SAMPLE_COUNT_1_BIT. %s", 7684315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, attachment, validation_error_map[VALIDATION_ERROR_140006a0]); 7685dc7c45f01ae5690f7c969b4760463c1a6bac52d5Chris Forbes } 7686ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton 7687ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (subpass_performs_resolve && subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED) { 7688ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton const auto &color_desc = pCreateInfo->pAttachments[attachment]; 7689ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton const auto &resolve_desc = pCreateInfo->pAttachments[subpass.pResolveAttachments[j].attachment]; 7690ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton if (color_desc.format != resolve_desc.format) { 7691315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 7692315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 7693315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis 0, __LINE__, VALIDATION_ERROR_140006a4, "DS", 7694315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "CreateRenderPass: Subpass %u pColorAttachments[%u] resolves to an attachment with a " 7695315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "different format. " 7696315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "color format: %u, resolve format: %u. %s", 7697315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, j, color_desc.format, resolve_desc.format, validation_error_map[VALIDATION_ERROR_140006a4]); 7698ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 7699ce7bf009f8fc7e268efdc76ba61e3491d290ebd9Cort Stratton } 77006a3bc5f071fe21799f0f7ae844716c333f11f39cChris Forbes } 77014f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7702dc7c45f01ae5690f7c969b4760463c1a6bac52d5Chris Forbes 77034f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 77044f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment = subpass.pDepthStencilAttachment->attachment; 77053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Depth stencil"); 7706805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 77073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip && attachment != VK_ATTACHMENT_UNUSED) { 7708805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes sample_count |= (unsigned)pCreateInfo->pAttachments[attachment].samples; 7709805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes } 77104f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7711dc7c45f01ae5690f7c969b4760463c1a6bac52d5Chris Forbes 77124f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 77134f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski uint32_t attachment = subpass.pInputAttachments[j].attachment; 77143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateAttachmentIndex(dev_data, attachment, pCreateInfo->attachmentCount, "Input"); 77154f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 7716805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes 7717805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes if (sample_count && !IsPowerOfTwo(sample_count)) { 77183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, 7719315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis __LINE__, VALIDATION_ERROR_0082b401, "DS", 77203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "CreateRenderPass: Subpass %u attempts to render to " 77213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "attachments with inconsistent sample counts. %s", 7722315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis i, validation_error_map[VALIDATION_ERROR_0082b401]); 7723805ec497391f6bc513f7653ba6d535c509b54062Chris Forbes } 77244f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 77253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 77264f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski} 77274f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 77285245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbesstatic void MarkAttachmentFirstUse(RENDER_PASS_STATE *render_pass, 77295245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes uint32_t index, 77305245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes bool is_read) { 77315245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (index == VK_ATTACHMENT_UNUSED) 77325245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes return; 77335245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes 77345245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (!render_pass->attachment_first_read.count(index)) 77355245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes render_pass->attachment_first_read[index] = is_read; 77365245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes} 77375245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes 773889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, 77394f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) { 77403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 774156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 77424f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 7743ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 77444f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski // TODO: As part of wrapping up the mem_tracker/core_validation merge the following routine should be consolidated with 77454f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski // ValidateLayouts. 77463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateRenderpassAttachmentUsage(dev_data, pCreateInfo); 7747208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) { 77483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateStageMaskGsTsEnables(dev_data, pCreateInfo->pDependencies[i].srcStageMask, "vkCreateRenderPass()", 7749315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_13e006b8, VALIDATION_ERROR_13e006bc); 77503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateStageMaskGsTsEnables(dev_data, pCreateInfo->pDependencies[i].dstStageMask, "vkCreateRenderPass()", 7751315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_13e006ba, VALIDATION_ERROR_13e006be); 7752208aecf4cb59762be429488d7d4484f138c2cd81Tobin Ehlis } 77533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 77543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateLayouts(dev_data, device, pCreateInfo); 7755ab38df28c5ae1816c5fa33c0c7840c6950e83f0dChris Forbes } 7756ff6101de02d1677fb54962e2ff57875e76898e26Chris Forbes lock.unlock(); 77574f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 77583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 77594f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski return VK_ERROR_VALIDATION_FAILED_EXT; 77604f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski } 77614f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 77624a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass); 7763ff6101de02d1677fb54962e2ff57875e76898e26Chris Forbes 77645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 77654f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski lock.lock(); 77664f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 77674f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski std::vector<bool> has_self_dependency(pCreateInfo->subpassCount); 77684f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount); 7769ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis std::vector<int32_t> subpass_to_dep_index(pCreateInfo->subpassCount); 7770ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis skip |= CreatePassDAG(dev_data, pCreateInfo, subpass_to_node, has_self_dependency, subpass_to_dep_index); 77714f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 7772127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis auto render_pass = unique_ptr<RENDER_PASS_STATE>(new RENDER_PASS_STATE(pCreateInfo)); 777398cddf7090b5d5dcc382045867753ef703d1c3d3Chris Forbes render_pass->renderPass = *pRenderPass; 7774cf2686cdbb12af8a29ca598c126b5e37215f0ef7Chris Forbes render_pass->hasSelfDependency = has_self_dependency; 7775cf2686cdbb12af8a29ca598c126b5e37215f0ef7Chris Forbes render_pass->subpassToNode = subpass_to_node; 7776ea0a13226a513846fe5a7009783c5536b1255a56Tobin Ehlis render_pass->subpass_to_dependency_index = subpass_to_dep_index; 7777db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes 777887e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) { 777987e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i]; 778087e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) { 77815245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pColorAttachments[j].attachment, false); 77829cde292b1c19c643b7c13018d9834cccfe6ef7eaChris Forbes 77835245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes // resolve attachments are considered to be written 77845245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (subpass.pResolveAttachments) { 77855245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pResolveAttachments[j].attachment, false); 77869cde292b1c19c643b7c13018d9834cccfe6ef7eaChris Forbes } 778787e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis } 77885245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes if (subpass.pDepthStencilAttachment) { 77895245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pDepthStencilAttachment->attachment, false); 779087e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis } 7791a5ce96d7c88653668a2b33a6b72bd3cb16d73f48Michael Lentine for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) { 77925245a74f239ad662d9ca3675789ad41f37424ce6Chris Forbes MarkAttachmentFirstUse(render_pass.get(), subpass.pInputAttachments[j].attachment, true); 7793a5ce96d7c88653668a2b33a6b72bd3cb16d73f48Michael Lentine } 779487e0afcd98dcf3c1e5e2cbb3023fe89d9dd10cd2Tobin Ehlis } 7795db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes 7796fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes dev_data->renderPassMap[*pRenderPass] = std::move(render_pass); 77975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 77985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 77995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 78004f76794409854faf16dd51f37d5fa21dff1c5d44Mark Lobodzinski 7801eb4c61477130f69f48fdf3ac31cb82104181cc73Chris Forbesstatic bool validatePrimaryCommandBuffer(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, char const *cmd_name, 78029bd94c6fc216a1d67d5e98542519002fa56d19dbMike Schuchardt UNIQUE_VALIDATION_ERROR_CODE error_code) { 78033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 78045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) { 78053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 78069b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, error_code, "DS", 78079b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Cannot execute command %s on a secondary command buffer. %s", cmd_name, validation_error_map[error_code]); 78085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78093251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 78105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 78115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 78128860b85a52096f9f9b28616bc37feed505497a54Chris Forbesstatic bool VerifyRenderAreaBounds(const layer_data *dev_data, const VkRenderPassBeginInfo *pRenderPassBegin) { 78133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 7814c54e405a4ce05f4de10bb78bfc3a4769c41d2d59Tobin Ehlis const safe_VkFramebufferCreateInfo *pFramebufferInfo = 78159a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis &GetFramebufferState(dev_data, pRenderPassBegin->framebuffer)->createInfo; 7816885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine if (pRenderPassBegin->renderArea.offset.x < 0 || 7817885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine (pRenderPassBegin->renderArea.offset.x + pRenderPassBegin->renderArea.extent.width) > pFramebufferInfo->width || 7818885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine pRenderPassBegin->renderArea.offset.y < 0 || 7819885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine (pRenderPassBegin->renderArea.offset.y + pRenderPassBegin->renderArea.extent.height) > pFramebufferInfo->height) { 78203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= static_cast<bool>(log_msg( 7821df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, 7822885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine DRAWSTATE_INVALID_RENDER_AREA, "CORE", 7823885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine "Cannot execute a render pass with renderArea not within the bound of the " 7824885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine "framebuffer. RenderArea: x %d, y %d, width %d, height %d. Framebuffer: width %d, " 7825885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine "height %d.", 7826885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine pRenderPassBegin->renderArea.offset.x, pRenderPassBegin->renderArea.offset.y, pRenderPassBegin->renderArea.extent.width, 7827885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine pRenderPassBegin->renderArea.extent.height, pFramebufferInfo->width, pFramebufferInfo->height)); 7828885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine } 78293251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 7830885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine} 7831885537d813d6fb3d199e76f6d63b6d3f78d0eeb0Michael Lentine 78321a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski// If this is a stencil format, make sure the stencil[Load|Store]Op flag is checked, while if it is a depth/color attachment the 78331a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski// [load|store]Op flag must be checked 78341a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski// TODO: The memory valid flag in DEVICE_MEM_INFO should probably be split to track the validity of stencil memory separately. 7835cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskitemplate <typename T> 7836cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinskistatic bool FormatSpecificLoadAndStoreOpSettings(VkFormat format, T color_depth_op, T stencil_op, T op) { 7837a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski if (color_depth_op != op && stencil_op != op) { 7838a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski return false; 7839a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski } 784016769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton bool check_color_depth_load_op = !FormatIsStencilOnly(format); 784116769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton bool check_stencil_load_op = FormatIsDepthAndStencil(format) || !check_color_depth_load_op; 7842a49b8a211ce07e7fa2225d23f8cb11f1055b418aMark Lobodzinski 78430d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes return ((check_color_depth_load_op && (color_depth_op == op)) || 78440d9453d85335963d6cabfbf400b058dc905ea238Chris Forbes (check_stencil_load_op && (stencil_op == op))); 78451a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski} 78461a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski 7847bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdBeginRenderPass(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, 7848bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkSubpassContents contents) { 78493251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 785056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7851ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 78529a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *cb_node = GetCBNode(dev_data, commandBuffer); 78539a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto render_pass_state = pRenderPassBegin ? GetRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr; 78549a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto framebuffer = pRenderPassBegin ? GetFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr; 7855f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis if (cb_node) { 7856308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski if (render_pass_state) { 7857cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR 7858f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeFramebuffer = pRenderPassBegin->framebuffer; 7859308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski for (uint32_t i = 0; i < render_pass_state->createInfo.attachmentCount; ++i) { 7860f40ab6d10b8d755ce0e461c33916b0d4d5a5d437Chris Forbes MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i]; 7861308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski auto pAttachment = &render_pass_state->createInfo.pAttachments[i]; 7862bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, pAttachment->stencilLoadOp, 78631a65650f856376768d7b03ea2d080aaff87cacfdMark Lobodzinski VK_ATTACHMENT_LOAD_OP_CLEAR)) { 786492bc0680357019834b7529148ab6d73353ce02c7Mark Lobodzinski clear_op_size = static_cast<uint32_t>(i) + 1; 786516387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 78669a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true); 786716387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes return false; 786816387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 7869f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->validate_functions.push_back(function); 7870db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, 7871bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_DONT_CARE)) { 787216387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 78739a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false); 787416387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes return false; 787516387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 7876f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->validate_functions.push_back(function); 7877db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp, 7878bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pAttachment->stencilLoadOp, VK_ATTACHMENT_LOAD_OP_LOAD)) { 787916387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 78809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), 7881f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis "vkCmdBeginRenderPass()"); 788216387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 7883f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->validate_functions.push_back(function); 788416387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes } 7885308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski if (render_pass_state->attachment_first_read[i]) { 788616387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes std::function<bool()> function = [=]() { 78879a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis return ValidateImageMemoryIsValid(dev_data, GetImageState(dev_data, fb_info.image), 7888f989de4217bce0f293121d0da53dc8328276370fTobin Ehlis "vkCmdBeginRenderPass()"); 788916387282d11e414ae7cb9ddf3d0c1bebf8f2c74dChris Forbes }; 7890f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->validate_functions.push_back(function); 78915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 78936de3c6ffa0819ee37cd5cecee918b062145e2ff1Tobin Ehlis if (clear_op_size > pRenderPassBegin->clearValueCount) { 78943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 7895369cf6deef1fca74f9eb1f8ef6e96deba715b133Slawomir Cygan dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, 7896315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(render_pass_state->renderPass), __LINE__, VALIDATION_ERROR_1200070c, "DS", 7897bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must " 7898bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "be at least %u entries in pClearValues array to account for the highest index attachment in renderPass " 7899cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "0x%" PRIx64 7900cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array " 7901bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to " 7902bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "attachments that aren't cleared they will be ignored. %s", 79039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pRenderPassBegin->clearValueCount, clear_op_size, HandleToUint64(render_pass_state->renderPass), clear_op_size, 7904315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis clear_op_size - 1, validation_error_map[VALIDATION_ERROR_1200070c]); 7905369cf6deef1fca74f9eb1f8ef6e96deba715b133Slawomir Cygan } 79063251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin); 79073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin, 79083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski GetFramebufferState(dev_data, pRenderPassBegin->framebuffer)); 7909315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= insideRenderPass(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00017); 79103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateDependencies(dev_data, framebuffer, render_pass_state); 7911315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, cb_node, "vkCmdBeginRenderPass()", VALIDATION_ERROR_17a00019); 7912315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, cb_node, "vkCmdBeginRenderPass()", VK_QUEUE_GRAPHICS_BIT, 7913315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_17a02415); 79143251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, cb_node, CMD_BEGINRENDERPASS, "vkCmdBeginRenderPass()"); 7915308153fd68fc050a302201fb5a7cca53de8dc866Mark Lobodzinski cb_node->activeRenderPass = render_pass_state; 79165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // This is a shallow copy as that is all that is needed for now 7917f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeRenderPassBeginInfo = *pRenderPassBegin; 7918f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeSubpass = 0; 7919f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->activeSubpassContents = contents; 7920f909505280723ee24d2e74afc759d38dc09a37beTobin Ehlis cb_node->framebuffers.insert(pRenderPassBegin->framebuffer); 7921883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis // Connect this framebuffer and its children to this cmdBuffer 7922883ee3f865f9dbd83134d148b26e96cb6a926b3dTobin Ehlis AddFramebufferBinding(dev_data, cb_node, framebuffer); 79235f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis // transition attachments to the correct layouts for beginning of renderPass and first subpass 79245f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis TransitionBeginRenderPassLayouts(dev_data, cb_node, render_pass_state, framebuffer); 79255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 79265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7927b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 79283251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 79294a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents); 79305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 79315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 79325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 793389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) { 79343251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 793556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7936ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 79379a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 79385b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 7939315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdNextSubpass()", VALIDATION_ERROR_1b600019); 7940315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdNextSubpass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1b602415); 79413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()"); 7942315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass()", VALIDATION_ERROR_1b600017); 794380281691386b37385846f21b38e8c9d4b12cc74eChris Forbes 7944fb13c2c4174108223d9f8e43084020eb09115ed6Chris Forbes auto subpassCount = pCB->activeRenderPass->createInfo.subpassCount; 794580281691386b37385846f21b38e8c9d4b12cc74eChris Forbes if (pCB->activeSubpass == subpassCount - 1) { 79463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 7947315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(commandBuffer), __LINE__, VALIDATION_ERROR_1b60071a, "DS", 79483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdNextSubpass(): Attempted to advance beyond final subpass. %s", 7949315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b60071a]); 795080281691386b37385846f21b38e8c9d4b12cc74eChris Forbes } 79515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 7952b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 795396ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes 79543251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return; 795596ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes 79564a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdNextSubpass(commandBuffer, contents); 795796ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes 795896ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes if (pCB) { 7959bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski lock.lock(); 7960bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pCB->activeSubpass++; 7961bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pCB->activeSubpassContents = contents; 79625f025a7d647e3257e12a816fa1db078b5fc8ed49Tobin Ehlis TransitionSubpassLayouts(dev_data, pCB, pCB->activeRenderPass, pCB->activeSubpass, 79639a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GetFramebufferState(dev_data, pCB->activeRenderPassBeginInfo.framebuffer)); 796496ebb1e373cc0993339e2ecc1dc47e9918406f87Chris Forbes } 79655b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 79665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 796789d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL CmdEndRenderPass(VkCommandBuffer commandBuffer) { 79683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 796956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 7970ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 79719a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pCB = GetCBNode(dev_data, commandBuffer); 797255867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski FRAMEBUFFER_STATE *framebuffer = NULL; 797358c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes if (pCB) { 7974127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis RENDER_PASS_STATE *rp_state = pCB->activeRenderPass; 79759a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis framebuffer = GetFramebufferState(dev_data, pCB->activeFramebuffer); 7976127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis if (rp_state) { 7977127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis if (pCB->activeSubpass != rp_state->createInfo.subpassCount - 1) { 79783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 79799b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer), __LINE__, 7980315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b00071c, "DS", "vkCmdEndRenderPass(): Called before reaching final subpass. %s", 7981315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b00071c]); 798202a3382f28fc7c6ec6018165be88aa6fc4f05c9eChris Forbes } 798302a3382f28fc7c6ec6018165be88aa6fc4f05c9eChris Forbes 7984127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis for (size_t i = 0; i < rp_state->createInfo.attachmentCount; ++i) { 7985e3ad4b1284408353cc56a04951c1df1f35a636ceChris Forbes MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i]; 7986127937bcdb5817ee4568887c298ce36c88f3c58bTobin Ehlis auto pAttachment = &rp_state->createInfo.pAttachments[i]; 7987bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp, pAttachment->stencilStoreOp, 7988bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VK_ATTACHMENT_STORE_OP_STORE)) { 798958c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes std::function<bool()> function = [=]() { 79909a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), true); 799158c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes return false; 799258c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes }; 799358c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->validate_functions.push_back(function); 7994db6ad16f7690669bb664b970a8e5c47abb8db9faChris Forbes } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp, 7995bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pAttachment->stencilStoreOp, VK_ATTACHMENT_STORE_OP_DONT_CARE)) { 799658c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes std::function<bool()> function = [=]() { 79979a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis SetImageMemoryValid(dev_data, GetImageState(dev_data, fb_info.image), false); 799858c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes return false; 799958c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes }; 800058c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->validate_functions.push_back(function); 80015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8004315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= outsideRenderPass(dev_data, pCB, "vkCmdEndRenderpass()", VALIDATION_ERROR_1b000017); 8005315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdEndRenderPass()", VALIDATION_ERROR_1b000019); 8006315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidateCmdQueueFlags(dev_data, pCB, "vkCmdEndRenderPass()", VK_QUEUE_GRAPHICS_BIT, VALIDATION_ERROR_1b002415); 80073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateCmd(dev_data, pCB, CMD_ENDRENDERPASS, "vkCmdEndRenderPass()"); 80080e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes } 80090e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes lock.unlock(); 80100e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes 80113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return; 80120e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes 80134a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.CmdEndRenderPass(commandBuffer); 80140e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes 80150e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes if (pCB) { 80160e21dda98453b5ced1fe7a2ffd5ca4b21847fe09Chris Forbes lock.lock(); 801755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski TransitionFinalSubpassLayouts(dev_data, pCB, &pCB->activeRenderPassBeginInfo, framebuffer); 801858c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->activeRenderPass = nullptr; 801958c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->activeSubpass = 0; 802058c3d40b47b6b30c1e7c508ec14ee67fcd238c93Chris Forbes pCB->activeFramebuffer = VK_NULL_HANDLE; 80215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 80235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8024a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlisstatic bool logInvalidAttachmentMessage(layer_data *dev_data, VkCommandBuffer secondaryBuffer, uint32_t primaryAttach, 8025a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis uint32_t secondaryAttach, const char *msg) { 8026df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8027315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(secondaryBuffer), __LINE__, VALIDATION_ERROR_1b2000c4, "DS", 8028df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "vkCmdExecuteCommands() called w/ invalid Secondary Cmd Buffer 0x%" PRIx64 8029df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski " which has a render pass " 8030df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "that is not compatible with the Primary Cmd Buffer current render pass. " 8031df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "Attachment %u is not compatible with %u: %s. %s", 80329b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(secondaryBuffer), primaryAttach, secondaryAttach, msg, 8033315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b2000c4]); 80345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 80355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8036a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlisstatic bool validateAttachmentCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer, 8037a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis VkRenderPassCreateInfo const *primaryPassCI, uint32_t primaryAttach, 8038a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis VkCommandBuffer secondaryBuffer, VkRenderPassCreateInfo const *secondaryPassCI, 8039e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves uint32_t secondaryAttach, bool is_multi) { 80403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 8041a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (primaryPassCI->attachmentCount <= primaryAttach) { 80425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primaryAttach = VK_ATTACHMENT_UNUSED; 80435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8044a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (secondaryPassCI->attachmentCount <= secondaryAttach) { 80455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondaryAttach = VK_ATTACHMENT_UNUSED; 80465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (primaryAttach == VK_ATTACHMENT_UNUSED && secondaryAttach == VK_ATTACHMENT_UNUSED) { 80483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 80495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (primaryAttach == VK_ATTACHMENT_UNUSED) { 80513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, 80523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "The first is unused while the second is not."); 80533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 80545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (secondaryAttach == VK_ATTACHMENT_UNUSED) { 80563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, 80573251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "The second is unused while the first is not."); 80583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 80595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8060a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (primaryPassCI->pAttachments[primaryAttach].format != secondaryPassCI->pAttachments[secondaryAttach].format) { 80613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8062a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, "They have different formats."); 80635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8064a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (primaryPassCI->pAttachments[primaryAttach].samples != secondaryPassCI->pAttachments[secondaryAttach].samples) { 80653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8066a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, "They have different samples."); 80675b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8068a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (is_multi && primaryPassCI->pAttachments[primaryAttach].flags != secondaryPassCI->pAttachments[secondaryAttach].flags) { 80693251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8070a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis logInvalidAttachmentMessage(dev_data, secondaryBuffer, primaryAttach, secondaryAttach, "They have different flags."); 80715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80723251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 80735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 80745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8075a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlisstatic bool validateSubpassCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer, 8076a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis VkRenderPassCreateInfo const *primaryPassCI, VkCommandBuffer secondaryBuffer, 8077a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis VkRenderPassCreateInfo const *secondaryPassCI, const int subpass, bool is_multi) { 80783251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 8079a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis const VkSubpassDescription &primary_desc = primaryPassCI->pSubpasses[subpass]; 8080a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis const VkSubpassDescription &secondary_desc = secondaryPassCI->pSubpasses[subpass]; 80815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t maxInputAttachmentCount = std::max(primary_desc.inputAttachmentCount, secondary_desc.inputAttachmentCount); 80825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < maxInputAttachmentCount; ++i) { 80835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t primary_input_attach = VK_ATTACHMENT_UNUSED, secondary_input_attach = VK_ATTACHMENT_UNUSED; 80845b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (i < primary_desc.inputAttachmentCount) { 80855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primary_input_attach = primary_desc.pInputAttachments[i].attachment; 80865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (i < secondary_desc.inputAttachmentCount) { 80885b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondary_input_attach = secondary_desc.pInputAttachments[i].attachment; 80895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_input_attach, secondaryBuffer, 80913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski secondaryPassCI, secondary_input_attach, is_multi); 80925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t maxColorAttachmentCount = std::max(primary_desc.colorAttachmentCount, secondary_desc.colorAttachmentCount); 80945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < maxColorAttachmentCount; ++i) { 80955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t primary_color_attach = VK_ATTACHMENT_UNUSED, secondary_color_attach = VK_ATTACHMENT_UNUSED; 80965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (i < primary_desc.colorAttachmentCount) { 80975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primary_color_attach = primary_desc.pColorAttachments[i].attachment; 80985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 80995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (i < secondary_desc.colorAttachmentCount) { 81005b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondary_color_attach = secondary_desc.pColorAttachments[i].attachment; 81015b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_color_attach, secondaryBuffer, 81033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski secondaryPassCI, secondary_color_attach, is_multi); 81045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t primary_resolve_attach = VK_ATTACHMENT_UNUSED, secondary_resolve_attach = VK_ATTACHMENT_UNUSED; 81055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (i < primary_desc.colorAttachmentCount && primary_desc.pResolveAttachments) { 81065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primary_resolve_attach = primary_desc.pResolveAttachments[i].attachment; 81075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (i < secondary_desc.colorAttachmentCount && secondary_desc.pResolveAttachments) { 81095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondary_resolve_attach = secondary_desc.pResolveAttachments[i].attachment; 81105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81113251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_resolve_attach, secondaryBuffer, 81123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski secondaryPassCI, secondary_resolve_attach, is_multi); 81135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis uint32_t primary_depthstencil_attach = VK_ATTACHMENT_UNUSED, secondary_depthstencil_attach = VK_ATTACHMENT_UNUSED; 81155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (primary_desc.pDepthStencilAttachment) { 81165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis primary_depthstencil_attach = primary_desc.pDepthStencilAttachment[0].attachment; 81175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (secondary_desc.pDepthStencilAttachment) { 81195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis secondary_depthstencil_attach = secondary_desc.pDepthStencilAttachment[0].attachment; 81205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81213251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateAttachmentCompatibility(dev_data, primaryBuffer, primaryPassCI, primary_depthstencil_attach, secondaryBuffer, 81223251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski secondaryPassCI, secondary_depthstencil_attach, is_multi); 81233251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 81245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 81255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8126a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis// Verify that given renderPass CreateInfo for primary and secondary command buffers are compatible. 8127a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis// This function deals directly with the CreateInfo, there are overloaded versions below that can take the renderPass handle and 8128a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis// will then feed into this function 8129a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlisstatic bool validateRenderPassCompatibility(layer_data *dev_data, VkCommandBuffer primaryBuffer, 8130a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis VkRenderPassCreateInfo const *primaryPassCI, VkCommandBuffer secondaryBuffer, 8131a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis VkRenderPassCreateInfo const *secondaryPassCI) { 81323251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 8133a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis 8134a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (primaryPassCI->subpassCount != secondaryPassCI->subpassCount) { 81353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 81369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(primaryBuffer), __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", 81373251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() called w/ invalid secondary Cmd Buffer 0x%" PRIx64 81383251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that has a subpassCount of %u that is incompatible with the primary Cmd Buffer 0x%" PRIx64 81393251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that has a subpassCount of %u.", 81409b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(secondaryBuffer), secondaryPassCI->subpassCount, HandleToUint64(primaryBuffer), 81419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus primaryPassCI->subpassCount); 8142a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis } else { 8143a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis for (uint32_t i = 0; i < primaryPassCI->subpassCount; ++i) { 81443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateSubpassCompatibility(dev_data, primaryBuffer, primaryPassCI, secondaryBuffer, secondaryPassCI, i, 81453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski primaryPassCI->subpassCount > 1); 8146a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis } 81475b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 81495b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 81505b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8151e3319189d6f8e3126522df7a5935d2c42f656291Dustin Gravesstatic bool validateFramebuffer(layer_data *dev_data, VkCommandBuffer primaryBuffer, const GLOBAL_CB_NODE *pCB, 8152e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves VkCommandBuffer secondaryBuffer, const GLOBAL_CB_NODE *pSubCB) { 81533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 81545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!pSubCB->beginInfo.pInheritanceInfo) { 81553251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 81565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8157c5b97dda856ff837638b3ebb7e231d5507c495a3Chris Forbes VkFramebuffer primary_fb = pCB->activeFramebuffer; 81585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkFramebuffer secondary_fb = pSubCB->beginInfo.pInheritanceInfo->framebuffer; 81595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (secondary_fb != VK_NULL_HANDLE) { 81605b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (primary_fb != secondary_fb) { 81613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8162315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(primaryBuffer), __LINE__, VALIDATION_ERROR_1b2000c6, "DS", 81633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() called w/ invalid secondary command buffer 0x%" PRIx64 81643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " which has a framebuffer 0x%" PRIx64 81653251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that is not the same as the primary command buffer's current active framebuffer 0x%" PRIx64 ". %s", 81669b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(secondaryBuffer), HandleToUint64(secondary_fb), HandleToUint64(primary_fb), 8167315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b2000c6]); 81685b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81699a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto fb = GetFramebufferState(dev_data, secondary_fb); 8170e3ad4b1284408353cc56a04951c1df1f35a636ceChris Forbes if (!fb) { 81713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 81729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(primaryBuffer), __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", 81733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p " 81743251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "which has invalid framebuffer 0x%" PRIx64 ".", 81759b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus (void *)secondaryBuffer, HandleToUint64(secondary_fb)); 81763251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 81775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81789a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto cb_renderpass = GetRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass); 8179a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis if (cb_renderpass->renderPass != fb->createInfo.renderPass) { 81803251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateRenderPassCompatibility(dev_data, secondaryBuffer, fb->renderPassCreateInfo.ptr(), secondaryBuffer, 81813251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski cb_renderpass->createInfo.ptr()); 8182a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis } 81835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 81843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 81855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 81865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8187e3319189d6f8e3126522df7a5935d2c42f656291Dustin Gravesstatic bool validateSecondaryCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB, GLOBAL_CB_NODE *pSubCB) { 81883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 81895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis unordered_set<int> activeTypes; 81905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto queryObject : pCB->activeQueries) { 81915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto queryPoolData = dev_data->queryPoolMap.find(queryObject.pool); 81925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (queryPoolData != dev_data->queryPoolMap.end()) { 81935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (queryPoolData->second.createInfo.queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS && 81945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pSubCB->beginInfo.pInheritanceInfo) { 81955b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkQueryPipelineStatisticFlags cmdBufStatistics = pSubCB->beginInfo.pInheritanceInfo->pipelineStatistics; 81965b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if ((cmdBufStatistics & queryPoolData->second.createInfo.pipelineStatistics) != cmdBufStatistics) { 81979b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 81989b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8199315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCB->commandBuffer), __LINE__, VALIDATION_ERROR_1b2000d0, "DS", 82009b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p " 82019b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "which has invalid active query pool 0x%" PRIx64 82029b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus ". Pipeline statistics is being queried so the command " 82039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "buffer must have all bits set on the queryPool. %s", 8204315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCB->commandBuffer, HandleToUint64(queryPoolData->first), validation_error_map[VALIDATION_ERROR_1b2000d0]); 82055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis activeTypes.insert(queryPoolData->second.createInfo.queryType); 82085b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82095b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto queryObject : pSubCB->startedQueries) { 82115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto queryPoolData = dev_data->queryPoolMap.find(queryObject.pool); 82125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (queryPoolData != dev_data->queryPoolMap.end() && activeTypes.count(queryPoolData->second.createInfo.queryType)) { 82139b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 82149b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_SECONDARY_COMMAND_BUFFER, "DS", 82159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkCmdExecuteCommands() called w/ invalid Cmd Buffer 0x%p " 82169b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "which has invalid active query pool 0x%" PRIx64 82179b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "of type %d but a query of that type has been started on " 82189b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "secondary Cmd Buffer 0x%p.", 82199b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pCB->commandBuffer, HandleToUint64(queryPoolData->first), queryPoolData->second.createInfo.queryType, 82209b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pSubCB->commandBuffer); 82215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82237bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 82249a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto primary_pool = GetCommandPoolNode(dev_data, pCB->createInfo.commandPool); 82259a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto secondary_pool = GetCommandPoolNode(dev_data, pSubCB->createInfo.commandPool); 82267bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski if (primary_pool && secondary_pool && (primary_pool->queueFamilyIndex != secondary_pool->queueFamilyIndex)) { 82273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8228226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 82299b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pSubCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_QUEUE_FAMILY, "DS", 8230226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "vkCmdExecuteCommands(): Primary command buffer 0x%p" 8231226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis " created in queue family %d has secondary command buffer 0x%p created in queue family %d.", 8232226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis pCB->commandBuffer, primary_pool->queueFamilyIndex, pSubCB->commandBuffer, secondary_pool->queueFamilyIndex); 82337bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski } 82347bd96b29f4b8df99339ff1f7bc64f2f8940f8d25Mark Lobodzinski 82353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski return skip; 82365b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 82375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8238bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBuffersCount, 8239bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkCommandBuffer *pCommandBuffers) { 82403251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 824156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 8242ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 82439a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis GLOBAL_CB_NODE *pCB = GetCBNode(dev_data, commandBuffer); 82445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB) { 82455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis GLOBAL_CB_NODE *pSubCB = NULL; 82465b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < commandBuffersCount; i++) { 82479a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis pSubCB = GetCBNode(dev_data, pCommandBuffers[i]); 82480a8b955c23012196339f3c10ffedc631ea0f7c58Tobin Ehlis assert(pSubCB); 82490a8b955c23012196339f3c10ffedc631ea0f7c58Tobin Ehlis if (VK_COMMAND_BUFFER_LEVEL_PRIMARY == pSubCB->createInfo.level) { 82503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8251df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8252315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_1b2000b0, "DS", 8253df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "vkCmdExecuteCommands() called w/ Primary Cmd Buffer 0x%p in element %u of pCommandBuffers " 8254df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski "array. All cmd buffers in pCommandBuffers array must be secondary. %s", 8255315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCommandBuffers[i], i, validation_error_map[VALIDATION_ERROR_1b2000b0]); 8256cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else if (pCB->activeRenderPass) { // Secondary CB w/i RenderPass must have *CONTINUE_BIT set 82570de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if (pSubCB->beginInfo.pInheritanceInfo != nullptr) { 82580de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski auto secondary_rp_state = GetRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass); 82590de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { 82600de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= log_msg( 82610de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8262315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_1b2000c0, "DS", 82630de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) executed within render pass (0x%" PRIxLEAST64 82640de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski ") must have had vkBeginCommandBuffer() called w/ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT " 82650de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "set. %s", 82660de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski pCommandBuffers[i], HandleToUint64(pCB->activeRenderPass->renderPass), 8267315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_1b2000c0]); 82680de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski } else { 82690de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski // Make sure render pass is compatible with parent command buffer pass if has continue 82700de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if (pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) { 82710de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= 82720de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->createInfo.ptr(), 82733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski pCommandBuffers[i], secondary_rp_state->createInfo.ptr()); 82740de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski } 82750de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski // If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB 82760de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB); 8277f384f33742c2b72888372332747298d08135ac92Tobin Ehlis if (VK_NULL_HANDLE == pSubCB->activeFramebuffer) { 827879fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis // Inherit primary's activeFramebuffer and while running validate functions 827979fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis for (auto &function : pSubCB->cmd_execute_commands_functions) { 828079fc00370d55e7cbfd4052b579120e64b0a1a4beTobin Ehlis skip |= function(pCB->activeFramebuffer); 8281f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 8282f384f33742c2b72888372332747298d08135ac92Tobin Ehlis } 82830de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski } 82840de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski string errorString = ""; 82850de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski // secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass 82860de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski if ((pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) && 82870de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(), 82880de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski secondary_rp_state->createInfo.ptr(), errorString)) { 82890de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski skip |= log_msg( 82900de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 82910de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski HandleToUint64(pCommandBuffers[i]), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS", 82920de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) w/ render pass (0x%" PRIxLEAST64 82930de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski ") is incompatible w/ primary command buffer (0x%p) w/ render pass (0x%" PRIxLEAST64 ") due to: %s", 82940de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski pCommandBuffers[i], HandleToUint64(pSubCB->beginInfo.pInheritanceInfo->renderPass), commandBuffer, 82950de5f3bbf5218c9bc92c5bb09c8547bd26adcabcMark Lobodzinski HandleToUint64(pCB->activeRenderPass->renderPass), errorString.c_str()); 8296a092085c225bbc24edb29cd34ca6b30889f7e111Tobin Ehlis } 82975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 82995b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // TODO(mlentine): Move more logic into this method 83003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= validateSecondaryCommandBufferState(dev_data, pCB, pSubCB); 8301315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validateCommandBufferState(dev_data, pSubCB, "vkCmdExecuteCommands()", 0, VALIDATION_ERROR_1b2000b2); 83025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) { 83039b2582dc67737351a72fbeb82e9e6e8cdff7a026Chris Forbes if (pSubCB->in_use.load() || pCB->linkedCommandBuffers.count(pSubCB)) { 83043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, 83059b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(pCB->commandBuffer), __LINE__, 8306315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1b2000b4, "DS", 83073251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Attempt to simultaneously execute command buffer 0x%p" 83083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set! %s", 8309315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCB->commandBuffer, validation_error_map[VALIDATION_ERROR_1b2000b4]); 83105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) { 83125b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Warn that non-simultaneous secondary cmd buffer renders primary non-simultaneous 83133251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 83145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 83159b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCommandBuffers[i]), __LINE__, DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS", 8316226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "vkCmdExecuteCommands(): Secondary Command Buffer (0x%p) " 8317226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and will cause primary command buffer " 8318226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis "(0x%p) to be treated as if it does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT " 831983b40cb743b7d87753e7503b148fef660ca45289Tobin Ehlis "set, even though it does.", 8320226a75bff897619b86cc227cf1196b5e245fb96dTobin Ehlis pCommandBuffers[i], pCB->commandBuffer); 83215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pCB->beginInfo.flags &= ~VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; 83225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8324f71dd305f197826a61f398bff725267a20ea1d90Chris Forbes if (!pCB->activeQueries.empty() && !dev_data->enabled_features.inheritedQueries) { 83253251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 8326cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 8327315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pCommandBuffers[i]), __LINE__, VALIDATION_ERROR_1b2000ca, "DS", 8328cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkCmdExecuteCommands(): Secondary Command Buffer " 8329cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "(0x%p) cannot be submitted with a query in " 8330cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "flight and inherited queries not " 8331cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "supported on this device. %s", 8332315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCommandBuffers[i], validation_error_map[VALIDATION_ERROR_1b2000ca]); 83335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83349b2582dc67737351a72fbeb82e9e6e8cdff7a026Chris Forbes // TODO: separate validate from update! This is very tangled. 83358567fecbf563420f5900ade277ca68908aa87259Tobin Ehlis // Propagate layout transitions to the primary cmd buffer 83368567fecbf563420f5900ade277ca68908aa87259Tobin Ehlis for (auto ilm_entry : pSubCB->imageLayoutMap) { 833755867dbad6ae423b3bd78c15f6771031a710b5adMark Lobodzinski SetLayout(dev_data, pCB, ilm_entry.first, ilm_entry.second); 83388567fecbf563420f5900ade277ca68908aa87259Tobin Ehlis } 83395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis pSubCB->primaryCommandBuffer = pCB->commandBuffer; 83401a3660584634742a3297915c94768d73f360e794Chris Forbes pCB->linkedCommandBuffers.insert(pSubCB); 83411a3660584634742a3297915c94768d73f360e794Chris Forbes pSubCB->linkedCommandBuffers.insert(pCB); 8342d4ee9fdb2def1e9dc70c5627c9103e264471b8ebMichael Lentine for (auto &function : pSubCB->queryUpdates) { 8343d4ee9fdb2def1e9dc70c5627c9103e264471b8ebMichael Lentine pCB->queryUpdates.push_back(function); 8344d4ee9fdb2def1e9dc70c5627c9103e264471b8ebMichael Lentine } 83455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8346315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= validatePrimaryCommandBuffer(dev_data, pCB, "vkCmdExecuteCommands()", VALIDATION_ERROR_1b200019); 8347315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 8348315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ValidateCmdQueueFlags(dev_data, pCB, "vkCmdExecuteCommands()", 8349315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, VALIDATION_ERROR_1b202415); 8350f5a52627a6576d3d532cd1f2e1be6d9987aeda7fChris Forbes skip |= ValidateCmd(dev_data, pCB, CMD_EXECUTECOMMANDS, "vkCmdExecuteCommands()"); 83515b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8352b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 83533251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers); 83545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 83555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8356bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkFlags flags, 8357bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski void **ppData) { 835856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 83595b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 83603251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 83615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 8362ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 83639a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis DEVICE_MEM_INFO *mem_info = GetMemObjInfo(dev_data, mem); 8364cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis if (mem_info) { 8365f541bf53dee6daf82a4c8304354eac599a884d29Tobin Ehlis // TODO : This could me more fine-grained to track just region that is valid 8366f541bf53dee6daf82a4c8304354eac599a884d29Tobin Ehlis mem_info->global_valid = true; 8367623548a271287ae55415e45e3c654ee66d4e79ffTobin Ehlis auto end_offset = (VK_WHOLE_SIZE == size) ? mem_info->alloc_info.allocationSize - 1 : offset + size - 1; 83683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateMapImageLayouts(dev_data, device, mem_info, offset, end_offset); 8369cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis // TODO : Do we need to create new "bound_range" for the mapped range? 8370623548a271287ae55415e45e3c654ee66d4e79ffTobin Ehlis SetMemRangesValid(dev_data, mem_info, offset, end_offset); 8371cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis if ((dev_data->phys_dev_mem_props.memoryTypes[mem_info->alloc_info.memoryTypeIndex].propertyFlags & 8372b1b606d27e8c4179534d7bbb48ce217429e37414Tobin Ehlis VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) { 83733251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8374315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), __LINE__, VALIDATION_ERROR_31200554, "MEM", 83753251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Mapping Memory without VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set: mem obj 0x%" PRIxLEAST64 ". %s", 8376315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem), validation_error_map[VALIDATION_ERROR_31200554]); 83775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateMapMemRange(dev_data, mem, offset, size); 8380b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 83815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 83823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 83834a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.MapMemory(device, mem, offset, size, flags, ppData); 83847c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis if (VK_SUCCESS == result) { 83857c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis lock.lock(); 8386cf17f50f6489504c0d8151c46d6f77404ce2ffffTobin Ehlis // TODO : What's the point of this range? See comment on creating new "bound_range" above, which may replace this 83877c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis storeMemRanges(dev_data, mem, offset, size); 83885f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski initializeAndTrackMemory(dev_data, mem, offset, size, ppData); 83897c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis lock.unlock(); 83907c0012acb5327961b0a5191434a08e5fa788786dTobin Ehlis } 83915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 83925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 83935b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 83945b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 839589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory mem) { 839656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 83973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 83985b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8399ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 84003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= deleteMemRanges(dev_data, mem); 8401b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 84023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 84034a0754042cf090e131e9e769d8a3633c228625beChris Forbes dev_data->dispatch_table.UnmapMemory(device, mem); 84045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 84065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 84078860b85a52096f9f9b28616bc37feed505497a54Chris Forbesstatic bool validateMemoryIsMapped(layer_data *dev_data, const char *funcName, uint32_t memRangeCount, 8408e3319189d6f8e3126522df7a5935d2c42f656291Dustin Graves const VkMappedMemoryRange *pMemRanges) { 8409c7ee6f2fe100c1aacfaa0872832717c906bb8a4aMark Lobodzinski bool skip = false; 84105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (uint32_t i = 0; i < memRangeCount; ++i) { 84119a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, pMemRanges[i].memory); 841257fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 8413f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski if (pMemRanges[i].size == VK_WHOLE_SIZE) { 8414f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski if (mem_info->mem_range.offset > pMemRanges[i].offset) { 8415315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= 8416315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8417315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pMemRanges[i].memory), __LINE__, VALIDATION_ERROR_0c20055c, "MEM", 8418315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "%s: Flush/Invalidate offset (" PRINTF_SIZE_T_SPECIFIER 8419315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis ") is less than Memory Object's offset " 8420315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis "(" PRINTF_SIZE_T_SPECIFIER "). %s", 8421315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis funcName, static_cast<size_t>(pMemRanges[i].offset), 8422315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis static_cast<size_t>(mem_info->mem_range.offset), validation_error_map[VALIDATION_ERROR_0c20055c]); 8423f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski } 8424f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski } else { 8425f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski const uint64_t data_end = (mem_info->mem_range.size == VK_WHOLE_SIZE) 8426f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski ? mem_info->alloc_info.allocationSize 8427f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski : (mem_info->mem_range.offset + mem_info->mem_range.size); 8428f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski if ((mem_info->mem_range.offset > pMemRanges[i].offset) || 8429f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski (data_end < (pMemRanges[i].offset + pMemRanges[i].size))) { 8430c7ee6f2fe100c1aacfaa0872832717c906bb8a4aMark Lobodzinski skip |= 8431f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8432315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pMemRanges[i].memory), __LINE__, VALIDATION_ERROR_0c20055a, "MEM", 8433f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski "%s: Flush/Invalidate size or offset (" PRINTF_SIZE_T_SPECIFIER ", " PRINTF_SIZE_T_SPECIFIER 8434f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski ") exceed the Memory Object's upper-bound " 8435f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski "(" PRINTF_SIZE_T_SPECIFIER "). %s", 8436f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski funcName, static_cast<size_t>(pMemRanges[i].offset + pMemRanges[i].size), 8437f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski static_cast<size_t>(pMemRanges[i].offset), static_cast<size_t>(data_end), 8438315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_0c20055a]); 8439f0b0053ba47c1fc2ee173cfef0eaf63356cd4b0cMark Lobodzinski } 84405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8443c7ee6f2fe100c1aacfaa0872832717c906bb8a4aMark Lobodzinski return skip; 84445b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 84455b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8446bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinskistatic bool ValidateAndCopyNoncoherentMemoryToDriver(layer_data *dev_data, uint32_t mem_range_count, 8447bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 8448bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski bool skip = false; 8449bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski for (uint32_t i = 0; i < mem_range_count; ++i) { 84509a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem_ranges[i].memory); 845157fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 84525f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski if (mem_info->shadow_copy) { 84535f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski VkDeviceSize size = (mem_info->mem_range.size != VK_WHOLE_SIZE) 84545f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski ? mem_info->mem_range.size 8455d8a53ade6b5501256798a8b4ec0bc14f72adc1faTobin Ehlis : (mem_info->alloc_info.allocationSize - mem_info->mem_range.offset); 84565f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski char *data = static_cast<char *>(mem_info->shadow_copy); 84575f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski for (uint64_t j = 0; j < mem_info->shadow_pad_size; ++j) { 84585b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (data[j] != NoncoherentMemoryFillValue) { 84599b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 84609b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 84619b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_ranges[i].memory), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 84629b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Memory underflow was detected on mem obj 0x%" PRIxLEAST64, HandleToUint64(mem_ranges[i].memory)); 84635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84655f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski for (uint64_t j = (size + mem_info->shadow_pad_size); j < (2 * mem_info->shadow_pad_size + size); ++j) { 84665b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (data[j] != NoncoherentMemoryFillValue) { 84679b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 84689b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 84699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(mem_ranges[i].memory), __LINE__, MEMTRACK_INVALID_MAP, "MEM", 84709b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Memory overflow was detected on mem obj 0x%" PRIxLEAST64, HandleToUint64(mem_ranges[i].memory)); 84715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84725b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84735f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski memcpy(mem_info->p_driver_data, static_cast<void *>(data + mem_info->shadow_pad_size), (size_t)(size)); 84745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84755b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 84765b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 8477bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski return skip; 84785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 84795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8480bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinskistatic void CopyNoncoherentMemoryFromDriver(layer_data *dev_data, uint32_t mem_range_count, const VkMappedMemoryRange *mem_ranges) { 8481bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski for (uint32_t i = 0; i < mem_range_count; ++i) { 84829a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem_ranges[i].memory); 84835f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski if (mem_info && mem_info->shadow_copy) { 84845f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski VkDeviceSize size = (mem_info->mem_range.size != VK_WHOLE_SIZE) 84855f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski ? mem_info->mem_range.size 84865f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski : (mem_info->alloc_info.allocationSize - mem_ranges[i].offset); 84875f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski char *data = static_cast<char *>(mem_info->shadow_copy); 84885f06b9eba1bf89d4066ca44120dcb72c4cf44104Mark Lobodzinski memcpy(data + mem_info->shadow_pad_size, mem_info->p_driver_data, (size_t)(size)); 84899e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski } 84909e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski } 84919e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski} 84929e21e56fc23ade48efd3752d2e2729895eb90349Mark Lobodzinski 8493ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinskistatic bool ValidateMappedMemoryRangeDeviceLimits(layer_data *dev_data, const char *func_name, uint32_t mem_range_count, 8494ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 8495ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski bool skip = false; 8496ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski for (uint32_t i = 0; i < mem_range_count; ++i) { 8497ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski uint64_t atom_size = dev_data->phys_dev_properties.properties.limits.nonCoherentAtomSize; 849816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(mem_ranges[i].offset, atom_size) != 0) { 8499df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8500315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem_ranges->memory), __LINE__, VALIDATION_ERROR_0c20055e, "MEM", 8501ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski "%s: Offset in pMemRanges[%d] is 0x%" PRIxLEAST64 8502ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski ", which is not a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize (0x%" PRIxLEAST64 "). %s", 8503315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, i, mem_ranges[i].offset, atom_size, validation_error_map[VALIDATION_ERROR_0c20055e]); 8504ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski } 850516769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if ((mem_ranges[i].size != VK_WHOLE_SIZE) && (SafeModulo(mem_ranges[i].size, atom_size) != 0)) { 8506df7c947594a31bb74004ab2ca335ece9b60721b6Mark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 8507315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(mem_ranges->memory), __LINE__, VALIDATION_ERROR_0c200560, "MEM", 8508ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski "%s: Size in pMemRanges[%d] is 0x%" PRIxLEAST64 8509ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski ", which is not a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize (0x%" PRIxLEAST64 "). %s", 8510315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, i, mem_ranges[i].size, atom_size, validation_error_map[VALIDATION_ERROR_0c200560]); 8511ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski } 8512ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski } 8513ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski return skip; 8514ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski} 8515ba16c7616eb49c78dc76eb7682d650287ad8614dMark Lobodzinski 851680e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinskistatic bool PreCallValidateFlushMappedMemoryRanges(layer_data *dev_data, uint32_t mem_range_count, 851780e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 851880e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski bool skip = false; 8519ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 852080e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski skip |= ValidateAndCopyNoncoherentMemoryToDriver(dev_data, mem_range_count, mem_ranges); 852180e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski skip |= validateMemoryIsMapped(dev_data, "vkFlushMappedMemoryRanges", mem_range_count, mem_ranges); 852280e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski return skip; 852380e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski} 852480e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski 8525bba0de708d942e9a2187158915856995db1c5a4dMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL FlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, 8526bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski const VkMappedMemoryRange *pMemRanges) { 85275b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 852856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 85295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 853080e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski if (!PreCallValidateFlushMappedMemoryRanges(dev_data, memRangeCount, pMemRanges)) { 85314a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.FlushMappedMemoryRanges(device, memRangeCount, pMemRanges); 85325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 85345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 85355b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 853680e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinskistatic bool PreCallValidateInvalidateMappedMemoryRanges(layer_data *dev_data, uint32_t mem_range_count, 853780e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 853880e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski bool skip = false; 8539ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 854080e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski skip |= validateMemoryIsMapped(dev_data, "vkInvalidateMappedMemoryRanges", mem_range_count, mem_ranges); 854180e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski return skip; 854280e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski} 854380e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski 854480e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinskistatic void PostCallRecordInvalidateMappedMemoryRanges(layer_data *dev_data, uint32_t mem_range_count, 854580e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski const VkMappedMemoryRange *mem_ranges) { 8546ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 854780e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski // Update our shadow copy with modified driver data 854880e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski CopyNoncoherentMemoryFromDriver(dev_data, mem_range_count, mem_ranges); 854980e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski} 855080e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski 8551bba0de708d942e9a2187158915856995db1c5a4dMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL InvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, 8552bba0de708d942e9a2187158915856995db1c5a4dMark Lobodzinski const VkMappedMemoryRange *pMemRanges) { 85535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 855456e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 85555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 855680e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski if (!PreCallValidateInvalidateMappedMemoryRanges(dev_data, memRangeCount, pMemRanges)) { 85574a0754042cf090e131e9e769d8a3633c228625beChris Forbes result = dev_data->dispatch_table.InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges); 855880e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski if (result == VK_SUCCESS) { 855980e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski PostCallRecordInvalidateMappedMemoryRanges(dev_data, memRangeCount, pMemRanges); 856080e8617d44ad5727efb3da174951080b54b21cd8Mark Lobodzinski } 85615b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 85625b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 85635b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 85645b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8565160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic bool PreCallValidateBindImageMemory(layer_data *dev_data, VkImage image, IMAGE_STATE *image_state, VkDeviceMemory mem, 8566160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 85670109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski bool skip = false; 85681facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (image_state) { 8569ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 857094c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis // Track objects tied to memory 85719b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t image_handle = HandleToUint64(image); 85727a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski skip = ValidateSetMemBinding(dev_data, mem, image_handle, kVulkanObjectTypeImage, "vkBindImageMemory()"); 8573ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis if (!image_state->memory_requirements_checked) { 8574ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis // There's not an explicit requirement in the spec to call vkGetImageMemoryRequirements() prior to calling 8575341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton // BindImageMemory but it's implied in that memory being bound must conform with VkMemoryRequirements from 8576341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton // vkGetImageMemoryRequirements() 85770109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 85780109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski image_handle, __LINE__, DRAWSTATE_INVALID_IMAGE, "DS", 85790109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski "vkBindImageMemory(): Binding memory to image 0x%" PRIxLEAST64 85800109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski " but vkGetImageMemoryRequirements() has not been called on that image.", 85810109928beb33325a442d7e3e7f38e73edf9cc38bMark Lobodzinski image_handle); 8582ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis // Make the call for them so we can verify the state 8583ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis lock.unlock(); 8584341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton dev_data->dispatch_table.GetImageMemoryRequirements(dev_data->device, image, &image_state->requirements); 8585ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis lock.lock(); 8586ff3ef1181960319d2268e82dae075726f650c553Tobin Ehlis } 858747aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 85880ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Validate bound memory range information 85899a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto mem_info = GetMemObjInfo(dev_data, mem); 859057fc8e28c2e16118f9827e3ae1b107a27e0451a2Tobin Ehlis if (mem_info) { 85910ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton skip |= ValidateInsertImageMemoryRange(dev_data, image, mem_info, memoryOffset, image_state->requirements, 85920ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton image_state->createInfo.tiling == VK_IMAGE_TILING_LINEAR, "vkBindImageMemory()"); 859374300755ed9ec780d6073af71e47f201217008d6Cort Stratton skip |= ValidateMemoryTypes(dev_data, mem_info, image_state->requirements.memoryTypeBits, "vkBindImageMemory()", 8594315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_1740082e); 859547aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski } 8596160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton 8597160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton // Validate memory requirements alignment 859816769f6b2a7721e391952a97f010cbb530e4f211Dave Houlton if (SafeModulo(memoryOffset, image_state->requirements.alignment) != 0) { 8599160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 8600315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis image_handle, __LINE__, VALIDATION_ERROR_17400830, "DS", 8601160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "vkBindImageMemory(): memoryOffset is 0x%" PRIxLEAST64 8602160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton " but must be an integer multiple of the " 8603160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "VkMemoryRequirements::alignment value 0x%" PRIxLEAST64 8604160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton ", returned from a call to vkGetImageMemoryRequirements with image. %s", 8605315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis memoryOffset, image_state->requirements.alignment, validation_error_map[VALIDATION_ERROR_17400830]); 8606160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton } 8607160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton 8608160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton // Validate memory requirements size 8609160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton if (image_state->requirements.size > mem_info->alloc_info.allocationSize - memoryOffset) { 8610160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, 8611315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis image_handle, __LINE__, VALIDATION_ERROR_17400832, "DS", 8612160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "vkBindImageMemory(): memory size minus memoryOffset is 0x%" PRIxLEAST64 8613160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton " but must be at least as large as " 8614160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton "VkMemoryRequirements::size value 0x%" PRIxLEAST64 8615160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton ", returned from a call to vkGetImageMemoryRequirements with image. %s", 8616160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton mem_info->alloc_info.allocationSize - memoryOffset, image_state->requirements.size, 8617315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_17400832]); 8618160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton } 8619341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton } 8620341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton return skip; 8621341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton} 862247aaf733d7394bda75c6de24289efe6b281e3cffMark Lobodzinski 8623160335c453ec51cc48bdef78e8befdb3c86ff292Cort Strattonstatic void PostCallRecordBindImageMemory(layer_data *dev_data, VkImage image, IMAGE_STATE *image_state, VkDeviceMemory mem, 8624160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton VkDeviceSize memoryOffset) { 8625341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton if (image_state) { 8626ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 86270ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton // Track bound memory range information 86280ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton auto mem_info = GetMemObjInfo(dev_data, mem); 86290ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton if (mem_info) { 86300ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton InsertImageMemoryRange(dev_data, image, mem_info, memoryOffset, image_state->requirements, 86310ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton image_state->createInfo.tiling == VK_IMAGE_TILING_LINEAR); 86320ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton } 86330ee7762cdcbfd554dd6a71c5ea48eec5e2a4a213Cort Stratton 8634c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton // Track objects tied to memory 86359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus uint64_t image_handle = HandleToUint64(image); 86367a9423788398dbeb6d1fe0354a66123b61afda96Mark Lobodzinski SetMemBinding(dev_data, mem, image_handle, kVulkanObjectTypeImage, "vkBindImageMemory()"); 8637c18f059542c30f6b37f8a654df020be38adfade6Cort Stratton 8638341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton image_state->binding.mem = mem; 8639341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton image_state->binding.offset = memoryOffset; 8640341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton image_state->binding.size = image_state->requirements.size; 8641341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton } 8642341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton} 8643341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton 8644341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort StrattonVKAPI_ATTR VkResult VKAPI_CALL BindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memoryOffset) { 8645341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 8646341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 8647160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton auto image_state = GetImageState(dev_data, image); 8648160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton bool skip = PreCallValidateBindImageMemory(dev_data, image, image_state, mem, memoryOffset); 8649341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton if (!skip) { 8650341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton result = dev_data->dispatch_table.BindImageMemory(device, image, mem, memoryOffset); 8651341d357dc354e888bfdc05b5dfd8c1cabe8417e0Cort Stratton if (result == VK_SUCCESS) { 8652160335c453ec51cc48bdef78e8befdb3c86ff292Cort Stratton PostCallRecordBindImageMemory(dev_data, image, image_state, mem, memoryOffset); 865394c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis } 86545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 86555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 86565b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 86575b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 865889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL SetEvent(VkDevice device, VkEvent event) { 86593251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 86603ee1d6057ee6c49b9dbbeb067b7fd149bdba7b5cTobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 866156e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 8662ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 86639a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto event_state = GetEventNode(dev_data, event); 86644710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state) { 86654710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->needsSignaled = false; 86664710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT; 86674710dda89a1dd2e023334d4eda710a394b211cdcTobin Ehlis if (event_state->write_in_use) { 86683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, 86699b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 86703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Cannot call vkSetEvent() on event 0x%" PRIxLEAST64 " that is already in use by a command buffer.", 86719b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(event)); 86723ee1d6057ee6c49b9dbbeb067b7fd149bdba7b5cTobin Ehlis } 86733ee1d6057ee6c49b9dbbeb067b7fd149bdba7b5cTobin Ehlis } 8674b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 86756fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis // Host setting event is visible to all queues immediately so update stageMask for any queue that's seen this event 86766fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis // TODO : For correctness this needs separate fix to verify that app doesn't make incorrect assumptions about the 86776fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis // ordering of this command in relation to vkCmd[Set|Reset]Events (see GH297) 86786fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis for (auto queue_data : dev_data->queueMap) { 86796fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis auto event_entry = queue_data.second.eventToStageMap.find(event); 86806fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis if (event_entry != queue_data.second.eventToStageMap.end()) { 86816fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis event_entry->second |= VK_PIPELINE_STAGE_HOST_BIT; 86826fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis } 86836fcff21b8cce5159fdfa317e612f75f5ea6a189eTobin Ehlis } 86843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) result = dev_data->dispatch_table.SetEvent(device, event); 86855b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 86865b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 86875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8688bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL QueueBindSparse(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo *pBindInfo, 8689bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkFence fence) { 869056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 86915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 86923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 8693ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 86949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 86959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pQueue = GetQueueState(dev_data, queue); 8696651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 86974b38d3aa8b6be6a7f5bebb472ab439da0562824fTobin Ehlis // First verify that fence is not in use 86983251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateFenceForSubmit(dev_data, pFence); 8699651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 87009867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (pFence) { 870193ccd9708dad3ffb58a3fc09a3d61cc5fe1569f8Mark Lobodzinski SubmitFence(pQueue, pFence, std::max(1u, bindInfoCount)); 87024b38d3aa8b6be6a7f5bebb472ab439da0562824fTobin Ehlis } 8703651d92815dfff917308137bb67aacccc4f60df86Chris Forbes 87041344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t bindIdx = 0; bindIdx < bindInfoCount; ++bindIdx) { 87051344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis const VkBindSparseInfo &bindInfo = pBindInfo[bindIdx]; 87065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis // Track objects tied to memory 87071344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t j = 0; j < bindInfo.bufferBindCount; j++) { 87081344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t k = 0; k < bindInfo.pBufferBinds[j].bindCount; k++) { 8709f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis auto sparse_binding = bindInfo.pBufferBinds[j].pBinds[k]; 8710f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, 87119b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(bindInfo.pBufferBinds[j].buffer), kVulkanObjectTypeBuffer)) 87123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = true; 87135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87151344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t j = 0; j < bindInfo.imageOpaqueBindCount; j++) { 87161344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t k = 0; k < bindInfo.pImageOpaqueBinds[j].bindCount; k++) { 8717f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis auto sparse_binding = bindInfo.pImageOpaqueBinds[j].pBinds[k]; 8718f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size}, 87199b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(bindInfo.pImageOpaqueBinds[j].image), kVulkanObjectTypeImage)) 87203251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = true; 87215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87231344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t j = 0; j < bindInfo.imageBindCount; j++) { 87241344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t k = 0; k < bindInfo.pImageBinds[j].bindCount; k++) { 8725f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis auto sparse_binding = bindInfo.pImageBinds[j].pBinds[k]; 8726f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data 8727f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4; 8728f19cf73769d6fc784ef4c3bf70b85739b4810693Tobin Ehlis if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, size}, 87299b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(bindInfo.pImageBinds[j].image), kVulkanObjectTypeImage)) 87303251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = true; 87315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87339867daedbf52debc77d6568162ee21e071699b80Chris Forbes 87349867daedbf52debc77d6568162ee21e071699b80Chris Forbes std::vector<SEMAPHORE_WAIT> semaphore_waits; 87359867daedbf52debc77d6568162ee21e071699b80Chris Forbes std::vector<VkSemaphore> semaphore_signals; 87361344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t i = 0; i < bindInfo.waitSemaphoreCount; ++i) { 873701a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = bindInfo.pWaitSemaphores[i]; 87389a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 873901a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore) { 874001a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore->signaled) { 87419867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (pSemaphore->signaler.first != VK_NULL_HANDLE) { 87429867daedbf52debc77d6568162ee21e071699b80Chris Forbes semaphore_waits.push_back({semaphore, pSemaphore->signaler.first, pSemaphore->signaler.second}); 87439867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->in_use.fetch_add(1); 87449867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 87459867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaler.first = VK_NULL_HANDLE; 874601a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes pSemaphore->signaled = false; 87471344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis } else { 87483251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 87499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 87503251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkQueueBindSparse: Queue 0x%p is waiting on semaphore 0x%" PRIx64 87513251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski " that has no way to be signaled.", 87529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus queue, HandleToUint64(semaphore)); 87535b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87545b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87555b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87561344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis for (uint32_t i = 0; i < bindInfo.signalSemaphoreCount; ++i) { 875701a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes VkSemaphore semaphore = bindInfo.pSignalSemaphores[i]; 87589a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 875901a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore) { 876001a48e41895b3951b297ff4245eff8f9c129ae20Chris Forbes if (pSemaphore->signaled) { 87613251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 87629b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(semaphore), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 87633251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkQueueBindSparse: Queue 0x%p is signaling semaphore 0x%" PRIx64 87643251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski ", but that semaphore is already signaled.", 87659b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus queue, HandleToUint64(semaphore)); 8766bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski } else { 87679867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaler.first = queue; 87689867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaler.second = pQueue->seq + pQueue->submissions.size() + 1; 87699867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaled = true; 87709867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->in_use.fetch_add(1); 87719867daedbf52debc77d6568162ee21e071699b80Chris Forbes semaphore_signals.push_back(semaphore); 87729867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 87735b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87759867daedbf52debc77d6568162ee21e071699b80Chris Forbes 8776bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), semaphore_waits, semaphore_signals, 87779867daedbf52debc77d6568162ee21e071699b80Chris Forbes bindIdx == bindInfoCount - 1 ? fence : VK_NULL_HANDLE); 87785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 87799867daedbf52debc77d6568162ee21e071699b80Chris Forbes 87809867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (pFence && !bindInfoCount) { 87819867daedbf52debc77d6568162ee21e071699b80Chris Forbes // No work to do, just dropping a fence in the queue by itself. 8782bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pQueue->submissions.emplace_back(std::vector<VkCommandBuffer>(), std::vector<SEMAPHORE_WAIT>(), std::vector<VkSemaphore>(), 87839867daedbf52debc77d6568162ee21e071699b80Chris Forbes fence); 87849867daedbf52debc77d6568162ee21e071699b80Chris Forbes } 87859867daedbf52debc77d6568162ee21e071699b80Chris Forbes 8786b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 87875b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 87883251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) return dev_data->dispatch_table.QueueBindSparse(queue, bindInfoCount, pBindInfo, fence); 87895b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 87905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 87915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 87925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 879389d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, 879489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) { 879556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 87964a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore); 87975b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 8798ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 8799bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski SEMAPHORE_NODE *sNode = &dev_data->semaphoreMap[*pSemaphore]; 88009867daedbf52debc77d6568162ee21e071699b80Chris Forbes sNode->signaler.first = VK_NULL_HANDLE; 88019867daedbf52debc77d6568162ee21e071699b80Chris Forbes sNode->signaler.second = 0; 88021344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis sNode->signaled = false; 88035b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 88045b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 88055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 88065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 8807bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, 8808bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) { 880956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 88104a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.CreateEvent(device, pCreateInfo, pAllocator, pEvent); 88115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (result == VK_SUCCESS) { 8812ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 88135b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->eventMap[*pEvent].needsSignaled = false; 8814293ecfc5e69ed3978a8c04518166d828294870a4Tony Barbour dev_data->eventMap[*pEvent].write_in_use = 0; 88155b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->eventMap[*pEvent].stageMask = VkPipelineStageFlags(0); 88165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 88175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 88185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 88195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 88209ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinskistatic bool PreCallValidateCreateSwapchainKHR(layer_data *dev_data, const char *func_name, 88219ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski VkSwapchainCreateInfoKHR const *pCreateInfo, SURFACE_STATE *surface_state, 88229ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski SWAPCHAIN_NODE *old_swapchain_state) { 8823d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes auto most_recent_swapchain = surface_state->swapchain ? surface_state->swapchain : surface_state->old_swapchain; 8824d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes 88254bd5f453535de3d3423ff1f9995b4acb15f791d2Chris Forbes // TODO: revisit this. some of these rules are being relaxed. 88260bbc015828bdb99e85e6731ce92428557902701fPetr Kraus 88270bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // All physical devices and queue families are required to be able 88280bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // to present to any native window on Android; require the 88290bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // application to have established support on any other platform. 8830d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (!dev_data->instance_data->extensions.vk_khr_android_surface) { 88310bbc015828bdb99e85e6731ce92428557902701fPetr Kraus auto support_predicate = [dev_data](decltype(surface_state->gpu_queue_support)::const_reference qs) -> bool { 88320bbc015828bdb99e85e6731ce92428557902701fPetr Kraus // TODO: should restrict search only to queue families of VkDeviceQueueCreateInfos, not whole phys. device 88330bbc015828bdb99e85e6731ce92428557902701fPetr Kraus return (qs.first.gpu == dev_data->physical_device) && qs.second; 88340bbc015828bdb99e85e6731ce92428557902701fPetr Kraus }; 88350bbc015828bdb99e85e6731ce92428557902701fPetr Kraus const auto& support = surface_state->gpu_queue_support; 88360bbc015828bdb99e85e6731ce92428557902701fPetr Kraus bool is_supported = std::any_of(support.begin(), support.end(), support_predicate); 88370bbc015828bdb99e85e6731ce92428557902701fPetr Kraus 88380bbc015828bdb99e85e6731ce92428557902701fPetr Kraus if (!is_supported) { 88390bbc015828bdb99e85e6731ce92428557902701fPetr Kraus if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8840315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009ec, "DS", 88410bbc015828bdb99e85e6731ce92428557902701fPetr Kraus "%s: pCreateInfo->surface is not known at this time to be supported for presentation by this device. " 88420bbc015828bdb99e85e6731ce92428557902701fPetr Kraus "The vkGetPhysicalDeviceSurfaceSupportKHR() must be called beforehand, and it must return VK_TRUE support " 88430bbc015828bdb99e85e6731ce92428557902701fPetr Kraus "with this surface for at least one queue family of this device. %s", 8844315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis func_name, validation_error_map[VALIDATION_ERROR_146009ec])) 88450bbc015828bdb99e85e6731ce92428557902701fPetr Kraus return true; 88460bbc015828bdb99e85e6731ce92428557902701fPetr Kraus } 88470bbc015828bdb99e85e6731ce92428557902701fPetr Kraus } 88480bbc015828bdb99e85e6731ce92428557902701fPetr Kraus 8849d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (most_recent_swapchain != old_swapchain_state || (surface_state->old_swapchain && surface_state->swapchain)) { 8850d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 88519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_ALREADY_EXISTS, "DS", 88529ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s: surface has an existing swapchain other than oldSwapchain", func_name)) 8853d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes return true; 8854d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes } 8855d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (old_swapchain_state && old_swapchain_state->createInfo.surface != pCreateInfo->surface) { 8856d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 88579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pCreateInfo->oldSwapchain), __LINE__, DRAWSTATE_SWAPCHAIN_WRONG_SURFACE, "DS", 88589b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "%s: pCreateInfo->oldSwapchain's surface is not pCreateInfo->surface", func_name)) 8859d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes return true; 8860d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes } 88619a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(dev_data->instance_data, dev_data->physical_device); 88627de258f87ca1192db116a66b209253793d276ebcChris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState == UNCALLED) { 88637de258f87ca1192db116a66b209253793d276ebcChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 88649b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->physical_device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, "DS", 88659ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s: surface capabilities not retrieved for this physical device", func_name)) 88667de258f87ca1192db116a66b209253793d276ebcChris Forbes return true; 8867cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else { // have valid capabilities 88685c99b4daed164798f307244c9bde17b4f66014fbChris Forbes auto &capabilities = physical_device_state->surfaceCapabilities; 88699ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->minImageCount against VkSurfaceCapabilitiesKHR::{min|max}ImageCount: 88702fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (pCreateInfo->minImageCount < capabilities.minImageCount) { 88712fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8872315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009ee, "DS", 88739ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with minImageCount = %d, which is outside the bounds returned " 88742fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = %d, maxImageCount = %d). %s", 88759ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->minImageCount, capabilities.minImageCount, capabilities.maxImageCount, 8876315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009ee])) 88772fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen return true; 88782fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen } 88792fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen 88802fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if ((capabilities.maxImageCount > 0) && (pCreateInfo->minImageCount > capabilities.maxImageCount)) { 88815c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8882315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f0, "DS", 88839ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with minImageCount = %d, which is outside the bounds returned " 88842fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen "by vkGetPhysicalDeviceSurfaceCapabilitiesKHR() (i.e. minImageCount = %d, maxImageCount = %d). %s", 88859ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->minImageCount, capabilities.minImageCount, capabilities.maxImageCount, 8886315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f0])) 88875c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 88885c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 88892fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen 88909ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageExtent against VkSurfaceCapabilitiesKHR::{current|min|max}ImageExtent: 88912e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill if ((capabilities.currentExtent.width == kSurfaceSizeFromSwapchain) && 88922e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill ((pCreateInfo->imageExtent.width < capabilities.minImageExtent.width) || 88932e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill (pCreateInfo->imageExtent.width > capabilities.maxImageExtent.width) || 88942e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill (pCreateInfo->imageExtent.height < capabilities.minImageExtent.height) || 88952e935bbc6cacaff38c073f86594a1b56d1f8a800Jamie Madill (pCreateInfo->imageExtent.height > capabilities.maxImageExtent.height))) { 88965c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8897315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f4, "DS", 88989ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with imageExtent = (%d,%d), which is outside the bounds returned by " 88999ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (%d,%d), minImageExtent = (%d,%d), " 89009ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "maxImageExtent = (%d,%d). %s", 89019ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->imageExtent.width, pCreateInfo->imageExtent.height, 89029ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski capabilities.currentExtent.width, capabilities.currentExtent.height, capabilities.minImageExtent.width, 89039ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski capabilities.minImageExtent.height, capabilities.maxImageExtent.width, capabilities.maxImageExtent.height, 8904315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f4])) 89055c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 89065c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89079ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // pCreateInfo->preTransform should have exactly one bit set, and that bit must also be set in 89089ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // VkSurfaceCapabilitiesKHR::supportedTransforms. 89095c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (!pCreateInfo->preTransform || (pCreateInfo->preTransform & (pCreateInfo->preTransform - 1)) || 89105c99b4daed164798f307244c9bde17b4f66014fbChris Forbes !(pCreateInfo->preTransform & capabilities.supportedTransforms)) { 89119ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // This is an error situation; one for which we'd like to give the developer a helpful, multi-line error message. Build 89129ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // it up a little at a time, and then log it: 89135c99b4daed164798f307244c9bde17b4f66014fbChris Forbes std::string errorString = ""; 89145c99b4daed164798f307244c9bde17b4f66014fbChris Forbes char str[1024]; 89155c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Here's the first part of the message: 89169ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski sprintf(str, "%s called with a non-supported pCreateInfo->preTransform (i.e. %s). Supported values are:\n", func_name, 89175c99b4daed164798f307244c9bde17b4f66014fbChris Forbes string_VkSurfaceTransformFlagBitsKHR(pCreateInfo->preTransform)); 89185c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 89195c99b4daed164798f307244c9bde17b4f66014fbChris Forbes for (int i = 0; i < 32; i++) { 89205c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Build up the rest of the message: 89215c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if ((1 << i) & capabilities.supportedTransforms) { 89225c99b4daed164798f307244c9bde17b4f66014fbChris Forbes const char *newStr = string_VkSurfaceTransformFlagBitsKHR((VkSurfaceTransformFlagBitsKHR)(1 << i)); 89235c99b4daed164798f307244c9bde17b4f66014fbChris Forbes sprintf(str, " %s\n", newStr); 89245c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 89255c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89265c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89275c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Log the message that we've built up: 89285c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8929315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009fe, "DS", "%s. %s", errorString.c_str(), 8930315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009fe])) 89315c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 89325c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89337b0d28d116977b91892f354e002edd760bdb86cbChris Forbes 89349ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // pCreateInfo->compositeAlpha should have exactly one bit set, and that bit must also be set in 89359ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // VkSurfaceCapabilitiesKHR::supportedCompositeAlpha 89365c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (!pCreateInfo->compositeAlpha || (pCreateInfo->compositeAlpha & (pCreateInfo->compositeAlpha - 1)) || 89375c99b4daed164798f307244c9bde17b4f66014fbChris Forbes !((pCreateInfo->compositeAlpha) & capabilities.supportedCompositeAlpha)) { 89389ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // This is an error situation; one for which we'd like to give the developer a helpful, multi-line error message. Build 89399ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // it up a little at a time, and then log it: 89405c99b4daed164798f307244c9bde17b4f66014fbChris Forbes std::string errorString = ""; 89415c99b4daed164798f307244c9bde17b4f66014fbChris Forbes char str[1024]; 89425c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Here's the first part of the message: 89439ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski sprintf(str, "%s called with a non-supported pCreateInfo->compositeAlpha (i.e. %s). Supported values are:\n", 89449ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, string_VkCompositeAlphaFlagBitsKHR(pCreateInfo->compositeAlpha)); 89455c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 89465c99b4daed164798f307244c9bde17b4f66014fbChris Forbes for (int i = 0; i < 32; i++) { 89475c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Build up the rest of the message: 89485c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if ((1 << i) & capabilities.supportedCompositeAlpha) { 89495c99b4daed164798f307244c9bde17b4f66014fbChris Forbes const char *newStr = string_VkCompositeAlphaFlagBitsKHR((VkCompositeAlphaFlagBitsKHR)(1 << i)); 89505c99b4daed164798f307244c9bde17b4f66014fbChris Forbes sprintf(str, " %s\n", newStr); 89515c99b4daed164798f307244c9bde17b4f66014fbChris Forbes errorString += str; 89525c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89535c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89545c99b4daed164798f307244c9bde17b4f66014fbChris Forbes // Log the message that we've built up: 89555c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8956315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_14600a00, "DS", "%s. %s", errorString.c_str(), 8957315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_14600a00])) 89585c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 89595c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89609ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageArrayLayers against VkSurfaceCapabilitiesKHR::maxImageArrayLayers: 89615c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if ((pCreateInfo->imageArrayLayers < 1) || (pCreateInfo->imageArrayLayers > capabilities.maxImageArrayLayers)) { 89625c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8963315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f6, "DS", 89649ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with a non-supported imageArrayLayers (i.e. %d). Minimum value is 1, maximum value is %d. %s", 89659ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->imageArrayLayers, capabilities.maxImageArrayLayers, 8966315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f6])) 89675c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 89685c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89699ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageUsage against VkSurfaceCapabilitiesKHR::supportedUsageFlags: 89705c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (pCreateInfo->imageUsage != (pCreateInfo->imageUsage & capabilities.supportedUsageFlags)) { 89715c99b4daed164798f307244c9bde17b4f66014fbChris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 8972315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f8, "DS", 89739ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with a non-supported pCreateInfo->imageUsage (i.e. 0x%08x). Supported flag bits are 0x%08x. %s", 89749ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name, pCreateInfo->imageUsage, capabilities.supportedUsageFlags, 8975315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_146009f8])) 89765c99b4daed164798f307244c9bde17b4f66014fbChris Forbes return true; 89775c99b4daed164798f307244c9bde17b4f66014fbChris Forbes } 89787de258f87ca1192db116a66b209253793d276ebcChris Forbes } 8979d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes 89809ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo values with the results of vkGetPhysicalDeviceSurfaceFormatsKHR(): 89815faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfaceFormatsKHRState != QUERY_DETAILS) { 89825faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 89839b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, "DS", 89849ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called before calling vkGetPhysicalDeviceSurfaceFormatsKHR().", func_name)) 89855faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes return true; 89865faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } else { 89879ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageFormat against VkSurfaceFormatKHR::format: 89885faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes bool foundFormat = false; 89895faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes bool foundColorSpace = false; 89905faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes bool foundMatch = false; 89915faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes for (auto const &format : physical_device_state->surface_formats) { 89925faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pCreateInfo->imageFormat == format.format) { 89939ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->imageColorSpace against VkSurfaceFormatKHR::colorSpace: 89945faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes foundFormat = true; 89955faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pCreateInfo->imageColorSpace == format.colorSpace) { 89965faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes foundMatch = true; 89975faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes break; 89985faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 89995faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } else { 90005faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pCreateInfo->imageColorSpace == format.colorSpace) { 90015faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes foundColorSpace = true; 90025faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 90035faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 90045faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 90055faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (!foundMatch) { 90065faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (!foundFormat) { 90075faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9008315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f2, "DS", 9009bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "%s called with a non-supported pCreateInfo->imageFormat (i.e. %d). %s", func_name, 9010315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo->imageFormat, validation_error_map[VALIDATION_ERROR_146009f2])) 90112fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen return true; 90122fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen } 90132fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (!foundColorSpace) { 90142fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9015315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_146009f2, "DS", 9016bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "%s called with a non-supported pCreateInfo->imageColorSpace (i.e. %d). %s", func_name, 9017315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis pCreateInfo->imageColorSpace, validation_error_map[VALIDATION_ERROR_146009f2])) 90185faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes return true; 90195faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 90205faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 90215faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 90225faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 90239ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo values with the results of vkGetPhysicalDeviceSurfacePresentModesKHR(): 90249e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfacePresentModesKHRState != QUERY_DETAILS) { 902525002b75574f762c62b1a00a595bab04ebb25452Mark Lobodzinski // FIFO is required to always be supported 90269e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (pCreateInfo->presentMode != VK_PRESENT_MODE_FIFO_KHR) { 90279e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 90289b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_CREATE_BEFORE_QUERY, "DS", 90299ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called before calling vkGetPhysicalDeviceSurfacePresentModesKHR().", func_name)) 90309e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes return true; 90319e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 90329e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } else { 90339ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski // Validate pCreateInfo->presentMode against vkGetPhysicalDeviceSurfacePresentModesKHR(): 9034bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski bool foundMatch = std::find(physical_device_state->present_modes.begin(), physical_device_state->present_modes.end(), 90359e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes pCreateInfo->presentMode) != physical_device_state->present_modes.end(); 90369e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (!foundMatch) { 90379e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9038315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, VALIDATION_ERROR_14600a02, "DS", 90399ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski "%s called with a non-supported presentMode (i.e. %s). %s", func_name, 9040315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis string_VkPresentModeKHR(pCreateInfo->presentMode), validation_error_map[VALIDATION_ERROR_14600a02])) 90419e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes return true; 90429e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 90439e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 904487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis // Validate state for shared presentable case 904587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR == pCreateInfo->presentMode || 904687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR == pCreateInfo->presentMode) { 9047a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski if (!dev_data->extensions.vk_khr_shared_presentable_image) { 904887a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9049480a11822ef9a45f577f13644759c0895a49db19Tobin Ehlis HandleToUint64(dev_data->device), __LINE__, DRAWSTATE_EXTENSION_NOT_ENABLED, "DS", 90506084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "%s called with presentMode %s which requires the VK_KHR_shared_presentable_image extension, which has not " 90516084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "been enabled.", 90526084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski func_name, string_VkPresentModeKHR(pCreateInfo->presentMode))) 90536084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski return true; 90546084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski } else if (pCreateInfo->minImageCount != 1) { 90556084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9056315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis reinterpret_cast<uint64_t>(dev_data->device), __LINE__, VALIDATION_ERROR_14600ace, "DS", 905787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis "%s called with presentMode %s, but minImageCount value is %d. For shared presentable image, minImageCount " 90586084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "must be 1. %s", 90596084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski func_name, string_VkPresentModeKHR(pCreateInfo->presentMode), pCreateInfo->minImageCount, 9060315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_14600ace])) 906187a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis return true; 906287a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 906387a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 90649e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 9065d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes return false; 9066d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes} 9067d3b3114fb37a32af2ba563f784da54a877492b23Chris Forbes 9068261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinskistatic void PostCallRecordCreateSwapchainKHR(layer_data *dev_data, VkResult result, const VkSwapchainCreateInfoKHR *pCreateInfo, 9069261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski VkSwapchainKHR *pSwapchain, SURFACE_STATE *surface_state, 9070261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski SWAPCHAIN_NODE *old_swapchain_state) { 90715b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == result) { 9072ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9073ddc5201048319558ce66701163a4546ee957af19Chris Forbes auto swapchain_state = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(pCreateInfo, *pSwapchain)); 907487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR == pCreateInfo->presentMode || 907587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR == pCreateInfo->presentMode) { 907687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis swapchain_state->shared_presentable = true; 907787a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 9078ddc5201048319558ce66701163a4546ee957af19Chris Forbes surface_state->swapchain = swapchain_state.get(); 907916a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes dev_data->swapchainMap[*pSwapchain] = std::move(swapchain_state); 9080ddc5201048319558ce66701163a4546ee957af19Chris Forbes } else { 9081ddc5201048319558ce66701163a4546ee957af19Chris Forbes surface_state->swapchain = nullptr; 90825b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9083ddc5201048319558ce66701163a4546ee957af19Chris Forbes // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain behaves as replaced. 90845b5488456e5afa0487f95b805a2aba59b13d69f4Chris Forbes if (old_swapchain_state) { 90855b5488456e5afa0487f95b805a2aba59b13d69f4Chris Forbes old_swapchain_state->replaced = true; 90865b5488456e5afa0487f95b805a2aba59b13d69f4Chris Forbes } 9087ddc5201048319558ce66701163a4546ee957af19Chris Forbes surface_state->old_swapchain = old_swapchain_state; 9088261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski return; 9089261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski} 9090261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 9091261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, 9092261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) { 909356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 90949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(dev_data->instance_data, pCreateInfo->surface); 90959a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto old_swapchain_state = GetSwapchainNode(dev_data, pCreateInfo->oldSwapchain); 9096261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 90979ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski if (PreCallValidateCreateSwapchainKHR(dev_data, "vkCreateSwapChainKHR()", pCreateInfo, surface_state, old_swapchain_state)) { 9098261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski return VK_ERROR_VALIDATION_FAILED_EXT; 9099261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski } 9100261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 9101261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski VkResult result = dev_data->dispatch_table.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); 9102261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski 9103261dc1ef7a86b64cce92a6811bf80ee4ba364a48Mark Lobodzinski PostCallRecordCreateSwapchainKHR(dev_data, result, pCreateInfo, pSwapchain, surface_state, old_swapchain_state); 9104ddc5201048319558ce66701163a4546ee957af19Chris Forbes 91055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 91065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 91075b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9108bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator) { 910956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 91103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 91115b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9112ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 91139a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, swapchain); 9114b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis if (swapchain_data) { 9115b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis if (swapchain_data->images.size() > 0) { 9116b110cb87b9478586719d7f7dc769b350857366baTobin Ehlis for (auto swapchain_image : swapchain_data->images) { 91175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto image_sub = dev_data->imageSubresourceMap.find(swapchain_image); 91185b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (image_sub != dev_data->imageSubresourceMap.end()) { 91195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis for (auto imgsubpair : image_sub->second) { 91205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis auto image_item = dev_data->imageLayoutMap.find(imgsubpair); 91215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (image_item != dev_data->imageLayoutMap.end()) { 91225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageLayoutMap.erase(image_item); 91235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 91245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 91255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis dev_data->imageSubresourceMap.erase(image_sub); 91265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 91279b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip = ClearMemoryObjectBindings(dev_data, HandleToUint64(swapchain_image), kVulkanObjectTypeSwapchainKHR); 912894c53c062f0ccc70ef0ada8e98edc90eadc4cb45Tobin Ehlis dev_data->imageMap.erase(swapchain_image); 91295b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 91305b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9131ddc5201048319558ce66701163a4546ee957af19Chris Forbes 91329a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(dev_data->instance_data, swapchain_data->createInfo.surface); 9133ddc5201048319558ce66701163a4546ee957af19Chris Forbes if (surface_state) { 9134cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (surface_state->swapchain == swapchain_data) surface_state->swapchain = nullptr; 9135cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (surface_state->old_swapchain == swapchain_data) surface_state->old_swapchain = nullptr; 9136ddc5201048319558ce66701163a4546ee957af19Chris Forbes } 9137ddc5201048319558ce66701163a4546ee957af19Chris Forbes 913816a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes dev_data->swapchainMap.erase(swapchain); 91395b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9140b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 91413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) dev_data->dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator); 91425b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 91435b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9144991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool PreCallValidateGetSwapchainImagesKHR(layer_data *device_data, SWAPCHAIN_NODE *swapchain_state, VkDevice device, 9145991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 9146991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 9147991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state && pSwapchainImages) { 9148ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9149991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski // Compare the preliminary value of *pSwapchainImageCount with the value this time: 9150991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->vkGetSwapchainImagesKHRState == UNCALLED) { 9151991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9152991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(device), __LINE__, SWAPCHAIN_PRIOR_COUNT, "DS", 9153991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetSwapchainImagesKHR() called with non-NULL pSwapchainImageCount; but no prior positive " 9154991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "value has been seen for pSwapchainImages."); 9155991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } else if (*pSwapchainImageCount > swapchain_state->get_swapchain_image_count) { 9156991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 9157991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(device), __LINE__, SWAPCHAIN_INVALID_COUNT, "DS", 9158991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetSwapchainImagesKHR() called with non-NULL pSwapchainImageCount, and with " 9159991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "pSwapchainImages set to a value (%d) that is greater than the value (%d) that was returned when " 9160991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "pSwapchainImageCount was NULL.", 9161991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski *pSwapchainImageCount, swapchain_state->get_swapchain_image_count); 9162991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9163991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9164991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 9165991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 9166991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9167991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic void PostCallRecordGetSwapchainImagesKHR(layer_data *device_data, SWAPCHAIN_NODE *swapchain_state, VkDevice device, 9168991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) { 9169ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 9170ee52d734440f0770b3ac5ebde5a137d2e40589deChris Forbes 9171991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (*pSwapchainImageCount > swapchain_state->images.size()) swapchain_state->images.resize(*pSwapchainImageCount); 9172ee52d734440f0770b3ac5ebde5a137d2e40589deChris Forbes 9173991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (pSwapchainImages) { 9174991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->vkGetSwapchainImagesKHRState < QUERY_DETAILS) { 9175991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->vkGetSwapchainImagesKHRState = QUERY_DETAILS; 9176991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9177991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) { 9178991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->images[i] != VK_NULL_HANDLE) continue; // Already retrieved this. 9179ee52d734440f0770b3ac5ebde5a137d2e40589deChris Forbes 91805b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis IMAGE_LAYOUT_NODE image_layout_node; 91815b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis image_layout_node.layout = VK_IMAGE_LAYOUT_UNDEFINED; 9182991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_layout_node.format = swapchain_state->createInfo.imageFormat; 91836d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis // Add imageMap entries for each swapchain image 91846d1373829eded68f6e080ff2c33e03231360ed57Tobin Ehlis VkImageCreateInfo image_ci = {}; 9185eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.flags = 0; 9186eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.imageType = VK_IMAGE_TYPE_2D; 9187991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.format = swapchain_state->createInfo.imageFormat; 9188991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.extent.width = swapchain_state->createInfo.imageExtent.width; 9189991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.extent.height = swapchain_state->createInfo.imageExtent.height; 9190d1a9776c1a22ec99a3ef0dd44e7f85a78a04d1edTony Barbour image_ci.extent.depth = 1; 9191eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.mipLevels = 1; 9192991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.arrayLayers = swapchain_state->createInfo.imageArrayLayers; 9193eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.samples = VK_SAMPLE_COUNT_1_BIT; 9194eb6ea7587bdc06e98a89398f113fe3610d270dcbChris Forbes image_ci.tiling = VK_IMAGE_TILING_OPTIMAL; 9195991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.usage = swapchain_state->createInfo.imageUsage; 9196991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski image_ci.sharingMode = swapchain_state->createInfo.imageSharingMode; 9197991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski device_data->imageMap[pSwapchainImages[i]] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pSwapchainImages[i], &image_ci)); 9198991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto &image_state = device_data->imageMap[pSwapchainImages[i]]; 91991facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->valid = false; 9200e46491ee6f16b9d29e68914fc6522aba2fde0ad4Tobin Ehlis image_state->binding.mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY; 9201991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->images[i] = pSwapchainImages[i]; 92025b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis ImageSubresourcePair subpair = {pSwapchainImages[i], false, VkImageSubresource()}; 9203991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski device_data->imageSubresourceMap[pSwapchainImages[i]].push_back(subpair); 9204991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski device_data->imageLayoutMap[subpair] = image_layout_node; 92055b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 92065b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9207991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9208991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (*pSwapchainImageCount) { 9209991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (swapchain_state->vkGetSwapchainImagesKHRState < QUERY_COUNT) { 9210991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->vkGetSwapchainImagesKHRState = QUERY_COUNT; 9211991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9212991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski swapchain_state->get_swapchain_image_count = *pSwapchainImageCount; 9213991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9214991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 9215991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9216991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, 9217991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkImage *pSwapchainImages) { 9218991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 9219991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9220991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9221991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto swapchain_state = GetSwapchainNode(device_data, swapchain); 9222991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = PreCallValidateGetSwapchainImagesKHR(device_data, swapchain_state, device, pSwapchainImageCount, pSwapchainImages); 9223991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9224991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (!skip) { 9225991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = device_data->dispatch_table.GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); 9226991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 9227991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 9228991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if ((result == VK_SUCCESS || result == VK_INCOMPLETE)) { 9229991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski PostCallRecordGetSwapchainImagesKHR(device_data, swapchain_state, device, pSwapchainImageCount, pSwapchainImages); 9230991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 92315b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 92325b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 92335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 923489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) { 923556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map); 92363251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 92375b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9238ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 92399a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto queue_state = GetQueueState(dev_data, queue); 92401671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes 92416c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) { 92429a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, pPresentInfo->pWaitSemaphores[i]); 92436c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes if (pSemaphore && !pSemaphore->signaled) { 92443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 92453251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS", 92463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Queue 0x%p is waiting on semaphore 0x%" PRIx64 " that has no way to be signaled.", queue, 92479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pWaitSemaphores[i])); 92485b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 92496c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 9250249eb117f85f5e0f3f3a83a2bf297893e0d054ceTobin Ehlis 92516c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) { 92529a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]); 9253a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes if (swapchain_data) { 9254a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes if (pPresentInfo->pImageIndices[i] >= swapchain_data->images.size()) { 92559b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 92569b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 92579b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 92589b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkQueuePresentKHR: Swapchain image index too large (%u). There are only %u images in this swapchain.", 92599b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus pPresentInfo->pImageIndices[i], (uint32_t)swapchain_data->images.size()); 9260bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski } else { 9261a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]]; 92629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 926387a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis 926487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (image_state->shared_presentable) { 926587a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis image_state->layout_locked = true; 926687a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 9267c4f799ed5502f05ce97543e0500b4a19dc5f2461Mark Lobodzinski 92683251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateImageMemoryIsValid(dev_data, image_state, "vkQueuePresentKHR()"); 9269a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes 92701facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis if (!image_state->acquired) { 92713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 9272bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 92739b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_IMAGE_NOT_ACQUIRED, "DS", 9274bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski "vkQueuePresentKHR: Swapchain image index %u has not been acquired.", pPresentInfo->pImageIndices[i]); 9275a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes } 9276a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes 9277a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes vector<VkImageLayout> layouts; 9278a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes if (FindLayouts(dev_data, image, layouts)) { 9279a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes for (auto layout : layouts) { 92806084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski if ((layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) && 9281a149f1a0cb39b48b19822c8cf9ef2426cd2251dfMark Lobodzinski (!dev_data->extensions.vk_khr_shared_presentable_image || 92826084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski (layout != VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR))) { 92833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 92842fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, 9285315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(queue), __LINE__, VALIDATION_ERROR_11200a20, "DS", 92862fbc1a61dff1781368a0c592c25985abb46e4891Mike Weiblen "Images passed to present must be in layout " 92876084b78a58b438d27591b81efe30997ac9d88d3cMark Lobodzinski "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in %s. %s", 9288315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis string_VkImageLayout(layout), validation_error_map[VALIDATION_ERROR_11200a20]); 9289a96bccebcf27add1b38bfe46c541e1484d7b4d88Chris Forbes } 92905b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 92915b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 92925b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 92931671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes 92941671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes // All physical devices and queue families are required to be able 92951671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes // to present to any native window on Android; require the 92961671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes // application to have established support on any other platform. 9297d4eaca34eca7f4b4e34190c441a579347bb2016aMark Lobodzinski if (!dev_data->instance_data->extensions.vk_khr_android_surface) { 92989a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(dev_data->instance_data, swapchain_data->createInfo.surface); 92991671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes auto support_it = surface_state->gpu_queue_support.find({dev_data->physical_device, queue_state->queueFamilyIndex}); 93001671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes 93011671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes if (support_it == surface_state->gpu_queue_support.end()) { 93023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 93031671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 93049b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_UNSUPPORTED_QUEUE, "DS", 9305cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkQueuePresentKHR: Presenting image without calling " 9306cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfaceSupportKHR"); 93071671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes } else if (!support_it->second) { 93089b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= 93099b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 9310315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, VALIDATION_ERROR_31800a18, "DS", 93119b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkQueuePresentKHR: Presenting image on queue that cannot " 93129b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "present to this surface. %s", 9313315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_31800a18]); 93141671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes } 93151671dfbfc53aa19dcf76d71c2dd1f8f2c4879174Chris Forbes } 93165b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 93175b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9318c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis if (pPresentInfo && pPresentInfo->pNext) { 9319c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis // Verify ext struct 9320c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis struct std_header { 9321c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis VkStructureType sType; 9322c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis const void *pNext; 9323c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis }; 9324c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis std_header *pnext = (std_header *)pPresentInfo->pNext; 9325c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis while (pnext) { 9326c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis if (VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR == pnext->sType) { 9327c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis VkPresentRegionsKHR *present_regions = (VkPresentRegionsKHR *)pnext; 9328c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis for (uint32_t i = 0; i < present_regions->swapchainCount; ++i) { 9329c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]); 9330c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis assert(swapchain_data); 9331c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis VkPresentRegionKHR region = present_regions->pRegions[i]; 9332c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis for (uint32_t j = 0; j < region.rectangleCount; ++j) { 9333c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis VkRectLayerKHR rect = region.pRectangles[j]; 9334c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis // TODO: Need to update these errors to their unique error ids when available 9335c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis if ((rect.offset.x + rect.extent.width) > swapchain_data->createInfo.imageExtent.width) { 93369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 93379b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 93389b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 93399b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkQueuePresentKHR(): For VkPresentRegionKHR down pNext " 93409b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "chain, pRegion[%i].pRectangles[%i], the sum of offset.x " 93419b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "(%i) and extent.width (%i) is greater than the " 93429b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "corresponding swapchain's imageExtent.width (%i).", 93439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus i, j, rect.offset.x, rect.extent.width, swapchain_data->createInfo.imageExtent.width); 9344c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9345c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis if ((rect.offset.y + rect.extent.height) > swapchain_data->createInfo.imageExtent.height) { 93469b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus skip |= log_msg( 93479b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 93489b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 93499b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "vkQueuePresentKHR(): For VkPresentRegionKHR down pNext " 93509b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "chain, pRegion[%i].pRectangles[%i], the sum of offset.y " 93519b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "(%i) and extent.height (%i) is greater than the " 93529b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "corresponding swapchain's imageExtent.height (%i).", 93539b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus i, j, rect.offset.y, rect.extent.height, swapchain_data->createInfo.imageExtent.height); 9354c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9355c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis if (rect.layer > swapchain_data->createInfo.imageArrayLayers) { 93563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 9357c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 93589b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE, "DS", 9359c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis "vkQueuePresentKHR(): For VkPresentRegionKHR down pNext chain, pRegion[%i].pRectangles[%i], the " 9360c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis "layer (%i) is greater than the corresponding swapchain's imageArrayLayers (%i).", 9361c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis i, j, rect.layer, swapchain_data->createInfo.imageArrayLayers); 9362c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9363c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9364c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 93655f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis } else if (VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE == pnext->sType) { 93665f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis VkPresentTimesInfoGOOGLE *present_times_info = (VkPresentTimesInfoGOOGLE *)pnext; 93675f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis if (pPresentInfo->swapchainCount != present_times_info->swapchainCount) { 93685f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis skip |= 93695f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 93709b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pPresentInfo->pSwapchains[0]), __LINE__, 93715f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis 9372315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis VALIDATION_ERROR_118009be, "DS", 93735f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "vkQueuePresentKHR(): VkPresentTimesInfoGOOGLE.swapchainCount is %i but " 93745f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "pPresentInfo->swapchainCount is %i. For VkPresentTimesInfoGOOGLE down pNext " 93755f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "chain of VkPresentInfoKHR, VkPresentTimesInfoGOOGLE.swapchainCount " 93765f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis "must equal VkPresentInfoKHR.swapchainCount.", 93775f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis present_times_info->swapchainCount, pPresentInfo->swapchainCount); 93785f5e4095d630df9003597a928c86502e3fc83176Tobin Ehlis } 9379c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9380c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis pnext = (std_header *)pnext->pNext; 9381c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 9382c78bb8f84551ddfb3802d18c678500e26e4116cbTobin Ehlis } 93835b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 93843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 93856c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes return VK_ERROR_VALIDATION_FAILED_EXT; 93866c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 93876c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes 93884a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.QueuePresentKHR(queue, pPresentInfo); 93896c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes 93906c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes if (result != VK_ERROR_VALIDATION_FAILED_EXT) { 93916c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes // Semaphore waits occur before error generation, if the call reached 93926c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes // the ICD. (Confirm?) 93936c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes for (uint32_t i = 0; i < pPresentInfo->waitSemaphoreCount; ++i) { 93949a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, pPresentInfo->pWaitSemaphores[i]); 93959867daedbf52debc77d6568162ee21e071699b80Chris Forbes if (pSemaphore) { 93969867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaler.first = VK_NULL_HANDLE; 93976c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes pSemaphore->signaled = false; 93986c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 93996c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 94009867daedbf52debc77d6568162ee21e071699b80Chris Forbes 9401220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) { 9402220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // Note: this is imperfect, in that we can get confused about what 9403220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // did or didn't succeed-- but if the app does that, it's confused 9404220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // itself just as much. 9405220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result; 9406220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 9407cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR) continue; // this present didn't actually happen. 9408220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 9409220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // Mark the image as having been released to the WSI 94109a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]); 9411220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]]; 94129a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 94131facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->acquired = false; 9414220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes } 9415220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 94169867daedbf52debc77d6568162ee21e071699b80Chris Forbes // Note: even though presentation is directed to a queue, there is no 94179867daedbf52debc77d6568162ee21e071699b80Chris Forbes // direct ordering between QP and subsequent work, so QP (and its 94189867daedbf52debc77d6568162ee21e071699b80Chris Forbes // semaphore waits) /never/ participate in any completion proof. 94196c87c6a8acda49a6406192a1b634e9bf060bd6fdChris Forbes } 94201344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 94215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 94225b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 94235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9424c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinskistatic bool PreCallValidateCreateSharedSwapchainsKHR(layer_data *dev_data, uint32_t swapchainCount, 9425c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkSwapchainCreateInfoKHR *pCreateInfos, VkSwapchainKHR *pSwapchains, 9426c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SURFACE_STATE *> &surface_state, 9427c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SWAPCHAIN_NODE *> &old_swapchain_state) { 94280342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski if (pCreateInfos) { 9429ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 94300342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 94319a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis surface_state.push_back(GetSurfaceState(dev_data->instance_data, pCreateInfos[i].surface)); 94329a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis old_swapchain_state.push_back(GetSwapchainNode(dev_data, pCreateInfos[i].oldSwapchain)); 94339ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski std::stringstream func_name; 94349ad55a294cd317a63498d79878e1d5e7d1156c91Mark Lobodzinski func_name << "vkCreateSharedSwapchainsKHR[" << swapchainCount << "]"; 9435bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski if (PreCallValidateCreateSwapchainKHR(dev_data, func_name.str().c_str(), &pCreateInfos[i], surface_state[i], 9436bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski old_swapchain_state[i])) { 9437c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return true; 94380342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 94390342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 94400342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 9441c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return false; 9442c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski} 94430342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski 9444c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinskistatic void PostCallRecordCreateSharedSwapchainsKHR(layer_data *dev_data, VkResult result, uint32_t swapchainCount, 9445c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkSwapchainCreateInfoKHR *pCreateInfos, VkSwapchainKHR *pSwapchains, 9446c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SURFACE_STATE *> &surface_state, 9447c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SWAPCHAIN_NODE *> &old_swapchain_state) { 94480342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski if (VK_SUCCESS == result) { 94490342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 94500342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski auto swapchain_state = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(&pCreateInfos[i], pSwapchains[i])); 945187a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis if (VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR == pCreateInfos[i].presentMode || 945287a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR == pCreateInfos[i].presentMode) { 945387a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis swapchain_state->shared_presentable = true; 945487a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis } 94550342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski surface_state[i]->swapchain = swapchain_state.get(); 945616a1f8f9c4af479b1873e82ff02360817fb658acChris Forbes dev_data->swapchainMap[pSwapchains[i]] = std::move(swapchain_state); 94570342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 94580342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } else { 94590342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 94600342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski surface_state[i]->swapchain = nullptr; 94610342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 94620342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 94630342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski // Spec requires that even if CreateSharedSwapchainKHR fails, oldSwapchain behaves as replaced. 94640342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski for (uint32_t i = 0; i < swapchainCount; i++) { 94650342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski if (old_swapchain_state[i]) { 94660342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski old_swapchain_state[i]->replaced = true; 94670342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 94680342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski surface_state[i]->old_swapchain = old_swapchain_state[i]; 94690342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski } 9470c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return; 9471c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski} 9472c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9473c6cd632d064579a64e61d8704b411d0e4ace7adaMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateSharedSwapchainsKHR(VkDevice device, uint32_t swapchainCount, 9474c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkSwapchainCreateInfoKHR *pCreateInfos, 9475c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchains) { 947656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 9477c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SURFACE_STATE *> surface_state; 9478c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski std::vector<SWAPCHAIN_NODE *> old_swapchain_state; 9479c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9480c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski if (PreCallValidateCreateSharedSwapchainsKHR(dev_data, swapchainCount, pCreateInfos, pSwapchains, surface_state, 9481c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski old_swapchain_state)) { 9482c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski return VK_ERROR_VALIDATION_FAILED_EXT; 9483c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski } 9484c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9485c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski VkResult result = 9486c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski dev_data->dispatch_table.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains); 9487c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski 9488c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski PostCallRecordCreateSharedSwapchainsKHR(dev_data, result, swapchainCount, pCreateInfos, pSwapchains, surface_state, 9489c6cd632d064579a64e61d8704b411d0e4ace7adaMark Lobodzinski old_swapchain_state); 94900342b03ca27e5dcd692e5161af9e0eddda80240eMark Lobodzinski 9491c827a5880dc3fabfc7d1a58bb62798649cab1181Mark Young return result; 9492c827a5880dc3fabfc7d1a58bb62798649cab1181Mark Young} 9493c827a5880dc3fabfc7d1a58bb62798649cab1181Mark Young 949489d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, 949589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) { 949656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 94973251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 94981344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 9499ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9500449670637ef4214b33018f497cf10daeff9dc85bChris Forbes 9501449670637ef4214b33018f497cf10daeff9dc85bChris Forbes if (fence == VK_NULL_HANDLE && semaphore == VK_NULL_HANDLE) { 95023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, 95039b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(device), __LINE__, DRAWSTATE_SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, "DS", 95043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: Semaphore and fence cannot both be VK_NULL_HANDLE. There would be no way " 95053251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "to determine the completion of this operation."); 9506449670637ef4214b33018f497cf10daeff9dc85bChris Forbes } 9507449670637ef4214b33018f497cf10daeff9dc85bChris Forbes 95089a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pSemaphore = GetSemaphoreNode(dev_data, semaphore); 9509f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (pSemaphore && pSemaphore->signaled) { 95103251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, 9511315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis HandleToUint64(semaphore), __LINE__, VALIDATION_ERROR_16400a0c, "DS", 95123251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: Semaphore must not be currently signaled or in a wait state. %s", 9513315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis validation_error_map[VALIDATION_ERROR_16400a0c]); 95145b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9515f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 95169a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto pFence = GetFenceNode(dev_data, fence); 9517f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (pFence) { 95183251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= ValidateFenceForSubmit(dev_data, pFence); 95195b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 95204a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes 95219a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto swapchain_data = GetSwapchainNode(dev_data, swapchain); 9522fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes 9523fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes if (swapchain_data->replaced) { 95243251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 95259b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(swapchain), __LINE__, DRAWSTATE_SWAPCHAIN_REPLACED, "DS", 95263251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: This swapchain has been replaced. The application can still " 95273251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "present any images it has acquired, but cannot acquire any more."); 9528fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes } 9529fc9f0448c3cb6ba4fc018fefe761bb43a1884846Chris Forbes 95309a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(dev_data->instance_data, dev_data->physical_device); 95314a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes if (physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState != UNCALLED) { 95326569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski uint64_t acquired_images = std::count_if(swapchain_data->images.begin(), swapchain_data->images.end(), 95339a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis [=](VkImage image) { return GetImageState(dev_data, image)->acquired; }); 95344a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes if (acquired_images > swapchain_data->images.size() - physical_device_state->surfaceCapabilities.minImageCount) { 95353251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 95366569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 95379b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(swapchain), __LINE__, DRAWSTATE_SWAPCHAIN_TOO_MANY_IMAGES, "DS", 95386569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski "vkAcquireNextImageKHR: Application has already acquired the maximum number of images (0x%" PRIxLEAST64 ")", 95396569ab421f45f905e69fa7345bda4fe5b87e9045Mark Lobodzinski acquired_images); 95404a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes } 95414a5614452104c88cb04390dac882dd94ebdcc3deChris Forbes } 954275269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis 954375269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis if (swapchain_data->images.size() == 0) { 95443251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, 95459b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(swapchain), __LINE__, DRAWSTATE_SWAPCHAIN_IMAGES_NOT_FOUND, "DS", 95463251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkAcquireNextImageKHR: No images found to acquire from. Application probably did not call " 95473251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkGetSwapchainImagesKHR after swapchain creation."); 954875269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis } 954975269fc9e5cc9696ddf3dd28ff201c9b2526dc7aThomas Louis 9550b9e992386a44404152747d66817a733aa127e281Jeremy Hayes lock.unlock(); 95511344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 95523251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 9553f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 95544a0754042cf090e131e9e769d8a3633c228625beChris Forbes VkResult result = dev_data->dispatch_table.AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); 9555f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 9556f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes lock.lock(); 9557f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) { 9558f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (pFence) { 9559f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes pFence->state = FENCE_INFLIGHT; 9560cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski pFence->signaler.first = VK_NULL_HANDLE; // ANI isn't on a queue, so this can't participate in a completion proof. 9561f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes } 9562f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes 9563f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes // A successful call to AcquireNextImageKHR counts as a signal operation on semaphore 9564f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes if (pSemaphore) { 9565f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes pSemaphore->signaled = true; 95669867daedbf52debc77d6568162ee21e071699b80Chris Forbes pSemaphore->signaler.first = VK_NULL_HANDLE; 9567f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes } 9568220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes 9569220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes // Mark the image as acquired. 9570220a9249bd81543e570b3f38c79d9b1e82e0d0dbChris Forbes auto image = swapchain_data->images[*pImageIndex]; 95719a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto image_state = GetImageState(dev_data, image); 95721facd2c91911508b9fb61f54a56269841299f663Tobin Ehlis image_state->acquired = true; 957387a57d8e822316de46ee97f514187331b1f4f09dTobin Ehlis image_state->shared_presentable = swapchain_data->shared_presentable; 95745b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 9575f91af4dfe0646cf509616910a8ec2d72c423ccdaChris Forbes lock.unlock(); 95761344302fce242e654df2fd518b6371a91b8a5c7dTobin Ehlis 95775b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return result; 95785b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 95795b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 9580f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount, 9581f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski VkPhysicalDevice *pPhysicalDevices) { 95823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 958356e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 9584bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis assert(instance_data); 9585219f00ffed576643641976122fa1db8e5fce5dc1Chris Forbes 9586bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS 9587bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis if (NULL == pPhysicalDevices) { 9588bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->vkEnumeratePhysicalDevicesState = QUERY_COUNT; 9589f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } else { 9590bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis if (UNCALLED == instance_data->vkEnumeratePhysicalDevicesState) { 9591bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // Flag warning here. You can call this without having queried the count, but it may not be 9592bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // robust on platforms with multiple physical devices. 95933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 95943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL", 95953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call sequence has vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first " 95963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount."); 9597cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state 9598bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis else if (instance_data->physical_devices_count != *pPhysicalDeviceCount) { 9599bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // Having actual count match count from app is not a requirement, so this can be a warning 96003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 96013251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 96023251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count " 96033251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "supported by this instance is %u.", 96043251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *pPhysicalDeviceCount, instance_data->physical_devices_count); 9605bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 9606bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->vkEnumeratePhysicalDevicesState = QUERY_DETAILS; 9607f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski } 96083251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 9609bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis return VK_ERROR_VALIDATION_FAILED_EXT; 9610bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 9611bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis VkResult result = instance_data->dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); 9612bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis if (NULL == pPhysicalDevices) { 9613bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->physical_devices_count = *pPhysicalDeviceCount; 9614cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } else if (result == VK_SUCCESS) { // Save physical devices 9615bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) { 9616bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis auto &phys_device_state = instance_data->physical_device_map[pPhysicalDevices[i]]; 9617bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis phys_device_state.phys_device = pPhysicalDevices[i]; 9618bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis // Init actual features for each physical device 9619bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features); 9620bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 9621bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis } 9622bfd47e4db53f595683fbe192d73bbda5c56606a6Tobin Ehlis return result; 9623f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski} 9624f83fcc51d156b056966509bfe4d05c9ccb37ce5dMark Lobodzinski 962543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis// Common function to handle validation for GetPhysicalDeviceQueueFamilyProperties & 2KHR version 962643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic bool ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_layer_data *instance_data, 962743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis PHYSICAL_DEVICE_STATE *pd_state, 96285770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t requested_queue_family_property_count, bool qfp_null, 96295770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus const char *caller_name) { 963043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis bool skip = false; 96315770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (!qfp_null) { 96325770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Verify that for each physical device, this command is called first with NULL pQueueFamilyProperties in order to get count 963343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis if (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) { 96345770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg( 96355770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 96369b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pd_state->phys_device), __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL", 96375770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "%s is called with non-NULL pQueueFamilyProperties before obtaining pQueueFamilyPropertyCount. It is recommended " 96385770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "to first call %s with NULL pQueueFamilyProperties in order to obtain the maximal pQueueFamilyPropertyCount.", 96395770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus caller_name, caller_name); 96405770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus // Then verify that pCount that is passed in on second call matches what was returned 96415770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus } else if (pd_state->queue_family_count != requested_queue_family_property_count) { 96425770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus skip |= log_msg( 96435770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 96449b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(pd_state->phys_device), __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 96455770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "%s is called with non-NULL pQueueFamilyProperties and pQueueFamilyPropertyCount value %" PRIu32 96465770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ", but the largest previously returned pQueueFamilyPropertyCount for this physicalDevice is %" PRIu32 96475770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus ". It is recommended to instead receive all the properties by calling %s with pQueueFamilyPropertyCount that was " 96485770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus "previously obtained by calling %s with NULL pQueueFamilyProperties.", 96495770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus caller_name, requested_queue_family_property_count, pd_state->queue_family_count, caller_name, caller_name); 965043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 965143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS; 965243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 96535770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 965443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis return skip; 965543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 965643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 965743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_layer_data *instance_data, 96585770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus PHYSICAL_DEVICE_STATE *pd_state, 96595770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t *pQueueFamilyPropertyCount, 966043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties *pQueueFamilyProperties) { 96615770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, *pQueueFamilyPropertyCount, 96625770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus (nullptr == pQueueFamilyProperties), 966343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis "vkGetPhysicalDeviceQueueFamilyProperties()"); 966443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 966543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 966643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic bool PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_layer_data *instance_data, 966743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis PHYSICAL_DEVICE_STATE *pd_state, 966843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis uint32_t *pQueueFamilyPropertyCount, 966943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 96705770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus return ValidateCommonGetPhysicalDeviceQueueFamilyProperties(instance_data, pd_state, *pQueueFamilyPropertyCount, 96715770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus (nullptr == pQueueFamilyProperties), 967243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis "vkGetPhysicalDeviceQueueFamilyProperties2KHR()"); 967343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 967443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 967543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis// Common function to update state for GetPhysicalDeviceQueueFamilyProperties & 2KHR version 967643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic void StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count, 967743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 967843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis if (!pQueueFamilyProperties) { 96795770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (UNCALLED == pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) 96805770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT; 96815770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->queue_family_count = count; 968243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } else { // Save queue family properties 96835770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS; 96845770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->queue_family_count = std::max(pd_state->queue_family_count, count); 96855770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 96865770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pd_state->queue_family_properties.resize(std::max(static_cast<uint32_t>(pd_state->queue_family_properties.size()), count)); 96875770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus for (uint32_t i = 0; i < count; ++i) { 968843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pd_state->queue_family_properties[i] = pQueueFamilyProperties[i].queueFamilyProperties; 968943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 969043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 969143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 969243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 969343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic void PostCallRecordGetPhysicalDeviceQueueFamilyProperties(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count, 969443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties *pQueueFamilyProperties) { 969543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pqfp = nullptr; 969643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis std::vector<VkQueueFamilyProperties2KHR> qfp; 969743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp.resize(count); 969843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis if (pQueueFamilyProperties) { 969943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis for (uint32_t i = 0; i < count; ++i) { 970043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR; 970143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp[i].pNext = nullptr; 970243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis qfp[i].queueFamilyProperties = pQueueFamilyProperties[i]; 970343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 970443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pqfp = qfp.data(); 970543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis } 970643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(pd_state, count, pqfp); 970743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 970843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 970943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlisstatic void PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(PHYSICAL_DEVICE_STATE *pd_state, uint32_t count, 971043947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 971143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis StateUpdateCommonGetPhysicalDeviceQueueFamilyProperties(pd_state, count, pQueueFamilyProperties); 971243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 971343947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 97145770f8ad21c40b2475201e73e9368a899b6886d0Petr KrausVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, 97155770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus uint32_t *pQueueFamilyPropertyCount, 9716bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkQueueFamilyProperties *pQueueFamilyProperties) { 971756e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 97189a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 971943947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis assert(physical_device_state); 9720ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 97215770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97225770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus bool skip = PreCallValidateGetPhysicalDeviceQueueFamilyProperties(instance_data, physical_device_state, 97235770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pQueueFamilyPropertyCount, pQueueFamilyProperties); 97245770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97255770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.unlock(); 97265770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97275770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (skip) return; 97285770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97295770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, 97305770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus pQueueFamilyProperties); 97315770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97325770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.lock(); 97335770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus PostCallRecordGetPhysicalDeviceQueueFamilyProperties(physical_device_state, *pQueueFamilyPropertyCount, pQueueFamilyProperties); 973443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis} 973543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis 973643947a6175e3e942e04d902f4d18928168e2d0dbTobin EhlisVKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceQueueFamilyProperties2KHR(VkPhysicalDevice physicalDevice, 973743947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis uint32_t *pQueueFamilyPropertyCount, 973843947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis VkQueueFamilyProperties2KHR *pQueueFamilyProperties) { 973956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 97409a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 974143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis assert(physical_device_state); 9742ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 97435770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 974443947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis bool skip = PreCallValidateGetPhysicalDeviceQueueFamilyProperties2KHR(instance_data, physical_device_state, 974543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pQueueFamilyPropertyCount, pQueueFamilyProperties); 97465770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97475770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.unlock(); 97485770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97495770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus if (skip) return; 97505770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 975143947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties2KHR(physicalDevice, pQueueFamilyPropertyCount, 975243947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pQueueFamilyProperties); 97535770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus 97545770f8ad21c40b2475201e73e9368a899b6886d0Petr Kraus lock.lock(); 975543947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis PostCallRecordGetPhysicalDeviceQueueFamilyProperties2KHR(physical_device_state, *pQueueFamilyPropertyCount, 975643947a6175e3e942e04d902f4d18928168e2d0dbTobin Ehlis pQueueFamilyProperties); 9757cd569b3559a7f8dca06012165480a4e6d7e6c492Mark Lobodzinski} 9758cd569b3559a7f8dca06012165480a4e6d7e6c492Mark Lobodzinski 9759bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskitemplate <typename TCreateInfo, typename FPtr> 9760bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinskistatic VkResult CreateSurface(VkInstance instance, TCreateInfo const *pCreateInfo, VkAllocationCallbacks const *pAllocator, 9761bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkSurfaceKHR *pSurface, FPtr fptr) { 976256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 9763747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9764747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes // Call down the call chain: 9765747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes VkResult result = (instance_data->dispatch_table.*fptr)(instance, pCreateInfo, pAllocator, pSurface); 9766747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9767747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes if (result == VK_SUCCESS) { 9768ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9769747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes instance_data->surface_map[*pSurface] = SURFACE_STATE(*pSurface); 9770747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes lock.unlock(); 9771747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 9772747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9773747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return result; 9774747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9775747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9776747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) { 97773251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 977856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 9779ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 97809a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(instance_data, surface); 9781747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9782991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if ((surface_state) && (surface_state->swapchain)) { 9783991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 9784991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(instance), __LINE__, VALIDATION_ERROR_26c009e4, "DS", 9785991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkDestroySurfaceKHR() called before its associated VkSwapchainKHR was destroyed. %s", 9786991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski validation_error_map[VALIDATION_ERROR_26c009e4]); 9787747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 9788991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->surface_map.erase(surface); 9789747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes lock.unlock(); 97903251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (!skip) { 9791747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes instance_data->dispatch_table.DestroySurfaceKHR(instance, surface, pAllocator); 9792747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes } 9793747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9794747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 97956f2ed666809272002a31b3b4f8adf6581cb41819Norbert NopperVKAPI_ATTR VkResult VKAPI_CALL CreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, 97966f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 97976f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateDisplayPlaneSurfaceKHR); 97986f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper} 97996f2ed666809272002a31b3b4f8adf6581cb41819Norbert Nopper 9800747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_ANDROID_KHR 9801747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, 9802747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 9803747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateAndroidSurfaceKHR); 9804747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9805cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_ANDROID_KHR 9806747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9807747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_MIR_KHR 9808747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo, 9809747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 9810747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateMirSurfaceKHR); 9811747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9812f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9813f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceMirPresentationSupportKHR(VkPhysicalDevice physicalDevice, 9814f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, MirConnection *connection) { 9815f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 9816f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 9817f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9818ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9819f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 9820f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9821315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2d2009e2, 9822f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceMirPresentationSupportKHR", "queueFamilyIndex"); 9823f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9824f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 9825f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9826f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 9827f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9828f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 9829f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = 9830f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_data->dispatch_table.GetPhysicalDeviceMirPresentationSupportKHR(physicalDevice, queueFamilyIndex, connection); 9831f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9832f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 9833f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 9834cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_MIR_KHR 9835747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9836747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_WAYLAND_KHR 9837747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, 9838747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 9839a9c6cc532ce0ef61d48d1419a96aae51b0e4c64aTobin Ehlis return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateWaylandSurfaceKHR); 9840747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9841f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9842f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, 9843f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, 9844f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus struct wl_display *display) { 9845f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 9846f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 9847f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9848ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9849f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 9850f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9851315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f000a34, 9852f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceWaylandPresentationSupportKHR", "queueFamilyIndex"); 9853f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9854f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 9855f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9856f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 9857f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9858f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 9859f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = 9860f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_data->dispatch_table.GetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice, queueFamilyIndex, display); 9861f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9862f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 9863f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 9864cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_WAYLAND_KHR 9865747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9866747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_WIN32_KHR 9867747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, 9868747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 9869747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateWin32SurfaceKHR); 9870747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9871f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9872f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, 9873f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex) { 9874f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 9875f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 9876f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9877ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9878f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 9879f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9880315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f200a3a, 9881f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceWin32PresentationSupportKHR", "queueFamilyIndex"); 9882f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9883f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 9884f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9885f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 9886f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9887f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 9888f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = instance_data->dispatch_table.GetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex); 9889f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9890f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 9891f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 9892cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_WIN32_KHR 9893747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9894747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_XCB_KHR 9895747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, 9896747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 9897747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateXcbSurfaceKHR); 9898747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9899f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9900f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, 9901f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, xcb_connection_t *connection, 9902f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus xcb_visualid_t visual_id) { 9903f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 9904f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 9905f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9906ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9907f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 9908f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9909315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f400a40, 9910f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceXcbPresentationSupportKHR", "queueFamilyIndex"); 9911f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9912f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 9913f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9914f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 9915f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9916f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 9917f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = instance_data->dispatch_table.GetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice, queueFamilyIndex, 9918f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus connection, visual_id); 9919f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9920f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 9921f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 9922cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_XCB_KHR 9923747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 9924747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes#ifdef VK_USE_PLATFORM_XLIB_KHR 9925747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, 9926bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { 9927747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateXlibSurfaceKHR); 9928747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes} 9929f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9930f25d461667ca2db55147d2be49f179945edf24dbPetr KrausVKAPI_ATTR VkBool32 VKAPI_CALL GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, 9931f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus uint32_t queueFamilyIndex, Display *dpy, 9932f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VisualID visualID) { 9933f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 9934f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 9935f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9936ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 9937f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 9938f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9939315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2f600a46, 9940f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceXlibPresentationSupportKHR", "queueFamilyIndex"); 9941f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9942f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus lock.unlock(); 9943f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9944f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_FALSE; 9945f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9946f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus // Call down the call chain: 9947f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus VkBool32 result = 9948f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus instance_data->dispatch_table.GetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice, queueFamilyIndex, dpy, visualID); 9949f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 9950f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus return result; 9951f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus} 9952cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski#endif // VK_USE_PLATFORM_XLIB_KHR 9953747ce6dd32eafd93da3dc12a6ffd670e746ae453Chris Forbes 995440921785005eb449ec7c18229f0d84c879708b8aChris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 995540921785005eb449ec7c18229f0d84c879708b8aChris Forbes VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { 995656e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 995740921785005eb449ec7c18229f0d84c879708b8aChris Forbes 9958ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 99599a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 996040921785005eb449ec7c18229f0d84c879708b8aChris Forbes lock.unlock(); 996140921785005eb449ec7c18229f0d84c879708b8aChris Forbes 9962bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 9963bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, pSurfaceCapabilities); 996440921785005eb449ec7c18229f0d84c879708b8aChris Forbes 996540921785005eb449ec7c18229f0d84c879708b8aChris Forbes if (result == VK_SUCCESS) { 996640921785005eb449ec7c18229f0d84c879708b8aChris Forbes physical_device_state->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = QUERY_DETAILS; 996740921785005eb449ec7c18229f0d84c879708b8aChris Forbes physical_device_state->surfaceCapabilities = *pSurfaceCapabilities; 996840921785005eb449ec7c18229f0d84c879708b8aChris Forbes } 996940921785005eb449ec7c18229f0d84c879708b8aChris Forbes 997040921785005eb449ec7c18229f0d84c879708b8aChris Forbes return result; 997140921785005eb449ec7c18229f0d84c879708b8aChris Forbes} 997240921785005eb449ec7c18229f0d84c879708b8aChris Forbes 997335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardtstatic void PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(instance_layer_data *instanceData, 997435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkPhysicalDevice physicalDevice, 997535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { 9976ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 997735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto physicalDeviceState = GetPhysicalDeviceState(instanceData, physicalDevice); 997835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = QUERY_DETAILS; 997935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities = pSurfaceCapabilities->surfaceCapabilities; 998035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 998135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 998235b630211642e709485879a2e8859736f0ab16a0Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, 998335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 998435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2KHR *pSurfaceCapabilities) { 998535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto instanceData = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 998635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 998735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto result = 998835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt instanceData->dispatch_table.GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities); 998935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 999035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (result == VK_SUCCESS) { 999135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt PostCallRecordGetPhysicalDeviceSurfaceCapabilities2KHR(instanceData, physicalDevice, pSurfaceCapabilities); 999235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 999335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 999435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt return result; 999535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 999635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 999735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardtstatic void PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(instance_layer_data *instanceData, 999835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkPhysicalDevice physicalDevice, 999935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 10000ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 1000135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto physicalDeviceState = GetPhysicalDeviceState(instanceData, physicalDevice); 1000235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceCapabilitiesKHRState = QUERY_DETAILS; 1000335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.minImageCount = pSurfaceCapabilities->minImageCount; 1000435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.maxImageCount = pSurfaceCapabilities->maxImageCount; 1000535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.currentExtent = pSurfaceCapabilities->currentExtent; 1000635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.minImageExtent = pSurfaceCapabilities->minImageExtent; 1000735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.maxImageExtent = pSurfaceCapabilities->maxImageExtent; 1000835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.maxImageArrayLayers = pSurfaceCapabilities->maxImageArrayLayers; 1000935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.supportedTransforms = pSurfaceCapabilities->supportedTransforms; 1001035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.currentTransform = pSurfaceCapabilities->currentTransform; 1001135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.supportedCompositeAlpha = pSurfaceCapabilities->supportedCompositeAlpha; 1001235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surfaceCapabilities.supportedUsageFlags = pSurfaceCapabilities->supportedUsageFlags; 1001335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1001435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1001535b630211642e709485879a2e8859736f0ab16a0Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 1001635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceCapabilities2EXT *pSurfaceCapabilities) { 1001735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto instanceData = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 1001835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1001935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto result = 1002035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt instanceData->dispatch_table.GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities); 1002135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1002235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (result == VK_SUCCESS) { 1002335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt PostCallRecordGetPhysicalDeviceSurfaceCapabilities2EXT(instanceData, physicalDevice, pSurfaceCapabilities); 1002435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1002535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1002635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt return result; 1002735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1002835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 10029418a8711f3301f3027a900bb45daaf0892f4e644Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, 10030418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes VkSurfaceKHR surface, VkBool32 *pSupported) { 10031f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus bool skip = false; 1003256e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10033f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10034ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10035f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus const auto pd_state = GetPhysicalDeviceState(instance_data, physicalDevice); 100369a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto surface_state = GetSurfaceState(instance_data, surface); 10037f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10038315b15c3d74eb1df11b992c2b9922cf98e939eb8Tobin Ehlis skip |= ValidatePhysicalDeviceQueueFamily(instance_data, pd_state, queueFamilyIndex, VALIDATION_ERROR_2ee009ea, 10039f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus "vkGetPhysicalDeviceSurfaceSupportKHR", "queueFamilyIndex"); 10040f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10041418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes lock.unlock(); 10042418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 10043f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 10044f25d461667ca2db55147d2be49f179945edf24dbPetr Kraus 10045bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = 10046bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->dispatch_table.GetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, pSupported); 10047418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 10048418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes if (result == VK_SUCCESS) { 100490bbc015828bdb99e85e6731ce92428557902701fPetr Kraus surface_state->gpu_queue_support[{physicalDevice, queueFamilyIndex}] = (*pSupported == VK_TRUE); 10050418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes } 10051418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 10052418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes return result; 10053418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes} 10054418a8711f3301f3027a900bb45daaf0892f4e644Chris Forbes 100559e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 100569e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes uint32_t *pPresentModeCount, 100579e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes VkPresentModeKHR *pPresentModes) { 100583251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1005956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10060ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 100619e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes // TODO: this isn't quite right. available modes may differ by surface AND physical device. 100629a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10063bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &call_state = physical_device_state->vkGetPhysicalDeviceSurfacePresentModesKHRState; 100649e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 100659e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (pPresentModes) { 100669e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes // Compare the preliminary value of *pPresentModeCount with the value this time: 10067bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto prev_mode_count = (uint32_t)physical_device_state->present_modes.size(); 100689e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes switch (call_state) { 10069cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case UNCALLED: 100703251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 10071bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 100729b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(physicalDevice), __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 10073cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfacePresentModesKHR() called with non-NULL pPresentModeCount; but no prior positive " 10074cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "value has been seen for pPresentModeCount."); 10075cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 10076cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 10077cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // both query count and query details 10078cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (*pPresentModeCount != prev_mode_count) { 100793251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 100809b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice), __LINE__, 100819b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DEVLIMITS_COUNT_MISMATCH, "DL", 100823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "vkGetPhysicalDeviceSurfacePresentModesKHR() called with *pPresentModeCount (%u) that " 100833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "differs from the value " 100843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "(%u) that was returned when pPresentModes was NULL.", 100853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *pPresentModeCount, prev_mode_count); 10086cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 10087cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 100889e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 100899e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 100909e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes lock.unlock(); 100919e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 100923251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 100939e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 10094bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto result = instance_data->dispatch_table.GetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, pPresentModeCount, 10095bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski pPresentModes); 100969e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 100979e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 100989e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes lock.lock(); 100999e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 101009e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (*pPresentModeCount) { 10101cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_COUNT) call_state = QUERY_COUNT; 101029e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (*pPresentModeCount > physical_device_state->present_modes.size()) 101039e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes physical_device_state->present_modes.resize(*pPresentModeCount); 101049e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 101059e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes if (pPresentModes) { 10106cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_DETAILS) call_state = QUERY_DETAILS; 101079e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes for (uint32_t i = 0; i < *pPresentModeCount; i++) { 101089e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes physical_device_state->present_modes[i] = pPresentModes[i]; 101099e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 101109e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 101115faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 101125faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101135faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes return result; 101145faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes} 101155faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101165faa662f6859b01c72d79027abde363d5f10dcd7Chris ForbesVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, 101175faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes uint32_t *pSurfaceFormatCount, 101185faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes VkSurfaceFormatKHR *pSurfaceFormats) { 101193251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 1012056e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis auto instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10121ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 101229a9a0db2a973034d4286b6d4c62a46beb7641791Tobin Ehlis auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 10123bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto &call_state = physical_device_state->vkGetPhysicalDeviceSurfaceFormatsKHRState; 101245faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101255faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pSurfaceFormats) { 10126bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski auto prev_format_count = (uint32_t)physical_device_state->surface_formats.size(); 101275faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101285faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes switch (call_state) { 10129cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski case UNCALLED: 10130cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // Since we haven't recorded a preliminary value of *pSurfaceFormatCount, that likely means that the application 10131cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // didn't 10132cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski // previously call this function with a NULL value of pSurfaceFormats: 101333251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 10134bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 101359b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(physicalDevice), __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL", 10136cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfaceFormatsKHR() called with non-NULL pSurfaceFormatCount; but no prior positive " 10137cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "value has been seen for pSurfaceFormats."); 10138cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 10139cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski default: 10140cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (prev_format_count != *pSurfaceFormatCount) { 101413251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg( 10142cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 101439b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, HandleToUint64(physicalDevice), __LINE__, 10144cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski DEVLIMITS_COUNT_MISMATCH, "DL", 10145cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "vkGetPhysicalDeviceSurfaceFormatsKHR() called with non-NULL pSurfaceFormatCount, and with pSurfaceFormats " 10146cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "set " 10147cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "to " 10148cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski "a value (%u) that is greater than the value (%u) that was returned when pSurfaceFormatCount was NULL.", 10149cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski *pSurfaceFormatCount, prev_format_count); 10150cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski } 10151cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski break; 101529e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 101539e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes } 101545faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes lock.unlock(); 101555faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101563251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) return VK_ERROR_VALIDATION_FAILED_EXT; 101579e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 101585faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes // Call down the call chain: 101595faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes auto result = instance_data->dispatch_table.GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, pSurfaceFormatCount, 101605faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes pSurfaceFormats); 101615faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101625faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 101635faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes lock.lock(); 101645faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes 101655faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (*pSurfaceFormatCount) { 10166cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_COUNT) call_state = QUERY_COUNT; 101675faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (*pSurfaceFormatCount > physical_device_state->surface_formats.size()) 101685faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes physical_device_state->surface_formats.resize(*pSurfaceFormatCount); 101695faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 101705faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes if (pSurfaceFormats) { 10171cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (call_state < QUERY_DETAILS) call_state = QUERY_DETAILS; 101725faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) { 101735faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes physical_device_state->surface_formats[i] = pSurfaceFormats[i]; 101745faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 101755faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 101765faa662f6859b01c72d79027abde363d5f10dcd7Chris Forbes } 101779e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes return result; 101789e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes} 101799e8e286e0ca0c7cd911c3e7ba3ddd1aceb29cbe9Chris Forbes 1018035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardtstatic void PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(instance_layer_data *instanceData, VkPhysicalDevice physicalDevice, 1018135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt uint32_t *pSurfaceFormatCount, VkSurfaceFormat2KHR *pSurfaceFormats) { 10182ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 1018335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto physicalDeviceState = GetPhysicalDeviceState(instanceData, physicalDevice); 1018435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (*pSurfaceFormatCount) { 1018535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState < QUERY_COUNT) { 1018635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState = QUERY_COUNT; 1018735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1018835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (*pSurfaceFormatCount > physicalDeviceState->surface_formats.size()) 1018935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surface_formats.resize(*pSurfaceFormatCount); 1019035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1019135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (pSurfaceFormats) { 1019235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState < QUERY_DETAILS) { 1019335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->vkGetPhysicalDeviceSurfaceFormatsKHRState = QUERY_DETAILS; 1019435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1019535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt for (uint32_t i = 0; i < *pSurfaceFormatCount; i++) { 1019635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt physicalDeviceState->surface_formats[i] = pSurfaceFormats[i].surfaceFormat; 1019735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1019835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1019935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1020035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 1020135b630211642e709485879a2e8859736f0ab16a0Mike SchuchardtVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, 1020235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, 1020335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt uint32_t *pSurfaceFormatCount, 1020435b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt VkSurfaceFormat2KHR *pSurfaceFormats) { 1020535b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto instanceData = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 1020635b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt auto result = instanceData->dispatch_table.GetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, 1020735b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt pSurfaceFormatCount, pSurfaceFormats); 1020835b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 1020935b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt PostCallRecordGetPhysicalDeviceSurfaceFormats2KHR(instanceData, physicalDevice, pSurfaceFormatCount, pSurfaceFormats); 1021035b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt } 1021135b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt return result; 1021235b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt} 1021335b630211642e709485879a2e8859736f0ab16a0Mike Schuchardt 10214bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance, 10215bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 10216bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const VkAllocationCallbacks *pAllocator, 10217bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDebugReportCallbackEXT *pMsgCallback) { 1021856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 102199172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes VkResult res = instance_data->dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback); 102205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis if (VK_SUCCESS == res) { 10221ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 102228860b85a52096f9f9b28616bc37feed505497a54Chris Forbes res = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback); 102235b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis } 102245b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis return res; 102255b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 102265b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10227bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, 1022889d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu const VkAllocationCallbacks *pAllocator) { 1022956e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 102309172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator); 10231ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 102328860b85a52096f9f9b28616bc37feed505497a54Chris Forbes layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator); 102335b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 102345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10235bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, 10236bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, 10237bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski int32_t msgCode, const char *pLayerPrefix, const char *pMsg) { 1023856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 102399172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes instance_data->dispatch_table.DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg); 102405b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 102415b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 10242bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) { 10243a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 10244a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu} 10245a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10246bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 10247bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkLayerProperties *pProperties) { 10248a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return util_GetLayerProperties(1, &global_layer, pCount, pProperties); 10249a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu} 10250a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10251bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, 10252bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkExtensionProperties *pProperties) { 10253a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) 10254a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return util_GetExtensionProperties(1, instance_extensions, pCount, pProperties); 10255a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10256a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return VK_ERROR_LAYER_NOT_PRESENT; 10257a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu} 10258a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu 10259bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, 10260bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski uint32_t *pCount, VkExtensionProperties *pProperties) { 10261cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (pLayerName && !strcmp(pLayerName, global_layer.layerName)) return util_GetExtensionProperties(0, NULL, pCount, pProperties); 10262a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu 10263a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu assert(physicalDevice); 10264a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu 1026556e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 102669172b640a0ae6a92f24ad0609d92b2c228cde89cChris Forbes return instance_data->dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties); 1026708939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 1026808939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 10269582b6ed09649188d55ed3b6237352caf9f3384a9Mike WeiblenVKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDeviceGroupsKHX( 10270582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupPropertiesKHX *pPhysicalDeviceGroupProperties) { 102713251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski bool skip = false; 10272582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 10273582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen 10274582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (instance_data) { 10275582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // For this instance, flag when EnumeratePhysicalDeviceGroupsKHX goes to QUERY_COUNT and then QUERY_DETAILS. 10276582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (NULL == pPhysicalDeviceGroupProperties) { 10277582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->vkEnumeratePhysicalDeviceGroupsState = QUERY_COUNT; 10278582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } else { 10279582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (UNCALLED == instance_data->vkEnumeratePhysicalDeviceGroupsState) { 10280582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // Flag warning here. You can call this without having queried the count, but it may not be 10281582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // robust on platforms with multiple physical devices. 102823251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 102833251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL", 102843251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call sequence has vkEnumeratePhysicalDeviceGroupsKHX() w/ non-NULL " 102853251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "pPhysicalDeviceGroupProperties. You should first " 102863251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "call vkEnumeratePhysicalDeviceGroupsKHX() w/ NULL pPhysicalDeviceGroupProperties to query " 102873251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "pPhysicalDeviceGroupCount."); 10288582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state 10289582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen else if (instance_data->physical_device_groups_count != *pPhysicalDeviceGroupCount) { 10290582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // Having actual count match count from app is not a requirement, so this can be a warning 102913251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski skip |= 10292582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, 102933251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL", 102943251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "Call to vkEnumeratePhysicalDeviceGroupsKHX() w/ pPhysicalDeviceGroupCount value %u, but actual count " 102953251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski "supported by this instance is %u.", 102963251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski *pPhysicalDeviceGroupCount, instance_data->physical_device_groups_count); 10297582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10298582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->vkEnumeratePhysicalDeviceGroupsState = QUERY_DETAILS; 10299582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 103003251dd855490066e66a663dece5afee8ca0b95cdMark Lobodzinski if (skip) { 10301582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen return VK_ERROR_VALIDATION_FAILED_EXT; 10302582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10303582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen VkResult result = instance_data->dispatch_table.EnumeratePhysicalDeviceGroupsKHX(instance, pPhysicalDeviceGroupCount, 10304582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen pPhysicalDeviceGroupProperties); 10305582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen if (NULL == pPhysicalDeviceGroupProperties) { 10306582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->physical_device_groups_count = *pPhysicalDeviceGroupCount; 10307582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } else if (result == VK_SUCCESS) { // Save physical devices 10308582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) { 10309582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen for (uint32_t j = 0; j < pPhysicalDeviceGroupProperties[i].physicalDeviceCount; j++) { 10310582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen VkPhysicalDevice cur_phys_dev = pPhysicalDeviceGroupProperties[i].physicalDevices[j]; 10311582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen auto &phys_device_state = instance_data->physical_device_map[cur_phys_dev]; 10312582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen phys_device_state.phys_device = cur_phys_dev; 10313582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen // Init actual features for each physical device 10314582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen instance_data->dispatch_table.GetPhysicalDeviceFeatures(cur_phys_dev, &phys_device_state.features); 10315582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10316582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10317582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10318582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen return result; 10319582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } else { 10320582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__, 103219b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus DEVLIMITS_INVALID_INSTANCE, "DL", 103229b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus "Invalid instance (0x%" PRIxLEAST64 ") passed into vkEnumeratePhysicalDeviceGroupsKHX().", 103239b6bedb9061a3ab94386ee9293da1dd43267a680Petr Kraus HandleToUint64(instance)); 10324582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen } 10325582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen return VK_ERROR_VALIDATION_FAILED_EXT; 10326582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen} 10327582b6ed09649188d55ed3b6237352caf9f3384a9Mike Weiblen 103286246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL CreateDescriptorUpdateTemplateKHR(VkDevice device, 103296246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo, 103306246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const VkAllocationCallbacks *pAllocator, 103316246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate) { 103326246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 10333a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski VkResult result = 10334a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski dev_data->dispatch_table.CreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate); 103356246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski if (VK_SUCCESS == result) { 10336ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 103376246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski // Shadow template createInfo for later updates 10338a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski safe_VkDescriptorUpdateTemplateCreateInfoKHR *local_create_info = 10339a538cd4fff983b172362b0bba58f984124481a1cMark Lobodzinski new safe_VkDescriptorUpdateTemplateCreateInfoKHR(pCreateInfo); 103406246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski std::unique_ptr<TEMPLATE_STATE> template_state(new TEMPLATE_STATE(*pDescriptorUpdateTemplate, local_create_info)); 103416246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->desc_template_map[*pDescriptorUpdateTemplate] = std::move(template_state); 103426246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski } 103436246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski return result; 103446246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 103456246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 103466246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR void VKAPI_CALL DestroyDescriptorUpdateTemplateKHR(VkDevice device, 103476246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 103486246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const VkAllocationCallbacks *pAllocator) { 103496246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 10350ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 103516246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->desc_template_map.erase(descriptorUpdateTemplate); 103526246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski lock.unlock(); 103536246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->dispatch_table.DestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator); 103546246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 103556246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 1035625f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski// PostCallRecord* handles recording state updates following call down chain to UpdateDescriptorSetsWithTemplate() 1035725f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinskistatic void PostCallRecordUpdateDescriptorSetWithTemplateKHR(layer_data *device_data, VkDescriptorSet descriptorSet, 1035825f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 1035925f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski const void *pData) { 1036067fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski auto const template_map_entry = device_data->desc_template_map.find(descriptorUpdateTemplate); 1036167fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski if (template_map_entry == device_data->desc_template_map.end()) { 1036267fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski assert(0); 1036367fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski } 1036467fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski 1036525f3712aed1cebdcb7c92eb25c5f1cc6e5986ac4Mark Lobodzinski cvdescriptorset::PerformUpdateDescriptorSetsWithTemplateKHR(device_data, descriptorSet, template_map_entry->second, pData); 1036667fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski} 1036767fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski 103686246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR void VKAPI_CALL UpdateDescriptorSetWithTemplateKHR(VkDevice device, VkDescriptorSet descriptorSet, 103696246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 103706246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski const void *pData) { 1037167fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 1037267fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski device_data->dispatch_table.UpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData); 1037367fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski 1037467fe2a610e6fc19f5bf11df4b663cef1f6c4e9caMark Lobodzinski PostCallRecordUpdateDescriptorSetWithTemplateKHR(device_data, descriptorSet, descriptorUpdateTemplate, pData); 103756246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 103766246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 103776246f8feba03ddc787c31b3daa6a50d4ef01024fMark LobodzinskiVKAPI_ATTR void VKAPI_CALL CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer, 103786246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, 103796246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski VkPipelineLayout layout, uint32_t set, const void *pData) { 103806246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 103816246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski dev_data->dispatch_table.CmdPushDescriptorSetWithTemplateKHR(commandBuffer, descriptorUpdateTemplate, layout, set, pData); 103826246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski} 103836246f8feba03ddc787c31b3daa6a50d4ef01024fMark Lobodzinski 10384991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic void PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(instance_layer_data *instanceData, 10385991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, 10386991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkDisplayPlanePropertiesKHR *pProperties) { 10387ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes unique_lock_t lock(global_lock); 10388991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto physical_device_state = GetPhysicalDeviceState(instanceData, physicalDevice); 10389991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10390991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (*pPropertyCount) { 103917c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes if (physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState < QUERY_COUNT) { 103927c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState = QUERY_COUNT; 10393991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10394991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski physical_device_state->display_plane_property_count = *pPropertyCount; 10395991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10396991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (pProperties) { 103977c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes if (physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState < QUERY_DETAILS) { 103987c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState = QUERY_DETAILS; 10399991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10400991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10401991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10402991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10403991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, 10404991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkDisplayPlanePropertiesKHR *pProperties) { 10405991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_SUCCESS; 10406991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10407991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10408991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = instance_data->dispatch_table.GetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, pPropertyCount, pProperties); 10409991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10410991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (result == VK_SUCCESS || result == VK_INCOMPLETE) { 10411991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski PostCallRecordGetPhysicalDeviceDisplayPlanePropertiesKHR(instance_data, physicalDevice, pPropertyCount, pProperties); 10412991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10413991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10414991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return result; 10415991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10416991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10417991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool ValidateGetPhysicalDeviceDisplayPlanePropertiesKHRQuery(instance_layer_data *instance_data, 10418991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkPhysicalDevice physicalDevice, uint32_t planeIndex, 10419991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski const char *api_name) { 10420991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 10421991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski auto physical_device_state = GetPhysicalDeviceState(instance_data, physicalDevice); 104227c9b2aea1e047762ea9cff97ddd1fd33b5efc71dChris Forbes if (physical_device_state->vkGetPhysicalDeviceDisplayPlanePropertiesKHRState == UNCALLED) { 10423991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg( 10424991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 10425991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(physicalDevice), __LINE__, SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY, "DL", 10426991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "Potential problem with calling %s() without first querying vkGetPhysicalDeviceDisplayPlanePropertiesKHR.", api_name); 10427991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } else { 10428991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (planeIndex >= physical_device_state->display_plane_property_count) { 10429991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= log_msg( 10430991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 10431991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski HandleToUint64(physicalDevice), __LINE__, VALIDATION_ERROR_29c009c2, "DL", 10432991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "%s(): planeIndex must be in the range [0, %d] that was returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR. " 10433991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "Do you have the plane index hardcoded? %s", 10434991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski api_name, physical_device_state->display_plane_property_count - 1, validation_error_map[VALIDATION_ERROR_29c009c2]); 10435991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10436991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10437991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 10438991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10439991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10440991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool PreCallValidateGetDisplayPlaneSupportedDisplaysKHR(instance_layer_data *instance_data, VkPhysicalDevice physicalDevice, 10441991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t planeIndex) { 10442991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 10443ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 10444991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= ValidateGetPhysicalDeviceDisplayPlanePropertiesKHRQuery(instance_data, physicalDevice, planeIndex, 10445991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetDisplayPlaneSupportedDisplaysKHR"); 10446991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 10447991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10448991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10449991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, 10450991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) { 10451991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 10452991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10453991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = PreCallValidateGetDisplayPlaneSupportedDisplaysKHR(instance_data, physicalDevice, planeIndex); 10454991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (!skip) { 10455991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = 10456991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_data->dispatch_table.GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays); 10457991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10458991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return result; 10459991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10460991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10461991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinskistatic bool PreCallValidateGetDisplayPlaneCapabilitiesKHR(instance_layer_data *instance_data, VkPhysicalDevice physicalDevice, 10462991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t planeIndex) { 10463991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = false; 10464ae7cdbc74057799801bb1d9a8203e38f75429a25Chris Forbes lock_guard_t lock(global_lock); 10465991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski skip |= ValidateGetPhysicalDeviceDisplayPlanePropertiesKHRQuery(instance_data, physicalDevice, planeIndex, 10466991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski "vkGetDisplayPlaneCapabilitiesKHR"); 10467991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return skip; 10468991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10469991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10470991f2555bc4f571e30b584937c7959805dff67c6Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, 10471991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR *pCapabilities) { 10472991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski VkResult result = VK_ERROR_VALIDATION_FAILED_EXT; 10473991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(physicalDevice), instance_layer_data_map); 10474991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski bool skip = PreCallValidateGetDisplayPlaneCapabilitiesKHR(instance_data, physicalDevice, planeIndex); 10475991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10476991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski if (!skip) { 10477991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski result = instance_data->dispatch_table.GetDisplayPlaneCapabilitiesKHR(physicalDevice, mode, planeIndex, pCapabilities); 10478991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski } 10479991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 10480991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski return result; 10481991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski} 10482991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski 104836dd9a6bc380bc606441fb036974f0ddadff4d0c8Mark LobodzinskiVKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) { 104841f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour std::unique_lock<std::mutex> lock(global_lock); 104851f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 104861f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour if (pNameInfo->pObjectName) { 104871f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->report_data->debugObjectNameMap->insert( 104881f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour std::make_pair<uint64_t, std::string>((uint64_t &&)pNameInfo->object, pNameInfo->pObjectName)); 104891f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour } else { 104901f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->report_data->debugObjectNameMap->erase(pNameInfo->object); 104911f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour } 104921f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour lock.unlock(); 104931f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour VkResult result = device_data->dispatch_table.DebugMarkerSetObjectNameEXT(device, pNameInfo); 104941f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour return result; 104951f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 104961f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 104971f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) { 104981f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 104991f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour VkResult result = device_data->dispatch_table.DebugMarkerSetObjectTagEXT(device, pTagInfo); 105001f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour return result; 105011f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 105021f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 105031f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) { 105041f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 105051f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->dispatch_table.CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo); 105061f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 105071f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 105081f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR void VKAPI_CALL CmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) { 105091f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 105101f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->dispatch_table.CmdDebugMarkerEndEXT(commandBuffer); 105111f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 105121f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 105131f53907e108555555ac7cc8e0daf639279ca67d4Tony BarbourVKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) { 105141f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour layer_data *device_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map); 105151f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour device_data->dispatch_table.CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo); 105161f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour} 105171f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour 105183616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName); 105193616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName); 105203616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName); 105213616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski 105223616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski// Map of all APIs to be intercepted by this layer 105233616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinskistatic const std::unordered_map<std::string, void*> name_to_funcptr_map = { 105243616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetInstanceProcAddr", (void*)GetInstanceProcAddr}, 105253616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vk_layerGetPhysicalDeviceProcAddr", (void*)GetPhysicalDeviceProcAddr}, 105263616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetDeviceProcAddr", (void*)GetDeviceProcAddr}, 105273616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateInstance", (void*)CreateInstance}, 105283616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDevice", (void*)CreateDevice}, 105293616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumeratePhysicalDevices", (void*)EnumeratePhysicalDevices}, 105303616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceQueueFamilyProperties", (void*)GetPhysicalDeviceQueueFamilyProperties}, 105313616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyInstance", (void*)DestroyInstance}, 105323616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateInstanceLayerProperties", (void*)EnumerateInstanceLayerProperties}, 105333616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateDeviceLayerProperties", (void*)EnumerateDeviceLayerProperties}, 105343616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateInstanceExtensionProperties", (void*)EnumerateInstanceExtensionProperties}, 105353616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumerateDeviceExtensionProperties", (void*)EnumerateDeviceExtensionProperties}, 105363616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDescriptorUpdateTemplateKHR", (void*)CreateDescriptorUpdateTemplateKHR}, 105373616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDescriptorUpdateTemplateKHR", (void*)DestroyDescriptorUpdateTemplateKHR}, 105383616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkUpdateDescriptorSetWithTemplateKHR", (void*)UpdateDescriptorSetWithTemplateKHR}, 105393616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdPushDescriptorSetWithTemplateKHR", (void*)CmdPushDescriptorSetWithTemplateKHR}, 105403616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateSwapchainKHR", (void*)CreateSwapchainKHR}, 105413616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySwapchainKHR", (void*)DestroySwapchainKHR}, 105423616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetSwapchainImagesKHR", (void*)GetSwapchainImagesKHR}, 105433616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAcquireNextImageKHR", (void*)AcquireNextImageKHR}, 105443616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueuePresentKHR", (void*)QueuePresentKHR}, 105453616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueueSubmit", (void*)QueueSubmit}, 105463616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkWaitForFences", (void*)WaitForFences}, 105473616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetFenceStatus", (void*)GetFenceStatus}, 105483616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueueWaitIdle", (void*)QueueWaitIdle}, 105493616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDeviceWaitIdle", (void*)DeviceWaitIdle}, 105503616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetDeviceQueue", (void*)GetDeviceQueue}, 105513616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDevice", (void*)DestroyDevice}, 105523616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyFence", (void*)DestroyFence}, 105533616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetFences", (void*)ResetFences}, 105543616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySemaphore", (void*)DestroySemaphore}, 105553616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyEvent", (void*)DestroyEvent}, 105563616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyQueryPool", (void*)DestroyQueryPool}, 105573616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyBuffer", (void*)DestroyBuffer}, 105583616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyBufferView", (void*)DestroyBufferView}, 105593616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyImage", (void*)DestroyImage}, 105603616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyImageView", (void*)DestroyImageView}, 105613616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyShaderModule", (void*)DestroyShaderModule}, 105623616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyPipeline", (void*)DestroyPipeline}, 105633616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyPipelineLayout", (void*)DestroyPipelineLayout}, 105643616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySampler", (void*)DestroySampler}, 105653616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDescriptorSetLayout", (void*)DestroyDescriptorSetLayout}, 105663616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDescriptorPool", (void*)DestroyDescriptorPool}, 105673616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyFramebuffer", (void*)DestroyFramebuffer}, 105683616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyRenderPass", (void*)DestroyRenderPass}, 105693616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateBuffer", (void*)CreateBuffer}, 105703616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateBufferView", (void*)CreateBufferView}, 105713616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateImage", (void*)CreateImage}, 105723616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateImageView", (void*)CreateImageView}, 105733616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateFence", (void*)CreateFence}, 105743616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreatePipelineCache", (void*)CreatePipelineCache}, 105753616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyPipelineCache", (void*)DestroyPipelineCache}, 105763616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPipelineCacheData", (void*)GetPipelineCacheData}, 105773616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkMergePipelineCaches", (void*)MergePipelineCaches}, 105783616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateGraphicsPipelines", (void*)CreateGraphicsPipelines}, 105793616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateComputePipelines", (void*)CreateComputePipelines}, 105803616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateSampler", (void*)CreateSampler}, 105813616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDescriptorSetLayout", (void*)CreateDescriptorSetLayout}, 105823616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreatePipelineLayout", (void*)CreatePipelineLayout}, 105833616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDescriptorPool", (void*)CreateDescriptorPool}, 105843616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetDescriptorPool", (void*)ResetDescriptorPool}, 105853616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAllocateDescriptorSets", (void*)AllocateDescriptorSets}, 105863616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFreeDescriptorSets", (void*)FreeDescriptorSets}, 105873616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkUpdateDescriptorSets", (void*)UpdateDescriptorSets}, 105883616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateCommandPool", (void*)CreateCommandPool}, 105893616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyCommandPool", (void*)DestroyCommandPool}, 105903616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetCommandPool", (void*)ResetCommandPool}, 105913616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateQueryPool", (void*)CreateQueryPool}, 105923616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAllocateCommandBuffers", (void*)AllocateCommandBuffers}, 105933616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFreeCommandBuffers", (void*)FreeCommandBuffers}, 105943616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkBeginCommandBuffer", (void*)BeginCommandBuffer}, 105953616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEndCommandBuffer", (void*)EndCommandBuffer}, 105963616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkResetCommandBuffer", (void*)ResetCommandBuffer}, 105973616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindPipeline", (void*)CmdBindPipeline}, 105983616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetViewport", (void*)CmdSetViewport}, 105993616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetScissor", (void*)CmdSetScissor}, 106003616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetLineWidth", (void*)CmdSetLineWidth}, 106013616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetDepthBias", (void*)CmdSetDepthBias}, 106023616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetBlendConstants", (void*)CmdSetBlendConstants}, 106033616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetDepthBounds", (void*)CmdSetDepthBounds}, 106043616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetStencilCompareMask", (void*)CmdSetStencilCompareMask}, 106053616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetStencilWriteMask", (void*)CmdSetStencilWriteMask}, 106063616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetStencilReference", (void*)CmdSetStencilReference}, 106073616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindDescriptorSets", (void*)CmdBindDescriptorSets}, 106083616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindVertexBuffers", (void*)CmdBindVertexBuffers}, 106093616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBindIndexBuffer", (void*)CmdBindIndexBuffer}, 106103616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDraw", (void*)CmdDraw}, 106113616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDrawIndexed", (void*)CmdDrawIndexed}, 106123616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDrawIndirect", (void*)CmdDrawIndirect}, 106133616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDrawIndexedIndirect", (void*)CmdDrawIndexedIndirect}, 106143616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDispatch", (void*)CmdDispatch}, 106153616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdDispatchIndirect", (void*)CmdDispatchIndirect}, 106163616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyBuffer", (void*)CmdCopyBuffer}, 106173616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyImage", (void*)CmdCopyImage}, 106183616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBlitImage", (void*)CmdBlitImage}, 106193616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyBufferToImage", (void*)CmdCopyBufferToImage}, 106203616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyImageToBuffer", (void*)CmdCopyImageToBuffer}, 106213616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdUpdateBuffer", (void*)CmdUpdateBuffer}, 106223616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdFillBuffer", (void*)CmdFillBuffer}, 106233616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdClearColorImage", (void*)CmdClearColorImage}, 106243616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdClearDepthStencilImage", (void*)CmdClearDepthStencilImage}, 106253616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdClearAttachments", (void*)CmdClearAttachments}, 106263616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdResolveImage", (void*)CmdResolveImage}, 106273616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetImageSubresourceLayout", (void*)GetImageSubresourceLayout}, 106283616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdSetEvent", (void*)CmdSetEvent}, 106293616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdResetEvent", (void*)CmdResetEvent}, 106303616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdWaitEvents", (void*)CmdWaitEvents}, 106313616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdPipelineBarrier", (void*)CmdPipelineBarrier}, 106323616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBeginQuery", (void*)CmdBeginQuery}, 106333616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdEndQuery", (void*)CmdEndQuery}, 106343616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdResetQueryPool", (void*)CmdResetQueryPool}, 106353616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdCopyQueryPoolResults", (void*)CmdCopyQueryPoolResults}, 106363616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdPushConstants", (void*)CmdPushConstants}, 106373616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdWriteTimestamp", (void*)CmdWriteTimestamp}, 106383616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateFramebuffer", (void*)CreateFramebuffer}, 106393616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateShaderModule", (void*)CreateShaderModule}, 106403616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateRenderPass", (void*)CreateRenderPass}, 106413616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdBeginRenderPass", (void*)CmdBeginRenderPass}, 106423616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdNextSubpass", (void*)CmdNextSubpass}, 106433616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdEndRenderPass", (void*)CmdEndRenderPass}, 106443616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCmdExecuteCommands", (void*)CmdExecuteCommands}, 106451f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkCmdDebugMarkerBeginEXT", (void*)CmdDebugMarkerBeginEXT}, 106461f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkCmdDebugMarkerEndEXT", (void*)CmdDebugMarkerEndEXT}, 106471f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkCmdDebugMarkerInsertEXT", (void*)CmdDebugMarkerInsertEXT}, 106481f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkDebugMarkerSetObjectNameEXT", (void*)DebugMarkerSetObjectNameEXT}, 106491f53907e108555555ac7cc8e0daf639279ca67d4Tony Barbour {"vkDebugMarkerSetObjectTagEXT", (void*)DebugMarkerSetObjectTagEXT}, 106503616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkSetEvent", (void*)SetEvent}, 106513616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkMapMemory", (void*)MapMemory}, 106523616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkUnmapMemory", (void*)UnmapMemory}, 106533616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFlushMappedMemoryRanges", (void*)FlushMappedMemoryRanges}, 106543616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkInvalidateMappedMemoryRanges", (void*)InvalidateMappedMemoryRanges}, 106553616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkAllocateMemory", (void*)AllocateMemory}, 106563616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkFreeMemory", (void*)FreeMemory}, 106573616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkBindBufferMemory", (void*)BindBufferMemory}, 106583616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetBufferMemoryRequirements", (void*)GetBufferMemoryRequirements}, 106593616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetImageMemoryRequirements", (void*)GetImageMemoryRequirements}, 106603616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetQueryPoolResults", (void*)GetQueryPoolResults}, 106613616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkBindImageMemory", (void*)BindImageMemory}, 106623616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkQueueBindSparse", (void*)QueueBindSparse}, 106633616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateSemaphore", (void*)CreateSemaphore}, 106643616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateEvent", (void*)CreateEvent}, 106653616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_ANDROID_KHR 106663616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateAndroidSurfaceKHR", (void*)CreateAndroidSurfaceKHR}, 106673616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 106683616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_MIR_KHR 106693616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateMirSurfaceKHR", (void*)CreateMirSurfaceKHR}, 106703616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceMirPresentationSupportKHR", (void*)GetPhysicalDeviceMirPresentationSupportKHR}, 106713616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 106723616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_WAYLAND_KHR 106733616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateWaylandSurfaceKHR", (void*)CreateWaylandSurfaceKHR}, 106743616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceWaylandPresentationSupportKHR", (void*)GetPhysicalDeviceWaylandPresentationSupportKHR}, 106753616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 106763616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_WIN32_KHR 106773616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateWin32SurfaceKHR", (void*)CreateWin32SurfaceKHR}, 106783616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceWin32PresentationSupportKHR", (void*)GetPhysicalDeviceWin32PresentationSupportKHR}, 106793616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 106803616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_XCB_KHR 106813616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateXcbSurfaceKHR", (void*)CreateXcbSurfaceKHR}, 106823616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceXcbPresentationSupportKHR", (void*)GetPhysicalDeviceXcbPresentationSupportKHR}, 106833616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 106843616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#ifdef VK_USE_PLATFORM_XLIB_KHR 106853616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateXlibSurfaceKHR", (void*)CreateXlibSurfaceKHR}, 106863616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceXlibPresentationSupportKHR", (void*)GetPhysicalDeviceXlibPresentationSupportKHR}, 106873616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski#endif 106883616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDisplayPlaneSurfaceKHR", (void*)CreateDisplayPlaneSurfaceKHR}, 106893616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroySurfaceKHR", (void*)DestroySurfaceKHR}, 106903616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", (void*)GetPhysicalDeviceSurfaceCapabilitiesKHR}, 106913616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceCapabilities2KHR", (void*)GetPhysicalDeviceSurfaceCapabilities2KHR}, 106923616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceCapabilities2EXT", (void*)GetPhysicalDeviceSurfaceCapabilities2EXT}, 106933616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceSupportKHR", (void*)GetPhysicalDeviceSurfaceSupportKHR}, 106943616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfacePresentModesKHR", (void*)GetPhysicalDeviceSurfacePresentModesKHR}, 106953616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceFormatsKHR", (void*)GetPhysicalDeviceSurfaceFormatsKHR}, 106963616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceSurfaceFormats2KHR", (void*)GetPhysicalDeviceSurfaceFormats2KHR}, 106973616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkGetPhysicalDeviceQueueFamilyProperties2KHR", (void*)GetPhysicalDeviceQueueFamilyProperties2KHR}, 106983616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkEnumeratePhysicalDeviceGroupsKHX", (void*)EnumeratePhysicalDeviceGroupsKHX}, 106993616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkCreateDebugReportCallbackEXT", (void*)CreateDebugReportCallbackEXT}, 107003616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDestroyDebugReportCallbackEXT", (void*)DestroyDebugReportCallbackEXT}, 107013616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski {"vkDebugReportMessageEXT", (void*)DebugReportMessageEXT}, 10702991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski {"vkGetPhysicalDeviceDisplayPlanePropertiesKHR", (void*)GetPhysicalDeviceDisplayPlanePropertiesKHR}, 10703991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski {"GetDisplayPlaneSupportedDisplaysKHR", (void*)GetDisplayPlaneSupportedDisplaysKHR}, 10704991f2555bc4f571e30b584937c7959805dff67c6Mark Lobodzinski {"GetDisplayPlaneCapabilitiesKHR", (void*)GetDisplayPlaneCapabilitiesKHR}, 107053616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski}; 10706b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 107073616276bb0053c612c0a8d223e81ae3808b1b2c4Mark LobodzinskiVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) { 107083616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski assert(device); 107093616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map); 107105b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 107113616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski // Is API to be intercepted by this layer? 107123616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski const auto &item = name_to_funcptr_map.find(funcName); 107133616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski if (item != name_to_funcptr_map.end()) { 107143616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski return reinterpret_cast<PFN_vkVoidFunction>(item->second); 107153616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski } 1071609a2f8128f58f032b73d29fab5afd789626562c3Chia-I Wu 107173616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski auto &table = device_data->dispatch_table; 10718cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!table.GetDeviceProcAddr) return nullptr; 107193616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski return table.GetDeviceProcAddr(device, funcName); 107205b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 107215b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis 1072289d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I WuVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) { 107233616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski instance_layer_data *instance_data; 107243616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski // Is API to be intercepted by this layer? 107253616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski const auto &item = name_to_funcptr_map.find(funcName); 107263616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski if (item != name_to_funcptr_map.end()) { 107273616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski return reinterpret_cast<PFN_vkVoidFunction>(item->second); 107283616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski } 10729b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 107303616276bb0053c612c0a8d223e81ae3808b1b2c4Mark Lobodzinski instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 107314a0754042cf090e131e9e769d8a3633c228625beChris Forbes auto &table = instance_data->dispatch_table; 10732cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!table.GetInstanceProcAddr) return nullptr; 107334a0754042cf090e131e9e769d8a3633c228625beChris Forbes return table.GetInstanceProcAddr(instance, funcName); 107345b5e7bcfe47d9ed90d0d5edbbe11edf7214a7784Tobin Ehlis} 1073508939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 10736b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark YoungVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char *funcName) { 10737b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young assert(instance); 1073856e14f5c1c3c1cc8e3137bee5c3093d238763a42Tobin Ehlis instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map); 10739b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10740b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young auto &table = instance_data->dispatch_table; 10741cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski if (!table.GetPhysicalDeviceProcAddr) return nullptr; 10742b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young return table.GetPhysicalDeviceProcAddr(instance, funcName); 10743b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young} 10744b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10745cc7c305c82f6443c324165edb7af59f60fc87eebMark Lobodzinski} // namespace core_validation 10746d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 10747a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu// loader-layer interface v0, just wrappers since there is only a layer 10748d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 10749bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount, 10750bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkExtensionProperties *pProperties) { 10751a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return core_validation::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties); 1075208939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 1075308939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 10754bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount, 10755bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkLayerProperties *pProperties) { 10756a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return core_validation::EnumerateInstanceLayerProperties(pCount, pProperties); 1075708939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 1075808939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu 10759bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, 10760bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski VkLayerProperties *pProperties) { 10761a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu // the layer command handles VK_NULL_HANDLE just fine internally 10762a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu assert(physicalDevice == VK_NULL_HANDLE); 10763a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu return core_validation::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties); 10764d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu} 10765d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 10766d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I WuVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, 10767d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu const char *pLayerName, uint32_t *pCount, 10768d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu VkExtensionProperties *pProperties) { 10769a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu // the layer command handles VK_NULL_HANDLE just fine internally 10770a4e71cd8b4e77502943dd894ed95426a25dffbd5Chia-I Wu assert(physicalDevice == VK_NULL_HANDLE); 10771a8f4a23b1e9c068717eda47cc583a93f447c77e3Chia-I Wu return core_validation::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties); 10772d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu} 10773d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 10774d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I WuVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) { 1077589d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu return core_validation::GetDeviceProcAddr(dev, funcName); 10776d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu} 10777d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I Wu 10778d16a2fd05d0b6bd20c7274560c88e37e4b3adefcChia-I WuVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) { 1077989d6bb8ab0ab38202ecfb3d6e21f60c884cc62e5Chia-I Wu return core_validation::GetInstanceProcAddr(instance, funcName); 1078008939232d080c94fc7b4c5ad348644928beb1519Chia-I Wu} 10781b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10782bc9caa57c5583dfdf05198e78b78a7cb361da16cMark LobodzinskiVK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_layerGetPhysicalDeviceProcAddr(VkInstance instance, 10783bc9caa57c5583dfdf05198e78b78a7cb361da16cMark Lobodzinski const char *funcName) { 10784b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young return core_validation::GetPhysicalDeviceProcAddr(instance, funcName); 10785b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young} 10786b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10787b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark YoungVK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct) { 10788b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young assert(pVersionStruct != NULL); 10789b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young assert(pVersionStruct->sType == LAYER_NEGOTIATE_INTERFACE_STRUCT); 10790b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10791b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young // Fill in the function pointers if our version is at least capable of having the structure contain them. 10792b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young if (pVersionStruct->loaderLayerInterfaceVersion >= 2) { 10793b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->pfnGetInstanceProcAddr = vkGetInstanceProcAddr; 10794b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->pfnGetDeviceProcAddr = vkGetDeviceProcAddr; 10795b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->pfnGetPhysicalDeviceProcAddr = vk_layerGetPhysicalDeviceProcAddr; 10796b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young } 10797b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10798b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young if (pVersionStruct->loaderLayerInterfaceVersion < CURRENT_LOADER_LAYER_INTERFACE_VERSION) { 10799b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young core_validation::loader_layer_if_version = pVersionStruct->loaderLayerInterfaceVersion; 10800b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young } else if (pVersionStruct->loaderLayerInterfaceVersion > CURRENT_LOADER_LAYER_INTERFACE_VERSION) { 10801b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young pVersionStruct->loaderLayerInterfaceVersion = CURRENT_LOADER_LAYER_INTERFACE_VERSION; 10802b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young } 10803b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young 10804b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young return VK_SUCCESS; 10805b5f087aec8b42faee128c5c3dd1cb11b662d85aaMark Young} 10806